1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998-2014 Free Software Foundation, Inc.
4 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;; Special characters after '%':
23 ;; A No effect (add 0).
24 ;; B Add 1 to REG number, MEM address or CONST_INT.
27 ;; j Branch condition.
28 ;; k Reverse branch condition.
29 ;;..m..Constant Direct Data memory address.
30 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
31 ;; RAM address. The resulting address is suitable to be used in IN/OUT.
32 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
33 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
34 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
35 ;; r Print a REG without the register prefix 'r'.
36 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
37 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
38 ;; just cashes the operand for the next %T. The second %T gets
39 ;; a CONST_INT that represents a bit position.
40 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
41 ;; "%T0%T1" it will print "r19,5".
42 ;; Notice that you must not write a comma between %T0 and %T1.
43 ;; T/t Similar to above, but don't print the comma and the bit number.
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
45 ;; "%T0%t1" it will print "r19".
46 ;;..x..Constant Direct Program memory address.
47 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
48 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
57 (LPM_REGNO 0) ; implicit target register of LPM
58 (TMP_REGNO 0) ; temporary register r0
59 (ZERO_REGNO 1) ; zero register r1
62 (define_c_enum "unspec"
75 (define_c_enum "unspecv"
76 [UNSPECV_PROLOGUE_SAVES
77 UNSPECV_EPILOGUE_RESTORES
81 UNSPECV_MEMORY_BARRIER
89 (include "predicates.md")
90 (include "constraints.md")
92 ;; Condition code settings.
93 (define_attr "cc" "none,set_czn,set_zn,set_vzn,set_n,compare,clobber,
95 (const_string "none"))
97 (define_attr "type" "branch,branch1,arith,xcall"
98 (const_string "arith"))
100 ;; The size of instructions in bytes.
101 ;; XXX may depend from "cc"
103 (define_attr "length" ""
104 (cond [(eq_attr "type" "branch")
105 (if_then_else (and (ge (minus (pc) (match_dup 0))
107 (le (minus (pc) (match_dup 0))
110 (if_then_else (and (ge (minus (pc) (match_dup 0))
112 (le (minus (pc) (match_dup 0))
116 (eq_attr "type" "branch1")
117 (if_then_else (and (ge (minus (pc) (match_dup 0))
119 (le (minus (pc) (match_dup 0))
122 (if_then_else (and (ge (minus (pc) (match_dup 0))
124 (le (minus (pc) (match_dup 0))
128 (eq_attr "type" "xcall")
129 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
134 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
135 ;; Following insn attribute tells if and how the adjustment has to be
137 ;; no No adjustment needed; attribute "length" is fine.
138 ;; Otherwise do special processing depending on the attribute.
140 (define_attr "adjust_len"
141 "out_bitop, plus, addto_sp,
142 tsthi, tstpsi, tstsi, compare, compare64, call,
143 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
144 ufract, sfract, round,
146 ashlqi, ashrqi, lshrqi,
147 ashlhi, ashrhi, lshrhi,
148 ashlsi, ashrsi, lshrsi,
149 ashlpsi, ashrpsi, lshrpsi,
154 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
156 ;; mov : ISA has no MOVW movw : ISA has MOVW
157 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
158 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
159 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
160 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
161 ;; no_xmega: non-XMEGA core xmega : XMEGA core
164 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
166 (const_string "standard"))
168 (define_attr "enabled" ""
169 (cond [(eq_attr "isa" "standard")
172 (and (eq_attr "isa" "mov")
173 (match_test "!AVR_HAVE_MOVW"))
176 (and (eq_attr "isa" "movw")
177 (match_test "AVR_HAVE_MOVW"))
180 (and (eq_attr "isa" "rjmp")
181 (match_test "!AVR_HAVE_JMP_CALL"))
184 (and (eq_attr "isa" "jmp")
185 (match_test "AVR_HAVE_JMP_CALL"))
188 (and (eq_attr "isa" "ijmp")
189 (match_test "!AVR_HAVE_EIJMP_EICALL"))
192 (and (eq_attr "isa" "eijmp")
193 (match_test "AVR_HAVE_EIJMP_EICALL"))
196 (and (eq_attr "isa" "lpm")
197 (match_test "!AVR_HAVE_LPMX"))
200 (and (eq_attr "isa" "lpmx")
201 (match_test "AVR_HAVE_LPMX"))
204 (and (eq_attr "isa" "elpm")
205 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
208 (and (eq_attr "isa" "elpmx")
209 (match_test "AVR_HAVE_ELPMX"))
212 (and (eq_attr "isa" "xmega")
213 (match_test "AVR_XMEGA"))
216 (and (eq_attr "isa" "no_xmega")
217 (match_test "!AVR_XMEGA"))
222 ;; Define mode iterators
223 (define_mode_iterator QIHI [QI HI])
224 (define_mode_iterator QIHI2 [QI HI])
225 (define_mode_iterator QISI [QI HI PSI SI])
226 (define_mode_iterator QIDI [QI HI PSI SI DI])
227 (define_mode_iterator HISI [HI PSI SI])
229 (define_mode_iterator ALL1 [QI QQ UQQ])
230 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
231 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
233 ;; All supported move-modes
234 (define_mode_iterator MOVMODE [QI QQ UQQ
239 ;; Supported ordered modes that are 2, 3, 4 bytes wide
240 (define_mode_iterator ORDERED234 [HI SI PSI
244 ;; Define code iterators
245 ;; Define two incarnations so that we can build the cross product.
246 (define_code_iterator any_extend [sign_extend zero_extend])
247 (define_code_iterator any_extend2 [sign_extend zero_extend])
249 (define_code_iterator xior [xor ior])
250 (define_code_iterator eqne [eq ne])
252 (define_code_iterator ss_addsub [ss_plus ss_minus])
253 (define_code_iterator us_addsub [us_plus us_minus])
254 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
256 ;; Define code attributes
257 (define_code_attr extend_su
261 (define_code_attr extend_u
265 (define_code_attr extend_s
269 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
270 (define_code_attr mul_r_d
274 (define_code_attr abelian
275 [(ss_minus "") (us_minus "")
276 (ss_plus "%") (us_plus "%")])
278 ;; Map RTX code to its standard insn name
279 (define_code_attr code_stdname
286 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
287 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
290 ;;========================================================================
291 ;; The following is used by nonlocal_goto and setjmp.
292 ;; The receiver pattern will create no instructions since internally
293 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
294 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
295 ;; The 'null' receiver also avoids problems with optimisation
296 ;; not recognising incoming jmp and removing code that resets frame_pointer.
297 ;; The code derived from builtins.c.
299 (define_expand "nonlocal_goto_receiver"
301 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
304 emit_move_insn (virtual_stack_vars_rtx,
305 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
306 gen_int_mode (STARTING_FRAME_OFFSET,
308 /* ; This might change the hard frame pointer in ways that aren't
309 ; apparent to early optimization passes, so force a clobber. */
310 emit_clobber (hard_frame_pointer_rtx);
315 ;; Defining nonlocal_goto_receiver means we must also define this.
316 ;; even though its function is identical to that in builtins.c
318 (define_expand "nonlocal_goto"
319 [(use (match_operand 0 "general_operand"))
320 (use (match_operand 1 "general_operand"))
321 (use (match_operand 2 "general_operand"))
322 (use (match_operand 3 "general_operand"))]
325 rtx r_label = copy_to_reg (operands[1]);
326 rtx r_fp = operands[3];
327 rtx r_sp = operands[2];
329 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
331 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
333 emit_move_insn (hard_frame_pointer_rtx, r_fp);
334 emit_stack_restore (SAVE_NONLOCAL, r_sp);
336 emit_use (hard_frame_pointer_rtx);
337 emit_use (stack_pointer_rtx);
339 emit_indirect_jump (r_label);
345 ;; "pushqq1" "pushuqq1"
346 (define_insn "push<mode>1"
347 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
348 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
353 [(set_attr "length" "1,1")])
355 ;; All modes for a multi-byte push. We must include complex modes here too,
356 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
357 (define_mode_iterator MPUSH
366 (define_expand "push<mode>1"
367 [(match_operand:MPUSH 0 "" "")]
372 // Avoid (subreg (mem)) for non-generic address spaces below. Because
373 // of the poor addressing capabilities of these spaces it's better to
374 // load them in one chunk. And it avoids PR61443.
376 if (MEM_P (operands[0])
377 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0])))
378 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]);
380 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
382 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
383 if (part != const0_rtx)
384 part = force_reg (QImode, part);
385 emit_insn (gen_pushqi1 (part));
390 ;; Notice a special-case when adding N to SP where N results in a
391 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
393 [(set (reg:HI REG_SP)
394 (match_operand:HI 0 "register_operand" ""))]
396 && frame_pointer_needed
397 && !cfun->calls_alloca
398 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
399 [(set (reg:HI REG_SP)
402 ;;========================================================================
405 ;; Secondary input reload from non-generic 16-bit address spaces
406 (define_insn "reload_in<mode>"
407 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
408 (match_operand:MOVMODE 1 "flash_operand" "m"))
409 (clobber (match_operand:QI 2 "d_register_operand" "=d"))]
410 ;; Fixme: The insn condition must not test the address space.
411 ;; Because the gen tools refuse to generate insns for address spaces
412 ;; and will generate insn-codes.h to look like:
413 ;; #define CODE_FOR_reload_inhi CODE_FOR_nothing
414 "reload_completed || reload_in_progress"
416 return avr_out_lpm (insn, operands, NULL);
418 [(set_attr "adjust_len" "lpm")
419 (set_attr "cc" "clobber")])
427 (define_expand "load<mode>_libgcc"
430 (set (reg:MOVMODE 22)
431 (match_operand:MOVMODE 1 "memory_operand" ""))
432 (set (match_operand:MOVMODE 0 "register_operand" "")
434 "avr_load_libgcc_p (operands[1])"
436 operands[3] = gen_rtx_REG (HImode, REG_Z);
437 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
438 operands[1] = replace_equiv_address (operands[1], operands[3]);
439 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
447 (define_insn "load_<mode>_libgcc"
448 [(set (reg:MOVMODE 22)
449 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
450 "avr_load_libgcc_p (operands[0])
451 && REG_P (XEXP (operands[0], 0))
452 && REG_Z == REGNO (XEXP (operands[0], 0))"
454 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
455 return "%~call __load_%0";
457 [(set_attr "length" "1,2")
458 (set_attr "isa" "rjmp,jmp")
459 (set_attr "cc" "clobber")])
463 ;; "xload8qq_A" "xload8uqq_A"
464 (define_insn_and_split "xload8<mode>_A"
465 [(set (match_operand:ALL1 0 "register_operand" "=r")
466 (match_operand:ALL1 1 "memory_operand" "m"))
467 (clobber (reg:HI REG_Z))]
468 "can_create_pseudo_p()
469 && !avr_xload_libgcc_p (<MODE>mode)
470 && avr_mem_memx_p (operands[1])
471 && REG_P (XEXP (operands[1], 0))"
472 { gcc_unreachable(); }
474 [(clobber (const_int 0))]
476 /* ; Split away the high part of the address. GCC's register allocator
477 ; in not able to allocate segment registers and reload the resulting
478 ; expressions. Notice that no address register can hold a PSImode. */
481 rtx addr = XEXP (operands[1], 0);
482 rtx hi8 = gen_reg_rtx (QImode);
483 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
485 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
486 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
488 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
489 set_mem_addr_space (SET_SRC (single_set (insn)),
490 MEM_ADDR_SPACE (operands[1]));
494 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
495 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
496 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
499 (define_insn_and_split "xload<mode>_A"
500 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
501 (match_operand:MOVMODE 1 "memory_operand" "m"))
502 (clobber (reg:MOVMODE 22))
503 (clobber (reg:QI 21))
504 (clobber (reg:HI REG_Z))]
505 "can_create_pseudo_p()
506 && avr_mem_memx_p (operands[1])
507 && REG_P (XEXP (operands[1], 0))"
508 { gcc_unreachable(); }
510 [(clobber (const_int 0))]
512 rtx addr = XEXP (operands[1], 0);
513 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
514 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
515 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
518 /* Split the address to R21:Z */
519 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
520 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
522 /* Load with code from libgcc */
523 insn = emit_insn (gen_xload_<mode>_libgcc ());
524 set_mem_addr_space (SET_SRC (single_set (insn)), as);
526 /* Move to destination */
527 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
532 ;; Move value from address space memx to a register
533 ;; These insns must be prior to respective generic move insn.
536 ;; "xloadqq_8" "xloaduqq_8"
537 (define_insn "xload<mode>_8"
538 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
539 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
541 "!avr_xload_libgcc_p (<MODE>mode)"
543 return avr_out_xload (insn, operands, NULL);
545 [(set_attr "length" "4,4")
546 (set_attr "adjust_len" "*,xload")
547 (set_attr "isa" "lpmx,lpm")
548 (set_attr "cc" "none")])
550 ;; R21:Z : 24-bit source address
551 ;; R22 : 1-4 byte output
553 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
554 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
555 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
557 ;; "xload_psi_libgcc"
558 (define_insn "xload_<mode>_libgcc"
559 [(set (reg:MOVMODE 22)
560 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
562 (clobber (reg:QI 21))
563 (clobber (reg:HI REG_Z))]
564 "avr_xload_libgcc_p (<MODE>mode)"
566 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
568 output_asm_insn ("%~call __xload_%0", &x_bytes);
571 [(set_attr "type" "xcall")
572 (set_attr "cc" "clobber")])
575 ;; General move expanders
577 ;; "movqi" "movqq" "movuqq"
578 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
579 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
582 (define_expand "mov<mode>"
583 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
584 (match_operand:MOVMODE 1 "general_operand" ""))]
587 rtx dest = operands[0];
588 rtx src = operands[1];
590 if (avr_mem_flash_p (dest))
593 /* One of the operands has to be in a register. */
594 if (!register_operand (dest, <MODE>mode)
595 && !reg_or_0_operand (src, <MODE>mode))
597 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
600 if (avr_mem_memx_p (src))
602 rtx addr = XEXP (src, 0);
605 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
607 if (!avr_xload_libgcc_p (<MODE>mode))
608 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
609 ; insn-emit does not depend on the mode, it's all about operands. */
610 emit_insn (gen_xload8qi_A (dest, src));
612 emit_insn (gen_xload<mode>_A (dest, src));
617 if (avr_load_libgcc_p (src))
619 /* For the small devices, do loads per libgcc call. */
620 emit_insn (gen_load<mode>_libgcc (dest, src));
625 ;;========================================================================
627 ;; The last alternative (any immediate constant to any register) is
628 ;; very expensive. It should be optimized by peephole2 if a scratch
629 ;; register is available, but then that register could just as well be
630 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
631 ;; are call-saved registers, and most of LD_REGS are call-used registers,
632 ;; so this may still be a win for registers live across function calls.
635 ;; "movqq_insn" "movuqq_insn"
636 (define_insn "mov<mode>_insn"
637 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
638 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
639 "register_operand (operands[0], <MODE>mode)
640 || reg_or_0_operand (operands[1], <MODE>mode)"
642 return output_movqi (insn, operands, NULL);
644 [(set_attr "length" "1,1,5,5,1,1,4")
645 (set_attr "adjust_len" "mov8")
646 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
648 ;; This is used in peephole2 to optimize loading immediate constants
649 ;; if a scratch register from LD_REGS happens to be available.
652 ;; "*reload_inqq" "*reload_inuqq"
653 (define_insn "*reload_in<mode>"
654 [(set (match_operand:ALL1 0 "register_operand" "=l")
655 (match_operand:ALL1 1 "const_operand" "i"))
656 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
660 [(set_attr "length" "2")
661 (set_attr "cc" "none")])
664 [(match_scratch:QI 2 "d")
665 (set (match_operand:ALL1 0 "l_register_operand" "")
666 (match_operand:ALL1 1 "const_operand" ""))]
667 ; No need for a clobber reg for 0x0, 0x01 or 0xff
668 "!satisfies_constraint_Y00 (operands[1])
669 && !satisfies_constraint_Y01 (operands[1])
670 && !satisfies_constraint_Ym1 (operands[1])"
671 [(parallel [(set (match_dup 0)
673 (clobber (match_dup 2))])])
675 ;;============================================================================
676 ;; move word (16 bit)
678 ;; Move register $1 to the Stack Pointer register SP.
679 ;; This insn is emit during function prologue/epilogue generation.
680 ;; $2 = 0: We know that IRQs are off
681 ;; $2 = 1: We know that IRQs are on
682 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
683 ;; $2 = -1: We don't know anything about IRQ on/off
684 ;; Always write SP via unspec, see PR50063
686 (define_insn "movhi_sp_r"
687 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
688 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
689 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
693 out %B0,%B1\;out %A0,%A1
694 cli\;out %B0,%B1\;sei\;out %A0,%A1
695 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
697 out %A0,%A1\;out %B0,%B1"
698 [(set_attr "length" "2,4,5,1,2")
699 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
700 (set_attr "cc" "none")])
703 [(match_scratch:QI 2 "d")
704 (set (match_operand:ALL2 0 "l_register_operand" "")
705 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
706 "operands[1] != CONST0_RTX (<MODE>mode)"
707 [(parallel [(set (match_dup 0)
709 (clobber (match_dup 2))])])
711 ;; '*' because it is not used in rtl generation, only in above peephole
713 ;; "*reload_inhq" "*reload_inuhq"
714 ;; "*reload_inha" "*reload_inuha"
715 (define_insn "*reload_in<mode>"
716 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
717 (match_operand:ALL2 1 "immediate_operand" "i"))
718 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
721 return output_reload_inhi (operands, operands[2], NULL);
723 [(set_attr "length" "4")
724 (set_attr "adjust_len" "reload_in16")
725 (set_attr "cc" "clobber")])
728 ;; "*movhq" "*movuhq"
729 ;; "*movha" "*movuha"
730 (define_insn "*mov<mode>"
731 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
732 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
733 "register_operand (operands[0], <MODE>mode)
734 || reg_or_0_operand (operands[1], <MODE>mode)"
736 return output_movhi (insn, operands, NULL);
738 [(set_attr "length" "2,2,6,7,2,6,5,2")
739 (set_attr "adjust_len" "mov16")
740 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
742 (define_peephole2 ; movw
743 [(set (match_operand:ALL1 0 "even_register_operand" "")
744 (match_operand:ALL1 1 "even_register_operand" ""))
745 (set (match_operand:ALL1 2 "odd_register_operand" "")
746 (match_operand:ALL1 3 "odd_register_operand" ""))]
748 && REGNO (operands[0]) == REGNO (operands[2]) - 1
749 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
753 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
754 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
757 (define_peephole2 ; movw_r
758 [(set (match_operand:ALL1 0 "odd_register_operand" "")
759 (match_operand:ALL1 1 "odd_register_operand" ""))
760 (set (match_operand:ALL1 2 "even_register_operand" "")
761 (match_operand:ALL1 3 "even_register_operand" ""))]
763 && REGNO (operands[2]) == REGNO (operands[0]) - 1
764 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
768 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
769 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
772 ;; For LPM loads from AS1 we split
776 ;; Z = Z - sizeof (R)
778 ;; so that the second instruction can be optimized out.
780 (define_split ; "split-lpmx"
781 [(set (match_operand:HISI 0 "register_operand" "")
782 (match_operand:HISI 1 "memory_operand" ""))]
788 (plus:HI (match_dup 3)
791 rtx addr = XEXP (operands[1], 0);
793 if (!avr_mem_flash_p (operands[1])
795 || reg_overlap_mentioned_p (addr, operands[0]))
800 operands[2] = replace_equiv_address (operands[1],
801 gen_rtx_POST_INC (Pmode, addr));
803 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
806 ;;==========================================================================
807 ;; xpointer move (24 bit)
809 (define_peephole2 ; *reload_inpsi
810 [(match_scratch:QI 2 "d")
811 (set (match_operand:PSI 0 "l_register_operand" "")
812 (match_operand:PSI 1 "immediate_operand" ""))
814 "operands[1] != const0_rtx
815 && operands[1] != constm1_rtx"
816 [(parallel [(set (match_dup 0)
818 (clobber (match_dup 2))])])
820 ;; '*' because it is not used in rtl generation.
821 (define_insn "*reload_inpsi"
822 [(set (match_operand:PSI 0 "register_operand" "=r")
823 (match_operand:PSI 1 "immediate_operand" "i"))
824 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
827 return avr_out_reload_inpsi (operands, operands[2], NULL);
829 [(set_attr "length" "6")
830 (set_attr "adjust_len" "reload_in24")
831 (set_attr "cc" "clobber")])
833 (define_insn "*movpsi"
834 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
835 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
836 "register_operand (operands[0], PSImode)
837 || register_operand (operands[1], PSImode)
838 || const0_rtx == operands[1]"
840 return avr_out_movpsi (insn, operands, NULL);
842 [(set_attr "length" "3,3,8,9,4,10")
843 (set_attr "adjust_len" "mov24")
844 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
846 ;;==========================================================================
847 ;; move double word (32 bit)
849 (define_peephole2 ; *reload_insi
850 [(match_scratch:QI 2 "d")
851 (set (match_operand:ALL4 0 "l_register_operand" "")
852 (match_operand:ALL4 1 "immediate_operand" ""))
854 "operands[1] != CONST0_RTX (<MODE>mode)"
855 [(parallel [(set (match_dup 0)
857 (clobber (match_dup 2))])])
859 ;; '*' because it is not used in rtl generation.
861 ;; "*reload_insq" "*reload_inusq"
862 ;; "*reload_insa" "*reload_inusa"
863 (define_insn "*reload_insi"
864 [(set (match_operand:ALL4 0 "register_operand" "=r")
865 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
866 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
869 return output_reload_insisf (operands, operands[2], NULL);
871 [(set_attr "length" "8")
872 (set_attr "adjust_len" "reload_in32")
873 (set_attr "cc" "clobber")])
877 ;; "*movsq" "*movusq"
878 ;; "*movsa" "*movusa"
879 (define_insn "*mov<mode>"
880 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
881 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
882 "register_operand (operands[0], <MODE>mode)
883 || reg_or_0_operand (operands[1], <MODE>mode)"
885 return output_movsisf (insn, operands, NULL);
887 [(set_attr "length" "4,4,8,9,4,10")
888 (set_attr "adjust_len" "mov32")
889 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
891 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
892 ;; move floating point numbers (32 bit)
894 (define_insn "*movsf"
895 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
896 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
897 "register_operand (operands[0], SFmode)
898 || reg_or_0_operand (operands[1], SFmode)"
900 return output_movsisf (insn, operands, NULL);
902 [(set_attr "length" "4,4,8,9,4,10")
903 (set_attr "adjust_len" "mov32")
904 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
906 (define_peephole2 ; *reload_insf
907 [(match_scratch:QI 2 "d")
908 (set (match_operand:SF 0 "l_register_operand" "")
909 (match_operand:SF 1 "const_double_operand" ""))
911 "operands[1] != CONST0_RTX (SFmode)"
912 [(parallel [(set (match_dup 0)
914 (clobber (match_dup 2))])])
916 ;; '*' because it is not used in rtl generation.
917 (define_insn "*reload_insf"
918 [(set (match_operand:SF 0 "register_operand" "=r")
919 (match_operand:SF 1 "const_double_operand" "F"))
920 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
923 return output_reload_insisf (operands, operands[2], NULL);
925 [(set_attr "length" "8")
926 (set_attr "adjust_len" "reload_in32")
927 (set_attr "cc" "clobber")])
929 ;;=========================================================================
930 ;; move string (like memcpy)
932 (define_expand "movmemhi"
933 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
934 (match_operand:BLK 1 "memory_operand" ""))
935 (use (match_operand:HI 2 "const_int_operand" ""))
936 (use (match_operand:HI 3 "const_int_operand" ""))])]
939 if (avr_emit_movmemhi (operands))
945 (define_mode_attr MOVMEM_r_d [(QI "r")
948 ;; $0 : Address Space
949 ;; $1, $2 : Loop register
950 ;; R30 : source address
951 ;; R26 : destination address
955 (define_insn "movmem_<mode>"
956 [(set (mem:BLK (reg:HI REG_X))
957 (mem:BLK (reg:HI REG_Z)))
958 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
960 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
961 (clobber (reg:HI REG_X))
962 (clobber (reg:HI REG_Z))
963 (clobber (reg:QI LPM_REGNO))
964 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
967 return avr_out_movmem (insn, operands, NULL);
969 [(set_attr "adjust_len" "movmem")
970 (set_attr "cc" "clobber")])
973 ;; $0 : Address Space
974 ;; $1 : RAMPZ RAM address
975 ;; R24 : #bytes and loop register
976 ;; R23:Z : 24-bit source address
977 ;; R26 : 16-bit destination address
981 (define_insn "movmemx_<mode>"
982 [(set (mem:BLK (reg:HI REG_X))
983 (mem:BLK (lo_sum:PSI (reg:QI 23)
985 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
988 (clobber (reg:HI REG_X))
989 (clobber (reg:HI REG_Z))
990 (clobber (reg:QI LPM_REGNO))
991 (clobber (reg:HI 24))
992 (clobber (reg:QI 23))
993 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
995 "%~call __movmemx_<mode>"
996 [(set_attr "type" "xcall")
997 (set_attr "cc" "clobber")])
1000 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
1001 ;; memset (%0, %2, %1)
1003 (define_expand "setmemhi"
1004 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1005 (match_operand 2 "const_int_operand" ""))
1006 (use (match_operand:HI 1 "const_int_operand" ""))
1007 (use (match_operand:HI 3 "const_int_operand" ""))
1008 (clobber (match_scratch:HI 4 ""))
1009 (clobber (match_dup 5))])]
1013 enum machine_mode mode;
1015 /* If value to set is not zero, use the library routine. */
1016 if (operands[2] != const0_rtx)
1019 if (!CONST_INT_P (operands[1]))
1022 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1023 operands[5] = gen_rtx_SCRATCH (mode);
1024 operands[1] = copy_to_mode_reg (mode,
1025 gen_int_mode (INTVAL (operands[1]), mode));
1026 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1027 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1031 (define_insn "*clrmemqi"
1032 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1034 (use (match_operand:QI 1 "register_operand" "r"))
1035 (use (match_operand:QI 2 "const_int_operand" "n"))
1036 (clobber (match_scratch:HI 3 "=0"))
1037 (clobber (match_scratch:QI 4 "=&1"))]
1039 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1040 [(set_attr "length" "3")
1041 (set_attr "cc" "clobber")])
1044 (define_insn "*clrmemhi"
1045 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1047 (use (match_operand:HI 1 "register_operand" "!w,d"))
1048 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1049 (clobber (match_scratch:HI 3 "=0,0"))
1050 (clobber (match_scratch:HI 4 "=&1,&1"))]
1053 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1054 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1055 [(set_attr "length" "3,4")
1056 (set_attr "cc" "clobber,clobber")])
1058 (define_expand "strlenhi"
1060 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1061 (match_operand:QI 2 "const_int_operand" "")
1062 (match_operand:HI 3 "immediate_operand" "")]
1065 (plus:HI (match_dup 4)
1067 (parallel [(set (match_operand:HI 0 "register_operand" "")
1068 (minus:HI (match_dup 4)
1070 (clobber (scratch:QI))])]
1074 if (operands[2] != const0_rtx)
1076 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1077 operands[1] = gen_rtx_MEM (BLKmode, addr);
1079 operands[4] = gen_reg_rtx (HImode);
1082 (define_insn "*strlenhi"
1083 [(set (match_operand:HI 0 "register_operand" "=e")
1084 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1086 (match_operand:HI 2 "immediate_operand" "i")]
1089 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1090 [(set_attr "length" "3")
1091 (set_attr "cc" "clobber")])
1093 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1097 ;; "addqq3" "adduqq3"
1098 (define_insn "add<mode>3"
1099 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1100 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1101 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1110 [(set_attr "length" "1,1,1,1,2,2")
1111 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
1114 ;; "addhq3" "adduhq3"
1115 ;; "addha3" "adduha3"
1116 (define_expand "add<mode>3"
1117 [(set (match_operand:ALL2 0 "register_operand" "")
1118 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1119 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1122 if (CONST_INT_P (operands[2]))
1124 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1126 if (can_create_pseudo_p()
1127 && !stack_register_operand (operands[0], HImode)
1128 && !stack_register_operand (operands[1], HImode)
1129 && !d_register_operand (operands[0], HImode)
1130 && !d_register_operand (operands[1], HImode))
1132 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1137 if (CONST_FIXED_P (operands[2]))
1139 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1145 (define_insn "*addhi3_zero_extend"
1146 [(set (match_operand:HI 0 "register_operand" "=r")
1147 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1148 (match_operand:HI 2 "register_operand" "0")))]
1150 "add %A0,%1\;adc %B0,__zero_reg__"
1151 [(set_attr "length" "2")
1152 (set_attr "cc" "set_n")])
1154 (define_insn "*addhi3_zero_extend1"
1155 [(set (match_operand:HI 0 "register_operand" "=r")
1156 (plus:HI (match_operand:HI 1 "register_operand" "0")
1157 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1159 "add %A0,%2\;adc %B0,__zero_reg__"
1160 [(set_attr "length" "2")
1161 (set_attr "cc" "set_n")])
1163 (define_insn "*addhi3.sign_extend1"
1164 [(set (match_operand:HI 0 "register_operand" "=r")
1165 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1166 (match_operand:HI 2 "register_operand" "0")))]
1169 return reg_overlap_mentioned_p (operands[0], operands[1])
1170 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1171 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1173 [(set_attr "length" "5")
1174 (set_attr "cc" "clobber")])
1176 (define_insn "*addhi3_sp"
1177 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1178 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1179 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1182 return avr_out_addto_sp (operands, NULL);
1184 [(set_attr "length" "6")
1185 (set_attr "adjust_len" "addto_sp")])
1188 ;; "*addhq3" "*adduhq3"
1189 ;; "*addha3" "*adduha3"
1190 (define_insn "*add<mode>3"
1191 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1192 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1193 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1196 return avr_out_plus (insn, operands);
1198 [(set_attr "length" "2")
1199 (set_attr "adjust_len" "plus")
1200 (set_attr "cc" "plus")])
1202 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1203 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1204 ;; itself because that insn is special to reload.
1206 (define_peephole2 ; addhi3_clobber
1207 [(set (match_operand:ALL2 0 "d_register_operand" "")
1208 (match_operand:ALL2 1 "const_operand" ""))
1209 (set (match_operand:ALL2 2 "l_register_operand" "")
1210 (plus:ALL2 (match_dup 2)
1212 "peep2_reg_dead_p (2, operands[0])"
1213 [(parallel [(set (match_dup 2)
1214 (plus:ALL2 (match_dup 2)
1216 (clobber (match_dup 3))])]
1218 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1221 ;; Same, but with reload to NO_LD_REGS
1222 ;; Combine *reload_inhi with *addhi3
1224 (define_peephole2 ; addhi3_clobber
1225 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1226 (match_operand:ALL2 1 "const_operand" ""))
1227 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1228 (set (match_operand:ALL2 3 "l_register_operand" "")
1229 (plus:ALL2 (match_dup 3)
1231 "peep2_reg_dead_p (2, operands[0])"
1232 [(parallel [(set (match_dup 3)
1233 (plus:ALL2 (match_dup 3)
1235 (clobber (match_dup 2))])])
1238 ;; "addhq3_clobber" "adduhq3_clobber"
1239 ;; "addha3_clobber" "adduha3_clobber"
1240 (define_insn "add<mode>3_clobber"
1241 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1242 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1243 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1244 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1247 return avr_out_plus (insn, operands);
1249 [(set_attr "length" "4")
1250 (set_attr "adjust_len" "plus")
1251 (set_attr "cc" "plus")])
1255 ;; "addsq3" "addusq3"
1256 ;; "addsa3" "addusa3"
1257 (define_insn "add<mode>3"
1258 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1259 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1260 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1261 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1264 return avr_out_plus (insn, operands);
1266 [(set_attr "length" "4")
1267 (set_attr "adjust_len" "plus")
1268 (set_attr "cc" "plus")])
1270 (define_insn "*addpsi3_zero_extend.qi"
1271 [(set (match_operand:PSI 0 "register_operand" "=r")
1272 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1273 (match_operand:PSI 2 "register_operand" "0")))]
1275 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1276 [(set_attr "length" "3")
1277 (set_attr "cc" "set_n")])
1279 (define_insn "*addpsi3_zero_extend.hi"
1280 [(set (match_operand:PSI 0 "register_operand" "=r")
1281 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1282 (match_operand:PSI 2 "register_operand" "0")))]
1284 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1285 [(set_attr "length" "3")
1286 (set_attr "cc" "set_n")])
1288 (define_insn "*addpsi3_sign_extend.hi"
1289 [(set (match_operand:PSI 0 "register_operand" "=r")
1290 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1291 (match_operand:PSI 2 "register_operand" "0")))]
1293 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1294 [(set_attr "length" "5")
1295 (set_attr "cc" "set_n")])
1297 (define_insn "*addsi3_zero_extend"
1298 [(set (match_operand:SI 0 "register_operand" "=r")
1299 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1300 (match_operand:SI 2 "register_operand" "0")))]
1302 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1303 [(set_attr "length" "4")
1304 (set_attr "cc" "set_n")])
1306 (define_insn "*addsi3_zero_extend.hi"
1307 [(set (match_operand:SI 0 "register_operand" "=r")
1308 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1309 (match_operand:SI 2 "register_operand" "0")))]
1311 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1312 [(set_attr "length" "4")
1313 (set_attr "cc" "set_n")])
1315 (define_insn "addpsi3"
1316 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1317 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1318 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1319 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1322 return avr_out_plus (insn, operands);
1324 [(set_attr "length" "3")
1325 (set_attr "adjust_len" "plus")
1326 (set_attr "cc" "plus")])
1328 (define_insn "subpsi3"
1329 [(set (match_operand:PSI 0 "register_operand" "=r")
1330 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1331 (match_operand:PSI 2 "register_operand" "r")))]
1333 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1334 [(set_attr "length" "3")
1335 (set_attr "cc" "set_czn")])
1337 (define_insn "*subpsi3_zero_extend.qi"
1338 [(set (match_operand:PSI 0 "register_operand" "=r")
1339 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1340 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1342 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1343 [(set_attr "length" "3")
1344 (set_attr "cc" "set_czn")])
1346 (define_insn "*subpsi3_zero_extend.hi"
1347 [(set (match_operand:PSI 0 "register_operand" "=r")
1348 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1349 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1351 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1352 [(set_attr "length" "3")
1353 (set_attr "cc" "set_czn")])
1355 (define_insn "*subpsi3_sign_extend.hi"
1356 [(set (match_operand:PSI 0 "register_operand" "=r")
1357 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1358 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1360 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1361 [(set_attr "length" "5")
1362 (set_attr "cc" "set_czn")])
1364 ;-----------------------------------------------------------------------------
1368 ;; "subqq3" "subuqq3"
1369 (define_insn "sub<mode>3"
1370 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1371 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1372 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1381 [(set_attr "length" "1,1,1,1,2,2")
1382 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
1385 ;; "subhq3" "subuhq3"
1386 ;; "subha3" "subuha3"
1387 (define_insn "sub<mode>3"
1388 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1389 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1390 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1391 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1394 return avr_out_plus (insn, operands);
1396 [(set_attr "adjust_len" "plus")
1397 (set_attr "cc" "plus")])
1399 (define_insn "*subhi3_zero_extend1"
1400 [(set (match_operand:HI 0 "register_operand" "=r")
1401 (minus:HI (match_operand:HI 1 "register_operand" "0")
1402 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1404 "sub %A0,%2\;sbc %B0,__zero_reg__"
1405 [(set_attr "length" "2")
1406 (set_attr "cc" "set_czn")])
1408 (define_insn "*subhi3.sign_extend2"
1409 [(set (match_operand:HI 0 "register_operand" "=r")
1410 (minus:HI (match_operand:HI 1 "register_operand" "0")
1411 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1414 return reg_overlap_mentioned_p (operands[0], operands[2])
1415 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1416 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1418 [(set_attr "length" "5")
1419 (set_attr "cc" "clobber")])
1422 ;; "subsq3" "subusq3"
1423 ;; "subsa3" "subusa3"
1424 (define_insn "sub<mode>3"
1425 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1426 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1427 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1428 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1431 return avr_out_plus (insn, operands);
1433 [(set_attr "adjust_len" "plus")
1434 (set_attr "cc" "plus")])
1436 (define_insn "*subsi3_zero_extend"
1437 [(set (match_operand:SI 0 "register_operand" "=r")
1438 (minus:SI (match_operand:SI 1 "register_operand" "0")
1439 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1441 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1442 [(set_attr "length" "4")
1443 (set_attr "cc" "set_czn")])
1445 (define_insn "*subsi3_zero_extend.hi"
1446 [(set (match_operand:SI 0 "register_operand" "=r")
1447 (minus:SI (match_operand:SI 1 "register_operand" "0")
1448 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1450 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1451 [(set_attr "length" "4")
1452 (set_attr "cc" "set_czn")])
1454 ;******************************************************************************
1457 (define_expand "mulqi3"
1458 [(set (match_operand:QI 0 "register_operand" "")
1459 (mult:QI (match_operand:QI 1 "register_operand" "")
1460 (match_operand:QI 2 "register_operand" "")))]
1465 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1470 (define_insn "*mulqi3_enh"
1471 [(set (match_operand:QI 0 "register_operand" "=r")
1472 (mult:QI (match_operand:QI 1 "register_operand" "r")
1473 (match_operand:QI 2 "register_operand" "r")))]
1478 [(set_attr "length" "3")
1479 (set_attr "cc" "clobber")])
1481 (define_expand "mulqi3_call"
1482 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1483 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1484 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1485 (clobber (reg:QI 22))])
1486 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
1488 (define_insn "*mulqi3_call"
1489 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1490 (clobber (reg:QI 22))]
1493 [(set_attr "type" "xcall")
1494 (set_attr "cc" "clobber")])
1496 ;; "umulqi3_highpart"
1497 ;; "smulqi3_highpart"
1498 (define_insn "<extend_su>mulqi3_highpart"
1499 [(set (match_operand:QI 0 "register_operand" "=r")
1501 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1502 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1505 "mul<extend_s> %1,%2
1508 [(set_attr "length" "3")
1509 (set_attr "cc" "clobber")])
1512 ;; Used when expanding div or mod inline for some special values
1513 (define_insn "*subqi3.ashiftrt7"
1514 [(set (match_operand:QI 0 "register_operand" "=r")
1515 (minus:QI (match_operand:QI 1 "register_operand" "0")
1516 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1520 [(set_attr "length" "2")
1521 (set_attr "cc" "clobber")])
1523 (define_insn "*addqi3.lt0"
1524 [(set (match_operand:QI 0 "register_operand" "=r")
1525 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1527 (match_operand:QI 2 "register_operand" "0")))]
1530 [(set_attr "length" "2")
1531 (set_attr "cc" "clobber")])
1533 (define_insn "*addhi3.lt0"
1534 [(set (match_operand:HI 0 "register_operand" "=w,r")
1535 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1537 (match_operand:HI 2 "register_operand" "0,0")))
1538 (clobber (match_scratch:QI 3 "=X,&1"))]
1541 sbrc %1,7\;adiw %0,1
1542 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1543 [(set_attr "length" "2,3")
1544 (set_attr "cc" "clobber")])
1546 (define_insn "*addpsi3.lt0"
1547 [(set (match_operand:PSI 0 "register_operand" "=r")
1548 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1550 (match_operand:PSI 2 "register_operand" "0")))]
1552 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1553 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1554 [(set_attr "length" "5")
1555 (set_attr "cc" "clobber")])
1557 (define_insn "*addsi3.lt0"
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1561 (match_operand:SI 2 "register_operand" "0")))]
1563 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1564 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1565 [(set_attr "length" "6")
1566 (set_attr "cc" "clobber")])
1568 (define_insn "*umulqihi3.call"
1570 (mult:HI (zero_extend:HI (reg:QI 22))
1571 (zero_extend:HI (reg:QI 24))))
1572 (clobber (reg:QI 21))
1573 (clobber (reg:HI 22))]
1575 "%~call __umulqihi3"
1576 [(set_attr "type" "xcall")
1577 (set_attr "cc" "clobber")])
1581 (define_insn "<extend_u>mulqihi3"
1582 [(set (match_operand:HI 0 "register_operand" "=r")
1583 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1584 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1586 "mul<extend_s> %1,%2
1589 [(set_attr "length" "3")
1590 (set_attr "cc" "clobber")])
1592 (define_insn "usmulqihi3"
1593 [(set (match_operand:HI 0 "register_operand" "=r")
1594 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1595 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1600 [(set_attr "length" "3")
1601 (set_attr "cc" "clobber")])
1603 ;; Above insn is not canonicalized by insn combine, so here is a version with
1604 ;; operands swapped.
1606 (define_insn "*sumulqihi3"
1607 [(set (match_operand:HI 0 "register_operand" "=r")
1608 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1609 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1614 [(set_attr "length" "3")
1615 (set_attr "cc" "clobber")])
1617 ;; One-extend operand 1
1619 (define_insn "*osmulqihi3"
1620 [(set (match_operand:HI 0 "register_operand" "=&r")
1621 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1622 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1628 [(set_attr "length" "4")
1629 (set_attr "cc" "clobber")])
1631 (define_insn "*oumulqihi3"
1632 [(set (match_operand:HI 0 "register_operand" "=&r")
1633 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1634 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1640 [(set_attr "length" "4")
1641 (set_attr "cc" "clobber")])
1643 ;******************************************************************************
1644 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1645 ;******************************************************************************
1647 (define_insn "*maddqi4"
1648 [(set (match_operand:QI 0 "register_operand" "=r")
1649 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1650 (match_operand:QI 2 "register_operand" "r"))
1651 (match_operand:QI 3 "register_operand" "0")))]
1657 [(set_attr "length" "4")
1658 (set_attr "cc" "clobber")])
1660 (define_insn "*msubqi4"
1661 [(set (match_operand:QI 0 "register_operand" "=r")
1662 (minus:QI (match_operand:QI 3 "register_operand" "0")
1663 (mult:QI (match_operand:QI 1 "register_operand" "r")
1664 (match_operand:QI 2 "register_operand" "r"))))]
1669 [(set_attr "length" "4")
1670 (set_attr "cc" "clobber")])
1672 (define_insn_and_split "*maddqi4.const"
1673 [(set (match_operand:QI 0 "register_operand" "=r")
1674 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1675 (match_operand:QI 2 "const_int_operand" "n"))
1676 (match_operand:QI 3 "register_operand" "0")))
1677 (clobber (match_scratch:QI 4 "=&d"))]
1680 "&& reload_completed"
1685 (plus:QI (mult:QI (match_dup 1)
1689 (define_insn_and_split "*msubqi4.const"
1690 [(set (match_operand:QI 0 "register_operand" "=r")
1691 (minus:QI (match_operand:QI 3 "register_operand" "0")
1692 (mult:QI (match_operand:QI 1 "register_operand" "r")
1693 (match_operand:QI 2 "const_int_operand" "n"))))
1694 (clobber (match_scratch:QI 4 "=&d"))]
1697 "&& reload_completed"
1702 (minus:QI (match_dup 3)
1703 (mult:QI (match_dup 1)
1707 ;******************************************************************************
1708 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1709 ;******************************************************************************
1711 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1714 ;; int foo (unsigned char z)
1716 ;; extern int aInt[];
1717 ;; return aInt[3*z+2];
1720 ;; because the constant +4 then is added explicitely instead of consuming it
1721 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1722 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1723 ;; The implementational effort is the same so we are fine with that approach.
1728 (define_insn "*<extend_u>maddqihi4"
1729 [(set (match_operand:HI 0 "register_operand" "=r")
1730 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1731 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1732 (match_operand:HI 3 "register_operand" "0")))]
1735 "mul<extend_s> %1,%2
1739 [(set_attr "length" "4")
1740 (set_attr "cc" "clobber")])
1744 (define_insn "*<extend_u>msubqihi4"
1745 [(set (match_operand:HI 0 "register_operand" "=r")
1746 (minus:HI (match_operand:HI 3 "register_operand" "0")
1747 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1748 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1750 "mul<extend_s> %1,%2
1754 [(set_attr "length" "4")
1755 (set_attr "cc" "clobber")])
1759 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1760 [(set (match_operand:HI 0 "register_operand" "=r")
1761 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1762 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1763 (match_operand:HI 3 "register_operand" "0")))]
1766 && <any_extend:CODE> != <any_extend2:CODE>"
1768 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1769 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1771 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1773 [(set_attr "length" "4")
1774 (set_attr "cc" "clobber")])
1778 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1779 [(set (match_operand:HI 0 "register_operand" "=r")
1780 (minus:HI (match_operand:HI 3 "register_operand" "0")
1781 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1782 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1785 && <any_extend:CODE> != <any_extend2:CODE>"
1787 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1788 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1790 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1792 [(set_attr "length" "4")
1793 (set_attr "cc" "clobber")])
1795 ;; Handle small constants
1797 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1798 ;; This is shorter, faster than MUL and has lower register pressure.
1800 (define_insn_and_split "*umaddqihi4.2"
1801 [(set (match_operand:HI 0 "register_operand" "=r")
1802 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1804 (match_operand:HI 2 "register_operand" "r")))]
1806 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1807 { gcc_unreachable(); }
1811 ; *addhi3_zero_extend
1813 (plus:HI (zero_extend:HI (match_dup 1))
1815 ; *addhi3_zero_extend
1817 (plus:HI (zero_extend:HI (match_dup 1))
1820 ;; "umaddqihi4.uconst"
1821 ;; "maddqihi4.sconst"
1822 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1823 [(set (match_operand:HI 0 "register_operand" "=r")
1824 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1825 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1826 (match_operand:HI 3 "register_operand" "0")))
1827 (clobber (match_scratch:QI 4 "=&d"))]
1830 "&& reload_completed"
1833 ; *umaddqihi4 resp. *maddqihi4
1835 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1836 (any_extend:HI (match_dup 4)))
1839 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1842 ;; "*umsubqihi4.uconst"
1843 ;; "*msubqihi4.sconst"
1844 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1845 [(set (match_operand:HI 0 "register_operand" "=r")
1846 (minus:HI (match_operand:HI 3 "register_operand" "0")
1847 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1848 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1849 (clobber (match_scratch:QI 4 "=&d"))]
1852 "&& reload_completed"
1855 ; *umsubqihi4 resp. *msubqihi4
1857 (minus:HI (match_dup 3)
1858 (mult:HI (any_extend:HI (match_dup 1))
1859 (any_extend:HI (match_dup 4)))))]
1861 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1864 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1865 ;; for MULT with power of 2 and skips trying MULT insn above.
1867 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1868 [(set (match_operand:HI 0 "register_operand" "=r")
1869 (minus:HI (match_operand:HI 3 "register_operand" "0")
1870 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1871 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1872 (clobber (match_scratch:QI 4 "=&d"))]
1875 "&& reload_completed"
1880 (minus:HI (match_dup 3)
1881 (mult:HI (zero_extend:HI (match_dup 1))
1882 (zero_extend:HI (match_dup 4)))))]
1884 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1887 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1888 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1889 ;; because this would require an extra pattern for just one value.
1891 (define_insn_and_split "*msubqihi4.sconst.ashift"
1892 [(set (match_operand:HI 0 "register_operand" "=r")
1893 (minus:HI (match_operand:HI 3 "register_operand" "0")
1894 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1895 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1896 (clobber (match_scratch:QI 4 "=&d"))]
1899 "&& reload_completed"
1904 (minus:HI (match_dup 3)
1905 (mult:HI (sign_extend:HI (match_dup 1))
1906 (sign_extend:HI (match_dup 4)))))]
1908 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1911 ;; For signed/unsigned combinations that require narrow constraint "a"
1912 ;; just provide a pattern if signed/unsigned combination is actually needed.
1914 (define_insn_and_split "*sumaddqihi4.uconst"
1915 [(set (match_operand:HI 0 "register_operand" "=r")
1916 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1917 (match_operand:HI 2 "u8_operand" "M"))
1918 (match_operand:HI 3 "register_operand" "0")))
1919 (clobber (match_scratch:QI 4 "=&a"))]
1921 && !s8_operand (operands[2], VOIDmode)"
1923 "&& reload_completed"
1928 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1929 (zero_extend:HI (match_dup 4)))
1932 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1935 (define_insn_and_split "*sumsubqihi4.uconst"
1936 [(set (match_operand:HI 0 "register_operand" "=r")
1937 (minus:HI (match_operand:HI 3 "register_operand" "0")
1938 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1939 (match_operand:HI 2 "u8_operand" "M"))))
1940 (clobber (match_scratch:QI 4 "=&a"))]
1942 && !s8_operand (operands[2], VOIDmode)"
1944 "&& reload_completed"
1949 (minus:HI (match_dup 3)
1950 (mult:HI (sign_extend:HI (match_dup 1))
1951 (zero_extend:HI (match_dup 4)))))]
1953 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1956 ;******************************************************************************
1957 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1958 ;******************************************************************************
1960 ;; "*muluqihi3.uconst"
1961 ;; "*mulsqihi3.sconst"
1962 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1963 [(set (match_operand:HI 0 "register_operand" "=r")
1964 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1965 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1966 (clobber (match_scratch:QI 3 "=&d"))]
1969 "&& reload_completed"
1972 ; umulqihi3 resp. mulqihi3
1974 (mult:HI (any_extend:HI (match_dup 1))
1975 (any_extend:HI (match_dup 3))))]
1977 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1980 (define_insn_and_split "*muluqihi3.sconst"
1981 [(set (match_operand:HI 0 "register_operand" "=r")
1982 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1983 (match_operand:HI 2 "s8_operand" "n")))
1984 (clobber (match_scratch:QI 3 "=&a"))]
1987 "&& reload_completed"
1992 (mult:HI (zero_extend:HI (match_dup 1))
1993 (sign_extend:HI (match_dup 3))))]
1995 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1998 (define_insn_and_split "*mulsqihi3.uconst"
1999 [(set (match_operand:HI 0 "register_operand" "=r")
2000 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2001 (match_operand:HI 2 "u8_operand" "M")))
2002 (clobber (match_scratch:QI 3 "=&a"))]
2005 "&& reload_completed"
2010 (mult:HI (zero_extend:HI (match_dup 3))
2011 (sign_extend:HI (match_dup 1))))]
2013 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2016 (define_insn_and_split "*mulsqihi3.oconst"
2017 [(set (match_operand:HI 0 "register_operand" "=&r")
2018 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2019 (match_operand:HI 2 "o8_operand" "n")))
2020 (clobber (match_scratch:QI 3 "=&a"))]
2023 "&& reload_completed"
2028 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2029 (sign_extend:HI (match_dup 1))))]
2031 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2034 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2035 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2036 ;; at that time. Fix that.
2038 (define_insn "*ashiftqihi2.signx.1"
2039 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2040 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2044 lsl %A0\;sbc %B0,%B0
2045 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2046 [(set_attr "length" "2,3")
2047 (set_attr "cc" "clobber")])
2049 (define_insn_and_split "*ashifthi3.signx.const"
2050 [(set (match_operand:HI 0 "register_operand" "=r")
2051 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2052 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2053 (clobber (match_scratch:QI 3 "=&d"))]
2056 "&& reload_completed"
2061 (mult:HI (sign_extend:HI (match_dup 1))
2062 (sign_extend:HI (match_dup 3))))]
2064 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2067 (define_insn_and_split "*ashifthi3.signx.const7"
2068 [(set (match_operand:HI 0 "register_operand" "=r")
2069 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2071 (clobber (match_scratch:QI 2 "=&a"))]
2074 "&& reload_completed"
2079 (mult:HI (zero_extend:HI (match_dup 2))
2080 (sign_extend:HI (match_dup 1))))]
2082 operands[3] = gen_int_mode (1 << 7, QImode);
2085 (define_insn_and_split "*ashifthi3.zerox.const"
2086 [(set (match_operand:HI 0 "register_operand" "=r")
2087 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2088 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2089 (clobber (match_scratch:QI 3 "=&d"))]
2092 "&& reload_completed"
2097 (mult:HI (zero_extend:HI (match_dup 1))
2098 (zero_extend:HI (match_dup 3))))]
2100 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2103 ;******************************************************************************
2104 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2105 ;******************************************************************************
2107 (define_insn "mulsqihi3"
2108 [(set (match_operand:HI 0 "register_operand" "=&r")
2109 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2110 (match_operand:HI 2 "register_operand" "a")))]
2117 [(set_attr "length" "5")
2118 (set_attr "cc" "clobber")])
2120 (define_insn "muluqihi3"
2121 [(set (match_operand:HI 0 "register_operand" "=&r")
2122 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2123 (match_operand:HI 2 "register_operand" "r")))]
2130 [(set_attr "length" "5")
2131 (set_attr "cc" "clobber")])
2133 ;; one-extend operand 1
2135 (define_insn "muloqihi3"
2136 [(set (match_operand:HI 0 "register_operand" "=&r")
2137 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2138 (match_operand:HI 2 "register_operand" "r")))]
2146 [(set_attr "length" "6")
2147 (set_attr "cc" "clobber")])
2149 ;******************************************************************************
2151 (define_expand "mulhi3"
2152 [(set (match_operand:HI 0 "register_operand" "")
2153 (mult:HI (match_operand:HI 1 "register_operand" "")
2154 (match_operand:HI 2 "register_or_s9_operand" "")))]
2159 if (!register_operand (operands[2], HImode))
2160 operands[2] = force_reg (HImode, operands[2]);
2162 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2166 /* For small constants we can do better by extending them on the fly.
2167 The constant can be loaded in one instruction and the widening
2168 multiplication is shorter. First try the unsigned variant because it
2169 allows constraint "d" instead of "a" for the signed version. */
2171 if (s9_operand (operands[2], HImode))
2173 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2175 if (u8_operand (operands[2], HImode))
2177 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2179 else if (s8_operand (operands[2], HImode))
2181 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2185 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2191 if (!register_operand (operands[2], HImode))
2192 operands[2] = force_reg (HImode, operands[2]);
2195 (define_insn "*mulhi3_enh"
2196 [(set (match_operand:HI 0 "register_operand" "=&r")
2197 (mult:HI (match_operand:HI 1 "register_operand" "r")
2198 (match_operand:HI 2 "register_operand" "r")))]
2201 return REGNO (operands[1]) == REGNO (operands[2])
2202 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2203 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2205 [(set_attr "length" "7")
2206 (set_attr "cc" "clobber")])
2208 (define_expand "mulhi3_call"
2209 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2210 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2211 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2212 (clobber (reg:HI 22))
2213 (clobber (reg:QI 21))])
2214 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
2216 (define_insn "*mulhi3_call"
2217 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2218 (clobber (reg:HI 22))
2219 (clobber (reg:QI 21))]
2222 [(set_attr "type" "xcall")
2223 (set_attr "cc" "clobber")])
2225 ;; To support widening multiplication with constant we postpone
2226 ;; expanding to the implicit library call until post combine and
2227 ;; prior to register allocation. Clobber all hard registers that
2228 ;; might be used by the (widening) multiply until it is split and
2229 ;; it's final register footprint is worked out.
2231 (define_expand "mulsi3"
2232 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2233 (mult:SI (match_operand:SI 1 "register_operand" "")
2234 (match_operand:SI 2 "nonmemory_operand" "")))
2235 (clobber (reg:HI 26))
2236 (clobber (reg:DI 18))])]
2239 if (u16_operand (operands[2], SImode))
2241 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2242 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2246 if (o16_operand (operands[2], SImode))
2248 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2249 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2254 (define_insn_and_split "*mulsi3"
2255 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2256 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2257 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2258 (clobber (reg:HI 26))
2259 (clobber (reg:DI 18))]
2260 "AVR_HAVE_MUL && !reload_completed"
2261 { gcc_unreachable(); }
2267 (parallel [(set (reg:SI 22)
2268 (mult:SI (reg:SI 22)
2270 (clobber (reg:HI 26))])
2274 if (u16_operand (operands[2], SImode))
2276 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2277 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2281 if (o16_operand (operands[2], SImode))
2283 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2284 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2291 (define_insn_and_split "mulu<mode>si3"
2292 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2293 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2294 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2295 (clobber (reg:HI 26))
2296 (clobber (reg:DI 18))]
2297 "AVR_HAVE_MUL && !reload_completed"
2298 { gcc_unreachable(); }
2305 (mult:SI (zero_extend:SI (reg:HI 26))
2310 /* Do the QI -> HI extension explicitely before the multiplication. */
2311 /* Do the HI -> SI extension implicitely and after the multiplication. */
2313 if (QImode == <MODE>mode)
2314 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2316 if (u16_operand (operands[2], SImode))
2318 operands[1] = force_reg (HImode, operands[1]);
2319 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2320 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2327 (define_insn_and_split "muls<mode>si3"
2328 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2329 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2330 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2331 (clobber (reg:HI 26))
2332 (clobber (reg:DI 18))]
2333 "AVR_HAVE_MUL && !reload_completed"
2334 { gcc_unreachable(); }
2341 (mult:SI (sign_extend:SI (reg:HI 26))
2346 /* Do the QI -> HI extension explicitely before the multiplication. */
2347 /* Do the HI -> SI extension implicitely and after the multiplication. */
2349 if (QImode == <MODE>mode)
2350 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2352 if (u16_operand (operands[2], SImode)
2353 || s16_operand (operands[2], SImode))
2355 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2357 operands[1] = force_reg (HImode, operands[1]);
2359 if (u16_operand (operands[2], SImode))
2360 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2362 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2368 ;; One-extend operand 1
2370 (define_insn_and_split "mulohisi3"
2371 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2372 (mult:SI (not:SI (zero_extend:SI
2373 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2374 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2375 (clobber (reg:HI 26))
2376 (clobber (reg:DI 18))]
2377 "AVR_HAVE_MUL && !reload_completed"
2378 { gcc_unreachable(); }
2385 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2392 (define_expand "<extend_u>mulhisi3"
2393 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2394 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2395 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2396 (clobber (reg:HI 26))
2397 (clobber (reg:DI 18))])]
2400 (define_expand "usmulhisi3"
2401 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2402 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2403 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2404 (clobber (reg:HI 26))
2405 (clobber (reg:DI 18))])]
2408 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2409 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2410 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2411 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2412 (define_insn_and_split
2413 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2414 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2415 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2416 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2417 (clobber (reg:HI 26))
2418 (clobber (reg:DI 18))]
2419 "AVR_HAVE_MUL && !reload_completed"
2420 { gcc_unreachable(); }
2427 (mult:SI (match_dup 3)
2432 rtx xop1 = operands[1];
2433 rtx xop2 = operands[2];
2435 /* Do the QI -> HI extension explicitely before the multiplication. */
2436 /* Do the HI -> SI extension implicitely and after the multiplication. */
2438 if (QImode == <QIHI:MODE>mode)
2439 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2441 if (QImode == <QIHI2:MODE>mode)
2442 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2444 if (<any_extend:CODE> == <any_extend2:CODE>
2445 || <any_extend:CODE> == ZERO_EXTEND)
2449 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2450 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2454 /* <any_extend:CODE> = SIGN_EXTEND */
2455 /* <any_extend2:CODE> = ZERO_EXTEND */
2459 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2460 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2464 ;; "smulhi3_highpart"
2465 ;; "umulhi3_highpart"
2466 (define_expand "<extend_su>mulhi3_highpart"
2468 (match_operand:HI 1 "nonmemory_operand" ""))
2470 (match_operand:HI 2 "nonmemory_operand" ""))
2471 (parallel [(set (reg:HI 24)
2472 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2473 (any_extend:SI (reg:HI 26)))
2475 (clobber (reg:HI 22))])
2476 (set (match_operand:HI 0 "register_operand" "")
2481 (define_insn "*mulsi3_call"
2483 (mult:SI (reg:SI 22)
2485 (clobber (reg:HI 26))]
2488 [(set_attr "type" "xcall")
2489 (set_attr "cc" "clobber")])
2492 ;; "*umulhisi3_call"
2493 (define_insn "*<extend_u>mulhisi3_call"
2495 (mult:SI (any_extend:SI (reg:HI 18))
2496 (any_extend:SI (reg:HI 26))))]
2498 "%~call __<extend_u>mulhisi3"
2499 [(set_attr "type" "xcall")
2500 (set_attr "cc" "clobber")])
2502 ;; "*umulhi3_highpart_call"
2503 ;; "*smulhi3_highpart_call"
2504 (define_insn "*<extend_su>mulhi3_highpart_call"
2506 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2507 (any_extend:SI (reg:HI 26)))
2509 (clobber (reg:HI 22))]
2511 "%~call __<extend_u>mulhisi3"
2512 [(set_attr "type" "xcall")
2513 (set_attr "cc" "clobber")])
2515 (define_insn "*usmulhisi3_call"
2517 (mult:SI (zero_extend:SI (reg:HI 18))
2518 (sign_extend:SI (reg:HI 26))))]
2520 "%~call __usmulhisi3"
2521 [(set_attr "type" "xcall")
2522 (set_attr "cc" "clobber")])
2524 (define_insn "*mul<extend_su>hisi3_call"
2526 (mult:SI (any_extend:SI (reg:HI 26))
2529 "%~call __mul<extend_su>hisi3"
2530 [(set_attr "type" "xcall")
2531 (set_attr "cc" "clobber")])
2533 (define_insn "*mulohisi3_call"
2535 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2538 "%~call __mulohisi3"
2539 [(set_attr "type" "xcall")
2540 (set_attr "cc" "clobber")])
2542 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2545 ;; Generate lib1funcs.S calls ourselves, because:
2546 ;; - we know exactly which registers are clobbered (for QI and HI
2547 ;; modes, some of the call-used registers are preserved)
2548 ;; - we get both the quotient and the remainder at no extra cost
2549 ;; - we split the patterns only after the first CSE passes because
2550 ;; CSE has problems to operate on hard regs.
2552 (define_insn_and_split "divmodqi4"
2553 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2554 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2555 (match_operand:QI 2 "pseudo_register_operand" "")))
2556 (set (match_operand:QI 3 "pseudo_register_operand" "")
2557 (mod:QI (match_dup 1) (match_dup 2)))
2558 (clobber (reg:QI 22))
2559 (clobber (reg:QI 23))
2560 (clobber (reg:QI 24))
2561 (clobber (reg:QI 25))])]
2563 "this divmodqi4 pattern should have been splitted;"
2565 [(set (reg:QI 24) (match_dup 1))
2566 (set (reg:QI 22) (match_dup 2))
2567 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2568 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2569 (clobber (reg:QI 22))
2570 (clobber (reg:QI 23))])
2571 (set (match_dup 0) (reg:QI 24))
2572 (set (match_dup 3) (reg:QI 25))])
2574 (define_insn "*divmodqi4_call"
2575 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2576 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2577 (clobber (reg:QI 22))
2578 (clobber (reg:QI 23))]
2580 "%~call __divmodqi4"
2581 [(set_attr "type" "xcall")
2582 (set_attr "cc" "clobber")])
2584 (define_insn_and_split "udivmodqi4"
2585 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2586 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2587 (match_operand:QI 2 "pseudo_register_operand" "")))
2588 (set (match_operand:QI 3 "pseudo_register_operand" "")
2589 (umod:QI (match_dup 1) (match_dup 2)))
2590 (clobber (reg:QI 22))
2591 (clobber (reg:QI 23))
2592 (clobber (reg:QI 24))
2593 (clobber (reg:QI 25))])]
2595 "this udivmodqi4 pattern should have been splitted;"
2597 [(set (reg:QI 24) (match_dup 1))
2598 (set (reg:QI 22) (match_dup 2))
2599 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2600 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2601 (clobber (reg:QI 23))])
2602 (set (match_dup 0) (reg:QI 24))
2603 (set (match_dup 3) (reg:QI 25))])
2605 (define_insn "*udivmodqi4_call"
2606 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2607 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2608 (clobber (reg:QI 23))]
2610 "%~call __udivmodqi4"
2611 [(set_attr "type" "xcall")
2612 (set_attr "cc" "clobber")])
2614 (define_insn_and_split "divmodhi4"
2615 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2616 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2617 (match_operand:HI 2 "pseudo_register_operand" "")))
2618 (set (match_operand:HI 3 "pseudo_register_operand" "")
2619 (mod:HI (match_dup 1) (match_dup 2)))
2620 (clobber (reg:QI 21))
2621 (clobber (reg:HI 22))
2622 (clobber (reg:HI 24))
2623 (clobber (reg:HI 26))])]
2625 "this should have been splitted;"
2627 [(set (reg:HI 24) (match_dup 1))
2628 (set (reg:HI 22) (match_dup 2))
2629 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2630 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2631 (clobber (reg:HI 26))
2632 (clobber (reg:QI 21))])
2633 (set (match_dup 0) (reg:HI 22))
2634 (set (match_dup 3) (reg:HI 24))])
2636 (define_insn "*divmodhi4_call"
2637 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2638 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2639 (clobber (reg:HI 26))
2640 (clobber (reg:QI 21))]
2642 "%~call __divmodhi4"
2643 [(set_attr "type" "xcall")
2644 (set_attr "cc" "clobber")])
2646 (define_insn_and_split "udivmodhi4"
2647 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2648 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2649 (match_operand:HI 2 "pseudo_register_operand" "")))
2650 (set (match_operand:HI 3 "pseudo_register_operand" "")
2651 (umod:HI (match_dup 1) (match_dup 2)))
2652 (clobber (reg:QI 21))
2653 (clobber (reg:HI 22))
2654 (clobber (reg:HI 24))
2655 (clobber (reg:HI 26))])]
2657 "this udivmodhi4 pattern should have been splitted.;"
2659 [(set (reg:HI 24) (match_dup 1))
2660 (set (reg:HI 22) (match_dup 2))
2661 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2662 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2663 (clobber (reg:HI 26))
2664 (clobber (reg:QI 21))])
2665 (set (match_dup 0) (reg:HI 22))
2666 (set (match_dup 3) (reg:HI 24))])
2668 (define_insn "*udivmodhi4_call"
2669 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2670 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2671 (clobber (reg:HI 26))
2672 (clobber (reg:QI 21))]
2674 "%~call __udivmodhi4"
2675 [(set_attr "type" "xcall")
2676 (set_attr "cc" "clobber")])
2678 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2681 ;; To support widening multiplication with constant we postpone
2682 ;; expanding to the implicit library call until post combine and
2683 ;; prior to register allocation. Clobber all hard registers that
2684 ;; might be used by the (widening) multiply until it is split and
2685 ;; it's final register footprint is worked out.
2687 (define_expand "mulpsi3"
2688 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2689 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2690 (match_operand:PSI 2 "nonmemory_operand" "")))
2691 (clobber (reg:HI 26))
2692 (clobber (reg:DI 18))])]
2695 if (s8_operand (operands[2], PSImode))
2697 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2698 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2703 (define_insn "*umulqihipsi3"
2704 [(set (match_operand:PSI 0 "register_operand" "=&r")
2705 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2706 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2715 [(set_attr "length" "7")
2716 (set_attr "cc" "clobber")])
2718 (define_insn "*umulhiqipsi3"
2719 [(set (match_operand:PSI 0 "register_operand" "=&r")
2720 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2721 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2729 adc %C0,__zero_reg__"
2730 [(set_attr "length" "7")
2731 (set_attr "cc" "clobber")])
2733 (define_insn_and_split "mulsqipsi3"
2734 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2735 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2736 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2737 (clobber (reg:HI 26))
2738 (clobber (reg:DI 18))]
2739 "AVR_HAVE_MUL && !reload_completed"
2740 { gcc_unreachable(); }
2747 (mult:PSI (sign_extend:PSI (reg:QI 25))
2752 (define_insn_and_split "*mulpsi3"
2753 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2754 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2755 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2756 (clobber (reg:HI 26))
2757 (clobber (reg:DI 18))]
2758 "AVR_HAVE_MUL && !reload_completed"
2759 { gcc_unreachable(); }
2765 (parallel [(set (reg:PSI 22)
2766 (mult:PSI (reg:PSI 22)
2768 (clobber (reg:QI 21))
2769 (clobber (reg:QI 25))
2770 (clobber (reg:HI 26))])
2774 if (s8_operand (operands[2], PSImode))
2776 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2777 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2782 (define_insn "*mulsqipsi3.libgcc"
2784 (mult:PSI (sign_extend:PSI (reg:QI 25))
2787 "%~call __mulsqipsi3"
2788 [(set_attr "type" "xcall")
2789 (set_attr "cc" "clobber")])
2791 (define_insn "*mulpsi3.libgcc"
2793 (mult:PSI (reg:PSI 22)
2795 (clobber (reg:QI 21))
2796 (clobber (reg:QI 25))
2797 (clobber (reg:HI 26))]
2800 [(set_attr "type" "xcall")
2801 (set_attr "cc" "clobber")])
2804 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2805 ;; 24-bit signed/unsigned division and modulo.
2806 ;; Notice that the libgcc implementation return the quotient in R22
2807 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2808 ;; implementation works the other way round.
2810 (define_insn_and_split "divmodpsi4"
2811 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2812 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2813 (match_operand:PSI 2 "pseudo_register_operand" "")))
2814 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2815 (mod:PSI (match_dup 1)
2817 (clobber (reg:DI 18))
2818 (clobber (reg:QI 26))])]
2820 { gcc_unreachable(); }
2822 [(set (reg:PSI 22) (match_dup 1))
2823 (set (reg:PSI 18) (match_dup 2))
2824 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2825 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2826 (clobber (reg:QI 21))
2827 (clobber (reg:QI 25))
2828 (clobber (reg:QI 26))])
2829 (set (match_dup 0) (reg:PSI 22))
2830 (set (match_dup 3) (reg:PSI 18))])
2832 (define_insn "*divmodpsi4_call"
2833 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2834 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2835 (clobber (reg:QI 21))
2836 (clobber (reg:QI 25))
2837 (clobber (reg:QI 26))]
2839 "%~call __divmodpsi4"
2840 [(set_attr "type" "xcall")
2841 (set_attr "cc" "clobber")])
2843 (define_insn_and_split "udivmodpsi4"
2844 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2845 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2846 (match_operand:PSI 2 "pseudo_register_operand" "")))
2847 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2848 (umod:PSI (match_dup 1)
2850 (clobber (reg:DI 18))
2851 (clobber (reg:QI 26))])]
2853 { gcc_unreachable(); }
2855 [(set (reg:PSI 22) (match_dup 1))
2856 (set (reg:PSI 18) (match_dup 2))
2857 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2858 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2859 (clobber (reg:QI 21))
2860 (clobber (reg:QI 25))
2861 (clobber (reg:QI 26))])
2862 (set (match_dup 0) (reg:PSI 22))
2863 (set (match_dup 3) (reg:PSI 18))])
2865 (define_insn "*udivmodpsi4_call"
2866 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2867 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2868 (clobber (reg:QI 21))
2869 (clobber (reg:QI 25))
2870 (clobber (reg:QI 26))]
2872 "%~call __udivmodpsi4"
2873 [(set_attr "type" "xcall")
2874 (set_attr "cc" "clobber")])
2876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2878 (define_insn_and_split "divmodsi4"
2879 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2880 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2881 (match_operand:SI 2 "pseudo_register_operand" "")))
2882 (set (match_operand:SI 3 "pseudo_register_operand" "")
2883 (mod:SI (match_dup 1) (match_dup 2)))
2884 (clobber (reg:SI 18))
2885 (clobber (reg:SI 22))
2886 (clobber (reg:HI 26))
2887 (clobber (reg:HI 30))])]
2889 "this divmodsi4 pattern should have been splitted;"
2891 [(set (reg:SI 22) (match_dup 1))
2892 (set (reg:SI 18) (match_dup 2))
2893 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2894 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2895 (clobber (reg:HI 26))
2896 (clobber (reg:HI 30))])
2897 (set (match_dup 0) (reg:SI 18))
2898 (set (match_dup 3) (reg:SI 22))])
2900 (define_insn "*divmodsi4_call"
2901 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2902 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2903 (clobber (reg:HI 26))
2904 (clobber (reg:HI 30))]
2906 "%~call __divmodsi4"
2907 [(set_attr "type" "xcall")
2908 (set_attr "cc" "clobber")])
2910 (define_insn_and_split "udivmodsi4"
2911 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2912 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2913 (match_operand:SI 2 "pseudo_register_operand" "")))
2914 (set (match_operand:SI 3 "pseudo_register_operand" "")
2915 (umod:SI (match_dup 1) (match_dup 2)))
2916 (clobber (reg:SI 18))
2917 (clobber (reg:SI 22))
2918 (clobber (reg:HI 26))
2919 (clobber (reg:HI 30))])]
2921 "this udivmodsi4 pattern should have been splitted;"
2923 [(set (reg:SI 22) (match_dup 1))
2924 (set (reg:SI 18) (match_dup 2))
2925 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2926 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2927 (clobber (reg:HI 26))
2928 (clobber (reg:HI 30))])
2929 (set (match_dup 0) (reg:SI 18))
2930 (set (match_dup 3) (reg:SI 22))])
2932 (define_insn "*udivmodsi4_call"
2933 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2934 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2935 (clobber (reg:HI 26))
2936 (clobber (reg:HI 30))]
2938 "%~call __udivmodsi4"
2939 [(set_attr "type" "xcall")
2940 (set_attr "cc" "clobber")])
2942 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2945 (define_insn "andqi3"
2946 [(set (match_operand:QI 0 "register_operand" "=??r,d")
2947 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2948 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2953 [(set_attr "length" "1,1")
2954 (set_attr "cc" "set_zn,set_zn")])
2956 (define_insn "andhi3"
2957 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
2958 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2959 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2960 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2963 if (which_alternative == 0)
2964 return "and %A0,%A2\;and %B0,%B2";
2965 else if (which_alternative == 1)
2966 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2968 return avr_out_bitop (insn, operands, NULL);
2970 [(set_attr "length" "2,2,2,4,4")
2971 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2972 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2974 (define_insn "andpsi3"
2975 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
2976 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2977 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2978 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2981 if (which_alternative == 0)
2982 return "and %A0,%A2" CR_TAB
2983 "and %B0,%B2" CR_TAB
2986 return avr_out_bitop (insn, operands, NULL);
2988 [(set_attr "length" "3,3,6,6")
2989 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2990 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2992 (define_insn "andsi3"
2993 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
2994 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2995 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2996 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2999 if (which_alternative == 0)
3000 return "and %0,%2" CR_TAB
3001 "and %B0,%B2" CR_TAB
3002 "and %C0,%C2" CR_TAB
3005 return avr_out_bitop (insn, operands, NULL);
3007 [(set_attr "length" "4,4,8,8")
3008 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3009 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3011 (define_peephole2 ; andi
3012 [(set (match_operand:QI 0 "d_register_operand" "")
3013 (and:QI (match_dup 0)
3014 (match_operand:QI 1 "const_int_operand" "")))
3016 (and:QI (match_dup 0)
3017 (match_operand:QI 2 "const_int_operand" "")))]
3019 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3021 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3024 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3027 (define_insn "iorqi3"
3028 [(set (match_operand:QI 0 "register_operand" "=??r,d")
3029 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3030 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3035 [(set_attr "length" "1,1")
3036 (set_attr "cc" "set_zn,set_zn")])
3038 (define_insn "iorhi3"
3039 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3040 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3041 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3042 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3045 if (which_alternative == 0)
3046 return "or %A0,%A2\;or %B0,%B2";
3047 else if (which_alternative == 1)
3048 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3050 return avr_out_bitop (insn, operands, NULL);
3052 [(set_attr "length" "2,2,2,4,4")
3053 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3054 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3056 (define_insn "iorpsi3"
3057 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3058 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3059 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3060 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3063 if (which_alternative == 0)
3064 return "or %A0,%A2" CR_TAB
3068 return avr_out_bitop (insn, operands, NULL);
3070 [(set_attr "length" "3,3,6,6")
3071 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3072 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3074 (define_insn "iorsi3"
3075 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3076 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3077 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3078 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3081 if (which_alternative == 0)
3082 return "or %0,%2" CR_TAB
3087 return avr_out_bitop (insn, operands, NULL);
3089 [(set_attr "length" "4,4,8,8")
3090 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3091 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3093 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3096 (define_insn "xorqi3"
3097 [(set (match_operand:QI 0 "register_operand" "=r")
3098 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3099 (match_operand:QI 2 "register_operand" "r")))]
3102 [(set_attr "length" "1")
3103 (set_attr "cc" "set_zn")])
3105 (define_insn "xorhi3"
3106 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
3107 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3108 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3109 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3112 if (which_alternative == 0)
3113 return "eor %A0,%A2\;eor %B0,%B2";
3115 return avr_out_bitop (insn, operands, NULL);
3117 [(set_attr "length" "2,2,4")
3118 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3119 (set_attr "cc" "set_n,clobber,clobber")])
3121 (define_insn "xorpsi3"
3122 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
3123 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3124 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3125 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3128 if (which_alternative == 0)
3129 return "eor %A0,%A2" CR_TAB
3130 "eor %B0,%B2" CR_TAB
3133 return avr_out_bitop (insn, operands, NULL);
3135 [(set_attr "length" "3,6,6")
3136 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3137 (set_attr "cc" "set_n,clobber,clobber")])
3139 (define_insn "xorsi3"
3140 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
3141 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3142 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3143 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3146 if (which_alternative == 0)
3147 return "eor %0,%2" CR_TAB
3148 "eor %B0,%B2" CR_TAB
3149 "eor %C0,%C2" CR_TAB
3152 return avr_out_bitop (insn, operands, NULL);
3154 [(set_attr "length" "4,8,8")
3155 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3156 (set_attr "cc" "set_n,clobber,clobber")])
3158 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3161 (define_expand "rotlqi3"
3162 [(set (match_operand:QI 0 "register_operand" "")
3163 (rotate:QI (match_operand:QI 1 "register_operand" "")
3164 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3167 if (!CONST_INT_P (operands[2]))
3170 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3173 ;; Expander used by __builtin_avr_swap
3174 (define_expand "rotlqi3_4"
3175 [(set (match_operand:QI 0 "register_operand" "")
3176 (rotate:QI (match_operand:QI 1 "register_operand" "")
3179 (define_insn "*rotlqi3"
3180 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3181 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3182 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3185 lsl %0\;adc %0,__zero_reg__
3186 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3187 swap %0\;bst %0,0\;ror %0\;bld %0,7
3189 swap %0\;lsl %0\;adc %0,__zero_reg__
3190 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3191 bst %0,0\;ror %0\;bld %0,7
3193 [(set_attr "length" "2,4,4,1,3,5,3,0")
3194 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3196 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3197 ;; a whole number of bytes. The split creates the appropriate moves and
3198 ;; considers all overlap situations.
3200 ;; HImode does not need scratch. Use attribute for this constraint.
3202 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3203 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3208 (define_expand "rotl<mode>3"
3209 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3210 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3211 (match_operand:VOID 2 "const_int_operand" "")))
3212 (clobber (match_dup 3))])]
3217 if (!CONST_INT_P (operands[2]))
3220 offset = INTVAL (operands[2]);
3222 if (0 == offset % 8)
3224 if (AVR_HAVE_MOVW && 0 == offset % 16)
3225 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3227 operands[3] = gen_rtx_SCRATCH (QImode);
3229 else if (offset == 1
3230 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3232 /*; Support rotate left/right by 1 */
3234 emit_move_insn (operands[0],
3235 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3242 (define_insn "*rotlhi2.1"
3243 [(set (match_operand:HI 0 "register_operand" "=r")
3244 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3247 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3248 [(set_attr "length" "3")
3249 (set_attr "cc" "clobber")])
3251 (define_insn "*rotlhi2.15"
3252 [(set (match_operand:HI 0 "register_operand" "=r")
3253 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3256 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3257 [(set_attr "length" "4")
3258 (set_attr "cc" "clobber")])
3260 (define_insn "*rotlpsi2.1"
3261 [(set (match_operand:PSI 0 "register_operand" "=r")
3262 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3265 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3266 [(set_attr "length" "4")
3267 (set_attr "cc" "clobber")])
3269 (define_insn "*rotlpsi2.23"
3270 [(set (match_operand:PSI 0 "register_operand" "=r")
3271 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3274 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3275 [(set_attr "length" "5")
3276 (set_attr "cc" "clobber")])
3278 (define_insn "*rotlsi2.1"
3279 [(set (match_operand:SI 0 "register_operand" "=r")
3280 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3283 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3284 [(set_attr "length" "5")
3285 (set_attr "cc" "clobber")])
3287 (define_insn "*rotlsi2.31"
3288 [(set (match_operand:SI 0 "register_operand" "=r")
3289 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3292 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3293 [(set_attr "length" "6")
3294 (set_attr "cc" "clobber")])
3296 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3297 ;; The best we can do is use early clobber alternative "#&r" so that
3298 ;; completely non-overlapping operands dont get a scratch but # so register
3299 ;; allocation does not prefer non-overlapping.
3302 ;; Split word aligned rotates using scratch that is mode dependent.
3306 (define_insn_and_split "*rotw<mode>"
3307 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3308 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3309 (match_operand 2 "const_int_operand" "n,n,n")))
3310 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3312 && CONST_INT_P (operands[2])
3313 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3314 && 0 == INTVAL (operands[2]) % 16"
3316 "&& reload_completed"
3319 avr_rotate_bytes (operands);
3324 ;; Split byte aligned rotates using scratch that is always QI mode.
3329 (define_insn_and_split "*rotb<mode>"
3330 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3331 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3332 (match_operand 2 "const_int_operand" "n,n,n")))
3333 (clobber (match_scratch:QI 3 "=<rotx>"))]
3334 "CONST_INT_P (operands[2])
3335 && (8 == INTVAL (operands[2]) % 16
3337 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3338 && 0 == INTVAL (operands[2]) % 16))"
3340 "&& reload_completed"
3343 avr_rotate_bytes (operands);
3348 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3349 ;; arithmetic shift left
3352 ;; "ashlqq3" "ashluqq3"
3353 (define_expand "ashl<mode>3"
3354 [(set (match_operand:ALL1 0 "register_operand" "")
3355 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3356 (match_operand:QI 2 "nop_general_operand" "")))])
3358 (define_split ; ashlqi3_const4
3359 [(set (match_operand:ALL1 0 "d_register_operand" "")
3360 (ashift:ALL1 (match_dup 0)
3364 (rotate:QI (match_dup 1)
3367 (and:QI (match_dup 1)
3370 operands[1] = avr_to_int_mode (operands[0]);
3373 (define_split ; ashlqi3_const5
3374 [(set (match_operand:ALL1 0 "d_register_operand" "")
3375 (ashift:ALL1 (match_dup 0)
3378 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3379 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3380 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3382 operands[1] = avr_to_int_mode (operands[0]);
3385 (define_split ; ashlqi3_const6
3386 [(set (match_operand:ALL1 0 "d_register_operand" "")
3387 (ashift:ALL1 (match_dup 0)
3390 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3391 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3392 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3394 operands[1] = avr_to_int_mode (operands[0]);
3398 ;; "*ashlqq3" "*ashluqq3"
3399 (define_insn "*ashl<mode>3"
3400 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3401 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3402 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3405 return ashlqi3_out (insn, operands, NULL);
3407 [(set_attr "length" "5,0,1,2,4,6,9")
3408 (set_attr "adjust_len" "ashlqi")
3409 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3411 (define_insn "ashl<mode>3"
3412 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3413 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3414 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3417 return ashlhi3_out (insn, operands, NULL);
3419 [(set_attr "length" "6,0,2,2,4,10,10")
3420 (set_attr "adjust_len" "ashlhi")
3421 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3424 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3425 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3429 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3430 [(set (match_operand:QI 0 "register_operand" "=r")
3431 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3432 (match_operand:QI 2 "register_operand" "r"))
3438 (ashift:QI (match_dup 1)
3441 ;; ??? Combiner does not recognize that it could split the following insn;
3442 ;; presumably because he has no register handy?
3444 ;; "*ashluqihiqi3.mem"
3445 ;; "*ashlsqihiqi3.mem"
3446 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3447 [(set (match_operand:QI 0 "memory_operand" "=m")
3448 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3449 (match_operand:QI 2 "register_operand" "r"))
3452 { gcc_unreachable(); }
3455 (ashift:QI (match_dup 1)
3460 operands[3] = gen_reg_rtx (QImode);
3465 (define_insn_and_split "*ashlhiqi3"
3466 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3467 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3468 (match_operand:QI 2 "register_operand" "r")) 0))]
3470 { gcc_unreachable(); }
3473 (ashift:QI (match_dup 3)
3478 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3479 operands[4] = gen_reg_rtx (QImode);
3482 ;; High part of 16-bit shift is unused after the instruction:
3483 ;; No need to compute it, map to 8-bit shift.
3486 [(set (match_operand:HI 0 "register_operand" "")
3487 (ashift:HI (match_dup 0)
3488 (match_operand:QI 1 "register_operand" "")))]
3491 (ashift:QI (match_dup 2)
3493 (clobber (match_dup 3))]
3495 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3497 if (!peep2_reg_dead_p (1, operands[3]))
3500 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3505 ;; "ashlsq3" "ashlusq3"
3506 ;; "ashlsa3" "ashlusa3"
3507 (define_insn "ashl<mode>3"
3508 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3509 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3510 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3513 return ashlsi3_out (insn, operands, NULL);
3515 [(set_attr "length" "8,0,4,4,8,10,12")
3516 (set_attr "adjust_len" "ashlsi")
3517 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3519 ;; Optimize if a scratch register from LD_REGS happens to be available.
3521 (define_peephole2 ; ashlqi3_l_const4
3522 [(set (match_operand:ALL1 0 "l_register_operand" "")
3523 (ashift:ALL1 (match_dup 0)
3525 (match_scratch:QI 1 "d")]
3527 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3528 (set (match_dup 1) (const_int -16))
3529 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3531 operands[2] = avr_to_int_mode (operands[0]);
3534 (define_peephole2 ; ashlqi3_l_const5
3535 [(set (match_operand:ALL1 0 "l_register_operand" "")
3536 (ashift:ALL1 (match_dup 0)
3538 (match_scratch:QI 1 "d")]
3540 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3541 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3542 (set (match_dup 1) (const_int -32))
3543 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3545 operands[2] = avr_to_int_mode (operands[0]);
3548 (define_peephole2 ; ashlqi3_l_const6
3549 [(set (match_operand:ALL1 0 "l_register_operand" "")
3550 (ashift:ALL1 (match_dup 0)
3552 (match_scratch:QI 1 "d")]
3554 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3555 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3556 (set (match_dup 1) (const_int -64))
3557 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3559 operands[2] = avr_to_int_mode (operands[0]);
3563 [(match_scratch:QI 3 "d")
3564 (set (match_operand:ALL2 0 "register_operand" "")
3565 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3566 (match_operand:QI 2 "const_int_operand" "")))]
3568 [(parallel [(set (match_dup 0)
3569 (ashift:ALL2 (match_dup 1)
3571 (clobber (match_dup 3))])])
3574 ;; "*ashlhq3_const" "*ashluhq3_const"
3575 ;; "*ashlha3_const" "*ashluha3_const"
3576 (define_insn "*ashl<mode>3_const"
3577 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3578 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3579 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3580 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3583 return ashlhi3_out (insn, operands, NULL);
3585 [(set_attr "length" "0,2,2,4,10")
3586 (set_attr "adjust_len" "ashlhi")
3587 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3590 [(match_scratch:QI 3 "d")
3591 (set (match_operand:ALL4 0 "register_operand" "")
3592 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3593 (match_operand:QI 2 "const_int_operand" "")))]
3595 [(parallel [(set (match_dup 0)
3596 (ashift:ALL4 (match_dup 1)
3598 (clobber (match_dup 3))])])
3601 ;; "*ashlsq3_const" "*ashlusq3_const"
3602 ;; "*ashlsa3_const" "*ashlusa3_const"
3603 (define_insn "*ashl<mode>3_const"
3604 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3605 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3606 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3607 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3610 return ashlsi3_out (insn, operands, NULL);
3612 [(set_attr "length" "0,4,4,10")
3613 (set_attr "adjust_len" "ashlsi")
3614 (set_attr "cc" "none,set_n,clobber,clobber")])
3616 (define_expand "ashlpsi3"
3617 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3618 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3619 (match_operand:QI 2 "nonmemory_operand" "")))
3620 (clobber (scratch:QI))])]
3624 && CONST_INT_P (operands[2]))
3626 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3628 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3629 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3632 else if (optimize_insn_for_speed_p ()
3633 && INTVAL (operands[2]) != 16
3634 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3636 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3637 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3643 (define_insn "*ashlpsi3"
3644 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3645 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3646 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3647 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3650 return avr_out_ashlpsi3 (insn, operands, NULL);
3652 [(set_attr "adjust_len" "ashlpsi")
3653 (set_attr "cc" "clobber")])
3655 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3656 ;; arithmetic shift right
3659 ;; "ashrqq3" "ashruqq3"
3660 (define_insn "ashr<mode>3"
3661 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3662 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3663 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3666 return ashrqi3_out (insn, operands, NULL);
3668 [(set_attr "length" "5,0,1,2,5,4,9")
3669 (set_attr "adjust_len" "ashrqi")
3670 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3673 ;; "ashrhq3" "ashruhq3"
3674 ;; "ashrha3" "ashruha3"
3675 (define_insn "ashr<mode>3"
3676 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3677 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3678 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3681 return ashrhi3_out (insn, operands, NULL);
3683 [(set_attr "length" "6,0,2,4,4,10,10")
3684 (set_attr "adjust_len" "ashrhi")
3685 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3687 (define_insn "ashrpsi3"
3688 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3689 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3690 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3691 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3694 return avr_out_ashrpsi3 (insn, operands, NULL);
3696 [(set_attr "adjust_len" "ashrpsi")
3697 (set_attr "cc" "clobber")])
3700 ;; "ashrsq3" "ashrusq3"
3701 ;; "ashrsa3" "ashrusa3"
3702 (define_insn "ashr<mode>3"
3703 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3704 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3705 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3708 return ashrsi3_out (insn, operands, NULL);
3710 [(set_attr "length" "8,0,4,6,8,10,12")
3711 (set_attr "adjust_len" "ashrsi")
3712 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3714 ;; Optimize if a scratch register from LD_REGS happens to be available.
3717 [(match_scratch:QI 3 "d")
3718 (set (match_operand:ALL2 0 "register_operand" "")
3719 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3720 (match_operand:QI 2 "const_int_operand" "")))]
3722 [(parallel [(set (match_dup 0)
3723 (ashiftrt:ALL2 (match_dup 1)
3725 (clobber (match_dup 3))])])
3728 ;; "*ashrhq3_const" "*ashruhq3_const"
3729 ;; "*ashrha3_const" "*ashruha3_const"
3730 (define_insn "*ashr<mode>3_const"
3731 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3732 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3733 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3734 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3737 return ashrhi3_out (insn, operands, NULL);
3739 [(set_attr "length" "0,2,4,4,10")
3740 (set_attr "adjust_len" "ashrhi")
3741 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3744 [(match_scratch:QI 3 "d")
3745 (set (match_operand:ALL4 0 "register_operand" "")
3746 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3747 (match_operand:QI 2 "const_int_operand" "")))]
3749 [(parallel [(set (match_dup 0)
3750 (ashiftrt:ALL4 (match_dup 1)
3752 (clobber (match_dup 3))])])
3755 ;; "*ashrsq3_const" "*ashrusq3_const"
3756 ;; "*ashrsa3_const" "*ashrusa3_const"
3757 (define_insn "*ashr<mode>3_const"
3758 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3759 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3760 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3761 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3764 return ashrsi3_out (insn, operands, NULL);
3766 [(set_attr "length" "0,4,4,10")
3767 (set_attr "adjust_len" "ashrsi")
3768 (set_attr "cc" "none,clobber,set_n,clobber")])
3770 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3771 ;; logical shift right
3774 ;; "lshrqq3 "lshruqq3"
3775 (define_expand "lshr<mode>3"
3776 [(set (match_operand:ALL1 0 "register_operand" "")
3777 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3778 (match_operand:QI 2 "nop_general_operand" "")))])
3780 (define_split ; lshrqi3_const4
3781 [(set (match_operand:ALL1 0 "d_register_operand" "")
3782 (lshiftrt:ALL1 (match_dup 0)
3786 (rotate:QI (match_dup 1)
3789 (and:QI (match_dup 1)
3792 operands[1] = avr_to_int_mode (operands[0]);
3795 (define_split ; lshrqi3_const5
3796 [(set (match_operand:ALL1 0 "d_register_operand" "")
3797 (lshiftrt:ALL1 (match_dup 0)
3800 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3801 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3802 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3804 operands[1] = avr_to_int_mode (operands[0]);
3807 (define_split ; lshrqi3_const6
3808 [(set (match_operand:QI 0 "d_register_operand" "")
3809 (lshiftrt:QI (match_dup 0)
3812 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3813 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3814 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3816 operands[1] = avr_to_int_mode (operands[0]);
3822 (define_insn "*lshr<mode>3"
3823 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3824 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3825 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3828 return lshrqi3_out (insn, operands, NULL);
3830 [(set_attr "length" "5,0,1,2,4,6,9")
3831 (set_attr "adjust_len" "lshrqi")
3832 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3835 ;; "lshrhq3" "lshruhq3"
3836 ;; "lshrha3" "lshruha3"
3837 (define_insn "lshr<mode>3"
3838 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3839 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3840 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3843 return lshrhi3_out (insn, operands, NULL);
3845 [(set_attr "length" "6,0,2,2,4,10,10")
3846 (set_attr "adjust_len" "lshrhi")
3847 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3849 (define_insn "lshrpsi3"
3850 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3851 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3852 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3853 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3856 return avr_out_lshrpsi3 (insn, operands, NULL);
3858 [(set_attr "adjust_len" "lshrpsi")
3859 (set_attr "cc" "clobber")])
3862 ;; "lshrsq3" "lshrusq3"
3863 ;; "lshrsa3" "lshrusa3"
3864 (define_insn "lshr<mode>3"
3865 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3866 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3867 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3870 return lshrsi3_out (insn, operands, NULL);
3872 [(set_attr "length" "8,0,4,4,8,10,12")
3873 (set_attr "adjust_len" "lshrsi")
3874 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3876 ;; Optimize if a scratch register from LD_REGS happens to be available.
3878 (define_peephole2 ; lshrqi3_l_const4
3879 [(set (match_operand:ALL1 0 "l_register_operand" "")
3880 (lshiftrt:ALL1 (match_dup 0)
3882 (match_scratch:QI 1 "d")]
3884 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3885 (set (match_dup 1) (const_int 15))
3886 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3888 operands[2] = avr_to_int_mode (operands[0]);
3891 (define_peephole2 ; lshrqi3_l_const5
3892 [(set (match_operand:ALL1 0 "l_register_operand" "")
3893 (lshiftrt:ALL1 (match_dup 0)
3895 (match_scratch:QI 1 "d")]
3897 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3898 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3899 (set (match_dup 1) (const_int 7))
3900 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3902 operands[2] = avr_to_int_mode (operands[0]);
3905 (define_peephole2 ; lshrqi3_l_const6
3906 [(set (match_operand:ALL1 0 "l_register_operand" "")
3907 (lshiftrt:ALL1 (match_dup 0)
3909 (match_scratch:QI 1 "d")]
3911 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3912 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3913 (set (match_dup 1) (const_int 3))
3914 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3916 operands[2] = avr_to_int_mode (operands[0]);
3920 [(match_scratch:QI 3 "d")
3921 (set (match_operand:ALL2 0 "register_operand" "")
3922 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3923 (match_operand:QI 2 "const_int_operand" "")))]
3925 [(parallel [(set (match_dup 0)
3926 (lshiftrt:ALL2 (match_dup 1)
3928 (clobber (match_dup 3))])])
3931 ;; "*lshrhq3_const" "*lshruhq3_const"
3932 ;; "*lshrha3_const" "*lshruha3_const"
3933 (define_insn "*lshr<mode>3_const"
3934 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3935 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3936 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3937 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3940 return lshrhi3_out (insn, operands, NULL);
3942 [(set_attr "length" "0,2,2,4,10")
3943 (set_attr "adjust_len" "lshrhi")
3944 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3947 [(match_scratch:QI 3 "d")
3948 (set (match_operand:ALL4 0 "register_operand" "")
3949 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3950 (match_operand:QI 2 "const_int_operand" "")))]
3952 [(parallel [(set (match_dup 0)
3953 (lshiftrt:ALL4 (match_dup 1)
3955 (clobber (match_dup 3))])])
3958 ;; "*lshrsq3_const" "*lshrusq3_const"
3959 ;; "*lshrsa3_const" "*lshrusa3_const"
3960 (define_insn "*lshr<mode>3_const"
3961 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3962 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3963 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3964 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3967 return lshrsi3_out (insn, operands, NULL);
3969 [(set_attr "length" "0,4,4,10")
3970 (set_attr "adjust_len" "lshrsi")
3971 (set_attr "cc" "none,clobber,clobber,clobber")])
3973 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3976 (define_insn "absqi2"
3977 [(set (match_operand:QI 0 "register_operand" "=r")
3978 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3982 [(set_attr "length" "2")
3983 (set_attr "cc" "clobber")])
3986 (define_insn "abssf2"
3987 [(set (match_operand:SF 0 "register_operand" "=d,r")
3988 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3993 [(set_attr "length" "1,2")
3994 (set_attr "cc" "set_n,clobber")])
3996 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3999 (define_insn "negqi2"
4000 [(set (match_operand:QI 0 "register_operand" "=r")
4001 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
4004 [(set_attr "length" "1")
4005 (set_attr "cc" "set_vzn")])
4007 (define_insn "*negqihi2"
4008 [(set (match_operand:HI 0 "register_operand" "=r")
4009 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4011 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4012 [(set_attr "length" "4")
4013 (set_attr "cc" "set_n")])
4015 (define_insn "neghi2"
4016 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4017 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4020 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4021 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4022 [(set_attr "length" "3,4")
4023 (set_attr "cc" "set_czn")])
4025 (define_insn "negpsi2"
4026 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4027 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4030 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4031 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4032 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4033 [(set_attr "length" "5,6,6")
4034 (set_attr "cc" "set_czn,set_n,set_czn")])
4036 (define_insn "negsi2"
4037 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4038 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4041 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4042 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4043 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4044 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4045 [(set_attr "length" "7,8,8,7")
4046 (set_attr "isa" "*,*,mov,movw")
4047 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4049 (define_insn "negsf2"
4050 [(set (match_operand:SF 0 "register_operand" "=d,r")
4051 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4055 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4056 [(set_attr "length" "1,4")
4057 (set_attr "cc" "set_n,set_n")])
4059 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4062 (define_insn "one_cmplqi2"
4063 [(set (match_operand:QI 0 "register_operand" "=r")
4064 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4067 [(set_attr "length" "1")
4068 (set_attr "cc" "set_czn")])
4070 (define_insn "one_cmplhi2"
4071 [(set (match_operand:HI 0 "register_operand" "=r")
4072 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4076 [(set_attr "length" "2")
4077 (set_attr "cc" "set_n")])
4079 (define_insn "one_cmplpsi2"
4080 [(set (match_operand:PSI 0 "register_operand" "=r")
4081 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4083 "com %0\;com %B0\;com %C0"
4084 [(set_attr "length" "3")
4085 (set_attr "cc" "set_n")])
4087 (define_insn "one_cmplsi2"
4088 [(set (match_operand:SI 0 "register_operand" "=r")
4089 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4095 [(set_attr "length" "4")
4096 (set_attr "cc" "set_n")])
4098 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4101 ;; We keep combiner from inserting hard registers into the input of sign- and
4102 ;; zero-extends. A hard register in the input operand is not wanted because
4103 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4104 ;; hard register that overlaps these clobbers won't be combined to a widening
4105 ;; multiplication. There is no need for combine to propagate hard registers,
4106 ;; register allocation can do it just as well.
4108 (define_insn "extendqihi2"
4109 [(set (match_operand:HI 0 "register_operand" "=r,r")
4110 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4113 clr %B0\;sbrc %0,7\;com %B0
4114 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4115 [(set_attr "length" "3,4")
4116 (set_attr "cc" "set_n,set_n")])
4118 (define_insn "extendqipsi2"
4119 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4120 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4123 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4124 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4125 [(set_attr "length" "4,5")
4126 (set_attr "cc" "set_n,set_n")])
4128 (define_insn "extendqisi2"
4129 [(set (match_operand:SI 0 "register_operand" "=r,r")
4130 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4133 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4134 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4135 [(set_attr "length" "5,6")
4136 (set_attr "cc" "set_n,set_n")])
4138 (define_insn "extendhipsi2"
4139 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4140 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4143 clr %C0\;sbrc %B0,7\;com %C0
4144 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4145 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4146 [(set_attr "length" "3,5,4")
4147 (set_attr "isa" "*,mov,movw")
4148 (set_attr "cc" "set_n")])
4150 (define_insn "extendhisi2"
4151 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4152 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4155 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4156 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4157 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4158 [(set_attr "length" "4,6,5")
4159 (set_attr "isa" "*,mov,movw")
4160 (set_attr "cc" "set_n")])
4162 (define_insn "extendpsisi2"
4163 [(set (match_operand:SI 0 "register_operand" "=r")
4164 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4166 "clr %D0\;sbrc %C0,7\;com %D0"
4167 [(set_attr "length" "3")
4168 (set_attr "cc" "set_n")])
4170 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4173 (define_insn_and_split "zero_extendqihi2"
4174 [(set (match_operand:HI 0 "register_operand" "=r")
4175 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4179 [(set (match_dup 2) (match_dup 1))
4180 (set (match_dup 3) (const_int 0))]
4182 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4183 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4185 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4186 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4189 (define_insn_and_split "zero_extendqipsi2"
4190 [(set (match_operand:PSI 0 "register_operand" "=r")
4191 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4195 [(set (match_dup 2) (match_dup 1))
4196 (set (match_dup 3) (const_int 0))
4197 (set (match_dup 4) (const_int 0))]
4199 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4200 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4201 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4204 (define_insn_and_split "zero_extendqisi2"
4205 [(set (match_operand:SI 0 "register_operand" "=r")
4206 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4210 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4211 (set (match_dup 3) (const_int 0))]
4213 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4214 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4216 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4217 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4220 (define_insn_and_split "zero_extendhipsi2"
4221 [(set (match_operand:PSI 0 "register_operand" "=r")
4222 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4226 [(set (match_dup 2) (match_dup 1))
4227 (set (match_dup 3) (const_int 0))]
4229 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4230 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4233 (define_insn_and_split "n_extendhipsi2"
4234 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4235 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4236 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4237 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4241 [(set (match_dup 4) (match_dup 2))
4242 (set (match_dup 3) (match_dup 6))
4243 ; no-op move in the case where no scratch is needed
4244 (set (match_dup 5) (match_dup 3))]
4246 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4247 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4248 operands[6] = operands[1];
4250 if (GET_CODE (operands[3]) == SCRATCH)
4251 operands[3] = operands[5];
4254 (define_insn_and_split "zero_extendhisi2"
4255 [(set (match_operand:SI 0 "register_operand" "=r")
4256 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4260 [(set (match_dup 2) (match_dup 1))
4261 (set (match_dup 3) (const_int 0))]
4263 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4264 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4266 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4267 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4270 (define_insn_and_split "zero_extendpsisi2"
4271 [(set (match_operand:SI 0 "register_operand" "=r")
4272 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4276 [(set (match_dup 2) (match_dup 1))
4277 (set (match_dup 3) (const_int 0))]
4279 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4280 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4283 (define_insn_and_split "zero_extendqidi2"
4284 [(set (match_operand:DI 0 "register_operand" "=r")
4285 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4289 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4290 (set (match_dup 3) (const_int 0))]
4292 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4293 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4295 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4296 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4299 (define_insn_and_split "zero_extendhidi2"
4300 [(set (match_operand:DI 0 "register_operand" "=r")
4301 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4305 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4306 (set (match_dup 3) (const_int 0))]
4308 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4309 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4311 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4312 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4315 (define_insn_and_split "zero_extendsidi2"
4316 [(set (match_operand:DI 0 "register_operand" "=r")
4317 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4321 [(set (match_dup 2) (match_dup 1))
4322 (set (match_dup 3) (const_int 0))]
4324 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4325 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4327 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4328 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4331 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4334 ; Optimize negated tests into reverse compare if overflow is undefined.
4335 (define_insn "*negated_tstqi"
4337 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4339 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4340 "cp __zero_reg__,%0"
4341 [(set_attr "cc" "compare")
4342 (set_attr "length" "1")])
4344 (define_insn "*reversed_tstqi"
4346 (compare (const_int 0)
4347 (match_operand:QI 0 "register_operand" "r")))]
4349 "cp __zero_reg__,%0"
4350 [(set_attr "cc" "compare")
4351 (set_attr "length" "2")])
4353 (define_insn "*negated_tsthi"
4355 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4357 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4358 "cp __zero_reg__,%A0
4359 cpc __zero_reg__,%B0"
4360 [(set_attr "cc" "compare")
4361 (set_attr "length" "2")])
4363 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4364 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4365 (define_insn "*reversed_tsthi"
4367 (compare (const_int 0)
4368 (match_operand:HI 0 "register_operand" "r")))
4369 (clobber (match_scratch:QI 1 "=X"))]
4371 "cp __zero_reg__,%A0
4372 cpc __zero_reg__,%B0"
4373 [(set_attr "cc" "compare")
4374 (set_attr "length" "2")])
4376 (define_insn "*negated_tstpsi"
4378 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4380 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4381 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4382 [(set_attr "cc" "compare")
4383 (set_attr "length" "3")])
4385 (define_insn "*reversed_tstpsi"
4387 (compare (const_int 0)
4388 (match_operand:PSI 0 "register_operand" "r")))
4389 (clobber (match_scratch:QI 1 "=X"))]
4391 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4392 [(set_attr "cc" "compare")
4393 (set_attr "length" "3")])
4395 (define_insn "*negated_tstsi"
4397 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4399 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4400 "cp __zero_reg__,%A0
4401 cpc __zero_reg__,%B0
4402 cpc __zero_reg__,%C0
4403 cpc __zero_reg__,%D0"
4404 [(set_attr "cc" "compare")
4405 (set_attr "length" "4")])
4407 ;; "*reversed_tstsi"
4408 ;; "*reversed_tstsq" "*reversed_tstusq"
4409 ;; "*reversed_tstsa" "*reversed_tstusa"
4410 (define_insn "*reversed_tst<mode>"
4412 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4413 (match_operand:ALL4 1 "register_operand" "r")))
4414 (clobber (match_scratch:QI 2 "=X"))]
4416 "cp __zero_reg__,%A1
4417 cpc __zero_reg__,%B1
4418 cpc __zero_reg__,%C1
4419 cpc __zero_reg__,%D1"
4420 [(set_attr "cc" "compare")
4421 (set_attr "length" "4")])
4425 ;; "*cmpqq" "*cmpuqq"
4426 (define_insn "*cmp<mode>"
4428 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4429 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4435 [(set_attr "cc" "compare,compare,compare")
4436 (set_attr "length" "1,1,1")])
4438 (define_insn "*cmpqi_sign_extend"
4440 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4441 (match_operand:HI 1 "s8_operand" "n")))]
4444 [(set_attr "cc" "compare")
4445 (set_attr "length" "1")])
4448 ;; "*cmphq" "*cmpuhq"
4449 ;; "*cmpha" "*cmpuha"
4450 (define_insn "*cmp<mode>"
4452 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4453 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4454 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4457 switch (which_alternative)
4461 return avr_out_tsthi (insn, operands, NULL);
4464 return "cp %A0,%A1\;cpc %B0,%B1";
4467 if (<MODE>mode != HImode)
4469 return reg_unused_after (insn, operands[0])
4470 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4471 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4474 if (<MODE>mode != HImode)
4476 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4479 return avr_out_compare (insn, operands, NULL);
4481 [(set_attr "cc" "compare")
4482 (set_attr "length" "1,2,2,3,4,2,4")
4483 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4485 (define_insn "*cmppsi"
4487 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4488 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4489 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4492 switch (which_alternative)
4495 return avr_out_tstpsi (insn, operands, NULL);
4498 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4501 return reg_unused_after (insn, operands[0])
4502 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4503 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4506 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4509 return avr_out_compare (insn, operands, NULL);
4511 [(set_attr "cc" "compare")
4512 (set_attr "length" "3,3,5,6,3,7")
4513 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4516 ;; "*cmpsq" "*cmpusq"
4517 ;; "*cmpsa" "*cmpusa"
4518 (define_insn "*cmp<mode>"
4520 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4521 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4522 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4525 if (0 == which_alternative)
4526 return avr_out_tstsi (insn, operands, NULL);
4527 else if (1 == which_alternative)
4528 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4530 return avr_out_compare (insn, operands, NULL);
4532 [(set_attr "cc" "compare")
4533 (set_attr "length" "4,4,4,5,8")
4534 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4537 ;; ----------------------------------------------------------------------
4538 ;; JUMP INSTRUCTIONS
4539 ;; ----------------------------------------------------------------------
4540 ;; Conditional jump instructions
4543 ;; "cbranchqq4" "cbranchuqq4"
4544 (define_expand "cbranch<mode>4"
4546 (compare (match_operand:ALL1 1 "register_operand" "")
4547 (match_operand:ALL1 2 "nonmemory_operand" "")))
4550 (match_operator 0 "ordered_comparison_operator" [(cc0)
4552 (label_ref (match_operand 3 "" ""))
4555 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4556 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4558 (define_expand "cbranch<mode>4"
4559 [(parallel [(set (cc0)
4560 (compare (match_operand:ORDERED234 1 "register_operand" "")
4561 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4562 (clobber (match_scratch:QI 4 ""))])
4565 (match_operator 0 "ordered_comparison_operator" [(cc0)
4567 (label_ref (match_operand 3 "" ""))
4571 ;; Test a single bit in a QI/HI/SImode register.
4572 ;; Combine will create zero extract patterns for single bit tests.
4573 ;; permit any mode in source pattern by using VOIDmode.
4575 (define_insn "*sbrx_branch<mode>"
4578 (match_operator 0 "eqne_operator"
4580 (match_operand:VOID 1 "register_operand" "r")
4582 (match_operand 2 "const_int_operand" "n"))
4584 (label_ref (match_operand 3 "" ""))
4588 return avr_out_sbxx_branch (insn, operands);
4590 [(set (attr "length")
4591 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4592 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4594 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4597 (set_attr "cc" "clobber")])
4599 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4600 ;; or for old peepholes.
4601 ;; Fixme - bitwise Mask will not work for DImode
4603 (define_insn "*sbrx_and_branch<mode>"
4606 (match_operator 0 "eqne_operator"
4608 (match_operand:QISI 1 "register_operand" "r")
4609 (match_operand:QISI 2 "single_one_operand" "n"))
4611 (label_ref (match_operand 3 "" ""))
4615 HOST_WIDE_INT bitnumber;
4616 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4617 operands[2] = GEN_INT (bitnumber);
4618 return avr_out_sbxx_branch (insn, operands);
4620 [(set (attr "length")
4621 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4622 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4624 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4627 (set_attr "cc" "clobber")])
4629 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4631 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4633 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4634 (label_ref (match_operand 1 "" ""))
4637 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4641 (label_ref (match_dup 1))
4645 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4647 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4648 (label_ref (match_operand 1 "" ""))
4651 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4655 (label_ref (match_dup 1))
4659 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4661 (clobber (match_operand:HI 2 ""))])
4662 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4663 (label_ref (match_operand 1 "" ""))
4666 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4668 (label_ref (match_dup 1))
4672 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4674 (clobber (match_operand:HI 2 ""))])
4675 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4676 (label_ref (match_operand 1 "" ""))
4679 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4681 (label_ref (match_dup 1))
4685 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4687 (clobber (match_operand:SI 2 ""))])
4688 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4689 (label_ref (match_operand 1 "" ""))
4692 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4694 (label_ref (match_dup 1))
4696 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4699 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4701 (clobber (match_operand:SI 2 ""))])
4702 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4703 (label_ref (match_operand 1 "" ""))
4706 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4708 (label_ref (match_dup 1))
4710 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4712 ;; ************************************************************************
4713 ;; Implementation of conditional jumps here.
4714 ;; Compare with 0 (test) jumps
4715 ;; ************************************************************************
4717 (define_insn "branch"
4719 (if_then_else (match_operator 1 "simple_comparison_operator"
4722 (label_ref (match_operand 0 "" ""))
4726 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4728 [(set_attr "type" "branch")
4729 (set_attr "cc" "clobber")])
4732 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4733 ;; or optimized in the remainder.
4735 (define_insn "branch_unspec"
4737 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4740 (label_ref (match_operand 0 "" ""))
4742 ] UNSPEC_IDENTITY))]
4745 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4747 [(set_attr "type" "branch")
4748 (set_attr "cc" "none")])
4750 ;; ****************************************************************
4751 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4752 ;; Convert them all to proper jumps.
4753 ;; ****************************************************************/
4755 (define_insn "difficult_branch"
4757 (if_then_else (match_operator 1 "difficult_comparison_operator"
4760 (label_ref (match_operand 0 "" ""))
4764 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4766 [(set_attr "type" "branch1")
4767 (set_attr "cc" "clobber")])
4771 (define_insn "rvbranch"
4773 (if_then_else (match_operator 1 "simple_comparison_operator"
4777 (label_ref (match_operand 0 "" ""))))]
4780 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4782 [(set_attr "type" "branch1")
4783 (set_attr "cc" "clobber")])
4785 (define_insn "difficult_rvbranch"
4787 (if_then_else (match_operator 1 "difficult_comparison_operator"
4791 (label_ref (match_operand 0 "" ""))))]
4794 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4796 [(set_attr "type" "branch")
4797 (set_attr "cc" "clobber")])
4799 ;; **************************************************************************
4800 ;; Unconditional and other jump instructions.
4804 (label_ref (match_operand 0 "" "")))]
4807 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4811 [(set (attr "length")
4812 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4813 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4816 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4817 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4820 (set_attr "cc" "none")])
4824 ;; Operand 1 not used on the AVR.
4825 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4826 (define_expand "call"
4827 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4828 (match_operand:HI 1 "general_operand" ""))
4829 (use (const_int 0))])])
4831 ;; Operand 1 not used on the AVR.
4832 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4833 (define_expand "sibcall"
4834 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4835 (match_operand:HI 1 "general_operand" ""))
4836 (use (const_int 1))])])
4840 ;; Operand 2 not used on the AVR.
4841 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4842 (define_expand "call_value"
4843 [(parallel[(set (match_operand 0 "register_operand" "")
4844 (call (match_operand:HI 1 "call_insn_operand" "")
4845 (match_operand:HI 2 "general_operand" "")))
4846 (use (const_int 0))])])
4848 ;; Operand 2 not used on the AVR.
4849 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4850 (define_expand "sibcall_value"
4851 [(parallel[(set (match_operand 0 "register_operand" "")
4852 (call (match_operand:HI 1 "call_insn_operand" "")
4853 (match_operand:HI 2 "general_operand" "")))
4854 (use (const_int 1))])])
4856 (define_insn "call_insn"
4857 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4858 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4859 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4860 ;; Operand 1 not used on the AVR.
4861 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4868 [(set_attr "cc" "clobber")
4869 (set_attr "length" "1,*,1,*")
4870 (set_attr "adjust_len" "*,call,*,call")])
4872 (define_insn "call_value_insn"
4873 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4874 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4875 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4876 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4877 ;; Operand 2 not used on the AVR.
4878 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4885 [(set_attr "cc" "clobber")
4886 (set_attr "length" "1,*,1,*")
4887 (set_attr "adjust_len" "*,call,*,call")])
4893 [(set_attr "cc" "none")
4894 (set_attr "length" "1")])
4898 (define_expand "indirect_jump"
4900 (match_operand:HI 0 "nonmemory_operand" ""))]
4903 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4905 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4910 (define_insn "*indirect_jump"
4912 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4918 push %A0\;push %B0\;ret
4920 [(set_attr "length" "1,2,1,3,1")
4921 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4922 (set_attr "cc" "none")])
4925 ;; For entries in jump table see avr_output_addr_vec_elt.
4928 ;; "rjmp .L<n>" instructions for <= 8K devices
4929 ;; ".word gs(.L<n>)" addresses for > 8K devices
4930 (define_insn "*tablejump"
4932 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4934 (use (label_ref (match_operand 1 "" "")))
4935 (clobber (match_dup 0))
4936 (clobber (const_int 0))]
4937 "!AVR_HAVE_EIJMP_EICALL"
4940 push %A0\;push %B0\;ret
4942 [(set_attr "length" "1,3,2")
4943 (set_attr "isa" "rjmp,rjmp,jmp")
4944 (set_attr "cc" "none,none,clobber")])
4946 (define_insn "*tablejump.3byte-pc"
4948 (unspec:HI [(reg:HI REG_Z)]
4950 (use (label_ref (match_operand 0 "" "")))
4951 (clobber (reg:HI REG_Z))
4952 (clobber (reg:QI 24))]
4953 "AVR_HAVE_EIJMP_EICALL"
4954 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
4955 [(set_attr "length" "6")
4956 (set_attr "isa" "eijmp")
4957 (set_attr "cc" "clobber")])
4960 (define_expand "casesi"
4961 [(parallel [(set (match_dup 6)
4962 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4963 (match_operand:HI 1 "register_operand" "")))
4964 (clobber (scratch:QI))])
4965 (parallel [(set (cc0)
4966 (compare (match_dup 6)
4967 (match_operand:HI 2 "register_operand" "")))
4968 (clobber (match_scratch:QI 9 ""))])
4971 (if_then_else (gtu (cc0)
4973 (label_ref (match_operand 4 "" ""))
4979 (parallel [(set (pc)
4980 (unspec:HI [(match_dup 10)] UNSPEC_INDEX_JMP))
4981 (use (label_ref (match_dup 3)))
4982 (clobber (match_dup 10))
4983 (clobber (match_dup 8))])]
4986 operands[6] = gen_reg_rtx (HImode);
4988 if (AVR_HAVE_EIJMP_EICALL)
4990 operands[7] = operands[6];
4991 operands[8] = all_regs_rtx[24];
4992 operands[10] = gen_rtx_REG (HImode, REG_Z);
4996 operands[7] = gen_rtx_PLUS (HImode, operands[6],
4997 gen_rtx_LABEL_REF (VOIDmode, operands[3]));
4998 operands[8] = const0_rtx;
4999 operands[10] = operands[6];
5004 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5005 ;; This instruction sets Z flag
5008 [(set (cc0) (const_int 0))]
5011 [(set_attr "length" "1")
5012 (set_attr "cc" "compare")])
5014 ;; Clear/set/test a single bit in I/O address space.
5017 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5018 (and:QI (mem:QI (match_dup 0))
5019 (match_operand:QI 1 "single_zero_operand" "n")))]
5022 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
5023 return "cbi %i0,%2";
5025 [(set_attr "length" "1")
5026 (set_attr "cc" "none")])
5029 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5030 (ior:QI (mem:QI (match_dup 0))
5031 (match_operand:QI 1 "single_one_operand" "n")))]
5034 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5035 return "sbi %i0,%2";
5037 [(set_attr "length" "1")
5038 (set_attr "cc" "none")])
5040 ;; Lower half of the I/O space - use sbic/sbis directly.
5041 (define_insn "*sbix_branch"
5044 (match_operator 0 "eqne_operator"
5046 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5048 (match_operand 2 "const_int_operand" "n"))
5050 (label_ref (match_operand 3 "" ""))
5054 return avr_out_sbxx_branch (insn, operands);
5056 [(set (attr "length")
5057 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5058 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5060 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5063 (set_attr "cc" "clobber")])
5065 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5066 (define_insn "*sbix_branch_bit7"
5069 (match_operator 0 "gelt_operator"
5070 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
5072 (label_ref (match_operand 2 "" ""))
5076 operands[3] = operands[2];
5077 operands[2] = GEN_INT (7);
5078 return avr_out_sbxx_branch (insn, operands);
5080 [(set (attr "length")
5081 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5082 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5084 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5087 (set_attr "cc" "clobber")])
5089 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5090 (define_insn "*sbix_branch_tmp"
5093 (match_operator 0 "eqne_operator"
5095 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5097 (match_operand 2 "const_int_operand" "n"))
5099 (label_ref (match_operand 3 "" ""))
5103 return avr_out_sbxx_branch (insn, operands);
5105 [(set (attr "length")
5106 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5107 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5109 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5112 (set_attr "cc" "clobber")])
5114 (define_insn "*sbix_branch_tmp_bit7"
5117 (match_operator 0 "gelt_operator"
5118 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5120 (label_ref (match_operand 2 "" ""))
5124 operands[3] = operands[2];
5125 operands[2] = GEN_INT (7);
5126 return avr_out_sbxx_branch (insn, operands);
5128 [(set (attr "length")
5129 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5130 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5132 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5135 (set_attr "cc" "clobber")])
5137 ;; ************************* Peepholes ********************************
5139 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5140 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5141 (plus:SI (match_dup 0)
5143 (clobber (scratch:QI))])
5144 (parallel [(set (cc0)
5145 (compare (match_dup 0)
5147 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5149 (if_then_else (eqne (cc0)
5151 (label_ref (match_operand 2 "" ""))
5158 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5159 output_asm_insn ("sbiw %0,1" CR_TAB
5160 "sbc %C0,__zero_reg__" CR_TAB
5161 "sbc %D0,__zero_reg__", operands);
5163 output_asm_insn ("subi %A0,1" CR_TAB
5164 "sbc %B0,__zero_reg__" CR_TAB
5165 "sbc %C0,__zero_reg__" CR_TAB
5166 "sbc %D0,__zero_reg__", operands);
5168 jump_mode = avr_jump_mode (operands[2], insn);
5169 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5170 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5174 case 1: return "%1 %2";
5175 case 2: return "%1 .+2\;rjmp %2";
5176 case 3: return "%1 .+4\;jmp %2";
5183 (define_peephole ; "*dec-and-branchhi!=-1"
5184 [(set (match_operand:HI 0 "d_register_operand" "")
5185 (plus:HI (match_dup 0)
5187 (parallel [(set (cc0)
5188 (compare (match_dup 0)
5190 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5192 (if_then_else (eqne (cc0)
5194 (label_ref (match_operand 2 "" ""))
5201 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5202 output_asm_insn ("sbiw %0,1", operands);
5204 output_asm_insn ("subi %A0,1" CR_TAB
5205 "sbc %B0,__zero_reg__", operands);
5207 jump_mode = avr_jump_mode (operands[2], insn);
5208 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5209 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5213 case 1: return "%1 %2";
5214 case 2: return "%1 .+2\;rjmp %2";
5215 case 3: return "%1 .+4\;jmp %2";
5222 ;; Same as above but with clobber flavour of addhi3
5223 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5224 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5225 (plus:HI (match_dup 0)
5227 (clobber (scratch:QI))])
5228 (parallel [(set (cc0)
5229 (compare (match_dup 0)
5231 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5233 (if_then_else (eqne (cc0)
5235 (label_ref (match_operand 2 "" ""))
5242 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5243 output_asm_insn ("sbiw %0,1", operands);
5245 output_asm_insn ("subi %A0,1" CR_TAB
5246 "sbc %B0,__zero_reg__", operands);
5248 jump_mode = avr_jump_mode (operands[2], insn);
5249 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5250 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5254 case 1: return "%1 %2";
5255 case 2: return "%1 .+2\;rjmp %2";
5256 case 3: return "%1 .+4\;jmp %2";
5263 ;; Same as above but with clobber flavour of addhi3
5264 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5265 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5266 (plus:HI (match_dup 0)
5268 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5269 (parallel [(set (cc0)
5270 (compare (match_dup 0)
5272 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5274 (if_then_else (eqne (cc0)
5276 (label_ref (match_operand 2 "" ""))
5283 output_asm_insn ("ldi %3,1" CR_TAB
5285 "sbc %B0,__zero_reg__", operands);
5287 jump_mode = avr_jump_mode (operands[2], insn);
5288 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5289 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5293 case 1: return "%1 %2";
5294 case 2: return "%1 .+2\;rjmp %2";
5295 case 3: return "%1 .+4\;jmp %2";
5302 (define_peephole ; "*dec-and-branchqi!=-1"
5303 [(set (match_operand:QI 0 "d_register_operand" "")
5304 (plus:QI (match_dup 0)
5307 (compare (match_dup 0)
5310 (if_then_else (eqne (cc0)
5312 (label_ref (match_operand 1 "" ""))
5319 cc_status.value1 = operands[0];
5320 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5322 output_asm_insn ("subi %A0,1", operands);
5324 jump_mode = avr_jump_mode (operands[1], insn);
5325 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5326 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5330 case 1: return "%0 %1";
5331 case 2: return "%0 .+2\;rjmp %1";
5332 case 3: return "%0 .+4\;jmp %1";
5340 (define_peephole ; "*cpse.eq"
5342 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5343 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5345 (if_then_else (eq (cc0)
5347 (label_ref (match_operand 0 "" ""))
5349 "jump_over_one_insn_p (insn, operands[0])"
5352 cpse %1,__zero_reg__")
5354 ;; This peephole avoids code like
5357 ;; BREQ .+2 ; branch
5360 ;; Notice that the peephole is always shorter than cmpqi + branch.
5361 ;; The reason to write it as peephole is that sequences like
5366 ;; shall not be superseeded. With a respective combine pattern
5367 ;; the latter sequence would be
5370 ;; CPSE Rm, __zero_reg__
5373 ;; and thus longer and slower and not easy to be rolled back.
5375 (define_peephole ; "*cpse.ne"
5377 (compare (match_operand:ALL1 1 "register_operand" "")
5378 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5380 (if_then_else (ne (cc0)
5382 (label_ref (match_operand 0 "" ""))
5385 || !(avr_current_device->dev_attribute & AVR_ERRATA_SKIP)"
5387 if (operands[2] == CONST0_RTX (<MODE>mode))
5388 operands[2] = zero_reg_rtx;
5390 return 3 == avr_jump_mode (operands[0], insn)
5391 ? "cpse %1,%2\;jmp %0"
5392 : "cpse %1,%2\;rjmp %0";
5395 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5396 ;;prologue/epilogue support instructions
5398 (define_insn "popqi"
5399 [(set (match_operand:QI 0 "register_operand" "=r")
5400 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5403 [(set_attr "cc" "none")
5404 (set_attr "length" "1")])
5406 ;; Enable Interrupts
5407 (define_expand "enable_interrupt"
5408 [(clobber (const_int 0))]
5411 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5412 MEM_VOLATILE_P (mem) = 1;
5413 emit_insn (gen_cli_sei (const1_rtx, mem));
5417 ;; Disable Interrupts
5418 (define_expand "disable_interrupt"
5419 [(clobber (const_int 0))]
5422 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5423 MEM_VOLATILE_P (mem) = 1;
5424 emit_insn (gen_cli_sei (const0_rtx, mem));
5428 (define_insn "cli_sei"
5429 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5430 UNSPECV_ENABLE_IRQS)
5431 (set (match_operand:BLK 1 "" "")
5432 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5437 [(set_attr "length" "1")
5438 (set_attr "cc" "none")])
5440 ;; Library prologue saves
5441 (define_insn "call_prologue_saves"
5442 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5443 (match_operand:HI 0 "immediate_operand" "i,i")
5444 (set (reg:HI REG_SP)
5445 (minus:HI (reg:HI REG_SP)
5446 (match_operand:HI 1 "immediate_operand" "i,i")))
5447 (use (reg:HI REG_X))
5448 (clobber (reg:HI REG_Z))]
5450 "ldi r30,lo8(gs(1f))
5452 %~jmp __prologue_saves__+((18 - %0) * 2)
5454 [(set_attr "length" "5,6")
5455 (set_attr "cc" "clobber")
5456 (set_attr "isa" "rjmp,jmp")])
5458 ; epilogue restores using library
5459 (define_insn "epilogue_restores"
5460 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5462 (plus:HI (reg:HI REG_Y)
5463 (match_operand:HI 0 "immediate_operand" "i,i")))
5464 (set (reg:HI REG_SP)
5465 (plus:HI (reg:HI REG_Y)
5467 (clobber (reg:QI REG_Z))]
5470 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5471 [(set_attr "length" "2,3")
5472 (set_attr "cc" "clobber")
5473 (set_attr "isa" "rjmp,jmp")])
5476 (define_insn "return"
5478 "reload_completed && avr_simple_epilogue ()"
5480 [(set_attr "cc" "none")
5481 (set_attr "length" "1")])
5483 (define_insn "return_from_epilogue"
5487 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5488 && !cfun->machine->is_naked"
5490 [(set_attr "cc" "none")
5491 (set_attr "length" "1")])
5493 (define_insn "return_from_interrupt_epilogue"
5497 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5498 && !cfun->machine->is_naked"
5500 [(set_attr "cc" "none")
5501 (set_attr "length" "1")])
5503 (define_insn "return_from_naked_epilogue"
5507 && cfun->machine->is_naked"
5509 [(set_attr "cc" "none")
5510 (set_attr "length" "0")])
5512 (define_expand "prologue"
5516 avr_expand_prologue ();
5520 (define_expand "epilogue"
5524 avr_expand_epilogue (false /* sibcall_p */);
5528 (define_expand "sibcall_epilogue"
5532 avr_expand_epilogue (true /* sibcall_p */);
5536 ;; Some instructions resp. instruction sequences available
5539 (define_insn "delay_cycles_1"
5540 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5542 UNSPECV_DELAY_CYCLES)
5543 (set (match_operand:BLK 1 "" "")
5544 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5545 (clobber (match_scratch:QI 2 "=&d"))]
5550 [(set_attr "length" "3")
5551 (set_attr "cc" "clobber")])
5553 (define_insn "delay_cycles_2"
5554 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5556 UNSPECV_DELAY_CYCLES)
5557 (set (match_operand:BLK 1 "" "")
5558 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5559 (clobber (match_scratch:HI 2 "=&w"))]
5565 [(set_attr "length" "4")
5566 (set_attr "cc" "clobber")])
5568 (define_insn "delay_cycles_3"
5569 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5571 UNSPECV_DELAY_CYCLES)
5572 (set (match_operand:BLK 1 "" "")
5573 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5574 (clobber (match_scratch:QI 2 "=&d"))
5575 (clobber (match_scratch:QI 3 "=&d"))
5576 (clobber (match_scratch:QI 4 "=&d"))]
5585 [(set_attr "length" "7")
5586 (set_attr "cc" "clobber")])
5588 (define_insn "delay_cycles_4"
5589 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5591 UNSPECV_DELAY_CYCLES)
5592 (set (match_operand:BLK 1 "" "")
5593 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5594 (clobber (match_scratch:QI 2 "=&d"))
5595 (clobber (match_scratch:QI 3 "=&d"))
5596 (clobber (match_scratch:QI 4 "=&d"))
5597 (clobber (match_scratch:QI 5 "=&d"))]
5608 [(set_attr "length" "9")
5609 (set_attr "cc" "clobber")])
5612 ;; __builtin_avr_insert_bits
5614 (define_insn "insert_bits"
5615 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5616 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5617 (match_operand:QI 2 "register_operand" "r ,r ,r")
5618 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5619 UNSPEC_INSERT_BITS))]
5622 return avr_out_insert_bits (operands, NULL);
5624 [(set_attr "adjust_len" "insert_bits")
5625 (set_attr "cc" "clobber")])
5628 ;; __builtin_avr_flash_segment
5630 ;; Just a helper for the next "official" expander.
5632 (define_expand "flash_segment1"
5633 [(set (match_operand:QI 0 "register_operand" "")
5634 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5637 (compare (match_dup 0)
5640 (if_then_else (ge (cc0)
5642 (label_ref (match_operand 2 "" ""))
5647 (define_expand "flash_segment"
5648 [(parallel [(match_operand:QI 0 "register_operand" "")
5649 (match_operand:PSI 1 "register_operand" "")])]
5652 rtx label = gen_label_rtx ();
5653 emit (gen_flash_segment1 (operands[0], operands[1], label));
5658 ;; Actually, it's too late now to work out address spaces known at compiletime.
5659 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5660 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5661 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5663 (define_insn_and_split "*split.flash_segment"
5664 [(set (match_operand:QI 0 "register_operand" "=d")
5665 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5666 (match_operand:HI 2 "register_operand" "r"))
5669 { gcc_unreachable(); }
5677 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5678 ;; better 8-bit parity recognition.
5680 (define_expand "parityhi2"
5681 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5682 (parity:HI (match_operand:HI 1 "register_operand" "")))
5683 (clobber (reg:HI 24))])])
5685 (define_insn_and_split "*parityhi2"
5686 [(set (match_operand:HI 0 "register_operand" "=r")
5687 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5688 (clobber (reg:HI 24))]
5690 { gcc_unreachable(); }
5695 (parity:HI (reg:HI 24)))
5699 (define_insn_and_split "*parityqihi2"
5700 [(set (match_operand:HI 0 "register_operand" "=r")
5701 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5702 (clobber (reg:HI 24))]
5704 { gcc_unreachable(); }
5709 (zero_extend:HI (parity:QI (reg:QI 24))))
5713 (define_expand "paritysi2"
5715 (match_operand:SI 1 "register_operand" ""))
5717 (truncate:HI (parity:SI (reg:SI 22))))
5720 (set (match_operand:SI 0 "register_operand" "")
5721 (zero_extend:SI (match_dup 2)))]
5724 operands[2] = gen_reg_rtx (HImode);
5727 (define_insn "*parityhi2.libgcc"
5729 (parity:HI (reg:HI 24)))]
5731 "%~call __parityhi2"
5732 [(set_attr "type" "xcall")
5733 (set_attr "cc" "clobber")])
5735 (define_insn "*parityqihi2.libgcc"
5737 (zero_extend:HI (parity:QI (reg:QI 24))))]
5739 "%~call __parityqi2"
5740 [(set_attr "type" "xcall")
5741 (set_attr "cc" "clobber")])
5743 (define_insn "*paritysihi2.libgcc"
5745 (truncate:HI (parity:SI (reg:SI 22))))]
5747 "%~call __paritysi2"
5748 [(set_attr "type" "xcall")
5749 (set_attr "cc" "clobber")])
5754 (define_expand "popcounthi2"
5756 (match_operand:HI 1 "register_operand" ""))
5758 (popcount:HI (reg:HI 24)))
5759 (set (match_operand:HI 0 "register_operand" "")
5764 (define_expand "popcountsi2"
5766 (match_operand:SI 1 "register_operand" ""))
5768 (truncate:HI (popcount:SI (reg:SI 22))))
5771 (set (match_operand:SI 0 "register_operand" "")
5772 (zero_extend:SI (match_dup 2)))]
5775 operands[2] = gen_reg_rtx (HImode);
5778 (define_insn "*popcounthi2.libgcc"
5780 (popcount:HI (reg:HI 24)))]
5782 "%~call __popcounthi2"
5783 [(set_attr "type" "xcall")
5784 (set_attr "cc" "clobber")])
5786 (define_insn "*popcountsi2.libgcc"
5788 (truncate:HI (popcount:SI (reg:SI 22))))]
5790 "%~call __popcountsi2"
5791 [(set_attr "type" "xcall")
5792 (set_attr "cc" "clobber")])
5794 (define_insn "*popcountqi2.libgcc"
5796 (popcount:QI (reg:QI 24)))]
5798 "%~call __popcountqi2"
5799 [(set_attr "type" "xcall")
5800 (set_attr "cc" "clobber")])
5802 (define_insn_and_split "*popcountqihi2.libgcc"
5804 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5809 (popcount:QI (reg:QI 24)))
5813 ;; Count Leading Zeros
5815 (define_expand "clzhi2"
5817 (match_operand:HI 1 "register_operand" ""))
5818 (parallel [(set (reg:HI 24)
5819 (clz:HI (reg:HI 24)))
5820 (clobber (reg:QI 26))])
5821 (set (match_operand:HI 0 "register_operand" "")
5824 (define_expand "clzsi2"
5826 (match_operand:SI 1 "register_operand" ""))
5827 (parallel [(set (reg:HI 24)
5828 (truncate:HI (clz:SI (reg:SI 22))))
5829 (clobber (reg:QI 26))])
5832 (set (match_operand:SI 0 "register_operand" "")
5833 (zero_extend:SI (match_dup 2)))]
5836 operands[2] = gen_reg_rtx (HImode);
5839 (define_insn "*clzhi2.libgcc"
5841 (clz:HI (reg:HI 24)))
5842 (clobber (reg:QI 26))]
5845 [(set_attr "type" "xcall")
5846 (set_attr "cc" "clobber")])
5848 (define_insn "*clzsihi2.libgcc"
5850 (truncate:HI (clz:SI (reg:SI 22))))
5851 (clobber (reg:QI 26))]
5854 [(set_attr "type" "xcall")
5855 (set_attr "cc" "clobber")])
5857 ;; Count Trailing Zeros
5859 (define_expand "ctzhi2"
5861 (match_operand:HI 1 "register_operand" ""))
5862 (parallel [(set (reg:HI 24)
5863 (ctz:HI (reg:HI 24)))
5864 (clobber (reg:QI 26))])
5865 (set (match_operand:HI 0 "register_operand" "")
5868 (define_expand "ctzsi2"
5870 (match_operand:SI 1 "register_operand" ""))
5871 (parallel [(set (reg:HI 24)
5872 (truncate:HI (ctz:SI (reg:SI 22))))
5873 (clobber (reg:QI 22))
5874 (clobber (reg:QI 26))])
5877 (set (match_operand:SI 0 "register_operand" "")
5878 (zero_extend:SI (match_dup 2)))]
5881 operands[2] = gen_reg_rtx (HImode);
5884 (define_insn "*ctzhi2.libgcc"
5886 (ctz:HI (reg:HI 24)))
5887 (clobber (reg:QI 26))]
5890 [(set_attr "type" "xcall")
5891 (set_attr "cc" "clobber")])
5893 (define_insn "*ctzsihi2.libgcc"
5895 (truncate:HI (ctz:SI (reg:SI 22))))
5896 (clobber (reg:QI 22))
5897 (clobber (reg:QI 26))]
5900 [(set_attr "type" "xcall")
5901 (set_attr "cc" "clobber")])
5905 (define_expand "ffshi2"
5907 (match_operand:HI 1 "register_operand" ""))
5908 (parallel [(set (reg:HI 24)
5909 (ffs:HI (reg:HI 24)))
5910 (clobber (reg:QI 26))])
5911 (set (match_operand:HI 0 "register_operand" "")
5914 (define_expand "ffssi2"
5916 (match_operand:SI 1 "register_operand" ""))
5917 (parallel [(set (reg:HI 24)
5918 (truncate:HI (ffs:SI (reg:SI 22))))
5919 (clobber (reg:QI 22))
5920 (clobber (reg:QI 26))])
5923 (set (match_operand:SI 0 "register_operand" "")
5924 (zero_extend:SI (match_dup 2)))]
5927 operands[2] = gen_reg_rtx (HImode);
5930 (define_insn "*ffshi2.libgcc"
5932 (ffs:HI (reg:HI 24)))
5933 (clobber (reg:QI 26))]
5936 [(set_attr "type" "xcall")
5937 (set_attr "cc" "clobber")])
5939 (define_insn "*ffssihi2.libgcc"
5941 (truncate:HI (ffs:SI (reg:SI 22))))
5942 (clobber (reg:QI 22))
5943 (clobber (reg:QI 26))]
5946 [(set_attr "type" "xcall")
5947 (set_attr "cc" "clobber")])
5951 (define_insn "copysignsf3"
5952 [(set (match_operand:SF 0 "register_operand" "=r")
5953 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5954 (match_operand:SF 2 "register_operand" "r")]
5957 "bst %D2,7\;bld %D0,7"
5958 [(set_attr "length" "2")
5959 (set_attr "cc" "none")])
5961 ;; Swap Bytes (change byte-endianess)
5963 (define_expand "bswapsi2"
5965 (match_operand:SI 1 "register_operand" ""))
5967 (bswap:SI (reg:SI 22)))
5968 (set (match_operand:SI 0 "register_operand" "")
5971 (define_insn "*bswapsi2.libgcc"
5973 (bswap:SI (reg:SI 22)))]
5976 [(set_attr "type" "xcall")
5977 (set_attr "cc" "clobber")])
5982 ;; NOP taking 1 or 2 Ticks
5983 (define_expand "nopv"
5984 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5987 (unspec_volatile:BLK [(match_dup 1)]
5988 UNSPECV_MEMORY_BARRIER))])]
5991 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5992 MEM_VOLATILE_P (operands[1]) = 1;
5995 (define_insn "*nopv"
5996 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5998 (set (match_operand:BLK 1 "" "")
5999 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
6004 [(set_attr "length" "1")
6005 (set_attr "cc" "none")])
6008 (define_expand "sleep"
6009 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6011 (unspec_volatile:BLK [(match_dup 0)]
6012 UNSPECV_MEMORY_BARRIER))])]
6015 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6016 MEM_VOLATILE_P (operands[0]) = 1;
6019 (define_insn "*sleep"
6020 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6021 (set (match_operand:BLK 0 "" "")
6022 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6025 [(set_attr "length" "1")
6026 (set_attr "cc" "none")])
6029 (define_expand "wdr"
6030 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6032 (unspec_volatile:BLK [(match_dup 0)]
6033 UNSPECV_MEMORY_BARRIER))])]
6036 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6037 MEM_VOLATILE_P (operands[0]) = 1;
6041 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6042 (set (match_operand:BLK 0 "" "")
6043 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6046 [(set_attr "length" "1")
6047 (set_attr "cc" "none")])
6050 (define_expand "fmul"
6052 (match_operand:QI 1 "register_operand" ""))
6054 (match_operand:QI 2 "register_operand" ""))
6055 (parallel [(set (reg:HI 22)
6056 (unspec:HI [(reg:QI 24)
6057 (reg:QI 25)] UNSPEC_FMUL))
6058 (clobber (reg:HI 24))])
6059 (set (match_operand:HI 0 "register_operand" "")
6065 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6070 (define_insn "fmul_insn"
6071 [(set (match_operand:HI 0 "register_operand" "=r")
6072 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6073 (match_operand:QI 2 "register_operand" "a")]
6079 [(set_attr "length" "3")
6080 (set_attr "cc" "clobber")])
6082 (define_insn "*fmul.call"
6084 (unspec:HI [(reg:QI 24)
6085 (reg:QI 25)] UNSPEC_FMUL))
6086 (clobber (reg:HI 24))]
6089 [(set_attr "type" "xcall")
6090 (set_attr "cc" "clobber")])
6093 (define_expand "fmuls"
6095 (match_operand:QI 1 "register_operand" ""))
6097 (match_operand:QI 2 "register_operand" ""))
6098 (parallel [(set (reg:HI 22)
6099 (unspec:HI [(reg:QI 24)
6100 (reg:QI 25)] UNSPEC_FMULS))
6101 (clobber (reg:HI 24))])
6102 (set (match_operand:HI 0 "register_operand" "")
6108 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6113 (define_insn "fmuls_insn"
6114 [(set (match_operand:HI 0 "register_operand" "=r")
6115 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6116 (match_operand:QI 2 "register_operand" "a")]
6122 [(set_attr "length" "3")
6123 (set_attr "cc" "clobber")])
6125 (define_insn "*fmuls.call"
6127 (unspec:HI [(reg:QI 24)
6128 (reg:QI 25)] UNSPEC_FMULS))
6129 (clobber (reg:HI 24))]
6132 [(set_attr "type" "xcall")
6133 (set_attr "cc" "clobber")])
6136 (define_expand "fmulsu"
6138 (match_operand:QI 1 "register_operand" ""))
6140 (match_operand:QI 2 "register_operand" ""))
6141 (parallel [(set (reg:HI 22)
6142 (unspec:HI [(reg:QI 24)
6143 (reg:QI 25)] UNSPEC_FMULSU))
6144 (clobber (reg:HI 24))])
6145 (set (match_operand:HI 0 "register_operand" "")
6151 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6156 (define_insn "fmulsu_insn"
6157 [(set (match_operand:HI 0 "register_operand" "=r")
6158 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6159 (match_operand:QI 2 "register_operand" "a")]
6165 [(set_attr "length" "3")
6166 (set_attr "cc" "clobber")])
6168 (define_insn "*fmulsu.call"
6170 (unspec:HI [(reg:QI 24)
6171 (reg:QI 25)] UNSPEC_FMULSU))
6172 (clobber (reg:HI 24))]
6175 [(set_attr "type" "xcall")
6176 (set_attr "cc" "clobber")])
6179 ;; Some combiner patterns dealing with bits.
6182 ;; Move bit $3.0 into bit $0.$4
6183 (define_insn "*movbitqi.1-6.a"
6184 [(set (match_operand:QI 0 "register_operand" "=r")
6185 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6186 (match_operand:QI 2 "single_zero_operand" "n"))
6187 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6188 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6189 (match_operand:QI 5 "single_one_operand" "n"))))]
6190 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6191 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6192 "bst %3,0\;bld %0,%4"
6193 [(set_attr "length" "2")
6194 (set_attr "cc" "none")])
6196 ;; Move bit $3.0 into bit $0.$4
6197 ;; Variation of above. Unfortunately, there is no canonicalized representation
6198 ;; of moving around bits. So what we see here depends on how user writes down
6199 ;; bit manipulations.
6200 (define_insn "*movbitqi.1-6.b"
6201 [(set (match_operand:QI 0 "register_operand" "=r")
6202 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6203 (match_operand:QI 2 "single_zero_operand" "n"))
6204 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6206 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6207 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6208 "bst %3,0\;bld %0,%4"
6209 [(set_attr "length" "2")
6210 (set_attr "cc" "none")])
6212 ;; Move bit $3.0 into bit $0.0.
6213 ;; For bit 0, combiner generates slightly different pattern.
6214 (define_insn "*movbitqi.0"
6215 [(set (match_operand:QI 0 "register_operand" "=r")
6216 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6217 (match_operand:QI 2 "single_zero_operand" "n"))
6218 (and:QI (match_operand:QI 3 "register_operand" "r")
6220 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6221 "bst %3,0\;bld %0,0"
6222 [(set_attr "length" "2")
6223 (set_attr "cc" "none")])
6225 ;; Move bit $2.0 into bit $0.7.
6226 ;; For bit 7, combiner generates slightly different pattern
6227 (define_insn "*movbitqi.7"
6228 [(set (match_operand:QI 0 "register_operand" "=r")
6229 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6231 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6234 "bst %2,0\;bld %0,7"
6235 [(set_attr "length" "2")
6236 (set_attr "cc" "none")])
6238 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6239 ;; and input/output match. We provide a special pattern for this, because
6240 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6241 ;; operation on I/O is atomic.
6242 (define_insn "*insv.io"
6243 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6245 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6246 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6251 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6252 [(set_attr "length" "1,1,4")
6253 (set_attr "cc" "none")])
6255 (define_insn "*insv.not.io"
6256 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6258 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6259 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6261 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6262 [(set_attr "length" "4")
6263 (set_attr "cc" "none")])
6265 ;; The insv expander.
6266 ;; We only support 1-bit inserts
6267 (define_expand "insv"
6268 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6269 (match_operand:QI 1 "const1_operand" "") ; width
6270 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6271 (match_operand:QI 3 "nonmemory_operand" ""))]
6274 ;; Insert bit $2.0 into $0.$1
6275 (define_insn "*insv.reg"
6276 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6278 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6279 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6283 andi %0,lo8(~(1<<%1))
6287 [(set_attr "length" "2,1,1,2,2")
6288 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6291 ;; Some combine patterns that try to fix bad code when a value is composed
6292 ;; from byte parts like in PR27663.
6293 ;; The patterns give some release but the code still is not optimal,
6294 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6295 ;; That switch obfuscates things here and in many other places.
6297 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6298 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6299 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6300 [(set (match_operand:HISI 0 "register_operand" "=r")
6302 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6303 (match_operand:HISI 2 "register_operand" "0")))]
6308 (xior:QI (match_dup 3)
6311 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6314 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6315 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6316 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6317 [(set (match_operand:HISI 0 "register_operand" "=r")
6319 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6320 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6321 (match_operand:HISI 3 "register_operand" "0")))]
6322 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6324 "&& reload_completed"
6326 (xior:QI (match_dup 4)
6329 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6330 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6333 (define_expand "extzv"
6334 [(set (match_operand:QI 0 "register_operand" "")
6335 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6336 (match_operand:QI 2 "const1_operand" "")
6337 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6339 (define_insn "*extzv"
6340 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6341 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6343 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6347 mov %0,%1\;andi %0,1
6350 bst %1,%2\;clr %0\;bld %0,0"
6351 [(set_attr "length" "1,2,2,2,3")
6352 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6354 (define_insn_and_split "*extzv.qihi1"
6355 [(set (match_operand:HI 0 "register_operand" "=r")
6356 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6358 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6363 (zero_extract:QI (match_dup 1)
6369 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6370 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6373 (define_insn_and_split "*extzv.qihi2"
6374 [(set (match_operand:HI 0 "register_operand" "=r")
6376 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6378 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6383 (zero_extract:QI (match_dup 1)
6389 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6390 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6394 ;; Fixed-point instructions
6395 (include "avr-fixed.md")
6397 ;; Operations on 64-bit registers
6398 (include "avr-dimode.md")