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 attributes
235 (define_code_attr extend_su
239 (define_code_attr extend_u
243 (define_code_attr extend_s
247 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
248 (define_code_attr mul_r_d
252 ;; Map RTX code to its standard insn name
253 (define_code_attr code_stdname
259 ;;========================================================================
260 ;; The following is used by nonlocal_goto and setjmp.
261 ;; The receiver pattern will create no instructions since internally
262 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
263 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
264 ;; The 'null' receiver also avoids problems with optimisation
265 ;; not recognising incoming jmp and removing code that resets frame_pointer.
266 ;; The code derived from builtins.c.
268 (define_expand "nonlocal_goto_receiver"
270 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
273 emit_move_insn (virtual_stack_vars_rtx,
274 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
275 gen_int_mode (STARTING_FRAME_OFFSET,
277 /* This might change the hard frame pointer in ways that aren't
278 apparent to early optimization passes, so force a clobber. */
279 emit_clobber (hard_frame_pointer_rtx);
284 ;; Defining nonlocal_goto_receiver means we must also define this.
285 ;; even though its function is identical to that in builtins.c
287 (define_expand "nonlocal_goto"
288 [(use (match_operand 0 "general_operand"))
289 (use (match_operand 1 "general_operand"))
290 (use (match_operand 2 "general_operand"))
291 (use (match_operand 3 "general_operand"))]
294 rtx r_label = copy_to_reg (operands[1]);
295 rtx r_fp = operands[3];
296 rtx r_sp = operands[2];
298 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
300 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
302 emit_move_insn (hard_frame_pointer_rtx, r_fp);
303 emit_stack_restore (SAVE_NONLOCAL, r_sp);
305 emit_use (hard_frame_pointer_rtx);
306 emit_use (stack_pointer_rtx);
308 emit_indirect_jump (r_label);
313 (define_insn "pushqi1"
314 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
315 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
320 [(set_attr "length" "1,1")])
322 ;; All modes for a multi-byte push. We must include complex modes here too,
323 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
324 (define_mode_iterator MPUSH
332 (define_expand "push<mode>1"
333 [(match_operand:MPUSH 0 "" "")]
337 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
339 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
340 if (part != const0_rtx)
341 part = force_reg (QImode, part);
342 emit_insn (gen_pushqi1 (part));
347 ;; Notice a special-case when adding N to SP where N results in a
348 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
350 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
352 && frame_pointer_needed
353 && !cfun->calls_alloca
354 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
355 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
358 ;;========================================================================
361 (define_expand "load<mode>_libgcc"
364 (set (reg:MOVMODE 22)
365 (match_operand:MOVMODE 1 "memory_operand" ""))
366 (set (match_operand:MOVMODE 0 "register_operand" "")
368 "avr_load_libgcc_p (operands[1])"
370 operands[3] = gen_rtx_REG (HImode, REG_Z);
371 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
372 operands[1] = replace_equiv_address (operands[1], operands[3]);
373 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
376 (define_insn "load_<mode>_libgcc"
377 [(set (reg:MOVMODE 22)
378 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
379 "avr_load_libgcc_p (operands[0])
380 && REG_P (XEXP (operands[0], 0))
381 && REG_Z == REGNO (XEXP (operands[0], 0))"
383 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
384 return "%~call __load_%0";
386 [(set_attr "length" "1,2")
387 (set_attr "isa" "rjmp,jmp")
388 (set_attr "cc" "clobber")])
391 (define_insn_and_split "xload8_A"
392 [(set (match_operand:QI 0 "register_operand" "=r")
393 (match_operand:QI 1 "memory_operand" "m"))
394 (clobber (reg:HI REG_Z))]
395 "can_create_pseudo_p()
396 && !avr_xload_libgcc_p (QImode)
397 && avr_mem_memx_p (operands[1])
398 && REG_P (XEXP (operands[1], 0))"
399 { gcc_unreachable(); }
401 [(clobber (const_int 0))]
403 rtx insn, addr = XEXP (operands[1], 0);
404 rtx hi8 = gen_reg_rtx (QImode);
405 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
407 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
408 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
410 insn = emit_insn (gen_xload_8 (operands[0], hi8));
411 set_mem_addr_space (SET_SRC (single_set (insn)),
412 MEM_ADDR_SPACE (operands[1]));
416 (define_insn_and_split "xload<mode>_A"
417 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
418 (match_operand:MOVMODE 1 "memory_operand" "m"))
419 (clobber (reg:QI 21))
420 (clobber (reg:HI REG_Z))]
421 "can_create_pseudo_p()
422 && avr_mem_memx_p (operands[1])
423 && REG_P (XEXP (operands[1], 0))"
424 { gcc_unreachable(); }
426 [(clobber (const_int 0))]
428 rtx addr = XEXP (operands[1], 0);
429 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
430 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
431 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
434 /* Split the address to R21:Z */
435 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
436 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
438 /* Load with code from libgcc */
439 insn = emit_insn (gen_xload_<mode>_libgcc ());
440 set_mem_addr_space (SET_SRC (single_set (insn)), as);
442 /* Move to destination */
443 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
448 ;; Move value from address space memx to a register
449 ;; These insns must be prior to respective generic move insn.
451 (define_insn "xload_8"
452 [(set (match_operand:QI 0 "register_operand" "=&r,r")
453 (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
455 "!avr_xload_libgcc_p (QImode)"
457 return avr_out_xload (insn, operands, NULL);
459 [(set_attr "length" "3,4")
460 (set_attr "adjust_len" "*,xload")
461 (set_attr "isa" "lpmx,lpm")
462 (set_attr "cc" "none")])
466 ;; "xload_psi_libgcc"
469 (define_insn "xload_<mode>_libgcc"
470 [(set (reg:MOVMODE 22)
471 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
473 (clobber (reg:QI 21))
474 (clobber (reg:HI REG_Z))]
475 "avr_xload_libgcc_p (<MODE>mode)"
477 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
479 output_asm_insn ("%~call __xload_%0", &x_bytes);
482 [(set_attr "type" "xcall")
483 (set_attr "cc" "clobber")])
486 ;; General move expanders
493 (define_expand "mov<mode>"
494 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
495 (match_operand:MOVMODE 1 "general_operand" ""))]
498 rtx dest = operands[0];
499 rtx src = operands[1];
501 if (avr_mem_flash_p (dest))
504 /* One of the operands has to be in a register. */
505 if (!register_operand (dest, <MODE>mode)
506 && !(register_operand (src, <MODE>mode)
507 || src == CONST0_RTX (<MODE>mode)))
509 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
512 if (avr_mem_memx_p (src))
514 rtx addr = XEXP (src, 0);
517 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
519 if (!avr_xload_libgcc_p (<MODE>mode))
520 emit_insn (gen_xload8_A (dest, src));
522 emit_insn (gen_xload<mode>_A (dest, src));
527 if (avr_load_libgcc_p (src))
529 /* For the small devices, do loads per libgcc call. */
530 emit_insn (gen_load<mode>_libgcc (dest, src));
535 ;;========================================================================
537 ;; The last alternative (any immediate constant to any register) is
538 ;; very expensive. It should be optimized by peephole2 if a scratch
539 ;; register is available, but then that register could just as well be
540 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
541 ;; are call-saved registers, and most of LD_REGS are call-used registers,
542 ;; so this may still be a win for registers live across function calls.
544 (define_insn "movqi_insn"
545 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
546 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
547 "register_operand (operands[0], QImode)
548 || register_operand (operands[1], QImode)
549 || const0_rtx == operands[1]"
551 return output_movqi (insn, operands, NULL);
553 [(set_attr "length" "1,1,5,5,1,1,4")
554 (set_attr "adjust_len" "mov8")
555 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
557 ;; This is used in peephole2 to optimize loading immediate constants
558 ;; if a scratch register from LD_REGS happens to be available.
560 (define_insn "*reload_inqi"
561 [(set (match_operand:QI 0 "register_operand" "=l")
562 (match_operand:QI 1 "immediate_operand" "i"))
563 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
567 [(set_attr "length" "2")
568 (set_attr "cc" "none")])
571 [(match_scratch:QI 2 "d")
572 (set (match_operand:QI 0 "l_register_operand" "")
573 (match_operand:QI 1 "immediate_operand" ""))]
574 "(operands[1] != const0_rtx
575 && operands[1] != const1_rtx
576 && operands[1] != constm1_rtx)"
577 [(parallel [(set (match_dup 0) (match_dup 1))
578 (clobber (match_dup 2))])]
581 ;;============================================================================
582 ;; move word (16 bit)
584 ;; Move register $1 to the Stack Pointer register SP.
585 ;; This insn is emit during function prologue/epilogue generation.
586 ;; $2 = 0: We know that IRQs are off
587 ;; $2 = 1: We know that IRQs are on
588 ;; Remaining cases when the state of the I-Flag is unknown are
589 ;; handled by generic movhi insn.
591 (define_insn "movhi_sp_r"
592 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q")
593 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r")
594 (match_operand:HI 2 "const_int_operand" "L,P,LP")]
598 out __SP_H__,%B1\;out __SP_L__,%A1
599 cli\;out __SP_H__,%B1\;sei\;out __SP_L__,%A1
600 out __SP_L__,%A1\;out __SP_H__,%B1"
601 [(set_attr "length" "2,4,2")
602 (set_attr "isa" "no_xmega,no_xmega,xmega")
603 (set_attr "cc" "none")])
606 [(match_scratch:QI 2 "d")
607 (set (match_operand:HI 0 "l_register_operand" "")
608 (match_operand:HI 1 "immediate_operand" ""))]
609 "(operands[1] != const0_rtx
610 && operands[1] != constm1_rtx)"
611 [(parallel [(set (match_dup 0) (match_dup 1))
612 (clobber (match_dup 2))])]
615 ;; '*' because it is not used in rtl generation, only in above peephole
616 (define_insn "*reload_inhi"
617 [(set (match_operand:HI 0 "register_operand" "=r")
618 (match_operand:HI 1 "immediate_operand" "i"))
619 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
622 return output_reload_inhi (operands, operands[2], NULL);
624 [(set_attr "length" "4")
625 (set_attr "adjust_len" "reload_in16")
626 (set_attr "cc" "none")])
628 (define_insn "*movhi"
629 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
630 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
631 "register_operand (operands[0], HImode)
632 || register_operand (operands[1], HImode)
633 || const0_rtx == operands[1]"
635 return output_movhi (insn, operands, NULL);
637 [(set_attr "length" "2,2,6,7,2,6,5,2")
638 (set_attr "adjust_len" "mov16")
639 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
641 (define_peephole2 ; movw
642 [(set (match_operand:QI 0 "even_register_operand" "")
643 (match_operand:QI 1 "even_register_operand" ""))
644 (set (match_operand:QI 2 "odd_register_operand" "")
645 (match_operand:QI 3 "odd_register_operand" ""))]
647 && REGNO (operands[0]) == REGNO (operands[2]) - 1
648 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
649 [(set (match_dup 4) (match_dup 5))]
651 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
652 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
655 (define_peephole2 ; movw_r
656 [(set (match_operand:QI 0 "odd_register_operand" "")
657 (match_operand:QI 1 "odd_register_operand" ""))
658 (set (match_operand:QI 2 "even_register_operand" "")
659 (match_operand:QI 3 "even_register_operand" ""))]
661 && REGNO (operands[2]) == REGNO (operands[0]) - 1
662 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
663 [(set (match_dup 4) (match_dup 5))]
665 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
666 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
669 ;; For LPM loads from AS1 we split
673 ;; Z = Z - sizeof (R)
675 ;; so that the second instruction can be optimized out.
677 (define_split ; "split-lpmx"
678 [(set (match_operand:HISI 0 "register_operand" "")
679 (match_operand:HISI 1 "memory_operand" ""))]
685 (plus:HI (match_dup 3)
688 rtx addr = XEXP (operands[1], 0);
690 if (!avr_mem_flash_p (operands[1])
692 || reg_overlap_mentioned_p (addr, operands[0]))
697 operands[2] = replace_equiv_address (operands[1],
698 gen_rtx_POST_INC (Pmode, addr));
700 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
703 ;;==========================================================================
704 ;; xpointer move (24 bit)
706 (define_peephole2 ; *reload_inpsi
707 [(match_scratch:QI 2 "d")
708 (set (match_operand:PSI 0 "l_register_operand" "")
709 (match_operand:PSI 1 "immediate_operand" ""))
711 "operands[1] != const0_rtx
712 && operands[1] != constm1_rtx"
713 [(parallel [(set (match_dup 0)
715 (clobber (match_dup 2))])]
718 ;; '*' because it is not used in rtl generation.
719 (define_insn "*reload_inpsi"
720 [(set (match_operand:PSI 0 "register_operand" "=r")
721 (match_operand:PSI 1 "immediate_operand" "i"))
722 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
725 return avr_out_reload_inpsi (operands, operands[2], NULL);
727 [(set_attr "length" "6")
728 (set_attr "adjust_len" "reload_in24")
729 (set_attr "cc" "clobber")])
731 (define_insn "*movpsi"
732 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
733 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
734 "register_operand (operands[0], PSImode)
735 || register_operand (operands[1], PSImode)
736 || const0_rtx == operands[1]"
738 return avr_out_movpsi (insn, operands, NULL);
740 [(set_attr "length" "3,3,8,9,4,10")
741 (set_attr "adjust_len" "mov24")
742 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
744 ;;==========================================================================
745 ;; move double word (32 bit)
747 (define_peephole2 ; *reload_insi
748 [(match_scratch:QI 2 "d")
749 (set (match_operand:SI 0 "l_register_operand" "")
750 (match_operand:SI 1 "const_int_operand" ""))
752 "(operands[1] != const0_rtx
753 && operands[1] != constm1_rtx)"
754 [(parallel [(set (match_dup 0) (match_dup 1))
755 (clobber (match_dup 2))])]
758 ;; '*' because it is not used in rtl generation.
759 (define_insn "*reload_insi"
760 [(set (match_operand:SI 0 "register_operand" "=r")
761 (match_operand:SI 1 "const_int_operand" "n"))
762 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
765 return output_reload_insisf (operands, operands[2], NULL);
767 [(set_attr "length" "8")
768 (set_attr "adjust_len" "reload_in32")
769 (set_attr "cc" "clobber")])
772 (define_insn "*movsi"
773 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
774 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
775 "register_operand (operands[0], SImode)
776 || register_operand (operands[1], SImode)
777 || const0_rtx == operands[1]"
779 return output_movsisf (insn, operands, NULL);
781 [(set_attr "length" "4,4,8,9,4,10")
782 (set_attr "adjust_len" "mov32")
783 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
785 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
786 ;; move floating point numbers (32 bit)
788 (define_insn "*movsf"
789 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
790 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
791 "register_operand (operands[0], SFmode)
792 || register_operand (operands[1], SFmode)
793 || operands[1] == CONST0_RTX (SFmode)"
795 return output_movsisf (insn, operands, NULL);
797 [(set_attr "length" "4,4,8,9,4,10")
798 (set_attr "adjust_len" "mov32")
799 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
801 (define_peephole2 ; *reload_insf
802 [(match_scratch:QI 2 "d")
803 (set (match_operand:SF 0 "l_register_operand" "")
804 (match_operand:SF 1 "const_double_operand" ""))
806 "operands[1] != CONST0_RTX (SFmode)"
807 [(parallel [(set (match_dup 0)
809 (clobber (match_dup 2))])]
812 ;; '*' because it is not used in rtl generation.
813 (define_insn "*reload_insf"
814 [(set (match_operand:SF 0 "register_operand" "=r")
815 (match_operand:SF 1 "const_double_operand" "F"))
816 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
819 return output_reload_insisf (operands, operands[2], NULL);
821 [(set_attr "length" "8")
822 (set_attr "adjust_len" "reload_in32")
823 (set_attr "cc" "clobber")])
825 ;;=========================================================================
826 ;; move string (like memcpy)
828 (define_expand "movmemhi"
829 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
830 (match_operand:BLK 1 "memory_operand" ""))
831 (use (match_operand:HI 2 "const_int_operand" ""))
832 (use (match_operand:HI 3 "const_int_operand" ""))])]
835 if (avr_emit_movmemhi (operands))
841 (define_mode_attr MOVMEM_r_d [(QI "r")
844 ;; $0, $4 : & dest (REG_X)
845 ;; $1, $5 : & src (REG_Z)
846 ;; $2 : Address Space
847 ;; $3, $7 : Loop register
848 ;; $6 : Scratch register
852 (define_insn "movmem_<mode>"
853 [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
854 (mem:BLK (match_operand:HI 1 "register_operand" "z")))
855 (unspec [(match_operand:QI 2 "const_int_operand" "n")]
857 (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>"))
858 (clobber (match_operand:HI 4 "register_operand" "=0"))
859 (clobber (match_operand:HI 5 "register_operand" "=1"))
860 (clobber (match_operand:QI 6 "register_operand" "=&r"))
861 (clobber (match_operand:QIHI 7 "register_operand" "=3"))]
864 return avr_out_movmem (insn, operands, NULL);
866 [(set_attr "adjust_len" "movmem")
867 (set_attr "cc" "clobber")])
870 ;; $3, $7 : Loop register = R24
871 ;; $8, $9 : hh8 (& src) = R23
876 (define_insn "movmemx_<mode>"
877 [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
878 (mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r")
879 (match_operand:HI 1 "register_operand" "z"))))
880 (unspec [(match_operand:QI 2 "const_int_operand" "n")]
882 (use (match_operand:QIHI 3 "register_operand" "w"))
883 (clobber (match_operand:HI 4 "register_operand" "=0"))
884 (clobber (match_operand:HI 5 "register_operand" "=1"))
885 (clobber (match_operand:QI 6 "register_operand" "=&r"))
886 (clobber (match_operand:HI 7 "register_operand" "=3"))
887 (clobber (match_operand:QI 9 "register_operand" "=8"))
888 (clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))]
890 "%~call __movmemx_<mode>"
891 [(set_attr "type" "xcall")
892 (set_attr "cc" "clobber")])
895 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
896 ;; memset (%0, %2, %1)
898 (define_expand "setmemhi"
899 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
900 (match_operand 2 "const_int_operand" ""))
901 (use (match_operand:HI 1 "const_int_operand" ""))
902 (use (match_operand:HI 3 "const_int_operand" ""))
903 (clobber (match_scratch:HI 4 ""))
904 (clobber (match_dup 5))])]
908 enum machine_mode mode;
910 /* If value to set is not zero, use the library routine. */
911 if (operands[2] != const0_rtx)
914 if (!CONST_INT_P (operands[1]))
917 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
918 operands[5] = gen_rtx_SCRATCH (mode);
919 operands[1] = copy_to_mode_reg (mode,
920 gen_int_mode (INTVAL (operands[1]), mode));
921 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
922 operands[0] = gen_rtx_MEM (BLKmode, addr0);
926 (define_insn "*clrmemqi"
927 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
929 (use (match_operand:QI 1 "register_operand" "r"))
930 (use (match_operand:QI 2 "const_int_operand" "n"))
931 (clobber (match_scratch:HI 3 "=0"))
932 (clobber (match_scratch:QI 4 "=&1"))]
934 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
935 [(set_attr "length" "3")
936 (set_attr "cc" "clobber")])
939 (define_insn "*clrmemhi"
940 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
942 (use (match_operand:HI 1 "register_operand" "!w,d"))
943 (use (match_operand:HI 2 "const_int_operand" "n,n"))
944 (clobber (match_scratch:HI 3 "=0,0"))
945 (clobber (match_scratch:HI 4 "=&1,&1"))]
948 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
949 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
950 [(set_attr "length" "3,4")
951 (set_attr "cc" "clobber,clobber")])
953 (define_expand "strlenhi"
955 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
956 (match_operand:QI 2 "const_int_operand" "")
957 (match_operand:HI 3 "immediate_operand" "")]
960 (plus:HI (match_dup 4)
962 (set (match_operand:HI 0 "register_operand" "")
963 (minus:HI (match_dup 4)
968 if (operands[2] != const0_rtx)
970 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
971 operands[1] = gen_rtx_MEM (BLKmode, addr);
973 operands[4] = gen_reg_rtx (HImode);
976 (define_insn "*strlenhi"
977 [(set (match_operand:HI 0 "register_operand" "=e")
978 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
980 (match_operand:HI 2 "immediate_operand" "i")]
983 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
984 [(set_attr "length" "3")
985 (set_attr "cc" "clobber")])
987 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
990 (define_insn "addqi3"
991 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
992 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
993 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
1002 [(set_attr "length" "1,1,1,1,2,2")
1003 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1006 (define_expand "addhi3"
1007 [(set (match_operand:HI 0 "register_operand" "")
1008 (plus:HI (match_operand:HI 1 "register_operand" "")
1009 (match_operand:HI 2 "nonmemory_operand" "")))]
1012 if (CONST_INT_P (operands[2]))
1014 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1016 if (can_create_pseudo_p()
1017 && !stack_register_operand (operands[0], HImode)
1018 && !stack_register_operand (operands[1], HImode)
1019 && !d_register_operand (operands[0], HImode)
1020 && !d_register_operand (operands[1], HImode))
1022 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1029 (define_insn "*addhi3_zero_extend"
1030 [(set (match_operand:HI 0 "register_operand" "=r")
1031 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1032 (match_operand:HI 2 "register_operand" "0")))]
1034 "add %A0,%1\;adc %B0,__zero_reg__"
1035 [(set_attr "length" "2")
1036 (set_attr "cc" "set_n")])
1038 (define_insn "*addhi3_zero_extend1"
1039 [(set (match_operand:HI 0 "register_operand" "=r")
1040 (plus:HI (match_operand:HI 1 "register_operand" "0")
1041 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1043 "add %A0,%2\;adc %B0,__zero_reg__"
1044 [(set_attr "length" "2")
1045 (set_attr "cc" "set_n")])
1047 (define_insn "*addhi3.sign_extend1"
1048 [(set (match_operand:HI 0 "register_operand" "=r")
1049 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1050 (match_operand:HI 2 "register_operand" "0")))]
1053 return reg_overlap_mentioned_p (operands[0], operands[1])
1054 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1055 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1057 [(set_attr "length" "5")
1058 (set_attr "cc" "clobber")])
1060 (define_insn "*addhi3_sp"
1061 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1062 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1063 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1066 return avr_out_addto_sp (operands, NULL);
1068 [(set_attr "length" "6")
1069 (set_attr "adjust_len" "addto_sp")])
1071 (define_insn "*addhi3"
1072 [(set (match_operand:HI 0 "register_operand" "=r,d,d")
1073 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1074 (match_operand:HI 2 "nonmemory_operand" "r,s,n")))]
1077 static const char * const asm_code[] =
1079 "add %A0,%A2\;adc %B0,%B2",
1080 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
1084 if (*asm_code[which_alternative])
1085 return asm_code[which_alternative];
1087 return avr_out_plus_noclobber (operands, NULL, NULL);
1089 [(set_attr "length" "2,2,2")
1090 (set_attr "adjust_len" "*,*,out_plus_noclobber")
1091 (set_attr "cc" "set_n,set_czn,out_plus_noclobber")])
1093 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1094 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1095 ;; itself because that insn is special to reload.
1097 (define_peephole2 ; addhi3_clobber
1098 [(set (match_operand:HI 0 "d_register_operand" "")
1099 (match_operand:HI 1 "const_int_operand" ""))
1100 (set (match_operand:HI 2 "l_register_operand" "")
1101 (plus:HI (match_dup 2)
1103 "peep2_reg_dead_p (2, operands[0])"
1104 [(parallel [(set (match_dup 2)
1105 (plus:HI (match_dup 2)
1107 (clobber (match_dup 3))])]
1109 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
1112 ;; Same, but with reload to NO_LD_REGS
1113 ;; Combine *reload_inhi with *addhi3
1115 (define_peephole2 ; addhi3_clobber
1116 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
1117 (match_operand:HI 1 "const_int_operand" ""))
1118 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1119 (set (match_operand:HI 3 "l_register_operand" "")
1120 (plus:HI (match_dup 3)
1122 "peep2_reg_dead_p (2, operands[0])"
1123 [(parallel [(set (match_dup 3)
1124 (plus:HI (match_dup 3)
1126 (clobber (match_dup 2))])])
1128 (define_insn "addhi3_clobber"
1129 [(set (match_operand:HI 0 "register_operand" "=d,l")
1130 (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
1131 (match_operand:HI 2 "const_int_operand" "n,n")))
1132 (clobber (match_scratch:QI 3 "=X,&d"))]
1135 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1137 return avr_out_plus (operands, NULL, NULL);
1139 [(set_attr "length" "4")
1140 (set_attr "adjust_len" "out_plus")
1141 (set_attr "cc" "out_plus")])
1144 (define_insn "addsi3"
1145 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1146 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1147 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1148 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1151 static const char * const asm_code[] =
1153 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
1154 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
1159 if (*asm_code[which_alternative])
1160 return asm_code[which_alternative];
1162 return avr_out_plus (operands, NULL, NULL);
1164 [(set_attr "length" "4,4,4,8")
1165 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1166 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1168 (define_insn "*addpsi3_zero_extend.qi"
1169 [(set (match_operand:PSI 0 "register_operand" "=r")
1170 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1171 (match_operand:PSI 2 "register_operand" "0")))]
1173 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1174 [(set_attr "length" "3")
1175 (set_attr "cc" "set_n")])
1177 (define_insn "*addpsi3_zero_extend.hi"
1178 [(set (match_operand:PSI 0 "register_operand" "=r")
1179 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1180 (match_operand:PSI 2 "register_operand" "0")))]
1182 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1183 [(set_attr "length" "3")
1184 (set_attr "cc" "set_n")])
1186 (define_insn "*addpsi3_sign_extend.hi"
1187 [(set (match_operand:PSI 0 "register_operand" "=r")
1188 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1189 (match_operand:PSI 2 "register_operand" "0")))]
1191 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1192 [(set_attr "length" "5")
1193 (set_attr "cc" "set_n")])
1195 (define_insn "*addsi3_zero_extend"
1196 [(set (match_operand:SI 0 "register_operand" "=r")
1197 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1198 (match_operand:SI 2 "register_operand" "0")))]
1200 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1201 [(set_attr "length" "4")
1202 (set_attr "cc" "set_n")])
1204 (define_insn "*addsi3_zero_extend.hi"
1205 [(set (match_operand:SI 0 "register_operand" "=r")
1206 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1207 (match_operand:SI 2 "register_operand" "0")))]
1209 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1210 [(set_attr "length" "4")
1211 (set_attr "cc" "set_n")])
1213 (define_insn "addpsi3"
1214 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1215 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1216 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1217 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1220 static const char * const asm_code[] =
1222 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1223 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1228 if (*asm_code[which_alternative])
1229 return asm_code[which_alternative];
1231 return avr_out_plus (operands, NULL, NULL);
1233 [(set_attr "length" "3,3,3,6")
1234 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1235 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1237 (define_insn "subpsi3"
1238 [(set (match_operand:PSI 0 "register_operand" "=r")
1239 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1240 (match_operand:PSI 2 "register_operand" "r")))]
1242 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1243 [(set_attr "length" "3")
1244 (set_attr "cc" "set_czn")])
1246 (define_insn "*subpsi3_zero_extend.qi"
1247 [(set (match_operand:PSI 0 "register_operand" "=r")
1248 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1249 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1251 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1252 [(set_attr "length" "3")
1253 (set_attr "cc" "set_czn")])
1255 (define_insn "*subpsi3_zero_extend.hi"
1256 [(set (match_operand:PSI 0 "register_operand" "=r")
1257 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1258 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1260 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1261 [(set_attr "length" "3")
1262 (set_attr "cc" "set_czn")])
1264 (define_insn "*subpsi3_sign_extend.hi"
1265 [(set (match_operand:PSI 0 "register_operand" "=r")
1266 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1267 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1269 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1270 [(set_attr "length" "5")
1271 (set_attr "cc" "set_czn")])
1273 ;-----------------------------------------------------------------------------
1275 (define_insn "subqi3"
1276 [(set (match_operand:QI 0 "register_operand" "=r,d")
1277 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1278 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1283 [(set_attr "length" "1,1")
1284 (set_attr "cc" "set_czn,set_czn")])
1286 (define_insn "subhi3"
1287 [(set (match_operand:HI 0 "register_operand" "=r,d")
1288 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1289 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1292 sub %A0,%A2\;sbc %B0,%B2
1293 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1294 [(set_attr "length" "2,2")
1295 (set_attr "cc" "set_czn,set_czn")])
1297 (define_insn "*subhi3_zero_extend1"
1298 [(set (match_operand:HI 0 "register_operand" "=r")
1299 (minus:HI (match_operand:HI 1 "register_operand" "0")
1300 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1302 "sub %A0,%2\;sbc %B0,__zero_reg__"
1303 [(set_attr "length" "2")
1304 (set_attr "cc" "set_czn")])
1306 (define_insn "*subhi3.sign_extend2"
1307 [(set (match_operand:HI 0 "register_operand" "=r")
1308 (minus:HI (match_operand:HI 1 "register_operand" "0")
1309 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1312 return reg_overlap_mentioned_p (operands[0], operands[2])
1313 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1314 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1316 [(set_attr "length" "5")
1317 (set_attr "cc" "clobber")])
1319 (define_insn "subsi3"
1320 [(set (match_operand:SI 0 "register_operand" "=r")
1321 (minus:SI (match_operand:SI 1 "register_operand" "0")
1322 (match_operand:SI 2 "register_operand" "r")))]
1324 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1325 [(set_attr "length" "4")
1326 (set_attr "cc" "set_czn")])
1328 (define_insn "*subsi3_zero_extend"
1329 [(set (match_operand:SI 0 "register_operand" "=r")
1330 (minus:SI (match_operand:SI 1 "register_operand" "0")
1331 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1333 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1334 [(set_attr "length" "4")
1335 (set_attr "cc" "set_czn")])
1337 (define_insn "*subsi3_zero_extend.hi"
1338 [(set (match_operand:SI 0 "register_operand" "=r")
1339 (minus:SI (match_operand:SI 1 "register_operand" "0")
1340 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1342 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1343 [(set_attr "length" "4")
1344 (set_attr "cc" "set_czn")])
1346 ;******************************************************************************
1349 (define_expand "mulqi3"
1350 [(set (match_operand:QI 0 "register_operand" "")
1351 (mult:QI (match_operand:QI 1 "register_operand" "")
1352 (match_operand:QI 2 "register_operand" "")))]
1357 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1362 (define_insn "*mulqi3_enh"
1363 [(set (match_operand:QI 0 "register_operand" "=r")
1364 (mult:QI (match_operand:QI 1 "register_operand" "r")
1365 (match_operand:QI 2 "register_operand" "r")))]
1370 [(set_attr "length" "3")
1371 (set_attr "cc" "clobber")])
1373 (define_expand "mulqi3_call"
1374 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1375 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1376 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1377 (clobber (reg:QI 22))])
1378 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1382 (define_insn "*mulqi3_call"
1383 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1384 (clobber (reg:QI 22))]
1387 [(set_attr "type" "xcall")
1388 (set_attr "cc" "clobber")])
1390 ;; "umulqi3_highpart"
1391 ;; "smulqi3_highpart"
1392 (define_insn "<extend_su>mulqi3_highpart"
1393 [(set (match_operand:QI 0 "register_operand" "=r")
1395 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1396 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1399 "mul<extend_s> %1,%2
1402 [(set_attr "length" "3")
1403 (set_attr "cc" "clobber")])
1406 ;; Used when expanding div or mod inline for some special values
1407 (define_insn "*subqi3.ashiftrt7"
1408 [(set (match_operand:QI 0 "register_operand" "=r")
1409 (minus:QI (match_operand:QI 1 "register_operand" "0")
1410 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1414 [(set_attr "length" "2")
1415 (set_attr "cc" "clobber")])
1417 (define_insn "*addqi3.lt0"
1418 [(set (match_operand:QI 0 "register_operand" "=r")
1419 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1421 (match_operand:QI 2 "register_operand" "0")))]
1424 [(set_attr "length" "2")
1425 (set_attr "cc" "clobber")])
1427 (define_insn "*addhi3.lt0"
1428 [(set (match_operand:HI 0 "register_operand" "=w,r")
1429 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1431 (match_operand:HI 2 "register_operand" "0,0")))
1432 (clobber (match_scratch:QI 3 "=X,&1"))]
1435 sbrc %1,7\;adiw %0,1
1436 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1437 [(set_attr "length" "2,3")
1438 (set_attr "cc" "clobber")])
1440 (define_insn "*addpsi3.lt0"
1441 [(set (match_operand:PSI 0 "register_operand" "=r")
1442 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1444 (match_operand:PSI 2 "register_operand" "0")))]
1446 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1447 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1448 [(set_attr "length" "5")
1449 (set_attr "cc" "clobber")])
1451 (define_insn "*addsi3.lt0"
1452 [(set (match_operand:SI 0 "register_operand" "=r")
1453 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1455 (match_operand:SI 2 "register_operand" "0")))]
1457 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1458 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1459 [(set_attr "length" "6")
1460 (set_attr "cc" "clobber")])
1465 (define_insn "<extend_u>mulqihi3"
1466 [(set (match_operand:HI 0 "register_operand" "=r")
1467 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1468 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1470 "mul<extend_s> %1,%2
1473 [(set_attr "length" "3")
1474 (set_attr "cc" "clobber")])
1476 (define_insn "usmulqihi3"
1477 [(set (match_operand:HI 0 "register_operand" "=r")
1478 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1479 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1484 [(set_attr "length" "3")
1485 (set_attr "cc" "clobber")])
1487 ;; Above insn is not canonicalized by insn combine, so here is a version with
1488 ;; operands swapped.
1490 (define_insn "*sumulqihi3"
1491 [(set (match_operand:HI 0 "register_operand" "=r")
1492 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1493 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1498 [(set_attr "length" "3")
1499 (set_attr "cc" "clobber")])
1501 ;; One-extend operand 1
1503 (define_insn "*osmulqihi3"
1504 [(set (match_operand:HI 0 "register_operand" "=&r")
1505 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1506 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1512 [(set_attr "length" "4")
1513 (set_attr "cc" "clobber")])
1515 (define_insn "*oumulqihi3"
1516 [(set (match_operand:HI 0 "register_operand" "=&r")
1517 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1518 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1524 [(set_attr "length" "4")
1525 (set_attr "cc" "clobber")])
1527 ;******************************************************************************
1528 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1529 ;******************************************************************************
1531 (define_insn "*maddqi4"
1532 [(set (match_operand:QI 0 "register_operand" "=r")
1533 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1534 (match_operand:QI 2 "register_operand" "r"))
1535 (match_operand:QI 3 "register_operand" "0")))]
1541 [(set_attr "length" "4")
1542 (set_attr "cc" "clobber")])
1544 (define_insn "*msubqi4"
1545 [(set (match_operand:QI 0 "register_operand" "=r")
1546 (minus:QI (match_operand:QI 3 "register_operand" "0")
1547 (mult:QI (match_operand:QI 1 "register_operand" "r")
1548 (match_operand:QI 2 "register_operand" "r"))))]
1553 [(set_attr "length" "4")
1554 (set_attr "cc" "clobber")])
1556 (define_insn_and_split "*maddqi4.const"
1557 [(set (match_operand:QI 0 "register_operand" "=r")
1558 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1559 (match_operand:QI 2 "const_int_operand" "n"))
1560 (match_operand:QI 3 "register_operand" "0")))
1561 (clobber (match_scratch:QI 4 "=&d"))]
1564 "&& reload_completed"
1569 (plus:QI (mult:QI (match_dup 1)
1574 (define_insn_and_split "*msubqi4.const"
1575 [(set (match_operand:QI 0 "register_operand" "=r")
1576 (minus:QI (match_operand:QI 3 "register_operand" "0")
1577 (mult:QI (match_operand:QI 1 "register_operand" "r")
1578 (match_operand:QI 2 "const_int_operand" "n"))))
1579 (clobber (match_scratch:QI 4 "=&d"))]
1582 "&& reload_completed"
1587 (minus:QI (match_dup 3)
1588 (mult:QI (match_dup 1)
1593 ;******************************************************************************
1594 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1595 ;******************************************************************************
1597 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1600 ;; int foo (unsigned char z)
1602 ;; extern int aInt[];
1603 ;; return aInt[3*z+2];
1606 ;; because the constant +4 then is added explicitely instead of consuming it
1607 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1608 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1609 ;; The implementational effort is the same so we are fine with that approach.
1614 (define_insn "*<extend_u>maddqihi4"
1615 [(set (match_operand:HI 0 "register_operand" "=r")
1616 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1617 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1618 (match_operand:HI 3 "register_operand" "0")))]
1621 "mul<extend_s> %1,%2
1625 [(set_attr "length" "4")
1626 (set_attr "cc" "clobber")])
1630 (define_insn "*<extend_u>msubqihi4"
1631 [(set (match_operand:HI 0 "register_operand" "=r")
1632 (minus:HI (match_operand:HI 3 "register_operand" "0")
1633 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1634 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1636 "mul<extend_s> %1,%2
1640 [(set_attr "length" "4")
1641 (set_attr "cc" "clobber")])
1645 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1646 [(set (match_operand:HI 0 "register_operand" "=r")
1647 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1648 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1649 (match_operand:HI 3 "register_operand" "0")))]
1652 && <any_extend:CODE> != <any_extend2:CODE>"
1654 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1655 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1657 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1659 [(set_attr "length" "4")
1660 (set_attr "cc" "clobber")])
1664 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1665 [(set (match_operand:HI 0 "register_operand" "=r")
1666 (minus:HI (match_operand:HI 3 "register_operand" "0")
1667 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1668 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1671 && <any_extend:CODE> != <any_extend2:CODE>"
1673 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1674 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1676 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1678 [(set_attr "length" "4")
1679 (set_attr "cc" "clobber")])
1681 ;; Handle small constants
1683 ;; "umaddqihi4.uconst"
1684 ;; "maddqihi4.sconst"
1685 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1686 [(set (match_operand:HI 0 "register_operand" "=r")
1687 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1688 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1689 (match_operand:HI 3 "register_operand" "0")))
1690 (clobber (match_scratch:QI 4 "=&d"))]
1693 "&& reload_completed"
1696 ; *umaddqihi4 resp. *maddqihi4
1698 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1699 (any_extend:HI (match_dup 4)))
1702 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1705 ;; "*umsubqihi4.uconst"
1706 ;; "*msubqihi4.sconst"
1707 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1708 [(set (match_operand:HI 0 "register_operand" "=r")
1709 (minus:HI (match_operand:HI 3 "register_operand" "0")
1710 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1711 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1712 (clobber (match_scratch:QI 4 "=&d"))]
1715 "&& reload_completed"
1718 ; *umsubqihi4 resp. *msubqihi4
1720 (minus:HI (match_dup 3)
1721 (mult:HI (any_extend:HI (match_dup 1))
1722 (any_extend:HI (match_dup 4)))))]
1724 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1727 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1728 ;; for MULT with power of 2 and skips trying MULT insn above.
1730 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1731 [(set (match_operand:HI 0 "register_operand" "=r")
1732 (minus:HI (match_operand:HI 3 "register_operand" "0")
1733 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1734 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1735 (clobber (match_scratch:QI 4 "=&d"))]
1738 "&& reload_completed"
1743 (minus:HI (match_dup 3)
1744 (mult:HI (zero_extend:HI (match_dup 1))
1745 (zero_extend:HI (match_dup 4)))))]
1747 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1750 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1751 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1752 ;; because this would require an extra pattern for just one value.
1754 (define_insn_and_split "*msubqihi4.sconst.ashift"
1755 [(set (match_operand:HI 0 "register_operand" "=r")
1756 (minus:HI (match_operand:HI 3 "register_operand" "0")
1757 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1758 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1759 (clobber (match_scratch:QI 4 "=&d"))]
1762 "&& reload_completed"
1767 (minus:HI (match_dup 3)
1768 (mult:HI (sign_extend:HI (match_dup 1))
1769 (sign_extend:HI (match_dup 4)))))]
1771 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1774 ;; For signed/unsigned combinations that require narrow constraint "a"
1775 ;; just provide a pattern if signed/unsigned combination is actually needed.
1777 (define_insn_and_split "*sumaddqihi4.uconst"
1778 [(set (match_operand:HI 0 "register_operand" "=r")
1779 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1780 (match_operand:HI 2 "u8_operand" "M"))
1781 (match_operand:HI 3 "register_operand" "0")))
1782 (clobber (match_scratch:QI 4 "=&a"))]
1784 && !s8_operand (operands[2], VOIDmode)"
1786 "&& reload_completed"
1791 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1792 (zero_extend:HI (match_dup 4)))
1795 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1798 (define_insn_and_split "*sumsubqihi4.uconst"
1799 [(set (match_operand:HI 0 "register_operand" "=r")
1800 (minus:HI (match_operand:HI 3 "register_operand" "0")
1801 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1802 (match_operand:HI 2 "u8_operand" "M"))))
1803 (clobber (match_scratch:QI 4 "=&a"))]
1805 && !s8_operand (operands[2], VOIDmode)"
1807 "&& reload_completed"
1812 (minus:HI (match_dup 3)
1813 (mult:HI (sign_extend:HI (match_dup 1))
1814 (zero_extend:HI (match_dup 4)))))]
1816 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1819 ;******************************************************************************
1820 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1821 ;******************************************************************************
1823 ;; "*muluqihi3.uconst"
1824 ;; "*mulsqihi3.sconst"
1825 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1826 [(set (match_operand:HI 0 "register_operand" "=r")
1827 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1828 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1829 (clobber (match_scratch:QI 3 "=&d"))]
1832 "&& reload_completed"
1835 ; umulqihi3 resp. mulqihi3
1837 (mult:HI (any_extend:HI (match_dup 1))
1838 (any_extend:HI (match_dup 3))))]
1840 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1843 (define_insn_and_split "*muluqihi3.sconst"
1844 [(set (match_operand:HI 0 "register_operand" "=r")
1845 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1846 (match_operand:HI 2 "s8_operand" "n")))
1847 (clobber (match_scratch:QI 3 "=&a"))]
1850 "&& reload_completed"
1855 (mult:HI (zero_extend:HI (match_dup 1))
1856 (sign_extend:HI (match_dup 3))))]
1858 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1861 (define_insn_and_split "*mulsqihi3.uconst"
1862 [(set (match_operand:HI 0 "register_operand" "=r")
1863 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1864 (match_operand:HI 2 "u8_operand" "M")))
1865 (clobber (match_scratch:QI 3 "=&a"))]
1868 "&& reload_completed"
1873 (mult:HI (zero_extend:HI (match_dup 3))
1874 (sign_extend:HI (match_dup 1))))]
1876 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1879 (define_insn_and_split "*mulsqihi3.oconst"
1880 [(set (match_operand:HI 0 "register_operand" "=&r")
1881 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1882 (match_operand:HI 2 "o8_operand" "n")))
1883 (clobber (match_scratch:QI 3 "=&a"))]
1886 "&& reload_completed"
1891 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1892 (sign_extend:HI (match_dup 1))))]
1894 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1897 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1898 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1899 ;; at that time. Fix that.
1901 (define_insn "*ashiftqihi2.signx.1"
1902 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1903 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1907 lsl %A0\;sbc %B0,%B0
1908 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1909 [(set_attr "length" "2,3")
1910 (set_attr "cc" "clobber")])
1912 (define_insn_and_split "*ashifthi3.signx.const"
1913 [(set (match_operand:HI 0 "register_operand" "=r")
1914 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1915 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1916 (clobber (match_scratch:QI 3 "=&d"))]
1919 "&& reload_completed"
1924 (mult:HI (sign_extend:HI (match_dup 1))
1925 (sign_extend:HI (match_dup 3))))]
1927 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1930 (define_insn_and_split "*ashifthi3.signx.const7"
1931 [(set (match_operand:HI 0 "register_operand" "=r")
1932 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1934 (clobber (match_scratch:QI 2 "=&a"))]
1937 "&& reload_completed"
1942 (mult:HI (zero_extend:HI (match_dup 2))
1943 (sign_extend:HI (match_dup 1))))]
1945 operands[3] = gen_int_mode (1 << 7, QImode);
1948 (define_insn_and_split "*ashifthi3.zerox.const"
1949 [(set (match_operand:HI 0 "register_operand" "=r")
1950 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1951 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1952 (clobber (match_scratch:QI 3 "=&d"))]
1955 "&& reload_completed"
1960 (mult:HI (zero_extend:HI (match_dup 1))
1961 (zero_extend:HI (match_dup 3))))]
1963 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1966 ;******************************************************************************
1967 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1968 ;******************************************************************************
1970 (define_insn "mulsqihi3"
1971 [(set (match_operand:HI 0 "register_operand" "=&r")
1972 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1973 (match_operand:HI 2 "register_operand" "a")))]
1980 [(set_attr "length" "5")
1981 (set_attr "cc" "clobber")])
1983 (define_insn "muluqihi3"
1984 [(set (match_operand:HI 0 "register_operand" "=&r")
1985 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1986 (match_operand:HI 2 "register_operand" "r")))]
1993 [(set_attr "length" "5")
1994 (set_attr "cc" "clobber")])
1996 ;; one-extend operand 1
1998 (define_insn "muloqihi3"
1999 [(set (match_operand:HI 0 "register_operand" "=&r")
2000 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2001 (match_operand:HI 2 "register_operand" "r")))]
2009 [(set_attr "length" "6")
2010 (set_attr "cc" "clobber")])
2012 ;******************************************************************************
2014 (define_expand "mulhi3"
2015 [(set (match_operand:HI 0 "register_operand" "")
2016 (mult:HI (match_operand:HI 1 "register_operand" "")
2017 (match_operand:HI 2 "register_or_s9_operand" "")))]
2022 if (!register_operand (operands[2], HImode))
2023 operands[2] = force_reg (HImode, operands[2]);
2025 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2029 /* For small constants we can do better by extending them on the fly.
2030 The constant can be loaded in one instruction and the widening
2031 multiplication is shorter. First try the unsigned variant because it
2032 allows constraint "d" instead of "a" for the signed version. */
2034 if (s9_operand (operands[2], HImode))
2036 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2038 if (u8_operand (operands[2], HImode))
2040 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2042 else if (s8_operand (operands[2], HImode))
2044 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2048 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2054 if (!register_operand (operands[2], HImode))
2055 operands[2] = force_reg (HImode, operands[2]);
2058 (define_insn "*mulhi3_enh"
2059 [(set (match_operand:HI 0 "register_operand" "=&r")
2060 (mult:HI (match_operand:HI 1 "register_operand" "r")
2061 (match_operand:HI 2 "register_operand" "r")))]
2064 return REGNO (operands[1]) == REGNO (operands[2])
2065 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2066 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2068 [(set_attr "length" "7")
2069 (set_attr "cc" "clobber")])
2071 (define_expand "mulhi3_call"
2072 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2073 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2074 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2075 (clobber (reg:HI 22))
2076 (clobber (reg:QI 21))])
2077 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2081 (define_insn "*mulhi3_call"
2082 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2083 (clobber (reg:HI 22))
2084 (clobber (reg:QI 21))]
2087 [(set_attr "type" "xcall")
2088 (set_attr "cc" "clobber")])
2090 ;; To support widening multiplication with constant we postpone
2091 ;; expanding to the implicit library call until post combine and
2092 ;; prior to register allocation. Clobber all hard registers that
2093 ;; might be used by the (widening) multiply until it is split and
2094 ;; it's final register footprint is worked out.
2096 (define_expand "mulsi3"
2097 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2098 (mult:SI (match_operand:SI 1 "register_operand" "")
2099 (match_operand:SI 2 "nonmemory_operand" "")))
2100 (clobber (reg:HI 26))
2101 (clobber (reg:DI 18))])]
2104 if (u16_operand (operands[2], SImode))
2106 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2107 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2111 if (o16_operand (operands[2], SImode))
2113 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2114 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2119 (define_insn_and_split "*mulsi3"
2120 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2121 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2122 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2123 (clobber (reg:HI 26))
2124 (clobber (reg:DI 18))]
2125 "AVR_HAVE_MUL && !reload_completed"
2126 { gcc_unreachable(); }
2132 (parallel [(set (reg:SI 22)
2133 (mult:SI (reg:SI 22)
2135 (clobber (reg:HI 26))])
2139 if (u16_operand (operands[2], SImode))
2141 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2142 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2146 if (o16_operand (operands[2], SImode))
2148 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2149 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2156 (define_insn_and_split "mulu<mode>si3"
2157 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2158 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2159 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2160 (clobber (reg:HI 26))
2161 (clobber (reg:DI 18))]
2162 "AVR_HAVE_MUL && !reload_completed"
2163 { gcc_unreachable(); }
2170 (mult:SI (zero_extend:SI (reg:HI 26))
2175 /* Do the QI -> HI extension explicitely before the multiplication. */
2176 /* Do the HI -> SI extension implicitely and after the multiplication. */
2178 if (QImode == <MODE>mode)
2179 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2181 if (u16_operand (operands[2], SImode))
2183 operands[1] = force_reg (HImode, operands[1]);
2184 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2185 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2192 (define_insn_and_split "muls<mode>si3"
2193 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2194 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2195 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2196 (clobber (reg:HI 26))
2197 (clobber (reg:DI 18))]
2198 "AVR_HAVE_MUL && !reload_completed"
2199 { gcc_unreachable(); }
2206 (mult:SI (sign_extend:SI (reg:HI 26))
2211 /* Do the QI -> HI extension explicitely before the multiplication. */
2212 /* Do the HI -> SI extension implicitely and after the multiplication. */
2214 if (QImode == <MODE>mode)
2215 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2217 if (u16_operand (operands[2], SImode)
2218 || s16_operand (operands[2], SImode))
2220 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2222 operands[1] = force_reg (HImode, operands[1]);
2224 if (u16_operand (operands[2], SImode))
2225 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2227 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2233 ;; One-extend operand 1
2235 (define_insn_and_split "mulohisi3"
2236 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2237 (mult:SI (not:SI (zero_extend:SI
2238 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2239 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2240 (clobber (reg:HI 26))
2241 (clobber (reg:DI 18))]
2242 "AVR_HAVE_MUL && !reload_completed"
2243 { gcc_unreachable(); }
2250 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2258 (define_expand "<extend_u>mulhisi3"
2259 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2260 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2261 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2262 (clobber (reg:HI 26))
2263 (clobber (reg:DI 18))])]
2267 (define_expand "usmulhisi3"
2268 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2269 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2270 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2271 (clobber (reg:HI 26))
2272 (clobber (reg:DI 18))])]
2276 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2277 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2278 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2279 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2280 (define_insn_and_split
2281 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2282 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2283 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2284 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2285 (clobber (reg:HI 26))
2286 (clobber (reg:DI 18))]
2287 "AVR_HAVE_MUL && !reload_completed"
2288 { gcc_unreachable(); }
2295 (mult:SI (match_dup 3)
2300 rtx xop1 = operands[1];
2301 rtx xop2 = operands[2];
2303 /* Do the QI -> HI extension explicitely before the multiplication. */
2304 /* Do the HI -> SI extension implicitely and after the multiplication. */
2306 if (QImode == <QIHI:MODE>mode)
2307 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2309 if (QImode == <QIHI2:MODE>mode)
2310 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2312 if (<any_extend:CODE> == <any_extend2:CODE>
2313 || <any_extend:CODE> == ZERO_EXTEND)
2317 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2318 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2322 /* <any_extend:CODE> = SIGN_EXTEND */
2323 /* <any_extend2:CODE> = ZERO_EXTEND */
2327 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2328 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2332 ;; "smulhi3_highpart"
2333 ;; "umulhi3_highpart"
2334 (define_expand "<extend_su>mulhi3_highpart"
2336 (match_operand:HI 1 "nonmemory_operand" ""))
2338 (match_operand:HI 2 "nonmemory_operand" ""))
2339 (parallel [(set (reg:HI 24)
2340 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2341 (any_extend:SI (reg:HI 26)))
2343 (clobber (reg:HI 22))])
2344 (set (match_operand:HI 0 "register_operand" "")
2350 (define_insn "*mulsi3_call"
2352 (mult:SI (reg:SI 22)
2354 (clobber (reg:HI 26))]
2357 [(set_attr "type" "xcall")
2358 (set_attr "cc" "clobber")])
2361 ;; "*umulhisi3_call"
2362 (define_insn "*<extend_u>mulhisi3_call"
2364 (mult:SI (any_extend:SI (reg:HI 18))
2365 (any_extend:SI (reg:HI 26))))]
2367 "%~call __<extend_u>mulhisi3"
2368 [(set_attr "type" "xcall")
2369 (set_attr "cc" "clobber")])
2371 ;; "*umulhi3_highpart_call"
2372 ;; "*smulhi3_highpart_call"
2373 (define_insn "*<extend_su>mulhi3_highpart_call"
2375 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2376 (any_extend:SI (reg:HI 26)))
2378 (clobber (reg:HI 22))]
2380 "%~call __<extend_u>mulhisi3"
2381 [(set_attr "type" "xcall")
2382 (set_attr "cc" "clobber")])
2384 (define_insn "*usmulhisi3_call"
2386 (mult:SI (zero_extend:SI (reg:HI 18))
2387 (sign_extend:SI (reg:HI 26))))]
2389 "%~call __usmulhisi3"
2390 [(set_attr "type" "xcall")
2391 (set_attr "cc" "clobber")])
2393 (define_insn "*mul<extend_su>hisi3_call"
2395 (mult:SI (any_extend:SI (reg:HI 26))
2398 "%~call __mul<extend_su>hisi3"
2399 [(set_attr "type" "xcall")
2400 (set_attr "cc" "clobber")])
2402 (define_insn "*mulohisi3_call"
2404 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2407 "%~call __mulohisi3"
2408 [(set_attr "type" "xcall")
2409 (set_attr "cc" "clobber")])
2411 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2414 ;; Generate lib1funcs.S calls ourselves, because:
2415 ;; - we know exactly which registers are clobbered (for QI and HI
2416 ;; modes, some of the call-used registers are preserved)
2417 ;; - we get both the quotient and the remainder at no extra cost
2418 ;; - we split the patterns only after the first CSE passes because
2419 ;; CSE has problems to operate on hard regs.
2421 (define_insn_and_split "divmodqi4"
2422 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2423 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2424 (match_operand:QI 2 "pseudo_register_operand" "")))
2425 (set (match_operand:QI 3 "pseudo_register_operand" "")
2426 (mod:QI (match_dup 1) (match_dup 2)))
2427 (clobber (reg:QI 22))
2428 (clobber (reg:QI 23))
2429 (clobber (reg:QI 24))
2430 (clobber (reg:QI 25))])]
2432 "this divmodqi4 pattern should have been splitted;"
2434 [(set (reg:QI 24) (match_dup 1))
2435 (set (reg:QI 22) (match_dup 2))
2436 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2437 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2438 (clobber (reg:QI 22))
2439 (clobber (reg:QI 23))])
2440 (set (match_dup 0) (reg:QI 24))
2441 (set (match_dup 3) (reg:QI 25))]
2444 (define_insn "*divmodqi4_call"
2445 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2446 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2447 (clobber (reg:QI 22))
2448 (clobber (reg:QI 23))]
2450 "%~call __divmodqi4"
2451 [(set_attr "type" "xcall")
2452 (set_attr "cc" "clobber")])
2454 (define_insn_and_split "udivmodqi4"
2455 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2456 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2457 (match_operand:QI 2 "pseudo_register_operand" "")))
2458 (set (match_operand:QI 3 "pseudo_register_operand" "")
2459 (umod:QI (match_dup 1) (match_dup 2)))
2460 (clobber (reg:QI 22))
2461 (clobber (reg:QI 23))
2462 (clobber (reg:QI 24))
2463 (clobber (reg:QI 25))])]
2465 "this udivmodqi4 pattern should have been splitted;"
2467 [(set (reg:QI 24) (match_dup 1))
2468 (set (reg:QI 22) (match_dup 2))
2469 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2470 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2471 (clobber (reg:QI 23))])
2472 (set (match_dup 0) (reg:QI 24))
2473 (set (match_dup 3) (reg:QI 25))]
2476 (define_insn "*udivmodqi4_call"
2477 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2478 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2479 (clobber (reg:QI 23))]
2481 "%~call __udivmodqi4"
2482 [(set_attr "type" "xcall")
2483 (set_attr "cc" "clobber")])
2485 (define_insn_and_split "divmodhi4"
2486 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2487 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2488 (match_operand:HI 2 "pseudo_register_operand" "")))
2489 (set (match_operand:HI 3 "pseudo_register_operand" "")
2490 (mod:HI (match_dup 1) (match_dup 2)))
2491 (clobber (reg:QI 21))
2492 (clobber (reg:HI 22))
2493 (clobber (reg:HI 24))
2494 (clobber (reg:HI 26))])]
2496 "this should have been splitted;"
2498 [(set (reg:HI 24) (match_dup 1))
2499 (set (reg:HI 22) (match_dup 2))
2500 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2501 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2502 (clobber (reg:HI 26))
2503 (clobber (reg:QI 21))])
2504 (set (match_dup 0) (reg:HI 22))
2505 (set (match_dup 3) (reg:HI 24))]
2508 (define_insn "*divmodhi4_call"
2509 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2510 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2511 (clobber (reg:HI 26))
2512 (clobber (reg:QI 21))]
2514 "%~call __divmodhi4"
2515 [(set_attr "type" "xcall")
2516 (set_attr "cc" "clobber")])
2518 (define_insn_and_split "udivmodhi4"
2519 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2520 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2521 (match_operand:HI 2 "pseudo_register_operand" "")))
2522 (set (match_operand:HI 3 "pseudo_register_operand" "")
2523 (umod:HI (match_dup 1) (match_dup 2)))
2524 (clobber (reg:QI 21))
2525 (clobber (reg:HI 22))
2526 (clobber (reg:HI 24))
2527 (clobber (reg:HI 26))])]
2529 "this udivmodhi4 pattern should have been splitted.;"
2531 [(set (reg:HI 24) (match_dup 1))
2532 (set (reg:HI 22) (match_dup 2))
2533 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2534 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2535 (clobber (reg:HI 26))
2536 (clobber (reg:QI 21))])
2537 (set (match_dup 0) (reg:HI 22))
2538 (set (match_dup 3) (reg:HI 24))]
2541 (define_insn "*udivmodhi4_call"
2542 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2543 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2544 (clobber (reg:HI 26))
2545 (clobber (reg:QI 21))]
2547 "%~call __udivmodhi4"
2548 [(set_attr "type" "xcall")
2549 (set_attr "cc" "clobber")])
2551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2554 ;; To support widening multiplication with constant we postpone
2555 ;; expanding to the implicit library call until post combine and
2556 ;; prior to register allocation. Clobber all hard registers that
2557 ;; might be used by the (widening) multiply until it is split and
2558 ;; it's final register footprint is worked out.
2560 (define_expand "mulpsi3"
2561 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2562 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2563 (match_operand:PSI 2 "nonmemory_operand" "")))
2564 (clobber (reg:HI 26))
2565 (clobber (reg:DI 18))])]
2568 if (s8_operand (operands[2], PSImode))
2570 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2571 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2576 (define_insn "*umulqihipsi3"
2577 [(set (match_operand:PSI 0 "register_operand" "=&r")
2578 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2579 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2588 [(set_attr "length" "7")
2589 (set_attr "cc" "clobber")])
2591 (define_insn "*umulhiqipsi3"
2592 [(set (match_operand:PSI 0 "register_operand" "=&r")
2593 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2594 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2602 adc %C0,__zero_reg__"
2603 [(set_attr "length" "7")
2604 (set_attr "cc" "clobber")])
2606 (define_insn_and_split "mulsqipsi3"
2607 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2608 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2609 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2610 (clobber (reg:HI 26))
2611 (clobber (reg:DI 18))]
2612 "AVR_HAVE_MUL && !reload_completed"
2613 { gcc_unreachable(); }
2620 (mult:PSI (sign_extend:PSI (reg:QI 25))
2625 (define_insn_and_split "*mulpsi3"
2626 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2627 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2628 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2629 (clobber (reg:HI 26))
2630 (clobber (reg:DI 18))]
2631 "AVR_HAVE_MUL && !reload_completed"
2632 { gcc_unreachable(); }
2638 (parallel [(set (reg:PSI 22)
2639 (mult:PSI (reg:PSI 22)
2641 (clobber (reg:QI 21))
2642 (clobber (reg:QI 25))
2643 (clobber (reg:HI 26))])
2647 if (s8_operand (operands[2], PSImode))
2649 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2650 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2655 (define_insn "*mulsqipsi3.libgcc"
2657 (mult:PSI (sign_extend:PSI (reg:QI 25))
2660 "%~call __mulsqipsi3"
2661 [(set_attr "type" "xcall")
2662 (set_attr "cc" "clobber")])
2664 (define_insn "*mulpsi3.libgcc"
2666 (mult:PSI (reg:PSI 22)
2668 (clobber (reg:QI 21))
2669 (clobber (reg:QI 25))
2670 (clobber (reg:HI 26))]
2673 [(set_attr "type" "xcall")
2674 (set_attr "cc" "clobber")])
2677 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2678 ;; 24-bit signed/unsigned division and modulo.
2679 ;; Notice that the libgcc implementation return the quotient in R22
2680 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2681 ;; implementation works the other way round.
2683 (define_insn_and_split "divmodpsi4"
2684 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2685 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2686 (match_operand:PSI 2 "pseudo_register_operand" "")))
2687 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2688 (mod:PSI (match_dup 1)
2690 (clobber (reg:DI 18))
2691 (clobber (reg:QI 26))])]
2693 { gcc_unreachable(); }
2695 [(set (reg:PSI 22) (match_dup 1))
2696 (set (reg:PSI 18) (match_dup 2))
2697 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2698 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2699 (clobber (reg:QI 21))
2700 (clobber (reg:QI 25))
2701 (clobber (reg:QI 26))])
2702 (set (match_dup 0) (reg:PSI 22))
2703 (set (match_dup 3) (reg:PSI 18))])
2705 (define_insn "*divmodpsi4_call"
2706 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2707 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2708 (clobber (reg:QI 21))
2709 (clobber (reg:QI 25))
2710 (clobber (reg:QI 26))]
2712 "%~call __divmodpsi4"
2713 [(set_attr "type" "xcall")
2714 (set_attr "cc" "clobber")])
2716 (define_insn_and_split "udivmodpsi4"
2717 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2718 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2719 (match_operand:PSI 2 "pseudo_register_operand" "")))
2720 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2721 (umod:PSI (match_dup 1)
2723 (clobber (reg:DI 18))
2724 (clobber (reg:QI 26))])]
2726 { gcc_unreachable(); }
2728 [(set (reg:PSI 22) (match_dup 1))
2729 (set (reg:PSI 18) (match_dup 2))
2730 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2731 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2732 (clobber (reg:QI 21))
2733 (clobber (reg:QI 25))
2734 (clobber (reg:QI 26))])
2735 (set (match_dup 0) (reg:PSI 22))
2736 (set (match_dup 3) (reg:PSI 18))])
2738 (define_insn "*udivmodpsi4_call"
2739 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2740 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2741 (clobber (reg:QI 21))
2742 (clobber (reg:QI 25))
2743 (clobber (reg:QI 26))]
2745 "%~call __udivmodpsi4"
2746 [(set_attr "type" "xcall")
2747 (set_attr "cc" "clobber")])
2749 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2751 (define_insn_and_split "divmodsi4"
2752 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2753 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2754 (match_operand:SI 2 "pseudo_register_operand" "")))
2755 (set (match_operand:SI 3 "pseudo_register_operand" "")
2756 (mod:SI (match_dup 1) (match_dup 2)))
2757 (clobber (reg:SI 18))
2758 (clobber (reg:SI 22))
2759 (clobber (reg:HI 26))
2760 (clobber (reg:HI 30))])]
2762 "this divmodsi4 pattern should have been splitted;"
2764 [(set (reg:SI 22) (match_dup 1))
2765 (set (reg:SI 18) (match_dup 2))
2766 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2767 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2768 (clobber (reg:HI 26))
2769 (clobber (reg:HI 30))])
2770 (set (match_dup 0) (reg:SI 18))
2771 (set (match_dup 3) (reg:SI 22))]
2774 (define_insn "*divmodsi4_call"
2775 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2776 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2777 (clobber (reg:HI 26))
2778 (clobber (reg:HI 30))]
2780 "%~call __divmodsi4"
2781 [(set_attr "type" "xcall")
2782 (set_attr "cc" "clobber")])
2784 (define_insn_and_split "udivmodsi4"
2785 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2786 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2787 (match_operand:SI 2 "pseudo_register_operand" "")))
2788 (set (match_operand:SI 3 "pseudo_register_operand" "")
2789 (umod:SI (match_dup 1) (match_dup 2)))
2790 (clobber (reg:SI 18))
2791 (clobber (reg:SI 22))
2792 (clobber (reg:HI 26))
2793 (clobber (reg:HI 30))])]
2795 "this udivmodsi4 pattern should have been splitted;"
2797 [(set (reg:SI 22) (match_dup 1))
2798 (set (reg:SI 18) (match_dup 2))
2799 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2800 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2801 (clobber (reg:HI 26))
2802 (clobber (reg:HI 30))])
2803 (set (match_dup 0) (reg:SI 18))
2804 (set (match_dup 3) (reg:SI 22))]
2807 (define_insn "*udivmodsi4_call"
2808 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2809 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2810 (clobber (reg:HI 26))
2811 (clobber (reg:HI 30))]
2813 "%~call __udivmodsi4"
2814 [(set_attr "type" "xcall")
2815 (set_attr "cc" "clobber")])
2817 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2820 (define_insn "andqi3"
2821 [(set (match_operand:QI 0 "register_operand" "=r,d")
2822 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2823 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2828 [(set_attr "length" "1,1")
2829 (set_attr "cc" "set_zn,set_zn")])
2831 (define_insn "andhi3"
2832 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2833 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2834 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2835 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2838 if (which_alternative == 0)
2839 return "and %A0,%A2\;and %B0,%B2";
2840 else if (which_alternative == 1)
2841 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2843 return avr_out_bitop (insn, operands, NULL);
2845 [(set_attr "length" "2,2,2,4,4")
2846 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2847 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2849 (define_insn "andpsi3"
2850 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2851 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2852 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2853 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2856 if (which_alternative == 0)
2857 return "and %A0,%A2" CR_TAB
2858 "and %B0,%B2" CR_TAB
2861 return avr_out_bitop (insn, operands, NULL);
2863 [(set_attr "length" "3,3,6,6")
2864 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2865 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2867 (define_insn "andsi3"
2868 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2869 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2870 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2871 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2874 if (which_alternative == 0)
2875 return "and %0,%2" CR_TAB
2876 "and %B0,%B2" CR_TAB
2877 "and %C0,%C2" CR_TAB
2880 return avr_out_bitop (insn, operands, NULL);
2882 [(set_attr "length" "4,4,8,8")
2883 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2884 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2886 (define_peephole2 ; andi
2887 [(set (match_operand:QI 0 "d_register_operand" "")
2888 (and:QI (match_dup 0)
2889 (match_operand:QI 1 "const_int_operand" "")))
2891 (and:QI (match_dup 0)
2892 (match_operand:QI 2 "const_int_operand" "")))]
2894 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2896 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2899 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2902 (define_insn "iorqi3"
2903 [(set (match_operand:QI 0 "register_operand" "=r,d")
2904 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2905 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2910 [(set_attr "length" "1,1")
2911 (set_attr "cc" "set_zn,set_zn")])
2913 (define_insn "iorhi3"
2914 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2915 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2916 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2917 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2920 if (which_alternative == 0)
2921 return "or %A0,%A2\;or %B0,%B2";
2922 else if (which_alternative == 1)
2923 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
2925 return avr_out_bitop (insn, operands, NULL);
2927 [(set_attr "length" "2,2,2,4,4")
2928 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2929 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2931 (define_insn "iorpsi3"
2932 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2933 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2934 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
2935 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2938 if (which_alternative == 0)
2939 return "or %A0,%A2" CR_TAB
2943 return avr_out_bitop (insn, operands, NULL);
2945 [(set_attr "length" "3,3,6,6")
2946 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2947 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2949 (define_insn "iorsi3"
2950 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2951 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2952 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2953 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2956 if (which_alternative == 0)
2957 return "or %0,%2" CR_TAB
2962 return avr_out_bitop (insn, operands, NULL);
2964 [(set_attr "length" "4,4,8,8")
2965 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2966 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2968 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2971 (define_insn "xorqi3"
2972 [(set (match_operand:QI 0 "register_operand" "=r")
2973 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2974 (match_operand:QI 2 "register_operand" "r")))]
2977 [(set_attr "length" "1")
2978 (set_attr "cc" "set_zn")])
2980 (define_insn "xorhi3"
2981 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
2982 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
2983 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
2984 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2987 if (which_alternative == 0)
2988 return "eor %A0,%A2\;eor %B0,%B2";
2990 return avr_out_bitop (insn, operands, NULL);
2992 [(set_attr "length" "2,2,4")
2993 (set_attr "adjust_len" "*,out_bitop,out_bitop")
2994 (set_attr "cc" "set_n,clobber,clobber")])
2996 (define_insn "xorpsi3"
2997 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
2998 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
2999 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3000 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3003 if (which_alternative == 0)
3004 return "eor %A0,%A2" CR_TAB
3005 "eor %B0,%B2" CR_TAB
3008 return avr_out_bitop (insn, operands, NULL);
3010 [(set_attr "length" "3,6,6")
3011 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3012 (set_attr "cc" "set_n,clobber,clobber")])
3014 (define_insn "xorsi3"
3015 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3016 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3017 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3018 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3021 if (which_alternative == 0)
3022 return "eor %0,%2" CR_TAB
3023 "eor %B0,%B2" CR_TAB
3024 "eor %C0,%C2" CR_TAB
3027 return avr_out_bitop (insn, operands, NULL);
3029 [(set_attr "length" "4,8,8")
3030 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3031 (set_attr "cc" "set_n,clobber,clobber")])
3033 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3036 (define_expand "rotlqi3"
3037 [(set (match_operand:QI 0 "register_operand" "")
3038 (rotate:QI (match_operand:QI 1 "register_operand" "")
3039 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3042 if (!CONST_INT_P (operands[2]))
3045 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3048 ;; Expander used by __builtin_avr_swap
3049 (define_expand "rotlqi3_4"
3050 [(set (match_operand:QI 0 "register_operand" "")
3051 (rotate:QI (match_operand:QI 1 "register_operand" "")
3054 (define_insn "*rotlqi3"
3055 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3056 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3057 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3060 lsl %0\;adc %0,__zero_reg__
3061 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3062 swap %0\;bst %0,0\;ror %0\;bld %0,7
3064 swap %0\;lsl %0\;adc %0,__zero_reg__
3065 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3066 bst %0,0\;ror %0\;bld %0,7
3068 [(set_attr "length" "2,4,4,1,3,5,3,0")
3069 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3071 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3072 ;; a whole number of bytes. The split creates the appropriate moves and
3073 ;; considers all overlap situations.
3075 ;; HImode does not need scratch. Use attribute for this constraint.
3077 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3078 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3083 (define_expand "rotl<mode>3"
3084 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3085 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3086 (match_operand:VOID 2 "const_int_operand" "")))
3087 (clobber (match_dup 3))])]
3092 if (!CONST_INT_P (operands[2]))
3095 offset = INTVAL (operands[2]);
3097 if (0 == offset % 8)
3099 if (AVR_HAVE_MOVW && 0 == offset % 16)
3100 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3102 operands[3] = gen_rtx_SCRATCH (QImode);
3104 else if (offset == 1
3105 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3107 /*; Support rotate left/right by 1 */
3109 emit_move_insn (operands[0],
3110 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3117 (define_insn "*rotlhi2.1"
3118 [(set (match_operand:HI 0 "register_operand" "=r")
3119 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3122 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3123 [(set_attr "length" "3")
3124 (set_attr "cc" "clobber")])
3126 (define_insn "*rotlhi2.15"
3127 [(set (match_operand:HI 0 "register_operand" "=r")
3128 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3131 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3132 [(set_attr "length" "4")
3133 (set_attr "cc" "clobber")])
3135 (define_insn "*rotlpsi2.1"
3136 [(set (match_operand:PSI 0 "register_operand" "=r")
3137 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3140 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3141 [(set_attr "length" "4")
3142 (set_attr "cc" "clobber")])
3144 (define_insn "*rotlpsi2.23"
3145 [(set (match_operand:PSI 0 "register_operand" "=r")
3146 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3149 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3150 [(set_attr "length" "5")
3151 (set_attr "cc" "clobber")])
3153 (define_insn "*rotlsi2.1"
3154 [(set (match_operand:SI 0 "register_operand" "=r")
3155 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3158 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3159 [(set_attr "length" "5")
3160 (set_attr "cc" "clobber")])
3162 (define_insn "*rotlsi2.31"
3163 [(set (match_operand:SI 0 "register_operand" "=r")
3164 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3167 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3168 [(set_attr "length" "6")
3169 (set_attr "cc" "clobber")])
3171 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3172 ;; The best we can do is use early clobber alternative "#&r" so that
3173 ;; completely non-overlapping operands dont get a scratch but # so register
3174 ;; allocation does not prefer non-overlapping.
3177 ;; Split word aligned rotates using scratch that is mode dependent.
3181 (define_insn_and_split "*rotw<mode>"
3182 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3183 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3184 (match_operand 2 "const_int_operand" "n,n,n")))
3185 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3187 && CONST_INT_P (operands[2])
3188 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3189 && 0 == INTVAL (operands[2]) % 16"
3191 "&& reload_completed"
3194 avr_rotate_bytes (operands);
3199 ;; Split byte aligned rotates using scratch that is always QI mode.
3204 (define_insn_and_split "*rotb<mode>"
3205 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3206 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3207 (match_operand 2 "const_int_operand" "n,n,n")))
3208 (clobber (match_scratch:QI 3 "=<rotx>"))]
3209 "CONST_INT_P (operands[2])
3210 && (8 == INTVAL (operands[2]) % 16
3212 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3213 && 0 == INTVAL (operands[2]) % 16))"
3215 "&& reload_completed"
3218 avr_rotate_bytes (operands);
3223 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3224 ;; arithmetic shift left
3226 (define_expand "ashlqi3"
3227 [(set (match_operand:QI 0 "register_operand" "")
3228 (ashift:QI (match_operand:QI 1 "register_operand" "")
3229 (match_operand:QI 2 "nop_general_operand" "")))])
3231 (define_split ; ashlqi3_const4
3232 [(set (match_operand:QI 0 "d_register_operand" "")
3233 (ashift:QI (match_dup 0)
3236 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3237 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
3240 (define_split ; ashlqi3_const5
3241 [(set (match_operand:QI 0 "d_register_operand" "")
3242 (ashift:QI (match_dup 0)
3245 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3246 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3247 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
3250 (define_split ; ashlqi3_const6
3251 [(set (match_operand:QI 0 "d_register_operand" "")
3252 (ashift:QI (match_dup 0)
3255 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3256 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3257 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
3260 (define_insn "*ashlqi3"
3261 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3262 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3263 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3266 return ashlqi3_out (insn, operands, NULL);
3268 [(set_attr "length" "5,0,1,2,4,6,9")
3269 (set_attr "adjust_len" "ashlqi")
3270 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3272 (define_insn "ashlhi3"
3273 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3274 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3275 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3278 return ashlhi3_out (insn, operands, NULL);
3280 [(set_attr "length" "6,0,2,2,4,10,10")
3281 (set_attr "adjust_len" "ashlhi")
3282 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3285 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3286 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3290 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3291 [(set (match_operand:QI 0 "register_operand" "=r")
3292 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3293 (match_operand:QI 2 "register_operand" "r"))
3299 (ashift:QI (match_dup 1)
3303 ;; ??? Combiner does not recognize that it could split the following insn;
3304 ;; presumably because he has no register handy?
3306 ;; "*ashluqihiqi3.mem"
3307 ;; "*ashlsqihiqi3.mem"
3308 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3309 [(set (match_operand:QI 0 "memory_operand" "=m")
3310 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3311 (match_operand:QI 2 "register_operand" "r"))
3314 { gcc_unreachable(); }
3317 (ashift:QI (match_dup 1)
3322 operands[3] = gen_reg_rtx (QImode);
3327 (define_insn_and_split "*ashlhiqi3"
3328 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3329 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3330 (match_operand:QI 2 "register_operand" "r")) 0))]
3332 { gcc_unreachable(); }
3335 (ashift:QI (match_dup 3)
3340 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3341 operands[4] = gen_reg_rtx (QImode);
3344 ;; High part of 16-bit shift is unused after the instruction:
3345 ;; No need to compute it, map to 8-bit shift.
3348 [(set (match_operand:HI 0 "register_operand" "")
3349 (ashift:HI (match_dup 0)
3350 (match_operand:QI 1 "register_operand" "")))]
3353 (ashift:QI (match_dup 2)
3355 (clobber (match_dup 3))]
3357 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3359 if (!peep2_reg_dead_p (1, operands[3]))
3362 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3366 (define_insn "ashlsi3"
3367 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3368 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3369 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3372 return ashlsi3_out (insn, operands, NULL);
3374 [(set_attr "length" "8,0,4,4,8,10,12")
3375 (set_attr "adjust_len" "ashlsi")
3376 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3378 ;; Optimize if a scratch register from LD_REGS happens to be available.
3380 (define_peephole2 ; ashlqi3_l_const4
3381 [(set (match_operand:QI 0 "l_register_operand" "")
3382 (ashift:QI (match_dup 0)
3384 (match_scratch:QI 1 "d")]
3386 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3387 (set (match_dup 1) (const_int -16))
3388 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3391 (define_peephole2 ; ashlqi3_l_const5
3392 [(set (match_operand:QI 0 "l_register_operand" "")
3393 (ashift:QI (match_dup 0)
3395 (match_scratch:QI 1 "d")]
3397 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3398 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3399 (set (match_dup 1) (const_int -32))
3400 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3403 (define_peephole2 ; ashlqi3_l_const6
3404 [(set (match_operand:QI 0 "l_register_operand" "")
3405 (ashift:QI (match_dup 0)
3407 (match_scratch:QI 1 "d")]
3409 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3410 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3411 (set (match_dup 1) (const_int -64))
3412 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3416 [(match_scratch:QI 3 "d")
3417 (set (match_operand:HI 0 "register_operand" "")
3418 (ashift:HI (match_operand:HI 1 "register_operand" "")
3419 (match_operand:QI 2 "const_int_operand" "")))]
3421 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3422 (clobber (match_dup 3))])]
3425 (define_insn "*ashlhi3_const"
3426 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3427 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3428 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3429 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3432 return ashlhi3_out (insn, operands, NULL);
3434 [(set_attr "length" "0,2,2,4,10")
3435 (set_attr "adjust_len" "ashlhi")
3436 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3439 [(match_scratch:QI 3 "d")
3440 (set (match_operand:SI 0 "register_operand" "")
3441 (ashift:SI (match_operand:SI 1 "register_operand" "")
3442 (match_operand:QI 2 "const_int_operand" "")))]
3444 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3445 (clobber (match_dup 3))])]
3448 (define_insn "*ashlsi3_const"
3449 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3450 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3451 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3452 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3455 return ashlsi3_out (insn, operands, NULL);
3457 [(set_attr "length" "0,4,4,10")
3458 (set_attr "adjust_len" "ashlsi")
3459 (set_attr "cc" "none,set_n,clobber,clobber")])
3461 (define_expand "ashlpsi3"
3462 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3463 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3464 (match_operand:QI 2 "nonmemory_operand" "")))
3465 (clobber (scratch:QI))])]
3469 && CONST_INT_P (operands[2]))
3471 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3473 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3474 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3477 else if (optimize_insn_for_speed_p ()
3478 && INTVAL (operands[2]) != 16
3479 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3481 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3482 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3488 (define_insn "*ashlpsi3"
3489 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3490 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3491 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3492 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3495 return avr_out_ashlpsi3 (insn, operands, NULL);
3497 [(set_attr "adjust_len" "ashlpsi")
3498 (set_attr "cc" "clobber")])
3500 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3501 ;; arithmetic shift right
3503 (define_insn "ashrqi3"
3504 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3505 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3506 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3509 return ashrqi3_out (insn, operands, NULL);
3511 [(set_attr "length" "5,0,1,2,5,4,9")
3512 (set_attr "adjust_len" "ashrqi")
3513 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3515 (define_insn "ashrhi3"
3516 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3517 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3518 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3521 return ashrhi3_out (insn, operands, NULL);
3523 [(set_attr "length" "6,0,2,4,4,10,10")
3524 (set_attr "adjust_len" "ashrhi")
3525 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3527 (define_insn "ashrpsi3"
3528 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3529 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3530 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3531 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3534 return avr_out_ashrpsi3 (insn, operands, NULL);
3536 [(set_attr "adjust_len" "ashrpsi")
3537 (set_attr "cc" "clobber")])
3539 (define_insn "ashrsi3"
3540 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3541 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3542 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3545 return ashrsi3_out (insn, operands, NULL);
3547 [(set_attr "length" "8,0,4,6,8,10,12")
3548 (set_attr "adjust_len" "ashrsi")
3549 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3551 ;; Optimize if a scratch register from LD_REGS happens to be available.
3554 [(match_scratch:QI 3 "d")
3555 (set (match_operand:HI 0 "register_operand" "")
3556 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3557 (match_operand:QI 2 "const_int_operand" "")))]
3559 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3560 (clobber (match_dup 3))])]
3563 (define_insn "*ashrhi3_const"
3564 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3565 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3566 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3567 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3570 return ashrhi3_out (insn, operands, NULL);
3572 [(set_attr "length" "0,2,4,4,10")
3573 (set_attr "adjust_len" "ashrhi")
3574 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3577 [(match_scratch:QI 3 "d")
3578 (set (match_operand:SI 0 "register_operand" "")
3579 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3580 (match_operand:QI 2 "const_int_operand" "")))]
3582 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3583 (clobber (match_dup 3))])]
3586 (define_insn "*ashrsi3_const"
3587 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3588 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3589 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3590 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3593 return ashrsi3_out (insn, operands, NULL);
3595 [(set_attr "length" "0,4,4,10")
3596 (set_attr "adjust_len" "ashrsi")
3597 (set_attr "cc" "none,clobber,set_n,clobber")])
3599 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3600 ;; logical shift right
3602 (define_expand "lshrqi3"
3603 [(set (match_operand:QI 0 "register_operand" "")
3604 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3605 (match_operand:QI 2 "nop_general_operand" "")))])
3607 (define_split ; lshrqi3_const4
3608 [(set (match_operand:QI 0 "d_register_operand" "")
3609 (lshiftrt:QI (match_dup 0)
3612 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3613 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3616 (define_split ; lshrqi3_const5
3617 [(set (match_operand:QI 0 "d_register_operand" "")
3618 (lshiftrt:QI (match_dup 0)
3621 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3622 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3623 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3626 (define_split ; lshrqi3_const6
3627 [(set (match_operand:QI 0 "d_register_operand" "")
3628 (lshiftrt:QI (match_dup 0)
3631 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3632 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3633 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3636 (define_insn "*lshrqi3"
3637 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3638 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3639 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3642 return lshrqi3_out (insn, operands, NULL);
3644 [(set_attr "length" "5,0,1,2,4,6,9")
3645 (set_attr "adjust_len" "lshrqi")
3646 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3648 (define_insn "lshrhi3"
3649 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3650 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3651 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3654 return lshrhi3_out (insn, operands, NULL);
3656 [(set_attr "length" "6,0,2,2,4,10,10")
3657 (set_attr "adjust_len" "lshrhi")
3658 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3660 (define_insn "lshrpsi3"
3661 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3662 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3663 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3664 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3667 return avr_out_lshrpsi3 (insn, operands, NULL);
3669 [(set_attr "adjust_len" "lshrpsi")
3670 (set_attr "cc" "clobber")])
3672 (define_insn "lshrsi3"
3673 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3674 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3675 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3678 return lshrsi3_out (insn, operands, NULL);
3680 [(set_attr "length" "8,0,4,4,8,10,12")
3681 (set_attr "adjust_len" "lshrsi")
3682 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3684 ;; Optimize if a scratch register from LD_REGS happens to be available.
3686 (define_peephole2 ; lshrqi3_l_const4
3687 [(set (match_operand:QI 0 "l_register_operand" "")
3688 (lshiftrt:QI (match_dup 0)
3690 (match_scratch:QI 1 "d")]
3692 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3693 (set (match_dup 1) (const_int 15))
3694 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3697 (define_peephole2 ; lshrqi3_l_const5
3698 [(set (match_operand:QI 0 "l_register_operand" "")
3699 (lshiftrt:QI (match_dup 0)
3701 (match_scratch:QI 1 "d")]
3703 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3704 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3705 (set (match_dup 1) (const_int 7))
3706 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3709 (define_peephole2 ; lshrqi3_l_const6
3710 [(set (match_operand:QI 0 "l_register_operand" "")
3711 (lshiftrt:QI (match_dup 0)
3713 (match_scratch:QI 1 "d")]
3715 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3716 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3717 (set (match_dup 1) (const_int 3))
3718 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3722 [(match_scratch:QI 3 "d")
3723 (set (match_operand:HI 0 "register_operand" "")
3724 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3725 (match_operand:QI 2 "const_int_operand" "")))]
3727 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3728 (clobber (match_dup 3))])]
3731 (define_insn "*lshrhi3_const"
3732 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3733 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3734 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3735 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3738 return lshrhi3_out (insn, operands, NULL);
3740 [(set_attr "length" "0,2,2,4,10")
3741 (set_attr "adjust_len" "lshrhi")
3742 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3745 [(match_scratch:QI 3 "d")
3746 (set (match_operand:SI 0 "register_operand" "")
3747 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3748 (match_operand:QI 2 "const_int_operand" "")))]
3750 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3751 (clobber (match_dup 3))])]
3754 (define_insn "*lshrsi3_const"
3755 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3756 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3757 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3758 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3761 return lshrsi3_out (insn, operands, NULL);
3763 [(set_attr "length" "0,4,4,10")
3764 (set_attr "adjust_len" "lshrsi")
3765 (set_attr "cc" "none,clobber,clobber,clobber")])
3767 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3770 (define_insn "absqi2"
3771 [(set (match_operand:QI 0 "register_operand" "=r")
3772 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3776 [(set_attr "length" "2")
3777 (set_attr "cc" "clobber")])
3780 (define_insn "abssf2"
3781 [(set (match_operand:SF 0 "register_operand" "=d,r")
3782 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3787 [(set_attr "length" "1,2")
3788 (set_attr "cc" "set_n,clobber")])
3790 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3793 (define_insn "negqi2"
3794 [(set (match_operand:QI 0 "register_operand" "=r")
3795 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3798 [(set_attr "length" "1")
3799 (set_attr "cc" "set_zn")])
3801 (define_insn "*negqihi2"
3802 [(set (match_operand:HI 0 "register_operand" "=r")
3803 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3805 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3806 [(set_attr "length" "4")
3807 (set_attr "cc" "set_n")])
3809 (define_insn "neghi2"
3810 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
3811 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
3814 com %B0\;neg %A0\;sbci %B0,lo8(-1)
3815 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
3816 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3817 [(set_attr "length" "3,4,4")
3818 (set_attr "cc" "set_czn,set_n,set_czn")])
3820 (define_insn "negpsi2"
3821 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3822 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3825 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3826 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3827 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3828 [(set_attr "length" "5,6,6")
3829 (set_attr "cc" "set_czn,set_n,set_czn")])
3831 (define_insn "negsi2"
3832 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3833 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
3836 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3837 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3838 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3839 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3840 [(set_attr "length" "7,8,8,7")
3841 (set_attr "isa" "*,*,mov,movw")
3842 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
3844 (define_insn "negsf2"
3845 [(set (match_operand:SF 0 "register_operand" "=d,r")
3846 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3850 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3851 [(set_attr "length" "1,4")
3852 (set_attr "cc" "set_n,set_n")])
3854 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3857 (define_insn "one_cmplqi2"
3858 [(set (match_operand:QI 0 "register_operand" "=r")
3859 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3862 [(set_attr "length" "1")
3863 (set_attr "cc" "set_czn")])
3865 (define_insn "one_cmplhi2"
3866 [(set (match_operand:HI 0 "register_operand" "=r")
3867 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3871 [(set_attr "length" "2")
3872 (set_attr "cc" "set_n")])
3874 (define_insn "one_cmplpsi2"
3875 [(set (match_operand:PSI 0 "register_operand" "=r")
3876 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3878 "com %0\;com %B0\;com %C0"
3879 [(set_attr "length" "3")
3880 (set_attr "cc" "set_n")])
3882 (define_insn "one_cmplsi2"
3883 [(set (match_operand:SI 0 "register_operand" "=r")
3884 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3890 [(set_attr "length" "4")
3891 (set_attr "cc" "set_n")])
3893 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3896 ;; We keep combiner from inserting hard registers into the input of sign- and
3897 ;; zero-extends. A hard register in the input operand is not wanted because
3898 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3899 ;; hard register that overlaps these clobbers won't be combined to a widening
3900 ;; multiplication. There is no need for combine to propagate hard registers,
3901 ;; register allocation can do it just as well.
3903 (define_insn "extendqihi2"
3904 [(set (match_operand:HI 0 "register_operand" "=r,r")
3905 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3908 clr %B0\;sbrc %0,7\;com %B0
3909 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3910 [(set_attr "length" "3,4")
3911 (set_attr "cc" "set_n,set_n")])
3913 (define_insn "extendqipsi2"
3914 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3915 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3918 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3919 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3920 [(set_attr "length" "4,5")
3921 (set_attr "cc" "set_n,set_n")])
3923 (define_insn "extendqisi2"
3924 [(set (match_operand:SI 0 "register_operand" "=r,r")
3925 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3928 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3929 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3930 [(set_attr "length" "5,6")
3931 (set_attr "cc" "set_n,set_n")])
3933 (define_insn "extendhipsi2"
3934 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3935 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3938 clr %C0\;sbrc %B0,7\;com %C0
3939 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
3940 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
3941 [(set_attr "length" "3,5,4")
3942 (set_attr "isa" "*,mov,movw")
3943 (set_attr "cc" "set_n")])
3945 (define_insn "extendhisi2"
3946 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3947 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3950 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3951 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3952 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3953 [(set_attr "length" "4,6,5")
3954 (set_attr "isa" "*,mov,movw")
3955 (set_attr "cc" "set_n")])
3957 (define_insn "extendpsisi2"
3958 [(set (match_operand:SI 0 "register_operand" "=r")
3959 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
3961 "clr %D0\;sbrc %C0,7\;com %D0"
3962 [(set_attr "length" "3")
3963 (set_attr "cc" "set_n")])
3965 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3968 (define_insn_and_split "zero_extendqihi2"
3969 [(set (match_operand:HI 0 "register_operand" "=r")
3970 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3974 [(set (match_dup 2) (match_dup 1))
3975 (set (match_dup 3) (const_int 0))]
3977 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
3978 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
3980 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
3981 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
3984 (define_insn_and_split "zero_extendqipsi2"
3985 [(set (match_operand:PSI 0 "register_operand" "=r")
3986 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3990 [(set (match_dup 2) (match_dup 1))
3991 (set (match_dup 3) (const_int 0))
3992 (set (match_dup 4) (const_int 0))]
3994 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
3995 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
3996 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
3999 (define_insn_and_split "zero_extendqisi2"
4000 [(set (match_operand:SI 0 "register_operand" "=r")
4001 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4005 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4006 (set (match_dup 3) (const_int 0))]
4008 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4009 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4011 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4012 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4015 (define_insn_and_split "zero_extendhipsi2"
4016 [(set (match_operand:PSI 0 "register_operand" "=r")
4017 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4021 [(set (match_dup 2) (match_dup 1))
4022 (set (match_dup 3) (const_int 0))]
4024 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4025 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4028 (define_insn_and_split "n_extendhipsi2"
4029 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4030 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4031 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4032 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4036 [(set (match_dup 4) (match_dup 2))
4037 (set (match_dup 3) (match_dup 6))
4038 ; no-op move in the case where no scratch is needed
4039 (set (match_dup 5) (match_dup 3))]
4041 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4042 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4043 operands[6] = operands[1];
4045 if (GET_CODE (operands[3]) == SCRATCH)
4046 operands[3] = operands[5];
4049 (define_insn_and_split "zero_extendhisi2"
4050 [(set (match_operand:SI 0 "register_operand" "=r")
4051 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4055 [(set (match_dup 2) (match_dup 1))
4056 (set (match_dup 3) (const_int 0))]
4058 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4059 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4061 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4062 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4065 (define_insn_and_split "zero_extendpsisi2"
4066 [(set (match_operand:SI 0 "register_operand" "=r")
4067 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4071 [(set (match_dup 2) (match_dup 1))
4072 (set (match_dup 3) (const_int 0))]
4074 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4075 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4078 (define_insn_and_split "zero_extendqidi2"
4079 [(set (match_operand:DI 0 "register_operand" "=r")
4080 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4084 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4085 (set (match_dup 3) (const_int 0))]
4087 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4088 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4090 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4091 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4094 (define_insn_and_split "zero_extendhidi2"
4095 [(set (match_operand:DI 0 "register_operand" "=r")
4096 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4100 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4101 (set (match_dup 3) (const_int 0))]
4103 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4104 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4106 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4107 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4110 (define_insn_and_split "zero_extendsidi2"
4111 [(set (match_operand:DI 0 "register_operand" "=r")
4112 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 3) (const_int 0))]
4119 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4120 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4122 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4123 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4126 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4129 ; Optimize negated tests into reverse compare if overflow is undefined.
4130 (define_insn "*negated_tstqi"
4132 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4134 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4135 "cp __zero_reg__,%0"
4136 [(set_attr "cc" "compare")
4137 (set_attr "length" "1")])
4139 (define_insn "*reversed_tstqi"
4141 (compare (const_int 0)
4142 (match_operand:QI 0 "register_operand" "r")))]
4144 "cp __zero_reg__,%0"
4145 [(set_attr "cc" "compare")
4146 (set_attr "length" "2")])
4148 (define_insn "*negated_tsthi"
4150 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4152 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4153 "cp __zero_reg__,%A0
4154 cpc __zero_reg__,%B0"
4155 [(set_attr "cc" "compare")
4156 (set_attr "length" "2")])
4158 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4159 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4160 (define_insn "*reversed_tsthi"
4162 (compare (const_int 0)
4163 (match_operand:HI 0 "register_operand" "r")))
4164 (clobber (match_scratch:QI 1 "=X"))]
4166 "cp __zero_reg__,%A0
4167 cpc __zero_reg__,%B0"
4168 [(set_attr "cc" "compare")
4169 (set_attr "length" "2")])
4171 (define_insn "*negated_tstpsi"
4173 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4175 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4176 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4177 [(set_attr "cc" "compare")
4178 (set_attr "length" "3")])
4180 (define_insn "*reversed_tstpsi"
4182 (compare (const_int 0)
4183 (match_operand:PSI 0 "register_operand" "r")))
4184 (clobber (match_scratch:QI 1 "=X"))]
4186 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4187 [(set_attr "cc" "compare")
4188 (set_attr "length" "3")])
4190 (define_insn "*negated_tstsi"
4192 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4194 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4195 "cp __zero_reg__,%A0
4196 cpc __zero_reg__,%B0
4197 cpc __zero_reg__,%C0
4198 cpc __zero_reg__,%D0"
4199 [(set_attr "cc" "compare")
4200 (set_attr "length" "4")])
4202 (define_insn "*reversed_tstsi"
4204 (compare (const_int 0)
4205 (match_operand:SI 0 "register_operand" "r")))
4206 (clobber (match_scratch:QI 1 "=X"))]
4208 "cp __zero_reg__,%A0
4209 cpc __zero_reg__,%B0
4210 cpc __zero_reg__,%C0
4211 cpc __zero_reg__,%D0"
4212 [(set_attr "cc" "compare")
4213 (set_attr "length" "4")])
4216 (define_insn "*cmpqi"
4218 (compare (match_operand:QI 0 "register_operand" "r,r,d")
4219 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
4225 [(set_attr "cc" "compare,compare,compare")
4226 (set_attr "length" "1,1,1")])
4228 (define_insn "*cmpqi_sign_extend"
4230 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4231 (match_operand:HI 1 "s8_operand" "n")))]
4234 [(set_attr "cc" "compare")
4235 (set_attr "length" "1")])
4237 (define_insn "*cmphi"
4239 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
4240 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
4241 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
4244 switch (which_alternative)
4248 return avr_out_tsthi (insn, operands, NULL);
4251 return "cp %A0,%A1\;cpc %B0,%B1";
4254 return reg_unused_after (insn, operands[0])
4255 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4256 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4259 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4262 return avr_out_compare (insn, operands, NULL);
4264 [(set_attr "cc" "compare")
4265 (set_attr "length" "1,2,2,3,4,2,4")
4266 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4268 (define_insn "*cmppsi"
4270 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4271 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4272 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4275 switch (which_alternative)
4278 return avr_out_tstpsi (insn, operands, NULL);
4281 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4284 return reg_unused_after (insn, operands[0])
4285 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4286 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4289 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4292 return avr_out_compare (insn, operands, NULL);
4294 [(set_attr "cc" "compare")
4295 (set_attr "length" "3,3,5,6,3,7")
4296 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4298 (define_insn "*cmpsi"
4300 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
4301 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
4302 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
4305 if (0 == which_alternative)
4306 return avr_out_tstsi (insn, operands, NULL);
4307 else if (1 == which_alternative)
4308 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4310 return avr_out_compare (insn, operands, NULL);
4312 [(set_attr "cc" "compare")
4313 (set_attr "length" "4,4,4,5,8")
4314 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4317 ;; ----------------------------------------------------------------------
4318 ;; JUMP INSTRUCTIONS
4319 ;; ----------------------------------------------------------------------
4320 ;; Conditional jump instructions
4322 (define_expand "cbranchsi4"
4323 [(parallel [(set (cc0)
4324 (compare (match_operand:SI 1 "register_operand" "")
4325 (match_operand:SI 2 "nonmemory_operand" "")))
4326 (clobber (match_scratch:QI 4 ""))])
4329 (match_operator 0 "ordered_comparison_operator" [(cc0)
4331 (label_ref (match_operand 3 "" ""))
4335 (define_expand "cbranchpsi4"
4336 [(parallel [(set (cc0)
4337 (compare (match_operand:PSI 1 "register_operand" "")
4338 (match_operand:PSI 2 "nonmemory_operand" "")))
4339 (clobber (match_scratch:QI 4 ""))])
4341 (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0)
4343 (label_ref (match_operand 3 "" ""))
4347 (define_expand "cbranchhi4"
4348 [(parallel [(set (cc0)
4349 (compare (match_operand:HI 1 "register_operand" "")
4350 (match_operand:HI 2 "nonmemory_operand" "")))
4351 (clobber (match_scratch:QI 4 ""))])
4354 (match_operator 0 "ordered_comparison_operator" [(cc0)
4356 (label_ref (match_operand 3 "" ""))
4360 (define_expand "cbranchqi4"
4362 (compare (match_operand:QI 1 "register_operand" "")
4363 (match_operand:QI 2 "nonmemory_operand" "")))
4366 (match_operator 0 "ordered_comparison_operator" [(cc0)
4368 (label_ref (match_operand 3 "" ""))
4373 ;; Test a single bit in a QI/HI/SImode register.
4374 ;; Combine will create zero extract patterns for single bit tests.
4375 ;; permit any mode in source pattern by using VOIDmode.
4377 (define_insn "*sbrx_branch<mode>"
4380 (match_operator 0 "eqne_operator"
4382 (match_operand:VOID 1 "register_operand" "r")
4384 (match_operand 2 "const_int_operand" "n"))
4386 (label_ref (match_operand 3 "" ""))
4390 return avr_out_sbxx_branch (insn, operands);
4392 [(set (attr "length")
4393 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4394 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4396 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4399 (set_attr "cc" "clobber")])
4401 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
4402 ;; or for old peepholes.
4403 ;; Fixme - bitwise Mask will not work for DImode
4405 (define_insn "*sbrx_and_branch<mode>"
4408 (match_operator 0 "eqne_operator"
4410 (match_operand:QISI 1 "register_operand" "r")
4411 (match_operand:QISI 2 "single_one_operand" "n"))
4413 (label_ref (match_operand 3 "" ""))
4417 HOST_WIDE_INT bitnumber;
4418 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4419 operands[2] = GEN_INT (bitnumber);
4420 return avr_out_sbxx_branch (insn, operands);
4422 [(set (attr "length")
4423 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4424 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4426 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4429 (set_attr "cc" "clobber")])
4431 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4433 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4435 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4436 (label_ref (match_operand 1 "" ""))
4439 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4443 (label_ref (match_dup 1))
4448 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4450 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4451 (label_ref (match_operand 1 "" ""))
4454 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4458 (label_ref (match_dup 1))
4463 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4465 (clobber (match_operand:HI 2 ""))])
4466 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4467 (label_ref (match_operand 1 "" ""))
4470 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4472 (label_ref (match_dup 1))
4477 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4479 (clobber (match_operand:HI 2 ""))])
4480 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4481 (label_ref (match_operand 1 "" ""))
4484 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4486 (label_ref (match_dup 1))
4491 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4493 (clobber (match_operand:SI 2 ""))])
4494 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4495 (label_ref (match_operand 1 "" ""))
4498 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4500 (label_ref (match_dup 1))
4502 "operands[2] = GEN_INT (-2147483647 - 1);")
4505 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4507 (clobber (match_operand:SI 2 ""))])
4508 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4509 (label_ref (match_operand 1 "" ""))
4512 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4514 (label_ref (match_dup 1))
4516 "operands[2] = GEN_INT (-2147483647 - 1);")
4518 ;; ************************************************************************
4519 ;; Implementation of conditional jumps here.
4520 ;; Compare with 0 (test) jumps
4521 ;; ************************************************************************
4523 (define_insn "branch"
4525 (if_then_else (match_operator 1 "simple_comparison_operator"
4528 (label_ref (match_operand 0 "" ""))
4532 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4534 [(set_attr "type" "branch")
4535 (set_attr "cc" "clobber")])
4538 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4539 ;; or optimized in the remainder.
4541 (define_insn "branch_unspec"
4543 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4546 (label_ref (match_operand 0 "" ""))
4548 ] UNSPEC_IDENTITY))]
4551 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4553 [(set_attr "type" "branch")
4554 (set_attr "cc" "none")])
4556 ;; ****************************************************************
4557 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4558 ;; Convert them all to proper jumps.
4559 ;; ****************************************************************/
4561 (define_insn "difficult_branch"
4563 (if_then_else (match_operator 1 "difficult_comparison_operator"
4566 (label_ref (match_operand 0 "" ""))
4570 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4572 [(set_attr "type" "branch1")
4573 (set_attr "cc" "clobber")])
4577 (define_insn "rvbranch"
4579 (if_then_else (match_operator 1 "simple_comparison_operator"
4583 (label_ref (match_operand 0 "" ""))))]
4586 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4588 [(set_attr "type" "branch1")
4589 (set_attr "cc" "clobber")])
4591 (define_insn "difficult_rvbranch"
4593 (if_then_else (match_operator 1 "difficult_comparison_operator"
4597 (label_ref (match_operand 0 "" ""))))]
4600 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4602 [(set_attr "type" "branch")
4603 (set_attr "cc" "clobber")])
4605 ;; **************************************************************************
4606 ;; Unconditional and other jump instructions.
4610 (label_ref (match_operand 0 "" "")))]
4613 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4617 [(set (attr "length")
4618 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4619 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4622 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4623 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4626 (set_attr "cc" "none")])
4630 (define_expand "call"
4631 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4632 (match_operand:HI 1 "general_operand" ""))
4633 (use (const_int 0))])]
4634 ;; Operand 1 not used on the AVR.
4635 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4639 (define_expand "sibcall"
4640 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4641 (match_operand:HI 1 "general_operand" ""))
4642 (use (const_int 1))])]
4643 ;; Operand 1 not used on the AVR.
4644 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4650 (define_expand "call_value"
4651 [(parallel[(set (match_operand 0 "register_operand" "")
4652 (call (match_operand:HI 1 "call_insn_operand" "")
4653 (match_operand:HI 2 "general_operand" "")))
4654 (use (const_int 0))])]
4655 ;; Operand 2 not used on the AVR.
4656 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4660 (define_expand "sibcall_value"
4661 [(parallel[(set (match_operand 0 "register_operand" "")
4662 (call (match_operand:HI 1 "call_insn_operand" "")
4663 (match_operand:HI 2 "general_operand" "")))
4664 (use (const_int 1))])]
4665 ;; Operand 2 not used on the AVR.
4666 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4670 (define_insn "call_insn"
4671 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4672 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4673 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4674 ;; Operand 1 not used on the AVR.
4675 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4682 [(set_attr "cc" "clobber")
4683 (set_attr "length" "1,*,1,*")
4684 (set_attr "adjust_len" "*,call,*,call")])
4686 (define_insn "call_value_insn"
4687 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4688 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4689 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4690 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4691 ;; Operand 2 not used on the AVR.
4692 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4699 [(set_attr "cc" "clobber")
4700 (set_attr "length" "1,*,1,*")
4701 (set_attr "adjust_len" "*,call,*,call")])
4707 [(set_attr "cc" "none")
4708 (set_attr "length" "1")])
4712 (define_expand "indirect_jump"
4714 (match_operand:HI 0 "nonmemory_operand" ""))]
4717 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4719 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4724 (define_insn "*indirect_jump"
4726 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4732 push %A0\;push %B0\;ret
4734 [(set_attr "length" "1,2,1,3,1")
4735 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4736 (set_attr "cc" "none")])
4739 ;; For entries in jump table see avr_output_addr_vec_elt.
4742 ;; "rjmp .L<n>" instructions for <= 8K devices
4743 ;; ".word gs(.L<n>)" addresses for > 8K devices
4744 (define_insn "*tablejump"
4746 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4748 (use (label_ref (match_operand 1 "" "")))
4749 (clobber (match_dup 0))]
4753 push %A0\;push %B0\;ret
4755 [(set_attr "length" "1,3,2")
4756 (set_attr "isa" "rjmp,rjmp,jmp")
4757 (set_attr "cc" "none,none,clobber")])
4760 (define_expand "casesi"
4762 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4763 (match_operand:HI 1 "register_operand" "")))
4764 (parallel [(set (cc0)
4765 (compare (match_dup 6)
4766 (match_operand:HI 2 "register_operand" "")))
4767 (clobber (match_scratch:QI 9 ""))])
4770 (if_then_else (gtu (cc0)
4772 (label_ref (match_operand 4 "" ""))
4776 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4778 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4779 (use (label_ref (match_dup 3)))
4780 (clobber (match_dup 6))])]
4783 operands[6] = gen_reg_rtx (HImode);
4787 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4788 ;; This instruction sets Z flag
4791 [(set (cc0) (const_int 0))]
4794 [(set_attr "length" "1")
4795 (set_attr "cc" "compare")])
4797 ;; Clear/set/test a single bit in I/O address space.
4800 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4801 (and:QI (mem:QI (match_dup 0))
4802 (match_operand:QI 1 "single_zero_operand" "n")))]
4805 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4806 return "cbi %i0,%2";
4808 [(set_attr "length" "1")
4809 (set_attr "cc" "none")])
4812 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4813 (ior:QI (mem:QI (match_dup 0))
4814 (match_operand:QI 1 "single_one_operand" "n")))]
4817 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4818 return "sbi %i0,%2";
4820 [(set_attr "length" "1")
4821 (set_attr "cc" "none")])
4823 ;; Lower half of the I/O space - use sbic/sbis directly.
4824 (define_insn "*sbix_branch"
4827 (match_operator 0 "eqne_operator"
4829 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
4831 (match_operand 2 "const_int_operand" "n"))
4833 (label_ref (match_operand 3 "" ""))
4837 return avr_out_sbxx_branch (insn, operands);
4839 [(set (attr "length")
4840 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4841 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4843 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4846 (set_attr "cc" "clobber")])
4848 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4849 (define_insn "*sbix_branch_bit7"
4852 (match_operator 0 "gelt_operator"
4853 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
4855 (label_ref (match_operand 2 "" ""))
4859 operands[3] = operands[2];
4860 operands[2] = GEN_INT (7);
4861 return avr_out_sbxx_branch (insn, operands);
4863 [(set (attr "length")
4864 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4865 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4867 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4870 (set_attr "cc" "clobber")])
4872 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4873 (define_insn "*sbix_branch_tmp"
4876 (match_operator 0 "eqne_operator"
4878 (mem:QI (match_operand 1 "high_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 2045)))
4892 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4895 (set_attr "cc" "clobber")])
4897 (define_insn "*sbix_branch_tmp_bit7"
4900 (match_operator 0 "gelt_operator"
4901 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
4903 (label_ref (match_operand 2 "" ""))
4907 operands[3] = operands[2];
4908 operands[2] = GEN_INT (7);
4909 return avr_out_sbxx_branch (insn, operands);
4911 [(set (attr "length")
4912 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4913 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4915 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4918 (set_attr "cc" "clobber")])
4920 ;; ************************* Peepholes ********************************
4923 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
4924 (plus:SI (match_dup 0)
4926 (clobber (scratch:QI))])
4927 (parallel [(set (cc0)
4928 (compare (match_dup 0)
4930 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4932 (if_then_else (ne (cc0)
4934 (label_ref (match_operand 2 "" ""))
4939 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4940 output_asm_insn ("sbiw %0,1" CR_TAB
4941 "sbc %C0,__zero_reg__" CR_TAB
4942 "sbc %D0,__zero_reg__", operands);
4944 output_asm_insn ("subi %A0,1" CR_TAB
4945 "sbc %B0,__zero_reg__" CR_TAB
4946 "sbc %C0,__zero_reg__" CR_TAB
4947 "sbc %D0,__zero_reg__", operands);
4949 switch (avr_jump_mode (operands[2], insn))
4954 return "brcs .+2\;rjmp %2";
4956 return "brcs .+4\;jmp %2";
4964 [(set (match_operand:HI 0 "d_register_operand" "")
4965 (plus:HI (match_dup 0)
4969 (compare (match_dup 0)
4971 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4973 (if_then_else (ne (cc0) (const_int 0))
4974 (label_ref (match_operand 2 "" ""))
4979 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4980 output_asm_insn ("sbiw %0,1", operands);
4982 output_asm_insn ("subi %A0,1" CR_TAB
4983 "sbc %B0,__zero_reg__", operands);
4985 switch (avr_jump_mode (operands[2], insn))
4990 return "brcs .+2\;rjmp %2";
4992 return "brcs .+4\;jmp %2";
5000 [(set (match_operand:QI 0 "d_register_operand" "")
5001 (plus:QI (match_dup 0)
5004 (compare (match_dup 0)
5007 (if_then_else (ne (cc0) (const_int 0))
5008 (label_ref (match_operand 1 "" ""))
5013 cc_status.value1 = operands[0];
5014 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5016 output_asm_insn ("subi %A0,1", operands);
5018 switch (avr_jump_mode (operands[1], insn))
5023 return "brcs .+2\;rjmp %1";
5025 return "brcs .+4\;jmp %1";
5033 (define_peephole ; "*cpse.eq"
5035 (compare (match_operand:QI 1 "register_operand" "r,r")
5036 (match_operand:QI 2 "reg_or_0_operand" "r,L")))
5038 (if_then_else (eq (cc0)
5040 (label_ref (match_operand 0 "" ""))
5042 "jump_over_one_insn_p (insn, operands[0])"
5045 cpse %1,__zero_reg__")
5047 ;; This peephole avoids code like
5050 ;; BREQ .+2 ; branch
5053 ;; Notice that the peephole is always shorter than cmpqi + branch.
5054 ;; The reason to write it as peephole is that sequences like
5059 ;; shall not be superseeded. With a respective combine pattern
5060 ;; the latter sequence would be
5063 ;; CPSE Rm, __zero_reg__
5066 ;; and thus longer and slower and not easy to be rolled back.
5068 (define_peephole ; "*cpse.ne"
5070 (compare (match_operand:QI 1 "register_operand" "")
5071 (match_operand:QI 2 "reg_or_0_operand" "")))
5073 (if_then_else (ne (cc0)
5075 (label_ref (match_operand 0 "" ""))
5078 || !avr_current_device->errata_skip"
5080 if (operands[2] == const0_rtx)
5081 operands[2] = zero_reg_rtx;
5083 return 3 == avr_jump_mode (operands[0], insn)
5084 ? "cpse %1,%2\;jmp %0"
5085 : "cpse %1,%2\;rjmp %0";
5088 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5089 ;;prologue/epilogue support instructions
5091 (define_insn "popqi"
5092 [(set (match_operand:QI 0 "register_operand" "=r")
5093 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5096 [(set_attr "cc" "none")
5097 (set_attr "length" "1")])
5099 ;; Enable Interrupts
5100 (define_insn "enable_interrupt"
5101 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
5104 [(set_attr "length" "1")
5105 (set_attr "cc" "none")])
5107 ;; Disable Interrupts
5108 (define_insn "disable_interrupt"
5109 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
5112 [(set_attr "length" "1")
5113 (set_attr "cc" "none")])
5115 ;; Library prologue saves
5116 (define_insn "call_prologue_saves"
5117 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5118 (match_operand:HI 0 "immediate_operand" "i,i")
5119 (set (reg:HI REG_SP)
5120 (minus:HI (reg:HI REG_SP)
5121 (match_operand:HI 1 "immediate_operand" "i,i")))
5122 (use (reg:HI REG_X))
5123 (clobber (reg:HI REG_Z))]
5125 "ldi r30,lo8(gs(1f))
5127 %~jmp __prologue_saves__+((18 - %0) * 2)
5129 [(set_attr "length" "5,6")
5130 (set_attr "cc" "clobber")
5131 (set_attr "isa" "rjmp,jmp")])
5133 ; epilogue restores using library
5134 (define_insn "epilogue_restores"
5135 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5137 (plus:HI (reg:HI REG_Y)
5138 (match_operand:HI 0 "immediate_operand" "i,i")))
5139 (set (reg:HI REG_SP)
5140 (plus:HI (reg:HI REG_Y)
5142 (clobber (reg:QI REG_Z))]
5145 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5146 [(set_attr "length" "2,3")
5147 (set_attr "cc" "clobber")
5148 (set_attr "isa" "rjmp,jmp")])
5151 (define_insn "return"
5153 "reload_completed && avr_simple_epilogue ()"
5155 [(set_attr "cc" "none")
5156 (set_attr "length" "1")])
5158 (define_insn "return_from_epilogue"
5162 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5163 && !cfun->machine->is_naked)"
5165 [(set_attr "cc" "none")
5166 (set_attr "length" "1")])
5168 (define_insn "return_from_interrupt_epilogue"
5172 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5173 && !cfun->machine->is_naked)"
5175 [(set_attr "cc" "none")
5176 (set_attr "length" "1")])
5178 (define_insn "return_from_naked_epilogue"
5182 && cfun->machine->is_naked)"
5184 [(set_attr "cc" "none")
5185 (set_attr "length" "0")])
5187 (define_expand "prologue"
5195 (define_expand "epilogue"
5199 expand_epilogue (false /* sibcall_p */);
5203 (define_expand "sibcall_epilogue"
5207 expand_epilogue (true /* sibcall_p */);
5211 ;; Some instructions resp. instruction sequences available
5214 (define_insn "delay_cycles_1"
5215 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5217 UNSPECV_DELAY_CYCLES)
5218 (clobber (match_scratch:QI 1 "=&d"))]
5223 [(set_attr "length" "3")
5224 (set_attr "cc" "clobber")])
5226 (define_insn "delay_cycles_2"
5227 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5229 UNSPECV_DELAY_CYCLES)
5230 (clobber (match_scratch:HI 1 "=&w"))]
5236 [(set_attr "length" "4")
5237 (set_attr "cc" "clobber")])
5239 (define_insn "delay_cycles_3"
5240 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5242 UNSPECV_DELAY_CYCLES)
5243 (clobber (match_scratch:QI 1 "=&d"))
5244 (clobber (match_scratch:QI 2 "=&d"))
5245 (clobber (match_scratch:QI 3 "=&d"))]
5254 [(set_attr "length" "7")
5255 (set_attr "cc" "clobber")])
5257 (define_insn "delay_cycles_4"
5258 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5260 UNSPECV_DELAY_CYCLES)
5261 (clobber (match_scratch:QI 1 "=&d"))
5262 (clobber (match_scratch:QI 2 "=&d"))
5263 (clobber (match_scratch:QI 3 "=&d"))
5264 (clobber (match_scratch:QI 4 "=&d"))]
5275 [(set_attr "length" "9")
5276 (set_attr "cc" "clobber")])
5279 ;; __builtin_avr_insert_bits
5281 (define_insn "insert_bits"
5282 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5283 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5284 (match_operand:QI 2 "register_operand" "r ,r ,r")
5285 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5286 UNSPEC_INSERT_BITS))]
5289 return avr_out_insert_bits (operands, NULL);
5291 [(set_attr "adjust_len" "insert_bits")
5292 (set_attr "cc" "clobber")])
5297 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5298 ;; better 8-bit parity recognition.
5300 (define_expand "parityhi2"
5301 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5302 (parity:HI (match_operand:HI 1 "register_operand" "")))
5303 (clobber (reg:HI 24))])])
5305 (define_insn_and_split "*parityhi2"
5306 [(set (match_operand:HI 0 "register_operand" "=r")
5307 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5308 (clobber (reg:HI 24))]
5310 { gcc_unreachable(); }
5315 (parity:HI (reg:HI 24)))
5319 (define_insn_and_split "*parityqihi2"
5320 [(set (match_operand:HI 0 "register_operand" "=r")
5321 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5322 (clobber (reg:HI 24))]
5324 { gcc_unreachable(); }
5329 (zero_extend:HI (parity:QI (reg:QI 24))))
5333 (define_expand "paritysi2"
5335 (match_operand:SI 1 "register_operand" ""))
5337 (truncate:HI (parity:SI (reg:SI 22))))
5340 (set (match_operand:SI 0 "register_operand" "")
5341 (zero_extend:SI (match_dup 2)))]
5344 operands[2] = gen_reg_rtx (HImode);
5347 (define_insn "*parityhi2.libgcc"
5349 (parity:HI (reg:HI 24)))]
5351 "%~call __parityhi2"
5352 [(set_attr "type" "xcall")
5353 (set_attr "cc" "clobber")])
5355 (define_insn "*parityqihi2.libgcc"
5357 (zero_extend:HI (parity:QI (reg:QI 24))))]
5359 "%~call __parityqi2"
5360 [(set_attr "type" "xcall")
5361 (set_attr "cc" "clobber")])
5363 (define_insn "*paritysihi2.libgcc"
5365 (truncate:HI (parity:SI (reg:SI 22))))]
5367 "%~call __paritysi2"
5368 [(set_attr "type" "xcall")
5369 (set_attr "cc" "clobber")])
5374 (define_expand "popcounthi2"
5376 (match_operand:HI 1 "register_operand" ""))
5378 (popcount:HI (reg:HI 24)))
5379 (set (match_operand:HI 0 "register_operand" "")
5384 (define_expand "popcountsi2"
5386 (match_operand:SI 1 "register_operand" ""))
5388 (truncate:HI (popcount:SI (reg:SI 22))))
5391 (set (match_operand:SI 0 "register_operand" "")
5392 (zero_extend:SI (match_dup 2)))]
5395 operands[2] = gen_reg_rtx (HImode);
5398 (define_insn "*popcounthi2.libgcc"
5400 (popcount:HI (reg:HI 24)))]
5402 "%~call __popcounthi2"
5403 [(set_attr "type" "xcall")
5404 (set_attr "cc" "clobber")])
5406 (define_insn "*popcountsi2.libgcc"
5408 (truncate:HI (popcount:SI (reg:SI 22))))]
5410 "%~call __popcountsi2"
5411 [(set_attr "type" "xcall")
5412 (set_attr "cc" "clobber")])
5414 (define_insn "*popcountqi2.libgcc"
5416 (popcount:QI (reg:QI 24)))]
5418 "%~call __popcountqi2"
5419 [(set_attr "type" "xcall")
5420 (set_attr "cc" "clobber")])
5422 (define_insn_and_split "*popcountqihi2.libgcc"
5424 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5429 (popcount:QI (reg:QI 24)))
5434 ;; Count Leading Zeros
5436 (define_expand "clzhi2"
5438 (match_operand:HI 1 "register_operand" ""))
5439 (parallel [(set (reg:HI 24)
5440 (clz:HI (reg:HI 24)))
5441 (clobber (reg:QI 26))])
5442 (set (match_operand:HI 0 "register_operand" "")
5447 (define_expand "clzsi2"
5449 (match_operand:SI 1 "register_operand" ""))
5450 (parallel [(set (reg:HI 24)
5451 (truncate:HI (clz:SI (reg:SI 22))))
5452 (clobber (reg:QI 26))])
5455 (set (match_operand:SI 0 "register_operand" "")
5456 (zero_extend:SI (match_dup 2)))]
5459 operands[2] = gen_reg_rtx (HImode);
5462 (define_insn "*clzhi2.libgcc"
5464 (clz:HI (reg:HI 24)))
5465 (clobber (reg:QI 26))]
5468 [(set_attr "type" "xcall")
5469 (set_attr "cc" "clobber")])
5471 (define_insn "*clzsihi2.libgcc"
5473 (truncate:HI (clz:SI (reg:SI 22))))
5474 (clobber (reg:QI 26))]
5477 [(set_attr "type" "xcall")
5478 (set_attr "cc" "clobber")])
5480 ;; Count Trailing Zeros
5482 (define_expand "ctzhi2"
5484 (match_operand:HI 1 "register_operand" ""))
5485 (parallel [(set (reg:HI 24)
5486 (ctz:HI (reg:HI 24)))
5487 (clobber (reg:QI 26))])
5488 (set (match_operand:HI 0 "register_operand" "")
5493 (define_expand "ctzsi2"
5495 (match_operand:SI 1 "register_operand" ""))
5496 (parallel [(set (reg:HI 24)
5497 (truncate:HI (ctz:SI (reg:SI 22))))
5498 (clobber (reg:QI 22))
5499 (clobber (reg:QI 26))])
5502 (set (match_operand:SI 0 "register_operand" "")
5503 (zero_extend:SI (match_dup 2)))]
5506 operands[2] = gen_reg_rtx (HImode);
5509 (define_insn "*ctzhi2.libgcc"
5511 (ctz:HI (reg:HI 24)))
5512 (clobber (reg:QI 26))]
5515 [(set_attr "type" "xcall")
5516 (set_attr "cc" "clobber")])
5518 (define_insn "*ctzsihi2.libgcc"
5520 (truncate:HI (ctz:SI (reg:SI 22))))
5521 (clobber (reg:QI 22))
5522 (clobber (reg:QI 26))]
5525 [(set_attr "type" "xcall")
5526 (set_attr "cc" "clobber")])
5530 (define_expand "ffshi2"
5532 (match_operand:HI 1 "register_operand" ""))
5533 (parallel [(set (reg:HI 24)
5534 (ffs:HI (reg:HI 24)))
5535 (clobber (reg:QI 26))])
5536 (set (match_operand:HI 0 "register_operand" "")
5541 (define_expand "ffssi2"
5543 (match_operand:SI 1 "register_operand" ""))
5544 (parallel [(set (reg:HI 24)
5545 (truncate:HI (ffs:SI (reg:SI 22))))
5546 (clobber (reg:QI 22))
5547 (clobber (reg:QI 26))])
5550 (set (match_operand:SI 0 "register_operand" "")
5551 (zero_extend:SI (match_dup 2)))]
5554 operands[2] = gen_reg_rtx (HImode);
5557 (define_insn "*ffshi2.libgcc"
5559 (ffs:HI (reg:HI 24)))
5560 (clobber (reg:QI 26))]
5563 [(set_attr "type" "xcall")
5564 (set_attr "cc" "clobber")])
5566 (define_insn "*ffssihi2.libgcc"
5568 (truncate:HI (ffs:SI (reg:SI 22))))
5569 (clobber (reg:QI 22))
5570 (clobber (reg:QI 26))]
5573 [(set_attr "type" "xcall")
5574 (set_attr "cc" "clobber")])
5578 (define_insn "copysignsf3"
5579 [(set (match_operand:SF 0 "register_operand" "=r")
5580 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5581 (match_operand:SF 2 "register_operand" "r")]
5584 "bst %D2,7\;bld %D0,7"
5585 [(set_attr "length" "2")
5586 (set_attr "cc" "none")])
5588 ;; Swap Bytes (change byte-endianess)
5590 (define_expand "bswapsi2"
5592 (match_operand:SI 1 "register_operand" ""))
5594 (bswap:SI (reg:SI 22)))
5595 (set (match_operand:SI 0 "register_operand" "")
5600 (define_insn "*bswapsi2.libgcc"
5602 (bswap:SI (reg:SI 22)))]
5605 [(set_attr "type" "xcall")
5606 (set_attr "cc" "clobber")])
5611 ;; NOP taking 1 or 2 Ticks
5613 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5619 [(set_attr "length" "1")
5620 (set_attr "cc" "none")])
5623 (define_insn "sleep"
5624 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
5627 [(set_attr "length" "1")
5628 (set_attr "cc" "none")])
5632 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
5635 [(set_attr "length" "1")
5636 (set_attr "cc" "none")])
5639 (define_expand "fmul"
5641 (match_operand:QI 1 "register_operand" ""))
5643 (match_operand:QI 2 "register_operand" ""))
5644 (parallel [(set (reg:HI 22)
5645 (unspec:HI [(reg:QI 24)
5646 (reg:QI 25)] UNSPEC_FMUL))
5647 (clobber (reg:HI 24))])
5648 (set (match_operand:HI 0 "register_operand" "")
5654 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
5659 (define_insn "fmul_insn"
5660 [(set (match_operand:HI 0 "register_operand" "=r")
5661 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5662 (match_operand:QI 2 "register_operand" "a")]
5668 [(set_attr "length" "3")
5669 (set_attr "cc" "clobber")])
5671 (define_insn "*fmul.call"
5673 (unspec:HI [(reg:QI 24)
5674 (reg:QI 25)] UNSPEC_FMUL))
5675 (clobber (reg:HI 24))]
5678 [(set_attr "type" "xcall")
5679 (set_attr "cc" "clobber")])
5682 (define_expand "fmuls"
5684 (match_operand:QI 1 "register_operand" ""))
5686 (match_operand:QI 2 "register_operand" ""))
5687 (parallel [(set (reg:HI 22)
5688 (unspec:HI [(reg:QI 24)
5689 (reg:QI 25)] UNSPEC_FMULS))
5690 (clobber (reg:HI 24))])
5691 (set (match_operand:HI 0 "register_operand" "")
5697 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
5702 (define_insn "fmuls_insn"
5703 [(set (match_operand:HI 0 "register_operand" "=r")
5704 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5705 (match_operand:QI 2 "register_operand" "a")]
5711 [(set_attr "length" "3")
5712 (set_attr "cc" "clobber")])
5714 (define_insn "*fmuls.call"
5716 (unspec:HI [(reg:QI 24)
5717 (reg:QI 25)] UNSPEC_FMULS))
5718 (clobber (reg:HI 24))]
5721 [(set_attr "type" "xcall")
5722 (set_attr "cc" "clobber")])
5725 (define_expand "fmulsu"
5727 (match_operand:QI 1 "register_operand" ""))
5729 (match_operand:QI 2 "register_operand" ""))
5730 (parallel [(set (reg:HI 22)
5731 (unspec:HI [(reg:QI 24)
5732 (reg:QI 25)] UNSPEC_FMULSU))
5733 (clobber (reg:HI 24))])
5734 (set (match_operand:HI 0 "register_operand" "")
5740 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
5745 (define_insn "fmulsu_insn"
5746 [(set (match_operand:HI 0 "register_operand" "=r")
5747 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5748 (match_operand:QI 2 "register_operand" "a")]
5754 [(set_attr "length" "3")
5755 (set_attr "cc" "clobber")])
5757 (define_insn "*fmulsu.call"
5759 (unspec:HI [(reg:QI 24)
5760 (reg:QI 25)] UNSPEC_FMULSU))
5761 (clobber (reg:HI 24))]
5764 [(set_attr "type" "xcall")
5765 (set_attr "cc" "clobber")])
5768 ;; Some combiner patterns dealing with bits.
5771 ;; Move bit $3.0 into bit $0.$4
5772 (define_insn "*movbitqi.1-6.a"
5773 [(set (match_operand:QI 0 "register_operand" "=r")
5774 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5775 (match_operand:QI 2 "single_zero_operand" "n"))
5776 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
5777 (match_operand:QI 4 "const_0_to_7_operand" "n"))
5778 (match_operand:QI 5 "single_one_operand" "n"))))]
5779 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
5780 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
5781 "bst %3,0\;bld %0,%4"
5782 [(set_attr "length" "2")
5783 (set_attr "cc" "none")])
5785 ;; Move bit $3.0 into bit $0.$4
5786 ;; Variation of above. Unfortunately, there is no canonicalized representation
5787 ;; of moving around bits. So what we see here depends on how user writes down
5788 ;; bit manipulations.
5789 (define_insn "*movbitqi.1-6.b"
5790 [(set (match_operand:QI 0 "register_operand" "=r")
5791 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5792 (match_operand:QI 2 "single_zero_operand" "n"))
5793 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
5795 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
5796 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5797 "bst %3,0\;bld %0,%4"
5798 [(set_attr "length" "2")
5799 (set_attr "cc" "none")])
5801 ;; Move bit $3.0 into bit $0.0.
5802 ;; For bit 0, combiner generates slightly different pattern.
5803 (define_insn "*movbitqi.0"
5804 [(set (match_operand:QI 0 "register_operand" "=r")
5805 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5806 (match_operand:QI 2 "single_zero_operand" "n"))
5807 (and:QI (match_operand:QI 3 "register_operand" "r")
5809 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5810 "bst %3,0\;bld %0,0"
5811 [(set_attr "length" "2")
5812 (set_attr "cc" "none")])
5814 ;; Move bit $2.0 into bit $0.7.
5815 ;; For bit 7, combiner generates slightly different pattern
5816 (define_insn "*movbitqi.7"
5817 [(set (match_operand:QI 0 "register_operand" "=r")
5818 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5820 (ashift:QI (match_operand:QI 2 "register_operand" "r")
5823 "bst %2,0\;bld %0,7"
5824 [(set_attr "length" "2")
5825 (set_attr "cc" "none")])
5827 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
5828 ;; and input/output match. We provide a special pattern for this, because
5829 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
5830 ;; operation on I/O is atomic.
5831 (define_insn "*insv.io"
5832 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
5834 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
5835 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
5840 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
5841 [(set_attr "length" "1,1,4")
5842 (set_attr "cc" "none")])
5844 (define_insn "*insv.not.io"
5845 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5847 (match_operand:QI 1 "const_0_to_7_operand" "n"))
5848 (not:QI (match_operand:QI 2 "register_operand" "r")))]
5850 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
5851 [(set_attr "length" "4")
5852 (set_attr "cc" "none")])
5854 ;; The insv expander.
5855 ;; We only support 1-bit inserts
5856 (define_expand "insv"
5857 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
5858 (match_operand:QI 1 "const1_operand" "") ; width
5859 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
5860 (match_operand:QI 3 "nonmemory_operand" ""))]
5864 ;; Insert bit $2.0 into $0.$1
5865 (define_insn "*insv.reg"
5866 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
5868 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
5869 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
5873 andi %0,lo8(~(1<<%1))
5877 [(set_attr "length" "2,1,1,2,2")
5878 (set_attr "cc" "none,set_zn,set_zn,none,none")])
5881 ;; Some combine patterns that try to fix bad code when a value is composed
5882 ;; from byte parts like in PR27663.
5883 ;; The patterns give some release but the code still is not optimal,
5884 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
5885 ;; That switch obfuscates things here and in many other places.
5887 (define_insn_and_split "*ior<mode>qi.byte0"
5888 [(set (match_operand:HISI 0 "register_operand" "=r")
5890 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5891 (match_operand:HISI 2 "register_operand" "0")))]
5896 (ior:QI (match_dup 3)
5899 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
5902 (define_insn_and_split "*ior<mode>qi.byte1-3"
5903 [(set (match_operand:HISI 0 "register_operand" "=r")
5905 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5906 (match_operand:QI 2 "const_8_16_24_operand" "n"))
5907 (match_operand:HISI 3 "register_operand" "0")))]
5908 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5910 "&& reload_completed"
5912 (ior:QI (match_dup 4)
5915 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
5916 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
5919 (define_expand "extzv"
5920 [(set (match_operand:QI 0 "register_operand" "")
5921 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
5922 (match_operand:QI 2 "const1_operand" "")
5923 (match_operand:QI 3 "const_0_to_7_operand" "")))]
5927 (define_insn "*extzv"
5928 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
5929 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
5931 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
5935 mov %0,%1\;andi %0,1
5938 bst %1,%2\;clr %0\;bld %0,0"
5939 [(set_attr "length" "1,2,2,2,3")
5940 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
5942 (define_insn_and_split "*extzv.qihi1"
5943 [(set (match_operand:HI 0 "register_operand" "=r")
5944 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
5946 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
5951 (zero_extract:QI (match_dup 1)
5957 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5958 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5961 (define_insn_and_split "*extzv.qihi2"
5962 [(set (match_operand:HI 0 "register_operand" "=r")
5964 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
5966 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
5971 (zero_extract:QI (match_dup 1)
5977 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5978 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5982 (include "avr-dimode.md")