1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998-2013 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 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
36 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
37 ;; just cashes the operand for the next %T. The second %T gets
38 ;; a CONST_INT that represents a bit position.
39 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
40 ;; "%T0%T1" it will print "r19,5".
41 ;; Notice that you must not write a comma between %T0 and %T1.
42 ;; T/t Similar to above, but don't print the comma and the bit number.
43 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
44 ;; "%T0%t1" it will print "r19".
45 ;;..x..Constant Direct Program memory address.
46 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
47 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
56 (LPM_REGNO 0) ; implicit target register of LPM
57 (TMP_REGNO 0) ; temporary register r0
58 (ZERO_REGNO 1) ; zero register r1
61 (define_c_enum "unspec"
74 (define_c_enum "unspecv"
75 [UNSPECV_PROLOGUE_SAVES
76 UNSPECV_EPILOGUE_RESTORES
80 UNSPECV_MEMORY_BARRIER
88 (include "predicates.md")
89 (include "constraints.md")
91 ;; Condition code settings.
92 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
94 (const_string "none"))
96 (define_attr "type" "branch,branch1,arith,xcall"
97 (const_string "arith"))
99 ;; The size of instructions in bytes.
100 ;; XXX may depend from "cc"
102 (define_attr "length" ""
103 (cond [(eq_attr "type" "branch")
104 (if_then_else (and (ge (minus (pc) (match_dup 0))
106 (le (minus (pc) (match_dup 0))
109 (if_then_else (and (ge (minus (pc) (match_dup 0))
111 (le (minus (pc) (match_dup 0))
115 (eq_attr "type" "branch1")
116 (if_then_else (and (ge (minus (pc) (match_dup 0))
118 (le (minus (pc) (match_dup 0))
121 (if_then_else (and (ge (minus (pc) (match_dup 0))
123 (le (minus (pc) (match_dup 0))
127 (eq_attr "type" "xcall")
128 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
133 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
134 ;; Following insn attribute tells if and how the adjustment has to be
136 ;; no No adjustment needed; attribute "length" is fine.
137 ;; Otherwise do special processing depending on the attribute.
139 (define_attr "adjust_len"
140 "out_bitop, plus, addto_sp,
141 tsthi, tstpsi, tstsi, compare, compare64, call,
142 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
145 ashlqi, ashrqi, lshrqi,
146 ashlhi, ashrhi, lshrhi,
147 ashlsi, ashrsi, lshrsi,
148 ashlpsi, ashrpsi, lshrpsi,
153 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
155 ;; mov : ISA has no MOVW movw : ISA has MOVW
156 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
157 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
158 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
159 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
160 ;; no_xmega: non-XMEGA core xmega : XMEGA core
163 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
165 (const_string "standard"))
167 (define_attr "enabled" ""
168 (cond [(eq_attr "isa" "standard")
171 (and (eq_attr "isa" "mov")
172 (match_test "!AVR_HAVE_MOVW"))
175 (and (eq_attr "isa" "movw")
176 (match_test "AVR_HAVE_MOVW"))
179 (and (eq_attr "isa" "rjmp")
180 (match_test "!AVR_HAVE_JMP_CALL"))
183 (and (eq_attr "isa" "jmp")
184 (match_test "AVR_HAVE_JMP_CALL"))
187 (and (eq_attr "isa" "ijmp")
188 (match_test "!AVR_HAVE_EIJMP_EICALL"))
191 (and (eq_attr "isa" "eijmp")
192 (match_test "AVR_HAVE_EIJMP_EICALL"))
195 (and (eq_attr "isa" "lpm")
196 (match_test "!AVR_HAVE_LPMX"))
199 (and (eq_attr "isa" "lpmx")
200 (match_test "AVR_HAVE_LPMX"))
203 (and (eq_attr "isa" "elpm")
204 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
207 (and (eq_attr "isa" "elpmx")
208 (match_test "AVR_HAVE_ELPMX"))
211 (and (eq_attr "isa" "xmega")
212 (match_test "AVR_XMEGA"))
215 (and (eq_attr "isa" "no_xmega")
216 (match_test "!AVR_XMEGA"))
221 ;; Define mode iterators
222 (define_mode_iterator QIHI [QI HI])
223 (define_mode_iterator QIHI2 [QI HI])
224 (define_mode_iterator QISI [QI HI PSI SI])
225 (define_mode_iterator QIDI [QI HI PSI SI DI])
226 (define_mode_iterator HISI [HI PSI SI])
228 (define_mode_iterator ALL1 [QI QQ UQQ])
229 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
230 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
232 ;; All supported move-modes
233 (define_mode_iterator MOVMODE [QI QQ UQQ
238 ;; Supported ordered modes that are 2, 3, 4 bytes wide
239 (define_mode_iterator ORDERED234 [HI SI PSI
243 ;; Define code iterators
244 ;; Define two incarnations so that we can build the cross product.
245 (define_code_iterator any_extend [sign_extend zero_extend])
246 (define_code_iterator any_extend2 [sign_extend zero_extend])
248 (define_code_iterator xior [xor ior])
249 (define_code_iterator eqne [eq ne])
251 (define_code_iterator ss_addsub [ss_plus ss_minus])
252 (define_code_iterator us_addsub [us_plus us_minus])
253 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
255 ;; Define code attributes
256 (define_code_attr extend_su
260 (define_code_attr extend_u
264 (define_code_attr extend_s
268 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
269 (define_code_attr mul_r_d
273 (define_code_attr abelian
274 [(ss_minus "") (us_minus "")
275 (ss_plus "%") (us_plus "%")])
277 ;; Map RTX code to its standard insn name
278 (define_code_attr code_stdname
285 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
286 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
289 ;;========================================================================
290 ;; The following is used by nonlocal_goto and setjmp.
291 ;; The receiver pattern will create no instructions since internally
292 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
293 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
294 ;; The 'null' receiver also avoids problems with optimisation
295 ;; not recognising incoming jmp and removing code that resets frame_pointer.
296 ;; The code derived from builtins.c.
298 (define_expand "nonlocal_goto_receiver"
300 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
303 emit_move_insn (virtual_stack_vars_rtx,
304 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
305 gen_int_mode (STARTING_FRAME_OFFSET,
307 /* ; This might change the hard frame pointer in ways that aren't
308 ; apparent to early optimization passes, so force a clobber. */
309 emit_clobber (hard_frame_pointer_rtx);
314 ;; Defining nonlocal_goto_receiver means we must also define this.
315 ;; even though its function is identical to that in builtins.c
317 (define_expand "nonlocal_goto"
318 [(use (match_operand 0 "general_operand"))
319 (use (match_operand 1 "general_operand"))
320 (use (match_operand 2 "general_operand"))
321 (use (match_operand 3 "general_operand"))]
324 rtx r_label = copy_to_reg (operands[1]);
325 rtx r_fp = operands[3];
326 rtx r_sp = operands[2];
328 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
330 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
332 emit_move_insn (hard_frame_pointer_rtx, r_fp);
333 emit_stack_restore (SAVE_NONLOCAL, r_sp);
335 emit_use (hard_frame_pointer_rtx);
336 emit_use (stack_pointer_rtx);
338 emit_indirect_jump (r_label);
344 ;; "pushqq1" "pushuqq1"
345 (define_insn "push<mode>1"
346 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
347 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
352 [(set_attr "length" "1,1")])
354 ;; All modes for a multi-byte push. We must include complex modes here too,
355 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
356 (define_mode_iterator MPUSH
365 (define_expand "push<mode>1"
366 [(match_operand:MPUSH 0 "" "")]
370 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
372 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
373 if (part != const0_rtx)
374 part = force_reg (QImode, part);
375 emit_insn (gen_pushqi1 (part));
380 ;; Notice a special-case when adding N to SP where N results in a
381 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
383 [(set (reg:HI REG_SP)
384 (match_operand:HI 0 "register_operand" ""))]
386 && frame_pointer_needed
387 && !cfun->calls_alloca
388 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
389 [(set (reg:HI REG_SP)
392 ;;========================================================================
395 ;; Secondary input reload from non-generic 16-bit address spaces
396 (define_insn "reload_in<mode>"
397 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
398 (match_operand:MOVMODE 1 "flash_operand" "m"))
399 (clobber (match_operand:QI 2 "d_register_operand" "=d"))]
400 ;; Fixme: The insn condition must not test the address space.
401 ;; Because the gen tools refuse to generate insns for address spaces
402 ;; and will generate insn-codes.h to look like:
403 ;; #define CODE_FOR_reload_inhi CODE_FOR_nothing
404 "reload_completed || reload_in_progress"
406 return avr_out_lpm (insn, operands, NULL);
408 [(set_attr "adjust_len" "lpm")
409 (set_attr "cc" "clobber")])
417 (define_expand "load<mode>_libgcc"
420 (set (reg:MOVMODE 22)
421 (match_operand:MOVMODE 1 "memory_operand" ""))
422 (set (match_operand:MOVMODE 0 "register_operand" "")
424 "avr_load_libgcc_p (operands[1])"
426 operands[3] = gen_rtx_REG (HImode, REG_Z);
427 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
428 operands[1] = replace_equiv_address (operands[1], operands[3]);
429 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
437 (define_insn "load_<mode>_libgcc"
438 [(set (reg:MOVMODE 22)
439 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
440 "avr_load_libgcc_p (operands[0])
441 && REG_P (XEXP (operands[0], 0))
442 && REG_Z == REGNO (XEXP (operands[0], 0))"
444 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
445 return "%~call __load_%0";
447 [(set_attr "length" "1,2")
448 (set_attr "isa" "rjmp,jmp")
449 (set_attr "cc" "clobber")])
453 ;; "xload8qq_A" "xload8uqq_A"
454 (define_insn_and_split "xload8<mode>_A"
455 [(set (match_operand:ALL1 0 "register_operand" "=r")
456 (match_operand:ALL1 1 "memory_operand" "m"))
457 (clobber (reg:HI REG_Z))]
458 "can_create_pseudo_p()
459 && !avr_xload_libgcc_p (<MODE>mode)
460 && avr_mem_memx_p (operands[1])
461 && REG_P (XEXP (operands[1], 0))"
462 { gcc_unreachable(); }
464 [(clobber (const_int 0))]
466 /* ; Split away the high part of the address. GCC's register allocator
467 ; in not able to allocate segment registers and reload the resulting
468 ; expressions. Notice that no address register can hold a PSImode. */
470 rtx insn, addr = XEXP (operands[1], 0);
471 rtx hi8 = gen_reg_rtx (QImode);
472 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
474 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
475 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
477 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
478 set_mem_addr_space (SET_SRC (single_set (insn)),
479 MEM_ADDR_SPACE (operands[1]));
483 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
484 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
485 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
488 (define_insn_and_split "xload<mode>_A"
489 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
490 (match_operand:MOVMODE 1 "memory_operand" "m"))
491 (clobber (reg:MOVMODE 22))
492 (clobber (reg:QI 21))
493 (clobber (reg:HI REG_Z))]
494 "can_create_pseudo_p()
495 && avr_mem_memx_p (operands[1])
496 && REG_P (XEXP (operands[1], 0))"
497 { gcc_unreachable(); }
499 [(clobber (const_int 0))]
501 rtx addr = XEXP (operands[1], 0);
502 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
503 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
504 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
507 /* Split the address to R21:Z */
508 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
509 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
511 /* Load with code from libgcc */
512 insn = emit_insn (gen_xload_<mode>_libgcc ());
513 set_mem_addr_space (SET_SRC (single_set (insn)), as);
515 /* Move to destination */
516 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
521 ;; Move value from address space memx to a register
522 ;; These insns must be prior to respective generic move insn.
525 ;; "xloadqq_8" "xloaduqq_8"
526 (define_insn "xload<mode>_8"
527 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
528 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
530 "!avr_xload_libgcc_p (<MODE>mode)"
532 return avr_out_xload (insn, operands, NULL);
534 [(set_attr "length" "4,4")
535 (set_attr "adjust_len" "*,xload")
536 (set_attr "isa" "lpmx,lpm")
537 (set_attr "cc" "none")])
539 ;; R21:Z : 24-bit source address
540 ;; R22 : 1-4 byte output
542 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
543 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
544 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
546 ;; "xload_psi_libgcc"
547 (define_insn "xload_<mode>_libgcc"
548 [(set (reg:MOVMODE 22)
549 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
551 (clobber (reg:QI 21))
552 (clobber (reg:HI REG_Z))]
553 "avr_xload_libgcc_p (<MODE>mode)"
555 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
557 output_asm_insn ("%~call __xload_%0", &x_bytes);
560 [(set_attr "type" "xcall")
561 (set_attr "cc" "clobber")])
564 ;; General move expanders
566 ;; "movqi" "movqq" "movuqq"
567 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
568 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
571 (define_expand "mov<mode>"
572 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
573 (match_operand:MOVMODE 1 "general_operand" ""))]
576 rtx dest = operands[0];
577 rtx src = operands[1];
579 if (avr_mem_flash_p (dest))
582 /* One of the operands has to be in a register. */
583 if (!register_operand (dest, <MODE>mode)
584 && !reg_or_0_operand (src, <MODE>mode))
586 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
589 if (avr_mem_memx_p (src))
591 rtx addr = XEXP (src, 0);
594 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
596 if (!avr_xload_libgcc_p (<MODE>mode))
597 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
598 ; insn-emit does not depend on the mode, it's all about operands. */
599 emit_insn (gen_xload8qi_A (dest, src));
601 emit_insn (gen_xload<mode>_A (dest, src));
606 if (avr_load_libgcc_p (src))
608 /* For the small devices, do loads per libgcc call. */
609 emit_insn (gen_load<mode>_libgcc (dest, src));
614 ;;========================================================================
616 ;; The last alternative (any immediate constant to any register) is
617 ;; very expensive. It should be optimized by peephole2 if a scratch
618 ;; register is available, but then that register could just as well be
619 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
620 ;; are call-saved registers, and most of LD_REGS are call-used registers,
621 ;; so this may still be a win for registers live across function calls.
624 ;; "movqq_insn" "movuqq_insn"
625 (define_insn "mov<mode>_insn"
626 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
627 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
628 "register_operand (operands[0], <MODE>mode)
629 || reg_or_0_operand (operands[1], <MODE>mode)"
631 return output_movqi (insn, operands, NULL);
633 [(set_attr "length" "1,1,5,5,1,1,4")
634 (set_attr "adjust_len" "mov8")
635 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
637 ;; This is used in peephole2 to optimize loading immediate constants
638 ;; if a scratch register from LD_REGS happens to be available.
641 ;; "*reload_inqq" "*reload_inuqq"
642 (define_insn "*reload_in<mode>"
643 [(set (match_operand:ALL1 0 "register_operand" "=l")
644 (match_operand:ALL1 1 "const_operand" "i"))
645 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
649 [(set_attr "length" "2")
650 (set_attr "cc" "none")])
653 [(match_scratch:QI 2 "d")
654 (set (match_operand:ALL1 0 "l_register_operand" "")
655 (match_operand:ALL1 1 "const_operand" ""))]
656 ; No need for a clobber reg for 0x0, 0x01 or 0xff
657 "!satisfies_constraint_Y00 (operands[1])
658 && !satisfies_constraint_Y01 (operands[1])
659 && !satisfies_constraint_Ym1 (operands[1])"
660 [(parallel [(set (match_dup 0)
662 (clobber (match_dup 2))])])
664 ;;============================================================================
665 ;; move word (16 bit)
667 ;; Move register $1 to the Stack Pointer register SP.
668 ;; This insn is emit during function prologue/epilogue generation.
669 ;; $2 = 0: We know that IRQs are off
670 ;; $2 = 1: We know that IRQs are on
671 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
672 ;; $2 = -1: We don't know anything about IRQ on/off
673 ;; Always write SP via unspec, see PR50063
675 (define_insn "movhi_sp_r"
676 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
677 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
678 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
682 out %B0,%B1\;out %A0,%A1
683 cli\;out %B0,%B1\;sei\;out %A0,%A1
684 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
686 out %A0,%A1\;out %B0,%B1"
687 [(set_attr "length" "2,4,5,1,2")
688 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
689 (set_attr "cc" "none")])
692 [(match_scratch:QI 2 "d")
693 (set (match_operand:ALL2 0 "l_register_operand" "")
694 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
695 "operands[1] != CONST0_RTX (<MODE>mode)"
696 [(parallel [(set (match_dup 0)
698 (clobber (match_dup 2))])])
700 ;; '*' because it is not used in rtl generation, only in above peephole
702 ;; "*reload_inhq" "*reload_inuhq"
703 ;; "*reload_inha" "*reload_inuha"
704 (define_insn "*reload_in<mode>"
705 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
706 (match_operand:ALL2 1 "immediate_operand" "i"))
707 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
710 return output_reload_inhi (operands, operands[2], NULL);
712 [(set_attr "length" "4")
713 (set_attr "adjust_len" "reload_in16")
714 (set_attr "cc" "clobber")])
717 ;; "*movhq" "*movuhq"
718 ;; "*movha" "*movuha"
719 (define_insn "*mov<mode>"
720 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
721 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
722 "register_operand (operands[0], <MODE>mode)
723 || reg_or_0_operand (operands[1], <MODE>mode)"
725 return output_movhi (insn, operands, NULL);
727 [(set_attr "length" "2,2,6,7,2,6,5,2")
728 (set_attr "adjust_len" "mov16")
729 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
731 (define_peephole2 ; movw
732 [(set (match_operand:ALL1 0 "even_register_operand" "")
733 (match_operand:ALL1 1 "even_register_operand" ""))
734 (set (match_operand:ALL1 2 "odd_register_operand" "")
735 (match_operand:ALL1 3 "odd_register_operand" ""))]
737 && REGNO (operands[0]) == REGNO (operands[2]) - 1
738 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
742 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
743 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
746 (define_peephole2 ; movw_r
747 [(set (match_operand:ALL1 0 "odd_register_operand" "")
748 (match_operand:ALL1 1 "odd_register_operand" ""))
749 (set (match_operand:ALL1 2 "even_register_operand" "")
750 (match_operand:ALL1 3 "even_register_operand" ""))]
752 && REGNO (operands[2]) == REGNO (operands[0]) - 1
753 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
757 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
758 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
761 ;; For LPM loads from AS1 we split
765 ;; Z = Z - sizeof (R)
767 ;; so that the second instruction can be optimized out.
769 (define_split ; "split-lpmx"
770 [(set (match_operand:HISI 0 "register_operand" "")
771 (match_operand:HISI 1 "memory_operand" ""))]
777 (plus:HI (match_dup 3)
780 rtx addr = XEXP (operands[1], 0);
782 if (!avr_mem_flash_p (operands[1])
784 || reg_overlap_mentioned_p (addr, operands[0]))
789 operands[2] = replace_equiv_address (operands[1],
790 gen_rtx_POST_INC (Pmode, addr));
792 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
795 ;;==========================================================================
796 ;; xpointer move (24 bit)
798 (define_peephole2 ; *reload_inpsi
799 [(match_scratch:QI 2 "d")
800 (set (match_operand:PSI 0 "l_register_operand" "")
801 (match_operand:PSI 1 "immediate_operand" ""))
803 "operands[1] != const0_rtx
804 && operands[1] != constm1_rtx"
805 [(parallel [(set (match_dup 0)
807 (clobber (match_dup 2))])])
809 ;; '*' because it is not used in rtl generation.
810 (define_insn "*reload_inpsi"
811 [(set (match_operand:PSI 0 "register_operand" "=r")
812 (match_operand:PSI 1 "immediate_operand" "i"))
813 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
816 return avr_out_reload_inpsi (operands, operands[2], NULL);
818 [(set_attr "length" "6")
819 (set_attr "adjust_len" "reload_in24")
820 (set_attr "cc" "clobber")])
822 (define_insn "*movpsi"
823 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
824 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
825 "register_operand (operands[0], PSImode)
826 || register_operand (operands[1], PSImode)
827 || const0_rtx == operands[1]"
829 return avr_out_movpsi (insn, operands, NULL);
831 [(set_attr "length" "3,3,8,9,4,10")
832 (set_attr "adjust_len" "mov24")
833 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
835 ;;==========================================================================
836 ;; move double word (32 bit)
838 (define_peephole2 ; *reload_insi
839 [(match_scratch:QI 2 "d")
840 (set (match_operand:ALL4 0 "l_register_operand" "")
841 (match_operand:ALL4 1 "immediate_operand" ""))
843 "operands[1] != CONST0_RTX (<MODE>mode)"
844 [(parallel [(set (match_dup 0)
846 (clobber (match_dup 2))])])
848 ;; '*' because it is not used in rtl generation.
850 ;; "*reload_insq" "*reload_inusq"
851 ;; "*reload_insa" "*reload_inusa"
852 (define_insn "*reload_insi"
853 [(set (match_operand:ALL4 0 "register_operand" "=r")
854 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
855 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
858 return output_reload_insisf (operands, operands[2], NULL);
860 [(set_attr "length" "8")
861 (set_attr "adjust_len" "reload_in32")
862 (set_attr "cc" "clobber")])
866 ;; "*movsq" "*movusq"
867 ;; "*movsa" "*movusa"
868 (define_insn "*mov<mode>"
869 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
870 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
871 "register_operand (operands[0], <MODE>mode)
872 || reg_or_0_operand (operands[1], <MODE>mode)"
874 return output_movsisf (insn, operands, NULL);
876 [(set_attr "length" "4,4,8,9,4,10")
877 (set_attr "adjust_len" "mov32")
878 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
880 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
881 ;; move floating point numbers (32 bit)
883 (define_insn "*movsf"
884 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
885 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
886 "register_operand (operands[0], SFmode)
887 || reg_or_0_operand (operands[1], SFmode)"
889 return output_movsisf (insn, operands, NULL);
891 [(set_attr "length" "4,4,8,9,4,10")
892 (set_attr "adjust_len" "mov32")
893 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
895 (define_peephole2 ; *reload_insf
896 [(match_scratch:QI 2 "d")
897 (set (match_operand:SF 0 "l_register_operand" "")
898 (match_operand:SF 1 "const_double_operand" ""))
900 "operands[1] != CONST0_RTX (SFmode)"
901 [(parallel [(set (match_dup 0)
903 (clobber (match_dup 2))])])
905 ;; '*' because it is not used in rtl generation.
906 (define_insn "*reload_insf"
907 [(set (match_operand:SF 0 "register_operand" "=r")
908 (match_operand:SF 1 "const_double_operand" "F"))
909 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
912 return output_reload_insisf (operands, operands[2], NULL);
914 [(set_attr "length" "8")
915 (set_attr "adjust_len" "reload_in32")
916 (set_attr "cc" "clobber")])
918 ;;=========================================================================
919 ;; move string (like memcpy)
921 (define_expand "movmemhi"
922 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
923 (match_operand:BLK 1 "memory_operand" ""))
924 (use (match_operand:HI 2 "const_int_operand" ""))
925 (use (match_operand:HI 3 "const_int_operand" ""))])]
928 if (avr_emit_movmemhi (operands))
934 (define_mode_attr MOVMEM_r_d [(QI "r")
937 ;; $0 : Address Space
938 ;; $1, $2 : Loop register
939 ;; R30 : source address
940 ;; R26 : destination address
944 (define_insn "movmem_<mode>"
945 [(set (mem:BLK (reg:HI REG_X))
946 (mem:BLK (reg:HI REG_Z)))
947 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
949 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
950 (clobber (reg:HI REG_X))
951 (clobber (reg:HI REG_Z))
952 (clobber (reg:QI LPM_REGNO))
953 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
956 return avr_out_movmem (insn, operands, NULL);
958 [(set_attr "adjust_len" "movmem")
959 (set_attr "cc" "clobber")])
962 ;; $0 : Address Space
963 ;; $1 : RAMPZ RAM address
964 ;; R24 : #bytes and loop register
965 ;; R23:Z : 24-bit source address
966 ;; R26 : 16-bit destination address
970 (define_insn "movmemx_<mode>"
971 [(set (mem:BLK (reg:HI REG_X))
972 (mem:BLK (lo_sum:PSI (reg:QI 23)
974 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
977 (clobber (reg:HI REG_X))
978 (clobber (reg:HI REG_Z))
979 (clobber (reg:QI LPM_REGNO))
980 (clobber (reg:HI 24))
981 (clobber (reg:QI 23))
982 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
984 "%~call __movmemx_<mode>"
985 [(set_attr "type" "xcall")
986 (set_attr "cc" "clobber")])
989 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
990 ;; memset (%0, %2, %1)
992 (define_expand "setmemhi"
993 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
994 (match_operand 2 "const_int_operand" ""))
995 (use (match_operand:HI 1 "const_int_operand" ""))
996 (use (match_operand:HI 3 "const_int_operand" ""))
997 (clobber (match_scratch:HI 4 ""))
998 (clobber (match_dup 5))])]
1002 enum machine_mode mode;
1004 /* If value to set is not zero, use the library routine. */
1005 if (operands[2] != const0_rtx)
1008 if (!CONST_INT_P (operands[1]))
1011 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1012 operands[5] = gen_rtx_SCRATCH (mode);
1013 operands[1] = copy_to_mode_reg (mode,
1014 gen_int_mode (INTVAL (operands[1]), mode));
1015 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1016 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1020 (define_insn "*clrmemqi"
1021 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1023 (use (match_operand:QI 1 "register_operand" "r"))
1024 (use (match_operand:QI 2 "const_int_operand" "n"))
1025 (clobber (match_scratch:HI 3 "=0"))
1026 (clobber (match_scratch:QI 4 "=&1"))]
1028 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1029 [(set_attr "length" "3")
1030 (set_attr "cc" "clobber")])
1033 (define_insn "*clrmemhi"
1034 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1036 (use (match_operand:HI 1 "register_operand" "!w,d"))
1037 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1038 (clobber (match_scratch:HI 3 "=0,0"))
1039 (clobber (match_scratch:HI 4 "=&1,&1"))]
1042 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1043 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1044 [(set_attr "length" "3,4")
1045 (set_attr "cc" "clobber,clobber")])
1047 (define_expand "strlenhi"
1049 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1050 (match_operand:QI 2 "const_int_operand" "")
1051 (match_operand:HI 3 "immediate_operand" "")]
1054 (plus:HI (match_dup 4)
1056 (parallel [(set (match_operand:HI 0 "register_operand" "")
1057 (minus:HI (match_dup 4)
1059 (clobber (scratch:QI))])]
1063 if (operands[2] != const0_rtx)
1065 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1066 operands[1] = gen_rtx_MEM (BLKmode, addr);
1068 operands[4] = gen_reg_rtx (HImode);
1071 (define_insn "*strlenhi"
1072 [(set (match_operand:HI 0 "register_operand" "=e")
1073 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1075 (match_operand:HI 2 "immediate_operand" "i")]
1078 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1079 [(set_attr "length" "3")
1080 (set_attr "cc" "clobber")])
1082 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1086 ;; "addqq3" "adduqq3"
1087 (define_insn "add<mode>3"
1088 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1089 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1090 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1099 [(set_attr "length" "1,1,1,1,2,2")
1100 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1103 ;; "addhq3" "adduhq3"
1104 ;; "addha3" "adduha3"
1105 (define_expand "add<mode>3"
1106 [(set (match_operand:ALL2 0 "register_operand" "")
1107 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1108 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1111 if (CONST_INT_P (operands[2]))
1113 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1115 if (can_create_pseudo_p()
1116 && !stack_register_operand (operands[0], HImode)
1117 && !stack_register_operand (operands[1], HImode)
1118 && !d_register_operand (operands[0], HImode)
1119 && !d_register_operand (operands[1], HImode))
1121 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1126 if (CONST_FIXED_P (operands[2]))
1128 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1134 (define_insn "*addhi3_zero_extend"
1135 [(set (match_operand:HI 0 "register_operand" "=r")
1136 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1137 (match_operand:HI 2 "register_operand" "0")))]
1139 "add %A0,%1\;adc %B0,__zero_reg__"
1140 [(set_attr "length" "2")
1141 (set_attr "cc" "set_n")])
1143 (define_insn "*addhi3_zero_extend1"
1144 [(set (match_operand:HI 0 "register_operand" "=r")
1145 (plus:HI (match_operand:HI 1 "register_operand" "0")
1146 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1148 "add %A0,%2\;adc %B0,__zero_reg__"
1149 [(set_attr "length" "2")
1150 (set_attr "cc" "set_n")])
1152 (define_insn "*addhi3.sign_extend1"
1153 [(set (match_operand:HI 0 "register_operand" "=r")
1154 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1155 (match_operand:HI 2 "register_operand" "0")))]
1158 return reg_overlap_mentioned_p (operands[0], operands[1])
1159 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1160 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1162 [(set_attr "length" "5")
1163 (set_attr "cc" "clobber")])
1165 (define_insn "*addhi3_sp"
1166 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1167 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1168 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1171 return avr_out_addto_sp (operands, NULL);
1173 [(set_attr "length" "6")
1174 (set_attr "adjust_len" "addto_sp")])
1177 ;; "*addhq3" "*adduhq3"
1178 ;; "*addha3" "*adduha3"
1179 (define_insn "*add<mode>3"
1180 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1181 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1182 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1185 return avr_out_plus (insn, operands);
1187 [(set_attr "length" "2")
1188 (set_attr "adjust_len" "plus")
1189 (set_attr "cc" "plus")])
1191 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1192 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1193 ;; itself because that insn is special to reload.
1195 (define_peephole2 ; addhi3_clobber
1196 [(set (match_operand:ALL2 0 "d_register_operand" "")
1197 (match_operand:ALL2 1 "const_operand" ""))
1198 (set (match_operand:ALL2 2 "l_register_operand" "")
1199 (plus:ALL2 (match_dup 2)
1201 "peep2_reg_dead_p (2, operands[0])"
1202 [(parallel [(set (match_dup 2)
1203 (plus:ALL2 (match_dup 2)
1205 (clobber (match_dup 3))])]
1207 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1210 ;; Same, but with reload to NO_LD_REGS
1211 ;; Combine *reload_inhi with *addhi3
1213 (define_peephole2 ; addhi3_clobber
1214 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1215 (match_operand:ALL2 1 "const_operand" ""))
1216 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1217 (set (match_operand:ALL2 3 "l_register_operand" "")
1218 (plus:ALL2 (match_dup 3)
1220 "peep2_reg_dead_p (2, operands[0])"
1221 [(parallel [(set (match_dup 3)
1222 (plus:ALL2 (match_dup 3)
1224 (clobber (match_dup 2))])])
1227 ;; "addhq3_clobber" "adduhq3_clobber"
1228 ;; "addha3_clobber" "adduha3_clobber"
1229 (define_insn "add<mode>3_clobber"
1230 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1231 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1232 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1233 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1236 return avr_out_plus (insn, operands);
1238 [(set_attr "length" "4")
1239 (set_attr "adjust_len" "plus")
1240 (set_attr "cc" "plus")])
1244 ;; "addsq3" "addusq3"
1245 ;; "addsa3" "addusa3"
1246 (define_insn "add<mode>3"
1247 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1248 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1249 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1250 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1253 return avr_out_plus (insn, operands);
1255 [(set_attr "length" "4")
1256 (set_attr "adjust_len" "plus")
1257 (set_attr "cc" "plus")])
1259 (define_insn "*addpsi3_zero_extend.qi"
1260 [(set (match_operand:PSI 0 "register_operand" "=r")
1261 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1262 (match_operand:PSI 2 "register_operand" "0")))]
1264 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1265 [(set_attr "length" "3")
1266 (set_attr "cc" "set_n")])
1268 (define_insn "*addpsi3_zero_extend.hi"
1269 [(set (match_operand:PSI 0 "register_operand" "=r")
1270 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1271 (match_operand:PSI 2 "register_operand" "0")))]
1273 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1274 [(set_attr "length" "3")
1275 (set_attr "cc" "set_n")])
1277 (define_insn "*addpsi3_sign_extend.hi"
1278 [(set (match_operand:PSI 0 "register_operand" "=r")
1279 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1280 (match_operand:PSI 2 "register_operand" "0")))]
1282 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1283 [(set_attr "length" "5")
1284 (set_attr "cc" "set_n")])
1286 (define_insn "*addsi3_zero_extend"
1287 [(set (match_operand:SI 0 "register_operand" "=r")
1288 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1289 (match_operand:SI 2 "register_operand" "0")))]
1291 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1292 [(set_attr "length" "4")
1293 (set_attr "cc" "set_n")])
1295 (define_insn "*addsi3_zero_extend.hi"
1296 [(set (match_operand:SI 0 "register_operand" "=r")
1297 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1298 (match_operand:SI 2 "register_operand" "0")))]
1300 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1301 [(set_attr "length" "4")
1302 (set_attr "cc" "set_n")])
1304 (define_insn "addpsi3"
1305 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1306 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1307 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1308 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1311 return avr_out_plus (insn, operands);
1313 [(set_attr "length" "3")
1314 (set_attr "adjust_len" "plus")
1315 (set_attr "cc" "plus")])
1317 (define_insn "subpsi3"
1318 [(set (match_operand:PSI 0 "register_operand" "=r")
1319 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1320 (match_operand:PSI 2 "register_operand" "r")))]
1322 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1323 [(set_attr "length" "3")
1324 (set_attr "cc" "set_czn")])
1326 (define_insn "*subpsi3_zero_extend.qi"
1327 [(set (match_operand:PSI 0 "register_operand" "=r")
1328 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1329 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1331 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1332 [(set_attr "length" "3")
1333 (set_attr "cc" "set_czn")])
1335 (define_insn "*subpsi3_zero_extend.hi"
1336 [(set (match_operand:PSI 0 "register_operand" "=r")
1337 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1338 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1340 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1341 [(set_attr "length" "3")
1342 (set_attr "cc" "set_czn")])
1344 (define_insn "*subpsi3_sign_extend.hi"
1345 [(set (match_operand:PSI 0 "register_operand" "=r")
1346 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1347 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1349 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1350 [(set_attr "length" "5")
1351 (set_attr "cc" "set_czn")])
1353 ;-----------------------------------------------------------------------------
1357 ;; "subqq3" "subuqq3"
1358 (define_insn "sub<mode>3"
1359 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1360 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1361 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1370 [(set_attr "length" "1,1,1,1,2,2")
1371 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1374 ;; "subhq3" "subuhq3"
1375 ;; "subha3" "subuha3"
1376 (define_insn "sub<mode>3"
1377 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1378 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1379 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1380 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1383 return avr_out_plus (insn, operands);
1385 [(set_attr "adjust_len" "plus")
1386 (set_attr "cc" "plus")])
1388 (define_insn "*subhi3_zero_extend1"
1389 [(set (match_operand:HI 0 "register_operand" "=r")
1390 (minus:HI (match_operand:HI 1 "register_operand" "0")
1391 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1393 "sub %A0,%2\;sbc %B0,__zero_reg__"
1394 [(set_attr "length" "2")
1395 (set_attr "cc" "set_czn")])
1397 (define_insn "*subhi3.sign_extend2"
1398 [(set (match_operand:HI 0 "register_operand" "=r")
1399 (minus:HI (match_operand:HI 1 "register_operand" "0")
1400 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1403 return reg_overlap_mentioned_p (operands[0], operands[2])
1404 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1405 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1407 [(set_attr "length" "5")
1408 (set_attr "cc" "clobber")])
1411 ;; "subsq3" "subusq3"
1412 ;; "subsa3" "subusa3"
1413 (define_insn "sub<mode>3"
1414 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1415 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1416 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1417 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1420 return avr_out_plus (insn, operands);
1422 [(set_attr "adjust_len" "plus")
1423 (set_attr "cc" "plus")])
1425 (define_insn "*subsi3_zero_extend"
1426 [(set (match_operand:SI 0 "register_operand" "=r")
1427 (minus:SI (match_operand:SI 1 "register_operand" "0")
1428 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1430 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1431 [(set_attr "length" "4")
1432 (set_attr "cc" "set_czn")])
1434 (define_insn "*subsi3_zero_extend.hi"
1435 [(set (match_operand:SI 0 "register_operand" "=r")
1436 (minus:SI (match_operand:SI 1 "register_operand" "0")
1437 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1439 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1440 [(set_attr "length" "4")
1441 (set_attr "cc" "set_czn")])
1443 ;******************************************************************************
1446 (define_expand "mulqi3"
1447 [(set (match_operand:QI 0 "register_operand" "")
1448 (mult:QI (match_operand:QI 1 "register_operand" "")
1449 (match_operand:QI 2 "register_operand" "")))]
1454 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1459 (define_insn "*mulqi3_enh"
1460 [(set (match_operand:QI 0 "register_operand" "=r")
1461 (mult:QI (match_operand:QI 1 "register_operand" "r")
1462 (match_operand:QI 2 "register_operand" "r")))]
1467 [(set_attr "length" "3")
1468 (set_attr "cc" "clobber")])
1470 (define_expand "mulqi3_call"
1471 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1472 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1473 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1474 (clobber (reg:QI 22))])
1475 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
1477 (define_insn "*mulqi3_call"
1478 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1479 (clobber (reg:QI 22))]
1482 [(set_attr "type" "xcall")
1483 (set_attr "cc" "clobber")])
1485 ;; "umulqi3_highpart"
1486 ;; "smulqi3_highpart"
1487 (define_insn "<extend_su>mulqi3_highpart"
1488 [(set (match_operand:QI 0 "register_operand" "=r")
1490 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1491 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1494 "mul<extend_s> %1,%2
1497 [(set_attr "length" "3")
1498 (set_attr "cc" "clobber")])
1501 ;; Used when expanding div or mod inline for some special values
1502 (define_insn "*subqi3.ashiftrt7"
1503 [(set (match_operand:QI 0 "register_operand" "=r")
1504 (minus:QI (match_operand:QI 1 "register_operand" "0")
1505 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1509 [(set_attr "length" "2")
1510 (set_attr "cc" "clobber")])
1512 (define_insn "*addqi3.lt0"
1513 [(set (match_operand:QI 0 "register_operand" "=r")
1514 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1516 (match_operand:QI 2 "register_operand" "0")))]
1519 [(set_attr "length" "2")
1520 (set_attr "cc" "clobber")])
1522 (define_insn "*addhi3.lt0"
1523 [(set (match_operand:HI 0 "register_operand" "=w,r")
1524 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1526 (match_operand:HI 2 "register_operand" "0,0")))
1527 (clobber (match_scratch:QI 3 "=X,&1"))]
1530 sbrc %1,7\;adiw %0,1
1531 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1532 [(set_attr "length" "2,3")
1533 (set_attr "cc" "clobber")])
1535 (define_insn "*addpsi3.lt0"
1536 [(set (match_operand:PSI 0 "register_operand" "=r")
1537 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1539 (match_operand:PSI 2 "register_operand" "0")))]
1541 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1542 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1543 [(set_attr "length" "5")
1544 (set_attr "cc" "clobber")])
1546 (define_insn "*addsi3.lt0"
1547 [(set (match_operand:SI 0 "register_operand" "=r")
1548 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1550 (match_operand:SI 2 "register_operand" "0")))]
1552 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1553 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1554 [(set_attr "length" "6")
1555 (set_attr "cc" "clobber")])
1557 (define_insn "*umulqihi3.call"
1559 (mult:HI (zero_extend:HI (reg:QI 22))
1560 (zero_extend:HI (reg:QI 24))))
1561 (clobber (reg:QI 21))
1562 (clobber (reg:HI 22))]
1564 "%~call __umulqihi3"
1565 [(set_attr "type" "xcall")
1566 (set_attr "cc" "clobber")])
1570 (define_insn "<extend_u>mulqihi3"
1571 [(set (match_operand:HI 0 "register_operand" "=r")
1572 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1573 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1575 "mul<extend_s> %1,%2
1578 [(set_attr "length" "3")
1579 (set_attr "cc" "clobber")])
1581 (define_insn "usmulqihi3"
1582 [(set (match_operand:HI 0 "register_operand" "=r")
1583 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1584 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1589 [(set_attr "length" "3")
1590 (set_attr "cc" "clobber")])
1592 ;; Above insn is not canonicalized by insn combine, so here is a version with
1593 ;; operands swapped.
1595 (define_insn "*sumulqihi3"
1596 [(set (match_operand:HI 0 "register_operand" "=r")
1597 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1598 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1603 [(set_attr "length" "3")
1604 (set_attr "cc" "clobber")])
1606 ;; One-extend operand 1
1608 (define_insn "*osmulqihi3"
1609 [(set (match_operand:HI 0 "register_operand" "=&r")
1610 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1611 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1617 [(set_attr "length" "4")
1618 (set_attr "cc" "clobber")])
1620 (define_insn "*oumulqihi3"
1621 [(set (match_operand:HI 0 "register_operand" "=&r")
1622 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1623 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1629 [(set_attr "length" "4")
1630 (set_attr "cc" "clobber")])
1632 ;******************************************************************************
1633 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1634 ;******************************************************************************
1636 (define_insn "*maddqi4"
1637 [(set (match_operand:QI 0 "register_operand" "=r")
1638 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1639 (match_operand:QI 2 "register_operand" "r"))
1640 (match_operand:QI 3 "register_operand" "0")))]
1646 [(set_attr "length" "4")
1647 (set_attr "cc" "clobber")])
1649 (define_insn "*msubqi4"
1650 [(set (match_operand:QI 0 "register_operand" "=r")
1651 (minus:QI (match_operand:QI 3 "register_operand" "0")
1652 (mult:QI (match_operand:QI 1 "register_operand" "r")
1653 (match_operand:QI 2 "register_operand" "r"))))]
1658 [(set_attr "length" "4")
1659 (set_attr "cc" "clobber")])
1661 (define_insn_and_split "*maddqi4.const"
1662 [(set (match_operand:QI 0 "register_operand" "=r")
1663 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1664 (match_operand:QI 2 "const_int_operand" "n"))
1665 (match_operand:QI 3 "register_operand" "0")))
1666 (clobber (match_scratch:QI 4 "=&d"))]
1669 "&& reload_completed"
1674 (plus:QI (mult:QI (match_dup 1)
1678 (define_insn_and_split "*msubqi4.const"
1679 [(set (match_operand:QI 0 "register_operand" "=r")
1680 (minus:QI (match_operand:QI 3 "register_operand" "0")
1681 (mult:QI (match_operand:QI 1 "register_operand" "r")
1682 (match_operand:QI 2 "const_int_operand" "n"))))
1683 (clobber (match_scratch:QI 4 "=&d"))]
1686 "&& reload_completed"
1691 (minus:QI (match_dup 3)
1692 (mult:QI (match_dup 1)
1696 ;******************************************************************************
1697 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1698 ;******************************************************************************
1700 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1703 ;; int foo (unsigned char z)
1705 ;; extern int aInt[];
1706 ;; return aInt[3*z+2];
1709 ;; because the constant +4 then is added explicitely instead of consuming it
1710 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1711 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1712 ;; The implementational effort is the same so we are fine with that approach.
1717 (define_insn "*<extend_u>maddqihi4"
1718 [(set (match_operand:HI 0 "register_operand" "=r")
1719 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1720 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1721 (match_operand:HI 3 "register_operand" "0")))]
1724 "mul<extend_s> %1,%2
1728 [(set_attr "length" "4")
1729 (set_attr "cc" "clobber")])
1733 (define_insn "*<extend_u>msubqihi4"
1734 [(set (match_operand:HI 0 "register_operand" "=r")
1735 (minus:HI (match_operand:HI 3 "register_operand" "0")
1736 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1737 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1739 "mul<extend_s> %1,%2
1743 [(set_attr "length" "4")
1744 (set_attr "cc" "clobber")])
1748 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1749 [(set (match_operand:HI 0 "register_operand" "=r")
1750 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1751 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1752 (match_operand:HI 3 "register_operand" "0")))]
1755 && <any_extend:CODE> != <any_extend2:CODE>"
1757 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1758 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1760 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1762 [(set_attr "length" "4")
1763 (set_attr "cc" "clobber")])
1767 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1768 [(set (match_operand:HI 0 "register_operand" "=r")
1769 (minus:HI (match_operand:HI 3 "register_operand" "0")
1770 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1771 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1774 && <any_extend:CODE> != <any_extend2:CODE>"
1776 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1777 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1779 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1781 [(set_attr "length" "4")
1782 (set_attr "cc" "clobber")])
1784 ;; Handle small constants
1786 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1787 ;; This is shorter, faster than MUL and has lower register pressure.
1789 (define_insn_and_split "*umaddqihi4.2"
1790 [(set (match_operand:HI 0 "register_operand" "=r")
1791 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1793 (match_operand:HI 2 "register_operand" "r")))]
1795 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1796 { gcc_unreachable(); }
1800 ; *addhi3_zero_extend
1802 (plus:HI (zero_extend:HI (match_dup 1))
1804 ; *addhi3_zero_extend
1806 (plus:HI (zero_extend:HI (match_dup 1))
1809 ;; "umaddqihi4.uconst"
1810 ;; "maddqihi4.sconst"
1811 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1812 [(set (match_operand:HI 0 "register_operand" "=r")
1813 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1814 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1815 (match_operand:HI 3 "register_operand" "0")))
1816 (clobber (match_scratch:QI 4 "=&d"))]
1819 "&& reload_completed"
1822 ; *umaddqihi4 resp. *maddqihi4
1824 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1825 (any_extend:HI (match_dup 4)))
1828 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1831 ;; "*umsubqihi4.uconst"
1832 ;; "*msubqihi4.sconst"
1833 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1834 [(set (match_operand:HI 0 "register_operand" "=r")
1835 (minus:HI (match_operand:HI 3 "register_operand" "0")
1836 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1837 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1838 (clobber (match_scratch:QI 4 "=&d"))]
1841 "&& reload_completed"
1844 ; *umsubqihi4 resp. *msubqihi4
1846 (minus:HI (match_dup 3)
1847 (mult:HI (any_extend:HI (match_dup 1))
1848 (any_extend:HI (match_dup 4)))))]
1850 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1853 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1854 ;; for MULT with power of 2 and skips trying MULT insn above.
1856 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1857 [(set (match_operand:HI 0 "register_operand" "=r")
1858 (minus:HI (match_operand:HI 3 "register_operand" "0")
1859 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1860 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1861 (clobber (match_scratch:QI 4 "=&d"))]
1864 "&& reload_completed"
1869 (minus:HI (match_dup 3)
1870 (mult:HI (zero_extend:HI (match_dup 1))
1871 (zero_extend:HI (match_dup 4)))))]
1873 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1876 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1877 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1878 ;; because this would require an extra pattern for just one value.
1880 (define_insn_and_split "*msubqihi4.sconst.ashift"
1881 [(set (match_operand:HI 0 "register_operand" "=r")
1882 (minus:HI (match_operand:HI 3 "register_operand" "0")
1883 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1884 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1885 (clobber (match_scratch:QI 4 "=&d"))]
1888 "&& reload_completed"
1893 (minus:HI (match_dup 3)
1894 (mult:HI (sign_extend:HI (match_dup 1))
1895 (sign_extend:HI (match_dup 4)))))]
1897 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1900 ;; For signed/unsigned combinations that require narrow constraint "a"
1901 ;; just provide a pattern if signed/unsigned combination is actually needed.
1903 (define_insn_and_split "*sumaddqihi4.uconst"
1904 [(set (match_operand:HI 0 "register_operand" "=r")
1905 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1906 (match_operand:HI 2 "u8_operand" "M"))
1907 (match_operand:HI 3 "register_operand" "0")))
1908 (clobber (match_scratch:QI 4 "=&a"))]
1910 && !s8_operand (operands[2], VOIDmode)"
1912 "&& reload_completed"
1917 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1918 (zero_extend:HI (match_dup 4)))
1921 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1924 (define_insn_and_split "*sumsubqihi4.uconst"
1925 [(set (match_operand:HI 0 "register_operand" "=r")
1926 (minus:HI (match_operand:HI 3 "register_operand" "0")
1927 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1928 (match_operand:HI 2 "u8_operand" "M"))))
1929 (clobber (match_scratch:QI 4 "=&a"))]
1931 && !s8_operand (operands[2], VOIDmode)"
1933 "&& reload_completed"
1938 (minus:HI (match_dup 3)
1939 (mult:HI (sign_extend:HI (match_dup 1))
1940 (zero_extend:HI (match_dup 4)))))]
1942 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1945 ;******************************************************************************
1946 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1947 ;******************************************************************************
1949 ;; "*muluqihi3.uconst"
1950 ;; "*mulsqihi3.sconst"
1951 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1952 [(set (match_operand:HI 0 "register_operand" "=r")
1953 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1954 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1955 (clobber (match_scratch:QI 3 "=&d"))]
1958 "&& reload_completed"
1961 ; umulqihi3 resp. mulqihi3
1963 (mult:HI (any_extend:HI (match_dup 1))
1964 (any_extend:HI (match_dup 3))))]
1966 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1969 (define_insn_and_split "*muluqihi3.sconst"
1970 [(set (match_operand:HI 0 "register_operand" "=r")
1971 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1972 (match_operand:HI 2 "s8_operand" "n")))
1973 (clobber (match_scratch:QI 3 "=&a"))]
1976 "&& reload_completed"
1981 (mult:HI (zero_extend:HI (match_dup 1))
1982 (sign_extend:HI (match_dup 3))))]
1984 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1987 (define_insn_and_split "*mulsqihi3.uconst"
1988 [(set (match_operand:HI 0 "register_operand" "=r")
1989 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1990 (match_operand:HI 2 "u8_operand" "M")))
1991 (clobber (match_scratch:QI 3 "=&a"))]
1994 "&& reload_completed"
1999 (mult:HI (zero_extend:HI (match_dup 3))
2000 (sign_extend:HI (match_dup 1))))]
2002 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2005 (define_insn_and_split "*mulsqihi3.oconst"
2006 [(set (match_operand:HI 0 "register_operand" "=&r")
2007 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2008 (match_operand:HI 2 "o8_operand" "n")))
2009 (clobber (match_scratch:QI 3 "=&a"))]
2012 "&& reload_completed"
2017 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2018 (sign_extend:HI (match_dup 1))))]
2020 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2023 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2024 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2025 ;; at that time. Fix that.
2027 (define_insn "*ashiftqihi2.signx.1"
2028 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2029 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2033 lsl %A0\;sbc %B0,%B0
2034 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2035 [(set_attr "length" "2,3")
2036 (set_attr "cc" "clobber")])
2038 (define_insn_and_split "*ashifthi3.signx.const"
2039 [(set (match_operand:HI 0 "register_operand" "=r")
2040 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2041 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2042 (clobber (match_scratch:QI 3 "=&d"))]
2045 "&& reload_completed"
2050 (mult:HI (sign_extend:HI (match_dup 1))
2051 (sign_extend:HI (match_dup 3))))]
2053 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2056 (define_insn_and_split "*ashifthi3.signx.const7"
2057 [(set (match_operand:HI 0 "register_operand" "=r")
2058 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2060 (clobber (match_scratch:QI 2 "=&a"))]
2063 "&& reload_completed"
2068 (mult:HI (zero_extend:HI (match_dup 2))
2069 (sign_extend:HI (match_dup 1))))]
2071 operands[3] = gen_int_mode (1 << 7, QImode);
2074 (define_insn_and_split "*ashifthi3.zerox.const"
2075 [(set (match_operand:HI 0 "register_operand" "=r")
2076 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2077 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2078 (clobber (match_scratch:QI 3 "=&d"))]
2081 "&& reload_completed"
2086 (mult:HI (zero_extend:HI (match_dup 1))
2087 (zero_extend:HI (match_dup 3))))]
2089 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2092 ;******************************************************************************
2093 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2094 ;******************************************************************************
2096 (define_insn "mulsqihi3"
2097 [(set (match_operand:HI 0 "register_operand" "=&r")
2098 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2099 (match_operand:HI 2 "register_operand" "a")))]
2106 [(set_attr "length" "5")
2107 (set_attr "cc" "clobber")])
2109 (define_insn "muluqihi3"
2110 [(set (match_operand:HI 0 "register_operand" "=&r")
2111 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2112 (match_operand:HI 2 "register_operand" "r")))]
2119 [(set_attr "length" "5")
2120 (set_attr "cc" "clobber")])
2122 ;; one-extend operand 1
2124 (define_insn "muloqihi3"
2125 [(set (match_operand:HI 0 "register_operand" "=&r")
2126 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2127 (match_operand:HI 2 "register_operand" "r")))]
2135 [(set_attr "length" "6")
2136 (set_attr "cc" "clobber")])
2138 ;******************************************************************************
2140 (define_expand "mulhi3"
2141 [(set (match_operand:HI 0 "register_operand" "")
2142 (mult:HI (match_operand:HI 1 "register_operand" "")
2143 (match_operand:HI 2 "register_or_s9_operand" "")))]
2148 if (!register_operand (operands[2], HImode))
2149 operands[2] = force_reg (HImode, operands[2]);
2151 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2155 /* For small constants we can do better by extending them on the fly.
2156 The constant can be loaded in one instruction and the widening
2157 multiplication is shorter. First try the unsigned variant because it
2158 allows constraint "d" instead of "a" for the signed version. */
2160 if (s9_operand (operands[2], HImode))
2162 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2164 if (u8_operand (operands[2], HImode))
2166 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2168 else if (s8_operand (operands[2], HImode))
2170 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2174 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2180 if (!register_operand (operands[2], HImode))
2181 operands[2] = force_reg (HImode, operands[2]);
2184 (define_insn "*mulhi3_enh"
2185 [(set (match_operand:HI 0 "register_operand" "=&r")
2186 (mult:HI (match_operand:HI 1 "register_operand" "r")
2187 (match_operand:HI 2 "register_operand" "r")))]
2190 return REGNO (operands[1]) == REGNO (operands[2])
2191 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2192 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2194 [(set_attr "length" "7")
2195 (set_attr "cc" "clobber")])
2197 (define_expand "mulhi3_call"
2198 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2199 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2200 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2201 (clobber (reg:HI 22))
2202 (clobber (reg:QI 21))])
2203 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
2205 (define_insn "*mulhi3_call"
2206 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2207 (clobber (reg:HI 22))
2208 (clobber (reg:QI 21))]
2211 [(set_attr "type" "xcall")
2212 (set_attr "cc" "clobber")])
2214 ;; To support widening multiplication with constant we postpone
2215 ;; expanding to the implicit library call until post combine and
2216 ;; prior to register allocation. Clobber all hard registers that
2217 ;; might be used by the (widening) multiply until it is split and
2218 ;; it's final register footprint is worked out.
2220 (define_expand "mulsi3"
2221 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2222 (mult:SI (match_operand:SI 1 "register_operand" "")
2223 (match_operand:SI 2 "nonmemory_operand" "")))
2224 (clobber (reg:HI 26))
2225 (clobber (reg:DI 18))])]
2228 if (u16_operand (operands[2], SImode))
2230 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2231 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2235 if (o16_operand (operands[2], SImode))
2237 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2238 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2243 (define_insn_and_split "*mulsi3"
2244 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2245 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2246 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2247 (clobber (reg:HI 26))
2248 (clobber (reg:DI 18))]
2249 "AVR_HAVE_MUL && !reload_completed"
2250 { gcc_unreachable(); }
2256 (parallel [(set (reg:SI 22)
2257 (mult:SI (reg:SI 22)
2259 (clobber (reg:HI 26))])
2263 if (u16_operand (operands[2], SImode))
2265 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2266 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2270 if (o16_operand (operands[2], SImode))
2272 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2273 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2280 (define_insn_and_split "mulu<mode>si3"
2281 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2282 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2283 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2284 (clobber (reg:HI 26))
2285 (clobber (reg:DI 18))]
2286 "AVR_HAVE_MUL && !reload_completed"
2287 { gcc_unreachable(); }
2294 (mult:SI (zero_extend:SI (reg:HI 26))
2299 /* Do the QI -> HI extension explicitely before the multiplication. */
2300 /* Do the HI -> SI extension implicitely and after the multiplication. */
2302 if (QImode == <MODE>mode)
2303 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2305 if (u16_operand (operands[2], SImode))
2307 operands[1] = force_reg (HImode, operands[1]);
2308 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2309 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2316 (define_insn_and_split "muls<mode>si3"
2317 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2318 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2319 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2320 (clobber (reg:HI 26))
2321 (clobber (reg:DI 18))]
2322 "AVR_HAVE_MUL && !reload_completed"
2323 { gcc_unreachable(); }
2330 (mult:SI (sign_extend:SI (reg:HI 26))
2335 /* Do the QI -> HI extension explicitely before the multiplication. */
2336 /* Do the HI -> SI extension implicitely and after the multiplication. */
2338 if (QImode == <MODE>mode)
2339 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2341 if (u16_operand (operands[2], SImode)
2342 || s16_operand (operands[2], SImode))
2344 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2346 operands[1] = force_reg (HImode, operands[1]);
2348 if (u16_operand (operands[2], SImode))
2349 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2351 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2357 ;; One-extend operand 1
2359 (define_insn_and_split "mulohisi3"
2360 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2361 (mult:SI (not:SI (zero_extend:SI
2362 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2363 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2364 (clobber (reg:HI 26))
2365 (clobber (reg:DI 18))]
2366 "AVR_HAVE_MUL && !reload_completed"
2367 { gcc_unreachable(); }
2374 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2381 (define_expand "<extend_u>mulhisi3"
2382 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2383 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2384 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2385 (clobber (reg:HI 26))
2386 (clobber (reg:DI 18))])]
2389 (define_expand "usmulhisi3"
2390 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2391 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2392 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2393 (clobber (reg:HI 26))
2394 (clobber (reg:DI 18))])]
2397 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2398 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2399 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2400 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2401 (define_insn_and_split
2402 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2403 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2404 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2405 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2406 (clobber (reg:HI 26))
2407 (clobber (reg:DI 18))]
2408 "AVR_HAVE_MUL && !reload_completed"
2409 { gcc_unreachable(); }
2416 (mult:SI (match_dup 3)
2421 rtx xop1 = operands[1];
2422 rtx xop2 = operands[2];
2424 /* Do the QI -> HI extension explicitely before the multiplication. */
2425 /* Do the HI -> SI extension implicitely and after the multiplication. */
2427 if (QImode == <QIHI:MODE>mode)
2428 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2430 if (QImode == <QIHI2:MODE>mode)
2431 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2433 if (<any_extend:CODE> == <any_extend2:CODE>
2434 || <any_extend:CODE> == ZERO_EXTEND)
2438 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2439 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2443 /* <any_extend:CODE> = SIGN_EXTEND */
2444 /* <any_extend2:CODE> = ZERO_EXTEND */
2448 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2449 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2453 ;; "smulhi3_highpart"
2454 ;; "umulhi3_highpart"
2455 (define_expand "<extend_su>mulhi3_highpart"
2457 (match_operand:HI 1 "nonmemory_operand" ""))
2459 (match_operand:HI 2 "nonmemory_operand" ""))
2460 (parallel [(set (reg:HI 24)
2461 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2462 (any_extend:SI (reg:HI 26)))
2464 (clobber (reg:HI 22))])
2465 (set (match_operand:HI 0 "register_operand" "")
2470 (define_insn "*mulsi3_call"
2472 (mult:SI (reg:SI 22)
2474 (clobber (reg:HI 26))]
2477 [(set_attr "type" "xcall")
2478 (set_attr "cc" "clobber")])
2481 ;; "*umulhisi3_call"
2482 (define_insn "*<extend_u>mulhisi3_call"
2484 (mult:SI (any_extend:SI (reg:HI 18))
2485 (any_extend:SI (reg:HI 26))))]
2487 "%~call __<extend_u>mulhisi3"
2488 [(set_attr "type" "xcall")
2489 (set_attr "cc" "clobber")])
2491 ;; "*umulhi3_highpart_call"
2492 ;; "*smulhi3_highpart_call"
2493 (define_insn "*<extend_su>mulhi3_highpart_call"
2495 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2496 (any_extend:SI (reg:HI 26)))
2498 (clobber (reg:HI 22))]
2500 "%~call __<extend_u>mulhisi3"
2501 [(set_attr "type" "xcall")
2502 (set_attr "cc" "clobber")])
2504 (define_insn "*usmulhisi3_call"
2506 (mult:SI (zero_extend:SI (reg:HI 18))
2507 (sign_extend:SI (reg:HI 26))))]
2509 "%~call __usmulhisi3"
2510 [(set_attr "type" "xcall")
2511 (set_attr "cc" "clobber")])
2513 (define_insn "*mul<extend_su>hisi3_call"
2515 (mult:SI (any_extend:SI (reg:HI 26))
2518 "%~call __mul<extend_su>hisi3"
2519 [(set_attr "type" "xcall")
2520 (set_attr "cc" "clobber")])
2522 (define_insn "*mulohisi3_call"
2524 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2527 "%~call __mulohisi3"
2528 [(set_attr "type" "xcall")
2529 (set_attr "cc" "clobber")])
2531 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2534 ;; Generate lib1funcs.S calls ourselves, because:
2535 ;; - we know exactly which registers are clobbered (for QI and HI
2536 ;; modes, some of the call-used registers are preserved)
2537 ;; - we get both the quotient and the remainder at no extra cost
2538 ;; - we split the patterns only after the first CSE passes because
2539 ;; CSE has problems to operate on hard regs.
2541 (define_insn_and_split "divmodqi4"
2542 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2543 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2544 (match_operand:QI 2 "pseudo_register_operand" "")))
2545 (set (match_operand:QI 3 "pseudo_register_operand" "")
2546 (mod:QI (match_dup 1) (match_dup 2)))
2547 (clobber (reg:QI 22))
2548 (clobber (reg:QI 23))
2549 (clobber (reg:QI 24))
2550 (clobber (reg:QI 25))])]
2552 "this divmodqi4 pattern should have been splitted;"
2554 [(set (reg:QI 24) (match_dup 1))
2555 (set (reg:QI 22) (match_dup 2))
2556 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2557 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2558 (clobber (reg:QI 22))
2559 (clobber (reg:QI 23))])
2560 (set (match_dup 0) (reg:QI 24))
2561 (set (match_dup 3) (reg:QI 25))])
2563 (define_insn "*divmodqi4_call"
2564 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2565 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2566 (clobber (reg:QI 22))
2567 (clobber (reg:QI 23))]
2569 "%~call __divmodqi4"
2570 [(set_attr "type" "xcall")
2571 (set_attr "cc" "clobber")])
2573 (define_insn_and_split "udivmodqi4"
2574 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2575 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2576 (match_operand:QI 2 "pseudo_register_operand" "")))
2577 (set (match_operand:QI 3 "pseudo_register_operand" "")
2578 (umod:QI (match_dup 1) (match_dup 2)))
2579 (clobber (reg:QI 22))
2580 (clobber (reg:QI 23))
2581 (clobber (reg:QI 24))
2582 (clobber (reg:QI 25))])]
2584 "this udivmodqi4 pattern should have been splitted;"
2586 [(set (reg:QI 24) (match_dup 1))
2587 (set (reg:QI 22) (match_dup 2))
2588 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2589 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2590 (clobber (reg:QI 23))])
2591 (set (match_dup 0) (reg:QI 24))
2592 (set (match_dup 3) (reg:QI 25))])
2594 (define_insn "*udivmodqi4_call"
2595 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2596 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2597 (clobber (reg:QI 23))]
2599 "%~call __udivmodqi4"
2600 [(set_attr "type" "xcall")
2601 (set_attr "cc" "clobber")])
2603 (define_insn_and_split "divmodhi4"
2604 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2605 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2606 (match_operand:HI 2 "pseudo_register_operand" "")))
2607 (set (match_operand:HI 3 "pseudo_register_operand" "")
2608 (mod:HI (match_dup 1) (match_dup 2)))
2609 (clobber (reg:QI 21))
2610 (clobber (reg:HI 22))
2611 (clobber (reg:HI 24))
2612 (clobber (reg:HI 26))])]
2614 "this should have been splitted;"
2616 [(set (reg:HI 24) (match_dup 1))
2617 (set (reg:HI 22) (match_dup 2))
2618 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2619 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2620 (clobber (reg:HI 26))
2621 (clobber (reg:QI 21))])
2622 (set (match_dup 0) (reg:HI 22))
2623 (set (match_dup 3) (reg:HI 24))])
2625 (define_insn "*divmodhi4_call"
2626 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2627 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2628 (clobber (reg:HI 26))
2629 (clobber (reg:QI 21))]
2631 "%~call __divmodhi4"
2632 [(set_attr "type" "xcall")
2633 (set_attr "cc" "clobber")])
2635 (define_insn_and_split "udivmodhi4"
2636 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2637 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2638 (match_operand:HI 2 "pseudo_register_operand" "")))
2639 (set (match_operand:HI 3 "pseudo_register_operand" "")
2640 (umod:HI (match_dup 1) (match_dup 2)))
2641 (clobber (reg:QI 21))
2642 (clobber (reg:HI 22))
2643 (clobber (reg:HI 24))
2644 (clobber (reg:HI 26))])]
2646 "this udivmodhi4 pattern should have been splitted.;"
2648 [(set (reg:HI 24) (match_dup 1))
2649 (set (reg:HI 22) (match_dup 2))
2650 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2651 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2652 (clobber (reg:HI 26))
2653 (clobber (reg:QI 21))])
2654 (set (match_dup 0) (reg:HI 22))
2655 (set (match_dup 3) (reg:HI 24))])
2657 (define_insn "*udivmodhi4_call"
2658 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2659 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2660 (clobber (reg:HI 26))
2661 (clobber (reg:QI 21))]
2663 "%~call __udivmodhi4"
2664 [(set_attr "type" "xcall")
2665 (set_attr "cc" "clobber")])
2667 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2670 ;; To support widening multiplication with constant we postpone
2671 ;; expanding to the implicit library call until post combine and
2672 ;; prior to register allocation. Clobber all hard registers that
2673 ;; might be used by the (widening) multiply until it is split and
2674 ;; it's final register footprint is worked out.
2676 (define_expand "mulpsi3"
2677 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2678 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2679 (match_operand:PSI 2 "nonmemory_operand" "")))
2680 (clobber (reg:HI 26))
2681 (clobber (reg:DI 18))])]
2684 if (s8_operand (operands[2], PSImode))
2686 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2687 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2692 (define_insn "*umulqihipsi3"
2693 [(set (match_operand:PSI 0 "register_operand" "=&r")
2694 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2695 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2704 [(set_attr "length" "7")
2705 (set_attr "cc" "clobber")])
2707 (define_insn "*umulhiqipsi3"
2708 [(set (match_operand:PSI 0 "register_operand" "=&r")
2709 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2710 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2718 adc %C0,__zero_reg__"
2719 [(set_attr "length" "7")
2720 (set_attr "cc" "clobber")])
2722 (define_insn_and_split "mulsqipsi3"
2723 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2724 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2725 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2726 (clobber (reg:HI 26))
2727 (clobber (reg:DI 18))]
2728 "AVR_HAVE_MUL && !reload_completed"
2729 { gcc_unreachable(); }
2736 (mult:PSI (sign_extend:PSI (reg:QI 25))
2741 (define_insn_and_split "*mulpsi3"
2742 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2743 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2744 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2745 (clobber (reg:HI 26))
2746 (clobber (reg:DI 18))]
2747 "AVR_HAVE_MUL && !reload_completed"
2748 { gcc_unreachable(); }
2754 (parallel [(set (reg:PSI 22)
2755 (mult:PSI (reg:PSI 22)
2757 (clobber (reg:QI 21))
2758 (clobber (reg:QI 25))
2759 (clobber (reg:HI 26))])
2763 if (s8_operand (operands[2], PSImode))
2765 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2766 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2771 (define_insn "*mulsqipsi3.libgcc"
2773 (mult:PSI (sign_extend:PSI (reg:QI 25))
2776 "%~call __mulsqipsi3"
2777 [(set_attr "type" "xcall")
2778 (set_attr "cc" "clobber")])
2780 (define_insn "*mulpsi3.libgcc"
2782 (mult:PSI (reg:PSI 22)
2784 (clobber (reg:QI 21))
2785 (clobber (reg:QI 25))
2786 (clobber (reg:HI 26))]
2789 [(set_attr "type" "xcall")
2790 (set_attr "cc" "clobber")])
2793 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2794 ;; 24-bit signed/unsigned division and modulo.
2795 ;; Notice that the libgcc implementation return the quotient in R22
2796 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2797 ;; implementation works the other way round.
2799 (define_insn_and_split "divmodpsi4"
2800 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2801 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2802 (match_operand:PSI 2 "pseudo_register_operand" "")))
2803 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2804 (mod:PSI (match_dup 1)
2806 (clobber (reg:DI 18))
2807 (clobber (reg:QI 26))])]
2809 { gcc_unreachable(); }
2811 [(set (reg:PSI 22) (match_dup 1))
2812 (set (reg:PSI 18) (match_dup 2))
2813 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2814 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2815 (clobber (reg:QI 21))
2816 (clobber (reg:QI 25))
2817 (clobber (reg:QI 26))])
2818 (set (match_dup 0) (reg:PSI 22))
2819 (set (match_dup 3) (reg:PSI 18))])
2821 (define_insn "*divmodpsi4_call"
2822 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2823 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2824 (clobber (reg:QI 21))
2825 (clobber (reg:QI 25))
2826 (clobber (reg:QI 26))]
2828 "%~call __divmodpsi4"
2829 [(set_attr "type" "xcall")
2830 (set_attr "cc" "clobber")])
2832 (define_insn_and_split "udivmodpsi4"
2833 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2834 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2835 (match_operand:PSI 2 "pseudo_register_operand" "")))
2836 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2837 (umod:PSI (match_dup 1)
2839 (clobber (reg:DI 18))
2840 (clobber (reg:QI 26))])]
2842 { gcc_unreachable(); }
2844 [(set (reg:PSI 22) (match_dup 1))
2845 (set (reg:PSI 18) (match_dup 2))
2846 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2847 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2848 (clobber (reg:QI 21))
2849 (clobber (reg:QI 25))
2850 (clobber (reg:QI 26))])
2851 (set (match_dup 0) (reg:PSI 22))
2852 (set (match_dup 3) (reg:PSI 18))])
2854 (define_insn "*udivmodpsi4_call"
2855 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2856 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2857 (clobber (reg:QI 21))
2858 (clobber (reg:QI 25))
2859 (clobber (reg:QI 26))]
2861 "%~call __udivmodpsi4"
2862 [(set_attr "type" "xcall")
2863 (set_attr "cc" "clobber")])
2865 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2867 (define_insn_and_split "divmodsi4"
2868 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2869 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2870 (match_operand:SI 2 "pseudo_register_operand" "")))
2871 (set (match_operand:SI 3 "pseudo_register_operand" "")
2872 (mod:SI (match_dup 1) (match_dup 2)))
2873 (clobber (reg:SI 18))
2874 (clobber (reg:SI 22))
2875 (clobber (reg:HI 26))
2876 (clobber (reg:HI 30))])]
2878 "this divmodsi4 pattern should have been splitted;"
2880 [(set (reg:SI 22) (match_dup 1))
2881 (set (reg:SI 18) (match_dup 2))
2882 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2883 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2884 (clobber (reg:HI 26))
2885 (clobber (reg:HI 30))])
2886 (set (match_dup 0) (reg:SI 18))
2887 (set (match_dup 3) (reg:SI 22))])
2889 (define_insn "*divmodsi4_call"
2890 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2891 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2892 (clobber (reg:HI 26))
2893 (clobber (reg:HI 30))]
2895 "%~call __divmodsi4"
2896 [(set_attr "type" "xcall")
2897 (set_attr "cc" "clobber")])
2899 (define_insn_and_split "udivmodsi4"
2900 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2901 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2902 (match_operand:SI 2 "pseudo_register_operand" "")))
2903 (set (match_operand:SI 3 "pseudo_register_operand" "")
2904 (umod:SI (match_dup 1) (match_dup 2)))
2905 (clobber (reg:SI 18))
2906 (clobber (reg:SI 22))
2907 (clobber (reg:HI 26))
2908 (clobber (reg:HI 30))])]
2910 "this udivmodsi4 pattern should have been splitted;"
2912 [(set (reg:SI 22) (match_dup 1))
2913 (set (reg:SI 18) (match_dup 2))
2914 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2915 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2916 (clobber (reg:HI 26))
2917 (clobber (reg:HI 30))])
2918 (set (match_dup 0) (reg:SI 18))
2919 (set (match_dup 3) (reg:SI 22))])
2921 (define_insn "*udivmodsi4_call"
2922 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2923 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2924 (clobber (reg:HI 26))
2925 (clobber (reg:HI 30))]
2927 "%~call __udivmodsi4"
2928 [(set_attr "type" "xcall")
2929 (set_attr "cc" "clobber")])
2931 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2934 (define_insn "andqi3"
2935 [(set (match_operand:QI 0 "register_operand" "=??r,d")
2936 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2937 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2942 [(set_attr "length" "1,1")
2943 (set_attr "cc" "set_zn,set_zn")])
2945 (define_insn "andhi3"
2946 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
2947 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2948 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2949 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2952 if (which_alternative == 0)
2953 return "and %A0,%A2\;and %B0,%B2";
2954 else if (which_alternative == 1)
2955 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2957 return avr_out_bitop (insn, operands, NULL);
2959 [(set_attr "length" "2,2,2,4,4")
2960 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2961 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2963 (define_insn "andpsi3"
2964 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
2965 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2966 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2967 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2970 if (which_alternative == 0)
2971 return "and %A0,%A2" CR_TAB
2972 "and %B0,%B2" CR_TAB
2975 return avr_out_bitop (insn, operands, NULL);
2977 [(set_attr "length" "3,3,6,6")
2978 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2979 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2981 (define_insn "andsi3"
2982 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
2983 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2984 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2985 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2988 if (which_alternative == 0)
2989 return "and %0,%2" CR_TAB
2990 "and %B0,%B2" CR_TAB
2991 "and %C0,%C2" CR_TAB
2994 return avr_out_bitop (insn, operands, NULL);
2996 [(set_attr "length" "4,4,8,8")
2997 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2998 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3000 (define_peephole2 ; andi
3001 [(set (match_operand:QI 0 "d_register_operand" "")
3002 (and:QI (match_dup 0)
3003 (match_operand:QI 1 "const_int_operand" "")))
3005 (and:QI (match_dup 0)
3006 (match_operand:QI 2 "const_int_operand" "")))]
3008 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3010 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3013 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3016 (define_insn "iorqi3"
3017 [(set (match_operand:QI 0 "register_operand" "=??r,d")
3018 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3019 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3024 [(set_attr "length" "1,1")
3025 (set_attr "cc" "set_zn,set_zn")])
3027 (define_insn "iorhi3"
3028 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3029 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3030 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3031 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3034 if (which_alternative == 0)
3035 return "or %A0,%A2\;or %B0,%B2";
3036 else if (which_alternative == 1)
3037 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3039 return avr_out_bitop (insn, operands, NULL);
3041 [(set_attr "length" "2,2,2,4,4")
3042 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3043 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3045 (define_insn "iorpsi3"
3046 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3047 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3048 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3049 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3052 if (which_alternative == 0)
3053 return "or %A0,%A2" CR_TAB
3057 return avr_out_bitop (insn, operands, NULL);
3059 [(set_attr "length" "3,3,6,6")
3060 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3061 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3063 (define_insn "iorsi3"
3064 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3065 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3066 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3067 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3070 if (which_alternative == 0)
3071 return "or %0,%2" CR_TAB
3076 return avr_out_bitop (insn, operands, NULL);
3078 [(set_attr "length" "4,4,8,8")
3079 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3080 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3082 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3085 (define_insn "xorqi3"
3086 [(set (match_operand:QI 0 "register_operand" "=r")
3087 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3088 (match_operand:QI 2 "register_operand" "r")))]
3091 [(set_attr "length" "1")
3092 (set_attr "cc" "set_zn")])
3094 (define_insn "xorhi3"
3095 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
3096 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3097 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3098 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3101 if (which_alternative == 0)
3102 return "eor %A0,%A2\;eor %B0,%B2";
3104 return avr_out_bitop (insn, operands, NULL);
3106 [(set_attr "length" "2,2,4")
3107 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3108 (set_attr "cc" "set_n,clobber,clobber")])
3110 (define_insn "xorpsi3"
3111 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
3112 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3113 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3114 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3117 if (which_alternative == 0)
3118 return "eor %A0,%A2" CR_TAB
3119 "eor %B0,%B2" CR_TAB
3122 return avr_out_bitop (insn, operands, NULL);
3124 [(set_attr "length" "3,6,6")
3125 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3126 (set_attr "cc" "set_n,clobber,clobber")])
3128 (define_insn "xorsi3"
3129 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
3130 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3131 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3132 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3135 if (which_alternative == 0)
3136 return "eor %0,%2" CR_TAB
3137 "eor %B0,%B2" CR_TAB
3138 "eor %C0,%C2" CR_TAB
3141 return avr_out_bitop (insn, operands, NULL);
3143 [(set_attr "length" "4,8,8")
3144 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3145 (set_attr "cc" "set_n,clobber,clobber")])
3147 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3150 (define_expand "rotlqi3"
3151 [(set (match_operand:QI 0 "register_operand" "")
3152 (rotate:QI (match_operand:QI 1 "register_operand" "")
3153 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3156 if (!CONST_INT_P (operands[2]))
3159 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3162 ;; Expander used by __builtin_avr_swap
3163 (define_expand "rotlqi3_4"
3164 [(set (match_operand:QI 0 "register_operand" "")
3165 (rotate:QI (match_operand:QI 1 "register_operand" "")
3168 (define_insn "*rotlqi3"
3169 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3170 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3171 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3174 lsl %0\;adc %0,__zero_reg__
3175 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3176 swap %0\;bst %0,0\;ror %0\;bld %0,7
3178 swap %0\;lsl %0\;adc %0,__zero_reg__
3179 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3180 bst %0,0\;ror %0\;bld %0,7
3182 [(set_attr "length" "2,4,4,1,3,5,3,0")
3183 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3185 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3186 ;; a whole number of bytes. The split creates the appropriate moves and
3187 ;; considers all overlap situations.
3189 ;; HImode does not need scratch. Use attribute for this constraint.
3191 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3192 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3197 (define_expand "rotl<mode>3"
3198 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3199 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3200 (match_operand:VOID 2 "const_int_operand" "")))
3201 (clobber (match_dup 3))])]
3206 if (!CONST_INT_P (operands[2]))
3209 offset = INTVAL (operands[2]);
3211 if (0 == offset % 8)
3213 if (AVR_HAVE_MOVW && 0 == offset % 16)
3214 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3216 operands[3] = gen_rtx_SCRATCH (QImode);
3218 else if (offset == 1
3219 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3221 /*; Support rotate left/right by 1 */
3223 emit_move_insn (operands[0],
3224 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3231 (define_insn "*rotlhi2.1"
3232 [(set (match_operand:HI 0 "register_operand" "=r")
3233 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3236 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3237 [(set_attr "length" "3")
3238 (set_attr "cc" "clobber")])
3240 (define_insn "*rotlhi2.15"
3241 [(set (match_operand:HI 0 "register_operand" "=r")
3242 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3245 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3246 [(set_attr "length" "4")
3247 (set_attr "cc" "clobber")])
3249 (define_insn "*rotlpsi2.1"
3250 [(set (match_operand:PSI 0 "register_operand" "=r")
3251 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3254 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3255 [(set_attr "length" "4")
3256 (set_attr "cc" "clobber")])
3258 (define_insn "*rotlpsi2.23"
3259 [(set (match_operand:PSI 0 "register_operand" "=r")
3260 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3263 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3264 [(set_attr "length" "5")
3265 (set_attr "cc" "clobber")])
3267 (define_insn "*rotlsi2.1"
3268 [(set (match_operand:SI 0 "register_operand" "=r")
3269 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3272 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3273 [(set_attr "length" "5")
3274 (set_attr "cc" "clobber")])
3276 (define_insn "*rotlsi2.31"
3277 [(set (match_operand:SI 0 "register_operand" "=r")
3278 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3281 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3282 [(set_attr "length" "6")
3283 (set_attr "cc" "clobber")])
3285 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3286 ;; The best we can do is use early clobber alternative "#&r" so that
3287 ;; completely non-overlapping operands dont get a scratch but # so register
3288 ;; allocation does not prefer non-overlapping.
3291 ;; Split word aligned rotates using scratch that is mode dependent.
3295 (define_insn_and_split "*rotw<mode>"
3296 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3297 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3298 (match_operand 2 "const_int_operand" "n,n,n")))
3299 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3301 && CONST_INT_P (operands[2])
3302 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3303 && 0 == INTVAL (operands[2]) % 16"
3305 "&& reload_completed"
3308 avr_rotate_bytes (operands);
3313 ;; Split byte aligned rotates using scratch that is always QI mode.
3318 (define_insn_and_split "*rotb<mode>"
3319 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3320 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3321 (match_operand 2 "const_int_operand" "n,n,n")))
3322 (clobber (match_scratch:QI 3 "=<rotx>"))]
3323 "CONST_INT_P (operands[2])
3324 && (8 == INTVAL (operands[2]) % 16
3326 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3327 && 0 == INTVAL (operands[2]) % 16))"
3329 "&& reload_completed"
3332 avr_rotate_bytes (operands);
3337 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3338 ;; arithmetic shift left
3341 ;; "ashlqq3" "ashluqq3"
3342 (define_expand "ashl<mode>3"
3343 [(set (match_operand:ALL1 0 "register_operand" "")
3344 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3345 (match_operand:QI 2 "nop_general_operand" "")))])
3347 (define_split ; ashlqi3_const4
3348 [(set (match_operand:ALL1 0 "d_register_operand" "")
3349 (ashift:ALL1 (match_dup 0)
3353 (rotate:QI (match_dup 1)
3356 (and:QI (match_dup 1)
3359 operands[1] = avr_to_int_mode (operands[0]);
3362 (define_split ; ashlqi3_const5
3363 [(set (match_operand:ALL1 0 "d_register_operand" "")
3364 (ashift:ALL1 (match_dup 0)
3367 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3368 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3369 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3371 operands[1] = avr_to_int_mode (operands[0]);
3374 (define_split ; ashlqi3_const6
3375 [(set (match_operand:ALL1 0 "d_register_operand" "")
3376 (ashift:ALL1 (match_dup 0)
3379 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3380 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3381 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3383 operands[1] = avr_to_int_mode (operands[0]);
3387 ;; "*ashlqq3" "*ashluqq3"
3388 (define_insn "*ashl<mode>3"
3389 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3390 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3391 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3394 return ashlqi3_out (insn, operands, NULL);
3396 [(set_attr "length" "5,0,1,2,4,6,9")
3397 (set_attr "adjust_len" "ashlqi")
3398 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3400 (define_insn "ashl<mode>3"
3401 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3402 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3403 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3406 return ashlhi3_out (insn, operands, NULL);
3408 [(set_attr "length" "6,0,2,2,4,10,10")
3409 (set_attr "adjust_len" "ashlhi")
3410 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3413 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3414 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3418 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3419 [(set (match_operand:QI 0 "register_operand" "=r")
3420 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3421 (match_operand:QI 2 "register_operand" "r"))
3427 (ashift:QI (match_dup 1)
3430 ;; ??? Combiner does not recognize that it could split the following insn;
3431 ;; presumably because he has no register handy?
3433 ;; "*ashluqihiqi3.mem"
3434 ;; "*ashlsqihiqi3.mem"
3435 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3436 [(set (match_operand:QI 0 "memory_operand" "=m")
3437 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3438 (match_operand:QI 2 "register_operand" "r"))
3441 { gcc_unreachable(); }
3444 (ashift:QI (match_dup 1)
3449 operands[3] = gen_reg_rtx (QImode);
3454 (define_insn_and_split "*ashlhiqi3"
3455 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3456 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3457 (match_operand:QI 2 "register_operand" "r")) 0))]
3459 { gcc_unreachable(); }
3462 (ashift:QI (match_dup 3)
3467 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3468 operands[4] = gen_reg_rtx (QImode);
3471 ;; High part of 16-bit shift is unused after the instruction:
3472 ;; No need to compute it, map to 8-bit shift.
3475 [(set (match_operand:HI 0 "register_operand" "")
3476 (ashift:HI (match_dup 0)
3477 (match_operand:QI 1 "register_operand" "")))]
3480 (ashift:QI (match_dup 2)
3482 (clobber (match_dup 3))]
3484 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3486 if (!peep2_reg_dead_p (1, operands[3]))
3489 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3494 ;; "ashlsq3" "ashlusq3"
3495 ;; "ashlsa3" "ashlusa3"
3496 (define_insn "ashl<mode>3"
3497 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3498 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3499 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3502 return ashlsi3_out (insn, operands, NULL);
3504 [(set_attr "length" "8,0,4,4,8,10,12")
3505 (set_attr "adjust_len" "ashlsi")
3506 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3508 ;; Optimize if a scratch register from LD_REGS happens to be available.
3510 (define_peephole2 ; ashlqi3_l_const4
3511 [(set (match_operand:ALL1 0 "l_register_operand" "")
3512 (ashift:ALL1 (match_dup 0)
3514 (match_scratch:QI 1 "d")]
3516 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3517 (set (match_dup 1) (const_int -16))
3518 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3520 operands[2] = avr_to_int_mode (operands[0]);
3523 (define_peephole2 ; ashlqi3_l_const5
3524 [(set (match_operand:ALL1 0 "l_register_operand" "")
3525 (ashift:ALL1 (match_dup 0)
3527 (match_scratch:QI 1 "d")]
3529 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3530 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3531 (set (match_dup 1) (const_int -32))
3532 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3534 operands[2] = avr_to_int_mode (operands[0]);
3537 (define_peephole2 ; ashlqi3_l_const6
3538 [(set (match_operand:ALL1 0 "l_register_operand" "")
3539 (ashift:ALL1 (match_dup 0)
3541 (match_scratch:QI 1 "d")]
3543 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3544 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3545 (set (match_dup 1) (const_int -64))
3546 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3548 operands[2] = avr_to_int_mode (operands[0]);
3552 [(match_scratch:QI 3 "d")
3553 (set (match_operand:ALL2 0 "register_operand" "")
3554 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3555 (match_operand:QI 2 "const_int_operand" "")))]
3557 [(parallel [(set (match_dup 0)
3558 (ashift:ALL2 (match_dup 1)
3560 (clobber (match_dup 3))])])
3563 ;; "*ashlhq3_const" "*ashluhq3_const"
3564 ;; "*ashlha3_const" "*ashluha3_const"
3565 (define_insn "*ashl<mode>3_const"
3566 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3567 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3568 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3569 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3572 return ashlhi3_out (insn, operands, NULL);
3574 [(set_attr "length" "0,2,2,4,10")
3575 (set_attr "adjust_len" "ashlhi")
3576 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3579 [(match_scratch:QI 3 "d")
3580 (set (match_operand:ALL4 0 "register_operand" "")
3581 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3582 (match_operand:QI 2 "const_int_operand" "")))]
3584 [(parallel [(set (match_dup 0)
3585 (ashift:ALL4 (match_dup 1)
3587 (clobber (match_dup 3))])])
3590 ;; "*ashlsq3_const" "*ashlusq3_const"
3591 ;; "*ashlsa3_const" "*ashlusa3_const"
3592 (define_insn "*ashl<mode>3_const"
3593 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3594 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3595 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3596 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3599 return ashlsi3_out (insn, operands, NULL);
3601 [(set_attr "length" "0,4,4,10")
3602 (set_attr "adjust_len" "ashlsi")
3603 (set_attr "cc" "none,set_n,clobber,clobber")])
3605 (define_expand "ashlpsi3"
3606 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3607 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3608 (match_operand:QI 2 "nonmemory_operand" "")))
3609 (clobber (scratch:QI))])]
3613 && CONST_INT_P (operands[2]))
3615 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3617 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3618 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3621 else if (optimize_insn_for_speed_p ()
3622 && INTVAL (operands[2]) != 16
3623 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3625 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3626 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3632 (define_insn "*ashlpsi3"
3633 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3634 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3635 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3636 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3639 return avr_out_ashlpsi3 (insn, operands, NULL);
3641 [(set_attr "adjust_len" "ashlpsi")
3642 (set_attr "cc" "clobber")])
3644 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3645 ;; arithmetic shift right
3648 ;; "ashrqq3" "ashruqq3"
3649 (define_insn "ashr<mode>3"
3650 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3651 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3652 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3655 return ashrqi3_out (insn, operands, NULL);
3657 [(set_attr "length" "5,0,1,2,5,4,9")
3658 (set_attr "adjust_len" "ashrqi")
3659 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3662 ;; "ashrhq3" "ashruhq3"
3663 ;; "ashrha3" "ashruha3"
3664 (define_insn "ashr<mode>3"
3665 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3666 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3667 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3670 return ashrhi3_out (insn, operands, NULL);
3672 [(set_attr "length" "6,0,2,4,4,10,10")
3673 (set_attr "adjust_len" "ashrhi")
3674 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3676 (define_insn "ashrpsi3"
3677 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3678 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3679 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3680 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3683 return avr_out_ashrpsi3 (insn, operands, NULL);
3685 [(set_attr "adjust_len" "ashrpsi")
3686 (set_attr "cc" "clobber")])
3689 ;; "ashrsq3" "ashrusq3"
3690 ;; "ashrsa3" "ashrusa3"
3691 (define_insn "ashr<mode>3"
3692 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3693 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3694 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3697 return ashrsi3_out (insn, operands, NULL);
3699 [(set_attr "length" "8,0,4,6,8,10,12")
3700 (set_attr "adjust_len" "ashrsi")
3701 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3703 ;; Optimize if a scratch register from LD_REGS happens to be available.
3706 [(match_scratch:QI 3 "d")
3707 (set (match_operand:ALL2 0 "register_operand" "")
3708 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3709 (match_operand:QI 2 "const_int_operand" "")))]
3711 [(parallel [(set (match_dup 0)
3712 (ashiftrt:ALL2 (match_dup 1)
3714 (clobber (match_dup 3))])])
3717 ;; "*ashrhq3_const" "*ashruhq3_const"
3718 ;; "*ashrha3_const" "*ashruha3_const"
3719 (define_insn "*ashr<mode>3_const"
3720 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3721 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3722 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3723 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3726 return ashrhi3_out (insn, operands, NULL);
3728 [(set_attr "length" "0,2,4,4,10")
3729 (set_attr "adjust_len" "ashrhi")
3730 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3733 [(match_scratch:QI 3 "d")
3734 (set (match_operand:ALL4 0 "register_operand" "")
3735 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3736 (match_operand:QI 2 "const_int_operand" "")))]
3738 [(parallel [(set (match_dup 0)
3739 (ashiftrt:ALL4 (match_dup 1)
3741 (clobber (match_dup 3))])])
3744 ;; "*ashrsq3_const" "*ashrusq3_const"
3745 ;; "*ashrsa3_const" "*ashrusa3_const"
3746 (define_insn "*ashr<mode>3_const"
3747 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3748 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3749 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3750 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3753 return ashrsi3_out (insn, operands, NULL);
3755 [(set_attr "length" "0,4,4,10")
3756 (set_attr "adjust_len" "ashrsi")
3757 (set_attr "cc" "none,clobber,set_n,clobber")])
3759 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3760 ;; logical shift right
3763 ;; "lshrqq3 "lshruqq3"
3764 (define_expand "lshr<mode>3"
3765 [(set (match_operand:ALL1 0 "register_operand" "")
3766 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3767 (match_operand:QI 2 "nop_general_operand" "")))])
3769 (define_split ; lshrqi3_const4
3770 [(set (match_operand:ALL1 0 "d_register_operand" "")
3771 (lshiftrt:ALL1 (match_dup 0)
3775 (rotate:QI (match_dup 1)
3778 (and:QI (match_dup 1)
3781 operands[1] = avr_to_int_mode (operands[0]);
3784 (define_split ; lshrqi3_const5
3785 [(set (match_operand:ALL1 0 "d_register_operand" "")
3786 (lshiftrt:ALL1 (match_dup 0)
3789 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3790 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3791 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3793 operands[1] = avr_to_int_mode (operands[0]);
3796 (define_split ; lshrqi3_const6
3797 [(set (match_operand:QI 0 "d_register_operand" "")
3798 (lshiftrt:QI (match_dup 0)
3801 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3802 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3803 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3805 operands[1] = avr_to_int_mode (operands[0]);
3811 (define_insn "*lshr<mode>3"
3812 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3813 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3814 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3817 return lshrqi3_out (insn, operands, NULL);
3819 [(set_attr "length" "5,0,1,2,4,6,9")
3820 (set_attr "adjust_len" "lshrqi")
3821 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3824 ;; "lshrhq3" "lshruhq3"
3825 ;; "lshrha3" "lshruha3"
3826 (define_insn "lshr<mode>3"
3827 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3828 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3829 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3832 return lshrhi3_out (insn, operands, NULL);
3834 [(set_attr "length" "6,0,2,2,4,10,10")
3835 (set_attr "adjust_len" "lshrhi")
3836 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3838 (define_insn "lshrpsi3"
3839 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3840 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3841 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3842 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3845 return avr_out_lshrpsi3 (insn, operands, NULL);
3847 [(set_attr "adjust_len" "lshrpsi")
3848 (set_attr "cc" "clobber")])
3851 ;; "lshrsq3" "lshrusq3"
3852 ;; "lshrsa3" "lshrusa3"
3853 (define_insn "lshr<mode>3"
3854 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3855 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3856 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3859 return lshrsi3_out (insn, operands, NULL);
3861 [(set_attr "length" "8,0,4,4,8,10,12")
3862 (set_attr "adjust_len" "lshrsi")
3863 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3865 ;; Optimize if a scratch register from LD_REGS happens to be available.
3867 (define_peephole2 ; lshrqi3_l_const4
3868 [(set (match_operand:ALL1 0 "l_register_operand" "")
3869 (lshiftrt:ALL1 (match_dup 0)
3871 (match_scratch:QI 1 "d")]
3873 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3874 (set (match_dup 1) (const_int 15))
3875 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3877 operands[2] = avr_to_int_mode (operands[0]);
3880 (define_peephole2 ; lshrqi3_l_const5
3881 [(set (match_operand:ALL1 0 "l_register_operand" "")
3882 (lshiftrt:ALL1 (match_dup 0)
3884 (match_scratch:QI 1 "d")]
3886 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3887 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3888 (set (match_dup 1) (const_int 7))
3889 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3891 operands[2] = avr_to_int_mode (operands[0]);
3894 (define_peephole2 ; lshrqi3_l_const6
3895 [(set (match_operand:ALL1 0 "l_register_operand" "")
3896 (lshiftrt:ALL1 (match_dup 0)
3898 (match_scratch:QI 1 "d")]
3900 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3901 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3902 (set (match_dup 1) (const_int 3))
3903 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3905 operands[2] = avr_to_int_mode (operands[0]);
3909 [(match_scratch:QI 3 "d")
3910 (set (match_operand:ALL2 0 "register_operand" "")
3911 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3912 (match_operand:QI 2 "const_int_operand" "")))]
3914 [(parallel [(set (match_dup 0)
3915 (lshiftrt:ALL2 (match_dup 1)
3917 (clobber (match_dup 3))])])
3920 ;; "*lshrhq3_const" "*lshruhq3_const"
3921 ;; "*lshrha3_const" "*lshruha3_const"
3922 (define_insn "*lshr<mode>3_const"
3923 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3924 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3925 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3926 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3929 return lshrhi3_out (insn, operands, NULL);
3931 [(set_attr "length" "0,2,2,4,10")
3932 (set_attr "adjust_len" "lshrhi")
3933 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3936 [(match_scratch:QI 3 "d")
3937 (set (match_operand:ALL4 0 "register_operand" "")
3938 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3939 (match_operand:QI 2 "const_int_operand" "")))]
3941 [(parallel [(set (match_dup 0)
3942 (lshiftrt:ALL4 (match_dup 1)
3944 (clobber (match_dup 3))])])
3947 ;; "*lshrsq3_const" "*lshrusq3_const"
3948 ;; "*lshrsa3_const" "*lshrusa3_const"
3949 (define_insn "*lshr<mode>3_const"
3950 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3951 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3952 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3953 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3956 return lshrsi3_out (insn, operands, NULL);
3958 [(set_attr "length" "0,4,4,10")
3959 (set_attr "adjust_len" "lshrsi")
3960 (set_attr "cc" "none,clobber,clobber,clobber")])
3962 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3965 (define_insn "absqi2"
3966 [(set (match_operand:QI 0 "register_operand" "=r")
3967 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3971 [(set_attr "length" "2")
3972 (set_attr "cc" "clobber")])
3975 (define_insn "abssf2"
3976 [(set (match_operand:SF 0 "register_operand" "=d,r")
3977 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3982 [(set_attr "length" "1,2")
3983 (set_attr "cc" "set_n,clobber")])
3985 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3988 (define_insn "negqi2"
3989 [(set (match_operand:QI 0 "register_operand" "=r")
3990 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3993 [(set_attr "length" "1")
3994 (set_attr "cc" "set_zn")])
3996 (define_insn "*negqihi2"
3997 [(set (match_operand:HI 0 "register_operand" "=r")
3998 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4000 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4001 [(set_attr "length" "4")
4002 (set_attr "cc" "set_n")])
4004 (define_insn "neghi2"
4005 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4006 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4009 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4010 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4011 [(set_attr "length" "3,4")
4012 (set_attr "cc" "set_czn")])
4014 (define_insn "negpsi2"
4015 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4016 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4019 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4020 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4021 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4022 [(set_attr "length" "5,6,6")
4023 (set_attr "cc" "set_czn,set_n,set_czn")])
4025 (define_insn "negsi2"
4026 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4027 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4030 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4031 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4032 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4033 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4034 [(set_attr "length" "7,8,8,7")
4035 (set_attr "isa" "*,*,mov,movw")
4036 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4038 (define_insn "negsf2"
4039 [(set (match_operand:SF 0 "register_operand" "=d,r")
4040 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4044 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4045 [(set_attr "length" "1,4")
4046 (set_attr "cc" "set_n,set_n")])
4048 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4051 (define_insn "one_cmplqi2"
4052 [(set (match_operand:QI 0 "register_operand" "=r")
4053 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4056 [(set_attr "length" "1")
4057 (set_attr "cc" "set_czn")])
4059 (define_insn "one_cmplhi2"
4060 [(set (match_operand:HI 0 "register_operand" "=r")
4061 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4065 [(set_attr "length" "2")
4066 (set_attr "cc" "set_n")])
4068 (define_insn "one_cmplpsi2"
4069 [(set (match_operand:PSI 0 "register_operand" "=r")
4070 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4072 "com %0\;com %B0\;com %C0"
4073 [(set_attr "length" "3")
4074 (set_attr "cc" "set_n")])
4076 (define_insn "one_cmplsi2"
4077 [(set (match_operand:SI 0 "register_operand" "=r")
4078 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4084 [(set_attr "length" "4")
4085 (set_attr "cc" "set_n")])
4087 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4090 ;; We keep combiner from inserting hard registers into the input of sign- and
4091 ;; zero-extends. A hard register in the input operand is not wanted because
4092 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4093 ;; hard register that overlaps these clobbers won't be combined to a widening
4094 ;; multiplication. There is no need for combine to propagate hard registers,
4095 ;; register allocation can do it just as well.
4097 (define_insn "extendqihi2"
4098 [(set (match_operand:HI 0 "register_operand" "=r,r")
4099 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4102 clr %B0\;sbrc %0,7\;com %B0
4103 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4104 [(set_attr "length" "3,4")
4105 (set_attr "cc" "set_n,set_n")])
4107 (define_insn "extendqipsi2"
4108 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4109 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4112 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4113 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4114 [(set_attr "length" "4,5")
4115 (set_attr "cc" "set_n,set_n")])
4117 (define_insn "extendqisi2"
4118 [(set (match_operand:SI 0 "register_operand" "=r,r")
4119 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4122 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4123 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4124 [(set_attr "length" "5,6")
4125 (set_attr "cc" "set_n,set_n")])
4127 (define_insn "extendhipsi2"
4128 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4129 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4132 clr %C0\;sbrc %B0,7\;com %C0
4133 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4134 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4135 [(set_attr "length" "3,5,4")
4136 (set_attr "isa" "*,mov,movw")
4137 (set_attr "cc" "set_n")])
4139 (define_insn "extendhisi2"
4140 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4141 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4144 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4145 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4146 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4147 [(set_attr "length" "4,6,5")
4148 (set_attr "isa" "*,mov,movw")
4149 (set_attr "cc" "set_n")])
4151 (define_insn "extendpsisi2"
4152 [(set (match_operand:SI 0 "register_operand" "=r")
4153 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4155 "clr %D0\;sbrc %C0,7\;com %D0"
4156 [(set_attr "length" "3")
4157 (set_attr "cc" "set_n")])
4159 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4162 (define_insn_and_split "zero_extendqihi2"
4163 [(set (match_operand:HI 0 "register_operand" "=r")
4164 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4168 [(set (match_dup 2) (match_dup 1))
4169 (set (match_dup 3) (const_int 0))]
4171 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4172 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4174 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4175 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4178 (define_insn_and_split "zero_extendqipsi2"
4179 [(set (match_operand:PSI 0 "register_operand" "=r")
4180 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4184 [(set (match_dup 2) (match_dup 1))
4185 (set (match_dup 3) (const_int 0))
4186 (set (match_dup 4) (const_int 0))]
4188 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4189 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4190 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4193 (define_insn_and_split "zero_extendqisi2"
4194 [(set (match_operand:SI 0 "register_operand" "=r")
4195 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4199 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4200 (set (match_dup 3) (const_int 0))]
4202 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4203 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4205 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4206 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4209 (define_insn_and_split "zero_extendhipsi2"
4210 [(set (match_operand:PSI 0 "register_operand" "=r")
4211 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4215 [(set (match_dup 2) (match_dup 1))
4216 (set (match_dup 3) (const_int 0))]
4218 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4219 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4222 (define_insn_and_split "n_extendhipsi2"
4223 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4224 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4225 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4226 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4230 [(set (match_dup 4) (match_dup 2))
4231 (set (match_dup 3) (match_dup 6))
4232 ; no-op move in the case where no scratch is needed
4233 (set (match_dup 5) (match_dup 3))]
4235 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4236 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4237 operands[6] = operands[1];
4239 if (GET_CODE (operands[3]) == SCRATCH)
4240 operands[3] = operands[5];
4243 (define_insn_and_split "zero_extendhisi2"
4244 [(set (match_operand:SI 0 "register_operand" "=r")
4245 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4249 [(set (match_dup 2) (match_dup 1))
4250 (set (match_dup 3) (const_int 0))]
4252 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4253 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4255 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4256 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4259 (define_insn_and_split "zero_extendpsisi2"
4260 [(set (match_operand:SI 0 "register_operand" "=r")
4261 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4265 [(set (match_dup 2) (match_dup 1))
4266 (set (match_dup 3) (const_int 0))]
4268 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4269 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4272 (define_insn_and_split "zero_extendqidi2"
4273 [(set (match_operand:DI 0 "register_operand" "=r")
4274 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4278 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4279 (set (match_dup 3) (const_int 0))]
4281 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4282 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4284 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4285 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4288 (define_insn_and_split "zero_extendhidi2"
4289 [(set (match_operand:DI 0 "register_operand" "=r")
4290 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4294 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4295 (set (match_dup 3) (const_int 0))]
4297 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4298 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4300 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4301 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4304 (define_insn_and_split "zero_extendsidi2"
4305 [(set (match_operand:DI 0 "register_operand" "=r")
4306 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 3) (const_int 0))]
4313 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4314 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4316 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4317 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4320 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4323 ; Optimize negated tests into reverse compare if overflow is undefined.
4324 (define_insn "*negated_tstqi"
4326 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4328 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4329 "cp __zero_reg__,%0"
4330 [(set_attr "cc" "compare")
4331 (set_attr "length" "1")])
4333 (define_insn "*reversed_tstqi"
4335 (compare (const_int 0)
4336 (match_operand:QI 0 "register_operand" "r")))]
4338 "cp __zero_reg__,%0"
4339 [(set_attr "cc" "compare")
4340 (set_attr "length" "2")])
4342 (define_insn "*negated_tsthi"
4344 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4346 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4347 "cp __zero_reg__,%A0
4348 cpc __zero_reg__,%B0"
4349 [(set_attr "cc" "compare")
4350 (set_attr "length" "2")])
4352 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4353 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4354 (define_insn "*reversed_tsthi"
4356 (compare (const_int 0)
4357 (match_operand:HI 0 "register_operand" "r")))
4358 (clobber (match_scratch:QI 1 "=X"))]
4360 "cp __zero_reg__,%A0
4361 cpc __zero_reg__,%B0"
4362 [(set_attr "cc" "compare")
4363 (set_attr "length" "2")])
4365 (define_insn "*negated_tstpsi"
4367 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4369 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4370 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4371 [(set_attr "cc" "compare")
4372 (set_attr "length" "3")])
4374 (define_insn "*reversed_tstpsi"
4376 (compare (const_int 0)
4377 (match_operand:PSI 0 "register_operand" "r")))
4378 (clobber (match_scratch:QI 1 "=X"))]
4380 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4381 [(set_attr "cc" "compare")
4382 (set_attr "length" "3")])
4384 (define_insn "*negated_tstsi"
4386 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4388 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4389 "cp __zero_reg__,%A0
4390 cpc __zero_reg__,%B0
4391 cpc __zero_reg__,%C0
4392 cpc __zero_reg__,%D0"
4393 [(set_attr "cc" "compare")
4394 (set_attr "length" "4")])
4396 ;; "*reversed_tstsi"
4397 ;; "*reversed_tstsq" "*reversed_tstusq"
4398 ;; "*reversed_tstsa" "*reversed_tstusa"
4399 (define_insn "*reversed_tst<mode>"
4401 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4402 (match_operand:ALL4 1 "register_operand" "r")))
4403 (clobber (match_scratch:QI 2 "=X"))]
4405 "cp __zero_reg__,%A1
4406 cpc __zero_reg__,%B1
4407 cpc __zero_reg__,%C1
4408 cpc __zero_reg__,%D1"
4409 [(set_attr "cc" "compare")
4410 (set_attr "length" "4")])
4414 ;; "*cmpqq" "*cmpuqq"
4415 (define_insn "*cmp<mode>"
4417 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4418 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4424 [(set_attr "cc" "compare,compare,compare")
4425 (set_attr "length" "1,1,1")])
4427 (define_insn "*cmpqi_sign_extend"
4429 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4430 (match_operand:HI 1 "s8_operand" "n")))]
4433 [(set_attr "cc" "compare")
4434 (set_attr "length" "1")])
4437 ;; "*cmphq" "*cmpuhq"
4438 ;; "*cmpha" "*cmpuha"
4439 (define_insn "*cmp<mode>"
4441 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4442 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4443 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4446 switch (which_alternative)
4450 return avr_out_tsthi (insn, operands, NULL);
4453 return "cp %A0,%A1\;cpc %B0,%B1";
4456 if (<MODE>mode != HImode)
4458 return reg_unused_after (insn, operands[0])
4459 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4460 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4463 if (<MODE>mode != HImode)
4465 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4468 return avr_out_compare (insn, operands, NULL);
4470 [(set_attr "cc" "compare")
4471 (set_attr "length" "1,2,2,3,4,2,4")
4472 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4474 (define_insn "*cmppsi"
4476 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4477 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4478 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4481 switch (which_alternative)
4484 return avr_out_tstpsi (insn, operands, NULL);
4487 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4490 return reg_unused_after (insn, operands[0])
4491 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4492 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4495 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4498 return avr_out_compare (insn, operands, NULL);
4500 [(set_attr "cc" "compare")
4501 (set_attr "length" "3,3,5,6,3,7")
4502 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4505 ;; "*cmpsq" "*cmpusq"
4506 ;; "*cmpsa" "*cmpusa"
4507 (define_insn "*cmp<mode>"
4509 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4510 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4511 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4514 if (0 == which_alternative)
4515 return avr_out_tstsi (insn, operands, NULL);
4516 else if (1 == which_alternative)
4517 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4519 return avr_out_compare (insn, operands, NULL);
4521 [(set_attr "cc" "compare")
4522 (set_attr "length" "4,4,4,5,8")
4523 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4526 ;; ----------------------------------------------------------------------
4527 ;; JUMP INSTRUCTIONS
4528 ;; ----------------------------------------------------------------------
4529 ;; Conditional jump instructions
4532 ;; "cbranchqq4" "cbranchuqq4"
4533 (define_expand "cbranch<mode>4"
4535 (compare (match_operand:ALL1 1 "register_operand" "")
4536 (match_operand:ALL1 2 "nonmemory_operand" "")))
4539 (match_operator 0 "ordered_comparison_operator" [(cc0)
4541 (label_ref (match_operand 3 "" ""))
4544 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4545 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4547 (define_expand "cbranch<mode>4"
4548 [(parallel [(set (cc0)
4549 (compare (match_operand:ORDERED234 1 "register_operand" "")
4550 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4551 (clobber (match_scratch:QI 4 ""))])
4554 (match_operator 0 "ordered_comparison_operator" [(cc0)
4556 (label_ref (match_operand 3 "" ""))
4560 ;; Test a single bit in a QI/HI/SImode register.
4561 ;; Combine will create zero extract patterns for single bit tests.
4562 ;; permit any mode in source pattern by using VOIDmode.
4564 (define_insn "*sbrx_branch<mode>"
4567 (match_operator 0 "eqne_operator"
4569 (match_operand:VOID 1 "register_operand" "r")
4571 (match_operand 2 "const_int_operand" "n"))
4573 (label_ref (match_operand 3 "" ""))
4577 return avr_out_sbxx_branch (insn, operands);
4579 [(set (attr "length")
4580 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4581 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4583 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4586 (set_attr "cc" "clobber")])
4588 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4589 ;; or for old peepholes.
4590 ;; Fixme - bitwise Mask will not work for DImode
4592 (define_insn "*sbrx_and_branch<mode>"
4595 (match_operator 0 "eqne_operator"
4597 (match_operand:QISI 1 "register_operand" "r")
4598 (match_operand:QISI 2 "single_one_operand" "n"))
4600 (label_ref (match_operand 3 "" ""))
4604 HOST_WIDE_INT bitnumber;
4605 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4606 operands[2] = GEN_INT (bitnumber);
4607 return avr_out_sbxx_branch (insn, operands);
4609 [(set (attr "length")
4610 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4611 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4613 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4616 (set_attr "cc" "clobber")])
4618 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4620 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4622 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4623 (label_ref (match_operand 1 "" ""))
4626 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4630 (label_ref (match_dup 1))
4634 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4636 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4637 (label_ref (match_operand 1 "" ""))
4640 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4644 (label_ref (match_dup 1))
4648 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4650 (clobber (match_operand:HI 2 ""))])
4651 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4652 (label_ref (match_operand 1 "" ""))
4655 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4657 (label_ref (match_dup 1))
4661 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4663 (clobber (match_operand:HI 2 ""))])
4664 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4665 (label_ref (match_operand 1 "" ""))
4668 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4670 (label_ref (match_dup 1))
4674 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4676 (clobber (match_operand:SI 2 ""))])
4677 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4678 (label_ref (match_operand 1 "" ""))
4681 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4683 (label_ref (match_dup 1))
4685 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4688 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4690 (clobber (match_operand:SI 2 ""))])
4691 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4692 (label_ref (match_operand 1 "" ""))
4695 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4697 (label_ref (match_dup 1))
4699 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4701 ;; ************************************************************************
4702 ;; Implementation of conditional jumps here.
4703 ;; Compare with 0 (test) jumps
4704 ;; ************************************************************************
4706 (define_insn "branch"
4708 (if_then_else (match_operator 1 "simple_comparison_operator"
4711 (label_ref (match_operand 0 "" ""))
4715 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4717 [(set_attr "type" "branch")
4718 (set_attr "cc" "clobber")])
4721 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4722 ;; or optimized in the remainder.
4724 (define_insn "branch_unspec"
4726 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4729 (label_ref (match_operand 0 "" ""))
4731 ] UNSPEC_IDENTITY))]
4734 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4736 [(set_attr "type" "branch")
4737 (set_attr "cc" "none")])
4739 ;; ****************************************************************
4740 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4741 ;; Convert them all to proper jumps.
4742 ;; ****************************************************************/
4744 (define_insn "difficult_branch"
4746 (if_then_else (match_operator 1 "difficult_comparison_operator"
4749 (label_ref (match_operand 0 "" ""))
4753 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4755 [(set_attr "type" "branch1")
4756 (set_attr "cc" "clobber")])
4760 (define_insn "rvbranch"
4762 (if_then_else (match_operator 1 "simple_comparison_operator"
4766 (label_ref (match_operand 0 "" ""))))]
4769 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4771 [(set_attr "type" "branch1")
4772 (set_attr "cc" "clobber")])
4774 (define_insn "difficult_rvbranch"
4776 (if_then_else (match_operator 1 "difficult_comparison_operator"
4780 (label_ref (match_operand 0 "" ""))))]
4783 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4785 [(set_attr "type" "branch")
4786 (set_attr "cc" "clobber")])
4788 ;; **************************************************************************
4789 ;; Unconditional and other jump instructions.
4793 (label_ref (match_operand 0 "" "")))]
4796 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4800 [(set (attr "length")
4801 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4802 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4805 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4806 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4809 (set_attr "cc" "none")])
4813 ;; Operand 1 not used on the AVR.
4814 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4815 (define_expand "call"
4816 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4817 (match_operand:HI 1 "general_operand" ""))
4818 (use (const_int 0))])])
4820 ;; Operand 1 not used on the AVR.
4821 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4822 (define_expand "sibcall"
4823 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4824 (match_operand:HI 1 "general_operand" ""))
4825 (use (const_int 1))])])
4829 ;; Operand 2 not used on the AVR.
4830 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4831 (define_expand "call_value"
4832 [(parallel[(set (match_operand 0 "register_operand" "")
4833 (call (match_operand:HI 1 "call_insn_operand" "")
4834 (match_operand:HI 2 "general_operand" "")))
4835 (use (const_int 0))])])
4837 ;; Operand 2 not used on the AVR.
4838 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4839 (define_expand "sibcall_value"
4840 [(parallel[(set (match_operand 0 "register_operand" "")
4841 (call (match_operand:HI 1 "call_insn_operand" "")
4842 (match_operand:HI 2 "general_operand" "")))
4843 (use (const_int 1))])])
4845 (define_insn "call_insn"
4846 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4847 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4848 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4849 ;; Operand 1 not used on the AVR.
4850 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4857 [(set_attr "cc" "clobber")
4858 (set_attr "length" "1,*,1,*")
4859 (set_attr "adjust_len" "*,call,*,call")])
4861 (define_insn "call_value_insn"
4862 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4863 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4864 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4865 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4866 ;; Operand 2 not used on the AVR.
4867 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4874 [(set_attr "cc" "clobber")
4875 (set_attr "length" "1,*,1,*")
4876 (set_attr "adjust_len" "*,call,*,call")])
4882 [(set_attr "cc" "none")
4883 (set_attr "length" "1")])
4887 (define_expand "indirect_jump"
4889 (match_operand:HI 0 "nonmemory_operand" ""))]
4892 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4894 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4899 (define_insn "*indirect_jump"
4901 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4907 push %A0\;push %B0\;ret
4909 [(set_attr "length" "1,2,1,3,1")
4910 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4911 (set_attr "cc" "none")])
4914 ;; For entries in jump table see avr_output_addr_vec_elt.
4917 ;; "rjmp .L<n>" instructions for <= 8K devices
4918 ;; ".word gs(.L<n>)" addresses for > 8K devices
4919 (define_insn "*tablejump"
4921 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4923 (use (label_ref (match_operand 1 "" "")))
4924 (clobber (match_dup 0))]
4928 push %A0\;push %B0\;ret
4930 [(set_attr "length" "1,3,2")
4931 (set_attr "isa" "rjmp,rjmp,jmp")
4932 (set_attr "cc" "none,none,clobber")])
4935 (define_expand "casesi"
4936 [(parallel [(set (match_dup 6)
4937 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4938 (match_operand:HI 1 "register_operand" "")))
4939 (clobber (scratch:QI))])
4940 (parallel [(set (cc0)
4941 (compare (match_dup 6)
4942 (match_operand:HI 2 "register_operand" "")))
4943 (clobber (match_scratch:QI 9 ""))])
4946 (if_then_else (gtu (cc0)
4948 (label_ref (match_operand 4 "" ""))
4952 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4954 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4955 (use (label_ref (match_dup 3)))
4956 (clobber (match_dup 6))])]
4959 operands[6] = gen_reg_rtx (HImode);
4963 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4964 ;; This instruction sets Z flag
4967 [(set (cc0) (const_int 0))]
4970 [(set_attr "length" "1")
4971 (set_attr "cc" "compare")])
4973 ;; Clear/set/test a single bit in I/O address space.
4976 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4977 (and:QI (mem:QI (match_dup 0))
4978 (match_operand:QI 1 "single_zero_operand" "n")))]
4981 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4982 return "cbi %i0,%2";
4984 [(set_attr "length" "1")
4985 (set_attr "cc" "none")])
4988 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4989 (ior:QI (mem:QI (match_dup 0))
4990 (match_operand:QI 1 "single_one_operand" "n")))]
4993 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4994 return "sbi %i0,%2";
4996 [(set_attr "length" "1")
4997 (set_attr "cc" "none")])
4999 ;; Lower half of the I/O space - use sbic/sbis directly.
5000 (define_insn "*sbix_branch"
5003 (match_operator 0 "eqne_operator"
5005 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5007 (match_operand 2 "const_int_operand" "n"))
5009 (label_ref (match_operand 3 "" ""))
5013 return avr_out_sbxx_branch (insn, operands);
5015 [(set (attr "length")
5016 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5017 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5019 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5022 (set_attr "cc" "clobber")])
5024 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5025 (define_insn "*sbix_branch_bit7"
5028 (match_operator 0 "gelt_operator"
5029 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
5031 (label_ref (match_operand 2 "" ""))
5035 operands[3] = operands[2];
5036 operands[2] = GEN_INT (7);
5037 return avr_out_sbxx_branch (insn, operands);
5039 [(set (attr "length")
5040 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5041 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5043 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5046 (set_attr "cc" "clobber")])
5048 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5049 (define_insn "*sbix_branch_tmp"
5052 (match_operator 0 "eqne_operator"
5054 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5056 (match_operand 2 "const_int_operand" "n"))
5058 (label_ref (match_operand 3 "" ""))
5062 return avr_out_sbxx_branch (insn, operands);
5064 [(set (attr "length")
5065 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5066 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5068 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5071 (set_attr "cc" "clobber")])
5073 (define_insn "*sbix_branch_tmp_bit7"
5076 (match_operator 0 "gelt_operator"
5077 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5079 (label_ref (match_operand 2 "" ""))
5083 operands[3] = operands[2];
5084 operands[2] = GEN_INT (7);
5085 return avr_out_sbxx_branch (insn, operands);
5087 [(set (attr "length")
5088 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5089 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5091 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5094 (set_attr "cc" "clobber")])
5096 ;; ************************* Peepholes ********************************
5098 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5099 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5100 (plus:SI (match_dup 0)
5102 (clobber (scratch:QI))])
5103 (parallel [(set (cc0)
5104 (compare (match_dup 0)
5106 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5108 (if_then_else (eqne (cc0)
5110 (label_ref (match_operand 2 "" ""))
5117 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5118 output_asm_insn ("sbiw %0,1" CR_TAB
5119 "sbc %C0,__zero_reg__" CR_TAB
5120 "sbc %D0,__zero_reg__", operands);
5122 output_asm_insn ("subi %A0,1" CR_TAB
5123 "sbc %B0,__zero_reg__" CR_TAB
5124 "sbc %C0,__zero_reg__" CR_TAB
5125 "sbc %D0,__zero_reg__", operands);
5127 jump_mode = avr_jump_mode (operands[2], insn);
5128 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5129 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5133 case 1: return "%1 %2";
5134 case 2: return "%1 .+2\;rjmp %2";
5135 case 3: return "%1 .+4\;jmp %2";
5142 (define_peephole ; "*dec-and-branchhi!=-1"
5143 [(set (match_operand:HI 0 "d_register_operand" "")
5144 (plus:HI (match_dup 0)
5146 (parallel [(set (cc0)
5147 (compare (match_dup 0)
5149 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5151 (if_then_else (eqne (cc0)
5153 (label_ref (match_operand 2 "" ""))
5160 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5161 output_asm_insn ("sbiw %0,1", operands);
5163 output_asm_insn ("subi %A0,1" CR_TAB
5164 "sbc %B0,__zero_reg__", operands);
5166 jump_mode = avr_jump_mode (operands[2], insn);
5167 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5168 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5172 case 1: return "%1 %2";
5173 case 2: return "%1 .+2\;rjmp %2";
5174 case 3: return "%1 .+4\;jmp %2";
5181 ;; Same as above but with clobber flavour of addhi3
5182 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5183 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5184 (plus:HI (match_dup 0)
5186 (clobber (scratch:QI))])
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.l.clobber"
5224 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5225 (plus:HI (match_dup 0)
5227 (clobber (match_operand:QI 3 "d_register_operand" ""))])
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 output_asm_insn ("ldi %3,1" CR_TAB
5244 "sbc %B0,__zero_reg__", operands);
5246 jump_mode = avr_jump_mode (operands[2], insn);
5247 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5248 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5252 case 1: return "%1 %2";
5253 case 2: return "%1 .+2\;rjmp %2";
5254 case 3: return "%1 .+4\;jmp %2";
5261 (define_peephole ; "*dec-and-branchqi!=-1"
5262 [(set (match_operand:QI 0 "d_register_operand" "")
5263 (plus:QI (match_dup 0)
5266 (compare (match_dup 0)
5269 (if_then_else (eqne (cc0)
5271 (label_ref (match_operand 1 "" ""))
5278 cc_status.value1 = operands[0];
5279 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5281 output_asm_insn ("subi %A0,1", operands);
5283 jump_mode = avr_jump_mode (operands[1], insn);
5284 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5285 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5289 case 1: return "%0 %1";
5290 case 2: return "%0 .+2\;rjmp %1";
5291 case 3: return "%0 .+4\;jmp %1";
5299 (define_peephole ; "*cpse.eq"
5301 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5302 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5304 (if_then_else (eq (cc0)
5306 (label_ref (match_operand 0 "" ""))
5308 "jump_over_one_insn_p (insn, operands[0])"
5311 cpse %1,__zero_reg__")
5313 ;; This peephole avoids code like
5316 ;; BREQ .+2 ; branch
5319 ;; Notice that the peephole is always shorter than cmpqi + branch.
5320 ;; The reason to write it as peephole is that sequences like
5325 ;; shall not be superseeded. With a respective combine pattern
5326 ;; the latter sequence would be
5329 ;; CPSE Rm, __zero_reg__
5332 ;; and thus longer and slower and not easy to be rolled back.
5334 (define_peephole ; "*cpse.ne"
5336 (compare (match_operand:ALL1 1 "register_operand" "")
5337 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5339 (if_then_else (ne (cc0)
5341 (label_ref (match_operand 0 "" ""))
5344 || !avr_current_device->errata_skip"
5346 if (operands[2] == CONST0_RTX (<MODE>mode))
5347 operands[2] = zero_reg_rtx;
5349 return 3 == avr_jump_mode (operands[0], insn)
5350 ? "cpse %1,%2\;jmp %0"
5351 : "cpse %1,%2\;rjmp %0";
5354 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5355 ;;prologue/epilogue support instructions
5357 (define_insn "popqi"
5358 [(set (match_operand:QI 0 "register_operand" "=r")
5359 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5362 [(set_attr "cc" "none")
5363 (set_attr "length" "1")])
5365 ;; Enable Interrupts
5366 (define_expand "enable_interrupt"
5367 [(clobber (const_int 0))]
5370 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5371 MEM_VOLATILE_P (mem) = 1;
5372 emit_insn (gen_cli_sei (const1_rtx, mem));
5376 ;; Disable Interrupts
5377 (define_expand "disable_interrupt"
5378 [(clobber (const_int 0))]
5381 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5382 MEM_VOLATILE_P (mem) = 1;
5383 emit_insn (gen_cli_sei (const0_rtx, mem));
5387 (define_insn "cli_sei"
5388 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5389 UNSPECV_ENABLE_IRQS)
5390 (set (match_operand:BLK 1 "" "")
5391 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5396 [(set_attr "length" "1")
5397 (set_attr "cc" "none")])
5399 ;; Library prologue saves
5400 (define_insn "call_prologue_saves"
5401 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5402 (match_operand:HI 0 "immediate_operand" "i,i")
5403 (set (reg:HI REG_SP)
5404 (minus:HI (reg:HI REG_SP)
5405 (match_operand:HI 1 "immediate_operand" "i,i")))
5406 (use (reg:HI REG_X))
5407 (clobber (reg:HI REG_Z))]
5409 "ldi r30,lo8(gs(1f))
5411 %~jmp __prologue_saves__+((18 - %0) * 2)
5413 [(set_attr "length" "5,6")
5414 (set_attr "cc" "clobber")
5415 (set_attr "isa" "rjmp,jmp")])
5417 ; epilogue restores using library
5418 (define_insn "epilogue_restores"
5419 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5421 (plus:HI (reg:HI REG_Y)
5422 (match_operand:HI 0 "immediate_operand" "i,i")))
5423 (set (reg:HI REG_SP)
5424 (plus:HI (reg:HI REG_Y)
5426 (clobber (reg:QI REG_Z))]
5429 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5430 [(set_attr "length" "2,3")
5431 (set_attr "cc" "clobber")
5432 (set_attr "isa" "rjmp,jmp")])
5435 (define_insn "return"
5437 "reload_completed && avr_simple_epilogue ()"
5439 [(set_attr "cc" "none")
5440 (set_attr "length" "1")])
5442 (define_insn "return_from_epilogue"
5446 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5447 && !cfun->machine->is_naked"
5449 [(set_attr "cc" "none")
5450 (set_attr "length" "1")])
5452 (define_insn "return_from_interrupt_epilogue"
5456 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5457 && !cfun->machine->is_naked"
5459 [(set_attr "cc" "none")
5460 (set_attr "length" "1")])
5462 (define_insn "return_from_naked_epilogue"
5466 && cfun->machine->is_naked"
5468 [(set_attr "cc" "none")
5469 (set_attr "length" "0")])
5471 (define_expand "prologue"
5475 avr_expand_prologue ();
5479 (define_expand "epilogue"
5483 avr_expand_epilogue (false /* sibcall_p */);
5487 (define_expand "sibcall_epilogue"
5491 avr_expand_epilogue (true /* sibcall_p */);
5495 ;; Some instructions resp. instruction sequences available
5498 (define_insn "delay_cycles_1"
5499 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5501 UNSPECV_DELAY_CYCLES)
5502 (set (match_operand:BLK 1 "" "")
5503 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5504 (clobber (match_scratch:QI 2 "=&d"))]
5509 [(set_attr "length" "3")
5510 (set_attr "cc" "clobber")])
5512 (define_insn "delay_cycles_2"
5513 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5515 UNSPECV_DELAY_CYCLES)
5516 (set (match_operand:BLK 1 "" "")
5517 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5518 (clobber (match_scratch:HI 2 "=&w"))]
5524 [(set_attr "length" "4")
5525 (set_attr "cc" "clobber")])
5527 (define_insn "delay_cycles_3"
5528 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5530 UNSPECV_DELAY_CYCLES)
5531 (set (match_operand:BLK 1 "" "")
5532 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5533 (clobber (match_scratch:QI 2 "=&d"))
5534 (clobber (match_scratch:QI 3 "=&d"))
5535 (clobber (match_scratch:QI 4 "=&d"))]
5544 [(set_attr "length" "7")
5545 (set_attr "cc" "clobber")])
5547 (define_insn "delay_cycles_4"
5548 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5550 UNSPECV_DELAY_CYCLES)
5551 (set (match_operand:BLK 1 "" "")
5552 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5553 (clobber (match_scratch:QI 2 "=&d"))
5554 (clobber (match_scratch:QI 3 "=&d"))
5555 (clobber (match_scratch:QI 4 "=&d"))
5556 (clobber (match_scratch:QI 5 "=&d"))]
5567 [(set_attr "length" "9")
5568 (set_attr "cc" "clobber")])
5571 ;; __builtin_avr_insert_bits
5573 (define_insn "insert_bits"
5574 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5575 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5576 (match_operand:QI 2 "register_operand" "r ,r ,r")
5577 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5578 UNSPEC_INSERT_BITS))]
5581 return avr_out_insert_bits (operands, NULL);
5583 [(set_attr "adjust_len" "insert_bits")
5584 (set_attr "cc" "clobber")])
5587 ;; __builtin_avr_flash_segment
5589 ;; Just a helper for the next "official" expander.
5591 (define_expand "flash_segment1"
5592 [(set (match_operand:QI 0 "register_operand" "")
5593 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5596 (compare (match_dup 0)
5599 (if_then_else (ge (cc0)
5601 (label_ref (match_operand 2 "" ""))
5606 (define_expand "flash_segment"
5607 [(parallel [(match_operand:QI 0 "register_operand" "")
5608 (match_operand:PSI 1 "register_operand" "")])]
5611 rtx label = gen_label_rtx ();
5612 emit (gen_flash_segment1 (operands[0], operands[1], label));
5617 ;; Actually, it's too late now to work out address spaces known at compiletime.
5618 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5619 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5620 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5622 (define_insn_and_split "*split.flash_segment"
5623 [(set (match_operand:QI 0 "register_operand" "=d")
5624 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5625 (match_operand:HI 2 "register_operand" "r"))
5628 { gcc_unreachable(); }
5636 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5637 ;; better 8-bit parity recognition.
5639 (define_expand "parityhi2"
5640 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5641 (parity:HI (match_operand:HI 1 "register_operand" "")))
5642 (clobber (reg:HI 24))])])
5644 (define_insn_and_split "*parityhi2"
5645 [(set (match_operand:HI 0 "register_operand" "=r")
5646 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5647 (clobber (reg:HI 24))]
5649 { gcc_unreachable(); }
5654 (parity:HI (reg:HI 24)))
5658 (define_insn_and_split "*parityqihi2"
5659 [(set (match_operand:HI 0 "register_operand" "=r")
5660 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5661 (clobber (reg:HI 24))]
5663 { gcc_unreachable(); }
5668 (zero_extend:HI (parity:QI (reg:QI 24))))
5672 (define_expand "paritysi2"
5674 (match_operand:SI 1 "register_operand" ""))
5676 (truncate:HI (parity:SI (reg:SI 22))))
5679 (set (match_operand:SI 0 "register_operand" "")
5680 (zero_extend:SI (match_dup 2)))]
5683 operands[2] = gen_reg_rtx (HImode);
5686 (define_insn "*parityhi2.libgcc"
5688 (parity:HI (reg:HI 24)))]
5690 "%~call __parityhi2"
5691 [(set_attr "type" "xcall")
5692 (set_attr "cc" "clobber")])
5694 (define_insn "*parityqihi2.libgcc"
5696 (zero_extend:HI (parity:QI (reg:QI 24))))]
5698 "%~call __parityqi2"
5699 [(set_attr "type" "xcall")
5700 (set_attr "cc" "clobber")])
5702 (define_insn "*paritysihi2.libgcc"
5704 (truncate:HI (parity:SI (reg:SI 22))))]
5706 "%~call __paritysi2"
5707 [(set_attr "type" "xcall")
5708 (set_attr "cc" "clobber")])
5713 (define_expand "popcounthi2"
5715 (match_operand:HI 1 "register_operand" ""))
5717 (popcount:HI (reg:HI 24)))
5718 (set (match_operand:HI 0 "register_operand" "")
5723 (define_expand "popcountsi2"
5725 (match_operand:SI 1 "register_operand" ""))
5727 (truncate:HI (popcount:SI (reg:SI 22))))
5730 (set (match_operand:SI 0 "register_operand" "")
5731 (zero_extend:SI (match_dup 2)))]
5734 operands[2] = gen_reg_rtx (HImode);
5737 (define_insn "*popcounthi2.libgcc"
5739 (popcount:HI (reg:HI 24)))]
5741 "%~call __popcounthi2"
5742 [(set_attr "type" "xcall")
5743 (set_attr "cc" "clobber")])
5745 (define_insn "*popcountsi2.libgcc"
5747 (truncate:HI (popcount:SI (reg:SI 22))))]
5749 "%~call __popcountsi2"
5750 [(set_attr "type" "xcall")
5751 (set_attr "cc" "clobber")])
5753 (define_insn "*popcountqi2.libgcc"
5755 (popcount:QI (reg:QI 24)))]
5757 "%~call __popcountqi2"
5758 [(set_attr "type" "xcall")
5759 (set_attr "cc" "clobber")])
5761 (define_insn_and_split "*popcountqihi2.libgcc"
5763 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5768 (popcount:QI (reg:QI 24)))
5772 ;; Count Leading Zeros
5774 (define_expand "clzhi2"
5776 (match_operand:HI 1 "register_operand" ""))
5777 (parallel [(set (reg:HI 24)
5778 (clz:HI (reg:HI 24)))
5779 (clobber (reg:QI 26))])
5780 (set (match_operand:HI 0 "register_operand" "")
5783 (define_expand "clzsi2"
5785 (match_operand:SI 1 "register_operand" ""))
5786 (parallel [(set (reg:HI 24)
5787 (truncate:HI (clz:SI (reg:SI 22))))
5788 (clobber (reg:QI 26))])
5791 (set (match_operand:SI 0 "register_operand" "")
5792 (zero_extend:SI (match_dup 2)))]
5795 operands[2] = gen_reg_rtx (HImode);
5798 (define_insn "*clzhi2.libgcc"
5800 (clz:HI (reg:HI 24)))
5801 (clobber (reg:QI 26))]
5804 [(set_attr "type" "xcall")
5805 (set_attr "cc" "clobber")])
5807 (define_insn "*clzsihi2.libgcc"
5809 (truncate:HI (clz:SI (reg:SI 22))))
5810 (clobber (reg:QI 26))]
5813 [(set_attr "type" "xcall")
5814 (set_attr "cc" "clobber")])
5816 ;; Count Trailing Zeros
5818 (define_expand "ctzhi2"
5820 (match_operand:HI 1 "register_operand" ""))
5821 (parallel [(set (reg:HI 24)
5822 (ctz:HI (reg:HI 24)))
5823 (clobber (reg:QI 26))])
5824 (set (match_operand:HI 0 "register_operand" "")
5827 (define_expand "ctzsi2"
5829 (match_operand:SI 1 "register_operand" ""))
5830 (parallel [(set (reg:HI 24)
5831 (truncate:HI (ctz:SI (reg:SI 22))))
5832 (clobber (reg:QI 22))
5833 (clobber (reg:QI 26))])
5836 (set (match_operand:SI 0 "register_operand" "")
5837 (zero_extend:SI (match_dup 2)))]
5840 operands[2] = gen_reg_rtx (HImode);
5843 (define_insn "*ctzhi2.libgcc"
5845 (ctz:HI (reg:HI 24)))
5846 (clobber (reg:QI 26))]
5849 [(set_attr "type" "xcall")
5850 (set_attr "cc" "clobber")])
5852 (define_insn "*ctzsihi2.libgcc"
5854 (truncate:HI (ctz:SI (reg:SI 22))))
5855 (clobber (reg:QI 22))
5856 (clobber (reg:QI 26))]
5859 [(set_attr "type" "xcall")
5860 (set_attr "cc" "clobber")])
5864 (define_expand "ffshi2"
5866 (match_operand:HI 1 "register_operand" ""))
5867 (parallel [(set (reg:HI 24)
5868 (ffs:HI (reg:HI 24)))
5869 (clobber (reg:QI 26))])
5870 (set (match_operand:HI 0 "register_operand" "")
5873 (define_expand "ffssi2"
5875 (match_operand:SI 1 "register_operand" ""))
5876 (parallel [(set (reg:HI 24)
5877 (truncate:HI (ffs:SI (reg:SI 22))))
5878 (clobber (reg:QI 22))
5879 (clobber (reg:QI 26))])
5882 (set (match_operand:SI 0 "register_operand" "")
5883 (zero_extend:SI (match_dup 2)))]
5886 operands[2] = gen_reg_rtx (HImode);
5889 (define_insn "*ffshi2.libgcc"
5891 (ffs:HI (reg:HI 24)))
5892 (clobber (reg:QI 26))]
5895 [(set_attr "type" "xcall")
5896 (set_attr "cc" "clobber")])
5898 (define_insn "*ffssihi2.libgcc"
5900 (truncate:HI (ffs:SI (reg:SI 22))))
5901 (clobber (reg:QI 22))
5902 (clobber (reg:QI 26))]
5905 [(set_attr "type" "xcall")
5906 (set_attr "cc" "clobber")])
5910 (define_insn "copysignsf3"
5911 [(set (match_operand:SF 0 "register_operand" "=r")
5912 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5913 (match_operand:SF 2 "register_operand" "r")]
5916 "bst %D2,7\;bld %D0,7"
5917 [(set_attr "length" "2")
5918 (set_attr "cc" "none")])
5920 ;; Swap Bytes (change byte-endianess)
5922 (define_expand "bswapsi2"
5924 (match_operand:SI 1 "register_operand" ""))
5926 (bswap:SI (reg:SI 22)))
5927 (set (match_operand:SI 0 "register_operand" "")
5930 (define_insn "*bswapsi2.libgcc"
5932 (bswap:SI (reg:SI 22)))]
5935 [(set_attr "type" "xcall")
5936 (set_attr "cc" "clobber")])
5941 ;; NOP taking 1 or 2 Ticks
5942 (define_expand "nopv"
5943 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5946 (unspec_volatile:BLK [(match_dup 1)]
5947 UNSPECV_MEMORY_BARRIER))])]
5950 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5951 MEM_VOLATILE_P (operands[1]) = 1;
5954 (define_insn "*nopv"
5955 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5957 (set (match_operand:BLK 1 "" "")
5958 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5963 [(set_attr "length" "1")
5964 (set_attr "cc" "none")])
5967 (define_expand "sleep"
5968 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5970 (unspec_volatile:BLK [(match_dup 0)]
5971 UNSPECV_MEMORY_BARRIER))])]
5974 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5975 MEM_VOLATILE_P (operands[0]) = 1;
5978 (define_insn "*sleep"
5979 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5980 (set (match_operand:BLK 0 "" "")
5981 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
5984 [(set_attr "length" "1")
5985 (set_attr "cc" "none")])
5988 (define_expand "wdr"
5989 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5991 (unspec_volatile:BLK [(match_dup 0)]
5992 UNSPECV_MEMORY_BARRIER))])]
5995 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5996 MEM_VOLATILE_P (operands[0]) = 1;
6000 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6001 (set (match_operand:BLK 0 "" "")
6002 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6005 [(set_attr "length" "1")
6006 (set_attr "cc" "none")])
6009 (define_expand "fmul"
6011 (match_operand:QI 1 "register_operand" ""))
6013 (match_operand:QI 2 "register_operand" ""))
6014 (parallel [(set (reg:HI 22)
6015 (unspec:HI [(reg:QI 24)
6016 (reg:QI 25)] UNSPEC_FMUL))
6017 (clobber (reg:HI 24))])
6018 (set (match_operand:HI 0 "register_operand" "")
6024 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6029 (define_insn "fmul_insn"
6030 [(set (match_operand:HI 0 "register_operand" "=r")
6031 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6032 (match_operand:QI 2 "register_operand" "a")]
6038 [(set_attr "length" "3")
6039 (set_attr "cc" "clobber")])
6041 (define_insn "*fmul.call"
6043 (unspec:HI [(reg:QI 24)
6044 (reg:QI 25)] UNSPEC_FMUL))
6045 (clobber (reg:HI 24))]
6048 [(set_attr "type" "xcall")
6049 (set_attr "cc" "clobber")])
6052 (define_expand "fmuls"
6054 (match_operand:QI 1 "register_operand" ""))
6056 (match_operand:QI 2 "register_operand" ""))
6057 (parallel [(set (reg:HI 22)
6058 (unspec:HI [(reg:QI 24)
6059 (reg:QI 25)] UNSPEC_FMULS))
6060 (clobber (reg:HI 24))])
6061 (set (match_operand:HI 0 "register_operand" "")
6067 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6072 (define_insn "fmuls_insn"
6073 [(set (match_operand:HI 0 "register_operand" "=r")
6074 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6075 (match_operand:QI 2 "register_operand" "a")]
6081 [(set_attr "length" "3")
6082 (set_attr "cc" "clobber")])
6084 (define_insn "*fmuls.call"
6086 (unspec:HI [(reg:QI 24)
6087 (reg:QI 25)] UNSPEC_FMULS))
6088 (clobber (reg:HI 24))]
6091 [(set_attr "type" "xcall")
6092 (set_attr "cc" "clobber")])
6095 (define_expand "fmulsu"
6097 (match_operand:QI 1 "register_operand" ""))
6099 (match_operand:QI 2 "register_operand" ""))
6100 (parallel [(set (reg:HI 22)
6101 (unspec:HI [(reg:QI 24)
6102 (reg:QI 25)] UNSPEC_FMULSU))
6103 (clobber (reg:HI 24))])
6104 (set (match_operand:HI 0 "register_operand" "")
6110 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6115 (define_insn "fmulsu_insn"
6116 [(set (match_operand:HI 0 "register_operand" "=r")
6117 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6118 (match_operand:QI 2 "register_operand" "a")]
6124 [(set_attr "length" "3")
6125 (set_attr "cc" "clobber")])
6127 (define_insn "*fmulsu.call"
6129 (unspec:HI [(reg:QI 24)
6130 (reg:QI 25)] UNSPEC_FMULSU))
6131 (clobber (reg:HI 24))]
6134 [(set_attr "type" "xcall")
6135 (set_attr "cc" "clobber")])
6138 ;; Some combiner patterns dealing with bits.
6141 ;; Move bit $3.0 into bit $0.$4
6142 (define_insn "*movbitqi.1-6.a"
6143 [(set (match_operand:QI 0 "register_operand" "=r")
6144 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6145 (match_operand:QI 2 "single_zero_operand" "n"))
6146 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6147 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6148 (match_operand:QI 5 "single_one_operand" "n"))))]
6149 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6150 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6151 "bst %3,0\;bld %0,%4"
6152 [(set_attr "length" "2")
6153 (set_attr "cc" "none")])
6155 ;; Move bit $3.0 into bit $0.$4
6156 ;; Variation of above. Unfortunately, there is no canonicalized representation
6157 ;; of moving around bits. So what we see here depends on how user writes down
6158 ;; bit manipulations.
6159 (define_insn "*movbitqi.1-6.b"
6160 [(set (match_operand:QI 0 "register_operand" "=r")
6161 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6162 (match_operand:QI 2 "single_zero_operand" "n"))
6163 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6165 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6166 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6167 "bst %3,0\;bld %0,%4"
6168 [(set_attr "length" "2")
6169 (set_attr "cc" "none")])
6171 ;; Move bit $3.0 into bit $0.0.
6172 ;; For bit 0, combiner generates slightly different pattern.
6173 (define_insn "*movbitqi.0"
6174 [(set (match_operand:QI 0 "register_operand" "=r")
6175 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6176 (match_operand:QI 2 "single_zero_operand" "n"))
6177 (and:QI (match_operand:QI 3 "register_operand" "r")
6179 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6180 "bst %3,0\;bld %0,0"
6181 [(set_attr "length" "2")
6182 (set_attr "cc" "none")])
6184 ;; Move bit $2.0 into bit $0.7.
6185 ;; For bit 7, combiner generates slightly different pattern
6186 (define_insn "*movbitqi.7"
6187 [(set (match_operand:QI 0 "register_operand" "=r")
6188 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6190 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6193 "bst %2,0\;bld %0,7"
6194 [(set_attr "length" "2")
6195 (set_attr "cc" "none")])
6197 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6198 ;; and input/output match. We provide a special pattern for this, because
6199 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6200 ;; operation on I/O is atomic.
6201 (define_insn "*insv.io"
6202 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6204 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6205 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6210 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6211 [(set_attr "length" "1,1,4")
6212 (set_attr "cc" "none")])
6214 (define_insn "*insv.not.io"
6215 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6217 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6218 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6220 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6221 [(set_attr "length" "4")
6222 (set_attr "cc" "none")])
6224 ;; The insv expander.
6225 ;; We only support 1-bit inserts
6226 (define_expand "insv"
6227 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6228 (match_operand:QI 1 "const1_operand" "") ; width
6229 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6230 (match_operand:QI 3 "nonmemory_operand" ""))]
6233 ;; Insert bit $2.0 into $0.$1
6234 (define_insn "*insv.reg"
6235 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6237 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6238 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6242 andi %0,lo8(~(1<<%1))
6246 [(set_attr "length" "2,1,1,2,2")
6247 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6250 ;; Some combine patterns that try to fix bad code when a value is composed
6251 ;; from byte parts like in PR27663.
6252 ;; The patterns give some release but the code still is not optimal,
6253 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6254 ;; That switch obfuscates things here and in many other places.
6256 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6257 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6258 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6259 [(set (match_operand:HISI 0 "register_operand" "=r")
6261 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6262 (match_operand:HISI 2 "register_operand" "0")))]
6267 (xior:QI (match_dup 3)
6270 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6273 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6274 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6275 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6276 [(set (match_operand:HISI 0 "register_operand" "=r")
6278 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6279 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6280 (match_operand:HISI 3 "register_operand" "0")))]
6281 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6283 "&& reload_completed"
6285 (xior:QI (match_dup 4)
6288 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6289 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6292 (define_expand "extzv"
6293 [(set (match_operand:QI 0 "register_operand" "")
6294 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6295 (match_operand:QI 2 "const1_operand" "")
6296 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6298 (define_insn "*extzv"
6299 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6300 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6302 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6306 mov %0,%1\;andi %0,1
6309 bst %1,%2\;clr %0\;bld %0,0"
6310 [(set_attr "length" "1,2,2,2,3")
6311 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6313 (define_insn_and_split "*extzv.qihi1"
6314 [(set (match_operand:HI 0 "register_operand" "=r")
6315 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6317 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6322 (zero_extract:QI (match_dup 1)
6328 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6329 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6332 (define_insn_and_split "*extzv.qihi2"
6333 [(set (match_operand:HI 0 "register_operand" "=r")
6335 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6337 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6342 (zero_extract:QI (match_dup 1)
6348 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6349 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6353 ;; Fixed-point instructions
6354 (include "avr-fixed.md")
6356 ;; Operations on 64-bit registers
6357 (include "avr-dimode.md")