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 ;; r Print a REG without the register prefix 'r'.
36 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
37 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
38 ;; just cashes the operand for the next %T. The second %T gets
39 ;; a CONST_INT that represents a bit position.
40 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
41 ;; "%T0%T1" it will print "r19,5".
42 ;; Notice that you must not write a comma between %T0 and %T1.
43 ;; T/t Similar to above, but don't print the comma and the bit number.
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
45 ;; "%T0%t1" it will print "r19".
46 ;;..x..Constant Direct Program memory address.
47 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
48 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
57 (LPM_REGNO 0) ; implicit target register of LPM
58 (TMP_REGNO 0) ; temporary register r0
59 (ZERO_REGNO 1) ; zero register r1
62 (define_c_enum "unspec"
75 (define_c_enum "unspecv"
76 [UNSPECV_PROLOGUE_SAVES
77 UNSPECV_EPILOGUE_RESTORES
81 UNSPECV_MEMORY_BARRIER
89 (include "predicates.md")
90 (include "constraints.md")
92 ;; Condition code settings.
93 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
95 (const_string "none"))
97 (define_attr "type" "branch,branch1,arith,xcall"
98 (const_string "arith"))
100 ;; The size of instructions in bytes.
101 ;; XXX may depend from "cc"
103 (define_attr "length" ""
104 (cond [(eq_attr "type" "branch")
105 (if_then_else (and (ge (minus (pc) (match_dup 0))
107 (le (minus (pc) (match_dup 0))
110 (if_then_else (and (ge (minus (pc) (match_dup 0))
112 (le (minus (pc) (match_dup 0))
116 (eq_attr "type" "branch1")
117 (if_then_else (and (ge (minus (pc) (match_dup 0))
119 (le (minus (pc) (match_dup 0))
122 (if_then_else (and (ge (minus (pc) (match_dup 0))
124 (le (minus (pc) (match_dup 0))
128 (eq_attr "type" "xcall")
129 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
134 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
135 ;; Following insn attribute tells if and how the adjustment has to be
137 ;; no No adjustment needed; attribute "length" is fine.
138 ;; Otherwise do special processing depending on the attribute.
140 (define_attr "adjust_len"
141 "out_bitop, plus, addto_sp,
142 tsthi, tstpsi, tstsi, compare, compare64, call,
143 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
144 ufract, sfract, round,
146 ashlqi, ashrqi, lshrqi,
147 ashlhi, ashrhi, lshrhi,
148 ashlsi, ashrsi, lshrsi,
149 ashlpsi, ashrpsi, lshrpsi,
154 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
156 ;; mov : ISA has no MOVW movw : ISA has MOVW
157 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
158 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
159 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
160 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
161 ;; no_xmega: non-XMEGA core xmega : XMEGA core
164 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
166 (const_string "standard"))
168 (define_attr "enabled" ""
169 (cond [(eq_attr "isa" "standard")
172 (and (eq_attr "isa" "mov")
173 (match_test "!AVR_HAVE_MOVW"))
176 (and (eq_attr "isa" "movw")
177 (match_test "AVR_HAVE_MOVW"))
180 (and (eq_attr "isa" "rjmp")
181 (match_test "!AVR_HAVE_JMP_CALL"))
184 (and (eq_attr "isa" "jmp")
185 (match_test "AVR_HAVE_JMP_CALL"))
188 (and (eq_attr "isa" "ijmp")
189 (match_test "!AVR_HAVE_EIJMP_EICALL"))
192 (and (eq_attr "isa" "eijmp")
193 (match_test "AVR_HAVE_EIJMP_EICALL"))
196 (and (eq_attr "isa" "lpm")
197 (match_test "!AVR_HAVE_LPMX"))
200 (and (eq_attr "isa" "lpmx")
201 (match_test "AVR_HAVE_LPMX"))
204 (and (eq_attr "isa" "elpm")
205 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
208 (and (eq_attr "isa" "elpmx")
209 (match_test "AVR_HAVE_ELPMX"))
212 (and (eq_attr "isa" "xmega")
213 (match_test "AVR_XMEGA"))
216 (and (eq_attr "isa" "no_xmega")
217 (match_test "!AVR_XMEGA"))
222 ;; Define mode iterators
223 (define_mode_iterator QIHI [QI HI])
224 (define_mode_iterator QIHI2 [QI HI])
225 (define_mode_iterator QISI [QI HI PSI SI])
226 (define_mode_iterator QIDI [QI HI PSI SI DI])
227 (define_mode_iterator HISI [HI PSI SI])
229 (define_mode_iterator ALL1 [QI QQ UQQ])
230 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
231 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
233 ;; All supported move-modes
234 (define_mode_iterator MOVMODE [QI QQ UQQ
239 ;; Supported ordered modes that are 2, 3, 4 bytes wide
240 (define_mode_iterator ORDERED234 [HI SI PSI
244 ;; Define code iterators
245 ;; Define two incarnations so that we can build the cross product.
246 (define_code_iterator any_extend [sign_extend zero_extend])
247 (define_code_iterator any_extend2 [sign_extend zero_extend])
249 (define_code_iterator xior [xor ior])
250 (define_code_iterator eqne [eq ne])
252 (define_code_iterator ss_addsub [ss_plus ss_minus])
253 (define_code_iterator us_addsub [us_plus us_minus])
254 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
256 ;; Define code attributes
257 (define_code_attr extend_su
261 (define_code_attr extend_u
265 (define_code_attr extend_s
269 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
270 (define_code_attr mul_r_d
274 (define_code_attr abelian
275 [(ss_minus "") (us_minus "")
276 (ss_plus "%") (us_plus "%")])
278 ;; Map RTX code to its standard insn name
279 (define_code_attr code_stdname
286 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
287 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
290 ;;========================================================================
291 ;; The following is used by nonlocal_goto and setjmp.
292 ;; The receiver pattern will create no instructions since internally
293 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
294 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
295 ;; The 'null' receiver also avoids problems with optimisation
296 ;; not recognising incoming jmp and removing code that resets frame_pointer.
297 ;; The code derived from builtins.c.
299 (define_expand "nonlocal_goto_receiver"
301 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
304 emit_move_insn (virtual_stack_vars_rtx,
305 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
306 gen_int_mode (STARTING_FRAME_OFFSET,
308 /* ; This might change the hard frame pointer in ways that aren't
309 ; apparent to early optimization passes, so force a clobber. */
310 emit_clobber (hard_frame_pointer_rtx);
315 ;; Defining nonlocal_goto_receiver means we must also define this.
316 ;; even though its function is identical to that in builtins.c
318 (define_expand "nonlocal_goto"
319 [(use (match_operand 0 "general_operand"))
320 (use (match_operand 1 "general_operand"))
321 (use (match_operand 2 "general_operand"))
322 (use (match_operand 3 "general_operand"))]
325 rtx r_label = copy_to_reg (operands[1]);
326 rtx r_fp = operands[3];
327 rtx r_sp = operands[2];
329 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
331 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
333 emit_move_insn (hard_frame_pointer_rtx, r_fp);
334 emit_stack_restore (SAVE_NONLOCAL, r_sp);
336 emit_use (hard_frame_pointer_rtx);
337 emit_use (stack_pointer_rtx);
339 emit_indirect_jump (r_label);
345 ;; "pushqq1" "pushuqq1"
346 (define_insn "push<mode>1"
347 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
348 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
353 [(set_attr "length" "1,1")])
355 ;; All modes for a multi-byte push. We must include complex modes here too,
356 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
357 (define_mode_iterator MPUSH
366 (define_expand "push<mode>1"
367 [(match_operand:MPUSH 0 "" "")]
371 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
373 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
374 if (part != const0_rtx)
375 part = force_reg (QImode, part);
376 emit_insn (gen_pushqi1 (part));
381 ;; Notice a special-case when adding N to SP where N results in a
382 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
384 [(set (reg:HI REG_SP)
385 (match_operand:HI 0 "register_operand" ""))]
387 && frame_pointer_needed
388 && !cfun->calls_alloca
389 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
390 [(set (reg:HI REG_SP)
393 ;;========================================================================
396 ;; Secondary input reload from non-generic 16-bit address spaces
397 (define_insn "reload_in<mode>"
398 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
399 (match_operand:MOVMODE 1 "flash_operand" "m"))
400 (clobber (match_operand:QI 2 "d_register_operand" "=d"))]
401 ;; Fixme: The insn condition must not test the address space.
402 ;; Because the gen tools refuse to generate insns for address spaces
403 ;; and will generate insn-codes.h to look like:
404 ;; #define CODE_FOR_reload_inhi CODE_FOR_nothing
405 "reload_completed || reload_in_progress"
407 return avr_out_lpm (insn, operands, NULL);
409 [(set_attr "adjust_len" "lpm")
410 (set_attr "cc" "clobber")])
418 (define_expand "load<mode>_libgcc"
421 (set (reg:MOVMODE 22)
422 (match_operand:MOVMODE 1 "memory_operand" ""))
423 (set (match_operand:MOVMODE 0 "register_operand" "")
425 "avr_load_libgcc_p (operands[1])"
427 operands[3] = gen_rtx_REG (HImode, REG_Z);
428 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
429 operands[1] = replace_equiv_address (operands[1], operands[3]);
430 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
438 (define_insn "load_<mode>_libgcc"
439 [(set (reg:MOVMODE 22)
440 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
441 "avr_load_libgcc_p (operands[0])
442 && REG_P (XEXP (operands[0], 0))
443 && REG_Z == REGNO (XEXP (operands[0], 0))"
445 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
446 return "%~call __load_%0";
448 [(set_attr "length" "1,2")
449 (set_attr "isa" "rjmp,jmp")
450 (set_attr "cc" "clobber")])
454 ;; "xload8qq_A" "xload8uqq_A"
455 (define_insn_and_split "xload8<mode>_A"
456 [(set (match_operand:ALL1 0 "register_operand" "=r")
457 (match_operand:ALL1 1 "memory_operand" "m"))
458 (clobber (reg:HI REG_Z))]
459 "can_create_pseudo_p()
460 && !avr_xload_libgcc_p (<MODE>mode)
461 && avr_mem_memx_p (operands[1])
462 && REG_P (XEXP (operands[1], 0))"
463 { gcc_unreachable(); }
465 [(clobber (const_int 0))]
467 /* ; Split away the high part of the address. GCC's register allocator
468 ; in not able to allocate segment registers and reload the resulting
469 ; expressions. Notice that no address register can hold a PSImode. */
471 rtx insn, addr = XEXP (operands[1], 0);
472 rtx hi8 = gen_reg_rtx (QImode);
473 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
475 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
476 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
478 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
479 set_mem_addr_space (SET_SRC (single_set (insn)),
480 MEM_ADDR_SPACE (operands[1]));
484 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
485 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
486 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
489 (define_insn_and_split "xload<mode>_A"
490 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
491 (match_operand:MOVMODE 1 "memory_operand" "m"))
492 (clobber (reg:MOVMODE 22))
493 (clobber (reg:QI 21))
494 (clobber (reg:HI REG_Z))]
495 "can_create_pseudo_p()
496 && avr_mem_memx_p (operands[1])
497 && REG_P (XEXP (operands[1], 0))"
498 { gcc_unreachable(); }
500 [(clobber (const_int 0))]
502 rtx addr = XEXP (operands[1], 0);
503 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
504 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
505 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
508 /* Split the address to R21:Z */
509 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
510 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
512 /* Load with code from libgcc */
513 insn = emit_insn (gen_xload_<mode>_libgcc ());
514 set_mem_addr_space (SET_SRC (single_set (insn)), as);
516 /* Move to destination */
517 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
522 ;; Move value from address space memx to a register
523 ;; These insns must be prior to respective generic move insn.
526 ;; "xloadqq_8" "xloaduqq_8"
527 (define_insn "xload<mode>_8"
528 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
529 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
531 "!avr_xload_libgcc_p (<MODE>mode)"
533 return avr_out_xload (insn, operands, NULL);
535 [(set_attr "length" "4,4")
536 (set_attr "adjust_len" "*,xload")
537 (set_attr "isa" "lpmx,lpm")
538 (set_attr "cc" "none")])
540 ;; R21:Z : 24-bit source address
541 ;; R22 : 1-4 byte output
543 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
544 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
545 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
547 ;; "xload_psi_libgcc"
548 (define_insn "xload_<mode>_libgcc"
549 [(set (reg:MOVMODE 22)
550 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
552 (clobber (reg:QI 21))
553 (clobber (reg:HI REG_Z))]
554 "avr_xload_libgcc_p (<MODE>mode)"
556 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
558 output_asm_insn ("%~call __xload_%0", &x_bytes);
561 [(set_attr "type" "xcall")
562 (set_attr "cc" "clobber")])
565 ;; General move expanders
567 ;; "movqi" "movqq" "movuqq"
568 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
569 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
572 (define_expand "mov<mode>"
573 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
574 (match_operand:MOVMODE 1 "general_operand" ""))]
577 rtx dest = operands[0];
578 rtx src = operands[1];
580 if (avr_mem_flash_p (dest))
583 /* One of the operands has to be in a register. */
584 if (!register_operand (dest, <MODE>mode)
585 && !reg_or_0_operand (src, <MODE>mode))
587 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
590 if (avr_mem_memx_p (src))
592 rtx addr = XEXP (src, 0);
595 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
597 if (!avr_xload_libgcc_p (<MODE>mode))
598 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
599 ; insn-emit does not depend on the mode, it's all about operands. */
600 emit_insn (gen_xload8qi_A (dest, src));
602 emit_insn (gen_xload<mode>_A (dest, src));
607 if (avr_load_libgcc_p (src))
609 /* For the small devices, do loads per libgcc call. */
610 emit_insn (gen_load<mode>_libgcc (dest, src));
615 ;;========================================================================
617 ;; The last alternative (any immediate constant to any register) is
618 ;; very expensive. It should be optimized by peephole2 if a scratch
619 ;; register is available, but then that register could just as well be
620 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
621 ;; are call-saved registers, and most of LD_REGS are call-used registers,
622 ;; so this may still be a win for registers live across function calls.
625 ;; "movqq_insn" "movuqq_insn"
626 (define_insn "mov<mode>_insn"
627 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
628 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
629 "register_operand (operands[0], <MODE>mode)
630 || reg_or_0_operand (operands[1], <MODE>mode)"
632 return output_movqi (insn, operands, NULL);
634 [(set_attr "length" "1,1,5,5,1,1,4")
635 (set_attr "adjust_len" "mov8")
636 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
638 ;; This is used in peephole2 to optimize loading immediate constants
639 ;; if a scratch register from LD_REGS happens to be available.
642 ;; "*reload_inqq" "*reload_inuqq"
643 (define_insn "*reload_in<mode>"
644 [(set (match_operand:ALL1 0 "register_operand" "=l")
645 (match_operand:ALL1 1 "const_operand" "i"))
646 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
650 [(set_attr "length" "2")
651 (set_attr "cc" "none")])
654 [(match_scratch:QI 2 "d")
655 (set (match_operand:ALL1 0 "l_register_operand" "")
656 (match_operand:ALL1 1 "const_operand" ""))]
657 ; No need for a clobber reg for 0x0, 0x01 or 0xff
658 "!satisfies_constraint_Y00 (operands[1])
659 && !satisfies_constraint_Y01 (operands[1])
660 && !satisfies_constraint_Ym1 (operands[1])"
661 [(parallel [(set (match_dup 0)
663 (clobber (match_dup 2))])])
665 ;;============================================================================
666 ;; move word (16 bit)
668 ;; Move register $1 to the Stack Pointer register SP.
669 ;; This insn is emit during function prologue/epilogue generation.
670 ;; $2 = 0: We know that IRQs are off
671 ;; $2 = 1: We know that IRQs are on
672 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
673 ;; $2 = -1: We don't know anything about IRQ on/off
674 ;; Always write SP via unspec, see PR50063
676 (define_insn "movhi_sp_r"
677 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
678 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
679 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
683 out %B0,%B1\;out %A0,%A1
684 cli\;out %B0,%B1\;sei\;out %A0,%A1
685 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
687 out %A0,%A1\;out %B0,%B1"
688 [(set_attr "length" "2,4,5,1,2")
689 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
690 (set_attr "cc" "none")])
693 [(match_scratch:QI 2 "d")
694 (set (match_operand:ALL2 0 "l_register_operand" "")
695 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
696 "operands[1] != CONST0_RTX (<MODE>mode)"
697 [(parallel [(set (match_dup 0)
699 (clobber (match_dup 2))])])
701 ;; '*' because it is not used in rtl generation, only in above peephole
703 ;; "*reload_inhq" "*reload_inuhq"
704 ;; "*reload_inha" "*reload_inuha"
705 (define_insn "*reload_in<mode>"
706 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
707 (match_operand:ALL2 1 "immediate_operand" "i"))
708 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
711 return output_reload_inhi (operands, operands[2], NULL);
713 [(set_attr "length" "4")
714 (set_attr "adjust_len" "reload_in16")
715 (set_attr "cc" "clobber")])
718 ;; "*movhq" "*movuhq"
719 ;; "*movha" "*movuha"
720 (define_insn "*mov<mode>"
721 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
722 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
723 "register_operand (operands[0], <MODE>mode)
724 || reg_or_0_operand (operands[1], <MODE>mode)"
726 return output_movhi (insn, operands, NULL);
728 [(set_attr "length" "2,2,6,7,2,6,5,2")
729 (set_attr "adjust_len" "mov16")
730 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
732 (define_peephole2 ; movw
733 [(set (match_operand:ALL1 0 "even_register_operand" "")
734 (match_operand:ALL1 1 "even_register_operand" ""))
735 (set (match_operand:ALL1 2 "odd_register_operand" "")
736 (match_operand:ALL1 3 "odd_register_operand" ""))]
738 && REGNO (operands[0]) == REGNO (operands[2]) - 1
739 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
743 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
744 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
747 (define_peephole2 ; movw_r
748 [(set (match_operand:ALL1 0 "odd_register_operand" "")
749 (match_operand:ALL1 1 "odd_register_operand" ""))
750 (set (match_operand:ALL1 2 "even_register_operand" "")
751 (match_operand:ALL1 3 "even_register_operand" ""))]
753 && REGNO (operands[2]) == REGNO (operands[0]) - 1
754 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
758 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
759 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
762 ;; For LPM loads from AS1 we split
766 ;; Z = Z - sizeof (R)
768 ;; so that the second instruction can be optimized out.
770 (define_split ; "split-lpmx"
771 [(set (match_operand:HISI 0 "register_operand" "")
772 (match_operand:HISI 1 "memory_operand" ""))]
778 (plus:HI (match_dup 3)
781 rtx addr = XEXP (operands[1], 0);
783 if (!avr_mem_flash_p (operands[1])
785 || reg_overlap_mentioned_p (addr, operands[0]))
790 operands[2] = replace_equiv_address (operands[1],
791 gen_rtx_POST_INC (Pmode, addr));
793 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
796 ;;==========================================================================
797 ;; xpointer move (24 bit)
799 (define_peephole2 ; *reload_inpsi
800 [(match_scratch:QI 2 "d")
801 (set (match_operand:PSI 0 "l_register_operand" "")
802 (match_operand:PSI 1 "immediate_operand" ""))
804 "operands[1] != const0_rtx
805 && operands[1] != constm1_rtx"
806 [(parallel [(set (match_dup 0)
808 (clobber (match_dup 2))])])
810 ;; '*' because it is not used in rtl generation.
811 (define_insn "*reload_inpsi"
812 [(set (match_operand:PSI 0 "register_operand" "=r")
813 (match_operand:PSI 1 "immediate_operand" "i"))
814 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
817 return avr_out_reload_inpsi (operands, operands[2], NULL);
819 [(set_attr "length" "6")
820 (set_attr "adjust_len" "reload_in24")
821 (set_attr "cc" "clobber")])
823 (define_insn "*movpsi"
824 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
825 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
826 "register_operand (operands[0], PSImode)
827 || register_operand (operands[1], PSImode)
828 || const0_rtx == operands[1]"
830 return avr_out_movpsi (insn, operands, NULL);
832 [(set_attr "length" "3,3,8,9,4,10")
833 (set_attr "adjust_len" "mov24")
834 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
836 ;;==========================================================================
837 ;; move double word (32 bit)
839 (define_peephole2 ; *reload_insi
840 [(match_scratch:QI 2 "d")
841 (set (match_operand:ALL4 0 "l_register_operand" "")
842 (match_operand:ALL4 1 "immediate_operand" ""))
844 "operands[1] != CONST0_RTX (<MODE>mode)"
845 [(parallel [(set (match_dup 0)
847 (clobber (match_dup 2))])])
849 ;; '*' because it is not used in rtl generation.
851 ;; "*reload_insq" "*reload_inusq"
852 ;; "*reload_insa" "*reload_inusa"
853 (define_insn "*reload_insi"
854 [(set (match_operand:ALL4 0 "register_operand" "=r")
855 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
856 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
859 return output_reload_insisf (operands, operands[2], NULL);
861 [(set_attr "length" "8")
862 (set_attr "adjust_len" "reload_in32")
863 (set_attr "cc" "clobber")])
867 ;; "*movsq" "*movusq"
868 ;; "*movsa" "*movusa"
869 (define_insn "*mov<mode>"
870 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
871 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
872 "register_operand (operands[0], <MODE>mode)
873 || reg_or_0_operand (operands[1], <MODE>mode)"
875 return output_movsisf (insn, operands, NULL);
877 [(set_attr "length" "4,4,8,9,4,10")
878 (set_attr "adjust_len" "mov32")
879 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
881 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
882 ;; move floating point numbers (32 bit)
884 (define_insn "*movsf"
885 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
886 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
887 "register_operand (operands[0], SFmode)
888 || reg_or_0_operand (operands[1], SFmode)"
890 return output_movsisf (insn, operands, NULL);
892 [(set_attr "length" "4,4,8,9,4,10")
893 (set_attr "adjust_len" "mov32")
894 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
896 (define_peephole2 ; *reload_insf
897 [(match_scratch:QI 2 "d")
898 (set (match_operand:SF 0 "l_register_operand" "")
899 (match_operand:SF 1 "const_double_operand" ""))
901 "operands[1] != CONST0_RTX (SFmode)"
902 [(parallel [(set (match_dup 0)
904 (clobber (match_dup 2))])])
906 ;; '*' because it is not used in rtl generation.
907 (define_insn "*reload_insf"
908 [(set (match_operand:SF 0 "register_operand" "=r")
909 (match_operand:SF 1 "const_double_operand" "F"))
910 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
913 return output_reload_insisf (operands, operands[2], NULL);
915 [(set_attr "length" "8")
916 (set_attr "adjust_len" "reload_in32")
917 (set_attr "cc" "clobber")])
919 ;;=========================================================================
920 ;; move string (like memcpy)
922 (define_expand "movmemhi"
923 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
924 (match_operand:BLK 1 "memory_operand" ""))
925 (use (match_operand:HI 2 "const_int_operand" ""))
926 (use (match_operand:HI 3 "const_int_operand" ""))])]
929 if (avr_emit_movmemhi (operands))
935 (define_mode_attr MOVMEM_r_d [(QI "r")
938 ;; $0 : Address Space
939 ;; $1, $2 : Loop register
940 ;; R30 : source address
941 ;; R26 : destination address
945 (define_insn "movmem_<mode>"
946 [(set (mem:BLK (reg:HI REG_X))
947 (mem:BLK (reg:HI REG_Z)))
948 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
950 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
951 (clobber (reg:HI REG_X))
952 (clobber (reg:HI REG_Z))
953 (clobber (reg:QI LPM_REGNO))
954 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
957 return avr_out_movmem (insn, operands, NULL);
959 [(set_attr "adjust_len" "movmem")
960 (set_attr "cc" "clobber")])
963 ;; $0 : Address Space
964 ;; $1 : RAMPZ RAM address
965 ;; R24 : #bytes and loop register
966 ;; R23:Z : 24-bit source address
967 ;; R26 : 16-bit destination address
971 (define_insn "movmemx_<mode>"
972 [(set (mem:BLK (reg:HI REG_X))
973 (mem:BLK (lo_sum:PSI (reg:QI 23)
975 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
978 (clobber (reg:HI REG_X))
979 (clobber (reg:HI REG_Z))
980 (clobber (reg:QI LPM_REGNO))
981 (clobber (reg:HI 24))
982 (clobber (reg:QI 23))
983 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
985 "%~call __movmemx_<mode>"
986 [(set_attr "type" "xcall")
987 (set_attr "cc" "clobber")])
990 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
991 ;; memset (%0, %2, %1)
993 (define_expand "setmemhi"
994 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
995 (match_operand 2 "const_int_operand" ""))
996 (use (match_operand:HI 1 "const_int_operand" ""))
997 (use (match_operand:HI 3 "const_int_operand" ""))
998 (clobber (match_scratch:HI 4 ""))
999 (clobber (match_dup 5))])]
1003 enum machine_mode mode;
1005 /* If value to set is not zero, use the library routine. */
1006 if (operands[2] != const0_rtx)
1009 if (!CONST_INT_P (operands[1]))
1012 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1013 operands[5] = gen_rtx_SCRATCH (mode);
1014 operands[1] = copy_to_mode_reg (mode,
1015 gen_int_mode (INTVAL (operands[1]), mode));
1016 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1017 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1021 (define_insn "*clrmemqi"
1022 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1024 (use (match_operand:QI 1 "register_operand" "r"))
1025 (use (match_operand:QI 2 "const_int_operand" "n"))
1026 (clobber (match_scratch:HI 3 "=0"))
1027 (clobber (match_scratch:QI 4 "=&1"))]
1029 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1030 [(set_attr "length" "3")
1031 (set_attr "cc" "clobber")])
1034 (define_insn "*clrmemhi"
1035 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1037 (use (match_operand:HI 1 "register_operand" "!w,d"))
1038 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1039 (clobber (match_scratch:HI 3 "=0,0"))
1040 (clobber (match_scratch:HI 4 "=&1,&1"))]
1043 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1044 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1045 [(set_attr "length" "3,4")
1046 (set_attr "cc" "clobber,clobber")])
1048 (define_expand "strlenhi"
1050 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1051 (match_operand:QI 2 "const_int_operand" "")
1052 (match_operand:HI 3 "immediate_operand" "")]
1055 (plus:HI (match_dup 4)
1057 (parallel [(set (match_operand:HI 0 "register_operand" "")
1058 (minus:HI (match_dup 4)
1060 (clobber (scratch:QI))])]
1064 if (operands[2] != const0_rtx)
1066 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1067 operands[1] = gen_rtx_MEM (BLKmode, addr);
1069 operands[4] = gen_reg_rtx (HImode);
1072 (define_insn "*strlenhi"
1073 [(set (match_operand:HI 0 "register_operand" "=e")
1074 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1076 (match_operand:HI 2 "immediate_operand" "i")]
1079 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1080 [(set_attr "length" "3")
1081 (set_attr "cc" "clobber")])
1083 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1087 ;; "addqq3" "adduqq3"
1088 (define_insn "add<mode>3"
1089 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1090 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1091 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1100 [(set_attr "length" "1,1,1,1,2,2")
1101 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1104 ;; "addhq3" "adduhq3"
1105 ;; "addha3" "adduha3"
1106 (define_expand "add<mode>3"
1107 [(set (match_operand:ALL2 0 "register_operand" "")
1108 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1109 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1112 if (CONST_INT_P (operands[2]))
1114 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1116 if (can_create_pseudo_p()
1117 && !stack_register_operand (operands[0], HImode)
1118 && !stack_register_operand (operands[1], HImode)
1119 && !d_register_operand (operands[0], HImode)
1120 && !d_register_operand (operands[1], HImode))
1122 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1127 if (CONST_FIXED_P (operands[2]))
1129 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1135 (define_insn "*addhi3_zero_extend"
1136 [(set (match_operand:HI 0 "register_operand" "=r")
1137 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1138 (match_operand:HI 2 "register_operand" "0")))]
1140 "add %A0,%1\;adc %B0,__zero_reg__"
1141 [(set_attr "length" "2")
1142 (set_attr "cc" "set_n")])
1144 (define_insn "*addhi3_zero_extend1"
1145 [(set (match_operand:HI 0 "register_operand" "=r")
1146 (plus:HI (match_operand:HI 1 "register_operand" "0")
1147 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1149 "add %A0,%2\;adc %B0,__zero_reg__"
1150 [(set_attr "length" "2")
1151 (set_attr "cc" "set_n")])
1153 (define_insn "*addhi3.sign_extend1"
1154 [(set (match_operand:HI 0 "register_operand" "=r")
1155 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1156 (match_operand:HI 2 "register_operand" "0")))]
1159 return reg_overlap_mentioned_p (operands[0], operands[1])
1160 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1161 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1163 [(set_attr "length" "5")
1164 (set_attr "cc" "clobber")])
1166 (define_insn "*addhi3_sp"
1167 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1168 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1169 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1172 return avr_out_addto_sp (operands, NULL);
1174 [(set_attr "length" "6")
1175 (set_attr "adjust_len" "addto_sp")])
1178 ;; "*addhq3" "*adduhq3"
1179 ;; "*addha3" "*adduha3"
1180 (define_insn "*add<mode>3"
1181 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1182 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1183 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1186 return avr_out_plus (insn, operands);
1188 [(set_attr "length" "2")
1189 (set_attr "adjust_len" "plus")
1190 (set_attr "cc" "plus")])
1192 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1193 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1194 ;; itself because that insn is special to reload.
1196 (define_peephole2 ; addhi3_clobber
1197 [(set (match_operand:ALL2 0 "d_register_operand" "")
1198 (match_operand:ALL2 1 "const_operand" ""))
1199 (set (match_operand:ALL2 2 "l_register_operand" "")
1200 (plus:ALL2 (match_dup 2)
1202 "peep2_reg_dead_p (2, operands[0])"
1203 [(parallel [(set (match_dup 2)
1204 (plus:ALL2 (match_dup 2)
1206 (clobber (match_dup 3))])]
1208 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1211 ;; Same, but with reload to NO_LD_REGS
1212 ;; Combine *reload_inhi with *addhi3
1214 (define_peephole2 ; addhi3_clobber
1215 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1216 (match_operand:ALL2 1 "const_operand" ""))
1217 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1218 (set (match_operand:ALL2 3 "l_register_operand" "")
1219 (plus:ALL2 (match_dup 3)
1221 "peep2_reg_dead_p (2, operands[0])"
1222 [(parallel [(set (match_dup 3)
1223 (plus:ALL2 (match_dup 3)
1225 (clobber (match_dup 2))])])
1228 ;; "addhq3_clobber" "adduhq3_clobber"
1229 ;; "addha3_clobber" "adduha3_clobber"
1230 (define_insn "add<mode>3_clobber"
1231 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1232 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1233 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1234 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1237 return avr_out_plus (insn, operands);
1239 [(set_attr "length" "4")
1240 (set_attr "adjust_len" "plus")
1241 (set_attr "cc" "plus")])
1245 ;; "addsq3" "addusq3"
1246 ;; "addsa3" "addusa3"
1247 (define_insn "add<mode>3"
1248 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1249 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1250 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1251 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1254 return avr_out_plus (insn, operands);
1256 [(set_attr "length" "4")
1257 (set_attr "adjust_len" "plus")
1258 (set_attr "cc" "plus")])
1260 (define_insn "*addpsi3_zero_extend.qi"
1261 [(set (match_operand:PSI 0 "register_operand" "=r")
1262 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1263 (match_operand:PSI 2 "register_operand" "0")))]
1265 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1266 [(set_attr "length" "3")
1267 (set_attr "cc" "set_n")])
1269 (define_insn "*addpsi3_zero_extend.hi"
1270 [(set (match_operand:PSI 0 "register_operand" "=r")
1271 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1272 (match_operand:PSI 2 "register_operand" "0")))]
1274 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1275 [(set_attr "length" "3")
1276 (set_attr "cc" "set_n")])
1278 (define_insn "*addpsi3_sign_extend.hi"
1279 [(set (match_operand:PSI 0 "register_operand" "=r")
1280 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1281 (match_operand:PSI 2 "register_operand" "0")))]
1283 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1284 [(set_attr "length" "5")
1285 (set_attr "cc" "set_n")])
1287 (define_insn "*addsi3_zero_extend"
1288 [(set (match_operand:SI 0 "register_operand" "=r")
1289 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1290 (match_operand:SI 2 "register_operand" "0")))]
1292 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1293 [(set_attr "length" "4")
1294 (set_attr "cc" "set_n")])
1296 (define_insn "*addsi3_zero_extend.hi"
1297 [(set (match_operand:SI 0 "register_operand" "=r")
1298 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1299 (match_operand:SI 2 "register_operand" "0")))]
1301 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1302 [(set_attr "length" "4")
1303 (set_attr "cc" "set_n")])
1305 (define_insn "addpsi3"
1306 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1307 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1308 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1309 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1312 return avr_out_plus (insn, operands);
1314 [(set_attr "length" "3")
1315 (set_attr "adjust_len" "plus")
1316 (set_attr "cc" "plus")])
1318 (define_insn "subpsi3"
1319 [(set (match_operand:PSI 0 "register_operand" "=r")
1320 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1321 (match_operand:PSI 2 "register_operand" "r")))]
1323 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1324 [(set_attr "length" "3")
1325 (set_attr "cc" "set_czn")])
1327 (define_insn "*subpsi3_zero_extend.qi"
1328 [(set (match_operand:PSI 0 "register_operand" "=r")
1329 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1330 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1332 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1333 [(set_attr "length" "3")
1334 (set_attr "cc" "set_czn")])
1336 (define_insn "*subpsi3_zero_extend.hi"
1337 [(set (match_operand:PSI 0 "register_operand" "=r")
1338 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1339 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1341 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1342 [(set_attr "length" "3")
1343 (set_attr "cc" "set_czn")])
1345 (define_insn "*subpsi3_sign_extend.hi"
1346 [(set (match_operand:PSI 0 "register_operand" "=r")
1347 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1348 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1350 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1351 [(set_attr "length" "5")
1352 (set_attr "cc" "set_czn")])
1354 ;-----------------------------------------------------------------------------
1358 ;; "subqq3" "subuqq3"
1359 (define_insn "sub<mode>3"
1360 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1361 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1362 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1371 [(set_attr "length" "1,1,1,1,2,2")
1372 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1375 ;; "subhq3" "subuhq3"
1376 ;; "subha3" "subuha3"
1377 (define_insn "sub<mode>3"
1378 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1379 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1380 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1381 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1384 return avr_out_plus (insn, operands);
1386 [(set_attr "adjust_len" "plus")
1387 (set_attr "cc" "plus")])
1389 (define_insn "*subhi3_zero_extend1"
1390 [(set (match_operand:HI 0 "register_operand" "=r")
1391 (minus:HI (match_operand:HI 1 "register_operand" "0")
1392 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1394 "sub %A0,%2\;sbc %B0,__zero_reg__"
1395 [(set_attr "length" "2")
1396 (set_attr "cc" "set_czn")])
1398 (define_insn "*subhi3.sign_extend2"
1399 [(set (match_operand:HI 0 "register_operand" "=r")
1400 (minus:HI (match_operand:HI 1 "register_operand" "0")
1401 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1404 return reg_overlap_mentioned_p (operands[0], operands[2])
1405 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1406 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1408 [(set_attr "length" "5")
1409 (set_attr "cc" "clobber")])
1412 ;; "subsq3" "subusq3"
1413 ;; "subsa3" "subusa3"
1414 (define_insn "sub<mode>3"
1415 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1416 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1417 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1418 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1421 return avr_out_plus (insn, operands);
1423 [(set_attr "adjust_len" "plus")
1424 (set_attr "cc" "plus")])
1426 (define_insn "*subsi3_zero_extend"
1427 [(set (match_operand:SI 0 "register_operand" "=r")
1428 (minus:SI (match_operand:SI 1 "register_operand" "0")
1429 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1431 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1432 [(set_attr "length" "4")
1433 (set_attr "cc" "set_czn")])
1435 (define_insn "*subsi3_zero_extend.hi"
1436 [(set (match_operand:SI 0 "register_operand" "=r")
1437 (minus:SI (match_operand:SI 1 "register_operand" "0")
1438 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1440 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1441 [(set_attr "length" "4")
1442 (set_attr "cc" "set_czn")])
1444 ;******************************************************************************
1447 (define_expand "mulqi3"
1448 [(set (match_operand:QI 0 "register_operand" "")
1449 (mult:QI (match_operand:QI 1 "register_operand" "")
1450 (match_operand:QI 2 "register_operand" "")))]
1455 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1460 (define_insn "*mulqi3_enh"
1461 [(set (match_operand:QI 0 "register_operand" "=r")
1462 (mult:QI (match_operand:QI 1 "register_operand" "r")
1463 (match_operand:QI 2 "register_operand" "r")))]
1468 [(set_attr "length" "3")
1469 (set_attr "cc" "clobber")])
1471 (define_expand "mulqi3_call"
1472 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1473 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1474 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1475 (clobber (reg:QI 22))])
1476 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
1478 (define_insn "*mulqi3_call"
1479 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1480 (clobber (reg:QI 22))]
1483 [(set_attr "type" "xcall")
1484 (set_attr "cc" "clobber")])
1486 ;; "umulqi3_highpart"
1487 ;; "smulqi3_highpart"
1488 (define_insn "<extend_su>mulqi3_highpart"
1489 [(set (match_operand:QI 0 "register_operand" "=r")
1491 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1492 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1495 "mul<extend_s> %1,%2
1498 [(set_attr "length" "3")
1499 (set_attr "cc" "clobber")])
1502 ;; Used when expanding div or mod inline for some special values
1503 (define_insn "*subqi3.ashiftrt7"
1504 [(set (match_operand:QI 0 "register_operand" "=r")
1505 (minus:QI (match_operand:QI 1 "register_operand" "0")
1506 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1510 [(set_attr "length" "2")
1511 (set_attr "cc" "clobber")])
1513 (define_insn "*addqi3.lt0"
1514 [(set (match_operand:QI 0 "register_operand" "=r")
1515 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1517 (match_operand:QI 2 "register_operand" "0")))]
1520 [(set_attr "length" "2")
1521 (set_attr "cc" "clobber")])
1523 (define_insn "*addhi3.lt0"
1524 [(set (match_operand:HI 0 "register_operand" "=w,r")
1525 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1527 (match_operand:HI 2 "register_operand" "0,0")))
1528 (clobber (match_scratch:QI 3 "=X,&1"))]
1531 sbrc %1,7\;adiw %0,1
1532 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1533 [(set_attr "length" "2,3")
1534 (set_attr "cc" "clobber")])
1536 (define_insn "*addpsi3.lt0"
1537 [(set (match_operand:PSI 0 "register_operand" "=r")
1538 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1540 (match_operand:PSI 2 "register_operand" "0")))]
1542 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1543 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1544 [(set_attr "length" "5")
1545 (set_attr "cc" "clobber")])
1547 (define_insn "*addsi3.lt0"
1548 [(set (match_operand:SI 0 "register_operand" "=r")
1549 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1551 (match_operand:SI 2 "register_operand" "0")))]
1553 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1554 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1555 [(set_attr "length" "6")
1556 (set_attr "cc" "clobber")])
1558 (define_insn "*umulqihi3.call"
1560 (mult:HI (zero_extend:HI (reg:QI 22))
1561 (zero_extend:HI (reg:QI 24))))
1562 (clobber (reg:QI 21))
1563 (clobber (reg:HI 22))]
1565 "%~call __umulqihi3"
1566 [(set_attr "type" "xcall")
1567 (set_attr "cc" "clobber")])
1571 (define_insn "<extend_u>mulqihi3"
1572 [(set (match_operand:HI 0 "register_operand" "=r")
1573 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1574 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1576 "mul<extend_s> %1,%2
1579 [(set_attr "length" "3")
1580 (set_attr "cc" "clobber")])
1582 (define_insn "usmulqihi3"
1583 [(set (match_operand:HI 0 "register_operand" "=r")
1584 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1585 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1590 [(set_attr "length" "3")
1591 (set_attr "cc" "clobber")])
1593 ;; Above insn is not canonicalized by insn combine, so here is a version with
1594 ;; operands swapped.
1596 (define_insn "*sumulqihi3"
1597 [(set (match_operand:HI 0 "register_operand" "=r")
1598 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1599 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1604 [(set_attr "length" "3")
1605 (set_attr "cc" "clobber")])
1607 ;; One-extend operand 1
1609 (define_insn "*osmulqihi3"
1610 [(set (match_operand:HI 0 "register_operand" "=&r")
1611 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1612 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1618 [(set_attr "length" "4")
1619 (set_attr "cc" "clobber")])
1621 (define_insn "*oumulqihi3"
1622 [(set (match_operand:HI 0 "register_operand" "=&r")
1623 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1624 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1630 [(set_attr "length" "4")
1631 (set_attr "cc" "clobber")])
1633 ;******************************************************************************
1634 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1635 ;******************************************************************************
1637 (define_insn "*maddqi4"
1638 [(set (match_operand:QI 0 "register_operand" "=r")
1639 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1640 (match_operand:QI 2 "register_operand" "r"))
1641 (match_operand:QI 3 "register_operand" "0")))]
1647 [(set_attr "length" "4")
1648 (set_attr "cc" "clobber")])
1650 (define_insn "*msubqi4"
1651 [(set (match_operand:QI 0 "register_operand" "=r")
1652 (minus:QI (match_operand:QI 3 "register_operand" "0")
1653 (mult:QI (match_operand:QI 1 "register_operand" "r")
1654 (match_operand:QI 2 "register_operand" "r"))))]
1659 [(set_attr "length" "4")
1660 (set_attr "cc" "clobber")])
1662 (define_insn_and_split "*maddqi4.const"
1663 [(set (match_operand:QI 0 "register_operand" "=r")
1664 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1665 (match_operand:QI 2 "const_int_operand" "n"))
1666 (match_operand:QI 3 "register_operand" "0")))
1667 (clobber (match_scratch:QI 4 "=&d"))]
1670 "&& reload_completed"
1675 (plus:QI (mult:QI (match_dup 1)
1679 (define_insn_and_split "*msubqi4.const"
1680 [(set (match_operand:QI 0 "register_operand" "=r")
1681 (minus:QI (match_operand:QI 3 "register_operand" "0")
1682 (mult:QI (match_operand:QI 1 "register_operand" "r")
1683 (match_operand:QI 2 "const_int_operand" "n"))))
1684 (clobber (match_scratch:QI 4 "=&d"))]
1687 "&& reload_completed"
1692 (minus:QI (match_dup 3)
1693 (mult:QI (match_dup 1)
1697 ;******************************************************************************
1698 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1699 ;******************************************************************************
1701 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1704 ;; int foo (unsigned char z)
1706 ;; extern int aInt[];
1707 ;; return aInt[3*z+2];
1710 ;; because the constant +4 then is added explicitely instead of consuming it
1711 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1712 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1713 ;; The implementational effort is the same so we are fine with that approach.
1718 (define_insn "*<extend_u>maddqihi4"
1719 [(set (match_operand:HI 0 "register_operand" "=r")
1720 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1721 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1722 (match_operand:HI 3 "register_operand" "0")))]
1725 "mul<extend_s> %1,%2
1729 [(set_attr "length" "4")
1730 (set_attr "cc" "clobber")])
1734 (define_insn "*<extend_u>msubqihi4"
1735 [(set (match_operand:HI 0 "register_operand" "=r")
1736 (minus:HI (match_operand:HI 3 "register_operand" "0")
1737 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1738 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1740 "mul<extend_s> %1,%2
1744 [(set_attr "length" "4")
1745 (set_attr "cc" "clobber")])
1749 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1750 [(set (match_operand:HI 0 "register_operand" "=r")
1751 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1752 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1753 (match_operand:HI 3 "register_operand" "0")))]
1756 && <any_extend:CODE> != <any_extend2:CODE>"
1758 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1759 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1761 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1763 [(set_attr "length" "4")
1764 (set_attr "cc" "clobber")])
1768 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1769 [(set (match_operand:HI 0 "register_operand" "=r")
1770 (minus:HI (match_operand:HI 3 "register_operand" "0")
1771 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1772 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1775 && <any_extend:CODE> != <any_extend2:CODE>"
1777 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1778 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1780 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1782 [(set_attr "length" "4")
1783 (set_attr "cc" "clobber")])
1785 ;; Handle small constants
1787 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1788 ;; This is shorter, faster than MUL and has lower register pressure.
1790 (define_insn_and_split "*umaddqihi4.2"
1791 [(set (match_operand:HI 0 "register_operand" "=r")
1792 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1794 (match_operand:HI 2 "register_operand" "r")))]
1796 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1797 { gcc_unreachable(); }
1801 ; *addhi3_zero_extend
1803 (plus:HI (zero_extend:HI (match_dup 1))
1805 ; *addhi3_zero_extend
1807 (plus:HI (zero_extend:HI (match_dup 1))
1810 ;; "umaddqihi4.uconst"
1811 ;; "maddqihi4.sconst"
1812 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1813 [(set (match_operand:HI 0 "register_operand" "=r")
1814 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1815 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1816 (match_operand:HI 3 "register_operand" "0")))
1817 (clobber (match_scratch:QI 4 "=&d"))]
1820 "&& reload_completed"
1823 ; *umaddqihi4 resp. *maddqihi4
1825 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1826 (any_extend:HI (match_dup 4)))
1829 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1832 ;; "*umsubqihi4.uconst"
1833 ;; "*msubqihi4.sconst"
1834 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1835 [(set (match_operand:HI 0 "register_operand" "=r")
1836 (minus:HI (match_operand:HI 3 "register_operand" "0")
1837 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1838 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1839 (clobber (match_scratch:QI 4 "=&d"))]
1842 "&& reload_completed"
1845 ; *umsubqihi4 resp. *msubqihi4
1847 (minus:HI (match_dup 3)
1848 (mult:HI (any_extend:HI (match_dup 1))
1849 (any_extend:HI (match_dup 4)))))]
1851 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1854 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1855 ;; for MULT with power of 2 and skips trying MULT insn above.
1857 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1858 [(set (match_operand:HI 0 "register_operand" "=r")
1859 (minus:HI (match_operand:HI 3 "register_operand" "0")
1860 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1861 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1862 (clobber (match_scratch:QI 4 "=&d"))]
1865 "&& reload_completed"
1870 (minus:HI (match_dup 3)
1871 (mult:HI (zero_extend:HI (match_dup 1))
1872 (zero_extend:HI (match_dup 4)))))]
1874 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1877 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1878 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1879 ;; because this would require an extra pattern for just one value.
1881 (define_insn_and_split "*msubqihi4.sconst.ashift"
1882 [(set (match_operand:HI 0 "register_operand" "=r")
1883 (minus:HI (match_operand:HI 3 "register_operand" "0")
1884 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1885 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1886 (clobber (match_scratch:QI 4 "=&d"))]
1889 "&& reload_completed"
1894 (minus:HI (match_dup 3)
1895 (mult:HI (sign_extend:HI (match_dup 1))
1896 (sign_extend:HI (match_dup 4)))))]
1898 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1901 ;; For signed/unsigned combinations that require narrow constraint "a"
1902 ;; just provide a pattern if signed/unsigned combination is actually needed.
1904 (define_insn_and_split "*sumaddqihi4.uconst"
1905 [(set (match_operand:HI 0 "register_operand" "=r")
1906 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1907 (match_operand:HI 2 "u8_operand" "M"))
1908 (match_operand:HI 3 "register_operand" "0")))
1909 (clobber (match_scratch:QI 4 "=&a"))]
1911 && !s8_operand (operands[2], VOIDmode)"
1913 "&& reload_completed"
1918 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1919 (zero_extend:HI (match_dup 4)))
1922 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1925 (define_insn_and_split "*sumsubqihi4.uconst"
1926 [(set (match_operand:HI 0 "register_operand" "=r")
1927 (minus:HI (match_operand:HI 3 "register_operand" "0")
1928 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1929 (match_operand:HI 2 "u8_operand" "M"))))
1930 (clobber (match_scratch:QI 4 "=&a"))]
1932 && !s8_operand (operands[2], VOIDmode)"
1934 "&& reload_completed"
1939 (minus:HI (match_dup 3)
1940 (mult:HI (sign_extend:HI (match_dup 1))
1941 (zero_extend:HI (match_dup 4)))))]
1943 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1946 ;******************************************************************************
1947 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1948 ;******************************************************************************
1950 ;; "*muluqihi3.uconst"
1951 ;; "*mulsqihi3.sconst"
1952 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1953 [(set (match_operand:HI 0 "register_operand" "=r")
1954 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1955 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1956 (clobber (match_scratch:QI 3 "=&d"))]
1959 "&& reload_completed"
1962 ; umulqihi3 resp. mulqihi3
1964 (mult:HI (any_extend:HI (match_dup 1))
1965 (any_extend:HI (match_dup 3))))]
1967 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1970 (define_insn_and_split "*muluqihi3.sconst"
1971 [(set (match_operand:HI 0 "register_operand" "=r")
1972 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1973 (match_operand:HI 2 "s8_operand" "n")))
1974 (clobber (match_scratch:QI 3 "=&a"))]
1977 "&& reload_completed"
1982 (mult:HI (zero_extend:HI (match_dup 1))
1983 (sign_extend:HI (match_dup 3))))]
1985 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1988 (define_insn_and_split "*mulsqihi3.uconst"
1989 [(set (match_operand:HI 0 "register_operand" "=r")
1990 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1991 (match_operand:HI 2 "u8_operand" "M")))
1992 (clobber (match_scratch:QI 3 "=&a"))]
1995 "&& reload_completed"
2000 (mult:HI (zero_extend:HI (match_dup 3))
2001 (sign_extend:HI (match_dup 1))))]
2003 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2006 (define_insn_and_split "*mulsqihi3.oconst"
2007 [(set (match_operand:HI 0 "register_operand" "=&r")
2008 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2009 (match_operand:HI 2 "o8_operand" "n")))
2010 (clobber (match_scratch:QI 3 "=&a"))]
2013 "&& reload_completed"
2018 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2019 (sign_extend:HI (match_dup 1))))]
2021 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2024 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2025 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2026 ;; at that time. Fix that.
2028 (define_insn "*ashiftqihi2.signx.1"
2029 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2030 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2034 lsl %A0\;sbc %B0,%B0
2035 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2036 [(set_attr "length" "2,3")
2037 (set_attr "cc" "clobber")])
2039 (define_insn_and_split "*ashifthi3.signx.const"
2040 [(set (match_operand:HI 0 "register_operand" "=r")
2041 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2042 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2043 (clobber (match_scratch:QI 3 "=&d"))]
2046 "&& reload_completed"
2051 (mult:HI (sign_extend:HI (match_dup 1))
2052 (sign_extend:HI (match_dup 3))))]
2054 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2057 (define_insn_and_split "*ashifthi3.signx.const7"
2058 [(set (match_operand:HI 0 "register_operand" "=r")
2059 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2061 (clobber (match_scratch:QI 2 "=&a"))]
2064 "&& reload_completed"
2069 (mult:HI (zero_extend:HI (match_dup 2))
2070 (sign_extend:HI (match_dup 1))))]
2072 operands[3] = gen_int_mode (1 << 7, QImode);
2075 (define_insn_and_split "*ashifthi3.zerox.const"
2076 [(set (match_operand:HI 0 "register_operand" "=r")
2077 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2078 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2079 (clobber (match_scratch:QI 3 "=&d"))]
2082 "&& reload_completed"
2087 (mult:HI (zero_extend:HI (match_dup 1))
2088 (zero_extend:HI (match_dup 3))))]
2090 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2093 ;******************************************************************************
2094 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2095 ;******************************************************************************
2097 (define_insn "mulsqihi3"
2098 [(set (match_operand:HI 0 "register_operand" "=&r")
2099 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2100 (match_operand:HI 2 "register_operand" "a")))]
2107 [(set_attr "length" "5")
2108 (set_attr "cc" "clobber")])
2110 (define_insn "muluqihi3"
2111 [(set (match_operand:HI 0 "register_operand" "=&r")
2112 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2113 (match_operand:HI 2 "register_operand" "r")))]
2120 [(set_attr "length" "5")
2121 (set_attr "cc" "clobber")])
2123 ;; one-extend operand 1
2125 (define_insn "muloqihi3"
2126 [(set (match_operand:HI 0 "register_operand" "=&r")
2127 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2128 (match_operand:HI 2 "register_operand" "r")))]
2136 [(set_attr "length" "6")
2137 (set_attr "cc" "clobber")])
2139 ;******************************************************************************
2141 (define_expand "mulhi3"
2142 [(set (match_operand:HI 0 "register_operand" "")
2143 (mult:HI (match_operand:HI 1 "register_operand" "")
2144 (match_operand:HI 2 "register_or_s9_operand" "")))]
2149 if (!register_operand (operands[2], HImode))
2150 operands[2] = force_reg (HImode, operands[2]);
2152 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2156 /* For small constants we can do better by extending them on the fly.
2157 The constant can be loaded in one instruction and the widening
2158 multiplication is shorter. First try the unsigned variant because it
2159 allows constraint "d" instead of "a" for the signed version. */
2161 if (s9_operand (operands[2], HImode))
2163 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2165 if (u8_operand (operands[2], HImode))
2167 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2169 else if (s8_operand (operands[2], HImode))
2171 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2175 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2181 if (!register_operand (operands[2], HImode))
2182 operands[2] = force_reg (HImode, operands[2]);
2185 (define_insn "*mulhi3_enh"
2186 [(set (match_operand:HI 0 "register_operand" "=&r")
2187 (mult:HI (match_operand:HI 1 "register_operand" "r")
2188 (match_operand:HI 2 "register_operand" "r")))]
2191 return REGNO (operands[1]) == REGNO (operands[2])
2192 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2193 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2195 [(set_attr "length" "7")
2196 (set_attr "cc" "clobber")])
2198 (define_expand "mulhi3_call"
2199 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2200 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2201 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2202 (clobber (reg:HI 22))
2203 (clobber (reg:QI 21))])
2204 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
2206 (define_insn "*mulhi3_call"
2207 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2208 (clobber (reg:HI 22))
2209 (clobber (reg:QI 21))]
2212 [(set_attr "type" "xcall")
2213 (set_attr "cc" "clobber")])
2215 ;; To support widening multiplication with constant we postpone
2216 ;; expanding to the implicit library call until post combine and
2217 ;; prior to register allocation. Clobber all hard registers that
2218 ;; might be used by the (widening) multiply until it is split and
2219 ;; it's final register footprint is worked out.
2221 (define_expand "mulsi3"
2222 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2223 (mult:SI (match_operand:SI 1 "register_operand" "")
2224 (match_operand:SI 2 "nonmemory_operand" "")))
2225 (clobber (reg:HI 26))
2226 (clobber (reg:DI 18))])]
2229 if (u16_operand (operands[2], SImode))
2231 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2232 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2236 if (o16_operand (operands[2], SImode))
2238 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2239 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2244 (define_insn_and_split "*mulsi3"
2245 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2246 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2247 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2248 (clobber (reg:HI 26))
2249 (clobber (reg:DI 18))]
2250 "AVR_HAVE_MUL && !reload_completed"
2251 { gcc_unreachable(); }
2257 (parallel [(set (reg:SI 22)
2258 (mult:SI (reg:SI 22)
2260 (clobber (reg:HI 26))])
2264 if (u16_operand (operands[2], SImode))
2266 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2267 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2271 if (o16_operand (operands[2], SImode))
2273 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2274 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2281 (define_insn_and_split "mulu<mode>si3"
2282 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2283 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2284 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2285 (clobber (reg:HI 26))
2286 (clobber (reg:DI 18))]
2287 "AVR_HAVE_MUL && !reload_completed"
2288 { gcc_unreachable(); }
2295 (mult:SI (zero_extend:SI (reg:HI 26))
2300 /* Do the QI -> HI extension explicitely before the multiplication. */
2301 /* Do the HI -> SI extension implicitely and after the multiplication. */
2303 if (QImode == <MODE>mode)
2304 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2306 if (u16_operand (operands[2], SImode))
2308 operands[1] = force_reg (HImode, operands[1]);
2309 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2310 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2317 (define_insn_and_split "muls<mode>si3"
2318 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2319 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2320 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2321 (clobber (reg:HI 26))
2322 (clobber (reg:DI 18))]
2323 "AVR_HAVE_MUL && !reload_completed"
2324 { gcc_unreachable(); }
2331 (mult:SI (sign_extend:SI (reg:HI 26))
2336 /* Do the QI -> HI extension explicitely before the multiplication. */
2337 /* Do the HI -> SI extension implicitely and after the multiplication. */
2339 if (QImode == <MODE>mode)
2340 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2342 if (u16_operand (operands[2], SImode)
2343 || s16_operand (operands[2], SImode))
2345 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2347 operands[1] = force_reg (HImode, operands[1]);
2349 if (u16_operand (operands[2], SImode))
2350 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2352 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2358 ;; One-extend operand 1
2360 (define_insn_and_split "mulohisi3"
2361 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2362 (mult:SI (not:SI (zero_extend:SI
2363 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2364 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2365 (clobber (reg:HI 26))
2366 (clobber (reg:DI 18))]
2367 "AVR_HAVE_MUL && !reload_completed"
2368 { gcc_unreachable(); }
2375 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2382 (define_expand "<extend_u>mulhisi3"
2383 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2384 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2385 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2386 (clobber (reg:HI 26))
2387 (clobber (reg:DI 18))])]
2390 (define_expand "usmulhisi3"
2391 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2392 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2393 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2394 (clobber (reg:HI 26))
2395 (clobber (reg:DI 18))])]
2398 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2399 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2400 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2401 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2402 (define_insn_and_split
2403 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2404 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2405 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2406 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2407 (clobber (reg:HI 26))
2408 (clobber (reg:DI 18))]
2409 "AVR_HAVE_MUL && !reload_completed"
2410 { gcc_unreachable(); }
2417 (mult:SI (match_dup 3)
2422 rtx xop1 = operands[1];
2423 rtx xop2 = operands[2];
2425 /* Do the QI -> HI extension explicitely before the multiplication. */
2426 /* Do the HI -> SI extension implicitely and after the multiplication. */
2428 if (QImode == <QIHI:MODE>mode)
2429 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2431 if (QImode == <QIHI2:MODE>mode)
2432 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2434 if (<any_extend:CODE> == <any_extend2:CODE>
2435 || <any_extend:CODE> == ZERO_EXTEND)
2439 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2440 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2444 /* <any_extend:CODE> = SIGN_EXTEND */
2445 /* <any_extend2:CODE> = ZERO_EXTEND */
2449 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2450 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2454 ;; "smulhi3_highpart"
2455 ;; "umulhi3_highpart"
2456 (define_expand "<extend_su>mulhi3_highpart"
2458 (match_operand:HI 1 "nonmemory_operand" ""))
2460 (match_operand:HI 2 "nonmemory_operand" ""))
2461 (parallel [(set (reg:HI 24)
2462 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2463 (any_extend:SI (reg:HI 26)))
2465 (clobber (reg:HI 22))])
2466 (set (match_operand:HI 0 "register_operand" "")
2471 (define_insn "*mulsi3_call"
2473 (mult:SI (reg:SI 22)
2475 (clobber (reg:HI 26))]
2478 [(set_attr "type" "xcall")
2479 (set_attr "cc" "clobber")])
2482 ;; "*umulhisi3_call"
2483 (define_insn "*<extend_u>mulhisi3_call"
2485 (mult:SI (any_extend:SI (reg:HI 18))
2486 (any_extend:SI (reg:HI 26))))]
2488 "%~call __<extend_u>mulhisi3"
2489 [(set_attr "type" "xcall")
2490 (set_attr "cc" "clobber")])
2492 ;; "*umulhi3_highpart_call"
2493 ;; "*smulhi3_highpart_call"
2494 (define_insn "*<extend_su>mulhi3_highpart_call"
2496 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2497 (any_extend:SI (reg:HI 26)))
2499 (clobber (reg:HI 22))]
2501 "%~call __<extend_u>mulhisi3"
2502 [(set_attr "type" "xcall")
2503 (set_attr "cc" "clobber")])
2505 (define_insn "*usmulhisi3_call"
2507 (mult:SI (zero_extend:SI (reg:HI 18))
2508 (sign_extend:SI (reg:HI 26))))]
2510 "%~call __usmulhisi3"
2511 [(set_attr "type" "xcall")
2512 (set_attr "cc" "clobber")])
2514 (define_insn "*mul<extend_su>hisi3_call"
2516 (mult:SI (any_extend:SI (reg:HI 26))
2519 "%~call __mul<extend_su>hisi3"
2520 [(set_attr "type" "xcall")
2521 (set_attr "cc" "clobber")])
2523 (define_insn "*mulohisi3_call"
2525 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2528 "%~call __mulohisi3"
2529 [(set_attr "type" "xcall")
2530 (set_attr "cc" "clobber")])
2532 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2535 ;; Generate lib1funcs.S calls ourselves, because:
2536 ;; - we know exactly which registers are clobbered (for QI and HI
2537 ;; modes, some of the call-used registers are preserved)
2538 ;; - we get both the quotient and the remainder at no extra cost
2539 ;; - we split the patterns only after the first CSE passes because
2540 ;; CSE has problems to operate on hard regs.
2542 (define_insn_and_split "divmodqi4"
2543 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2544 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2545 (match_operand:QI 2 "pseudo_register_operand" "")))
2546 (set (match_operand:QI 3 "pseudo_register_operand" "")
2547 (mod:QI (match_dup 1) (match_dup 2)))
2548 (clobber (reg:QI 22))
2549 (clobber (reg:QI 23))
2550 (clobber (reg:QI 24))
2551 (clobber (reg:QI 25))])]
2553 "this divmodqi4 pattern should have been splitted;"
2555 [(set (reg:QI 24) (match_dup 1))
2556 (set (reg:QI 22) (match_dup 2))
2557 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2558 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2559 (clobber (reg:QI 22))
2560 (clobber (reg:QI 23))])
2561 (set (match_dup 0) (reg:QI 24))
2562 (set (match_dup 3) (reg:QI 25))])
2564 (define_insn "*divmodqi4_call"
2565 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2566 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2567 (clobber (reg:QI 22))
2568 (clobber (reg:QI 23))]
2570 "%~call __divmodqi4"
2571 [(set_attr "type" "xcall")
2572 (set_attr "cc" "clobber")])
2574 (define_insn_and_split "udivmodqi4"
2575 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2576 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2577 (match_operand:QI 2 "pseudo_register_operand" "")))
2578 (set (match_operand:QI 3 "pseudo_register_operand" "")
2579 (umod:QI (match_dup 1) (match_dup 2)))
2580 (clobber (reg:QI 22))
2581 (clobber (reg:QI 23))
2582 (clobber (reg:QI 24))
2583 (clobber (reg:QI 25))])]
2585 "this udivmodqi4 pattern should have been splitted;"
2587 [(set (reg:QI 24) (match_dup 1))
2588 (set (reg:QI 22) (match_dup 2))
2589 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2590 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2591 (clobber (reg:QI 23))])
2592 (set (match_dup 0) (reg:QI 24))
2593 (set (match_dup 3) (reg:QI 25))])
2595 (define_insn "*udivmodqi4_call"
2596 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2597 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2598 (clobber (reg:QI 23))]
2600 "%~call __udivmodqi4"
2601 [(set_attr "type" "xcall")
2602 (set_attr "cc" "clobber")])
2604 (define_insn_and_split "divmodhi4"
2605 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2606 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2607 (match_operand:HI 2 "pseudo_register_operand" "")))
2608 (set (match_operand:HI 3 "pseudo_register_operand" "")
2609 (mod:HI (match_dup 1) (match_dup 2)))
2610 (clobber (reg:QI 21))
2611 (clobber (reg:HI 22))
2612 (clobber (reg:HI 24))
2613 (clobber (reg:HI 26))])]
2615 "this should have been splitted;"
2617 [(set (reg:HI 24) (match_dup 1))
2618 (set (reg:HI 22) (match_dup 2))
2619 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2620 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2621 (clobber (reg:HI 26))
2622 (clobber (reg:QI 21))])
2623 (set (match_dup 0) (reg:HI 22))
2624 (set (match_dup 3) (reg:HI 24))])
2626 (define_insn "*divmodhi4_call"
2627 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2628 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2629 (clobber (reg:HI 26))
2630 (clobber (reg:QI 21))]
2632 "%~call __divmodhi4"
2633 [(set_attr "type" "xcall")
2634 (set_attr "cc" "clobber")])
2636 (define_insn_and_split "udivmodhi4"
2637 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2638 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2639 (match_operand:HI 2 "pseudo_register_operand" "")))
2640 (set (match_operand:HI 3 "pseudo_register_operand" "")
2641 (umod:HI (match_dup 1) (match_dup 2)))
2642 (clobber (reg:QI 21))
2643 (clobber (reg:HI 22))
2644 (clobber (reg:HI 24))
2645 (clobber (reg:HI 26))])]
2647 "this udivmodhi4 pattern should have been splitted.;"
2649 [(set (reg:HI 24) (match_dup 1))
2650 (set (reg:HI 22) (match_dup 2))
2651 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2652 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2653 (clobber (reg:HI 26))
2654 (clobber (reg:QI 21))])
2655 (set (match_dup 0) (reg:HI 22))
2656 (set (match_dup 3) (reg:HI 24))])
2658 (define_insn "*udivmodhi4_call"
2659 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2660 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2661 (clobber (reg:HI 26))
2662 (clobber (reg:QI 21))]
2664 "%~call __udivmodhi4"
2665 [(set_attr "type" "xcall")
2666 (set_attr "cc" "clobber")])
2668 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2671 ;; To support widening multiplication with constant we postpone
2672 ;; expanding to the implicit library call until post combine and
2673 ;; prior to register allocation. Clobber all hard registers that
2674 ;; might be used by the (widening) multiply until it is split and
2675 ;; it's final register footprint is worked out.
2677 (define_expand "mulpsi3"
2678 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2679 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2680 (match_operand:PSI 2 "nonmemory_operand" "")))
2681 (clobber (reg:HI 26))
2682 (clobber (reg:DI 18))])]
2685 if (s8_operand (operands[2], PSImode))
2687 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2688 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2693 (define_insn "*umulqihipsi3"
2694 [(set (match_operand:PSI 0 "register_operand" "=&r")
2695 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2696 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2705 [(set_attr "length" "7")
2706 (set_attr "cc" "clobber")])
2708 (define_insn "*umulhiqipsi3"
2709 [(set (match_operand:PSI 0 "register_operand" "=&r")
2710 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2711 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2719 adc %C0,__zero_reg__"
2720 [(set_attr "length" "7")
2721 (set_attr "cc" "clobber")])
2723 (define_insn_and_split "mulsqipsi3"
2724 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2725 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2726 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2727 (clobber (reg:HI 26))
2728 (clobber (reg:DI 18))]
2729 "AVR_HAVE_MUL && !reload_completed"
2730 { gcc_unreachable(); }
2737 (mult:PSI (sign_extend:PSI (reg:QI 25))
2742 (define_insn_and_split "*mulpsi3"
2743 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2744 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2745 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2746 (clobber (reg:HI 26))
2747 (clobber (reg:DI 18))]
2748 "AVR_HAVE_MUL && !reload_completed"
2749 { gcc_unreachable(); }
2755 (parallel [(set (reg:PSI 22)
2756 (mult:PSI (reg:PSI 22)
2758 (clobber (reg:QI 21))
2759 (clobber (reg:QI 25))
2760 (clobber (reg:HI 26))])
2764 if (s8_operand (operands[2], PSImode))
2766 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2767 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2772 (define_insn "*mulsqipsi3.libgcc"
2774 (mult:PSI (sign_extend:PSI (reg:QI 25))
2777 "%~call __mulsqipsi3"
2778 [(set_attr "type" "xcall")
2779 (set_attr "cc" "clobber")])
2781 (define_insn "*mulpsi3.libgcc"
2783 (mult:PSI (reg:PSI 22)
2785 (clobber (reg:QI 21))
2786 (clobber (reg:QI 25))
2787 (clobber (reg:HI 26))]
2790 [(set_attr "type" "xcall")
2791 (set_attr "cc" "clobber")])
2794 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2795 ;; 24-bit signed/unsigned division and modulo.
2796 ;; Notice that the libgcc implementation return the quotient in R22
2797 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2798 ;; implementation works the other way round.
2800 (define_insn_and_split "divmodpsi4"
2801 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2802 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2803 (match_operand:PSI 2 "pseudo_register_operand" "")))
2804 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2805 (mod:PSI (match_dup 1)
2807 (clobber (reg:DI 18))
2808 (clobber (reg:QI 26))])]
2810 { gcc_unreachable(); }
2812 [(set (reg:PSI 22) (match_dup 1))
2813 (set (reg:PSI 18) (match_dup 2))
2814 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2815 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2816 (clobber (reg:QI 21))
2817 (clobber (reg:QI 25))
2818 (clobber (reg:QI 26))])
2819 (set (match_dup 0) (reg:PSI 22))
2820 (set (match_dup 3) (reg:PSI 18))])
2822 (define_insn "*divmodpsi4_call"
2823 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2824 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2825 (clobber (reg:QI 21))
2826 (clobber (reg:QI 25))
2827 (clobber (reg:QI 26))]
2829 "%~call __divmodpsi4"
2830 [(set_attr "type" "xcall")
2831 (set_attr "cc" "clobber")])
2833 (define_insn_and_split "udivmodpsi4"
2834 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2835 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2836 (match_operand:PSI 2 "pseudo_register_operand" "")))
2837 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2838 (umod:PSI (match_dup 1)
2840 (clobber (reg:DI 18))
2841 (clobber (reg:QI 26))])]
2843 { gcc_unreachable(); }
2845 [(set (reg:PSI 22) (match_dup 1))
2846 (set (reg:PSI 18) (match_dup 2))
2847 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2848 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2849 (clobber (reg:QI 21))
2850 (clobber (reg:QI 25))
2851 (clobber (reg:QI 26))])
2852 (set (match_dup 0) (reg:PSI 22))
2853 (set (match_dup 3) (reg:PSI 18))])
2855 (define_insn "*udivmodpsi4_call"
2856 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2857 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2858 (clobber (reg:QI 21))
2859 (clobber (reg:QI 25))
2860 (clobber (reg:QI 26))]
2862 "%~call __udivmodpsi4"
2863 [(set_attr "type" "xcall")
2864 (set_attr "cc" "clobber")])
2866 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2868 (define_insn_and_split "divmodsi4"
2869 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2870 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2871 (match_operand:SI 2 "pseudo_register_operand" "")))
2872 (set (match_operand:SI 3 "pseudo_register_operand" "")
2873 (mod:SI (match_dup 1) (match_dup 2)))
2874 (clobber (reg:SI 18))
2875 (clobber (reg:SI 22))
2876 (clobber (reg:HI 26))
2877 (clobber (reg:HI 30))])]
2879 "this divmodsi4 pattern should have been splitted;"
2881 [(set (reg:SI 22) (match_dup 1))
2882 (set (reg:SI 18) (match_dup 2))
2883 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2884 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2885 (clobber (reg:HI 26))
2886 (clobber (reg:HI 30))])
2887 (set (match_dup 0) (reg:SI 18))
2888 (set (match_dup 3) (reg:SI 22))])
2890 (define_insn "*divmodsi4_call"
2891 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2892 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2893 (clobber (reg:HI 26))
2894 (clobber (reg:HI 30))]
2896 "%~call __divmodsi4"
2897 [(set_attr "type" "xcall")
2898 (set_attr "cc" "clobber")])
2900 (define_insn_and_split "udivmodsi4"
2901 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2902 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2903 (match_operand:SI 2 "pseudo_register_operand" "")))
2904 (set (match_operand:SI 3 "pseudo_register_operand" "")
2905 (umod:SI (match_dup 1) (match_dup 2)))
2906 (clobber (reg:SI 18))
2907 (clobber (reg:SI 22))
2908 (clobber (reg:HI 26))
2909 (clobber (reg:HI 30))])]
2911 "this udivmodsi4 pattern should have been splitted;"
2913 [(set (reg:SI 22) (match_dup 1))
2914 (set (reg:SI 18) (match_dup 2))
2915 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2916 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2917 (clobber (reg:HI 26))
2918 (clobber (reg:HI 30))])
2919 (set (match_dup 0) (reg:SI 18))
2920 (set (match_dup 3) (reg:SI 22))])
2922 (define_insn "*udivmodsi4_call"
2923 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2924 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2925 (clobber (reg:HI 26))
2926 (clobber (reg:HI 30))]
2928 "%~call __udivmodsi4"
2929 [(set_attr "type" "xcall")
2930 (set_attr "cc" "clobber")])
2932 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2935 (define_insn "andqi3"
2936 [(set (match_operand:QI 0 "register_operand" "=??r,d")
2937 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2938 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2943 [(set_attr "length" "1,1")
2944 (set_attr "cc" "set_zn,set_zn")])
2946 (define_insn "andhi3"
2947 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
2948 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2949 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2950 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2953 if (which_alternative == 0)
2954 return "and %A0,%A2\;and %B0,%B2";
2955 else if (which_alternative == 1)
2956 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2958 return avr_out_bitop (insn, operands, NULL);
2960 [(set_attr "length" "2,2,2,4,4")
2961 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2962 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2964 (define_insn "andpsi3"
2965 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
2966 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2967 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2968 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2971 if (which_alternative == 0)
2972 return "and %A0,%A2" CR_TAB
2973 "and %B0,%B2" CR_TAB
2976 return avr_out_bitop (insn, operands, NULL);
2978 [(set_attr "length" "3,3,6,6")
2979 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2980 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2982 (define_insn "andsi3"
2983 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
2984 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2985 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2986 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2989 if (which_alternative == 0)
2990 return "and %0,%2" CR_TAB
2991 "and %B0,%B2" CR_TAB
2992 "and %C0,%C2" CR_TAB
2995 return avr_out_bitop (insn, operands, NULL);
2997 [(set_attr "length" "4,4,8,8")
2998 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2999 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3001 (define_peephole2 ; andi
3002 [(set (match_operand:QI 0 "d_register_operand" "")
3003 (and:QI (match_dup 0)
3004 (match_operand:QI 1 "const_int_operand" "")))
3006 (and:QI (match_dup 0)
3007 (match_operand:QI 2 "const_int_operand" "")))]
3009 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3011 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3014 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3017 (define_insn "iorqi3"
3018 [(set (match_operand:QI 0 "register_operand" "=??r,d")
3019 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3020 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3025 [(set_attr "length" "1,1")
3026 (set_attr "cc" "set_zn,set_zn")])
3028 (define_insn "iorhi3"
3029 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3030 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3031 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3032 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3035 if (which_alternative == 0)
3036 return "or %A0,%A2\;or %B0,%B2";
3037 else if (which_alternative == 1)
3038 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3040 return avr_out_bitop (insn, operands, NULL);
3042 [(set_attr "length" "2,2,2,4,4")
3043 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3044 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3046 (define_insn "iorpsi3"
3047 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3048 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3049 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3050 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3053 if (which_alternative == 0)
3054 return "or %A0,%A2" CR_TAB
3058 return avr_out_bitop (insn, operands, NULL);
3060 [(set_attr "length" "3,3,6,6")
3061 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3062 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3064 (define_insn "iorsi3"
3065 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3066 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3067 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3068 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3071 if (which_alternative == 0)
3072 return "or %0,%2" CR_TAB
3077 return avr_out_bitop (insn, operands, NULL);
3079 [(set_attr "length" "4,4,8,8")
3080 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3081 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3083 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3086 (define_insn "xorqi3"
3087 [(set (match_operand:QI 0 "register_operand" "=r")
3088 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3089 (match_operand:QI 2 "register_operand" "r")))]
3092 [(set_attr "length" "1")
3093 (set_attr "cc" "set_zn")])
3095 (define_insn "xorhi3"
3096 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
3097 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3098 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3099 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3102 if (which_alternative == 0)
3103 return "eor %A0,%A2\;eor %B0,%B2";
3105 return avr_out_bitop (insn, operands, NULL);
3107 [(set_attr "length" "2,2,4")
3108 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3109 (set_attr "cc" "set_n,clobber,clobber")])
3111 (define_insn "xorpsi3"
3112 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
3113 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3114 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3115 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3118 if (which_alternative == 0)
3119 return "eor %A0,%A2" CR_TAB
3120 "eor %B0,%B2" CR_TAB
3123 return avr_out_bitop (insn, operands, NULL);
3125 [(set_attr "length" "3,6,6")
3126 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3127 (set_attr "cc" "set_n,clobber,clobber")])
3129 (define_insn "xorsi3"
3130 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
3131 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3132 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3133 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3136 if (which_alternative == 0)
3137 return "eor %0,%2" CR_TAB
3138 "eor %B0,%B2" CR_TAB
3139 "eor %C0,%C2" CR_TAB
3142 return avr_out_bitop (insn, operands, NULL);
3144 [(set_attr "length" "4,8,8")
3145 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3146 (set_attr "cc" "set_n,clobber,clobber")])
3148 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3151 (define_expand "rotlqi3"
3152 [(set (match_operand:QI 0 "register_operand" "")
3153 (rotate:QI (match_operand:QI 1 "register_operand" "")
3154 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3157 if (!CONST_INT_P (operands[2]))
3160 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3163 ;; Expander used by __builtin_avr_swap
3164 (define_expand "rotlqi3_4"
3165 [(set (match_operand:QI 0 "register_operand" "")
3166 (rotate:QI (match_operand:QI 1 "register_operand" "")
3169 (define_insn "*rotlqi3"
3170 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3171 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3172 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3175 lsl %0\;adc %0,__zero_reg__
3176 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3177 swap %0\;bst %0,0\;ror %0\;bld %0,7
3179 swap %0\;lsl %0\;adc %0,__zero_reg__
3180 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3181 bst %0,0\;ror %0\;bld %0,7
3183 [(set_attr "length" "2,4,4,1,3,5,3,0")
3184 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3186 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3187 ;; a whole number of bytes. The split creates the appropriate moves and
3188 ;; considers all overlap situations.
3190 ;; HImode does not need scratch. Use attribute for this constraint.
3192 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3193 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3198 (define_expand "rotl<mode>3"
3199 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3200 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3201 (match_operand:VOID 2 "const_int_operand" "")))
3202 (clobber (match_dup 3))])]
3207 if (!CONST_INT_P (operands[2]))
3210 offset = INTVAL (operands[2]);
3212 if (0 == offset % 8)
3214 if (AVR_HAVE_MOVW && 0 == offset % 16)
3215 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3217 operands[3] = gen_rtx_SCRATCH (QImode);
3219 else if (offset == 1
3220 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3222 /*; Support rotate left/right by 1 */
3224 emit_move_insn (operands[0],
3225 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3232 (define_insn "*rotlhi2.1"
3233 [(set (match_operand:HI 0 "register_operand" "=r")
3234 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3237 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3238 [(set_attr "length" "3")
3239 (set_attr "cc" "clobber")])
3241 (define_insn "*rotlhi2.15"
3242 [(set (match_operand:HI 0 "register_operand" "=r")
3243 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3246 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3247 [(set_attr "length" "4")
3248 (set_attr "cc" "clobber")])
3250 (define_insn "*rotlpsi2.1"
3251 [(set (match_operand:PSI 0 "register_operand" "=r")
3252 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3255 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3256 [(set_attr "length" "4")
3257 (set_attr "cc" "clobber")])
3259 (define_insn "*rotlpsi2.23"
3260 [(set (match_operand:PSI 0 "register_operand" "=r")
3261 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3264 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3265 [(set_attr "length" "5")
3266 (set_attr "cc" "clobber")])
3268 (define_insn "*rotlsi2.1"
3269 [(set (match_operand:SI 0 "register_operand" "=r")
3270 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3273 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3274 [(set_attr "length" "5")
3275 (set_attr "cc" "clobber")])
3277 (define_insn "*rotlsi2.31"
3278 [(set (match_operand:SI 0 "register_operand" "=r")
3279 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3282 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3283 [(set_attr "length" "6")
3284 (set_attr "cc" "clobber")])
3286 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3287 ;; The best we can do is use early clobber alternative "#&r" so that
3288 ;; completely non-overlapping operands dont get a scratch but # so register
3289 ;; allocation does not prefer non-overlapping.
3292 ;; Split word aligned rotates using scratch that is mode dependent.
3296 (define_insn_and_split "*rotw<mode>"
3297 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3298 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3299 (match_operand 2 "const_int_operand" "n,n,n")))
3300 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3302 && CONST_INT_P (operands[2])
3303 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3304 && 0 == INTVAL (operands[2]) % 16"
3306 "&& reload_completed"
3309 avr_rotate_bytes (operands);
3314 ;; Split byte aligned rotates using scratch that is always QI mode.
3319 (define_insn_and_split "*rotb<mode>"
3320 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3321 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3322 (match_operand 2 "const_int_operand" "n,n,n")))
3323 (clobber (match_scratch:QI 3 "=<rotx>"))]
3324 "CONST_INT_P (operands[2])
3325 && (8 == INTVAL (operands[2]) % 16
3327 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3328 && 0 == INTVAL (operands[2]) % 16))"
3330 "&& reload_completed"
3333 avr_rotate_bytes (operands);
3338 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3339 ;; arithmetic shift left
3342 ;; "ashlqq3" "ashluqq3"
3343 (define_expand "ashl<mode>3"
3344 [(set (match_operand:ALL1 0 "register_operand" "")
3345 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3346 (match_operand:QI 2 "nop_general_operand" "")))])
3348 (define_split ; ashlqi3_const4
3349 [(set (match_operand:ALL1 0 "d_register_operand" "")
3350 (ashift:ALL1 (match_dup 0)
3354 (rotate:QI (match_dup 1)
3357 (and:QI (match_dup 1)
3360 operands[1] = avr_to_int_mode (operands[0]);
3363 (define_split ; ashlqi3_const5
3364 [(set (match_operand:ALL1 0 "d_register_operand" "")
3365 (ashift:ALL1 (match_dup 0)
3368 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3369 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3370 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3372 operands[1] = avr_to_int_mode (operands[0]);
3375 (define_split ; ashlqi3_const6
3376 [(set (match_operand:ALL1 0 "d_register_operand" "")
3377 (ashift:ALL1 (match_dup 0)
3380 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3381 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3382 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3384 operands[1] = avr_to_int_mode (operands[0]);
3388 ;; "*ashlqq3" "*ashluqq3"
3389 (define_insn "*ashl<mode>3"
3390 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3391 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3392 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3395 return ashlqi3_out (insn, operands, NULL);
3397 [(set_attr "length" "5,0,1,2,4,6,9")
3398 (set_attr "adjust_len" "ashlqi")
3399 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3401 (define_insn "ashl<mode>3"
3402 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3403 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3404 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3407 return ashlhi3_out (insn, operands, NULL);
3409 [(set_attr "length" "6,0,2,2,4,10,10")
3410 (set_attr "adjust_len" "ashlhi")
3411 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3414 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3415 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3419 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3420 [(set (match_operand:QI 0 "register_operand" "=r")
3421 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3422 (match_operand:QI 2 "register_operand" "r"))
3428 (ashift:QI (match_dup 1)
3431 ;; ??? Combiner does not recognize that it could split the following insn;
3432 ;; presumably because he has no register handy?
3434 ;; "*ashluqihiqi3.mem"
3435 ;; "*ashlsqihiqi3.mem"
3436 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3437 [(set (match_operand:QI 0 "memory_operand" "=m")
3438 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3439 (match_operand:QI 2 "register_operand" "r"))
3442 { gcc_unreachable(); }
3445 (ashift:QI (match_dup 1)
3450 operands[3] = gen_reg_rtx (QImode);
3455 (define_insn_and_split "*ashlhiqi3"
3456 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3457 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3458 (match_operand:QI 2 "register_operand" "r")) 0))]
3460 { gcc_unreachable(); }
3463 (ashift:QI (match_dup 3)
3468 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3469 operands[4] = gen_reg_rtx (QImode);
3472 ;; High part of 16-bit shift is unused after the instruction:
3473 ;; No need to compute it, map to 8-bit shift.
3476 [(set (match_operand:HI 0 "register_operand" "")
3477 (ashift:HI (match_dup 0)
3478 (match_operand:QI 1 "register_operand" "")))]
3481 (ashift:QI (match_dup 2)
3483 (clobber (match_dup 3))]
3485 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3487 if (!peep2_reg_dead_p (1, operands[3]))
3490 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3495 ;; "ashlsq3" "ashlusq3"
3496 ;; "ashlsa3" "ashlusa3"
3497 (define_insn "ashl<mode>3"
3498 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3499 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3500 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3503 return ashlsi3_out (insn, operands, NULL);
3505 [(set_attr "length" "8,0,4,4,8,10,12")
3506 (set_attr "adjust_len" "ashlsi")
3507 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3509 ;; Optimize if a scratch register from LD_REGS happens to be available.
3511 (define_peephole2 ; ashlqi3_l_const4
3512 [(set (match_operand:ALL1 0 "l_register_operand" "")
3513 (ashift:ALL1 (match_dup 0)
3515 (match_scratch:QI 1 "d")]
3517 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3518 (set (match_dup 1) (const_int -16))
3519 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3521 operands[2] = avr_to_int_mode (operands[0]);
3524 (define_peephole2 ; ashlqi3_l_const5
3525 [(set (match_operand:ALL1 0 "l_register_operand" "")
3526 (ashift:ALL1 (match_dup 0)
3528 (match_scratch:QI 1 "d")]
3530 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3531 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3532 (set (match_dup 1) (const_int -32))
3533 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3535 operands[2] = avr_to_int_mode (operands[0]);
3538 (define_peephole2 ; ashlqi3_l_const6
3539 [(set (match_operand:ALL1 0 "l_register_operand" "")
3540 (ashift:ALL1 (match_dup 0)
3542 (match_scratch:QI 1 "d")]
3544 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3545 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3546 (set (match_dup 1) (const_int -64))
3547 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3549 operands[2] = avr_to_int_mode (operands[0]);
3553 [(match_scratch:QI 3 "d")
3554 (set (match_operand:ALL2 0 "register_operand" "")
3555 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3556 (match_operand:QI 2 "const_int_operand" "")))]
3558 [(parallel [(set (match_dup 0)
3559 (ashift:ALL2 (match_dup 1)
3561 (clobber (match_dup 3))])])
3564 ;; "*ashlhq3_const" "*ashluhq3_const"
3565 ;; "*ashlha3_const" "*ashluha3_const"
3566 (define_insn "*ashl<mode>3_const"
3567 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3568 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3569 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3570 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3573 return ashlhi3_out (insn, operands, NULL);
3575 [(set_attr "length" "0,2,2,4,10")
3576 (set_attr "adjust_len" "ashlhi")
3577 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3580 [(match_scratch:QI 3 "d")
3581 (set (match_operand:ALL4 0 "register_operand" "")
3582 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3583 (match_operand:QI 2 "const_int_operand" "")))]
3585 [(parallel [(set (match_dup 0)
3586 (ashift:ALL4 (match_dup 1)
3588 (clobber (match_dup 3))])])
3591 ;; "*ashlsq3_const" "*ashlusq3_const"
3592 ;; "*ashlsa3_const" "*ashlusa3_const"
3593 (define_insn "*ashl<mode>3_const"
3594 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3595 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3596 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3597 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3600 return ashlsi3_out (insn, operands, NULL);
3602 [(set_attr "length" "0,4,4,10")
3603 (set_attr "adjust_len" "ashlsi")
3604 (set_attr "cc" "none,set_n,clobber,clobber")])
3606 (define_expand "ashlpsi3"
3607 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3608 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3609 (match_operand:QI 2 "nonmemory_operand" "")))
3610 (clobber (scratch:QI))])]
3614 && CONST_INT_P (operands[2]))
3616 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3618 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3619 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3622 else if (optimize_insn_for_speed_p ()
3623 && INTVAL (operands[2]) != 16
3624 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3626 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3627 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3633 (define_insn "*ashlpsi3"
3634 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3635 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3636 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3637 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3640 return avr_out_ashlpsi3 (insn, operands, NULL);
3642 [(set_attr "adjust_len" "ashlpsi")
3643 (set_attr "cc" "clobber")])
3645 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3646 ;; arithmetic shift right
3649 ;; "ashrqq3" "ashruqq3"
3650 (define_insn "ashr<mode>3"
3651 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3652 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3653 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3656 return ashrqi3_out (insn, operands, NULL);
3658 [(set_attr "length" "5,0,1,2,5,4,9")
3659 (set_attr "adjust_len" "ashrqi")
3660 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3663 ;; "ashrhq3" "ashruhq3"
3664 ;; "ashrha3" "ashruha3"
3665 (define_insn "ashr<mode>3"
3666 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3667 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3668 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3671 return ashrhi3_out (insn, operands, NULL);
3673 [(set_attr "length" "6,0,2,4,4,10,10")
3674 (set_attr "adjust_len" "ashrhi")
3675 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3677 (define_insn "ashrpsi3"
3678 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3679 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3680 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3681 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3684 return avr_out_ashrpsi3 (insn, operands, NULL);
3686 [(set_attr "adjust_len" "ashrpsi")
3687 (set_attr "cc" "clobber")])
3690 ;; "ashrsq3" "ashrusq3"
3691 ;; "ashrsa3" "ashrusa3"
3692 (define_insn "ashr<mode>3"
3693 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3694 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3695 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3698 return ashrsi3_out (insn, operands, NULL);
3700 [(set_attr "length" "8,0,4,6,8,10,12")
3701 (set_attr "adjust_len" "ashrsi")
3702 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3704 ;; Optimize if a scratch register from LD_REGS happens to be available.
3707 [(match_scratch:QI 3 "d")
3708 (set (match_operand:ALL2 0 "register_operand" "")
3709 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3710 (match_operand:QI 2 "const_int_operand" "")))]
3712 [(parallel [(set (match_dup 0)
3713 (ashiftrt:ALL2 (match_dup 1)
3715 (clobber (match_dup 3))])])
3718 ;; "*ashrhq3_const" "*ashruhq3_const"
3719 ;; "*ashrha3_const" "*ashruha3_const"
3720 (define_insn "*ashr<mode>3_const"
3721 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3722 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3723 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3724 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3727 return ashrhi3_out (insn, operands, NULL);
3729 [(set_attr "length" "0,2,4,4,10")
3730 (set_attr "adjust_len" "ashrhi")
3731 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3734 [(match_scratch:QI 3 "d")
3735 (set (match_operand:ALL4 0 "register_operand" "")
3736 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3737 (match_operand:QI 2 "const_int_operand" "")))]
3739 [(parallel [(set (match_dup 0)
3740 (ashiftrt:ALL4 (match_dup 1)
3742 (clobber (match_dup 3))])])
3745 ;; "*ashrsq3_const" "*ashrusq3_const"
3746 ;; "*ashrsa3_const" "*ashrusa3_const"
3747 (define_insn "*ashr<mode>3_const"
3748 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3749 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3750 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3751 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3754 return ashrsi3_out (insn, operands, NULL);
3756 [(set_attr "length" "0,4,4,10")
3757 (set_attr "adjust_len" "ashrsi")
3758 (set_attr "cc" "none,clobber,set_n,clobber")])
3760 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3761 ;; logical shift right
3764 ;; "lshrqq3 "lshruqq3"
3765 (define_expand "lshr<mode>3"
3766 [(set (match_operand:ALL1 0 "register_operand" "")
3767 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3768 (match_operand:QI 2 "nop_general_operand" "")))])
3770 (define_split ; lshrqi3_const4
3771 [(set (match_operand:ALL1 0 "d_register_operand" "")
3772 (lshiftrt:ALL1 (match_dup 0)
3776 (rotate:QI (match_dup 1)
3779 (and:QI (match_dup 1)
3782 operands[1] = avr_to_int_mode (operands[0]);
3785 (define_split ; lshrqi3_const5
3786 [(set (match_operand:ALL1 0 "d_register_operand" "")
3787 (lshiftrt:ALL1 (match_dup 0)
3790 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3791 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3792 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3794 operands[1] = avr_to_int_mode (operands[0]);
3797 (define_split ; lshrqi3_const6
3798 [(set (match_operand:QI 0 "d_register_operand" "")
3799 (lshiftrt:QI (match_dup 0)
3802 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3803 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3804 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3806 operands[1] = avr_to_int_mode (operands[0]);
3812 (define_insn "*lshr<mode>3"
3813 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3814 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3815 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3818 return lshrqi3_out (insn, operands, NULL);
3820 [(set_attr "length" "5,0,1,2,4,6,9")
3821 (set_attr "adjust_len" "lshrqi")
3822 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3825 ;; "lshrhq3" "lshruhq3"
3826 ;; "lshrha3" "lshruha3"
3827 (define_insn "lshr<mode>3"
3828 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3829 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3830 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3833 return lshrhi3_out (insn, operands, NULL);
3835 [(set_attr "length" "6,0,2,2,4,10,10")
3836 (set_attr "adjust_len" "lshrhi")
3837 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3839 (define_insn "lshrpsi3"
3840 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3841 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3842 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3843 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3846 return avr_out_lshrpsi3 (insn, operands, NULL);
3848 [(set_attr "adjust_len" "lshrpsi")
3849 (set_attr "cc" "clobber")])
3852 ;; "lshrsq3" "lshrusq3"
3853 ;; "lshrsa3" "lshrusa3"
3854 (define_insn "lshr<mode>3"
3855 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3856 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3857 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3860 return lshrsi3_out (insn, operands, NULL);
3862 [(set_attr "length" "8,0,4,4,8,10,12")
3863 (set_attr "adjust_len" "lshrsi")
3864 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3866 ;; Optimize if a scratch register from LD_REGS happens to be available.
3868 (define_peephole2 ; lshrqi3_l_const4
3869 [(set (match_operand:ALL1 0 "l_register_operand" "")
3870 (lshiftrt:ALL1 (match_dup 0)
3872 (match_scratch:QI 1 "d")]
3874 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3875 (set (match_dup 1) (const_int 15))
3876 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3878 operands[2] = avr_to_int_mode (operands[0]);
3881 (define_peephole2 ; lshrqi3_l_const5
3882 [(set (match_operand:ALL1 0 "l_register_operand" "")
3883 (lshiftrt:ALL1 (match_dup 0)
3885 (match_scratch:QI 1 "d")]
3887 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3888 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3889 (set (match_dup 1) (const_int 7))
3890 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3892 operands[2] = avr_to_int_mode (operands[0]);
3895 (define_peephole2 ; lshrqi3_l_const6
3896 [(set (match_operand:ALL1 0 "l_register_operand" "")
3897 (lshiftrt:ALL1 (match_dup 0)
3899 (match_scratch:QI 1 "d")]
3901 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3902 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3903 (set (match_dup 1) (const_int 3))
3904 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3906 operands[2] = avr_to_int_mode (operands[0]);
3910 [(match_scratch:QI 3 "d")
3911 (set (match_operand:ALL2 0 "register_operand" "")
3912 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3913 (match_operand:QI 2 "const_int_operand" "")))]
3915 [(parallel [(set (match_dup 0)
3916 (lshiftrt:ALL2 (match_dup 1)
3918 (clobber (match_dup 3))])])
3921 ;; "*lshrhq3_const" "*lshruhq3_const"
3922 ;; "*lshrha3_const" "*lshruha3_const"
3923 (define_insn "*lshr<mode>3_const"
3924 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3925 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3926 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3927 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3930 return lshrhi3_out (insn, operands, NULL);
3932 [(set_attr "length" "0,2,2,4,10")
3933 (set_attr "adjust_len" "lshrhi")
3934 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3937 [(match_scratch:QI 3 "d")
3938 (set (match_operand:ALL4 0 "register_operand" "")
3939 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3940 (match_operand:QI 2 "const_int_operand" "")))]
3942 [(parallel [(set (match_dup 0)
3943 (lshiftrt:ALL4 (match_dup 1)
3945 (clobber (match_dup 3))])])
3948 ;; "*lshrsq3_const" "*lshrusq3_const"
3949 ;; "*lshrsa3_const" "*lshrusa3_const"
3950 (define_insn "*lshr<mode>3_const"
3951 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3952 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3953 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3954 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3957 return lshrsi3_out (insn, operands, NULL);
3959 [(set_attr "length" "0,4,4,10")
3960 (set_attr "adjust_len" "lshrsi")
3961 (set_attr "cc" "none,clobber,clobber,clobber")])
3963 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3966 (define_insn "absqi2"
3967 [(set (match_operand:QI 0 "register_operand" "=r")
3968 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3972 [(set_attr "length" "2")
3973 (set_attr "cc" "clobber")])
3976 (define_insn "abssf2"
3977 [(set (match_operand:SF 0 "register_operand" "=d,r")
3978 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3983 [(set_attr "length" "1,2")
3984 (set_attr "cc" "set_n,clobber")])
3986 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3989 (define_insn "negqi2"
3990 [(set (match_operand:QI 0 "register_operand" "=r")
3991 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3994 [(set_attr "length" "1")
3995 (set_attr "cc" "set_zn")])
3997 (define_insn "*negqihi2"
3998 [(set (match_operand:HI 0 "register_operand" "=r")
3999 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4001 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4002 [(set_attr "length" "4")
4003 (set_attr "cc" "set_n")])
4005 (define_insn "neghi2"
4006 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4007 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4010 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4011 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4012 [(set_attr "length" "3,4")
4013 (set_attr "cc" "set_czn")])
4015 (define_insn "negpsi2"
4016 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4017 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4020 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4021 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4022 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4023 [(set_attr "length" "5,6,6")
4024 (set_attr "cc" "set_czn,set_n,set_czn")])
4026 (define_insn "negsi2"
4027 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4028 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4031 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4032 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4033 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4034 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4035 [(set_attr "length" "7,8,8,7")
4036 (set_attr "isa" "*,*,mov,movw")
4037 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4039 (define_insn "negsf2"
4040 [(set (match_operand:SF 0 "register_operand" "=d,r")
4041 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4045 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4046 [(set_attr "length" "1,4")
4047 (set_attr "cc" "set_n,set_n")])
4049 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4052 (define_insn "one_cmplqi2"
4053 [(set (match_operand:QI 0 "register_operand" "=r")
4054 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4057 [(set_attr "length" "1")
4058 (set_attr "cc" "set_czn")])
4060 (define_insn "one_cmplhi2"
4061 [(set (match_operand:HI 0 "register_operand" "=r")
4062 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4066 [(set_attr "length" "2")
4067 (set_attr "cc" "set_n")])
4069 (define_insn "one_cmplpsi2"
4070 [(set (match_operand:PSI 0 "register_operand" "=r")
4071 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4073 "com %0\;com %B0\;com %C0"
4074 [(set_attr "length" "3")
4075 (set_attr "cc" "set_n")])
4077 (define_insn "one_cmplsi2"
4078 [(set (match_operand:SI 0 "register_operand" "=r")
4079 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4085 [(set_attr "length" "4")
4086 (set_attr "cc" "set_n")])
4088 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4091 ;; We keep combiner from inserting hard registers into the input of sign- and
4092 ;; zero-extends. A hard register in the input operand is not wanted because
4093 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4094 ;; hard register that overlaps these clobbers won't be combined to a widening
4095 ;; multiplication. There is no need for combine to propagate hard registers,
4096 ;; register allocation can do it just as well.
4098 (define_insn "extendqihi2"
4099 [(set (match_operand:HI 0 "register_operand" "=r,r")
4100 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4103 clr %B0\;sbrc %0,7\;com %B0
4104 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4105 [(set_attr "length" "3,4")
4106 (set_attr "cc" "set_n,set_n")])
4108 (define_insn "extendqipsi2"
4109 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4110 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4113 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4114 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4115 [(set_attr "length" "4,5")
4116 (set_attr "cc" "set_n,set_n")])
4118 (define_insn "extendqisi2"
4119 [(set (match_operand:SI 0 "register_operand" "=r,r")
4120 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4123 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4124 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4125 [(set_attr "length" "5,6")
4126 (set_attr "cc" "set_n,set_n")])
4128 (define_insn "extendhipsi2"
4129 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4130 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4133 clr %C0\;sbrc %B0,7\;com %C0
4134 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4135 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4136 [(set_attr "length" "3,5,4")
4137 (set_attr "isa" "*,mov,movw")
4138 (set_attr "cc" "set_n")])
4140 (define_insn "extendhisi2"
4141 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4142 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4145 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4146 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4147 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4148 [(set_attr "length" "4,6,5")
4149 (set_attr "isa" "*,mov,movw")
4150 (set_attr "cc" "set_n")])
4152 (define_insn "extendpsisi2"
4153 [(set (match_operand:SI 0 "register_operand" "=r")
4154 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4156 "clr %D0\;sbrc %C0,7\;com %D0"
4157 [(set_attr "length" "3")
4158 (set_attr "cc" "set_n")])
4160 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4163 (define_insn_and_split "zero_extendqihi2"
4164 [(set (match_operand:HI 0 "register_operand" "=r")
4165 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4169 [(set (match_dup 2) (match_dup 1))
4170 (set (match_dup 3) (const_int 0))]
4172 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4173 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4175 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4176 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4179 (define_insn_and_split "zero_extendqipsi2"
4180 [(set (match_operand:PSI 0 "register_operand" "=r")
4181 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4185 [(set (match_dup 2) (match_dup 1))
4186 (set (match_dup 3) (const_int 0))
4187 (set (match_dup 4) (const_int 0))]
4189 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4190 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4191 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4194 (define_insn_and_split "zero_extendqisi2"
4195 [(set (match_operand:SI 0 "register_operand" "=r")
4196 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4200 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4201 (set (match_dup 3) (const_int 0))]
4203 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4204 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4206 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4207 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4210 (define_insn_and_split "zero_extendhipsi2"
4211 [(set (match_operand:PSI 0 "register_operand" "=r")
4212 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4216 [(set (match_dup 2) (match_dup 1))
4217 (set (match_dup 3) (const_int 0))]
4219 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4220 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4223 (define_insn_and_split "n_extendhipsi2"
4224 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4225 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4226 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4227 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4231 [(set (match_dup 4) (match_dup 2))
4232 (set (match_dup 3) (match_dup 6))
4233 ; no-op move in the case where no scratch is needed
4234 (set (match_dup 5) (match_dup 3))]
4236 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4237 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4238 operands[6] = operands[1];
4240 if (GET_CODE (operands[3]) == SCRATCH)
4241 operands[3] = operands[5];
4244 (define_insn_and_split "zero_extendhisi2"
4245 [(set (match_operand:SI 0 "register_operand" "=r")
4246 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4250 [(set (match_dup 2) (match_dup 1))
4251 (set (match_dup 3) (const_int 0))]
4253 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4254 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4256 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4257 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4260 (define_insn_and_split "zero_extendpsisi2"
4261 [(set (match_operand:SI 0 "register_operand" "=r")
4262 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4266 [(set (match_dup 2) (match_dup 1))
4267 (set (match_dup 3) (const_int 0))]
4269 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4270 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4273 (define_insn_and_split "zero_extendqidi2"
4274 [(set (match_operand:DI 0 "register_operand" "=r")
4275 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4279 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4280 (set (match_dup 3) (const_int 0))]
4282 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4283 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4285 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4286 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4289 (define_insn_and_split "zero_extendhidi2"
4290 [(set (match_operand:DI 0 "register_operand" "=r")
4291 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4295 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4296 (set (match_dup 3) (const_int 0))]
4298 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4299 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4301 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4302 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4305 (define_insn_and_split "zero_extendsidi2"
4306 [(set (match_operand:DI 0 "register_operand" "=r")
4307 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4311 [(set (match_dup 2) (match_dup 1))
4312 (set (match_dup 3) (const_int 0))]
4314 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4315 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4317 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4318 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4321 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4324 ; Optimize negated tests into reverse compare if overflow is undefined.
4325 (define_insn "*negated_tstqi"
4327 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4329 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4330 "cp __zero_reg__,%0"
4331 [(set_attr "cc" "compare")
4332 (set_attr "length" "1")])
4334 (define_insn "*reversed_tstqi"
4336 (compare (const_int 0)
4337 (match_operand:QI 0 "register_operand" "r")))]
4339 "cp __zero_reg__,%0"
4340 [(set_attr "cc" "compare")
4341 (set_attr "length" "2")])
4343 (define_insn "*negated_tsthi"
4345 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4347 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4348 "cp __zero_reg__,%A0
4349 cpc __zero_reg__,%B0"
4350 [(set_attr "cc" "compare")
4351 (set_attr "length" "2")])
4353 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4354 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4355 (define_insn "*reversed_tsthi"
4357 (compare (const_int 0)
4358 (match_operand:HI 0 "register_operand" "r")))
4359 (clobber (match_scratch:QI 1 "=X"))]
4361 "cp __zero_reg__,%A0
4362 cpc __zero_reg__,%B0"
4363 [(set_attr "cc" "compare")
4364 (set_attr "length" "2")])
4366 (define_insn "*negated_tstpsi"
4368 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4370 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4371 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4372 [(set_attr "cc" "compare")
4373 (set_attr "length" "3")])
4375 (define_insn "*reversed_tstpsi"
4377 (compare (const_int 0)
4378 (match_operand:PSI 0 "register_operand" "r")))
4379 (clobber (match_scratch:QI 1 "=X"))]
4381 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4382 [(set_attr "cc" "compare")
4383 (set_attr "length" "3")])
4385 (define_insn "*negated_tstsi"
4387 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4389 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4390 "cp __zero_reg__,%A0
4391 cpc __zero_reg__,%B0
4392 cpc __zero_reg__,%C0
4393 cpc __zero_reg__,%D0"
4394 [(set_attr "cc" "compare")
4395 (set_attr "length" "4")])
4397 ;; "*reversed_tstsi"
4398 ;; "*reversed_tstsq" "*reversed_tstusq"
4399 ;; "*reversed_tstsa" "*reversed_tstusa"
4400 (define_insn "*reversed_tst<mode>"
4402 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4403 (match_operand:ALL4 1 "register_operand" "r")))
4404 (clobber (match_scratch:QI 2 "=X"))]
4406 "cp __zero_reg__,%A1
4407 cpc __zero_reg__,%B1
4408 cpc __zero_reg__,%C1
4409 cpc __zero_reg__,%D1"
4410 [(set_attr "cc" "compare")
4411 (set_attr "length" "4")])
4415 ;; "*cmpqq" "*cmpuqq"
4416 (define_insn "*cmp<mode>"
4418 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4419 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4425 [(set_attr "cc" "compare,compare,compare")
4426 (set_attr "length" "1,1,1")])
4428 (define_insn "*cmpqi_sign_extend"
4430 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4431 (match_operand:HI 1 "s8_operand" "n")))]
4434 [(set_attr "cc" "compare")
4435 (set_attr "length" "1")])
4438 ;; "*cmphq" "*cmpuhq"
4439 ;; "*cmpha" "*cmpuha"
4440 (define_insn "*cmp<mode>"
4442 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4443 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4444 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4447 switch (which_alternative)
4451 return avr_out_tsthi (insn, operands, NULL);
4454 return "cp %A0,%A1\;cpc %B0,%B1";
4457 if (<MODE>mode != HImode)
4459 return reg_unused_after (insn, operands[0])
4460 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4461 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4464 if (<MODE>mode != HImode)
4466 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4469 return avr_out_compare (insn, operands, NULL);
4471 [(set_attr "cc" "compare")
4472 (set_attr "length" "1,2,2,3,4,2,4")
4473 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4475 (define_insn "*cmppsi"
4477 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4478 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4479 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4482 switch (which_alternative)
4485 return avr_out_tstpsi (insn, operands, NULL);
4488 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4491 return reg_unused_after (insn, operands[0])
4492 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4493 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4496 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4499 return avr_out_compare (insn, operands, NULL);
4501 [(set_attr "cc" "compare")
4502 (set_attr "length" "3,3,5,6,3,7")
4503 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4506 ;; "*cmpsq" "*cmpusq"
4507 ;; "*cmpsa" "*cmpusa"
4508 (define_insn "*cmp<mode>"
4510 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4511 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4512 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4515 if (0 == which_alternative)
4516 return avr_out_tstsi (insn, operands, NULL);
4517 else if (1 == which_alternative)
4518 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4520 return avr_out_compare (insn, operands, NULL);
4522 [(set_attr "cc" "compare")
4523 (set_attr "length" "4,4,4,5,8")
4524 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4527 ;; ----------------------------------------------------------------------
4528 ;; JUMP INSTRUCTIONS
4529 ;; ----------------------------------------------------------------------
4530 ;; Conditional jump instructions
4533 ;; "cbranchqq4" "cbranchuqq4"
4534 (define_expand "cbranch<mode>4"
4536 (compare (match_operand:ALL1 1 "register_operand" "")
4537 (match_operand:ALL1 2 "nonmemory_operand" "")))
4540 (match_operator 0 "ordered_comparison_operator" [(cc0)
4542 (label_ref (match_operand 3 "" ""))
4545 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4546 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4548 (define_expand "cbranch<mode>4"
4549 [(parallel [(set (cc0)
4550 (compare (match_operand:ORDERED234 1 "register_operand" "")
4551 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4552 (clobber (match_scratch:QI 4 ""))])
4555 (match_operator 0 "ordered_comparison_operator" [(cc0)
4557 (label_ref (match_operand 3 "" ""))
4561 ;; Test a single bit in a QI/HI/SImode register.
4562 ;; Combine will create zero extract patterns for single bit tests.
4563 ;; permit any mode in source pattern by using VOIDmode.
4565 (define_insn "*sbrx_branch<mode>"
4568 (match_operator 0 "eqne_operator"
4570 (match_operand:VOID 1 "register_operand" "r")
4572 (match_operand 2 "const_int_operand" "n"))
4574 (label_ref (match_operand 3 "" ""))
4578 return avr_out_sbxx_branch (insn, operands);
4580 [(set (attr "length")
4581 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4582 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4584 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4587 (set_attr "cc" "clobber")])
4589 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4590 ;; or for old peepholes.
4591 ;; Fixme - bitwise Mask will not work for DImode
4593 (define_insn "*sbrx_and_branch<mode>"
4596 (match_operator 0 "eqne_operator"
4598 (match_operand:QISI 1 "register_operand" "r")
4599 (match_operand:QISI 2 "single_one_operand" "n"))
4601 (label_ref (match_operand 3 "" ""))
4605 HOST_WIDE_INT bitnumber;
4606 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4607 operands[2] = GEN_INT (bitnumber);
4608 return avr_out_sbxx_branch (insn, operands);
4610 [(set (attr "length")
4611 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4612 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4614 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4617 (set_attr "cc" "clobber")])
4619 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4621 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4623 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4624 (label_ref (match_operand 1 "" ""))
4627 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4631 (label_ref (match_dup 1))
4635 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4637 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4638 (label_ref (match_operand 1 "" ""))
4641 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4645 (label_ref (match_dup 1))
4649 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4651 (clobber (match_operand:HI 2 ""))])
4652 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4653 (label_ref (match_operand 1 "" ""))
4656 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4658 (label_ref (match_dup 1))
4662 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4664 (clobber (match_operand:HI 2 ""))])
4665 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4666 (label_ref (match_operand 1 "" ""))
4669 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4671 (label_ref (match_dup 1))
4675 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4677 (clobber (match_operand:SI 2 ""))])
4678 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4679 (label_ref (match_operand 1 "" ""))
4682 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4684 (label_ref (match_dup 1))
4686 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4689 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4691 (clobber (match_operand:SI 2 ""))])
4692 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4693 (label_ref (match_operand 1 "" ""))
4696 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4698 (label_ref (match_dup 1))
4700 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4702 ;; ************************************************************************
4703 ;; Implementation of conditional jumps here.
4704 ;; Compare with 0 (test) jumps
4705 ;; ************************************************************************
4707 (define_insn "branch"
4709 (if_then_else (match_operator 1 "simple_comparison_operator"
4712 (label_ref (match_operand 0 "" ""))
4716 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4718 [(set_attr "type" "branch")
4719 (set_attr "cc" "clobber")])
4722 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4723 ;; or optimized in the remainder.
4725 (define_insn "branch_unspec"
4727 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4730 (label_ref (match_operand 0 "" ""))
4732 ] UNSPEC_IDENTITY))]
4735 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4737 [(set_attr "type" "branch")
4738 (set_attr "cc" "none")])
4740 ;; ****************************************************************
4741 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4742 ;; Convert them all to proper jumps.
4743 ;; ****************************************************************/
4745 (define_insn "difficult_branch"
4747 (if_then_else (match_operator 1 "difficult_comparison_operator"
4750 (label_ref (match_operand 0 "" ""))
4754 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4756 [(set_attr "type" "branch1")
4757 (set_attr "cc" "clobber")])
4761 (define_insn "rvbranch"
4763 (if_then_else (match_operator 1 "simple_comparison_operator"
4767 (label_ref (match_operand 0 "" ""))))]
4770 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4772 [(set_attr "type" "branch1")
4773 (set_attr "cc" "clobber")])
4775 (define_insn "difficult_rvbranch"
4777 (if_then_else (match_operator 1 "difficult_comparison_operator"
4781 (label_ref (match_operand 0 "" ""))))]
4784 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4786 [(set_attr "type" "branch")
4787 (set_attr "cc" "clobber")])
4789 ;; **************************************************************************
4790 ;; Unconditional and other jump instructions.
4794 (label_ref (match_operand 0 "" "")))]
4797 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4801 [(set (attr "length")
4802 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4803 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4806 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4807 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4810 (set_attr "cc" "none")])
4814 ;; Operand 1 not used on the AVR.
4815 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4816 (define_expand "call"
4817 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4818 (match_operand:HI 1 "general_operand" ""))
4819 (use (const_int 0))])])
4821 ;; Operand 1 not used on the AVR.
4822 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4823 (define_expand "sibcall"
4824 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4825 (match_operand:HI 1 "general_operand" ""))
4826 (use (const_int 1))])])
4830 ;; Operand 2 not used on the AVR.
4831 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4832 (define_expand "call_value"
4833 [(parallel[(set (match_operand 0 "register_operand" "")
4834 (call (match_operand:HI 1 "call_insn_operand" "")
4835 (match_operand:HI 2 "general_operand" "")))
4836 (use (const_int 0))])])
4838 ;; Operand 2 not used on the AVR.
4839 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4840 (define_expand "sibcall_value"
4841 [(parallel[(set (match_operand 0 "register_operand" "")
4842 (call (match_operand:HI 1 "call_insn_operand" "")
4843 (match_operand:HI 2 "general_operand" "")))
4844 (use (const_int 1))])])
4846 (define_insn "call_insn"
4847 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4848 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4849 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4850 ;; Operand 1 not used on the AVR.
4851 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4858 [(set_attr "cc" "clobber")
4859 (set_attr "length" "1,*,1,*")
4860 (set_attr "adjust_len" "*,call,*,call")])
4862 (define_insn "call_value_insn"
4863 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4864 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4865 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4866 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4867 ;; Operand 2 not used on the AVR.
4868 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4875 [(set_attr "cc" "clobber")
4876 (set_attr "length" "1,*,1,*")
4877 (set_attr "adjust_len" "*,call,*,call")])
4883 [(set_attr "cc" "none")
4884 (set_attr "length" "1")])
4888 (define_expand "indirect_jump"
4890 (match_operand:HI 0 "nonmemory_operand" ""))]
4893 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4895 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4900 (define_insn "*indirect_jump"
4902 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4908 push %A0\;push %B0\;ret
4910 [(set_attr "length" "1,2,1,3,1")
4911 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4912 (set_attr "cc" "none")])
4915 ;; For entries in jump table see avr_output_addr_vec_elt.
4918 ;; "rjmp .L<n>" instructions for <= 8K devices
4919 ;; ".word gs(.L<n>)" addresses for > 8K devices
4920 (define_insn "*tablejump"
4922 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4924 (use (label_ref (match_operand 1 "" "")))
4925 (clobber (match_dup 0))]
4929 push %A0\;push %B0\;ret
4931 [(set_attr "length" "1,3,2")
4932 (set_attr "isa" "rjmp,rjmp,jmp")
4933 (set_attr "cc" "none,none,clobber")])
4936 (define_expand "casesi"
4937 [(parallel [(set (match_dup 6)
4938 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4939 (match_operand:HI 1 "register_operand" "")))
4940 (clobber (scratch:QI))])
4941 (parallel [(set (cc0)
4942 (compare (match_dup 6)
4943 (match_operand:HI 2 "register_operand" "")))
4944 (clobber (match_scratch:QI 9 ""))])
4947 (if_then_else (gtu (cc0)
4949 (label_ref (match_operand 4 "" ""))
4953 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4955 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4956 (use (label_ref (match_dup 3)))
4957 (clobber (match_dup 6))])]
4960 operands[6] = gen_reg_rtx (HImode);
4964 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4965 ;; This instruction sets Z flag
4968 [(set (cc0) (const_int 0))]
4971 [(set_attr "length" "1")
4972 (set_attr "cc" "compare")])
4974 ;; Clear/set/test a single bit in I/O address space.
4977 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4978 (and:QI (mem:QI (match_dup 0))
4979 (match_operand:QI 1 "single_zero_operand" "n")))]
4982 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4983 return "cbi %i0,%2";
4985 [(set_attr "length" "1")
4986 (set_attr "cc" "none")])
4989 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4990 (ior:QI (mem:QI (match_dup 0))
4991 (match_operand:QI 1 "single_one_operand" "n")))]
4994 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4995 return "sbi %i0,%2";
4997 [(set_attr "length" "1")
4998 (set_attr "cc" "none")])
5000 ;; Lower half of the I/O space - use sbic/sbis directly.
5001 (define_insn "*sbix_branch"
5004 (match_operator 0 "eqne_operator"
5006 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5008 (match_operand 2 "const_int_operand" "n"))
5010 (label_ref (match_operand 3 "" ""))
5014 return avr_out_sbxx_branch (insn, operands);
5016 [(set (attr "length")
5017 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5018 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5020 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5023 (set_attr "cc" "clobber")])
5025 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5026 (define_insn "*sbix_branch_bit7"
5029 (match_operator 0 "gelt_operator"
5030 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
5032 (label_ref (match_operand 2 "" ""))
5036 operands[3] = operands[2];
5037 operands[2] = GEN_INT (7);
5038 return avr_out_sbxx_branch (insn, operands);
5040 [(set (attr "length")
5041 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5042 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5044 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5047 (set_attr "cc" "clobber")])
5049 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5050 (define_insn "*sbix_branch_tmp"
5053 (match_operator 0 "eqne_operator"
5055 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5057 (match_operand 2 "const_int_operand" "n"))
5059 (label_ref (match_operand 3 "" ""))
5063 return avr_out_sbxx_branch (insn, operands);
5065 [(set (attr "length")
5066 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5067 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5069 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5072 (set_attr "cc" "clobber")])
5074 (define_insn "*sbix_branch_tmp_bit7"
5077 (match_operator 0 "gelt_operator"
5078 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5080 (label_ref (match_operand 2 "" ""))
5084 operands[3] = operands[2];
5085 operands[2] = GEN_INT (7);
5086 return avr_out_sbxx_branch (insn, operands);
5088 [(set (attr "length")
5089 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5090 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5092 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5095 (set_attr "cc" "clobber")])
5097 ;; ************************* Peepholes ********************************
5099 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5100 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5101 (plus:SI (match_dup 0)
5103 (clobber (scratch:QI))])
5104 (parallel [(set (cc0)
5105 (compare (match_dup 0)
5107 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5109 (if_then_else (eqne (cc0)
5111 (label_ref (match_operand 2 "" ""))
5118 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5119 output_asm_insn ("sbiw %0,1" CR_TAB
5120 "sbc %C0,__zero_reg__" CR_TAB
5121 "sbc %D0,__zero_reg__", operands);
5123 output_asm_insn ("subi %A0,1" CR_TAB
5124 "sbc %B0,__zero_reg__" CR_TAB
5125 "sbc %C0,__zero_reg__" CR_TAB
5126 "sbc %D0,__zero_reg__", operands);
5128 jump_mode = avr_jump_mode (operands[2], insn);
5129 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5130 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5134 case 1: return "%1 %2";
5135 case 2: return "%1 .+2\;rjmp %2";
5136 case 3: return "%1 .+4\;jmp %2";
5143 (define_peephole ; "*dec-and-branchhi!=-1"
5144 [(set (match_operand:HI 0 "d_register_operand" "")
5145 (plus:HI (match_dup 0)
5147 (parallel [(set (cc0)
5148 (compare (match_dup 0)
5150 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5152 (if_then_else (eqne (cc0)
5154 (label_ref (match_operand 2 "" ""))
5161 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5162 output_asm_insn ("sbiw %0,1", operands);
5164 output_asm_insn ("subi %A0,1" CR_TAB
5165 "sbc %B0,__zero_reg__", operands);
5167 jump_mode = avr_jump_mode (operands[2], insn);
5168 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5169 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5173 case 1: return "%1 %2";
5174 case 2: return "%1 .+2\;rjmp %2";
5175 case 3: return "%1 .+4\;jmp %2";
5182 ;; Same as above but with clobber flavour of addhi3
5183 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5184 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5185 (plus:HI (match_dup 0)
5187 (clobber (scratch:QI))])
5188 (parallel [(set (cc0)
5189 (compare (match_dup 0)
5191 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5193 (if_then_else (eqne (cc0)
5195 (label_ref (match_operand 2 "" ""))
5202 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5203 output_asm_insn ("sbiw %0,1", operands);
5205 output_asm_insn ("subi %A0,1" CR_TAB
5206 "sbc %B0,__zero_reg__", operands);
5208 jump_mode = avr_jump_mode (operands[2], insn);
5209 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5210 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5214 case 1: return "%1 %2";
5215 case 2: return "%1 .+2\;rjmp %2";
5216 case 3: return "%1 .+4\;jmp %2";
5223 ;; Same as above but with clobber flavour of addhi3
5224 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5225 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5226 (plus:HI (match_dup 0)
5228 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5229 (parallel [(set (cc0)
5230 (compare (match_dup 0)
5232 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5234 (if_then_else (eqne (cc0)
5236 (label_ref (match_operand 2 "" ""))
5243 output_asm_insn ("ldi %3,1" CR_TAB
5245 "sbc %B0,__zero_reg__", operands);
5247 jump_mode = avr_jump_mode (operands[2], insn);
5248 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5249 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5253 case 1: return "%1 %2";
5254 case 2: return "%1 .+2\;rjmp %2";
5255 case 3: return "%1 .+4\;jmp %2";
5262 (define_peephole ; "*dec-and-branchqi!=-1"
5263 [(set (match_operand:QI 0 "d_register_operand" "")
5264 (plus:QI (match_dup 0)
5267 (compare (match_dup 0)
5270 (if_then_else (eqne (cc0)
5272 (label_ref (match_operand 1 "" ""))
5279 cc_status.value1 = operands[0];
5280 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5282 output_asm_insn ("subi %A0,1", operands);
5284 jump_mode = avr_jump_mode (operands[1], insn);
5285 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5286 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5290 case 1: return "%0 %1";
5291 case 2: return "%0 .+2\;rjmp %1";
5292 case 3: return "%0 .+4\;jmp %1";
5300 (define_peephole ; "*cpse.eq"
5302 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5303 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5305 (if_then_else (eq (cc0)
5307 (label_ref (match_operand 0 "" ""))
5309 "jump_over_one_insn_p (insn, operands[0])"
5312 cpse %1,__zero_reg__")
5314 ;; This peephole avoids code like
5317 ;; BREQ .+2 ; branch
5320 ;; Notice that the peephole is always shorter than cmpqi + branch.
5321 ;; The reason to write it as peephole is that sequences like
5326 ;; shall not be superseeded. With a respective combine pattern
5327 ;; the latter sequence would be
5330 ;; CPSE Rm, __zero_reg__
5333 ;; and thus longer and slower and not easy to be rolled back.
5335 (define_peephole ; "*cpse.ne"
5337 (compare (match_operand:ALL1 1 "register_operand" "")
5338 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5340 (if_then_else (ne (cc0)
5342 (label_ref (match_operand 0 "" ""))
5345 || !avr_current_device->errata_skip"
5347 if (operands[2] == CONST0_RTX (<MODE>mode))
5348 operands[2] = zero_reg_rtx;
5350 return 3 == avr_jump_mode (operands[0], insn)
5351 ? "cpse %1,%2\;jmp %0"
5352 : "cpse %1,%2\;rjmp %0";
5355 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5356 ;;prologue/epilogue support instructions
5358 (define_insn "popqi"
5359 [(set (match_operand:QI 0 "register_operand" "=r")
5360 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5363 [(set_attr "cc" "none")
5364 (set_attr "length" "1")])
5366 ;; Enable Interrupts
5367 (define_expand "enable_interrupt"
5368 [(clobber (const_int 0))]
5371 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5372 MEM_VOLATILE_P (mem) = 1;
5373 emit_insn (gen_cli_sei (const1_rtx, mem));
5377 ;; Disable Interrupts
5378 (define_expand "disable_interrupt"
5379 [(clobber (const_int 0))]
5382 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5383 MEM_VOLATILE_P (mem) = 1;
5384 emit_insn (gen_cli_sei (const0_rtx, mem));
5388 (define_insn "cli_sei"
5389 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5390 UNSPECV_ENABLE_IRQS)
5391 (set (match_operand:BLK 1 "" "")
5392 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5397 [(set_attr "length" "1")
5398 (set_attr "cc" "none")])
5400 ;; Library prologue saves
5401 (define_insn "call_prologue_saves"
5402 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5403 (match_operand:HI 0 "immediate_operand" "i,i")
5404 (set (reg:HI REG_SP)
5405 (minus:HI (reg:HI REG_SP)
5406 (match_operand:HI 1 "immediate_operand" "i,i")))
5407 (use (reg:HI REG_X))
5408 (clobber (reg:HI REG_Z))]
5410 "ldi r30,lo8(gs(1f))
5412 %~jmp __prologue_saves__+((18 - %0) * 2)
5414 [(set_attr "length" "5,6")
5415 (set_attr "cc" "clobber")
5416 (set_attr "isa" "rjmp,jmp")])
5418 ; epilogue restores using library
5419 (define_insn "epilogue_restores"
5420 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5422 (plus:HI (reg:HI REG_Y)
5423 (match_operand:HI 0 "immediate_operand" "i,i")))
5424 (set (reg:HI REG_SP)
5425 (plus:HI (reg:HI REG_Y)
5427 (clobber (reg:QI REG_Z))]
5430 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5431 [(set_attr "length" "2,3")
5432 (set_attr "cc" "clobber")
5433 (set_attr "isa" "rjmp,jmp")])
5436 (define_insn "return"
5438 "reload_completed && avr_simple_epilogue ()"
5440 [(set_attr "cc" "none")
5441 (set_attr "length" "1")])
5443 (define_insn "return_from_epilogue"
5447 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5448 && !cfun->machine->is_naked"
5450 [(set_attr "cc" "none")
5451 (set_attr "length" "1")])
5453 (define_insn "return_from_interrupt_epilogue"
5457 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5458 && !cfun->machine->is_naked"
5460 [(set_attr "cc" "none")
5461 (set_attr "length" "1")])
5463 (define_insn "return_from_naked_epilogue"
5467 && cfun->machine->is_naked"
5469 [(set_attr "cc" "none")
5470 (set_attr "length" "0")])
5472 (define_expand "prologue"
5476 avr_expand_prologue ();
5480 (define_expand "epilogue"
5484 avr_expand_epilogue (false /* sibcall_p */);
5488 (define_expand "sibcall_epilogue"
5492 avr_expand_epilogue (true /* sibcall_p */);
5496 ;; Some instructions resp. instruction sequences available
5499 (define_insn "delay_cycles_1"
5500 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5502 UNSPECV_DELAY_CYCLES)
5503 (set (match_operand:BLK 1 "" "")
5504 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5505 (clobber (match_scratch:QI 2 "=&d"))]
5510 [(set_attr "length" "3")
5511 (set_attr "cc" "clobber")])
5513 (define_insn "delay_cycles_2"
5514 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5516 UNSPECV_DELAY_CYCLES)
5517 (set (match_operand:BLK 1 "" "")
5518 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5519 (clobber (match_scratch:HI 2 "=&w"))]
5525 [(set_attr "length" "4")
5526 (set_attr "cc" "clobber")])
5528 (define_insn "delay_cycles_3"
5529 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5531 UNSPECV_DELAY_CYCLES)
5532 (set (match_operand:BLK 1 "" "")
5533 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5534 (clobber (match_scratch:QI 2 "=&d"))
5535 (clobber (match_scratch:QI 3 "=&d"))
5536 (clobber (match_scratch:QI 4 "=&d"))]
5545 [(set_attr "length" "7")
5546 (set_attr "cc" "clobber")])
5548 (define_insn "delay_cycles_4"
5549 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5551 UNSPECV_DELAY_CYCLES)
5552 (set (match_operand:BLK 1 "" "")
5553 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5554 (clobber (match_scratch:QI 2 "=&d"))
5555 (clobber (match_scratch:QI 3 "=&d"))
5556 (clobber (match_scratch:QI 4 "=&d"))
5557 (clobber (match_scratch:QI 5 "=&d"))]
5568 [(set_attr "length" "9")
5569 (set_attr "cc" "clobber")])
5572 ;; __builtin_avr_insert_bits
5574 (define_insn "insert_bits"
5575 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5576 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5577 (match_operand:QI 2 "register_operand" "r ,r ,r")
5578 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5579 UNSPEC_INSERT_BITS))]
5582 return avr_out_insert_bits (operands, NULL);
5584 [(set_attr "adjust_len" "insert_bits")
5585 (set_attr "cc" "clobber")])
5588 ;; __builtin_avr_flash_segment
5590 ;; Just a helper for the next "official" expander.
5592 (define_expand "flash_segment1"
5593 [(set (match_operand:QI 0 "register_operand" "")
5594 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5597 (compare (match_dup 0)
5600 (if_then_else (ge (cc0)
5602 (label_ref (match_operand 2 "" ""))
5607 (define_expand "flash_segment"
5608 [(parallel [(match_operand:QI 0 "register_operand" "")
5609 (match_operand:PSI 1 "register_operand" "")])]
5612 rtx label = gen_label_rtx ();
5613 emit (gen_flash_segment1 (operands[0], operands[1], label));
5618 ;; Actually, it's too late now to work out address spaces known at compiletime.
5619 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5620 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5621 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5623 (define_insn_and_split "*split.flash_segment"
5624 [(set (match_operand:QI 0 "register_operand" "=d")
5625 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5626 (match_operand:HI 2 "register_operand" "r"))
5629 { gcc_unreachable(); }
5637 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5638 ;; better 8-bit parity recognition.
5640 (define_expand "parityhi2"
5641 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5642 (parity:HI (match_operand:HI 1 "register_operand" "")))
5643 (clobber (reg:HI 24))])])
5645 (define_insn_and_split "*parityhi2"
5646 [(set (match_operand:HI 0 "register_operand" "=r")
5647 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5648 (clobber (reg:HI 24))]
5650 { gcc_unreachable(); }
5655 (parity:HI (reg:HI 24)))
5659 (define_insn_and_split "*parityqihi2"
5660 [(set (match_operand:HI 0 "register_operand" "=r")
5661 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5662 (clobber (reg:HI 24))]
5664 { gcc_unreachable(); }
5669 (zero_extend:HI (parity:QI (reg:QI 24))))
5673 (define_expand "paritysi2"
5675 (match_operand:SI 1 "register_operand" ""))
5677 (truncate:HI (parity:SI (reg:SI 22))))
5680 (set (match_operand:SI 0 "register_operand" "")
5681 (zero_extend:SI (match_dup 2)))]
5684 operands[2] = gen_reg_rtx (HImode);
5687 (define_insn "*parityhi2.libgcc"
5689 (parity:HI (reg:HI 24)))]
5691 "%~call __parityhi2"
5692 [(set_attr "type" "xcall")
5693 (set_attr "cc" "clobber")])
5695 (define_insn "*parityqihi2.libgcc"
5697 (zero_extend:HI (parity:QI (reg:QI 24))))]
5699 "%~call __parityqi2"
5700 [(set_attr "type" "xcall")
5701 (set_attr "cc" "clobber")])
5703 (define_insn "*paritysihi2.libgcc"
5705 (truncate:HI (parity:SI (reg:SI 22))))]
5707 "%~call __paritysi2"
5708 [(set_attr "type" "xcall")
5709 (set_attr "cc" "clobber")])
5714 (define_expand "popcounthi2"
5716 (match_operand:HI 1 "register_operand" ""))
5718 (popcount:HI (reg:HI 24)))
5719 (set (match_operand:HI 0 "register_operand" "")
5724 (define_expand "popcountsi2"
5726 (match_operand:SI 1 "register_operand" ""))
5728 (truncate:HI (popcount:SI (reg:SI 22))))
5731 (set (match_operand:SI 0 "register_operand" "")
5732 (zero_extend:SI (match_dup 2)))]
5735 operands[2] = gen_reg_rtx (HImode);
5738 (define_insn "*popcounthi2.libgcc"
5740 (popcount:HI (reg:HI 24)))]
5742 "%~call __popcounthi2"
5743 [(set_attr "type" "xcall")
5744 (set_attr "cc" "clobber")])
5746 (define_insn "*popcountsi2.libgcc"
5748 (truncate:HI (popcount:SI (reg:SI 22))))]
5750 "%~call __popcountsi2"
5751 [(set_attr "type" "xcall")
5752 (set_attr "cc" "clobber")])
5754 (define_insn "*popcountqi2.libgcc"
5756 (popcount:QI (reg:QI 24)))]
5758 "%~call __popcountqi2"
5759 [(set_attr "type" "xcall")
5760 (set_attr "cc" "clobber")])
5762 (define_insn_and_split "*popcountqihi2.libgcc"
5764 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5769 (popcount:QI (reg:QI 24)))
5773 ;; Count Leading Zeros
5775 (define_expand "clzhi2"
5777 (match_operand:HI 1 "register_operand" ""))
5778 (parallel [(set (reg:HI 24)
5779 (clz:HI (reg:HI 24)))
5780 (clobber (reg:QI 26))])
5781 (set (match_operand:HI 0 "register_operand" "")
5784 (define_expand "clzsi2"
5786 (match_operand:SI 1 "register_operand" ""))
5787 (parallel [(set (reg:HI 24)
5788 (truncate:HI (clz:SI (reg:SI 22))))
5789 (clobber (reg:QI 26))])
5792 (set (match_operand:SI 0 "register_operand" "")
5793 (zero_extend:SI (match_dup 2)))]
5796 operands[2] = gen_reg_rtx (HImode);
5799 (define_insn "*clzhi2.libgcc"
5801 (clz:HI (reg:HI 24)))
5802 (clobber (reg:QI 26))]
5805 [(set_attr "type" "xcall")
5806 (set_attr "cc" "clobber")])
5808 (define_insn "*clzsihi2.libgcc"
5810 (truncate:HI (clz:SI (reg:SI 22))))
5811 (clobber (reg:QI 26))]
5814 [(set_attr "type" "xcall")
5815 (set_attr "cc" "clobber")])
5817 ;; Count Trailing Zeros
5819 (define_expand "ctzhi2"
5821 (match_operand:HI 1 "register_operand" ""))
5822 (parallel [(set (reg:HI 24)
5823 (ctz:HI (reg:HI 24)))
5824 (clobber (reg:QI 26))])
5825 (set (match_operand:HI 0 "register_operand" "")
5828 (define_expand "ctzsi2"
5830 (match_operand:SI 1 "register_operand" ""))
5831 (parallel [(set (reg:HI 24)
5832 (truncate:HI (ctz:SI (reg:SI 22))))
5833 (clobber (reg:QI 22))
5834 (clobber (reg:QI 26))])
5837 (set (match_operand:SI 0 "register_operand" "")
5838 (zero_extend:SI (match_dup 2)))]
5841 operands[2] = gen_reg_rtx (HImode);
5844 (define_insn "*ctzhi2.libgcc"
5846 (ctz:HI (reg:HI 24)))
5847 (clobber (reg:QI 26))]
5850 [(set_attr "type" "xcall")
5851 (set_attr "cc" "clobber")])
5853 (define_insn "*ctzsihi2.libgcc"
5855 (truncate:HI (ctz:SI (reg:SI 22))))
5856 (clobber (reg:QI 22))
5857 (clobber (reg:QI 26))]
5860 [(set_attr "type" "xcall")
5861 (set_attr "cc" "clobber")])
5865 (define_expand "ffshi2"
5867 (match_operand:HI 1 "register_operand" ""))
5868 (parallel [(set (reg:HI 24)
5869 (ffs:HI (reg:HI 24)))
5870 (clobber (reg:QI 26))])
5871 (set (match_operand:HI 0 "register_operand" "")
5874 (define_expand "ffssi2"
5876 (match_operand:SI 1 "register_operand" ""))
5877 (parallel [(set (reg:HI 24)
5878 (truncate:HI (ffs:SI (reg:SI 22))))
5879 (clobber (reg:QI 22))
5880 (clobber (reg:QI 26))])
5883 (set (match_operand:SI 0 "register_operand" "")
5884 (zero_extend:SI (match_dup 2)))]
5887 operands[2] = gen_reg_rtx (HImode);
5890 (define_insn "*ffshi2.libgcc"
5892 (ffs:HI (reg:HI 24)))
5893 (clobber (reg:QI 26))]
5896 [(set_attr "type" "xcall")
5897 (set_attr "cc" "clobber")])
5899 (define_insn "*ffssihi2.libgcc"
5901 (truncate:HI (ffs:SI (reg:SI 22))))
5902 (clobber (reg:QI 22))
5903 (clobber (reg:QI 26))]
5906 [(set_attr "type" "xcall")
5907 (set_attr "cc" "clobber")])
5911 (define_insn "copysignsf3"
5912 [(set (match_operand:SF 0 "register_operand" "=r")
5913 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5914 (match_operand:SF 2 "register_operand" "r")]
5917 "bst %D2,7\;bld %D0,7"
5918 [(set_attr "length" "2")
5919 (set_attr "cc" "none")])
5921 ;; Swap Bytes (change byte-endianess)
5923 (define_expand "bswapsi2"
5925 (match_operand:SI 1 "register_operand" ""))
5927 (bswap:SI (reg:SI 22)))
5928 (set (match_operand:SI 0 "register_operand" "")
5931 (define_insn "*bswapsi2.libgcc"
5933 (bswap:SI (reg:SI 22)))]
5936 [(set_attr "type" "xcall")
5937 (set_attr "cc" "clobber")])
5942 ;; NOP taking 1 or 2 Ticks
5943 (define_expand "nopv"
5944 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5947 (unspec_volatile:BLK [(match_dup 1)]
5948 UNSPECV_MEMORY_BARRIER))])]
5951 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5952 MEM_VOLATILE_P (operands[1]) = 1;
5955 (define_insn "*nopv"
5956 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5958 (set (match_operand:BLK 1 "" "")
5959 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5964 [(set_attr "length" "1")
5965 (set_attr "cc" "none")])
5968 (define_expand "sleep"
5969 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5971 (unspec_volatile:BLK [(match_dup 0)]
5972 UNSPECV_MEMORY_BARRIER))])]
5975 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5976 MEM_VOLATILE_P (operands[0]) = 1;
5979 (define_insn "*sleep"
5980 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5981 (set (match_operand:BLK 0 "" "")
5982 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
5985 [(set_attr "length" "1")
5986 (set_attr "cc" "none")])
5989 (define_expand "wdr"
5990 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5992 (unspec_volatile:BLK [(match_dup 0)]
5993 UNSPECV_MEMORY_BARRIER))])]
5996 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5997 MEM_VOLATILE_P (operands[0]) = 1;
6001 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6002 (set (match_operand:BLK 0 "" "")
6003 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6006 [(set_attr "length" "1")
6007 (set_attr "cc" "none")])
6010 (define_expand "fmul"
6012 (match_operand:QI 1 "register_operand" ""))
6014 (match_operand:QI 2 "register_operand" ""))
6015 (parallel [(set (reg:HI 22)
6016 (unspec:HI [(reg:QI 24)
6017 (reg:QI 25)] UNSPEC_FMUL))
6018 (clobber (reg:HI 24))])
6019 (set (match_operand:HI 0 "register_operand" "")
6025 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6030 (define_insn "fmul_insn"
6031 [(set (match_operand:HI 0 "register_operand" "=r")
6032 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6033 (match_operand:QI 2 "register_operand" "a")]
6039 [(set_attr "length" "3")
6040 (set_attr "cc" "clobber")])
6042 (define_insn "*fmul.call"
6044 (unspec:HI [(reg:QI 24)
6045 (reg:QI 25)] UNSPEC_FMUL))
6046 (clobber (reg:HI 24))]
6049 [(set_attr "type" "xcall")
6050 (set_attr "cc" "clobber")])
6053 (define_expand "fmuls"
6055 (match_operand:QI 1 "register_operand" ""))
6057 (match_operand:QI 2 "register_operand" ""))
6058 (parallel [(set (reg:HI 22)
6059 (unspec:HI [(reg:QI 24)
6060 (reg:QI 25)] UNSPEC_FMULS))
6061 (clobber (reg:HI 24))])
6062 (set (match_operand:HI 0 "register_operand" "")
6068 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6073 (define_insn "fmuls_insn"
6074 [(set (match_operand:HI 0 "register_operand" "=r")
6075 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6076 (match_operand:QI 2 "register_operand" "a")]
6082 [(set_attr "length" "3")
6083 (set_attr "cc" "clobber")])
6085 (define_insn "*fmuls.call"
6087 (unspec:HI [(reg:QI 24)
6088 (reg:QI 25)] UNSPEC_FMULS))
6089 (clobber (reg:HI 24))]
6092 [(set_attr "type" "xcall")
6093 (set_attr "cc" "clobber")])
6096 (define_expand "fmulsu"
6098 (match_operand:QI 1 "register_operand" ""))
6100 (match_operand:QI 2 "register_operand" ""))
6101 (parallel [(set (reg:HI 22)
6102 (unspec:HI [(reg:QI 24)
6103 (reg:QI 25)] UNSPEC_FMULSU))
6104 (clobber (reg:HI 24))])
6105 (set (match_operand:HI 0 "register_operand" "")
6111 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6116 (define_insn "fmulsu_insn"
6117 [(set (match_operand:HI 0 "register_operand" "=r")
6118 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6119 (match_operand:QI 2 "register_operand" "a")]
6125 [(set_attr "length" "3")
6126 (set_attr "cc" "clobber")])
6128 (define_insn "*fmulsu.call"
6130 (unspec:HI [(reg:QI 24)
6131 (reg:QI 25)] UNSPEC_FMULSU))
6132 (clobber (reg:HI 24))]
6135 [(set_attr "type" "xcall")
6136 (set_attr "cc" "clobber")])
6139 ;; Some combiner patterns dealing with bits.
6142 ;; Move bit $3.0 into bit $0.$4
6143 (define_insn "*movbitqi.1-6.a"
6144 [(set (match_operand:QI 0 "register_operand" "=r")
6145 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6146 (match_operand:QI 2 "single_zero_operand" "n"))
6147 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6148 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6149 (match_operand:QI 5 "single_one_operand" "n"))))]
6150 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6151 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6152 "bst %3,0\;bld %0,%4"
6153 [(set_attr "length" "2")
6154 (set_attr "cc" "none")])
6156 ;; Move bit $3.0 into bit $0.$4
6157 ;; Variation of above. Unfortunately, there is no canonicalized representation
6158 ;; of moving around bits. So what we see here depends on how user writes down
6159 ;; bit manipulations.
6160 (define_insn "*movbitqi.1-6.b"
6161 [(set (match_operand:QI 0 "register_operand" "=r")
6162 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6163 (match_operand:QI 2 "single_zero_operand" "n"))
6164 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6166 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6167 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6168 "bst %3,0\;bld %0,%4"
6169 [(set_attr "length" "2")
6170 (set_attr "cc" "none")])
6172 ;; Move bit $3.0 into bit $0.0.
6173 ;; For bit 0, combiner generates slightly different pattern.
6174 (define_insn "*movbitqi.0"
6175 [(set (match_operand:QI 0 "register_operand" "=r")
6176 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6177 (match_operand:QI 2 "single_zero_operand" "n"))
6178 (and:QI (match_operand:QI 3 "register_operand" "r")
6180 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6181 "bst %3,0\;bld %0,0"
6182 [(set_attr "length" "2")
6183 (set_attr "cc" "none")])
6185 ;; Move bit $2.0 into bit $0.7.
6186 ;; For bit 7, combiner generates slightly different pattern
6187 (define_insn "*movbitqi.7"
6188 [(set (match_operand:QI 0 "register_operand" "=r")
6189 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6191 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6194 "bst %2,0\;bld %0,7"
6195 [(set_attr "length" "2")
6196 (set_attr "cc" "none")])
6198 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6199 ;; and input/output match. We provide a special pattern for this, because
6200 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6201 ;; operation on I/O is atomic.
6202 (define_insn "*insv.io"
6203 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6205 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6206 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6211 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6212 [(set_attr "length" "1,1,4")
6213 (set_attr "cc" "none")])
6215 (define_insn "*insv.not.io"
6216 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6218 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6219 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6221 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6222 [(set_attr "length" "4")
6223 (set_attr "cc" "none")])
6225 ;; The insv expander.
6226 ;; We only support 1-bit inserts
6227 (define_expand "insv"
6228 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6229 (match_operand:QI 1 "const1_operand" "") ; width
6230 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6231 (match_operand:QI 3 "nonmemory_operand" ""))]
6234 ;; Insert bit $2.0 into $0.$1
6235 (define_insn "*insv.reg"
6236 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6238 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6239 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6243 andi %0,lo8(~(1<<%1))
6247 [(set_attr "length" "2,1,1,2,2")
6248 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6251 ;; Some combine patterns that try to fix bad code when a value is composed
6252 ;; from byte parts like in PR27663.
6253 ;; The patterns give some release but the code still is not optimal,
6254 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6255 ;; That switch obfuscates things here and in many other places.
6257 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6258 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6259 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6260 [(set (match_operand:HISI 0 "register_operand" "=r")
6262 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6263 (match_operand:HISI 2 "register_operand" "0")))]
6268 (xior:QI (match_dup 3)
6271 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6274 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6275 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6276 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6277 [(set (match_operand:HISI 0 "register_operand" "=r")
6279 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6280 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6281 (match_operand:HISI 3 "register_operand" "0")))]
6282 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6284 "&& reload_completed"
6286 (xior:QI (match_dup 4)
6289 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6290 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6293 (define_expand "extzv"
6294 [(set (match_operand:QI 0 "register_operand" "")
6295 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6296 (match_operand:QI 2 "const1_operand" "")
6297 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6299 (define_insn "*extzv"
6300 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6301 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6303 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6307 mov %0,%1\;andi %0,1
6310 bst %1,%2\;clr %0\;bld %0,0"
6311 [(set_attr "length" "1,2,2,2,3")
6312 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6314 (define_insn_and_split "*extzv.qihi1"
6315 [(set (match_operand:HI 0 "register_operand" "=r")
6316 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6318 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6323 (zero_extract:QI (match_dup 1)
6329 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6330 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6333 (define_insn_and_split "*extzv.qihi2"
6334 [(set (match_operand:HI 0 "register_operand" "=r")
6336 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6338 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6343 (zero_extract:QI (match_dup 1)
6349 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6350 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6354 ;; Fixed-point instructions
6355 (include "avr-fixed.md")
6357 ;; Operations on 64-bit registers
6358 (include "avr-dimode.md")