1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998-2013 Free Software Foundation, Inc.
4 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;; Special characters after '%':
23 ;; A No effect (add 0).
24 ;; B Add 1 to REG number, MEM address or CONST_INT.
27 ;; j Branch condition.
28 ;; k Reverse branch condition.
29 ;;..m..Constant Direct Data memory address.
30 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
31 ;; RAM address. The resulting address is suitable to be used in IN/OUT.
32 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
33 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
34 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
35 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
36 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
37 ;; just cashes the operand for the next %T. The second %T gets
38 ;; a CONST_INT that represents a bit position.
39 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
40 ;; "%T0%T1" it will print "r19,5".
41 ;; Notice that you must not write a comma between %T0 and %T1.
42 ;; T/t Similar to above, but don't print the comma and the bit number.
43 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
44 ;; "%T0%t1" it will print "r19".
45 ;;..x..Constant Direct Program memory address.
46 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
47 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
56 (LPM_REGNO 0) ; implicit target register of LPM
57 (TMP_REGNO 0) ; temporary register r0
58 (ZERO_REGNO 1) ; zero register r1
61 (define_c_enum "unspec"
73 (define_c_enum "unspecv"
74 [UNSPECV_PROLOGUE_SAVES
75 UNSPECV_EPILOGUE_RESTORES
79 UNSPECV_MEMORY_BARRIER
87 (include "predicates.md")
88 (include "constraints.md")
90 ;; Condition code settings.
91 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
93 (const_string "none"))
95 (define_attr "type" "branch,branch1,arith,xcall"
96 (const_string "arith"))
98 ;; The size of instructions in bytes.
99 ;; XXX may depend from "cc"
101 (define_attr "length" ""
102 (cond [(eq_attr "type" "branch")
103 (if_then_else (and (ge (minus (pc) (match_dup 0))
105 (le (minus (pc) (match_dup 0))
108 (if_then_else (and (ge (minus (pc) (match_dup 0))
110 (le (minus (pc) (match_dup 0))
114 (eq_attr "type" "branch1")
115 (if_then_else (and (ge (minus (pc) (match_dup 0))
117 (le (minus (pc) (match_dup 0))
120 (if_then_else (and (ge (minus (pc) (match_dup 0))
122 (le (minus (pc) (match_dup 0))
126 (eq_attr "type" "xcall")
127 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
132 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
133 ;; Following insn attribute tells if and how the adjustment has to be
135 ;; no No adjustment needed; attribute "length" is fine.
136 ;; Otherwise do special processing depending on the attribute.
138 (define_attr "adjust_len"
139 "out_bitop, plus, addto_sp,
140 tsthi, tstpsi, tstsi, compare, compare64, call,
141 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
144 ashlqi, ashrqi, lshrqi,
145 ashlhi, ashrhi, lshrhi,
146 ashlsi, ashrsi, lshrsi,
147 ashlpsi, ashrpsi, lshrpsi,
152 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
154 ;; mov : ISA has no MOVW movw : ISA has MOVW
155 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
156 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
157 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
158 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
159 ;; no_xmega: non-XMEGA core xmega : XMEGA core
162 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
164 (const_string "standard"))
166 (define_attr "enabled" ""
167 (cond [(eq_attr "isa" "standard")
170 (and (eq_attr "isa" "mov")
171 (match_test "!AVR_HAVE_MOVW"))
174 (and (eq_attr "isa" "movw")
175 (match_test "AVR_HAVE_MOVW"))
178 (and (eq_attr "isa" "rjmp")
179 (match_test "!AVR_HAVE_JMP_CALL"))
182 (and (eq_attr "isa" "jmp")
183 (match_test "AVR_HAVE_JMP_CALL"))
186 (and (eq_attr "isa" "ijmp")
187 (match_test "!AVR_HAVE_EIJMP_EICALL"))
190 (and (eq_attr "isa" "eijmp")
191 (match_test "AVR_HAVE_EIJMP_EICALL"))
194 (and (eq_attr "isa" "lpm")
195 (match_test "!AVR_HAVE_LPMX"))
198 (and (eq_attr "isa" "lpmx")
199 (match_test "AVR_HAVE_LPMX"))
202 (and (eq_attr "isa" "elpm")
203 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
206 (and (eq_attr "isa" "elpmx")
207 (match_test "AVR_HAVE_ELPMX"))
210 (and (eq_attr "isa" "xmega")
211 (match_test "AVR_XMEGA"))
214 (and (eq_attr "isa" "no_xmega")
215 (match_test "!AVR_XMEGA"))
220 ;; Define mode iterators
221 (define_mode_iterator QIHI [QI HI])
222 (define_mode_iterator QIHI2 [QI HI])
223 (define_mode_iterator QISI [QI HI PSI SI])
224 (define_mode_iterator QIDI [QI HI PSI SI DI])
225 (define_mode_iterator HISI [HI PSI SI])
227 (define_mode_iterator ALL1 [QI QQ UQQ])
228 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
229 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
231 ;; All supported move-modes
232 (define_mode_iterator MOVMODE [QI QQ UQQ
237 ;; Supported ordered modes that are 2, 3, 4 bytes wide
238 (define_mode_iterator ORDERED234 [HI SI PSI
242 ;; Define code iterators
243 ;; Define two incarnations so that we can build the cross product.
244 (define_code_iterator any_extend [sign_extend zero_extend])
245 (define_code_iterator any_extend2 [sign_extend zero_extend])
247 (define_code_iterator xior [xor ior])
248 (define_code_iterator eqne [eq ne])
250 (define_code_iterator ss_addsub [ss_plus ss_minus])
251 (define_code_iterator us_addsub [us_plus us_minus])
252 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
254 ;; Define code attributes
255 (define_code_attr extend_su
259 (define_code_attr extend_u
263 (define_code_attr extend_s
267 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
268 (define_code_attr mul_r_d
272 (define_code_attr abelian
273 [(ss_minus "") (us_minus "")
274 (ss_plus "%") (us_plus "%")])
276 ;; Map RTX code to its standard insn name
277 (define_code_attr code_stdname
284 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
285 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
288 ;;========================================================================
289 ;; The following is used by nonlocal_goto and setjmp.
290 ;; The receiver pattern will create no instructions since internally
291 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
292 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
293 ;; The 'null' receiver also avoids problems with optimisation
294 ;; not recognising incoming jmp and removing code that resets frame_pointer.
295 ;; The code derived from builtins.c.
297 (define_expand "nonlocal_goto_receiver"
299 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
302 emit_move_insn (virtual_stack_vars_rtx,
303 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
304 gen_int_mode (STARTING_FRAME_OFFSET,
306 /* ; This might change the hard frame pointer in ways that aren't
307 ; apparent to early optimization passes, so force a clobber. */
308 emit_clobber (hard_frame_pointer_rtx);
313 ;; Defining nonlocal_goto_receiver means we must also define this.
314 ;; even though its function is identical to that in builtins.c
316 (define_expand "nonlocal_goto"
317 [(use (match_operand 0 "general_operand"))
318 (use (match_operand 1 "general_operand"))
319 (use (match_operand 2 "general_operand"))
320 (use (match_operand 3 "general_operand"))]
323 rtx r_label = copy_to_reg (operands[1]);
324 rtx r_fp = operands[3];
325 rtx r_sp = operands[2];
327 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
329 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
331 emit_move_insn (hard_frame_pointer_rtx, r_fp);
332 emit_stack_restore (SAVE_NONLOCAL, r_sp);
334 emit_use (hard_frame_pointer_rtx);
335 emit_use (stack_pointer_rtx);
337 emit_indirect_jump (r_label);
343 ;; "pushqq1" "pushuqq1"
344 (define_insn "push<mode>1"
345 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
346 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
351 [(set_attr "length" "1,1")])
353 ;; All modes for a multi-byte push. We must include complex modes here too,
354 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
355 (define_mode_iterator MPUSH
364 (define_expand "push<mode>1"
365 [(match_operand:MPUSH 0 "" "")]
369 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
371 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
372 if (part != const0_rtx)
373 part = force_reg (QImode, part);
374 emit_insn (gen_pushqi1 (part));
379 ;; Notice a special-case when adding N to SP where N results in a
380 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
382 [(set (reg:HI REG_SP)
383 (match_operand:HI 0 "register_operand" ""))]
385 && frame_pointer_needed
386 && !cfun->calls_alloca
387 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
388 [(set (reg:HI REG_SP)
391 ;;========================================================================
394 ;; Secondary input reload from non-generic 16-bit address spaces
395 (define_insn "reload_in<mode>"
396 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
397 (match_operand:MOVMODE 1 "flash_operand" "m"))
398 (clobber (match_operand:QI 2 "d_register_operand" "=d"))]
399 ;; Fixme: The insn condition must not test the address space.
400 ;; Because the gen tools refuse to generate insns for address spaces
401 ;; and will generate insn-codes.h to look like:
402 ;; #define CODE_FOR_reload_inhi CODE_FOR_nothing
403 "reload_completed || reload_in_progress"
405 return avr_out_lpm (insn, operands, NULL);
407 [(set_attr "adjust_len" "lpm")
408 (set_attr "cc" "clobber")])
416 (define_expand "load<mode>_libgcc"
419 (set (reg:MOVMODE 22)
420 (match_operand:MOVMODE 1 "memory_operand" ""))
421 (set (match_operand:MOVMODE 0 "register_operand" "")
423 "avr_load_libgcc_p (operands[1])"
425 operands[3] = gen_rtx_REG (HImode, REG_Z);
426 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
427 operands[1] = replace_equiv_address (operands[1], operands[3]);
428 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
436 (define_insn "load_<mode>_libgcc"
437 [(set (reg:MOVMODE 22)
438 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
439 "avr_load_libgcc_p (operands[0])
440 && REG_P (XEXP (operands[0], 0))
441 && REG_Z == REGNO (XEXP (operands[0], 0))"
443 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
444 return "%~call __load_%0";
446 [(set_attr "length" "1,2")
447 (set_attr "isa" "rjmp,jmp")
448 (set_attr "cc" "clobber")])
452 ;; "xload8qq_A" "xload8uqq_A"
453 (define_insn_and_split "xload8<mode>_A"
454 [(set (match_operand:ALL1 0 "register_operand" "=r")
455 (match_operand:ALL1 1 "memory_operand" "m"))
456 (clobber (reg:HI REG_Z))]
457 "can_create_pseudo_p()
458 && !avr_xload_libgcc_p (<MODE>mode)
459 && avr_mem_memx_p (operands[1])
460 && REG_P (XEXP (operands[1], 0))"
461 { gcc_unreachable(); }
463 [(clobber (const_int 0))]
465 /* ; Split away the high part of the address. GCC's register allocator
466 ; in not able to allocate segment registers and reload the resulting
467 ; expressions. Notice that no address register can hold a PSImode. */
469 rtx insn, addr = XEXP (operands[1], 0);
470 rtx hi8 = gen_reg_rtx (QImode);
471 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
473 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
474 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
476 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
477 set_mem_addr_space (SET_SRC (single_set (insn)),
478 MEM_ADDR_SPACE (operands[1]));
482 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
483 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
484 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
487 (define_insn_and_split "xload<mode>_A"
488 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
489 (match_operand:MOVMODE 1 "memory_operand" "m"))
490 (clobber (reg:MOVMODE 22))
491 (clobber (reg:QI 21))
492 (clobber (reg:HI REG_Z))]
493 "can_create_pseudo_p()
494 && avr_mem_memx_p (operands[1])
495 && REG_P (XEXP (operands[1], 0))"
496 { gcc_unreachable(); }
498 [(clobber (const_int 0))]
500 rtx addr = XEXP (operands[1], 0);
501 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
502 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
503 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
506 /* Split the address to R21:Z */
507 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
508 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
510 /* Load with code from libgcc */
511 insn = emit_insn (gen_xload_<mode>_libgcc ());
512 set_mem_addr_space (SET_SRC (single_set (insn)), as);
514 /* Move to destination */
515 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
520 ;; Move value from address space memx to a register
521 ;; These insns must be prior to respective generic move insn.
524 ;; "xloadqq_8" "xloaduqq_8"
525 (define_insn "xload<mode>_8"
526 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
527 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
529 "!avr_xload_libgcc_p (<MODE>mode)"
531 return avr_out_xload (insn, operands, NULL);
533 [(set_attr "length" "4,4")
534 (set_attr "adjust_len" "*,xload")
535 (set_attr "isa" "lpmx,lpm")
536 (set_attr "cc" "none")])
538 ;; R21:Z : 24-bit source address
539 ;; R22 : 1-4 byte output
541 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
542 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
543 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
545 ;; "xload_psi_libgcc"
546 (define_insn "xload_<mode>_libgcc"
547 [(set (reg:MOVMODE 22)
548 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
550 (clobber (reg:QI 21))
551 (clobber (reg:HI REG_Z))]
552 "avr_xload_libgcc_p (<MODE>mode)"
554 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
556 output_asm_insn ("%~call __xload_%0", &x_bytes);
559 [(set_attr "type" "xcall")
560 (set_attr "cc" "clobber")])
563 ;; General move expanders
565 ;; "movqi" "movqq" "movuqq"
566 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
567 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
570 (define_expand "mov<mode>"
571 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
572 (match_operand:MOVMODE 1 "general_operand" ""))]
575 rtx dest = operands[0];
576 rtx src = operands[1];
578 if (avr_mem_flash_p (dest))
581 /* One of the operands has to be in a register. */
582 if (!register_operand (dest, <MODE>mode)
583 && !reg_or_0_operand (src, <MODE>mode))
585 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
588 if (avr_mem_memx_p (src))
590 rtx addr = XEXP (src, 0);
593 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
595 if (!avr_xload_libgcc_p (<MODE>mode))
596 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
597 ; insn-emit does not depend on the mode, it's all about operands. */
598 emit_insn (gen_xload8qi_A (dest, src));
600 emit_insn (gen_xload<mode>_A (dest, src));
605 if (avr_load_libgcc_p (src))
607 /* For the small devices, do loads per libgcc call. */
608 emit_insn (gen_load<mode>_libgcc (dest, src));
613 ;;========================================================================
615 ;; The last alternative (any immediate constant to any register) is
616 ;; very expensive. It should be optimized by peephole2 if a scratch
617 ;; register is available, but then that register could just as well be
618 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
619 ;; are call-saved registers, and most of LD_REGS are call-used registers,
620 ;; so this may still be a win for registers live across function calls.
623 ;; "movqq_insn" "movuqq_insn"
624 (define_insn "mov<mode>_insn"
625 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
626 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
627 "register_operand (operands[0], <MODE>mode)
628 || reg_or_0_operand (operands[1], <MODE>mode)"
630 return output_movqi (insn, operands, NULL);
632 [(set_attr "length" "1,1,5,5,1,1,4")
633 (set_attr "adjust_len" "mov8")
634 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
636 ;; This is used in peephole2 to optimize loading immediate constants
637 ;; if a scratch register from LD_REGS happens to be available.
640 ;; "*reload_inqq" "*reload_inuqq"
641 (define_insn "*reload_in<mode>"
642 [(set (match_operand:ALL1 0 "register_operand" "=l")
643 (match_operand:ALL1 1 "const_operand" "i"))
644 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
648 [(set_attr "length" "2")
649 (set_attr "cc" "none")])
652 [(match_scratch:QI 2 "d")
653 (set (match_operand:ALL1 0 "l_register_operand" "")
654 (match_operand:ALL1 1 "const_operand" ""))]
655 ; No need for a clobber reg for 0x0, 0x01 or 0xff
656 "!satisfies_constraint_Y00 (operands[1])
657 && !satisfies_constraint_Y01 (operands[1])
658 && !satisfies_constraint_Ym1 (operands[1])"
659 [(parallel [(set (match_dup 0)
661 (clobber (match_dup 2))])])
663 ;;============================================================================
664 ;; move word (16 bit)
666 ;; Move register $1 to the Stack Pointer register SP.
667 ;; This insn is emit during function prologue/epilogue generation.
668 ;; $2 = 0: We know that IRQs are off
669 ;; $2 = 1: We know that IRQs are on
670 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
671 ;; $2 = -1: We don't know anything about IRQ on/off
672 ;; Always write SP via unspec, see PR50063
674 (define_insn "movhi_sp_r"
675 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
676 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
677 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
681 out %B0,%B1\;out %A0,%A1
682 cli\;out %B0,%B1\;sei\;out %A0,%A1
683 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
685 out %A0,%A1\;out %B0,%B1"
686 [(set_attr "length" "2,4,5,1,2")
687 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
688 (set_attr "cc" "none")])
691 [(match_scratch:QI 2 "d")
692 (set (match_operand:ALL2 0 "l_register_operand" "")
693 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
694 "operands[1] != CONST0_RTX (<MODE>mode)"
695 [(parallel [(set (match_dup 0)
697 (clobber (match_dup 2))])])
699 ;; '*' because it is not used in rtl generation, only in above peephole
701 ;; "*reload_inhq" "*reload_inuhq"
702 ;; "*reload_inha" "*reload_inuha"
703 (define_insn "*reload_in<mode>"
704 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
705 (match_operand:ALL2 1 "immediate_operand" "i"))
706 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
709 return output_reload_inhi (operands, operands[2], NULL);
711 [(set_attr "length" "4")
712 (set_attr "adjust_len" "reload_in16")
713 (set_attr "cc" "clobber")])
716 ;; "*movhq" "*movuhq"
717 ;; "*movha" "*movuha"
718 (define_insn "*mov<mode>"
719 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
720 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
721 "register_operand (operands[0], <MODE>mode)
722 || reg_or_0_operand (operands[1], <MODE>mode)"
724 return output_movhi (insn, operands, NULL);
726 [(set_attr "length" "2,2,6,7,2,6,5,2")
727 (set_attr "adjust_len" "mov16")
728 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
730 (define_peephole2 ; movw
731 [(set (match_operand:ALL1 0 "even_register_operand" "")
732 (match_operand:ALL1 1 "even_register_operand" ""))
733 (set (match_operand:ALL1 2 "odd_register_operand" "")
734 (match_operand:ALL1 3 "odd_register_operand" ""))]
736 && REGNO (operands[0]) == REGNO (operands[2]) - 1
737 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
741 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
742 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
745 (define_peephole2 ; movw_r
746 [(set (match_operand:ALL1 0 "odd_register_operand" "")
747 (match_operand:ALL1 1 "odd_register_operand" ""))
748 (set (match_operand:ALL1 2 "even_register_operand" "")
749 (match_operand:ALL1 3 "even_register_operand" ""))]
751 && REGNO (operands[2]) == REGNO (operands[0]) - 1
752 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
756 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
757 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
760 ;; For LPM loads from AS1 we split
764 ;; Z = Z - sizeof (R)
766 ;; so that the second instruction can be optimized out.
768 (define_split ; "split-lpmx"
769 [(set (match_operand:HISI 0 "register_operand" "")
770 (match_operand:HISI 1 "memory_operand" ""))]
776 (plus:HI (match_dup 3)
779 rtx addr = XEXP (operands[1], 0);
781 if (!avr_mem_flash_p (operands[1])
783 || reg_overlap_mentioned_p (addr, operands[0]))
788 operands[2] = replace_equiv_address (operands[1],
789 gen_rtx_POST_INC (Pmode, addr));
791 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
794 ;;==========================================================================
795 ;; xpointer move (24 bit)
797 (define_peephole2 ; *reload_inpsi
798 [(match_scratch:QI 2 "d")
799 (set (match_operand:PSI 0 "l_register_operand" "")
800 (match_operand:PSI 1 "immediate_operand" ""))
802 "operands[1] != const0_rtx
803 && operands[1] != constm1_rtx"
804 [(parallel [(set (match_dup 0)
806 (clobber (match_dup 2))])])
808 ;; '*' because it is not used in rtl generation.
809 (define_insn "*reload_inpsi"
810 [(set (match_operand:PSI 0 "register_operand" "=r")
811 (match_operand:PSI 1 "immediate_operand" "i"))
812 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
815 return avr_out_reload_inpsi (operands, operands[2], NULL);
817 [(set_attr "length" "6")
818 (set_attr "adjust_len" "reload_in24")
819 (set_attr "cc" "clobber")])
821 (define_insn "*movpsi"
822 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
823 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
824 "register_operand (operands[0], PSImode)
825 || register_operand (operands[1], PSImode)
826 || const0_rtx == operands[1]"
828 return avr_out_movpsi (insn, operands, NULL);
830 [(set_attr "length" "3,3,8,9,4,10")
831 (set_attr "adjust_len" "mov24")
832 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
834 ;;==========================================================================
835 ;; move double word (32 bit)
837 (define_peephole2 ; *reload_insi
838 [(match_scratch:QI 2 "d")
839 (set (match_operand:ALL4 0 "l_register_operand" "")
840 (match_operand:ALL4 1 "immediate_operand" ""))
842 "operands[1] != CONST0_RTX (<MODE>mode)"
843 [(parallel [(set (match_dup 0)
845 (clobber (match_dup 2))])])
847 ;; '*' because it is not used in rtl generation.
849 ;; "*reload_insq" "*reload_inusq"
850 ;; "*reload_insa" "*reload_inusa"
851 (define_insn "*reload_insi"
852 [(set (match_operand:ALL4 0 "register_operand" "=r")
853 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
854 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
857 return output_reload_insisf (operands, operands[2], NULL);
859 [(set_attr "length" "8")
860 (set_attr "adjust_len" "reload_in32")
861 (set_attr "cc" "clobber")])
865 ;; "*movsq" "*movusq"
866 ;; "*movsa" "*movusa"
867 (define_insn "*mov<mode>"
868 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
869 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
870 "register_operand (operands[0], <MODE>mode)
871 || reg_or_0_operand (operands[1], <MODE>mode)"
873 return output_movsisf (insn, operands, NULL);
875 [(set_attr "length" "4,4,8,9,4,10")
876 (set_attr "adjust_len" "mov32")
877 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
879 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
880 ;; move floating point numbers (32 bit)
882 (define_insn "*movsf"
883 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
884 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
885 "register_operand (operands[0], SFmode)
886 || reg_or_0_operand (operands[1], SFmode)"
888 return output_movsisf (insn, operands, NULL);
890 [(set_attr "length" "4,4,8,9,4,10")
891 (set_attr "adjust_len" "mov32")
892 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
894 (define_peephole2 ; *reload_insf
895 [(match_scratch:QI 2 "d")
896 (set (match_operand:SF 0 "l_register_operand" "")
897 (match_operand:SF 1 "const_double_operand" ""))
899 "operands[1] != CONST0_RTX (SFmode)"
900 [(parallel [(set (match_dup 0)
902 (clobber (match_dup 2))])])
904 ;; '*' because it is not used in rtl generation.
905 (define_insn "*reload_insf"
906 [(set (match_operand:SF 0 "register_operand" "=r")
907 (match_operand:SF 1 "const_double_operand" "F"))
908 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
911 return output_reload_insisf (operands, operands[2], NULL);
913 [(set_attr "length" "8")
914 (set_attr "adjust_len" "reload_in32")
915 (set_attr "cc" "clobber")])
917 ;;=========================================================================
918 ;; move string (like memcpy)
920 (define_expand "movmemhi"
921 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
922 (match_operand:BLK 1 "memory_operand" ""))
923 (use (match_operand:HI 2 "const_int_operand" ""))
924 (use (match_operand:HI 3 "const_int_operand" ""))])]
927 if (avr_emit_movmemhi (operands))
933 (define_mode_attr MOVMEM_r_d [(QI "r")
936 ;; $0 : Address Space
937 ;; $1, $2 : Loop register
938 ;; R30 : source address
939 ;; R26 : destination address
943 (define_insn "movmem_<mode>"
944 [(set (mem:BLK (reg:HI REG_X))
945 (mem:BLK (reg:HI REG_Z)))
946 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
948 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
949 (clobber (reg:HI REG_X))
950 (clobber (reg:HI REG_Z))
951 (clobber (reg:QI LPM_REGNO))
952 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
955 return avr_out_movmem (insn, operands, NULL);
957 [(set_attr "adjust_len" "movmem")
958 (set_attr "cc" "clobber")])
961 ;; $0 : Address Space
962 ;; $1 : RAMPZ RAM address
963 ;; R24 : #bytes and loop register
964 ;; R23:Z : 24-bit source address
965 ;; R26 : 16-bit destination address
969 (define_insn "movmemx_<mode>"
970 [(set (mem:BLK (reg:HI REG_X))
971 (mem:BLK (lo_sum:PSI (reg:QI 23)
973 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
976 (clobber (reg:HI REG_X))
977 (clobber (reg:HI REG_Z))
978 (clobber (reg:QI LPM_REGNO))
979 (clobber (reg:HI 24))
980 (clobber (reg:QI 23))
981 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
983 "%~call __movmemx_<mode>"
984 [(set_attr "type" "xcall")
985 (set_attr "cc" "clobber")])
988 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
989 ;; memset (%0, %2, %1)
991 (define_expand "setmemhi"
992 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
993 (match_operand 2 "const_int_operand" ""))
994 (use (match_operand:HI 1 "const_int_operand" ""))
995 (use (match_operand:HI 3 "const_int_operand" ""))
996 (clobber (match_scratch:HI 4 ""))
997 (clobber (match_dup 5))])]
1001 enum machine_mode mode;
1003 /* If value to set is not zero, use the library routine. */
1004 if (operands[2] != const0_rtx)
1007 if (!CONST_INT_P (operands[1]))
1010 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1011 operands[5] = gen_rtx_SCRATCH (mode);
1012 operands[1] = copy_to_mode_reg (mode,
1013 gen_int_mode (INTVAL (operands[1]), mode));
1014 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1015 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1019 (define_insn "*clrmemqi"
1020 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1022 (use (match_operand:QI 1 "register_operand" "r"))
1023 (use (match_operand:QI 2 "const_int_operand" "n"))
1024 (clobber (match_scratch:HI 3 "=0"))
1025 (clobber (match_scratch:QI 4 "=&1"))]
1027 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1028 [(set_attr "length" "3")
1029 (set_attr "cc" "clobber")])
1032 (define_insn "*clrmemhi"
1033 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1035 (use (match_operand:HI 1 "register_operand" "!w,d"))
1036 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1037 (clobber (match_scratch:HI 3 "=0,0"))
1038 (clobber (match_scratch:HI 4 "=&1,&1"))]
1041 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1042 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1043 [(set_attr "length" "3,4")
1044 (set_attr "cc" "clobber,clobber")])
1046 (define_expand "strlenhi"
1048 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1049 (match_operand:QI 2 "const_int_operand" "")
1050 (match_operand:HI 3 "immediate_operand" "")]
1053 (plus:HI (match_dup 4)
1055 (parallel [(set (match_operand:HI 0 "register_operand" "")
1056 (minus:HI (match_dup 4)
1058 (clobber (scratch:QI))])]
1062 if (operands[2] != const0_rtx)
1064 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1065 operands[1] = gen_rtx_MEM (BLKmode, addr);
1067 operands[4] = gen_reg_rtx (HImode);
1070 (define_insn "*strlenhi"
1071 [(set (match_operand:HI 0 "register_operand" "=e")
1072 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1074 (match_operand:HI 2 "immediate_operand" "i")]
1077 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1078 [(set_attr "length" "3")
1079 (set_attr "cc" "clobber")])
1081 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1085 ;; "addqq3" "adduqq3"
1086 (define_insn "add<mode>3"
1087 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1088 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1089 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1098 [(set_attr "length" "1,1,1,1,2,2")
1099 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1102 ;; "addhq3" "adduhq3"
1103 ;; "addha3" "adduha3"
1104 (define_expand "add<mode>3"
1105 [(set (match_operand:ALL2 0 "register_operand" "")
1106 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1107 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1110 if (CONST_INT_P (operands[2]))
1112 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1114 if (can_create_pseudo_p()
1115 && !stack_register_operand (operands[0], HImode)
1116 && !stack_register_operand (operands[1], HImode)
1117 && !d_register_operand (operands[0], HImode)
1118 && !d_register_operand (operands[1], HImode))
1120 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1125 if (CONST_FIXED_P (operands[2]))
1127 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1133 (define_insn "*addhi3_zero_extend"
1134 [(set (match_operand:HI 0 "register_operand" "=r")
1135 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1136 (match_operand:HI 2 "register_operand" "0")))]
1138 "add %A0,%1\;adc %B0,__zero_reg__"
1139 [(set_attr "length" "2")
1140 (set_attr "cc" "set_n")])
1142 (define_insn "*addhi3_zero_extend1"
1143 [(set (match_operand:HI 0 "register_operand" "=r")
1144 (plus:HI (match_operand:HI 1 "register_operand" "0")
1145 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1147 "add %A0,%2\;adc %B0,__zero_reg__"
1148 [(set_attr "length" "2")
1149 (set_attr "cc" "set_n")])
1151 (define_insn "*addhi3.sign_extend1"
1152 [(set (match_operand:HI 0 "register_operand" "=r")
1153 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1154 (match_operand:HI 2 "register_operand" "0")))]
1157 return reg_overlap_mentioned_p (operands[0], operands[1])
1158 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1159 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1161 [(set_attr "length" "5")
1162 (set_attr "cc" "clobber")])
1164 (define_insn "*addhi3_sp"
1165 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1166 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1167 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1170 return avr_out_addto_sp (operands, NULL);
1172 [(set_attr "length" "6")
1173 (set_attr "adjust_len" "addto_sp")])
1176 ;; "*addhq3" "*adduhq3"
1177 ;; "*addha3" "*adduha3"
1178 (define_insn "*add<mode>3"
1179 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1180 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1181 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1184 return avr_out_plus (insn, operands);
1186 [(set_attr "length" "2")
1187 (set_attr "adjust_len" "plus")
1188 (set_attr "cc" "plus")])
1190 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1191 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1192 ;; itself because that insn is special to reload.
1194 (define_peephole2 ; addhi3_clobber
1195 [(set (match_operand:ALL2 0 "d_register_operand" "")
1196 (match_operand:ALL2 1 "const_operand" ""))
1197 (set (match_operand:ALL2 2 "l_register_operand" "")
1198 (plus:ALL2 (match_dup 2)
1200 "peep2_reg_dead_p (2, operands[0])"
1201 [(parallel [(set (match_dup 2)
1202 (plus:ALL2 (match_dup 2)
1204 (clobber (match_dup 3))])]
1206 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1209 ;; Same, but with reload to NO_LD_REGS
1210 ;; Combine *reload_inhi with *addhi3
1212 (define_peephole2 ; addhi3_clobber
1213 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1214 (match_operand:ALL2 1 "const_operand" ""))
1215 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1216 (set (match_operand:ALL2 3 "l_register_operand" "")
1217 (plus:ALL2 (match_dup 3)
1219 "peep2_reg_dead_p (2, operands[0])"
1220 [(parallel [(set (match_dup 3)
1221 (plus:ALL2 (match_dup 3)
1223 (clobber (match_dup 2))])])
1226 ;; "addhq3_clobber" "adduhq3_clobber"
1227 ;; "addha3_clobber" "adduha3_clobber"
1228 (define_insn "add<mode>3_clobber"
1229 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1230 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1231 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1232 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1235 return avr_out_plus (insn, operands);
1237 [(set_attr "length" "4")
1238 (set_attr "adjust_len" "plus")
1239 (set_attr "cc" "plus")])
1243 ;; "addsq3" "addusq3"
1244 ;; "addsa3" "addusa3"
1245 (define_insn "add<mode>3"
1246 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1247 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1248 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1249 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1252 return avr_out_plus (insn, operands);
1254 [(set_attr "length" "4")
1255 (set_attr "adjust_len" "plus")
1256 (set_attr "cc" "plus")])
1258 (define_insn "*addpsi3_zero_extend.qi"
1259 [(set (match_operand:PSI 0 "register_operand" "=r")
1260 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1261 (match_operand:PSI 2 "register_operand" "0")))]
1263 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1264 [(set_attr "length" "3")
1265 (set_attr "cc" "set_n")])
1267 (define_insn "*addpsi3_zero_extend.hi"
1268 [(set (match_operand:PSI 0 "register_operand" "=r")
1269 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1270 (match_operand:PSI 2 "register_operand" "0")))]
1272 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1273 [(set_attr "length" "3")
1274 (set_attr "cc" "set_n")])
1276 (define_insn "*addpsi3_sign_extend.hi"
1277 [(set (match_operand:PSI 0 "register_operand" "=r")
1278 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1279 (match_operand:PSI 2 "register_operand" "0")))]
1281 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1282 [(set_attr "length" "5")
1283 (set_attr "cc" "set_n")])
1285 (define_insn "*addsi3_zero_extend"
1286 [(set (match_operand:SI 0 "register_operand" "=r")
1287 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1288 (match_operand:SI 2 "register_operand" "0")))]
1290 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1291 [(set_attr "length" "4")
1292 (set_attr "cc" "set_n")])
1294 (define_insn "*addsi3_zero_extend.hi"
1295 [(set (match_operand:SI 0 "register_operand" "=r")
1296 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1297 (match_operand:SI 2 "register_operand" "0")))]
1299 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1300 [(set_attr "length" "4")
1301 (set_attr "cc" "set_n")])
1303 (define_insn "addpsi3"
1304 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1305 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1306 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1307 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1310 return avr_out_plus (insn, operands);
1312 [(set_attr "length" "3")
1313 (set_attr "adjust_len" "plus")
1314 (set_attr "cc" "plus")])
1316 (define_insn "subpsi3"
1317 [(set (match_operand:PSI 0 "register_operand" "=r")
1318 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1319 (match_operand:PSI 2 "register_operand" "r")))]
1321 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1322 [(set_attr "length" "3")
1323 (set_attr "cc" "set_czn")])
1325 (define_insn "*subpsi3_zero_extend.qi"
1326 [(set (match_operand:PSI 0 "register_operand" "=r")
1327 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1328 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1330 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1331 [(set_attr "length" "3")
1332 (set_attr "cc" "set_czn")])
1334 (define_insn "*subpsi3_zero_extend.hi"
1335 [(set (match_operand:PSI 0 "register_operand" "=r")
1336 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1337 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1339 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1340 [(set_attr "length" "3")
1341 (set_attr "cc" "set_czn")])
1343 (define_insn "*subpsi3_sign_extend.hi"
1344 [(set (match_operand:PSI 0 "register_operand" "=r")
1345 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1346 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1348 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1349 [(set_attr "length" "5")
1350 (set_attr "cc" "set_czn")])
1352 ;-----------------------------------------------------------------------------
1356 ;; "subqq3" "subuqq3"
1357 (define_insn "sub<mode>3"
1358 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1359 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1360 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1369 [(set_attr "length" "1,1,1,1,2,2")
1370 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1373 ;; "subhq3" "subuhq3"
1374 ;; "subha3" "subuha3"
1375 (define_insn "sub<mode>3"
1376 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1377 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1378 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1379 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1382 return avr_out_plus (insn, operands);
1384 [(set_attr "adjust_len" "plus")
1385 (set_attr "cc" "plus")])
1387 (define_insn "*subhi3_zero_extend1"
1388 [(set (match_operand:HI 0 "register_operand" "=r")
1389 (minus:HI (match_operand:HI 1 "register_operand" "0")
1390 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1392 "sub %A0,%2\;sbc %B0,__zero_reg__"
1393 [(set_attr "length" "2")
1394 (set_attr "cc" "set_czn")])
1396 (define_insn "*subhi3.sign_extend2"
1397 [(set (match_operand:HI 0 "register_operand" "=r")
1398 (minus:HI (match_operand:HI 1 "register_operand" "0")
1399 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1402 return reg_overlap_mentioned_p (operands[0], operands[2])
1403 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1404 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1406 [(set_attr "length" "5")
1407 (set_attr "cc" "clobber")])
1410 ;; "subsq3" "subusq3"
1411 ;; "subsa3" "subusa3"
1412 (define_insn "sub<mode>3"
1413 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1414 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1415 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1416 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1419 return avr_out_plus (insn, operands);
1421 [(set_attr "adjust_len" "plus")
1422 (set_attr "cc" "plus")])
1424 (define_insn "*subsi3_zero_extend"
1425 [(set (match_operand:SI 0 "register_operand" "=r")
1426 (minus:SI (match_operand:SI 1 "register_operand" "0")
1427 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1429 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1430 [(set_attr "length" "4")
1431 (set_attr "cc" "set_czn")])
1433 (define_insn "*subsi3_zero_extend.hi"
1434 [(set (match_operand:SI 0 "register_operand" "=r")
1435 (minus:SI (match_operand:SI 1 "register_operand" "0")
1436 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1438 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1439 [(set_attr "length" "4")
1440 (set_attr "cc" "set_czn")])
1442 ;******************************************************************************
1445 (define_expand "mulqi3"
1446 [(set (match_operand:QI 0 "register_operand" "")
1447 (mult:QI (match_operand:QI 1 "register_operand" "")
1448 (match_operand:QI 2 "register_operand" "")))]
1453 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1458 (define_insn "*mulqi3_enh"
1459 [(set (match_operand:QI 0 "register_operand" "=r")
1460 (mult:QI (match_operand:QI 1 "register_operand" "r")
1461 (match_operand:QI 2 "register_operand" "r")))]
1466 [(set_attr "length" "3")
1467 (set_attr "cc" "clobber")])
1469 (define_expand "mulqi3_call"
1470 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1471 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1472 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1473 (clobber (reg:QI 22))])
1474 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
1476 (define_insn "*mulqi3_call"
1477 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1478 (clobber (reg:QI 22))]
1481 [(set_attr "type" "xcall")
1482 (set_attr "cc" "clobber")])
1484 ;; "umulqi3_highpart"
1485 ;; "smulqi3_highpart"
1486 (define_insn "<extend_su>mulqi3_highpart"
1487 [(set (match_operand:QI 0 "register_operand" "=r")
1489 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1490 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1493 "mul<extend_s> %1,%2
1496 [(set_attr "length" "3")
1497 (set_attr "cc" "clobber")])
1500 ;; Used when expanding div or mod inline for some special values
1501 (define_insn "*subqi3.ashiftrt7"
1502 [(set (match_operand:QI 0 "register_operand" "=r")
1503 (minus:QI (match_operand:QI 1 "register_operand" "0")
1504 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1508 [(set_attr "length" "2")
1509 (set_attr "cc" "clobber")])
1511 (define_insn "*addqi3.lt0"
1512 [(set (match_operand:QI 0 "register_operand" "=r")
1513 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1515 (match_operand:QI 2 "register_operand" "0")))]
1518 [(set_attr "length" "2")
1519 (set_attr "cc" "clobber")])
1521 (define_insn "*addhi3.lt0"
1522 [(set (match_operand:HI 0 "register_operand" "=w,r")
1523 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1525 (match_operand:HI 2 "register_operand" "0,0")))
1526 (clobber (match_scratch:QI 3 "=X,&1"))]
1529 sbrc %1,7\;adiw %0,1
1530 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1531 [(set_attr "length" "2,3")
1532 (set_attr "cc" "clobber")])
1534 (define_insn "*addpsi3.lt0"
1535 [(set (match_operand:PSI 0 "register_operand" "=r")
1536 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1538 (match_operand:PSI 2 "register_operand" "0")))]
1540 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1541 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1542 [(set_attr "length" "5")
1543 (set_attr "cc" "clobber")])
1545 (define_insn "*addsi3.lt0"
1546 [(set (match_operand:SI 0 "register_operand" "=r")
1547 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1549 (match_operand:SI 2 "register_operand" "0")))]
1551 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1552 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1553 [(set_attr "length" "6")
1554 (set_attr "cc" "clobber")])
1556 (define_insn "*umulqihi3.call"
1558 (mult:HI (zero_extend:HI (reg:QI 22))
1559 (zero_extend:HI (reg:QI 24))))
1560 (clobber (reg:QI 21))
1561 (clobber (reg:HI 22))]
1563 "%~call __umulqihi3"
1564 [(set_attr "type" "xcall")
1565 (set_attr "cc" "clobber")])
1569 (define_insn "<extend_u>mulqihi3"
1570 [(set (match_operand:HI 0 "register_operand" "=r")
1571 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1572 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1574 "mul<extend_s> %1,%2
1577 [(set_attr "length" "3")
1578 (set_attr "cc" "clobber")])
1580 (define_insn "usmulqihi3"
1581 [(set (match_operand:HI 0 "register_operand" "=r")
1582 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1583 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1588 [(set_attr "length" "3")
1589 (set_attr "cc" "clobber")])
1591 ;; Above insn is not canonicalized by insn combine, so here is a version with
1592 ;; operands swapped.
1594 (define_insn "*sumulqihi3"
1595 [(set (match_operand:HI 0 "register_operand" "=r")
1596 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1597 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1602 [(set_attr "length" "3")
1603 (set_attr "cc" "clobber")])
1605 ;; One-extend operand 1
1607 (define_insn "*osmulqihi3"
1608 [(set (match_operand:HI 0 "register_operand" "=&r")
1609 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1610 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1616 [(set_attr "length" "4")
1617 (set_attr "cc" "clobber")])
1619 (define_insn "*oumulqihi3"
1620 [(set (match_operand:HI 0 "register_operand" "=&r")
1621 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1622 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1628 [(set_attr "length" "4")
1629 (set_attr "cc" "clobber")])
1631 ;******************************************************************************
1632 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1633 ;******************************************************************************
1635 (define_insn "*maddqi4"
1636 [(set (match_operand:QI 0 "register_operand" "=r")
1637 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1638 (match_operand:QI 2 "register_operand" "r"))
1639 (match_operand:QI 3 "register_operand" "0")))]
1645 [(set_attr "length" "4")
1646 (set_attr "cc" "clobber")])
1648 (define_insn "*msubqi4"
1649 [(set (match_operand:QI 0 "register_operand" "=r")
1650 (minus:QI (match_operand:QI 3 "register_operand" "0")
1651 (mult:QI (match_operand:QI 1 "register_operand" "r")
1652 (match_operand:QI 2 "register_operand" "r"))))]
1657 [(set_attr "length" "4")
1658 (set_attr "cc" "clobber")])
1660 (define_insn_and_split "*maddqi4.const"
1661 [(set (match_operand:QI 0 "register_operand" "=r")
1662 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1663 (match_operand:QI 2 "const_int_operand" "n"))
1664 (match_operand:QI 3 "register_operand" "0")))
1665 (clobber (match_scratch:QI 4 "=&d"))]
1668 "&& reload_completed"
1673 (plus:QI (mult:QI (match_dup 1)
1677 (define_insn_and_split "*msubqi4.const"
1678 [(set (match_operand:QI 0 "register_operand" "=r")
1679 (minus:QI (match_operand:QI 3 "register_operand" "0")
1680 (mult:QI (match_operand:QI 1 "register_operand" "r")
1681 (match_operand:QI 2 "const_int_operand" "n"))))
1682 (clobber (match_scratch:QI 4 "=&d"))]
1685 "&& reload_completed"
1690 (minus:QI (match_dup 3)
1691 (mult:QI (match_dup 1)
1695 ;******************************************************************************
1696 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1697 ;******************************************************************************
1699 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1702 ;; int foo (unsigned char z)
1704 ;; extern int aInt[];
1705 ;; return aInt[3*z+2];
1708 ;; because the constant +4 then is added explicitely instead of consuming it
1709 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1710 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1711 ;; The implementational effort is the same so we are fine with that approach.
1716 (define_insn "*<extend_u>maddqihi4"
1717 [(set (match_operand:HI 0 "register_operand" "=r")
1718 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1719 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1720 (match_operand:HI 3 "register_operand" "0")))]
1723 "mul<extend_s> %1,%2
1727 [(set_attr "length" "4")
1728 (set_attr "cc" "clobber")])
1732 (define_insn "*<extend_u>msubqihi4"
1733 [(set (match_operand:HI 0 "register_operand" "=r")
1734 (minus:HI (match_operand:HI 3 "register_operand" "0")
1735 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1736 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1738 "mul<extend_s> %1,%2
1742 [(set_attr "length" "4")
1743 (set_attr "cc" "clobber")])
1747 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1748 [(set (match_operand:HI 0 "register_operand" "=r")
1749 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1750 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1751 (match_operand:HI 3 "register_operand" "0")))]
1754 && <any_extend:CODE> != <any_extend2:CODE>"
1756 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1757 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1759 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1761 [(set_attr "length" "4")
1762 (set_attr "cc" "clobber")])
1766 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1767 [(set (match_operand:HI 0 "register_operand" "=r")
1768 (minus:HI (match_operand:HI 3 "register_operand" "0")
1769 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1770 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1773 && <any_extend:CODE> != <any_extend2:CODE>"
1775 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1776 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1778 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1780 [(set_attr "length" "4")
1781 (set_attr "cc" "clobber")])
1783 ;; Handle small constants
1785 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1786 ;; This is shorter, faster than MUL and has lower register pressure.
1788 (define_insn_and_split "*umaddqihi4.2"
1789 [(set (match_operand:HI 0 "register_operand" "=r")
1790 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1792 (match_operand:HI 2 "register_operand" "r")))]
1794 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1795 { gcc_unreachable(); }
1799 ; *addhi3_zero_extend
1801 (plus:HI (zero_extend:HI (match_dup 1))
1803 ; *addhi3_zero_extend
1805 (plus:HI (zero_extend:HI (match_dup 1))
1808 ;; "umaddqihi4.uconst"
1809 ;; "maddqihi4.sconst"
1810 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1811 [(set (match_operand:HI 0 "register_operand" "=r")
1812 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1813 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1814 (match_operand:HI 3 "register_operand" "0")))
1815 (clobber (match_scratch:QI 4 "=&d"))]
1818 "&& reload_completed"
1821 ; *umaddqihi4 resp. *maddqihi4
1823 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1824 (any_extend:HI (match_dup 4)))
1827 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1830 ;; "*umsubqihi4.uconst"
1831 ;; "*msubqihi4.sconst"
1832 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1833 [(set (match_operand:HI 0 "register_operand" "=r")
1834 (minus:HI (match_operand:HI 3 "register_operand" "0")
1835 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1836 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1837 (clobber (match_scratch:QI 4 "=&d"))]
1840 "&& reload_completed"
1843 ; *umsubqihi4 resp. *msubqihi4
1845 (minus:HI (match_dup 3)
1846 (mult:HI (any_extend:HI (match_dup 1))
1847 (any_extend:HI (match_dup 4)))))]
1849 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1852 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1853 ;; for MULT with power of 2 and skips trying MULT insn above.
1855 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1856 [(set (match_operand:HI 0 "register_operand" "=r")
1857 (minus:HI (match_operand:HI 3 "register_operand" "0")
1858 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1859 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1860 (clobber (match_scratch:QI 4 "=&d"))]
1863 "&& reload_completed"
1868 (minus:HI (match_dup 3)
1869 (mult:HI (zero_extend:HI (match_dup 1))
1870 (zero_extend:HI (match_dup 4)))))]
1872 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1875 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1876 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1877 ;; because this would require an extra pattern for just one value.
1879 (define_insn_and_split "*msubqihi4.sconst.ashift"
1880 [(set (match_operand:HI 0 "register_operand" "=r")
1881 (minus:HI (match_operand:HI 3 "register_operand" "0")
1882 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1883 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1884 (clobber (match_scratch:QI 4 "=&d"))]
1887 "&& reload_completed"
1892 (minus:HI (match_dup 3)
1893 (mult:HI (sign_extend:HI (match_dup 1))
1894 (sign_extend:HI (match_dup 4)))))]
1896 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1899 ;; For signed/unsigned combinations that require narrow constraint "a"
1900 ;; just provide a pattern if signed/unsigned combination is actually needed.
1902 (define_insn_and_split "*sumaddqihi4.uconst"
1903 [(set (match_operand:HI 0 "register_operand" "=r")
1904 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1905 (match_operand:HI 2 "u8_operand" "M"))
1906 (match_operand:HI 3 "register_operand" "0")))
1907 (clobber (match_scratch:QI 4 "=&a"))]
1909 && !s8_operand (operands[2], VOIDmode)"
1911 "&& reload_completed"
1916 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1917 (zero_extend:HI (match_dup 4)))
1920 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1923 (define_insn_and_split "*sumsubqihi4.uconst"
1924 [(set (match_operand:HI 0 "register_operand" "=r")
1925 (minus:HI (match_operand:HI 3 "register_operand" "0")
1926 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1927 (match_operand:HI 2 "u8_operand" "M"))))
1928 (clobber (match_scratch:QI 4 "=&a"))]
1930 && !s8_operand (operands[2], VOIDmode)"
1932 "&& reload_completed"
1937 (minus:HI (match_dup 3)
1938 (mult:HI (sign_extend:HI (match_dup 1))
1939 (zero_extend:HI (match_dup 4)))))]
1941 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1944 ;******************************************************************************
1945 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1946 ;******************************************************************************
1948 ;; "*muluqihi3.uconst"
1949 ;; "*mulsqihi3.sconst"
1950 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1951 [(set (match_operand:HI 0 "register_operand" "=r")
1952 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1953 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1954 (clobber (match_scratch:QI 3 "=&d"))]
1957 "&& reload_completed"
1960 ; umulqihi3 resp. mulqihi3
1962 (mult:HI (any_extend:HI (match_dup 1))
1963 (any_extend:HI (match_dup 3))))]
1965 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1968 (define_insn_and_split "*muluqihi3.sconst"
1969 [(set (match_operand:HI 0 "register_operand" "=r")
1970 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1971 (match_operand:HI 2 "s8_operand" "n")))
1972 (clobber (match_scratch:QI 3 "=&a"))]
1975 "&& reload_completed"
1980 (mult:HI (zero_extend:HI (match_dup 1))
1981 (sign_extend:HI (match_dup 3))))]
1983 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1986 (define_insn_and_split "*mulsqihi3.uconst"
1987 [(set (match_operand:HI 0 "register_operand" "=r")
1988 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1989 (match_operand:HI 2 "u8_operand" "M")))
1990 (clobber (match_scratch:QI 3 "=&a"))]
1993 "&& reload_completed"
1998 (mult:HI (zero_extend:HI (match_dup 3))
1999 (sign_extend:HI (match_dup 1))))]
2001 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2004 (define_insn_and_split "*mulsqihi3.oconst"
2005 [(set (match_operand:HI 0 "register_operand" "=&r")
2006 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2007 (match_operand:HI 2 "o8_operand" "n")))
2008 (clobber (match_scratch:QI 3 "=&a"))]
2011 "&& reload_completed"
2016 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2017 (sign_extend:HI (match_dup 1))))]
2019 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2022 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2023 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2024 ;; at that time. Fix that.
2026 (define_insn "*ashiftqihi2.signx.1"
2027 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2028 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2032 lsl %A0\;sbc %B0,%B0
2033 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2034 [(set_attr "length" "2,3")
2035 (set_attr "cc" "clobber")])
2037 (define_insn_and_split "*ashifthi3.signx.const"
2038 [(set (match_operand:HI 0 "register_operand" "=r")
2039 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2040 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2041 (clobber (match_scratch:QI 3 "=&d"))]
2044 "&& reload_completed"
2049 (mult:HI (sign_extend:HI (match_dup 1))
2050 (sign_extend:HI (match_dup 3))))]
2052 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2055 (define_insn_and_split "*ashifthi3.signx.const7"
2056 [(set (match_operand:HI 0 "register_operand" "=r")
2057 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2059 (clobber (match_scratch:QI 2 "=&a"))]
2062 "&& reload_completed"
2067 (mult:HI (zero_extend:HI (match_dup 2))
2068 (sign_extend:HI (match_dup 1))))]
2070 operands[3] = gen_int_mode (1 << 7, QImode);
2073 (define_insn_and_split "*ashifthi3.zerox.const"
2074 [(set (match_operand:HI 0 "register_operand" "=r")
2075 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2076 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2077 (clobber (match_scratch:QI 3 "=&d"))]
2080 "&& reload_completed"
2085 (mult:HI (zero_extend:HI (match_dup 1))
2086 (zero_extend:HI (match_dup 3))))]
2088 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2091 ;******************************************************************************
2092 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2093 ;******************************************************************************
2095 (define_insn "mulsqihi3"
2096 [(set (match_operand:HI 0 "register_operand" "=&r")
2097 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2098 (match_operand:HI 2 "register_operand" "a")))]
2105 [(set_attr "length" "5")
2106 (set_attr "cc" "clobber")])
2108 (define_insn "muluqihi3"
2109 [(set (match_operand:HI 0 "register_operand" "=&r")
2110 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2111 (match_operand:HI 2 "register_operand" "r")))]
2118 [(set_attr "length" "5")
2119 (set_attr "cc" "clobber")])
2121 ;; one-extend operand 1
2123 (define_insn "muloqihi3"
2124 [(set (match_operand:HI 0 "register_operand" "=&r")
2125 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2126 (match_operand:HI 2 "register_operand" "r")))]
2134 [(set_attr "length" "6")
2135 (set_attr "cc" "clobber")])
2137 ;******************************************************************************
2139 (define_expand "mulhi3"
2140 [(set (match_operand:HI 0 "register_operand" "")
2141 (mult:HI (match_operand:HI 1 "register_operand" "")
2142 (match_operand:HI 2 "register_or_s9_operand" "")))]
2147 if (!register_operand (operands[2], HImode))
2148 operands[2] = force_reg (HImode, operands[2]);
2150 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2154 /* For small constants we can do better by extending them on the fly.
2155 The constant can be loaded in one instruction and the widening
2156 multiplication is shorter. First try the unsigned variant because it
2157 allows constraint "d" instead of "a" for the signed version. */
2159 if (s9_operand (operands[2], HImode))
2161 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2163 if (u8_operand (operands[2], HImode))
2165 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2167 else if (s8_operand (operands[2], HImode))
2169 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2173 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2179 if (!register_operand (operands[2], HImode))
2180 operands[2] = force_reg (HImode, operands[2]);
2183 (define_insn "*mulhi3_enh"
2184 [(set (match_operand:HI 0 "register_operand" "=&r")
2185 (mult:HI (match_operand:HI 1 "register_operand" "r")
2186 (match_operand:HI 2 "register_operand" "r")))]
2189 return REGNO (operands[1]) == REGNO (operands[2])
2190 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2191 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2193 [(set_attr "length" "7")
2194 (set_attr "cc" "clobber")])
2196 (define_expand "mulhi3_call"
2197 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2198 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2199 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2200 (clobber (reg:HI 22))
2201 (clobber (reg:QI 21))])
2202 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
2204 (define_insn "*mulhi3_call"
2205 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2206 (clobber (reg:HI 22))
2207 (clobber (reg:QI 21))]
2210 [(set_attr "type" "xcall")
2211 (set_attr "cc" "clobber")])
2213 ;; To support widening multiplication with constant we postpone
2214 ;; expanding to the implicit library call until post combine and
2215 ;; prior to register allocation. Clobber all hard registers that
2216 ;; might be used by the (widening) multiply until it is split and
2217 ;; it's final register footprint is worked out.
2219 (define_expand "mulsi3"
2220 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2221 (mult:SI (match_operand:SI 1 "register_operand" "")
2222 (match_operand:SI 2 "nonmemory_operand" "")))
2223 (clobber (reg:HI 26))
2224 (clobber (reg:DI 18))])]
2227 if (u16_operand (operands[2], SImode))
2229 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2230 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2234 if (o16_operand (operands[2], SImode))
2236 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2237 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2242 (define_insn_and_split "*mulsi3"
2243 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2244 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2245 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2246 (clobber (reg:HI 26))
2247 (clobber (reg:DI 18))]
2248 "AVR_HAVE_MUL && !reload_completed"
2249 { gcc_unreachable(); }
2255 (parallel [(set (reg:SI 22)
2256 (mult:SI (reg:SI 22)
2258 (clobber (reg:HI 26))])
2262 if (u16_operand (operands[2], SImode))
2264 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2265 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2269 if (o16_operand (operands[2], SImode))
2271 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2272 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2279 (define_insn_and_split "mulu<mode>si3"
2280 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2281 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2282 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2283 (clobber (reg:HI 26))
2284 (clobber (reg:DI 18))]
2285 "AVR_HAVE_MUL && !reload_completed"
2286 { gcc_unreachable(); }
2293 (mult:SI (zero_extend:SI (reg:HI 26))
2298 /* Do the QI -> HI extension explicitely before the multiplication. */
2299 /* Do the HI -> SI extension implicitely and after the multiplication. */
2301 if (QImode == <MODE>mode)
2302 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2304 if (u16_operand (operands[2], SImode))
2306 operands[1] = force_reg (HImode, operands[1]);
2307 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2308 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2315 (define_insn_and_split "muls<mode>si3"
2316 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2317 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2318 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2319 (clobber (reg:HI 26))
2320 (clobber (reg:DI 18))]
2321 "AVR_HAVE_MUL && !reload_completed"
2322 { gcc_unreachable(); }
2329 (mult:SI (sign_extend:SI (reg:HI 26))
2334 /* Do the QI -> HI extension explicitely before the multiplication. */
2335 /* Do the HI -> SI extension implicitely and after the multiplication. */
2337 if (QImode == <MODE>mode)
2338 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2340 if (u16_operand (operands[2], SImode)
2341 || s16_operand (operands[2], SImode))
2343 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2345 operands[1] = force_reg (HImode, operands[1]);
2347 if (u16_operand (operands[2], SImode))
2348 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2350 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2356 ;; One-extend operand 1
2358 (define_insn_and_split "mulohisi3"
2359 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2360 (mult:SI (not:SI (zero_extend:SI
2361 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2362 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2363 (clobber (reg:HI 26))
2364 (clobber (reg:DI 18))]
2365 "AVR_HAVE_MUL && !reload_completed"
2366 { gcc_unreachable(); }
2373 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2380 (define_expand "<extend_u>mulhisi3"
2381 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2382 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2383 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2384 (clobber (reg:HI 26))
2385 (clobber (reg:DI 18))])]
2388 (define_expand "usmulhisi3"
2389 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2390 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2391 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2392 (clobber (reg:HI 26))
2393 (clobber (reg:DI 18))])]
2396 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2397 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2398 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2399 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2400 (define_insn_and_split
2401 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2402 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2403 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2404 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2405 (clobber (reg:HI 26))
2406 (clobber (reg:DI 18))]
2407 "AVR_HAVE_MUL && !reload_completed"
2408 { gcc_unreachable(); }
2415 (mult:SI (match_dup 3)
2420 rtx xop1 = operands[1];
2421 rtx xop2 = operands[2];
2423 /* Do the QI -> HI extension explicitely before the multiplication. */
2424 /* Do the HI -> SI extension implicitely and after the multiplication. */
2426 if (QImode == <QIHI:MODE>mode)
2427 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2429 if (QImode == <QIHI2:MODE>mode)
2430 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2432 if (<any_extend:CODE> == <any_extend2:CODE>
2433 || <any_extend:CODE> == ZERO_EXTEND)
2437 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2438 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2442 /* <any_extend:CODE> = SIGN_EXTEND */
2443 /* <any_extend2:CODE> = ZERO_EXTEND */
2447 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2448 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2452 ;; "smulhi3_highpart"
2453 ;; "umulhi3_highpart"
2454 (define_expand "<extend_su>mulhi3_highpart"
2456 (match_operand:HI 1 "nonmemory_operand" ""))
2458 (match_operand:HI 2 "nonmemory_operand" ""))
2459 (parallel [(set (reg:HI 24)
2460 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2461 (any_extend:SI (reg:HI 26)))
2463 (clobber (reg:HI 22))])
2464 (set (match_operand:HI 0 "register_operand" "")
2469 (define_insn "*mulsi3_call"
2471 (mult:SI (reg:SI 22)
2473 (clobber (reg:HI 26))]
2476 [(set_attr "type" "xcall")
2477 (set_attr "cc" "clobber")])
2480 ;; "*umulhisi3_call"
2481 (define_insn "*<extend_u>mulhisi3_call"
2483 (mult:SI (any_extend:SI (reg:HI 18))
2484 (any_extend:SI (reg:HI 26))))]
2486 "%~call __<extend_u>mulhisi3"
2487 [(set_attr "type" "xcall")
2488 (set_attr "cc" "clobber")])
2490 ;; "*umulhi3_highpart_call"
2491 ;; "*smulhi3_highpart_call"
2492 (define_insn "*<extend_su>mulhi3_highpart_call"
2494 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2495 (any_extend:SI (reg:HI 26)))
2497 (clobber (reg:HI 22))]
2499 "%~call __<extend_u>mulhisi3"
2500 [(set_attr "type" "xcall")
2501 (set_attr "cc" "clobber")])
2503 (define_insn "*usmulhisi3_call"
2505 (mult:SI (zero_extend:SI (reg:HI 18))
2506 (sign_extend:SI (reg:HI 26))))]
2508 "%~call __usmulhisi3"
2509 [(set_attr "type" "xcall")
2510 (set_attr "cc" "clobber")])
2512 (define_insn "*mul<extend_su>hisi3_call"
2514 (mult:SI (any_extend:SI (reg:HI 26))
2517 "%~call __mul<extend_su>hisi3"
2518 [(set_attr "type" "xcall")
2519 (set_attr "cc" "clobber")])
2521 (define_insn "*mulohisi3_call"
2523 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2526 "%~call __mulohisi3"
2527 [(set_attr "type" "xcall")
2528 (set_attr "cc" "clobber")])
2530 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2533 ;; Generate lib1funcs.S calls ourselves, because:
2534 ;; - we know exactly which registers are clobbered (for QI and HI
2535 ;; modes, some of the call-used registers are preserved)
2536 ;; - we get both the quotient and the remainder at no extra cost
2537 ;; - we split the patterns only after the first CSE passes because
2538 ;; CSE has problems to operate on hard regs.
2540 (define_insn_and_split "divmodqi4"
2541 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2542 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2543 (match_operand:QI 2 "pseudo_register_operand" "")))
2544 (set (match_operand:QI 3 "pseudo_register_operand" "")
2545 (mod:QI (match_dup 1) (match_dup 2)))
2546 (clobber (reg:QI 22))
2547 (clobber (reg:QI 23))
2548 (clobber (reg:QI 24))
2549 (clobber (reg:QI 25))])]
2551 "this divmodqi4 pattern should have been splitted;"
2553 [(set (reg:QI 24) (match_dup 1))
2554 (set (reg:QI 22) (match_dup 2))
2555 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2556 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2557 (clobber (reg:QI 22))
2558 (clobber (reg:QI 23))])
2559 (set (match_dup 0) (reg:QI 24))
2560 (set (match_dup 3) (reg:QI 25))])
2562 (define_insn "*divmodqi4_call"
2563 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2564 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2565 (clobber (reg:QI 22))
2566 (clobber (reg:QI 23))]
2568 "%~call __divmodqi4"
2569 [(set_attr "type" "xcall")
2570 (set_attr "cc" "clobber")])
2572 (define_insn_and_split "udivmodqi4"
2573 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2574 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2575 (match_operand:QI 2 "pseudo_register_operand" "")))
2576 (set (match_operand:QI 3 "pseudo_register_operand" "")
2577 (umod:QI (match_dup 1) (match_dup 2)))
2578 (clobber (reg:QI 22))
2579 (clobber (reg:QI 23))
2580 (clobber (reg:QI 24))
2581 (clobber (reg:QI 25))])]
2583 "this udivmodqi4 pattern should have been splitted;"
2585 [(set (reg:QI 24) (match_dup 1))
2586 (set (reg:QI 22) (match_dup 2))
2587 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2588 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2589 (clobber (reg:QI 23))])
2590 (set (match_dup 0) (reg:QI 24))
2591 (set (match_dup 3) (reg:QI 25))])
2593 (define_insn "*udivmodqi4_call"
2594 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2595 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2596 (clobber (reg:QI 23))]
2598 "%~call __udivmodqi4"
2599 [(set_attr "type" "xcall")
2600 (set_attr "cc" "clobber")])
2602 (define_insn_and_split "divmodhi4"
2603 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2604 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2605 (match_operand:HI 2 "pseudo_register_operand" "")))
2606 (set (match_operand:HI 3 "pseudo_register_operand" "")
2607 (mod:HI (match_dup 1) (match_dup 2)))
2608 (clobber (reg:QI 21))
2609 (clobber (reg:HI 22))
2610 (clobber (reg:HI 24))
2611 (clobber (reg:HI 26))])]
2613 "this should have been splitted;"
2615 [(set (reg:HI 24) (match_dup 1))
2616 (set (reg:HI 22) (match_dup 2))
2617 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2618 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2619 (clobber (reg:HI 26))
2620 (clobber (reg:QI 21))])
2621 (set (match_dup 0) (reg:HI 22))
2622 (set (match_dup 3) (reg:HI 24))])
2624 (define_insn "*divmodhi4_call"
2625 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2626 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2627 (clobber (reg:HI 26))
2628 (clobber (reg:QI 21))]
2630 "%~call __divmodhi4"
2631 [(set_attr "type" "xcall")
2632 (set_attr "cc" "clobber")])
2634 (define_insn_and_split "udivmodhi4"
2635 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2636 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2637 (match_operand:HI 2 "pseudo_register_operand" "")))
2638 (set (match_operand:HI 3 "pseudo_register_operand" "")
2639 (umod:HI (match_dup 1) (match_dup 2)))
2640 (clobber (reg:QI 21))
2641 (clobber (reg:HI 22))
2642 (clobber (reg:HI 24))
2643 (clobber (reg:HI 26))])]
2645 "this udivmodhi4 pattern should have been splitted.;"
2647 [(set (reg:HI 24) (match_dup 1))
2648 (set (reg:HI 22) (match_dup 2))
2649 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2650 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2651 (clobber (reg:HI 26))
2652 (clobber (reg:QI 21))])
2653 (set (match_dup 0) (reg:HI 22))
2654 (set (match_dup 3) (reg:HI 24))])
2656 (define_insn "*udivmodhi4_call"
2657 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2658 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2659 (clobber (reg:HI 26))
2660 (clobber (reg:QI 21))]
2662 "%~call __udivmodhi4"
2663 [(set_attr "type" "xcall")
2664 (set_attr "cc" "clobber")])
2666 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2669 ;; To support widening multiplication with constant we postpone
2670 ;; expanding to the implicit library call until post combine and
2671 ;; prior to register allocation. Clobber all hard registers that
2672 ;; might be used by the (widening) multiply until it is split and
2673 ;; it's final register footprint is worked out.
2675 (define_expand "mulpsi3"
2676 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2677 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2678 (match_operand:PSI 2 "nonmemory_operand" "")))
2679 (clobber (reg:HI 26))
2680 (clobber (reg:DI 18))])]
2683 if (s8_operand (operands[2], PSImode))
2685 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2686 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2691 (define_insn "*umulqihipsi3"
2692 [(set (match_operand:PSI 0 "register_operand" "=&r")
2693 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2694 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2703 [(set_attr "length" "7")
2704 (set_attr "cc" "clobber")])
2706 (define_insn "*umulhiqipsi3"
2707 [(set (match_operand:PSI 0 "register_operand" "=&r")
2708 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2709 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2717 adc %C0,__zero_reg__"
2718 [(set_attr "length" "7")
2719 (set_attr "cc" "clobber")])
2721 (define_insn_and_split "mulsqipsi3"
2722 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2723 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2724 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2725 (clobber (reg:HI 26))
2726 (clobber (reg:DI 18))]
2727 "AVR_HAVE_MUL && !reload_completed"
2728 { gcc_unreachable(); }
2735 (mult:PSI (sign_extend:PSI (reg:QI 25))
2740 (define_insn_and_split "*mulpsi3"
2741 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2742 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2743 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2744 (clobber (reg:HI 26))
2745 (clobber (reg:DI 18))]
2746 "AVR_HAVE_MUL && !reload_completed"
2747 { gcc_unreachable(); }
2753 (parallel [(set (reg:PSI 22)
2754 (mult:PSI (reg:PSI 22)
2756 (clobber (reg:QI 21))
2757 (clobber (reg:QI 25))
2758 (clobber (reg:HI 26))])
2762 if (s8_operand (operands[2], PSImode))
2764 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2765 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2770 (define_insn "*mulsqipsi3.libgcc"
2772 (mult:PSI (sign_extend:PSI (reg:QI 25))
2775 "%~call __mulsqipsi3"
2776 [(set_attr "type" "xcall")
2777 (set_attr "cc" "clobber")])
2779 (define_insn "*mulpsi3.libgcc"
2781 (mult:PSI (reg:PSI 22)
2783 (clobber (reg:QI 21))
2784 (clobber (reg:QI 25))
2785 (clobber (reg:HI 26))]
2788 [(set_attr "type" "xcall")
2789 (set_attr "cc" "clobber")])
2792 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2793 ;; 24-bit signed/unsigned division and modulo.
2794 ;; Notice that the libgcc implementation return the quotient in R22
2795 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2796 ;; implementation works the other way round.
2798 (define_insn_and_split "divmodpsi4"
2799 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2800 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2801 (match_operand:PSI 2 "pseudo_register_operand" "")))
2802 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2803 (mod:PSI (match_dup 1)
2805 (clobber (reg:DI 18))
2806 (clobber (reg:QI 26))])]
2808 { gcc_unreachable(); }
2810 [(set (reg:PSI 22) (match_dup 1))
2811 (set (reg:PSI 18) (match_dup 2))
2812 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2813 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2814 (clobber (reg:QI 21))
2815 (clobber (reg:QI 25))
2816 (clobber (reg:QI 26))])
2817 (set (match_dup 0) (reg:PSI 22))
2818 (set (match_dup 3) (reg:PSI 18))])
2820 (define_insn "*divmodpsi4_call"
2821 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2822 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2823 (clobber (reg:QI 21))
2824 (clobber (reg:QI 25))
2825 (clobber (reg:QI 26))]
2827 "%~call __divmodpsi4"
2828 [(set_attr "type" "xcall")
2829 (set_attr "cc" "clobber")])
2831 (define_insn_and_split "udivmodpsi4"
2832 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2833 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2834 (match_operand:PSI 2 "pseudo_register_operand" "")))
2835 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2836 (umod:PSI (match_dup 1)
2838 (clobber (reg:DI 18))
2839 (clobber (reg:QI 26))])]
2841 { gcc_unreachable(); }
2843 [(set (reg:PSI 22) (match_dup 1))
2844 (set (reg:PSI 18) (match_dup 2))
2845 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2846 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2847 (clobber (reg:QI 21))
2848 (clobber (reg:QI 25))
2849 (clobber (reg:QI 26))])
2850 (set (match_dup 0) (reg:PSI 22))
2851 (set (match_dup 3) (reg:PSI 18))])
2853 (define_insn "*udivmodpsi4_call"
2854 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2855 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2856 (clobber (reg:QI 21))
2857 (clobber (reg:QI 25))
2858 (clobber (reg:QI 26))]
2860 "%~call __udivmodpsi4"
2861 [(set_attr "type" "xcall")
2862 (set_attr "cc" "clobber")])
2864 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2866 (define_insn_and_split "divmodsi4"
2867 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2868 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2869 (match_operand:SI 2 "pseudo_register_operand" "")))
2870 (set (match_operand:SI 3 "pseudo_register_operand" "")
2871 (mod:SI (match_dup 1) (match_dup 2)))
2872 (clobber (reg:SI 18))
2873 (clobber (reg:SI 22))
2874 (clobber (reg:HI 26))
2875 (clobber (reg:HI 30))])]
2877 "this divmodsi4 pattern should have been splitted;"
2879 [(set (reg:SI 22) (match_dup 1))
2880 (set (reg:SI 18) (match_dup 2))
2881 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2882 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2883 (clobber (reg:HI 26))
2884 (clobber (reg:HI 30))])
2885 (set (match_dup 0) (reg:SI 18))
2886 (set (match_dup 3) (reg:SI 22))])
2888 (define_insn "*divmodsi4_call"
2889 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2890 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2891 (clobber (reg:HI 26))
2892 (clobber (reg:HI 30))]
2894 "%~call __divmodsi4"
2895 [(set_attr "type" "xcall")
2896 (set_attr "cc" "clobber")])
2898 (define_insn_and_split "udivmodsi4"
2899 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2900 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2901 (match_operand:SI 2 "pseudo_register_operand" "")))
2902 (set (match_operand:SI 3 "pseudo_register_operand" "")
2903 (umod:SI (match_dup 1) (match_dup 2)))
2904 (clobber (reg:SI 18))
2905 (clobber (reg:SI 22))
2906 (clobber (reg:HI 26))
2907 (clobber (reg:HI 30))])]
2909 "this udivmodsi4 pattern should have been splitted;"
2911 [(set (reg:SI 22) (match_dup 1))
2912 (set (reg:SI 18) (match_dup 2))
2913 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2914 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2915 (clobber (reg:HI 26))
2916 (clobber (reg:HI 30))])
2917 (set (match_dup 0) (reg:SI 18))
2918 (set (match_dup 3) (reg:SI 22))])
2920 (define_insn "*udivmodsi4_call"
2921 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2922 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2923 (clobber (reg:HI 26))
2924 (clobber (reg:HI 30))]
2926 "%~call __udivmodsi4"
2927 [(set_attr "type" "xcall")
2928 (set_attr "cc" "clobber")])
2930 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2933 (define_insn "andqi3"
2934 [(set (match_operand:QI 0 "register_operand" "=??r,d")
2935 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2936 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2941 [(set_attr "length" "1,1")
2942 (set_attr "cc" "set_zn,set_zn")])
2944 (define_insn "andhi3"
2945 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
2946 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2947 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2948 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2951 if (which_alternative == 0)
2952 return "and %A0,%A2\;and %B0,%B2";
2953 else if (which_alternative == 1)
2954 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2956 return avr_out_bitop (insn, operands, NULL);
2958 [(set_attr "length" "2,2,2,4,4")
2959 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2960 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2962 (define_insn "andpsi3"
2963 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
2964 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2965 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2966 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2969 if (which_alternative == 0)
2970 return "and %A0,%A2" CR_TAB
2971 "and %B0,%B2" CR_TAB
2974 return avr_out_bitop (insn, operands, NULL);
2976 [(set_attr "length" "3,3,6,6")
2977 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2978 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2980 (define_insn "andsi3"
2981 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
2982 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2983 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2984 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2987 if (which_alternative == 0)
2988 return "and %0,%2" CR_TAB
2989 "and %B0,%B2" CR_TAB
2990 "and %C0,%C2" CR_TAB
2993 return avr_out_bitop (insn, operands, NULL);
2995 [(set_attr "length" "4,4,8,8")
2996 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2997 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2999 (define_peephole2 ; andi
3000 [(set (match_operand:QI 0 "d_register_operand" "")
3001 (and:QI (match_dup 0)
3002 (match_operand:QI 1 "const_int_operand" "")))
3004 (and:QI (match_dup 0)
3005 (match_operand:QI 2 "const_int_operand" "")))]
3007 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3009 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3012 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3015 (define_insn "iorqi3"
3016 [(set (match_operand:QI 0 "register_operand" "=??r,d")
3017 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3018 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3023 [(set_attr "length" "1,1")
3024 (set_attr "cc" "set_zn,set_zn")])
3026 (define_insn "iorhi3"
3027 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3028 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3029 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3030 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3033 if (which_alternative == 0)
3034 return "or %A0,%A2\;or %B0,%B2";
3035 else if (which_alternative == 1)
3036 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3038 return avr_out_bitop (insn, operands, NULL);
3040 [(set_attr "length" "2,2,2,4,4")
3041 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3042 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3044 (define_insn "iorpsi3"
3045 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3046 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3047 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3048 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3051 if (which_alternative == 0)
3052 return "or %A0,%A2" CR_TAB
3056 return avr_out_bitop (insn, operands, NULL);
3058 [(set_attr "length" "3,3,6,6")
3059 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3060 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3062 (define_insn "iorsi3"
3063 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3064 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3065 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3066 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3069 if (which_alternative == 0)
3070 return "or %0,%2" CR_TAB
3075 return avr_out_bitop (insn, operands, NULL);
3077 [(set_attr "length" "4,4,8,8")
3078 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3079 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3081 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3084 (define_insn "xorqi3"
3085 [(set (match_operand:QI 0 "register_operand" "=r")
3086 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3087 (match_operand:QI 2 "register_operand" "r")))]
3090 [(set_attr "length" "1")
3091 (set_attr "cc" "set_zn")])
3093 (define_insn "xorhi3"
3094 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
3095 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3096 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3097 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3100 if (which_alternative == 0)
3101 return "eor %A0,%A2\;eor %B0,%B2";
3103 return avr_out_bitop (insn, operands, NULL);
3105 [(set_attr "length" "2,2,4")
3106 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3107 (set_attr "cc" "set_n,clobber,clobber")])
3109 (define_insn "xorpsi3"
3110 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
3111 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3112 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3113 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3116 if (which_alternative == 0)
3117 return "eor %A0,%A2" CR_TAB
3118 "eor %B0,%B2" CR_TAB
3121 return avr_out_bitop (insn, operands, NULL);
3123 [(set_attr "length" "3,6,6")
3124 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3125 (set_attr "cc" "set_n,clobber,clobber")])
3127 (define_insn "xorsi3"
3128 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
3129 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3130 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3131 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3134 if (which_alternative == 0)
3135 return "eor %0,%2" CR_TAB
3136 "eor %B0,%B2" CR_TAB
3137 "eor %C0,%C2" CR_TAB
3140 return avr_out_bitop (insn, operands, NULL);
3142 [(set_attr "length" "4,8,8")
3143 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3144 (set_attr "cc" "set_n,clobber,clobber")])
3146 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3149 (define_expand "rotlqi3"
3150 [(set (match_operand:QI 0 "register_operand" "")
3151 (rotate:QI (match_operand:QI 1 "register_operand" "")
3152 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3155 if (!CONST_INT_P (operands[2]))
3158 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3161 ;; Expander used by __builtin_avr_swap
3162 (define_expand "rotlqi3_4"
3163 [(set (match_operand:QI 0 "register_operand" "")
3164 (rotate:QI (match_operand:QI 1 "register_operand" "")
3167 (define_insn "*rotlqi3"
3168 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3169 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3170 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3173 lsl %0\;adc %0,__zero_reg__
3174 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3175 swap %0\;bst %0,0\;ror %0\;bld %0,7
3177 swap %0\;lsl %0\;adc %0,__zero_reg__
3178 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3179 bst %0,0\;ror %0\;bld %0,7
3181 [(set_attr "length" "2,4,4,1,3,5,3,0")
3182 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3184 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3185 ;; a whole number of bytes. The split creates the appropriate moves and
3186 ;; considers all overlap situations.
3188 ;; HImode does not need scratch. Use attribute for this constraint.
3190 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3191 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3196 (define_expand "rotl<mode>3"
3197 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3198 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3199 (match_operand:VOID 2 "const_int_operand" "")))
3200 (clobber (match_dup 3))])]
3205 if (!CONST_INT_P (operands[2]))
3208 offset = INTVAL (operands[2]);
3210 if (0 == offset % 8)
3212 if (AVR_HAVE_MOVW && 0 == offset % 16)
3213 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3215 operands[3] = gen_rtx_SCRATCH (QImode);
3217 else if (offset == 1
3218 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3220 /*; Support rotate left/right by 1 */
3222 emit_move_insn (operands[0],
3223 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3230 (define_insn "*rotlhi2.1"
3231 [(set (match_operand:HI 0 "register_operand" "=r")
3232 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3235 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3236 [(set_attr "length" "3")
3237 (set_attr "cc" "clobber")])
3239 (define_insn "*rotlhi2.15"
3240 [(set (match_operand:HI 0 "register_operand" "=r")
3241 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3244 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3245 [(set_attr "length" "4")
3246 (set_attr "cc" "clobber")])
3248 (define_insn "*rotlpsi2.1"
3249 [(set (match_operand:PSI 0 "register_operand" "=r")
3250 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3253 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3254 [(set_attr "length" "4")
3255 (set_attr "cc" "clobber")])
3257 (define_insn "*rotlpsi2.23"
3258 [(set (match_operand:PSI 0 "register_operand" "=r")
3259 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3262 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3263 [(set_attr "length" "5")
3264 (set_attr "cc" "clobber")])
3266 (define_insn "*rotlsi2.1"
3267 [(set (match_operand:SI 0 "register_operand" "=r")
3268 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3271 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3272 [(set_attr "length" "5")
3273 (set_attr "cc" "clobber")])
3275 (define_insn "*rotlsi2.31"
3276 [(set (match_operand:SI 0 "register_operand" "=r")
3277 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3280 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3281 [(set_attr "length" "6")
3282 (set_attr "cc" "clobber")])
3284 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3285 ;; The best we can do is use early clobber alternative "#&r" so that
3286 ;; completely non-overlapping operands dont get a scratch but # so register
3287 ;; allocation does not prefer non-overlapping.
3290 ;; Split word aligned rotates using scratch that is mode dependent.
3294 (define_insn_and_split "*rotw<mode>"
3295 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3296 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3297 (match_operand 2 "const_int_operand" "n,n,n")))
3298 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3300 && CONST_INT_P (operands[2])
3301 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3302 && 0 == INTVAL (operands[2]) % 16"
3304 "&& reload_completed"
3307 avr_rotate_bytes (operands);
3312 ;; Split byte aligned rotates using scratch that is always QI mode.
3317 (define_insn_and_split "*rotb<mode>"
3318 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3319 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3320 (match_operand 2 "const_int_operand" "n,n,n")))
3321 (clobber (match_scratch:QI 3 "=<rotx>"))]
3322 "CONST_INT_P (operands[2])
3323 && (8 == INTVAL (operands[2]) % 16
3325 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3326 && 0 == INTVAL (operands[2]) % 16))"
3328 "&& reload_completed"
3331 avr_rotate_bytes (operands);
3336 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3337 ;; arithmetic shift left
3340 ;; "ashlqq3" "ashluqq3"
3341 (define_expand "ashl<mode>3"
3342 [(set (match_operand:ALL1 0 "register_operand" "")
3343 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3344 (match_operand:QI 2 "nop_general_operand" "")))])
3346 (define_split ; ashlqi3_const4
3347 [(set (match_operand:ALL1 0 "d_register_operand" "")
3348 (ashift:ALL1 (match_dup 0)
3352 (rotate:QI (match_dup 1)
3355 (and:QI (match_dup 1)
3358 operands[1] = avr_to_int_mode (operands[0]);
3361 (define_split ; ashlqi3_const5
3362 [(set (match_operand:ALL1 0 "d_register_operand" "")
3363 (ashift:ALL1 (match_dup 0)
3366 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3367 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3368 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3370 operands[1] = avr_to_int_mode (operands[0]);
3373 (define_split ; ashlqi3_const6
3374 [(set (match_operand:ALL1 0 "d_register_operand" "")
3375 (ashift:ALL1 (match_dup 0)
3378 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3379 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3380 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3382 operands[1] = avr_to_int_mode (operands[0]);
3386 ;; "*ashlqq3" "*ashluqq3"
3387 (define_insn "*ashl<mode>3"
3388 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3389 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3390 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3393 return ashlqi3_out (insn, operands, NULL);
3395 [(set_attr "length" "5,0,1,2,4,6,9")
3396 (set_attr "adjust_len" "ashlqi")
3397 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3399 (define_insn "ashl<mode>3"
3400 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3401 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3402 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3405 return ashlhi3_out (insn, operands, NULL);
3407 [(set_attr "length" "6,0,2,2,4,10,10")
3408 (set_attr "adjust_len" "ashlhi")
3409 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3412 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3413 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3417 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3418 [(set (match_operand:QI 0 "register_operand" "=r")
3419 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3420 (match_operand:QI 2 "register_operand" "r"))
3426 (ashift:QI (match_dup 1)
3429 ;; ??? Combiner does not recognize that it could split the following insn;
3430 ;; presumably because he has no register handy?
3432 ;; "*ashluqihiqi3.mem"
3433 ;; "*ashlsqihiqi3.mem"
3434 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3435 [(set (match_operand:QI 0 "memory_operand" "=m")
3436 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3437 (match_operand:QI 2 "register_operand" "r"))
3440 { gcc_unreachable(); }
3443 (ashift:QI (match_dup 1)
3448 operands[3] = gen_reg_rtx (QImode);
3453 (define_insn_and_split "*ashlhiqi3"
3454 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3455 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3456 (match_operand:QI 2 "register_operand" "r")) 0))]
3458 { gcc_unreachable(); }
3461 (ashift:QI (match_dup 3)
3466 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3467 operands[4] = gen_reg_rtx (QImode);
3470 ;; High part of 16-bit shift is unused after the instruction:
3471 ;; No need to compute it, map to 8-bit shift.
3474 [(set (match_operand:HI 0 "register_operand" "")
3475 (ashift:HI (match_dup 0)
3476 (match_operand:QI 1 "register_operand" "")))]
3479 (ashift:QI (match_dup 2)
3481 (clobber (match_dup 3))]
3483 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3485 if (!peep2_reg_dead_p (1, operands[3]))
3488 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3493 ;; "ashlsq3" "ashlusq3"
3494 ;; "ashlsa3" "ashlusa3"
3495 (define_insn "ashl<mode>3"
3496 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3497 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3498 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3501 return ashlsi3_out (insn, operands, NULL);
3503 [(set_attr "length" "8,0,4,4,8,10,12")
3504 (set_attr "adjust_len" "ashlsi")
3505 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3507 ;; Optimize if a scratch register from LD_REGS happens to be available.
3509 (define_peephole2 ; ashlqi3_l_const4
3510 [(set (match_operand:ALL1 0 "l_register_operand" "")
3511 (ashift:ALL1 (match_dup 0)
3513 (match_scratch:QI 1 "d")]
3515 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3516 (set (match_dup 1) (const_int -16))
3517 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3519 operands[2] = avr_to_int_mode (operands[0]);
3522 (define_peephole2 ; ashlqi3_l_const5
3523 [(set (match_operand:ALL1 0 "l_register_operand" "")
3524 (ashift:ALL1 (match_dup 0)
3526 (match_scratch:QI 1 "d")]
3528 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3529 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3530 (set (match_dup 1) (const_int -32))
3531 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3533 operands[2] = avr_to_int_mode (operands[0]);
3536 (define_peephole2 ; ashlqi3_l_const6
3537 [(set (match_operand:ALL1 0 "l_register_operand" "")
3538 (ashift:ALL1 (match_dup 0)
3540 (match_scratch:QI 1 "d")]
3542 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3543 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3544 (set (match_dup 1) (const_int -64))
3545 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3547 operands[2] = avr_to_int_mode (operands[0]);
3551 [(match_scratch:QI 3 "d")
3552 (set (match_operand:ALL2 0 "register_operand" "")
3553 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3554 (match_operand:QI 2 "const_int_operand" "")))]
3556 [(parallel [(set (match_dup 0)
3557 (ashift:ALL2 (match_dup 1)
3559 (clobber (match_dup 3))])])
3562 ;; "*ashlhq3_const" "*ashluhq3_const"
3563 ;; "*ashlha3_const" "*ashluha3_const"
3564 (define_insn "*ashl<mode>3_const"
3565 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3566 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3567 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3568 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3571 return ashlhi3_out (insn, operands, NULL);
3573 [(set_attr "length" "0,2,2,4,10")
3574 (set_attr "adjust_len" "ashlhi")
3575 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3578 [(match_scratch:QI 3 "d")
3579 (set (match_operand:ALL4 0 "register_operand" "")
3580 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3581 (match_operand:QI 2 "const_int_operand" "")))]
3583 [(parallel [(set (match_dup 0)
3584 (ashift:ALL4 (match_dup 1)
3586 (clobber (match_dup 3))])])
3589 ;; "*ashlsq3_const" "*ashlusq3_const"
3590 ;; "*ashlsa3_const" "*ashlusa3_const"
3591 (define_insn "*ashl<mode>3_const"
3592 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3593 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3594 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3595 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3598 return ashlsi3_out (insn, operands, NULL);
3600 [(set_attr "length" "0,4,4,10")
3601 (set_attr "adjust_len" "ashlsi")
3602 (set_attr "cc" "none,set_n,clobber,clobber")])
3604 (define_expand "ashlpsi3"
3605 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3606 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3607 (match_operand:QI 2 "nonmemory_operand" "")))
3608 (clobber (scratch:QI))])]
3612 && CONST_INT_P (operands[2]))
3614 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3616 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3617 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3620 else if (optimize_insn_for_speed_p ()
3621 && INTVAL (operands[2]) != 16
3622 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3624 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3625 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3631 (define_insn "*ashlpsi3"
3632 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3633 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3634 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3635 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3638 return avr_out_ashlpsi3 (insn, operands, NULL);
3640 [(set_attr "adjust_len" "ashlpsi")
3641 (set_attr "cc" "clobber")])
3643 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3644 ;; arithmetic shift right
3647 ;; "ashrqq3" "ashruqq3"
3648 (define_insn "ashr<mode>3"
3649 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3650 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3651 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3654 return ashrqi3_out (insn, operands, NULL);
3656 [(set_attr "length" "5,0,1,2,5,4,9")
3657 (set_attr "adjust_len" "ashrqi")
3658 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3661 ;; "ashrhq3" "ashruhq3"
3662 ;; "ashrha3" "ashruha3"
3663 (define_insn "ashr<mode>3"
3664 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3665 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3666 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3669 return ashrhi3_out (insn, operands, NULL);
3671 [(set_attr "length" "6,0,2,4,4,10,10")
3672 (set_attr "adjust_len" "ashrhi")
3673 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3675 (define_insn "ashrpsi3"
3676 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3677 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3678 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3679 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3682 return avr_out_ashrpsi3 (insn, operands, NULL);
3684 [(set_attr "adjust_len" "ashrpsi")
3685 (set_attr "cc" "clobber")])
3688 ;; "ashrsq3" "ashrusq3"
3689 ;; "ashrsa3" "ashrusa3"
3690 (define_insn "ashr<mode>3"
3691 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3692 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3693 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3696 return ashrsi3_out (insn, operands, NULL);
3698 [(set_attr "length" "8,0,4,6,8,10,12")
3699 (set_attr "adjust_len" "ashrsi")
3700 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3702 ;; Optimize if a scratch register from LD_REGS happens to be available.
3705 [(match_scratch:QI 3 "d")
3706 (set (match_operand:ALL2 0 "register_operand" "")
3707 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3708 (match_operand:QI 2 "const_int_operand" "")))]
3710 [(parallel [(set (match_dup 0)
3711 (ashiftrt:ALL2 (match_dup 1)
3713 (clobber (match_dup 3))])])
3716 ;; "*ashrhq3_const" "*ashruhq3_const"
3717 ;; "*ashrha3_const" "*ashruha3_const"
3718 (define_insn "*ashr<mode>3_const"
3719 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3720 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3721 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3722 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3725 return ashrhi3_out (insn, operands, NULL);
3727 [(set_attr "length" "0,2,4,4,10")
3728 (set_attr "adjust_len" "ashrhi")
3729 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3732 [(match_scratch:QI 3 "d")
3733 (set (match_operand:ALL4 0 "register_operand" "")
3734 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3735 (match_operand:QI 2 "const_int_operand" "")))]
3737 [(parallel [(set (match_dup 0)
3738 (ashiftrt:ALL4 (match_dup 1)
3740 (clobber (match_dup 3))])])
3743 ;; "*ashrsq3_const" "*ashrusq3_const"
3744 ;; "*ashrsa3_const" "*ashrusa3_const"
3745 (define_insn "*ashr<mode>3_const"
3746 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3747 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3748 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3749 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3752 return ashrsi3_out (insn, operands, NULL);
3754 [(set_attr "length" "0,4,4,10")
3755 (set_attr "adjust_len" "ashrsi")
3756 (set_attr "cc" "none,clobber,set_n,clobber")])
3758 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3759 ;; logical shift right
3762 ;; "lshrqq3 "lshruqq3"
3763 (define_expand "lshr<mode>3"
3764 [(set (match_operand:ALL1 0 "register_operand" "")
3765 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3766 (match_operand:QI 2 "nop_general_operand" "")))])
3768 (define_split ; lshrqi3_const4
3769 [(set (match_operand:ALL1 0 "d_register_operand" "")
3770 (lshiftrt:ALL1 (match_dup 0)
3774 (rotate:QI (match_dup 1)
3777 (and:QI (match_dup 1)
3780 operands[1] = avr_to_int_mode (operands[0]);
3783 (define_split ; lshrqi3_const5
3784 [(set (match_operand:ALL1 0 "d_register_operand" "")
3785 (lshiftrt:ALL1 (match_dup 0)
3788 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3789 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3790 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3792 operands[1] = avr_to_int_mode (operands[0]);
3795 (define_split ; lshrqi3_const6
3796 [(set (match_operand:QI 0 "d_register_operand" "")
3797 (lshiftrt:QI (match_dup 0)
3800 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3801 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3802 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3804 operands[1] = avr_to_int_mode (operands[0]);
3810 (define_insn "*lshr<mode>3"
3811 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3812 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3813 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3816 return lshrqi3_out (insn, operands, NULL);
3818 [(set_attr "length" "5,0,1,2,4,6,9")
3819 (set_attr "adjust_len" "lshrqi")
3820 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3823 ;; "lshrhq3" "lshruhq3"
3824 ;; "lshrha3" "lshruha3"
3825 (define_insn "lshr<mode>3"
3826 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3827 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3828 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3831 return lshrhi3_out (insn, operands, NULL);
3833 [(set_attr "length" "6,0,2,2,4,10,10")
3834 (set_attr "adjust_len" "lshrhi")
3835 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3837 (define_insn "lshrpsi3"
3838 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3839 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3840 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3841 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3844 return avr_out_lshrpsi3 (insn, operands, NULL);
3846 [(set_attr "adjust_len" "lshrpsi")
3847 (set_attr "cc" "clobber")])
3850 ;; "lshrsq3" "lshrusq3"
3851 ;; "lshrsa3" "lshrusa3"
3852 (define_insn "lshr<mode>3"
3853 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3854 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3855 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3858 return lshrsi3_out (insn, operands, NULL);
3860 [(set_attr "length" "8,0,4,4,8,10,12")
3861 (set_attr "adjust_len" "lshrsi")
3862 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3864 ;; Optimize if a scratch register from LD_REGS happens to be available.
3866 (define_peephole2 ; lshrqi3_l_const4
3867 [(set (match_operand:ALL1 0 "l_register_operand" "")
3868 (lshiftrt:ALL1 (match_dup 0)
3870 (match_scratch:QI 1 "d")]
3872 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3873 (set (match_dup 1) (const_int 15))
3874 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3876 operands[2] = avr_to_int_mode (operands[0]);
3879 (define_peephole2 ; lshrqi3_l_const5
3880 [(set (match_operand:ALL1 0 "l_register_operand" "")
3881 (lshiftrt:ALL1 (match_dup 0)
3883 (match_scratch:QI 1 "d")]
3885 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3886 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3887 (set (match_dup 1) (const_int 7))
3888 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3890 operands[2] = avr_to_int_mode (operands[0]);
3893 (define_peephole2 ; lshrqi3_l_const6
3894 [(set (match_operand:ALL1 0 "l_register_operand" "")
3895 (lshiftrt:ALL1 (match_dup 0)
3897 (match_scratch:QI 1 "d")]
3899 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3900 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3901 (set (match_dup 1) (const_int 3))
3902 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3904 operands[2] = avr_to_int_mode (operands[0]);
3908 [(match_scratch:QI 3 "d")
3909 (set (match_operand:ALL2 0 "register_operand" "")
3910 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3911 (match_operand:QI 2 "const_int_operand" "")))]
3913 [(parallel [(set (match_dup 0)
3914 (lshiftrt:ALL2 (match_dup 1)
3916 (clobber (match_dup 3))])])
3919 ;; "*lshrhq3_const" "*lshruhq3_const"
3920 ;; "*lshrha3_const" "*lshruha3_const"
3921 (define_insn "*lshr<mode>3_const"
3922 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3923 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3924 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3925 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3928 return lshrhi3_out (insn, operands, NULL);
3930 [(set_attr "length" "0,2,2,4,10")
3931 (set_attr "adjust_len" "lshrhi")
3932 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3935 [(match_scratch:QI 3 "d")
3936 (set (match_operand:ALL4 0 "register_operand" "")
3937 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3938 (match_operand:QI 2 "const_int_operand" "")))]
3940 [(parallel [(set (match_dup 0)
3941 (lshiftrt:ALL4 (match_dup 1)
3943 (clobber (match_dup 3))])])
3946 ;; "*lshrsq3_const" "*lshrusq3_const"
3947 ;; "*lshrsa3_const" "*lshrusa3_const"
3948 (define_insn "*lshr<mode>3_const"
3949 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3950 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3951 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3952 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3955 return lshrsi3_out (insn, operands, NULL);
3957 [(set_attr "length" "0,4,4,10")
3958 (set_attr "adjust_len" "lshrsi")
3959 (set_attr "cc" "none,clobber,clobber,clobber")])
3961 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3964 (define_insn "absqi2"
3965 [(set (match_operand:QI 0 "register_operand" "=r")
3966 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3970 [(set_attr "length" "2")
3971 (set_attr "cc" "clobber")])
3974 (define_insn "abssf2"
3975 [(set (match_operand:SF 0 "register_operand" "=d,r")
3976 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3981 [(set_attr "length" "1,2")
3982 (set_attr "cc" "set_n,clobber")])
3984 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3987 (define_insn "negqi2"
3988 [(set (match_operand:QI 0 "register_operand" "=r")
3989 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3992 [(set_attr "length" "1")
3993 (set_attr "cc" "set_zn")])
3995 (define_insn "*negqihi2"
3996 [(set (match_operand:HI 0 "register_operand" "=r")
3997 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3999 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4000 [(set_attr "length" "4")
4001 (set_attr "cc" "set_n")])
4003 (define_insn "neghi2"
4004 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4005 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4008 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4009 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4010 [(set_attr "length" "3,4")
4011 (set_attr "cc" "set_czn")])
4013 (define_insn "negpsi2"
4014 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4015 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4018 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4019 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4020 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4021 [(set_attr "length" "5,6,6")
4022 (set_attr "cc" "set_czn,set_n,set_czn")])
4024 (define_insn "negsi2"
4025 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4026 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4029 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4030 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4031 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4032 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4033 [(set_attr "length" "7,8,8,7")
4034 (set_attr "isa" "*,*,mov,movw")
4035 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4037 (define_insn "negsf2"
4038 [(set (match_operand:SF 0 "register_operand" "=d,r")
4039 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4043 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4044 [(set_attr "length" "1,4")
4045 (set_attr "cc" "set_n,set_n")])
4047 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4050 (define_insn "one_cmplqi2"
4051 [(set (match_operand:QI 0 "register_operand" "=r")
4052 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4055 [(set_attr "length" "1")
4056 (set_attr "cc" "set_czn")])
4058 (define_insn "one_cmplhi2"
4059 [(set (match_operand:HI 0 "register_operand" "=r")
4060 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4064 [(set_attr "length" "2")
4065 (set_attr "cc" "set_n")])
4067 (define_insn "one_cmplpsi2"
4068 [(set (match_operand:PSI 0 "register_operand" "=r")
4069 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4071 "com %0\;com %B0\;com %C0"
4072 [(set_attr "length" "3")
4073 (set_attr "cc" "set_n")])
4075 (define_insn "one_cmplsi2"
4076 [(set (match_operand:SI 0 "register_operand" "=r")
4077 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4083 [(set_attr "length" "4")
4084 (set_attr "cc" "set_n")])
4086 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4089 ;; We keep combiner from inserting hard registers into the input of sign- and
4090 ;; zero-extends. A hard register in the input operand is not wanted because
4091 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4092 ;; hard register that overlaps these clobbers won't be combined to a widening
4093 ;; multiplication. There is no need for combine to propagate hard registers,
4094 ;; register allocation can do it just as well.
4096 (define_insn "extendqihi2"
4097 [(set (match_operand:HI 0 "register_operand" "=r,r")
4098 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4101 clr %B0\;sbrc %0,7\;com %B0
4102 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4103 [(set_attr "length" "3,4")
4104 (set_attr "cc" "set_n,set_n")])
4106 (define_insn "extendqipsi2"
4107 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4108 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4111 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4112 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4113 [(set_attr "length" "4,5")
4114 (set_attr "cc" "set_n,set_n")])
4116 (define_insn "extendqisi2"
4117 [(set (match_operand:SI 0 "register_operand" "=r,r")
4118 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4121 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4122 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4123 [(set_attr "length" "5,6")
4124 (set_attr "cc" "set_n,set_n")])
4126 (define_insn "extendhipsi2"
4127 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4128 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4131 clr %C0\;sbrc %B0,7\;com %C0
4132 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4133 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4134 [(set_attr "length" "3,5,4")
4135 (set_attr "isa" "*,mov,movw")
4136 (set_attr "cc" "set_n")])
4138 (define_insn "extendhisi2"
4139 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4140 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4143 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4144 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4145 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4146 [(set_attr "length" "4,6,5")
4147 (set_attr "isa" "*,mov,movw")
4148 (set_attr "cc" "set_n")])
4150 (define_insn "extendpsisi2"
4151 [(set (match_operand:SI 0 "register_operand" "=r")
4152 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4154 "clr %D0\;sbrc %C0,7\;com %D0"
4155 [(set_attr "length" "3")
4156 (set_attr "cc" "set_n")])
4158 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4161 (define_insn_and_split "zero_extendqihi2"
4162 [(set (match_operand:HI 0 "register_operand" "=r")
4163 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4167 [(set (match_dup 2) (match_dup 1))
4168 (set (match_dup 3) (const_int 0))]
4170 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4171 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4173 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4174 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4177 (define_insn_and_split "zero_extendqipsi2"
4178 [(set (match_operand:PSI 0 "register_operand" "=r")
4179 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4183 [(set (match_dup 2) (match_dup 1))
4184 (set (match_dup 3) (const_int 0))
4185 (set (match_dup 4) (const_int 0))]
4187 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4188 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4189 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4192 (define_insn_and_split "zero_extendqisi2"
4193 [(set (match_operand:SI 0 "register_operand" "=r")
4194 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4198 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4199 (set (match_dup 3) (const_int 0))]
4201 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4202 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4204 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4205 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4208 (define_insn_and_split "zero_extendhipsi2"
4209 [(set (match_operand:PSI 0 "register_operand" "=r")
4210 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4214 [(set (match_dup 2) (match_dup 1))
4215 (set (match_dup 3) (const_int 0))]
4217 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4218 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4221 (define_insn_and_split "n_extendhipsi2"
4222 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4223 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4224 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4225 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4229 [(set (match_dup 4) (match_dup 2))
4230 (set (match_dup 3) (match_dup 6))
4231 ; no-op move in the case where no scratch is needed
4232 (set (match_dup 5) (match_dup 3))]
4234 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4235 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4236 operands[6] = operands[1];
4238 if (GET_CODE (operands[3]) == SCRATCH)
4239 operands[3] = operands[5];
4242 (define_insn_and_split "zero_extendhisi2"
4243 [(set (match_operand:SI 0 "register_operand" "=r")
4244 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4248 [(set (match_dup 2) (match_dup 1))
4249 (set (match_dup 3) (const_int 0))]
4251 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4252 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4254 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4255 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4258 (define_insn_and_split "zero_extendpsisi2"
4259 [(set (match_operand:SI 0 "register_operand" "=r")
4260 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4264 [(set (match_dup 2) (match_dup 1))
4265 (set (match_dup 3) (const_int 0))]
4267 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4268 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4271 (define_insn_and_split "zero_extendqidi2"
4272 [(set (match_operand:DI 0 "register_operand" "=r")
4273 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4277 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4278 (set (match_dup 3) (const_int 0))]
4280 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4281 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4283 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4284 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4287 (define_insn_and_split "zero_extendhidi2"
4288 [(set (match_operand:DI 0 "register_operand" "=r")
4289 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4293 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4294 (set (match_dup 3) (const_int 0))]
4296 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4297 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4299 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4300 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4303 (define_insn_and_split "zero_extendsidi2"
4304 [(set (match_operand:DI 0 "register_operand" "=r")
4305 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4309 [(set (match_dup 2) (match_dup 1))
4310 (set (match_dup 3) (const_int 0))]
4312 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4313 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4315 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4316 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4319 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4322 ; Optimize negated tests into reverse compare if overflow is undefined.
4323 (define_insn "*negated_tstqi"
4325 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4327 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4328 "cp __zero_reg__,%0"
4329 [(set_attr "cc" "compare")
4330 (set_attr "length" "1")])
4332 (define_insn "*reversed_tstqi"
4334 (compare (const_int 0)
4335 (match_operand:QI 0 "register_operand" "r")))]
4337 "cp __zero_reg__,%0"
4338 [(set_attr "cc" "compare")
4339 (set_attr "length" "2")])
4341 (define_insn "*negated_tsthi"
4343 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4345 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4346 "cp __zero_reg__,%A0
4347 cpc __zero_reg__,%B0"
4348 [(set_attr "cc" "compare")
4349 (set_attr "length" "2")])
4351 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4352 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4353 (define_insn "*reversed_tsthi"
4355 (compare (const_int 0)
4356 (match_operand:HI 0 "register_operand" "r")))
4357 (clobber (match_scratch:QI 1 "=X"))]
4359 "cp __zero_reg__,%A0
4360 cpc __zero_reg__,%B0"
4361 [(set_attr "cc" "compare")
4362 (set_attr "length" "2")])
4364 (define_insn "*negated_tstpsi"
4366 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4368 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4369 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4370 [(set_attr "cc" "compare")
4371 (set_attr "length" "3")])
4373 (define_insn "*reversed_tstpsi"
4375 (compare (const_int 0)
4376 (match_operand:PSI 0 "register_operand" "r")))
4377 (clobber (match_scratch:QI 1 "=X"))]
4379 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4380 [(set_attr "cc" "compare")
4381 (set_attr "length" "3")])
4383 (define_insn "*negated_tstsi"
4385 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4387 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4388 "cp __zero_reg__,%A0
4389 cpc __zero_reg__,%B0
4390 cpc __zero_reg__,%C0
4391 cpc __zero_reg__,%D0"
4392 [(set_attr "cc" "compare")
4393 (set_attr "length" "4")])
4395 ;; "*reversed_tstsi"
4396 ;; "*reversed_tstsq" "*reversed_tstusq"
4397 ;; "*reversed_tstsa" "*reversed_tstusa"
4398 (define_insn "*reversed_tst<mode>"
4400 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4401 (match_operand:ALL4 1 "register_operand" "r")))
4402 (clobber (match_scratch:QI 2 "=X"))]
4404 "cp __zero_reg__,%A1
4405 cpc __zero_reg__,%B1
4406 cpc __zero_reg__,%C1
4407 cpc __zero_reg__,%D1"
4408 [(set_attr "cc" "compare")
4409 (set_attr "length" "4")])
4413 ;; "*cmpqq" "*cmpuqq"
4414 (define_insn "*cmp<mode>"
4416 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4417 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4423 [(set_attr "cc" "compare,compare,compare")
4424 (set_attr "length" "1,1,1")])
4426 (define_insn "*cmpqi_sign_extend"
4428 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4429 (match_operand:HI 1 "s8_operand" "n")))]
4432 [(set_attr "cc" "compare")
4433 (set_attr "length" "1")])
4436 ;; "*cmphq" "*cmpuhq"
4437 ;; "*cmpha" "*cmpuha"
4438 (define_insn "*cmp<mode>"
4440 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4441 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4442 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4445 switch (which_alternative)
4449 return avr_out_tsthi (insn, operands, NULL);
4452 return "cp %A0,%A1\;cpc %B0,%B1";
4455 if (<MODE>mode != HImode)
4457 return reg_unused_after (insn, operands[0])
4458 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4459 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4462 if (<MODE>mode != HImode)
4464 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4467 return avr_out_compare (insn, operands, NULL);
4469 [(set_attr "cc" "compare")
4470 (set_attr "length" "1,2,2,3,4,2,4")
4471 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4473 (define_insn "*cmppsi"
4475 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4476 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4477 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4480 switch (which_alternative)
4483 return avr_out_tstpsi (insn, operands, NULL);
4486 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4489 return reg_unused_after (insn, operands[0])
4490 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4491 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4494 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4497 return avr_out_compare (insn, operands, NULL);
4499 [(set_attr "cc" "compare")
4500 (set_attr "length" "3,3,5,6,3,7")
4501 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4504 ;; "*cmpsq" "*cmpusq"
4505 ;; "*cmpsa" "*cmpusa"
4506 (define_insn "*cmp<mode>"
4508 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4509 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4510 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4513 if (0 == which_alternative)
4514 return avr_out_tstsi (insn, operands, NULL);
4515 else if (1 == which_alternative)
4516 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4518 return avr_out_compare (insn, operands, NULL);
4520 [(set_attr "cc" "compare")
4521 (set_attr "length" "4,4,4,5,8")
4522 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4525 ;; ----------------------------------------------------------------------
4526 ;; JUMP INSTRUCTIONS
4527 ;; ----------------------------------------------------------------------
4528 ;; Conditional jump instructions
4531 ;; "cbranchqq4" "cbranchuqq4"
4532 (define_expand "cbranch<mode>4"
4534 (compare (match_operand:ALL1 1 "register_operand" "")
4535 (match_operand:ALL1 2 "nonmemory_operand" "")))
4538 (match_operator 0 "ordered_comparison_operator" [(cc0)
4540 (label_ref (match_operand 3 "" ""))
4543 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4544 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4546 (define_expand "cbranch<mode>4"
4547 [(parallel [(set (cc0)
4548 (compare (match_operand:ORDERED234 1 "register_operand" "")
4549 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4550 (clobber (match_scratch:QI 4 ""))])
4553 (match_operator 0 "ordered_comparison_operator" [(cc0)
4555 (label_ref (match_operand 3 "" ""))
4559 ;; Test a single bit in a QI/HI/SImode register.
4560 ;; Combine will create zero extract patterns for single bit tests.
4561 ;; permit any mode in source pattern by using VOIDmode.
4563 (define_insn "*sbrx_branch<mode>"
4566 (match_operator 0 "eqne_operator"
4568 (match_operand:VOID 1 "register_operand" "r")
4570 (match_operand 2 "const_int_operand" "n"))
4572 (label_ref (match_operand 3 "" ""))
4576 return avr_out_sbxx_branch (insn, operands);
4578 [(set (attr "length")
4579 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4580 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4582 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4585 (set_attr "cc" "clobber")])
4587 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4588 ;; or for old peepholes.
4589 ;; Fixme - bitwise Mask will not work for DImode
4591 (define_insn "*sbrx_and_branch<mode>"
4594 (match_operator 0 "eqne_operator"
4596 (match_operand:QISI 1 "register_operand" "r")
4597 (match_operand:QISI 2 "single_one_operand" "n"))
4599 (label_ref (match_operand 3 "" ""))
4603 HOST_WIDE_INT bitnumber;
4604 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4605 operands[2] = GEN_INT (bitnumber);
4606 return avr_out_sbxx_branch (insn, operands);
4608 [(set (attr "length")
4609 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4610 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4612 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4615 (set_attr "cc" "clobber")])
4617 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4619 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4621 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4622 (label_ref (match_operand 1 "" ""))
4625 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4629 (label_ref (match_dup 1))
4633 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4635 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4636 (label_ref (match_operand 1 "" ""))
4639 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4643 (label_ref (match_dup 1))
4647 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4649 (clobber (match_operand:HI 2 ""))])
4650 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4651 (label_ref (match_operand 1 "" ""))
4654 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4656 (label_ref (match_dup 1))
4660 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4662 (clobber (match_operand:HI 2 ""))])
4663 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4664 (label_ref (match_operand 1 "" ""))
4667 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4669 (label_ref (match_dup 1))
4673 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4675 (clobber (match_operand:SI 2 ""))])
4676 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4677 (label_ref (match_operand 1 "" ""))
4680 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4682 (label_ref (match_dup 1))
4684 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4687 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4689 (clobber (match_operand:SI 2 ""))])
4690 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4691 (label_ref (match_operand 1 "" ""))
4694 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4696 (label_ref (match_dup 1))
4698 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4700 ;; ************************************************************************
4701 ;; Implementation of conditional jumps here.
4702 ;; Compare with 0 (test) jumps
4703 ;; ************************************************************************
4705 (define_insn "branch"
4707 (if_then_else (match_operator 1 "simple_comparison_operator"
4710 (label_ref (match_operand 0 "" ""))
4714 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4716 [(set_attr "type" "branch")
4717 (set_attr "cc" "clobber")])
4720 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4721 ;; or optimized in the remainder.
4723 (define_insn "branch_unspec"
4725 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4728 (label_ref (match_operand 0 "" ""))
4730 ] UNSPEC_IDENTITY))]
4733 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4735 [(set_attr "type" "branch")
4736 (set_attr "cc" "none")])
4738 ;; ****************************************************************
4739 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4740 ;; Convert them all to proper jumps.
4741 ;; ****************************************************************/
4743 (define_insn "difficult_branch"
4745 (if_then_else (match_operator 1 "difficult_comparison_operator"
4748 (label_ref (match_operand 0 "" ""))
4752 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4754 [(set_attr "type" "branch1")
4755 (set_attr "cc" "clobber")])
4759 (define_insn "rvbranch"
4761 (if_then_else (match_operator 1 "simple_comparison_operator"
4765 (label_ref (match_operand 0 "" ""))))]
4768 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4770 [(set_attr "type" "branch1")
4771 (set_attr "cc" "clobber")])
4773 (define_insn "difficult_rvbranch"
4775 (if_then_else (match_operator 1 "difficult_comparison_operator"
4779 (label_ref (match_operand 0 "" ""))))]
4782 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4784 [(set_attr "type" "branch")
4785 (set_attr "cc" "clobber")])
4787 ;; **************************************************************************
4788 ;; Unconditional and other jump instructions.
4792 (label_ref (match_operand 0 "" "")))]
4795 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4799 [(set (attr "length")
4800 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4801 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4804 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4805 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4808 (set_attr "cc" "none")])
4812 ;; Operand 1 not used on the AVR.
4813 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4814 (define_expand "call"
4815 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4816 (match_operand:HI 1 "general_operand" ""))
4817 (use (const_int 0))])])
4819 ;; Operand 1 not used on the AVR.
4820 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4821 (define_expand "sibcall"
4822 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4823 (match_operand:HI 1 "general_operand" ""))
4824 (use (const_int 1))])])
4828 ;; Operand 2 not used on the AVR.
4829 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4830 (define_expand "call_value"
4831 [(parallel[(set (match_operand 0 "register_operand" "")
4832 (call (match_operand:HI 1 "call_insn_operand" "")
4833 (match_operand:HI 2 "general_operand" "")))
4834 (use (const_int 0))])])
4836 ;; Operand 2 not used on the AVR.
4837 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4838 (define_expand "sibcall_value"
4839 [(parallel[(set (match_operand 0 "register_operand" "")
4840 (call (match_operand:HI 1 "call_insn_operand" "")
4841 (match_operand:HI 2 "general_operand" "")))
4842 (use (const_int 1))])])
4844 (define_insn "call_insn"
4845 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4846 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4847 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4848 ;; Operand 1 not used on the AVR.
4849 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4856 [(set_attr "cc" "clobber")
4857 (set_attr "length" "1,*,1,*")
4858 (set_attr "adjust_len" "*,call,*,call")])
4860 (define_insn "call_value_insn"
4861 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4862 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4863 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4864 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4865 ;; Operand 2 not used on the AVR.
4866 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4873 [(set_attr "cc" "clobber")
4874 (set_attr "length" "1,*,1,*")
4875 (set_attr "adjust_len" "*,call,*,call")])
4881 [(set_attr "cc" "none")
4882 (set_attr "length" "1")])
4886 (define_expand "indirect_jump"
4888 (match_operand:HI 0 "nonmemory_operand" ""))]
4891 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4893 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4898 (define_insn "*indirect_jump"
4900 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4906 push %A0\;push %B0\;ret
4908 [(set_attr "length" "1,2,1,3,1")
4909 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4910 (set_attr "cc" "none")])
4913 ;; For entries in jump table see avr_output_addr_vec_elt.
4916 ;; "rjmp .L<n>" instructions for <= 8K devices
4917 ;; ".word gs(.L<n>)" addresses for > 8K devices
4918 (define_insn "*tablejump"
4920 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4922 (use (label_ref (match_operand 1 "" "")))
4923 (clobber (match_dup 0))]
4927 push %A0\;push %B0\;ret
4929 [(set_attr "length" "1,3,2")
4930 (set_attr "isa" "rjmp,rjmp,jmp")
4931 (set_attr "cc" "none,none,clobber")])
4934 (define_expand "casesi"
4935 [(parallel [(set (match_dup 6)
4936 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4937 (match_operand:HI 1 "register_operand" "")))
4938 (clobber (scratch:QI))])
4939 (parallel [(set (cc0)
4940 (compare (match_dup 6)
4941 (match_operand:HI 2 "register_operand" "")))
4942 (clobber (match_scratch:QI 9 ""))])
4945 (if_then_else (gtu (cc0)
4947 (label_ref (match_operand 4 "" ""))
4951 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4953 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4954 (use (label_ref (match_dup 3)))
4955 (clobber (match_dup 6))])]
4958 operands[6] = gen_reg_rtx (HImode);
4962 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4963 ;; This instruction sets Z flag
4966 [(set (cc0) (const_int 0))]
4969 [(set_attr "length" "1")
4970 (set_attr "cc" "compare")])
4972 ;; Clear/set/test a single bit in I/O address space.
4975 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4976 (and:QI (mem:QI (match_dup 0))
4977 (match_operand:QI 1 "single_zero_operand" "n")))]
4980 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4981 return "cbi %i0,%2";
4983 [(set_attr "length" "1")
4984 (set_attr "cc" "none")])
4987 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4988 (ior:QI (mem:QI (match_dup 0))
4989 (match_operand:QI 1 "single_one_operand" "n")))]
4992 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4993 return "sbi %i0,%2";
4995 [(set_attr "length" "1")
4996 (set_attr "cc" "none")])
4998 ;; Lower half of the I/O space - use sbic/sbis directly.
4999 (define_insn "*sbix_branch"
5002 (match_operator 0 "eqne_operator"
5004 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5006 (match_operand 2 "const_int_operand" "n"))
5008 (label_ref (match_operand 3 "" ""))
5012 return avr_out_sbxx_branch (insn, operands);
5014 [(set (attr "length")
5015 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5016 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5018 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5021 (set_attr "cc" "clobber")])
5023 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5024 (define_insn "*sbix_branch_bit7"
5027 (match_operator 0 "gelt_operator"
5028 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
5030 (label_ref (match_operand 2 "" ""))
5034 operands[3] = operands[2];
5035 operands[2] = GEN_INT (7);
5036 return avr_out_sbxx_branch (insn, operands);
5038 [(set (attr "length")
5039 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5040 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5042 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5045 (set_attr "cc" "clobber")])
5047 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5048 (define_insn "*sbix_branch_tmp"
5051 (match_operator 0 "eqne_operator"
5053 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5055 (match_operand 2 "const_int_operand" "n"))
5057 (label_ref (match_operand 3 "" ""))
5061 return avr_out_sbxx_branch (insn, operands);
5063 [(set (attr "length")
5064 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5065 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5067 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5070 (set_attr "cc" "clobber")])
5072 (define_insn "*sbix_branch_tmp_bit7"
5075 (match_operator 0 "gelt_operator"
5076 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5078 (label_ref (match_operand 2 "" ""))
5082 operands[3] = operands[2];
5083 operands[2] = GEN_INT (7);
5084 return avr_out_sbxx_branch (insn, operands);
5086 [(set (attr "length")
5087 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5088 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5090 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5093 (set_attr "cc" "clobber")])
5095 ;; ************************* Peepholes ********************************
5097 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5098 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5099 (plus:SI (match_dup 0)
5101 (clobber (scratch:QI))])
5102 (parallel [(set (cc0)
5103 (compare (match_dup 0)
5105 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5107 (if_then_else (eqne (cc0)
5109 (label_ref (match_operand 2 "" ""))
5116 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5117 output_asm_insn ("sbiw %0,1" CR_TAB
5118 "sbc %C0,__zero_reg__" CR_TAB
5119 "sbc %D0,__zero_reg__", operands);
5121 output_asm_insn ("subi %A0,1" CR_TAB
5122 "sbc %B0,__zero_reg__" CR_TAB
5123 "sbc %C0,__zero_reg__" CR_TAB
5124 "sbc %D0,__zero_reg__", operands);
5126 jump_mode = avr_jump_mode (operands[2], insn);
5127 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5128 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5132 case 1: return "%1 %2";
5133 case 2: return "%1 .+2\;rjmp %2";
5134 case 3: return "%1 .+4\;jmp %2";
5141 (define_peephole ; "*dec-and-branchhi!=-1"
5142 [(set (match_operand:HI 0 "d_register_operand" "")
5143 (plus:HI (match_dup 0)
5145 (parallel [(set (cc0)
5146 (compare (match_dup 0)
5148 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5150 (if_then_else (eqne (cc0)
5152 (label_ref (match_operand 2 "" ""))
5159 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5160 output_asm_insn ("sbiw %0,1", operands);
5162 output_asm_insn ("subi %A0,1" CR_TAB
5163 "sbc %B0,__zero_reg__", operands);
5165 jump_mode = avr_jump_mode (operands[2], insn);
5166 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5167 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5171 case 1: return "%1 %2";
5172 case 2: return "%1 .+2\;rjmp %2";
5173 case 3: return "%1 .+4\;jmp %2";
5180 ;; Same as above but with clobber flavour of addhi3
5181 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5182 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5183 (plus:HI (match_dup 0)
5185 (clobber (scratch:QI))])
5186 (parallel [(set (cc0)
5187 (compare (match_dup 0)
5189 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5191 (if_then_else (eqne (cc0)
5193 (label_ref (match_operand 2 "" ""))
5200 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5201 output_asm_insn ("sbiw %0,1", operands);
5203 output_asm_insn ("subi %A0,1" CR_TAB
5204 "sbc %B0,__zero_reg__", operands);
5206 jump_mode = avr_jump_mode (operands[2], insn);
5207 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5208 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5212 case 1: return "%1 %2";
5213 case 2: return "%1 .+2\;rjmp %2";
5214 case 3: return "%1 .+4\;jmp %2";
5221 ;; Same as above but with clobber flavour of addhi3
5222 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5223 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5224 (plus:HI (match_dup 0)
5226 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5227 (parallel [(set (cc0)
5228 (compare (match_dup 0)
5230 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5232 (if_then_else (eqne (cc0)
5234 (label_ref (match_operand 2 "" ""))
5241 output_asm_insn ("ldi %3,1" CR_TAB
5243 "sbc %B0,__zero_reg__", operands);
5245 jump_mode = avr_jump_mode (operands[2], insn);
5246 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5247 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5251 case 1: return "%1 %2";
5252 case 2: return "%1 .+2\;rjmp %2";
5253 case 3: return "%1 .+4\;jmp %2";
5260 (define_peephole ; "*dec-and-branchqi!=-1"
5261 [(set (match_operand:QI 0 "d_register_operand" "")
5262 (plus:QI (match_dup 0)
5265 (compare (match_dup 0)
5268 (if_then_else (eqne (cc0)
5270 (label_ref (match_operand 1 "" ""))
5277 cc_status.value1 = operands[0];
5278 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5280 output_asm_insn ("subi %A0,1", operands);
5282 jump_mode = avr_jump_mode (operands[1], insn);
5283 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5284 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5288 case 1: return "%0 %1";
5289 case 2: return "%0 .+2\;rjmp %1";
5290 case 3: return "%0 .+4\;jmp %1";
5298 (define_peephole ; "*cpse.eq"
5300 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5301 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5303 (if_then_else (eq (cc0)
5305 (label_ref (match_operand 0 "" ""))
5307 "jump_over_one_insn_p (insn, operands[0])"
5310 cpse %1,__zero_reg__")
5312 ;; This peephole avoids code like
5315 ;; BREQ .+2 ; branch
5318 ;; Notice that the peephole is always shorter than cmpqi + branch.
5319 ;; The reason to write it as peephole is that sequences like
5324 ;; shall not be superseeded. With a respective combine pattern
5325 ;; the latter sequence would be
5328 ;; CPSE Rm, __zero_reg__
5331 ;; and thus longer and slower and not easy to be rolled back.
5333 (define_peephole ; "*cpse.ne"
5335 (compare (match_operand:ALL1 1 "register_operand" "")
5336 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5338 (if_then_else (ne (cc0)
5340 (label_ref (match_operand 0 "" ""))
5343 || !avr_current_device->errata_skip"
5345 if (operands[2] == CONST0_RTX (<MODE>mode))
5346 operands[2] = zero_reg_rtx;
5348 return 3 == avr_jump_mode (operands[0], insn)
5349 ? "cpse %1,%2\;jmp %0"
5350 : "cpse %1,%2\;rjmp %0";
5353 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5354 ;;prologue/epilogue support instructions
5356 (define_insn "popqi"
5357 [(set (match_operand:QI 0 "register_operand" "=r")
5358 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5361 [(set_attr "cc" "none")
5362 (set_attr "length" "1")])
5364 ;; Enable Interrupts
5365 (define_expand "enable_interrupt"
5366 [(clobber (const_int 0))]
5369 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5370 MEM_VOLATILE_P (mem) = 1;
5371 emit_insn (gen_cli_sei (const1_rtx, mem));
5375 ;; Disable Interrupts
5376 (define_expand "disable_interrupt"
5377 [(clobber (const_int 0))]
5380 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5381 MEM_VOLATILE_P (mem) = 1;
5382 emit_insn (gen_cli_sei (const0_rtx, mem));
5386 (define_insn "cli_sei"
5387 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5388 UNSPECV_ENABLE_IRQS)
5389 (set (match_operand:BLK 1 "" "")
5390 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5395 [(set_attr "length" "1")
5396 (set_attr "cc" "none")])
5398 ;; Library prologue saves
5399 (define_insn "call_prologue_saves"
5400 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5401 (match_operand:HI 0 "immediate_operand" "i,i")
5402 (set (reg:HI REG_SP)
5403 (minus:HI (reg:HI REG_SP)
5404 (match_operand:HI 1 "immediate_operand" "i,i")))
5405 (use (reg:HI REG_X))
5406 (clobber (reg:HI REG_Z))]
5408 "ldi r30,lo8(gs(1f))
5410 %~jmp __prologue_saves__+((18 - %0) * 2)
5412 [(set_attr "length" "5,6")
5413 (set_attr "cc" "clobber")
5414 (set_attr "isa" "rjmp,jmp")])
5416 ; epilogue restores using library
5417 (define_insn "epilogue_restores"
5418 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5420 (plus:HI (reg:HI REG_Y)
5421 (match_operand:HI 0 "immediate_operand" "i,i")))
5422 (set (reg:HI REG_SP)
5423 (plus:HI (reg:HI REG_Y)
5425 (clobber (reg:QI REG_Z))]
5428 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5429 [(set_attr "length" "2,3")
5430 (set_attr "cc" "clobber")
5431 (set_attr "isa" "rjmp,jmp")])
5434 (define_insn "return"
5436 "reload_completed && avr_simple_epilogue ()"
5438 [(set_attr "cc" "none")
5439 (set_attr "length" "1")])
5441 (define_insn "return_from_epilogue"
5445 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5446 && !cfun->machine->is_naked"
5448 [(set_attr "cc" "none")
5449 (set_attr "length" "1")])
5451 (define_insn "return_from_interrupt_epilogue"
5455 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5456 && !cfun->machine->is_naked"
5458 [(set_attr "cc" "none")
5459 (set_attr "length" "1")])
5461 (define_insn "return_from_naked_epilogue"
5465 && cfun->machine->is_naked"
5467 [(set_attr "cc" "none")
5468 (set_attr "length" "0")])
5470 (define_expand "prologue"
5474 avr_expand_prologue ();
5478 (define_expand "epilogue"
5482 avr_expand_epilogue (false /* sibcall_p */);
5486 (define_expand "sibcall_epilogue"
5490 avr_expand_epilogue (true /* sibcall_p */);
5494 ;; Some instructions resp. instruction sequences available
5497 (define_insn "delay_cycles_1"
5498 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5500 UNSPECV_DELAY_CYCLES)
5501 (set (match_operand:BLK 1 "" "")
5502 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5503 (clobber (match_scratch:QI 2 "=&d"))]
5508 [(set_attr "length" "3")
5509 (set_attr "cc" "clobber")])
5511 (define_insn "delay_cycles_2"
5512 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5514 UNSPECV_DELAY_CYCLES)
5515 (set (match_operand:BLK 1 "" "")
5516 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5517 (clobber (match_scratch:HI 2 "=&w"))]
5523 [(set_attr "length" "4")
5524 (set_attr "cc" "clobber")])
5526 (define_insn "delay_cycles_3"
5527 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5529 UNSPECV_DELAY_CYCLES)
5530 (set (match_operand:BLK 1 "" "")
5531 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5532 (clobber (match_scratch:QI 2 "=&d"))
5533 (clobber (match_scratch:QI 3 "=&d"))
5534 (clobber (match_scratch:QI 4 "=&d"))]
5543 [(set_attr "length" "7")
5544 (set_attr "cc" "clobber")])
5546 (define_insn "delay_cycles_4"
5547 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5549 UNSPECV_DELAY_CYCLES)
5550 (set (match_operand:BLK 1 "" "")
5551 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5552 (clobber (match_scratch:QI 2 "=&d"))
5553 (clobber (match_scratch:QI 3 "=&d"))
5554 (clobber (match_scratch:QI 4 "=&d"))
5555 (clobber (match_scratch:QI 5 "=&d"))]
5566 [(set_attr "length" "9")
5567 (set_attr "cc" "clobber")])
5570 ;; __builtin_avr_insert_bits
5572 (define_insn "insert_bits"
5573 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5574 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5575 (match_operand:QI 2 "register_operand" "r ,r ,r")
5576 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5577 UNSPEC_INSERT_BITS))]
5580 return avr_out_insert_bits (operands, NULL);
5582 [(set_attr "adjust_len" "insert_bits")
5583 (set_attr "cc" "clobber")])
5586 ;; __builtin_avr_flash_segment
5588 ;; Just a helper for the next "official" expander.
5590 (define_expand "flash_segment1"
5591 [(set (match_operand:QI 0 "register_operand" "")
5592 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5595 (compare (match_dup 0)
5598 (if_then_else (ge (cc0)
5600 (label_ref (match_operand 2 "" ""))
5605 (define_expand "flash_segment"
5606 [(parallel [(match_operand:QI 0 "register_operand" "")
5607 (match_operand:PSI 1 "register_operand" "")])]
5610 rtx label = gen_label_rtx ();
5611 emit (gen_flash_segment1 (operands[0], operands[1], label));
5616 ;; Actually, it's too late now to work out address spaces known at compiletime.
5617 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5618 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5619 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5621 (define_insn_and_split "*split.flash_segment"
5622 [(set (match_operand:QI 0 "register_operand" "=d")
5623 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5624 (match_operand:HI 2 "register_operand" "r"))
5627 { gcc_unreachable(); }
5635 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5636 ;; better 8-bit parity recognition.
5638 (define_expand "parityhi2"
5639 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5640 (parity:HI (match_operand:HI 1 "register_operand" "")))
5641 (clobber (reg:HI 24))])])
5643 (define_insn_and_split "*parityhi2"
5644 [(set (match_operand:HI 0 "register_operand" "=r")
5645 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5646 (clobber (reg:HI 24))]
5648 { gcc_unreachable(); }
5653 (parity:HI (reg:HI 24)))
5657 (define_insn_and_split "*parityqihi2"
5658 [(set (match_operand:HI 0 "register_operand" "=r")
5659 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5660 (clobber (reg:HI 24))]
5662 { gcc_unreachable(); }
5667 (zero_extend:HI (parity:QI (reg:QI 24))))
5671 (define_expand "paritysi2"
5673 (match_operand:SI 1 "register_operand" ""))
5675 (truncate:HI (parity:SI (reg:SI 22))))
5678 (set (match_operand:SI 0 "register_operand" "")
5679 (zero_extend:SI (match_dup 2)))]
5682 operands[2] = gen_reg_rtx (HImode);
5685 (define_insn "*parityhi2.libgcc"
5687 (parity:HI (reg:HI 24)))]
5689 "%~call __parityhi2"
5690 [(set_attr "type" "xcall")
5691 (set_attr "cc" "clobber")])
5693 (define_insn "*parityqihi2.libgcc"
5695 (zero_extend:HI (parity:QI (reg:QI 24))))]
5697 "%~call __parityqi2"
5698 [(set_attr "type" "xcall")
5699 (set_attr "cc" "clobber")])
5701 (define_insn "*paritysihi2.libgcc"
5703 (truncate:HI (parity:SI (reg:SI 22))))]
5705 "%~call __paritysi2"
5706 [(set_attr "type" "xcall")
5707 (set_attr "cc" "clobber")])
5712 (define_expand "popcounthi2"
5714 (match_operand:HI 1 "register_operand" ""))
5716 (popcount:HI (reg:HI 24)))
5717 (set (match_operand:HI 0 "register_operand" "")
5722 (define_expand "popcountsi2"
5724 (match_operand:SI 1 "register_operand" ""))
5726 (truncate:HI (popcount:SI (reg:SI 22))))
5729 (set (match_operand:SI 0 "register_operand" "")
5730 (zero_extend:SI (match_dup 2)))]
5733 operands[2] = gen_reg_rtx (HImode);
5736 (define_insn "*popcounthi2.libgcc"
5738 (popcount:HI (reg:HI 24)))]
5740 "%~call __popcounthi2"
5741 [(set_attr "type" "xcall")
5742 (set_attr "cc" "clobber")])
5744 (define_insn "*popcountsi2.libgcc"
5746 (truncate:HI (popcount:SI (reg:SI 22))))]
5748 "%~call __popcountsi2"
5749 [(set_attr "type" "xcall")
5750 (set_attr "cc" "clobber")])
5752 (define_insn "*popcountqi2.libgcc"
5754 (popcount:QI (reg:QI 24)))]
5756 "%~call __popcountqi2"
5757 [(set_attr "type" "xcall")
5758 (set_attr "cc" "clobber")])
5760 (define_insn_and_split "*popcountqihi2.libgcc"
5762 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5767 (popcount:QI (reg:QI 24)))
5771 ;; Count Leading Zeros
5773 (define_expand "clzhi2"
5775 (match_operand:HI 1 "register_operand" ""))
5776 (parallel [(set (reg:HI 24)
5777 (clz:HI (reg:HI 24)))
5778 (clobber (reg:QI 26))])
5779 (set (match_operand:HI 0 "register_operand" "")
5782 (define_expand "clzsi2"
5784 (match_operand:SI 1 "register_operand" ""))
5785 (parallel [(set (reg:HI 24)
5786 (truncate:HI (clz:SI (reg:SI 22))))
5787 (clobber (reg:QI 26))])
5790 (set (match_operand:SI 0 "register_operand" "")
5791 (zero_extend:SI (match_dup 2)))]
5794 operands[2] = gen_reg_rtx (HImode);
5797 (define_insn "*clzhi2.libgcc"
5799 (clz:HI (reg:HI 24)))
5800 (clobber (reg:QI 26))]
5803 [(set_attr "type" "xcall")
5804 (set_attr "cc" "clobber")])
5806 (define_insn "*clzsihi2.libgcc"
5808 (truncate:HI (clz:SI (reg:SI 22))))
5809 (clobber (reg:QI 26))]
5812 [(set_attr "type" "xcall")
5813 (set_attr "cc" "clobber")])
5815 ;; Count Trailing Zeros
5817 (define_expand "ctzhi2"
5819 (match_operand:HI 1 "register_operand" ""))
5820 (parallel [(set (reg:HI 24)
5821 (ctz:HI (reg:HI 24)))
5822 (clobber (reg:QI 26))])
5823 (set (match_operand:HI 0 "register_operand" "")
5826 (define_expand "ctzsi2"
5828 (match_operand:SI 1 "register_operand" ""))
5829 (parallel [(set (reg:HI 24)
5830 (truncate:HI (ctz:SI (reg:SI 22))))
5831 (clobber (reg:QI 22))
5832 (clobber (reg:QI 26))])
5835 (set (match_operand:SI 0 "register_operand" "")
5836 (zero_extend:SI (match_dup 2)))]
5839 operands[2] = gen_reg_rtx (HImode);
5842 (define_insn "*ctzhi2.libgcc"
5844 (ctz:HI (reg:HI 24)))
5845 (clobber (reg:QI 26))]
5848 [(set_attr "type" "xcall")
5849 (set_attr "cc" "clobber")])
5851 (define_insn "*ctzsihi2.libgcc"
5853 (truncate:HI (ctz:SI (reg:SI 22))))
5854 (clobber (reg:QI 22))
5855 (clobber (reg:QI 26))]
5858 [(set_attr "type" "xcall")
5859 (set_attr "cc" "clobber")])
5863 (define_expand "ffshi2"
5865 (match_operand:HI 1 "register_operand" ""))
5866 (parallel [(set (reg:HI 24)
5867 (ffs:HI (reg:HI 24)))
5868 (clobber (reg:QI 26))])
5869 (set (match_operand:HI 0 "register_operand" "")
5872 (define_expand "ffssi2"
5874 (match_operand:SI 1 "register_operand" ""))
5875 (parallel [(set (reg:HI 24)
5876 (truncate:HI (ffs:SI (reg:SI 22))))
5877 (clobber (reg:QI 22))
5878 (clobber (reg:QI 26))])
5881 (set (match_operand:SI 0 "register_operand" "")
5882 (zero_extend:SI (match_dup 2)))]
5885 operands[2] = gen_reg_rtx (HImode);
5888 (define_insn "*ffshi2.libgcc"
5890 (ffs:HI (reg:HI 24)))
5891 (clobber (reg:QI 26))]
5894 [(set_attr "type" "xcall")
5895 (set_attr "cc" "clobber")])
5897 (define_insn "*ffssihi2.libgcc"
5899 (truncate:HI (ffs:SI (reg:SI 22))))
5900 (clobber (reg:QI 22))
5901 (clobber (reg:QI 26))]
5904 [(set_attr "type" "xcall")
5905 (set_attr "cc" "clobber")])
5909 (define_insn "copysignsf3"
5910 [(set (match_operand:SF 0 "register_operand" "=r")
5911 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5912 (match_operand:SF 2 "register_operand" "r")]
5915 "bst %D2,7\;bld %D0,7"
5916 [(set_attr "length" "2")
5917 (set_attr "cc" "none")])
5919 ;; Swap Bytes (change byte-endianess)
5921 (define_expand "bswapsi2"
5923 (match_operand:SI 1 "register_operand" ""))
5925 (bswap:SI (reg:SI 22)))
5926 (set (match_operand:SI 0 "register_operand" "")
5929 (define_insn "*bswapsi2.libgcc"
5931 (bswap:SI (reg:SI 22)))]
5934 [(set_attr "type" "xcall")
5935 (set_attr "cc" "clobber")])
5940 ;; NOP taking 1 or 2 Ticks
5941 (define_expand "nopv"
5942 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5945 (unspec_volatile:BLK [(match_dup 1)]
5946 UNSPECV_MEMORY_BARRIER))])]
5949 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5950 MEM_VOLATILE_P (operands[1]) = 1;
5953 (define_insn "*nopv"
5954 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5956 (set (match_operand:BLK 1 "" "")
5957 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5962 [(set_attr "length" "1")
5963 (set_attr "cc" "none")])
5966 (define_expand "sleep"
5967 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5969 (unspec_volatile:BLK [(match_dup 0)]
5970 UNSPECV_MEMORY_BARRIER))])]
5973 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5974 MEM_VOLATILE_P (operands[0]) = 1;
5977 (define_insn "*sleep"
5978 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5979 (set (match_operand:BLK 0 "" "")
5980 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
5983 [(set_attr "length" "1")
5984 (set_attr "cc" "none")])
5987 (define_expand "wdr"
5988 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5990 (unspec_volatile:BLK [(match_dup 0)]
5991 UNSPECV_MEMORY_BARRIER))])]
5994 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5995 MEM_VOLATILE_P (operands[0]) = 1;
5999 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6000 (set (match_operand:BLK 0 "" "")
6001 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6004 [(set_attr "length" "1")
6005 (set_attr "cc" "none")])
6008 (define_expand "fmul"
6010 (match_operand:QI 1 "register_operand" ""))
6012 (match_operand:QI 2 "register_operand" ""))
6013 (parallel [(set (reg:HI 22)
6014 (unspec:HI [(reg:QI 24)
6015 (reg:QI 25)] UNSPEC_FMUL))
6016 (clobber (reg:HI 24))])
6017 (set (match_operand:HI 0 "register_operand" "")
6023 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6028 (define_insn "fmul_insn"
6029 [(set (match_operand:HI 0 "register_operand" "=r")
6030 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6031 (match_operand:QI 2 "register_operand" "a")]
6037 [(set_attr "length" "3")
6038 (set_attr "cc" "clobber")])
6040 (define_insn "*fmul.call"
6042 (unspec:HI [(reg:QI 24)
6043 (reg:QI 25)] UNSPEC_FMUL))
6044 (clobber (reg:HI 24))]
6047 [(set_attr "type" "xcall")
6048 (set_attr "cc" "clobber")])
6051 (define_expand "fmuls"
6053 (match_operand:QI 1 "register_operand" ""))
6055 (match_operand:QI 2 "register_operand" ""))
6056 (parallel [(set (reg:HI 22)
6057 (unspec:HI [(reg:QI 24)
6058 (reg:QI 25)] UNSPEC_FMULS))
6059 (clobber (reg:HI 24))])
6060 (set (match_operand:HI 0 "register_operand" "")
6066 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6071 (define_insn "fmuls_insn"
6072 [(set (match_operand:HI 0 "register_operand" "=r")
6073 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6074 (match_operand:QI 2 "register_operand" "a")]
6080 [(set_attr "length" "3")
6081 (set_attr "cc" "clobber")])
6083 (define_insn "*fmuls.call"
6085 (unspec:HI [(reg:QI 24)
6086 (reg:QI 25)] UNSPEC_FMULS))
6087 (clobber (reg:HI 24))]
6090 [(set_attr "type" "xcall")
6091 (set_attr "cc" "clobber")])
6094 (define_expand "fmulsu"
6096 (match_operand:QI 1 "register_operand" ""))
6098 (match_operand:QI 2 "register_operand" ""))
6099 (parallel [(set (reg:HI 22)
6100 (unspec:HI [(reg:QI 24)
6101 (reg:QI 25)] UNSPEC_FMULSU))
6102 (clobber (reg:HI 24))])
6103 (set (match_operand:HI 0 "register_operand" "")
6109 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6114 (define_insn "fmulsu_insn"
6115 [(set (match_operand:HI 0 "register_operand" "=r")
6116 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6117 (match_operand:QI 2 "register_operand" "a")]
6123 [(set_attr "length" "3")
6124 (set_attr "cc" "clobber")])
6126 (define_insn "*fmulsu.call"
6128 (unspec:HI [(reg:QI 24)
6129 (reg:QI 25)] UNSPEC_FMULSU))
6130 (clobber (reg:HI 24))]
6133 [(set_attr "type" "xcall")
6134 (set_attr "cc" "clobber")])
6137 ;; Some combiner patterns dealing with bits.
6140 ;; Move bit $3.0 into bit $0.$4
6141 (define_insn "*movbitqi.1-6.a"
6142 [(set (match_operand:QI 0 "register_operand" "=r")
6143 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6144 (match_operand:QI 2 "single_zero_operand" "n"))
6145 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6146 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6147 (match_operand:QI 5 "single_one_operand" "n"))))]
6148 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6149 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6150 "bst %3,0\;bld %0,%4"
6151 [(set_attr "length" "2")
6152 (set_attr "cc" "none")])
6154 ;; Move bit $3.0 into bit $0.$4
6155 ;; Variation of above. Unfortunately, there is no canonicalized representation
6156 ;; of moving around bits. So what we see here depends on how user writes down
6157 ;; bit manipulations.
6158 (define_insn "*movbitqi.1-6.b"
6159 [(set (match_operand:QI 0 "register_operand" "=r")
6160 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6161 (match_operand:QI 2 "single_zero_operand" "n"))
6162 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6164 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6165 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6166 "bst %3,0\;bld %0,%4"
6167 [(set_attr "length" "2")
6168 (set_attr "cc" "none")])
6170 ;; Move bit $3.0 into bit $0.0.
6171 ;; For bit 0, combiner generates slightly different pattern.
6172 (define_insn "*movbitqi.0"
6173 [(set (match_operand:QI 0 "register_operand" "=r")
6174 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6175 (match_operand:QI 2 "single_zero_operand" "n"))
6176 (and:QI (match_operand:QI 3 "register_operand" "r")
6178 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6179 "bst %3,0\;bld %0,0"
6180 [(set_attr "length" "2")
6181 (set_attr "cc" "none")])
6183 ;; Move bit $2.0 into bit $0.7.
6184 ;; For bit 7, combiner generates slightly different pattern
6185 (define_insn "*movbitqi.7"
6186 [(set (match_operand:QI 0 "register_operand" "=r")
6187 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6189 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6192 "bst %2,0\;bld %0,7"
6193 [(set_attr "length" "2")
6194 (set_attr "cc" "none")])
6196 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6197 ;; and input/output match. We provide a special pattern for this, because
6198 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6199 ;; operation on I/O is atomic.
6200 (define_insn "*insv.io"
6201 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6203 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6204 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6209 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6210 [(set_attr "length" "1,1,4")
6211 (set_attr "cc" "none")])
6213 (define_insn "*insv.not.io"
6214 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6216 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6217 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6219 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6220 [(set_attr "length" "4")
6221 (set_attr "cc" "none")])
6223 ;; The insv expander.
6224 ;; We only support 1-bit inserts
6225 (define_expand "insv"
6226 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6227 (match_operand:QI 1 "const1_operand" "") ; width
6228 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6229 (match_operand:QI 3 "nonmemory_operand" ""))]
6232 ;; Insert bit $2.0 into $0.$1
6233 (define_insn "*insv.reg"
6234 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6236 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6237 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6241 andi %0,lo8(~(1<<%1))
6245 [(set_attr "length" "2,1,1,2,2")
6246 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6249 ;; Some combine patterns that try to fix bad code when a value is composed
6250 ;; from byte parts like in PR27663.
6251 ;; The patterns give some release but the code still is not optimal,
6252 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6253 ;; That switch obfuscates things here and in many other places.
6255 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6256 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6257 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6258 [(set (match_operand:HISI 0 "register_operand" "=r")
6260 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6261 (match_operand:HISI 2 "register_operand" "0")))]
6266 (xior:QI (match_dup 3)
6269 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6272 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6273 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6274 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6275 [(set (match_operand:HISI 0 "register_operand" "=r")
6277 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6278 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6279 (match_operand:HISI 3 "register_operand" "0")))]
6280 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6282 "&& reload_completed"
6284 (xior:QI (match_dup 4)
6287 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6288 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6291 (define_expand "extzv"
6292 [(set (match_operand:QI 0 "register_operand" "")
6293 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6294 (match_operand:QI 2 "const1_operand" "")
6295 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6297 (define_insn "*extzv"
6298 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6299 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6301 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6305 mov %0,%1\;andi %0,1
6308 bst %1,%2\;clr %0\;bld %0,0"
6309 [(set_attr "length" "1,2,2,2,3")
6310 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6312 (define_insn_and_split "*extzv.qihi1"
6313 [(set (match_operand:HI 0 "register_operand" "=r")
6314 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6316 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6321 (zero_extract:QI (match_dup 1)
6327 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6328 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6331 (define_insn_and_split "*extzv.qihi2"
6332 [(set (match_operand:HI 0 "register_operand" "=r")
6334 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6336 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6341 (zero_extract:QI (match_dup 1)
6347 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6348 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6352 ;; Fixed-point instructions
6353 (include "avr-fixed.md")
6355 ;; Operations on 64-bit registers
6356 (include "avr-dimode.md")