1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
4 ;; 2009, 2010, 2011 Free Software Foundation, Inc.
5 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;; Special characters after '%':
24 ;; A No effect (add 0).
25 ;; B Add 1 to REG number, MEM address or CONST_INT.
28 ;; j Branch condition.
29 ;; k Reverse branch condition.
30 ;;..m..Constant Direct Data memory address.
31 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
32 ;; RAM address. The resulting addres is suitable to be used in IN/OUT.
33 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
34 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
35 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
36 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
37 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
38 ;; just cashes the operand for the next %T. The second %T gets
39 ;; a CONST_INT that represents a bit position.
40 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
41 ;; "%T0%T1" it will print "r19,5".
42 ;; Notice that you must not write a comma between %T0 and %T1.
43 ;; T/t Similar to above, but don't print the comma and the bit number.
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
45 ;; "%T0%t1" it will print "r19".
46 ;;..x..Constant Direct Program memory address.
47 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
48 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
57 (LPM_REGNO 0) ; implicit target register of LPM
58 (TMP_REGNO 0) ; temporary register r0
59 (ZERO_REGNO 1) ; zero register r1
61 ;; RAM addresses of some SFRs common to all Devices.
63 (SREG_ADDR 0x5F) ; Status Register
64 (SP_ADDR 0x5D) ; Stack Pointer
65 (RAMPZ_ADDR 0x5B) ; Address' high part when loading via ELPM
68 (define_c_enum "unspec"
80 (define_c_enum "unspecv"
81 [UNSPECV_PROLOGUE_SAVES
82 UNSPECV_EPILOGUE_RESTORES
93 (include "predicates.md")
94 (include "constraints.md")
96 ;; Condition code settings.
97 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
98 out_plus, out_plus_noclobber"
99 (const_string "none"))
101 (define_attr "type" "branch,branch1,arith,xcall"
102 (const_string "arith"))
104 ;; The size of instructions in bytes.
105 ;; XXX may depend from "cc"
107 (define_attr "length" ""
108 (cond [(eq_attr "type" "branch")
109 (if_then_else (and (ge (minus (pc) (match_dup 0))
111 (le (minus (pc) (match_dup 0))
114 (if_then_else (and (ge (minus (pc) (match_dup 0))
116 (le (minus (pc) (match_dup 0))
120 (eq_attr "type" "branch1")
121 (if_then_else (and (ge (minus (pc) (match_dup 0))
123 (le (minus (pc) (match_dup 0))
126 (if_then_else (and (ge (minus (pc) (match_dup 0))
128 (le (minus (pc) (match_dup 0))
132 (eq_attr "type" "xcall")
133 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
138 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
139 ;; Following insn attribute tells if and how the adjustment has to be
141 ;; no No adjustment needed; attribute "length" is fine.
142 ;; Otherwise do special processing depending on the attribute.
144 (define_attr "adjust_len"
145 "out_bitop, out_plus, out_plus_noclobber, plus64, addto_sp,
146 tsthi, tstpsi, tstsi, compare, compare64, call,
147 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
149 ashlqi, ashrqi, lshrqi,
150 ashlhi, ashrhi, lshrhi,
151 ashlsi, ashrsi, lshrsi,
152 ashlpsi, ashrpsi, lshrpsi,
157 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
159 ;; mov : ISA has no MOVW movw : ISA has MOVW
160 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
161 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
162 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
163 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
166 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx,
168 (const_string "standard"))
170 (define_attr "enabled" ""
171 (cond [(eq_attr "isa" "standard")
174 (and (eq_attr "isa" "mov")
175 (match_test "!AVR_HAVE_MOVW"))
178 (and (eq_attr "isa" "movw")
179 (match_test "AVR_HAVE_MOVW"))
182 (and (eq_attr "isa" "rjmp")
183 (match_test "!AVR_HAVE_JMP_CALL"))
186 (and (eq_attr "isa" "jmp")
187 (match_test "AVR_HAVE_JMP_CALL"))
190 (and (eq_attr "isa" "ijmp")
191 (match_test "!AVR_HAVE_EIJMP_EICALL"))
194 (and (eq_attr "isa" "eijmp")
195 (match_test "AVR_HAVE_EIJMP_EICALL"))
198 (and (eq_attr "isa" "lpm")
199 (match_test "!AVR_HAVE_LPMX"))
202 (and (eq_attr "isa" "lpmx")
203 (match_test "AVR_HAVE_LPMX"))
206 (and (eq_attr "isa" "elpm")
207 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
210 (and (eq_attr "isa" "elpmx")
211 (match_test "AVR_HAVE_ELPMX"))
216 ;; Define mode iterators
217 (define_mode_iterator QIHI [(QI "") (HI "")])
218 (define_mode_iterator QIHI2 [(QI "") (HI "")])
219 (define_mode_iterator QISI [(QI "") (HI "") (PSI "") (SI "")])
220 (define_mode_iterator QIDI [(QI "") (HI "") (PSI "") (SI "") (DI "")])
221 (define_mode_iterator HISI [(HI "") (PSI "") (SI "")])
223 ;; All supported move-modes
224 (define_mode_iterator MOVMODE [(QI "") (HI "") (SI "") (SF "") (PSI "")])
226 ;; Define code iterators
227 ;; Define two incarnations so that we can build the cross product.
228 (define_code_iterator any_extend [sign_extend zero_extend])
229 (define_code_iterator any_extend2 [sign_extend zero_extend])
231 ;; Define code attributes
232 (define_code_attr extend_su
236 (define_code_attr extend_u
240 (define_code_attr extend_s
244 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
245 (define_code_attr mul_r_d
249 ;; Map RTX code to its standard insn name
250 (define_code_attr code_stdname
256 ;;========================================================================
257 ;; The following is used by nonlocal_goto and setjmp.
258 ;; The receiver pattern will create no instructions since internally
259 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
260 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
261 ;; The 'null' receiver also avoids problems with optimisation
262 ;; not recognising incoming jmp and removing code that resets frame_pointer.
263 ;; The code derived from builtins.c.
265 (define_expand "nonlocal_goto_receiver"
267 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
270 emit_move_insn (virtual_stack_vars_rtx,
271 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
272 gen_int_mode (STARTING_FRAME_OFFSET,
274 /* This might change the hard frame pointer in ways that aren't
275 apparent to early optimization passes, so force a clobber. */
276 emit_clobber (hard_frame_pointer_rtx);
281 ;; Defining nonlocal_goto_receiver means we must also define this.
282 ;; even though its function is identical to that in builtins.c
284 (define_expand "nonlocal_goto"
285 [(use (match_operand 0 "general_operand"))
286 (use (match_operand 1 "general_operand"))
287 (use (match_operand 2 "general_operand"))
288 (use (match_operand 3 "general_operand"))]
291 rtx r_label = copy_to_reg (operands[1]);
292 rtx r_fp = operands[3];
293 rtx r_sp = operands[2];
295 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
297 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
299 emit_move_insn (hard_frame_pointer_rtx, r_fp);
300 emit_stack_restore (SAVE_NONLOCAL, r_sp);
302 emit_use (hard_frame_pointer_rtx);
303 emit_use (stack_pointer_rtx);
305 emit_indirect_jump (r_label);
310 (define_insn "pushqi1"
311 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
312 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
317 [(set_attr "length" "1,1")])
319 ;; All modes for a multi-byte push. We must include complex modes here too,
320 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
321 (define_mode_iterator MPUSH
329 (define_expand "push<mode>1"
330 [(match_operand:MPUSH 0 "" "")]
334 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
336 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
337 if (part != const0_rtx)
338 part = force_reg (QImode, part);
339 emit_insn (gen_pushqi1 (part));
344 ;; Notice a special-case when adding N to SP where N results in a
345 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
347 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
349 && frame_pointer_needed
350 && !cfun->calls_alloca
351 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
352 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
355 ;;========================================================================
358 (define_expand "load<mode>_libgcc"
361 (set (reg:MOVMODE 22)
362 (match_operand:MOVMODE 1 "memory_operand" ""))
363 (set (match_operand:MOVMODE 0 "register_operand" "")
365 "avr_load_libgcc_p (operands[1])"
367 operands[3] = gen_rtx_REG (HImode, REG_Z);
368 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
369 operands[1] = replace_equiv_address (operands[1], operands[3]);
370 set_mem_addr_space (operands[1], ADDR_SPACE_PGM);
373 (define_insn "load_<mode>_libgcc"
374 [(set (reg:MOVMODE 22)
375 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
376 "avr_load_libgcc_p (operands[0])
377 && REG_P (XEXP (operands[0], 0))
378 && REG_Z == REGNO (XEXP (operands[0], 0))"
380 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
381 return "%~call __load_%0";
383 [(set_attr "length" "1,2")
384 (set_attr "isa" "rjmp,jmp")
385 (set_attr "cc" "clobber")])
388 (define_insn_and_split "xload8_A"
389 [(set (match_operand:QI 0 "register_operand" "=r")
390 (match_operand:QI 1 "memory_operand" "m"))
391 (clobber (reg:HI REG_Z))]
392 "can_create_pseudo_p()
393 && avr_mem_pgmx_p (operands[1])
394 && REG_P (XEXP (operands[1], 0))"
395 { gcc_unreachable(); }
397 [(clobber (const_int 0))]
399 rtx insn, addr = XEXP (operands[1], 0);
400 rtx hi8 = gen_reg_rtx (QImode);
401 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
403 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
404 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
406 insn = emit_insn (gen_xload_8 (operands[0], hi8));
407 set_mem_addr_space (SET_SRC (single_set (insn)),
408 MEM_ADDR_SPACE (operands[1]));
412 (define_insn_and_split "xload<mode>_A"
413 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
414 (match_operand:MOVMODE 1 "memory_operand" "m"))
415 (clobber (reg:QI 21))
416 (clobber (reg:HI REG_Z))]
417 "QImode != <MODE>mode
418 && can_create_pseudo_p()
419 && avr_mem_pgmx_p (operands[1])
420 && REG_P (XEXP (operands[1], 0))"
421 { gcc_unreachable(); }
423 [(clobber (const_int 0))]
425 rtx addr = XEXP (operands[1], 0);
426 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
427 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
428 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
431 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
433 if (avr_xload_libgcc_p (<MODE>mode))
435 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
436 insn = emit_insn (gen_xload_<mode>_libgcc ());
437 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
439 else if (avr_current_arch->n_segments == 1
440 && GET_MODE_SIZE (<MODE>mode) > 2
443 rtx src = gen_rtx_MEM (<MODE>mode, reg_z);
446 insn = emit_insn (gen_load_<mode>_libgcc (src));
447 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
451 hi8 = gen_reg_rtx (QImode);
452 emit_move_insn (hi8, addr_hi8);
453 insn = emit_insn (gen_xload_<mode> (operands[0], hi8));
456 set_mem_addr_space (SET_SRC (single_set (insn)), as);
461 ;; Move value from address space pgmx to a register
462 ;; These insns must be prior to respective generic move insn.
464 (define_insn "xload_8"
465 [(set (match_operand:QI 0 "register_operand" "=r")
466 (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r")
470 return avr_out_xload (insn, operands, NULL);
472 [(set_attr "adjust_len" "xload")
473 (set_attr "cc" "clobber")])
476 ;; "xload_psi_libgcc"
479 (define_insn "xload_<mode>_libgcc"
480 [(set (reg:MOVMODE 22)
481 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
483 (clobber (reg:QI 21))
484 (clobber (reg:HI REG_Z))]
485 "<MODE>mode != QImode
486 && avr_xload_libgcc_p (<MODE>mode)"
488 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
490 /* Devices with ELPM* also have CALL. */
492 output_asm_insn ("call __xload_%0", &x_bytes);
495 [(set_attr "length" "2")
496 (set_attr "cc" "clobber")])
502 (define_insn "xload_<mode>"
503 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
504 (mem:MOVMODE (lo_sum:PSI (match_operand:QI 1 "register_operand" "r")
506 (clobber (scratch:HI))
507 (clobber (reg:HI REG_Z))]
508 "<MODE>mode != QImode
509 && !avr_xload_libgcc_p (<MODE>mode)"
511 return avr_out_xload (insn, operands, NULL);
513 [(set_attr "adjust_len" "xload")
514 (set_attr "cc" "clobber")])
517 ;; General move expanders
525 (define_expand "mov<mode>"
526 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
527 (match_operand:MOVMODE 1 "general_operand" ""))]
530 rtx dest = operands[0];
531 rtx src = operands[1];
533 if (avr_mem_pgm_p (dest))
536 /* One of the operands has to be in a register. */
537 if (!register_operand (dest, <MODE>mode)
538 && !(register_operand (src, <MODE>mode)
539 || src == CONST0_RTX (<MODE>mode)))
541 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
544 if (avr_mem_pgmx_p (src))
546 rtx addr = XEXP (src, 0);
549 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
551 if (QImode == <MODE>mode)
552 emit_insn (gen_xload8_A (dest, src));
554 emit_insn (gen_xload<mode>_A (dest, src));
559 if (avr_load_libgcc_p (src))
561 /* For the small devices, do loads per libgcc call. */
562 emit_insn (gen_load<mode>_libgcc (dest, src));
567 ;;========================================================================
569 ;; The last alternative (any immediate constant to any register) is
570 ;; very expensive. It should be optimized by peephole2 if a scratch
571 ;; register is available, but then that register could just as well be
572 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
573 ;; are call-saved registers, and most of LD_REGS are call-used registers,
574 ;; so this may still be a win for registers live across function calls.
576 (define_insn "movqi_insn"
577 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
578 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
579 "register_operand (operands[0], QImode)
580 || register_operand (operands[1], QImode)
581 || const0_rtx == operands[1]"
583 return output_movqi (insn, operands, NULL);
585 [(set_attr "length" "1,1,5,5,1,1,4")
586 (set_attr "adjust_len" "mov8")
587 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
589 ;; This is used in peephole2 to optimize loading immediate constants
590 ;; if a scratch register from LD_REGS happens to be available.
592 (define_insn "*reload_inqi"
593 [(set (match_operand:QI 0 "register_operand" "=l")
594 (match_operand:QI 1 "immediate_operand" "i"))
595 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
599 [(set_attr "length" "2")
600 (set_attr "cc" "none")])
603 [(match_scratch:QI 2 "d")
604 (set (match_operand:QI 0 "l_register_operand" "")
605 (match_operand:QI 1 "immediate_operand" ""))]
606 "(operands[1] != const0_rtx
607 && operands[1] != const1_rtx
608 && operands[1] != constm1_rtx)"
609 [(parallel [(set (match_dup 0) (match_dup 1))
610 (clobber (match_dup 2))])]
613 ;;============================================================================
614 ;; move word (16 bit)
616 ;; Move register $1 to the Stack Pointer register SP.
617 ;; This insn is emit during function prologue/epilogue generation.
618 ;; $2 = 0: We know that IRQs are off
619 ;; $2 = 1: We know that IRQs are on
620 ;; Remaining cases when the state of the I-Flag is unknown are
621 ;; handled by generic movhi insn.
623 (define_insn "movhi_sp_r"
624 [(set (match_operand:HI 0 "stack_register_operand" "=q,q")
625 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r")
626 (match_operand:HI 2 "const_int_operand" "L,P")]
630 out __SP_H__,%B1\;out __SP_L__,%A1
631 cli\;out __SP_H__,%B1\;sei\;out __SP_L__,%A1"
632 [(set_attr "length" "2,4")
633 (set_attr "cc" "none")])
636 [(match_scratch:QI 2 "d")
637 (set (match_operand:HI 0 "l_register_operand" "")
638 (match_operand:HI 1 "immediate_operand" ""))]
639 "(operands[1] != const0_rtx
640 && operands[1] != constm1_rtx)"
641 [(parallel [(set (match_dup 0) (match_dup 1))
642 (clobber (match_dup 2))])]
645 ;; '*' because it is not used in rtl generation, only in above peephole
646 (define_insn "*reload_inhi"
647 [(set (match_operand:HI 0 "register_operand" "=r")
648 (match_operand:HI 1 "immediate_operand" "i"))
649 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
652 return output_reload_inhi (operands, operands[2], NULL);
654 [(set_attr "length" "4")
655 (set_attr "adjust_len" "reload_in16")
656 (set_attr "cc" "none")])
658 (define_insn "*movhi"
659 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
660 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
661 "register_operand (operands[0], HImode)
662 || register_operand (operands[1], HImode)
663 || const0_rtx == operands[1]"
665 return output_movhi (insn, operands, NULL);
667 [(set_attr "length" "2,2,6,7,2,6,5,2")
668 (set_attr "adjust_len" "mov16")
669 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
671 (define_peephole2 ; movw
672 [(set (match_operand:QI 0 "even_register_operand" "")
673 (match_operand:QI 1 "even_register_operand" ""))
674 (set (match_operand:QI 2 "odd_register_operand" "")
675 (match_operand:QI 3 "odd_register_operand" ""))]
677 && REGNO (operands[0]) == REGNO (operands[2]) - 1
678 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
679 [(set (match_dup 4) (match_dup 5))]
681 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
682 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
685 (define_peephole2 ; movw_r
686 [(set (match_operand:QI 0 "odd_register_operand" "")
687 (match_operand:QI 1 "odd_register_operand" ""))
688 (set (match_operand:QI 2 "even_register_operand" "")
689 (match_operand:QI 3 "even_register_operand" ""))]
691 && REGNO (operands[2]) == REGNO (operands[0]) - 1
692 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
693 [(set (match_dup 4) (match_dup 5))]
695 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
696 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
699 ;; For LPM loads from AS1 we split
703 ;; Z = Z - sizeof (R)
705 ;; so that the second instruction can be optimized out.
707 (define_split ; "split-lpmx"
708 [(set (match_operand:HISI 0 "register_operand" "")
709 (match_operand:HISI 1 "memory_operand" ""))]
715 (plus:HI (match_dup 3)
718 rtx addr = XEXP (operands[1], 0);
720 if (!avr_mem_pgm_p (operands[1])
722 || reg_overlap_mentioned_p (addr, operands[0]))
727 operands[2] = replace_equiv_address (operands[1],
728 gen_rtx_POST_INC (Pmode, addr));
730 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
733 ;;==========================================================================
734 ;; xpointer move (24 bit)
736 (define_peephole2 ; *reload_inpsi
737 [(match_scratch:QI 2 "d")
738 (set (match_operand:PSI 0 "l_register_operand" "")
739 (match_operand:PSI 1 "immediate_operand" ""))
741 "operands[1] != const0_rtx
742 && operands[1] != constm1_rtx"
743 [(parallel [(set (match_dup 0)
745 (clobber (match_dup 2))])]
748 ;; '*' because it is not used in rtl generation.
749 (define_insn "*reload_inpsi"
750 [(set (match_operand:PSI 0 "register_operand" "=r")
751 (match_operand:PSI 1 "immediate_operand" "i"))
752 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
755 return avr_out_reload_inpsi (operands, operands[2], NULL);
757 [(set_attr "length" "6")
758 (set_attr "adjust_len" "reload_in24")
759 (set_attr "cc" "clobber")])
761 (define_insn "*movpsi"
762 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
763 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
764 "register_operand (operands[0], PSImode)
765 || register_operand (operands[1], PSImode)
766 || const0_rtx == operands[1]"
768 return avr_out_movpsi (insn, operands, NULL);
770 [(set_attr "length" "3,3,8,9,4,10")
771 (set_attr "adjust_len" "mov24")
772 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
774 ;;==========================================================================
775 ;; move double word (32 bit)
777 (define_peephole2 ; *reload_insi
778 [(match_scratch:QI 2 "d")
779 (set (match_operand:SI 0 "l_register_operand" "")
780 (match_operand:SI 1 "const_int_operand" ""))
782 "(operands[1] != const0_rtx
783 && operands[1] != constm1_rtx)"
784 [(parallel [(set (match_dup 0) (match_dup 1))
785 (clobber (match_dup 2))])]
788 ;; '*' because it is not used in rtl generation.
789 (define_insn "*reload_insi"
790 [(set (match_operand:SI 0 "register_operand" "=r")
791 (match_operand:SI 1 "const_int_operand" "n"))
792 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
795 return output_reload_insisf (operands, operands[2], NULL);
797 [(set_attr "length" "8")
798 (set_attr "adjust_len" "reload_in32")
799 (set_attr "cc" "clobber")])
802 (define_insn "*movsi"
803 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
804 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
805 "register_operand (operands[0], SImode)
806 || register_operand (operands[1], SImode)
807 || const0_rtx == operands[1]"
809 return output_movsisf (insn, operands, NULL);
811 [(set_attr "length" "4,4,8,9,4,10")
812 (set_attr "adjust_len" "mov32")
813 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
815 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
816 ;; move floating point numbers (32 bit)
818 (define_insn "*movsf"
819 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
820 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
821 "register_operand (operands[0], SFmode)
822 || register_operand (operands[1], SFmode)
823 || operands[1] == CONST0_RTX (SFmode)"
825 return output_movsisf (insn, operands, NULL);
827 [(set_attr "length" "4,4,8,9,4,10")
828 (set_attr "adjust_len" "mov32")
829 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
831 (define_peephole2 ; *reload_insf
832 [(match_scratch:QI 2 "d")
833 (set (match_operand:SF 0 "l_register_operand" "")
834 (match_operand:SF 1 "const_double_operand" ""))
836 "operands[1] != CONST0_RTX (SFmode)"
837 [(parallel [(set (match_dup 0)
839 (clobber (match_dup 2))])]
842 ;; '*' because it is not used in rtl generation.
843 (define_insn "*reload_insf"
844 [(set (match_operand:SF 0 "register_operand" "=r")
845 (match_operand:SF 1 "const_double_operand" "F"))
846 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
849 return output_reload_insisf (operands, operands[2], NULL);
851 [(set_attr "length" "8")
852 (set_attr "adjust_len" "reload_in32")
853 (set_attr "cc" "clobber")])
855 ;;=========================================================================
856 ;; move string (like memcpy)
858 (define_expand "movmemhi"
859 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
860 (match_operand:BLK 1 "memory_operand" ""))
861 (use (match_operand:HI 2 "const_int_operand" ""))
862 (use (match_operand:HI 3 "const_int_operand" ""))])]
865 if (avr_emit_movmemhi (operands))
871 (define_mode_attr MOVMEM_r_d [(QI "r")
876 ;; $2 : Address Space
877 ;; $3, $7 : Loop register
878 ;; $6 : Scratch register
882 (define_insn "movmem_<mode>"
883 [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
884 (mem:BLK (match_operand:HI 1 "register_operand" "z")))
885 (unspec [(match_operand:QI 2 "const_int_operand" "LP")]
887 (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>"))
888 (clobber (match_operand:HI 4 "register_operand" "=0"))
889 (clobber (match_operand:HI 5 "register_operand" "=1"))
890 (clobber (match_operand:QI 6 "register_operand" "=&r"))
891 (clobber (match_operand:QIHI 7 "register_operand" "=3"))]
894 return avr_out_movmem (insn, operands, NULL);
896 [(set_attr "adjust_len" "movmem")
897 (set_attr "cc" "clobber")])
900 ;; $8, $9 : hh8 (& src)
905 (define_insn "movmem_<mode>_elpm"
906 [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
907 (mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r")
908 (match_operand:HI 1 "register_operand" "z"))))
909 (unspec [(match_operand:QI 2 "const_int_operand" "n")]
911 (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>"))
912 (clobber (match_operand:HI 4 "register_operand" "=0"))
913 (clobber (match_operand:HI 5 "register_operand" "=1"))
914 (clobber (match_operand:QI 6 "register_operand" "=&r"))
915 (clobber (match_operand:QIHI 7 "register_operand" "=3"))
916 (clobber (match_operand:QI 9 "register_operand" "=8"))
917 (clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))]
920 return avr_out_movmem (insn, operands, NULL);
922 [(set_attr "adjust_len" "movmem")
923 (set_attr "cc" "clobber")])
926 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
927 ;; memset (%0, %2, %1)
929 (define_expand "setmemhi"
930 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
931 (match_operand 2 "const_int_operand" ""))
932 (use (match_operand:HI 1 "const_int_operand" ""))
933 (use (match_operand:HI 3 "const_int_operand" ""))
934 (clobber (match_scratch:HI 4 ""))
935 (clobber (match_dup 5))])]
939 enum machine_mode mode;
941 /* If value to set is not zero, use the library routine. */
942 if (operands[2] != const0_rtx)
945 if (!CONST_INT_P (operands[1]))
948 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
949 operands[5] = gen_rtx_SCRATCH (mode);
950 operands[1] = copy_to_mode_reg (mode,
951 gen_int_mode (INTVAL (operands[1]), mode));
952 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
953 operands[0] = gen_rtx_MEM (BLKmode, addr0);
957 (define_insn "*clrmemqi"
958 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
960 (use (match_operand:QI 1 "register_operand" "r"))
961 (use (match_operand:QI 2 "const_int_operand" "n"))
962 (clobber (match_scratch:HI 3 "=0"))
963 (clobber (match_scratch:QI 4 "=&1"))]
965 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
966 [(set_attr "length" "3")
967 (set_attr "cc" "clobber")])
970 (define_insn "*clrmemhi"
971 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
973 (use (match_operand:HI 1 "register_operand" "!w,d"))
974 (use (match_operand:HI 2 "const_int_operand" "n,n"))
975 (clobber (match_scratch:HI 3 "=0,0"))
976 (clobber (match_scratch:HI 4 "=&1,&1"))]
979 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
980 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
981 [(set_attr "length" "3,4")
982 (set_attr "cc" "clobber,clobber")])
984 (define_expand "strlenhi"
986 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
987 (match_operand:QI 2 "const_int_operand" "")
988 (match_operand:HI 3 "immediate_operand" "")]
991 (plus:HI (match_dup 4)
993 (set (match_operand:HI 0 "register_operand" "")
994 (minus:HI (match_dup 4)
999 if (operands[2] != const0_rtx)
1001 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1002 operands[1] = gen_rtx_MEM (BLKmode, addr);
1004 operands[4] = gen_reg_rtx (HImode);
1007 (define_insn "*strlenhi"
1008 [(set (match_operand:HI 0 "register_operand" "=e")
1009 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1011 (match_operand:HI 2 "immediate_operand" "i")]
1014 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1015 [(set_attr "length" "3")
1016 (set_attr "cc" "clobber")])
1018 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1021 (define_insn "addqi3"
1022 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
1023 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
1024 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
1033 [(set_attr "length" "1,1,1,1,2,2")
1034 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1037 (define_expand "addhi3"
1038 [(set (match_operand:HI 0 "register_operand" "")
1039 (plus:HI (match_operand:HI 1 "register_operand" "")
1040 (match_operand:HI 2 "nonmemory_operand" "")))]
1043 if (CONST_INT_P (operands[2]))
1045 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1047 if (can_create_pseudo_p()
1048 && !stack_register_operand (operands[0], HImode)
1049 && !stack_register_operand (operands[1], HImode)
1050 && !d_register_operand (operands[0], HImode)
1051 && !d_register_operand (operands[1], HImode))
1053 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1060 (define_insn "*addhi3_zero_extend"
1061 [(set (match_operand:HI 0 "register_operand" "=r")
1062 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1063 (match_operand:HI 2 "register_operand" "0")))]
1065 "add %A0,%1\;adc %B0,__zero_reg__"
1066 [(set_attr "length" "2")
1067 (set_attr "cc" "set_n")])
1069 (define_insn "*addhi3_zero_extend1"
1070 [(set (match_operand:HI 0 "register_operand" "=r")
1071 (plus:HI (match_operand:HI 1 "register_operand" "0")
1072 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1074 "add %A0,%2\;adc %B0,__zero_reg__"
1075 [(set_attr "length" "2")
1076 (set_attr "cc" "set_n")])
1078 (define_insn "*addhi3.sign_extend1"
1079 [(set (match_operand:HI 0 "register_operand" "=r")
1080 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1081 (match_operand:HI 2 "register_operand" "0")))]
1084 return reg_overlap_mentioned_p (operands[0], operands[1])
1085 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1086 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1088 [(set_attr "length" "5")
1089 (set_attr "cc" "clobber")])
1091 (define_insn "*addhi3_sp"
1092 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1093 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1094 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1097 return avr_out_addto_sp (operands, NULL);
1099 [(set_attr "length" "6")
1100 (set_attr "adjust_len" "addto_sp")])
1102 (define_insn "*addhi3"
1103 [(set (match_operand:HI 0 "register_operand" "=r,d,d")
1104 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1105 (match_operand:HI 2 "nonmemory_operand" "r,s,n")))]
1108 static const char * const asm_code[] =
1110 "add %A0,%A2\;adc %B0,%B2",
1111 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
1115 if (*asm_code[which_alternative])
1116 return asm_code[which_alternative];
1118 return avr_out_plus_noclobber (operands, NULL, NULL);
1120 [(set_attr "length" "2,2,2")
1121 (set_attr "adjust_len" "*,*,out_plus_noclobber")
1122 (set_attr "cc" "set_n,set_czn,out_plus_noclobber")])
1124 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1125 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1126 ;; itself because that insn is special to reload.
1128 (define_peephole2 ; addhi3_clobber
1129 [(set (match_operand:HI 0 "d_register_operand" "")
1130 (match_operand:HI 1 "const_int_operand" ""))
1131 (set (match_operand:HI 2 "l_register_operand" "")
1132 (plus:HI (match_dup 2)
1134 "peep2_reg_dead_p (2, operands[0])"
1135 [(parallel [(set (match_dup 2)
1136 (plus:HI (match_dup 2)
1138 (clobber (match_dup 3))])]
1140 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
1143 ;; Same, but with reload to NO_LD_REGS
1144 ;; Combine *reload_inhi with *addhi3
1146 (define_peephole2 ; addhi3_clobber
1147 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
1148 (match_operand:HI 1 "const_int_operand" ""))
1149 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1150 (set (match_operand:HI 3 "l_register_operand" "")
1151 (plus:HI (match_dup 3)
1153 "peep2_reg_dead_p (2, operands[0])"
1154 [(parallel [(set (match_dup 3)
1155 (plus:HI (match_dup 3)
1157 (clobber (match_dup 2))])])
1159 (define_insn "addhi3_clobber"
1160 [(set (match_operand:HI 0 "register_operand" "=d,l")
1161 (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
1162 (match_operand:HI 2 "const_int_operand" "n,n")))
1163 (clobber (match_scratch:QI 3 "=X,&d"))]
1166 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1168 return avr_out_plus (operands, NULL, NULL);
1170 [(set_attr "length" "4")
1171 (set_attr "adjust_len" "out_plus")
1172 (set_attr "cc" "out_plus")])
1175 (define_insn "addsi3"
1176 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1177 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1178 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1179 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1182 static const char * const asm_code[] =
1184 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
1185 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
1190 if (*asm_code[which_alternative])
1191 return asm_code [which_alternative];
1193 return avr_out_plus (operands, NULL, NULL);
1195 [(set_attr "length" "4,4,4,8")
1196 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1197 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1199 (define_insn "*addpsi3_zero_extend.qi"
1200 [(set (match_operand:PSI 0 "register_operand" "=r")
1201 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1202 (match_operand:PSI 2 "register_operand" "0")))]
1204 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1205 [(set_attr "length" "3")
1206 (set_attr "cc" "set_n")])
1208 (define_insn "*addpsi3_zero_extend.hi"
1209 [(set (match_operand:PSI 0 "register_operand" "=r")
1210 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1211 (match_operand:PSI 2 "register_operand" "0")))]
1213 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1214 [(set_attr "length" "3")
1215 (set_attr "cc" "set_n")])
1217 (define_insn "*addpsi3_sign_extend.hi"
1218 [(set (match_operand:PSI 0 "register_operand" "=r")
1219 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1220 (match_operand:PSI 2 "register_operand" "0")))]
1222 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1223 [(set_attr "length" "5")
1224 (set_attr "cc" "set_n")])
1226 (define_insn "*addsi3_zero_extend"
1227 [(set (match_operand:SI 0 "register_operand" "=r")
1228 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1229 (match_operand:SI 2 "register_operand" "0")))]
1231 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1232 [(set_attr "length" "4")
1233 (set_attr "cc" "set_n")])
1235 (define_insn "*addsi3_zero_extend.hi"
1236 [(set (match_operand:SI 0 "register_operand" "=r")
1237 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1238 (match_operand:SI 2 "register_operand" "0")))]
1240 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1241 [(set_attr "length" "4")
1242 (set_attr "cc" "set_n")])
1244 (define_insn "addpsi3"
1245 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1246 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1247 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1248 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1251 static const char * const asm_code[] =
1253 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1254 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1259 if (*asm_code[which_alternative])
1260 return asm_code [which_alternative];
1262 return avr_out_plus (operands, NULL, NULL);
1264 [(set_attr "length" "3,3,3,6")
1265 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1266 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1268 (define_insn "subpsi3"
1269 [(set (match_operand:PSI 0 "register_operand" "=r")
1270 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1271 (match_operand:PSI 2 "register_operand" "r")))]
1273 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1274 [(set_attr "length" "3")
1275 (set_attr "cc" "set_czn")])
1277 (define_insn "*subpsi3_zero_extend.qi"
1278 [(set (match_operand:PSI 0 "register_operand" "=r")
1279 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1280 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1282 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1283 [(set_attr "length" "3")
1284 (set_attr "cc" "set_czn")])
1286 (define_insn "*subpsi3_zero_extend.hi"
1287 [(set (match_operand:PSI 0 "register_operand" "=r")
1288 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1289 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1291 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1292 [(set_attr "length" "3")
1293 (set_attr "cc" "set_czn")])
1295 (define_insn "*subpsi3_sign_extend.hi"
1296 [(set (match_operand:PSI 0 "register_operand" "=r")
1297 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1298 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1300 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1301 [(set_attr "length" "5")
1302 (set_attr "cc" "set_czn")])
1304 ;-----------------------------------------------------------------------------
1306 (define_insn "subqi3"
1307 [(set (match_operand:QI 0 "register_operand" "=r,d")
1308 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1309 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1314 [(set_attr "length" "1,1")
1315 (set_attr "cc" "set_czn,set_czn")])
1317 (define_insn "subhi3"
1318 [(set (match_operand:HI 0 "register_operand" "=r,d")
1319 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1320 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1323 sub %A0,%A2\;sbc %B0,%B2
1324 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1325 [(set_attr "length" "2,2")
1326 (set_attr "cc" "set_czn,set_czn")])
1328 (define_insn "*subhi3_zero_extend1"
1329 [(set (match_operand:HI 0 "register_operand" "=r")
1330 (minus:HI (match_operand:HI 1 "register_operand" "0")
1331 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1333 "sub %A0,%2\;sbc %B0,__zero_reg__"
1334 [(set_attr "length" "2")
1335 (set_attr "cc" "set_czn")])
1337 (define_insn "*subhi3.sign_extend2"
1338 [(set (match_operand:HI 0 "register_operand" "=r")
1339 (minus:HI (match_operand:HI 1 "register_operand" "0")
1340 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1343 return reg_overlap_mentioned_p (operands[0], operands[2])
1344 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1345 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1347 [(set_attr "length" "5")
1348 (set_attr "cc" "clobber")])
1350 (define_insn "subsi3"
1351 [(set (match_operand:SI 0 "register_operand" "=r")
1352 (minus:SI (match_operand:SI 1 "register_operand" "0")
1353 (match_operand:SI 2 "register_operand" "r")))]
1355 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1356 [(set_attr "length" "4")
1357 (set_attr "cc" "set_czn")])
1359 (define_insn "*subsi3_zero_extend"
1360 [(set (match_operand:SI 0 "register_operand" "=r")
1361 (minus:SI (match_operand:SI 1 "register_operand" "0")
1362 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1364 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1365 [(set_attr "length" "4")
1366 (set_attr "cc" "set_czn")])
1368 (define_insn "*subsi3_zero_extend.hi"
1369 [(set (match_operand:SI 0 "register_operand" "=r")
1370 (minus:SI (match_operand:SI 1 "register_operand" "0")
1371 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1373 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1374 [(set_attr "length" "4")
1375 (set_attr "cc" "set_czn")])
1377 ;******************************************************************************
1380 (define_expand "mulqi3"
1381 [(set (match_operand:QI 0 "register_operand" "")
1382 (mult:QI (match_operand:QI 1 "register_operand" "")
1383 (match_operand:QI 2 "register_operand" "")))]
1388 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1393 (define_insn "*mulqi3_enh"
1394 [(set (match_operand:QI 0 "register_operand" "=r")
1395 (mult:QI (match_operand:QI 1 "register_operand" "r")
1396 (match_operand:QI 2 "register_operand" "r")))]
1401 [(set_attr "length" "3")
1402 (set_attr "cc" "clobber")])
1404 (define_expand "mulqi3_call"
1405 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1406 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1407 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1408 (clobber (reg:QI 22))])
1409 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1413 (define_insn "*mulqi3_call"
1414 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1415 (clobber (reg:QI 22))]
1418 [(set_attr "type" "xcall")
1419 (set_attr "cc" "clobber")])
1421 ;; "umulqi3_highpart"
1422 ;; "smulqi3_highpart"
1423 (define_insn "<extend_su>mulqi3_highpart"
1424 [(set (match_operand:QI 0 "register_operand" "=r")
1426 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1427 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1430 "mul<extend_s> %1,%2
1433 [(set_attr "length" "3")
1434 (set_attr "cc" "clobber")])
1437 ;; Used when expanding div or mod inline for some special values
1438 (define_insn "*subqi3.ashiftrt7"
1439 [(set (match_operand:QI 0 "register_operand" "=r")
1440 (minus:QI (match_operand:QI 1 "register_operand" "0")
1441 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1445 [(set_attr "length" "2")
1446 (set_attr "cc" "clobber")])
1448 (define_insn "*addqi3.lt0"
1449 [(set (match_operand:QI 0 "register_operand" "=r")
1450 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1452 (match_operand:QI 2 "register_operand" "0")))]
1455 [(set_attr "length" "2")
1456 (set_attr "cc" "clobber")])
1458 (define_insn "*addhi3.lt0"
1459 [(set (match_operand:HI 0 "register_operand" "=w,r")
1460 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1462 (match_operand:HI 2 "register_operand" "0,0")))
1463 (clobber (match_scratch:QI 3 "=X,&1"))]
1466 sbrc %1,7\;adiw %0,1
1467 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1468 [(set_attr "length" "2,3")
1469 (set_attr "cc" "clobber")])
1471 (define_insn "*addpsi3.lt0"
1472 [(set (match_operand:PSI 0 "register_operand" "=r")
1473 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1475 (match_operand:PSI 2 "register_operand" "0")))]
1477 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1478 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1479 [(set_attr "length" "5")
1480 (set_attr "cc" "clobber")])
1482 (define_insn "*addsi3.lt0"
1483 [(set (match_operand:SI 0 "register_operand" "=r")
1484 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1486 (match_operand:SI 2 "register_operand" "0")))]
1488 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1489 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1490 [(set_attr "length" "6")
1491 (set_attr "cc" "clobber")])
1496 (define_insn "<extend_u>mulqihi3"
1497 [(set (match_operand:HI 0 "register_operand" "=r")
1498 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1499 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1501 "mul<extend_s> %1,%2
1504 [(set_attr "length" "3")
1505 (set_attr "cc" "clobber")])
1507 (define_insn "usmulqihi3"
1508 [(set (match_operand:HI 0 "register_operand" "=r")
1509 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1510 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1515 [(set_attr "length" "3")
1516 (set_attr "cc" "clobber")])
1518 ;; Above insn is not canonicalized by insn combine, so here is a version with
1519 ;; operands swapped.
1521 (define_insn "*sumulqihi3"
1522 [(set (match_operand:HI 0 "register_operand" "=r")
1523 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1524 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1529 [(set_attr "length" "3")
1530 (set_attr "cc" "clobber")])
1532 ;; One-extend operand 1
1534 (define_insn "*osmulqihi3"
1535 [(set (match_operand:HI 0 "register_operand" "=&r")
1536 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1537 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1543 [(set_attr "length" "4")
1544 (set_attr "cc" "clobber")])
1546 (define_insn "*oumulqihi3"
1547 [(set (match_operand:HI 0 "register_operand" "=&r")
1548 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1549 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1555 [(set_attr "length" "4")
1556 (set_attr "cc" "clobber")])
1558 ;******************************************************************************
1559 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1560 ;******************************************************************************
1562 (define_insn "*maddqi4"
1563 [(set (match_operand:QI 0 "register_operand" "=r")
1564 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1565 (match_operand:QI 2 "register_operand" "r"))
1566 (match_operand:QI 3 "register_operand" "0")))]
1572 [(set_attr "length" "4")
1573 (set_attr "cc" "clobber")])
1575 (define_insn "*msubqi4"
1576 [(set (match_operand:QI 0 "register_operand" "=r")
1577 (minus:QI (match_operand:QI 3 "register_operand" "0")
1578 (mult:QI (match_operand:QI 1 "register_operand" "r")
1579 (match_operand:QI 2 "register_operand" "r"))))]
1584 [(set_attr "length" "4")
1585 (set_attr "cc" "clobber")])
1587 (define_insn_and_split "*maddqi4.const"
1588 [(set (match_operand:QI 0 "register_operand" "=r")
1589 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1590 (match_operand:QI 2 "const_int_operand" "n"))
1591 (match_operand:QI 3 "register_operand" "0")))
1592 (clobber (match_scratch:QI 4 "=&d"))]
1595 "&& reload_completed"
1600 (plus:QI (mult:QI (match_dup 1)
1605 (define_insn_and_split "*msubqi4.const"
1606 [(set (match_operand:QI 0 "register_operand" "=r")
1607 (minus:QI (match_operand:QI 3 "register_operand" "0")
1608 (mult:QI (match_operand:QI 1 "register_operand" "r")
1609 (match_operand:QI 2 "const_int_operand" "n"))))
1610 (clobber (match_scratch:QI 4 "=&d"))]
1613 "&& reload_completed"
1618 (minus:QI (match_dup 3)
1619 (mult:QI (match_dup 1)
1624 ;******************************************************************************
1625 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1626 ;******************************************************************************
1628 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1631 ;; int foo (unsigned char z)
1633 ;; extern int aInt[];
1634 ;; return aInt[3*z+2];
1637 ;; because the constant +4 then is added explicitely instead of consuming it
1638 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1639 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1640 ;; The implementational effort is the same so we are fine with that approach.
1645 (define_insn "*<extend_u>maddqihi4"
1646 [(set (match_operand:HI 0 "register_operand" "=r")
1647 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1648 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1649 (match_operand:HI 3 "register_operand" "0")))]
1652 "mul<extend_s> %1,%2
1656 [(set_attr "length" "4")
1657 (set_attr "cc" "clobber")])
1661 (define_insn "*<extend_u>msubqihi4"
1662 [(set (match_operand:HI 0 "register_operand" "=r")
1663 (minus:HI (match_operand:HI 3 "register_operand" "0")
1664 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1665 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1667 "mul<extend_s> %1,%2
1671 [(set_attr "length" "4")
1672 (set_attr "cc" "clobber")])
1676 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1677 [(set (match_operand:HI 0 "register_operand" "=r")
1678 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1679 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1680 (match_operand:HI 3 "register_operand" "0")))]
1683 && <any_extend:CODE> != <any_extend2:CODE>"
1685 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1686 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1688 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1690 [(set_attr "length" "4")
1691 (set_attr "cc" "clobber")])
1695 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1696 [(set (match_operand:HI 0 "register_operand" "=r")
1697 (minus:HI (match_operand:HI 3 "register_operand" "0")
1698 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1699 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1702 && <any_extend:CODE> != <any_extend2:CODE>"
1704 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1705 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1707 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1709 [(set_attr "length" "4")
1710 (set_attr "cc" "clobber")])
1712 ;; Handle small constants
1714 ;; "umaddqihi4.uconst"
1715 ;; "maddqihi4.sconst"
1716 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
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 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1720 (match_operand:HI 3 "register_operand" "0")))
1721 (clobber (match_scratch:QI 4 "=&d"))]
1724 "&& reload_completed"
1727 ; *umaddqihi4 resp. *maddqihi4
1729 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1730 (any_extend:HI (match_dup 4)))
1733 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1736 ;; "*umsubqihi4.uconst"
1737 ;; "*msubqihi4.sconst"
1738 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1739 [(set (match_operand:HI 0 "register_operand" "=r")
1740 (minus:HI (match_operand:HI 3 "register_operand" "0")
1741 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1742 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1743 (clobber (match_scratch:QI 4 "=&d"))]
1746 "&& reload_completed"
1749 ; *umsubqihi4 resp. *msubqihi4
1751 (minus:HI (match_dup 3)
1752 (mult:HI (any_extend:HI (match_dup 1))
1753 (any_extend:HI (match_dup 4)))))]
1755 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1758 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1759 ;; for MULT with power of 2 and skips trying MULT insn above.
1761 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1762 [(set (match_operand:HI 0 "register_operand" "=r")
1763 (minus:HI (match_operand:HI 3 "register_operand" "0")
1764 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1765 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1766 (clobber (match_scratch:QI 4 "=&d"))]
1769 "&& reload_completed"
1774 (minus:HI (match_dup 3)
1775 (mult:HI (zero_extend:HI (match_dup 1))
1776 (zero_extend:HI (match_dup 4)))))]
1778 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1781 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1782 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1783 ;; because this would require an extra pattern for just one value.
1785 (define_insn_and_split "*msubqihi4.sconst.ashift"
1786 [(set (match_operand:HI 0 "register_operand" "=r")
1787 (minus:HI (match_operand:HI 3 "register_operand" "0")
1788 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1789 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1790 (clobber (match_scratch:QI 4 "=&d"))]
1793 "&& reload_completed"
1798 (minus:HI (match_dup 3)
1799 (mult:HI (sign_extend:HI (match_dup 1))
1800 (sign_extend:HI (match_dup 4)))))]
1802 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1805 ;; For signed/unsigned combinations that require narrow constraint "a"
1806 ;; just provide a pattern if signed/unsigned combination is actually needed.
1808 (define_insn_and_split "*sumaddqihi4.uconst"
1809 [(set (match_operand:HI 0 "register_operand" "=r")
1810 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1811 (match_operand:HI 2 "u8_operand" "M"))
1812 (match_operand:HI 3 "register_operand" "0")))
1813 (clobber (match_scratch:QI 4 "=&a"))]
1815 && !s8_operand (operands[2], VOIDmode)"
1817 "&& reload_completed"
1822 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1823 (zero_extend:HI (match_dup 4)))
1826 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1829 (define_insn_and_split "*sumsubqihi4.uconst"
1830 [(set (match_operand:HI 0 "register_operand" "=r")
1831 (minus:HI (match_operand:HI 3 "register_operand" "0")
1832 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1833 (match_operand:HI 2 "u8_operand" "M"))))
1834 (clobber (match_scratch:QI 4 "=&a"))]
1836 && !s8_operand (operands[2], VOIDmode)"
1838 "&& reload_completed"
1843 (minus:HI (match_dup 3)
1844 (mult:HI (sign_extend:HI (match_dup 1))
1845 (zero_extend:HI (match_dup 4)))))]
1847 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1850 ;******************************************************************************
1851 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1852 ;******************************************************************************
1854 ;; "*muluqihi3.uconst"
1855 ;; "*mulsqihi3.sconst"
1856 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1857 [(set (match_operand:HI 0 "register_operand" "=r")
1858 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1859 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1860 (clobber (match_scratch:QI 3 "=&d"))]
1863 "&& reload_completed"
1866 ; umulqihi3 resp. mulqihi3
1868 (mult:HI (any_extend:HI (match_dup 1))
1869 (any_extend:HI (match_dup 3))))]
1871 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1874 (define_insn_and_split "*muluqihi3.sconst"
1875 [(set (match_operand:HI 0 "register_operand" "=r")
1876 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1877 (match_operand:HI 2 "s8_operand" "n")))
1878 (clobber (match_scratch:QI 3 "=&a"))]
1881 "&& reload_completed"
1886 (mult:HI (zero_extend:HI (match_dup 1))
1887 (sign_extend:HI (match_dup 3))))]
1889 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1892 (define_insn_and_split "*mulsqihi3.uconst"
1893 [(set (match_operand:HI 0 "register_operand" "=r")
1894 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1895 (match_operand:HI 2 "u8_operand" "M")))
1896 (clobber (match_scratch:QI 3 "=&a"))]
1899 "&& reload_completed"
1904 (mult:HI (zero_extend:HI (match_dup 3))
1905 (sign_extend:HI (match_dup 1))))]
1907 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1910 (define_insn_and_split "*mulsqihi3.oconst"
1911 [(set (match_operand:HI 0 "register_operand" "=&r")
1912 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1913 (match_operand:HI 2 "o8_operand" "n")))
1914 (clobber (match_scratch:QI 3 "=&a"))]
1917 "&& reload_completed"
1922 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1923 (sign_extend:HI (match_dup 1))))]
1925 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1928 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1929 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1930 ;; at that time. Fix that.
1932 (define_insn "*ashiftqihi2.signx.1"
1933 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1934 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1938 lsl %A0\;sbc %B0,%B0
1939 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1940 [(set_attr "length" "2,3")
1941 (set_attr "cc" "clobber")])
1943 (define_insn_and_split "*ashifthi3.signx.const"
1944 [(set (match_operand:HI 0 "register_operand" "=r")
1945 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1946 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1947 (clobber (match_scratch:QI 3 "=&d"))]
1950 "&& reload_completed"
1955 (mult:HI (sign_extend:HI (match_dup 1))
1956 (sign_extend:HI (match_dup 3))))]
1958 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1961 (define_insn_and_split "*ashifthi3.signx.const7"
1962 [(set (match_operand:HI 0 "register_operand" "=r")
1963 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1965 (clobber (match_scratch:QI 2 "=&a"))]
1968 "&& reload_completed"
1973 (mult:HI (zero_extend:HI (match_dup 2))
1974 (sign_extend:HI (match_dup 1))))]
1976 operands[3] = gen_int_mode (1 << 7, QImode);
1979 (define_insn_and_split "*ashifthi3.zerox.const"
1980 [(set (match_operand:HI 0 "register_operand" "=r")
1981 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1982 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1983 (clobber (match_scratch:QI 3 "=&d"))]
1986 "&& reload_completed"
1991 (mult:HI (zero_extend:HI (match_dup 1))
1992 (zero_extend:HI (match_dup 3))))]
1994 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1997 ;******************************************************************************
1998 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1999 ;******************************************************************************
2001 (define_insn "mulsqihi3"
2002 [(set (match_operand:HI 0 "register_operand" "=&r")
2003 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2004 (match_operand:HI 2 "register_operand" "a")))]
2011 [(set_attr "length" "5")
2012 (set_attr "cc" "clobber")])
2014 (define_insn "muluqihi3"
2015 [(set (match_operand:HI 0 "register_operand" "=&r")
2016 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2017 (match_operand:HI 2 "register_operand" "r")))]
2024 [(set_attr "length" "5")
2025 (set_attr "cc" "clobber")])
2027 ;; one-extend operand 1
2029 (define_insn "muloqihi3"
2030 [(set (match_operand:HI 0 "register_operand" "=&r")
2031 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2032 (match_operand:HI 2 "register_operand" "r")))]
2040 [(set_attr "length" "6")
2041 (set_attr "cc" "clobber")])
2043 ;******************************************************************************
2045 (define_expand "mulhi3"
2046 [(set (match_operand:HI 0 "register_operand" "")
2047 (mult:HI (match_operand:HI 1 "register_operand" "")
2048 (match_operand:HI 2 "register_or_s9_operand" "")))]
2053 if (!register_operand (operands[2], HImode))
2054 operands[2] = force_reg (HImode, operands[2]);
2056 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2060 /* For small constants we can do better by extending them on the fly.
2061 The constant can be loaded in one instruction and the widening
2062 multiplication is shorter. First try the unsigned variant because it
2063 allows constraint "d" instead of "a" for the signed version. */
2065 if (s9_operand (operands[2], HImode))
2067 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2069 if (u8_operand (operands[2], HImode))
2071 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2073 else if (s8_operand (operands[2], HImode))
2075 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2079 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2085 if (!register_operand (operands[2], HImode))
2086 operands[2] = force_reg (HImode, operands[2]);
2089 (define_insn "*mulhi3_enh"
2090 [(set (match_operand:HI 0 "register_operand" "=&r")
2091 (mult:HI (match_operand:HI 1 "register_operand" "r")
2092 (match_operand:HI 2 "register_operand" "r")))]
2095 return REGNO (operands[1]) == REGNO (operands[2])
2096 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2097 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2099 [(set_attr "length" "7")
2100 (set_attr "cc" "clobber")])
2102 (define_expand "mulhi3_call"
2103 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2104 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2105 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2106 (clobber (reg:HI 22))
2107 (clobber (reg:QI 21))])
2108 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2112 (define_insn "*mulhi3_call"
2113 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2114 (clobber (reg:HI 22))
2115 (clobber (reg:QI 21))]
2118 [(set_attr "type" "xcall")
2119 (set_attr "cc" "clobber")])
2121 ;; To support widening multiplication with constant we postpone
2122 ;; expanding to the implicit library call until post combine and
2123 ;; prior to register allocation. Clobber all hard registers that
2124 ;; might be used by the (widening) multiply until it is split and
2125 ;; it's final register footprint is worked out.
2127 (define_expand "mulsi3"
2128 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2129 (mult:SI (match_operand:SI 1 "register_operand" "")
2130 (match_operand:SI 2 "nonmemory_operand" "")))
2131 (clobber (reg:HI 26))
2132 (clobber (reg:DI 18))])]
2135 if (u16_operand (operands[2], SImode))
2137 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2138 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2142 if (o16_operand (operands[2], SImode))
2144 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2145 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2150 (define_insn_and_split "*mulsi3"
2151 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2152 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2153 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2154 (clobber (reg:HI 26))
2155 (clobber (reg:DI 18))]
2156 "AVR_HAVE_MUL && !reload_completed"
2157 { gcc_unreachable(); }
2163 (parallel [(set (reg:SI 22)
2164 (mult:SI (reg:SI 22)
2166 (clobber (reg:HI 26))])
2170 if (u16_operand (operands[2], SImode))
2172 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2173 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2177 if (o16_operand (operands[2], SImode))
2179 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2180 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2187 (define_insn_and_split "mulu<mode>si3"
2188 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2189 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2190 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2191 (clobber (reg:HI 26))
2192 (clobber (reg:DI 18))]
2193 "AVR_HAVE_MUL && !reload_completed"
2194 { gcc_unreachable(); }
2201 (mult:SI (zero_extend:SI (reg:HI 26))
2206 /* Do the QI -> HI extension explicitely before the multiplication. */
2207 /* Do the HI -> SI extension implicitely and after the multiplication. */
2209 if (QImode == <MODE>mode)
2210 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2212 if (u16_operand (operands[2], SImode))
2214 operands[1] = force_reg (HImode, operands[1]);
2215 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2216 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2223 (define_insn_and_split "muls<mode>si3"
2224 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2225 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2226 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2227 (clobber (reg:HI 26))
2228 (clobber (reg:DI 18))]
2229 "AVR_HAVE_MUL && !reload_completed"
2230 { gcc_unreachable(); }
2237 (mult:SI (sign_extend:SI (reg:HI 26))
2242 /* Do the QI -> HI extension explicitely before the multiplication. */
2243 /* Do the HI -> SI extension implicitely and after the multiplication. */
2245 if (QImode == <MODE>mode)
2246 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2248 if (u16_operand (operands[2], SImode)
2249 || s16_operand (operands[2], SImode))
2251 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2253 operands[1] = force_reg (HImode, operands[1]);
2255 if (u16_operand (operands[2], SImode))
2256 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2258 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2264 ;; One-extend operand 1
2266 (define_insn_and_split "mulohisi3"
2267 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2268 (mult:SI (not:SI (zero_extend:SI
2269 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2270 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2271 (clobber (reg:HI 26))
2272 (clobber (reg:DI 18))]
2273 "AVR_HAVE_MUL && !reload_completed"
2274 { gcc_unreachable(); }
2281 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2289 (define_expand "<extend_u>mulhisi3"
2290 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2291 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2292 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2293 (clobber (reg:HI 26))
2294 (clobber (reg:DI 18))])]
2298 (define_expand "usmulhisi3"
2299 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2300 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2301 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2302 (clobber (reg:HI 26))
2303 (clobber (reg:DI 18))])]
2307 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2308 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2309 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2310 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2311 (define_insn_and_split
2312 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2313 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2314 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2315 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2316 (clobber (reg:HI 26))
2317 (clobber (reg:DI 18))]
2318 "AVR_HAVE_MUL && !reload_completed"
2319 { gcc_unreachable(); }
2326 (mult:SI (match_dup 3)
2331 rtx xop1 = operands[1];
2332 rtx xop2 = operands[2];
2334 /* Do the QI -> HI extension explicitely before the multiplication. */
2335 /* Do the HI -> SI extension implicitely and after the multiplication. */
2337 if (QImode == <QIHI:MODE>mode)
2338 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2340 if (QImode == <QIHI2:MODE>mode)
2341 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2343 if (<any_extend:CODE> == <any_extend2:CODE>
2344 || <any_extend:CODE> == ZERO_EXTEND)
2348 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2349 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2353 /* <any_extend:CODE> = SIGN_EXTEND */
2354 /* <any_extend2:CODE> = ZERO_EXTEND */
2358 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2359 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2363 ;; "smulhi3_highpart"
2364 ;; "umulhi3_highpart"
2365 (define_expand "<extend_su>mulhi3_highpart"
2367 (match_operand:HI 1 "nonmemory_operand" ""))
2369 (match_operand:HI 2 "nonmemory_operand" ""))
2370 (parallel [(set (reg:HI 24)
2371 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2372 (any_extend:SI (reg:HI 26)))
2374 (clobber (reg:HI 22))])
2375 (set (match_operand:HI 0 "register_operand" "")
2381 (define_insn "*mulsi3_call"
2383 (mult:SI (reg:SI 22)
2385 (clobber (reg:HI 26))]
2388 [(set_attr "type" "xcall")
2389 (set_attr "cc" "clobber")])
2392 ;; "*umulhisi3_call"
2393 (define_insn "*<extend_u>mulhisi3_call"
2395 (mult:SI (any_extend:SI (reg:HI 18))
2396 (any_extend:SI (reg:HI 26))))]
2398 "%~call __<extend_u>mulhisi3"
2399 [(set_attr "type" "xcall")
2400 (set_attr "cc" "clobber")])
2402 ;; "*umulhi3_highpart_call"
2403 ;; "*smulhi3_highpart_call"
2404 (define_insn "*<extend_su>mulhi3_highpart_call"
2406 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2407 (any_extend:SI (reg:HI 26)))
2409 (clobber (reg:HI 22))]
2411 "%~call __<extend_u>mulhisi3"
2412 [(set_attr "type" "xcall")
2413 (set_attr "cc" "clobber")])
2415 (define_insn "*usmulhisi3_call"
2417 (mult:SI (zero_extend:SI (reg:HI 18))
2418 (sign_extend:SI (reg:HI 26))))]
2420 "%~call __usmulhisi3"
2421 [(set_attr "type" "xcall")
2422 (set_attr "cc" "clobber")])
2424 (define_insn "*mul<extend_su>hisi3_call"
2426 (mult:SI (any_extend:SI (reg:HI 26))
2429 "%~call __mul<extend_su>hisi3"
2430 [(set_attr "type" "xcall")
2431 (set_attr "cc" "clobber")])
2433 (define_insn "*mulohisi3_call"
2435 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2438 "%~call __mulohisi3"
2439 [(set_attr "type" "xcall")
2440 (set_attr "cc" "clobber")])
2442 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2445 ;; Generate lib1funcs.S calls ourselves, because:
2446 ;; - we know exactly which registers are clobbered (for QI and HI
2447 ;; modes, some of the call-used registers are preserved)
2448 ;; - we get both the quotient and the remainder at no extra cost
2449 ;; - we split the patterns only after the first CSE passes because
2450 ;; CSE has problems to operate on hard regs.
2452 (define_insn_and_split "divmodqi4"
2453 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2454 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2455 (match_operand:QI 2 "pseudo_register_operand" "")))
2456 (set (match_operand:QI 3 "pseudo_register_operand" "")
2457 (mod:QI (match_dup 1) (match_dup 2)))
2458 (clobber (reg:QI 22))
2459 (clobber (reg:QI 23))
2460 (clobber (reg:QI 24))
2461 (clobber (reg:QI 25))])]
2463 "this divmodqi4 pattern should have been splitted;"
2465 [(set (reg:QI 24) (match_dup 1))
2466 (set (reg:QI 22) (match_dup 2))
2467 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2468 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2469 (clobber (reg:QI 22))
2470 (clobber (reg:QI 23))])
2471 (set (match_dup 0) (reg:QI 24))
2472 (set (match_dup 3) (reg:QI 25))]
2475 (define_insn "*divmodqi4_call"
2476 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2477 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2478 (clobber (reg:QI 22))
2479 (clobber (reg:QI 23))]
2481 "%~call __divmodqi4"
2482 [(set_attr "type" "xcall")
2483 (set_attr "cc" "clobber")])
2485 (define_insn_and_split "udivmodqi4"
2486 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2487 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2488 (match_operand:QI 2 "pseudo_register_operand" "")))
2489 (set (match_operand:QI 3 "pseudo_register_operand" "")
2490 (umod:QI (match_dup 1) (match_dup 2)))
2491 (clobber (reg:QI 22))
2492 (clobber (reg:QI 23))
2493 (clobber (reg:QI 24))
2494 (clobber (reg:QI 25))])]
2496 "this udivmodqi4 pattern should have been splitted;"
2498 [(set (reg:QI 24) (match_dup 1))
2499 (set (reg:QI 22) (match_dup 2))
2500 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2501 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2502 (clobber (reg:QI 23))])
2503 (set (match_dup 0) (reg:QI 24))
2504 (set (match_dup 3) (reg:QI 25))]
2507 (define_insn "*udivmodqi4_call"
2508 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2509 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2510 (clobber (reg:QI 23))]
2512 "%~call __udivmodqi4"
2513 [(set_attr "type" "xcall")
2514 (set_attr "cc" "clobber")])
2516 (define_insn_and_split "divmodhi4"
2517 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2518 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2519 (match_operand:HI 2 "pseudo_register_operand" "")))
2520 (set (match_operand:HI 3 "pseudo_register_operand" "")
2521 (mod:HI (match_dup 1) (match_dup 2)))
2522 (clobber (reg:QI 21))
2523 (clobber (reg:HI 22))
2524 (clobber (reg:HI 24))
2525 (clobber (reg:HI 26))])]
2527 "this should have been splitted;"
2529 [(set (reg:HI 24) (match_dup 1))
2530 (set (reg:HI 22) (match_dup 2))
2531 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2532 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2533 (clobber (reg:HI 26))
2534 (clobber (reg:QI 21))])
2535 (set (match_dup 0) (reg:HI 22))
2536 (set (match_dup 3) (reg:HI 24))]
2539 (define_insn "*divmodhi4_call"
2540 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2541 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2542 (clobber (reg:HI 26))
2543 (clobber (reg:QI 21))]
2545 "%~call __divmodhi4"
2546 [(set_attr "type" "xcall")
2547 (set_attr "cc" "clobber")])
2549 (define_insn_and_split "udivmodhi4"
2550 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2551 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2552 (match_operand:HI 2 "pseudo_register_operand" "")))
2553 (set (match_operand:HI 3 "pseudo_register_operand" "")
2554 (umod:HI (match_dup 1) (match_dup 2)))
2555 (clobber (reg:QI 21))
2556 (clobber (reg:HI 22))
2557 (clobber (reg:HI 24))
2558 (clobber (reg:HI 26))])]
2560 "this udivmodhi4 pattern should have been splitted.;"
2562 [(set (reg:HI 24) (match_dup 1))
2563 (set (reg:HI 22) (match_dup 2))
2564 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2565 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2566 (clobber (reg:HI 26))
2567 (clobber (reg:QI 21))])
2568 (set (match_dup 0) (reg:HI 22))
2569 (set (match_dup 3) (reg:HI 24))]
2572 (define_insn "*udivmodhi4_call"
2573 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2574 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2575 (clobber (reg:HI 26))
2576 (clobber (reg:QI 21))]
2578 "%~call __udivmodhi4"
2579 [(set_attr "type" "xcall")
2580 (set_attr "cc" "clobber")])
2582 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2585 ;; To support widening multiplication with constant we postpone
2586 ;; expanding to the implicit library call until post combine and
2587 ;; prior to register allocation. Clobber all hard registers that
2588 ;; might be used by the (widening) multiply until it is split and
2589 ;; it's final register footprint is worked out.
2591 (define_expand "mulpsi3"
2592 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2593 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2594 (match_operand:PSI 2 "nonmemory_operand" "")))
2595 (clobber (reg:HI 26))
2596 (clobber (reg:DI 18))])]
2599 if (s8_operand (operands[2], PSImode))
2601 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2602 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2607 (define_insn "*umulqihipsi3"
2608 [(set (match_operand:PSI 0 "register_operand" "=&r")
2609 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2610 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2619 [(set_attr "length" "7")
2620 (set_attr "cc" "clobber")])
2622 (define_insn "*umulhiqipsi3"
2623 [(set (match_operand:PSI 0 "register_operand" "=&r")
2624 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2625 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2633 adc %C0,__zero_reg__"
2634 [(set_attr "length" "7")
2635 (set_attr "cc" "clobber")])
2637 (define_insn_and_split "mulsqipsi3"
2638 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2639 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2640 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2641 (clobber (reg:HI 26))
2642 (clobber (reg:DI 18))]
2643 "AVR_HAVE_MUL && !reload_completed"
2644 { gcc_unreachable(); }
2651 (mult:PSI (sign_extend:PSI (reg:QI 25))
2656 (define_insn_and_split "*mulpsi3"
2657 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2658 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2659 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2660 (clobber (reg:HI 26))
2661 (clobber (reg:DI 18))]
2662 "AVR_HAVE_MUL && !reload_completed"
2663 { gcc_unreachable(); }
2669 (parallel [(set (reg:PSI 22)
2670 (mult:PSI (reg:PSI 22)
2672 (clobber (reg:QI 21))
2673 (clobber (reg:QI 25))
2674 (clobber (reg:HI 26))])
2678 if (s8_operand (operands[2], PSImode))
2680 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2681 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2686 (define_insn "*mulsqipsi3.libgcc"
2688 (mult:PSI (sign_extend:PSI (reg:QI 25))
2691 "%~call __mulsqipsi3"
2692 [(set_attr "type" "xcall")
2693 (set_attr "cc" "clobber")])
2695 (define_insn "*mulpsi3.libgcc"
2697 (mult:PSI (reg:PSI 22)
2699 (clobber (reg:QI 21))
2700 (clobber (reg:QI 25))
2701 (clobber (reg:HI 26))]
2704 [(set_attr "type" "xcall")
2705 (set_attr "cc" "clobber")])
2708 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2709 ;; 24-bit signed/unsigned division and modulo.
2710 ;; Notice that the libgcc implementation return the quotient in R22
2711 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2712 ;; implementation works the other way round.
2714 (define_insn_and_split "divmodpsi4"
2715 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2716 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2717 (match_operand:PSI 2 "pseudo_register_operand" "")))
2718 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2719 (mod:PSI (match_dup 1)
2721 (clobber (reg:DI 18))
2722 (clobber (reg:QI 26))])]
2724 { gcc_unreachable(); }
2726 [(set (reg:PSI 22) (match_dup 1))
2727 (set (reg:PSI 18) (match_dup 2))
2728 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2729 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2730 (clobber (reg:QI 21))
2731 (clobber (reg:QI 25))
2732 (clobber (reg:QI 26))])
2733 (set (match_dup 0) (reg:PSI 22))
2734 (set (match_dup 3) (reg:PSI 18))])
2736 (define_insn "*divmodpsi4_call"
2737 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2738 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2739 (clobber (reg:QI 21))
2740 (clobber (reg:QI 25))
2741 (clobber (reg:QI 26))]
2743 "%~call __divmodpsi4"
2744 [(set_attr "type" "xcall")
2745 (set_attr "cc" "clobber")])
2747 (define_insn_and_split "udivmodpsi4"
2748 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2749 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2750 (match_operand:PSI 2 "pseudo_register_operand" "")))
2751 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2752 (umod:PSI (match_dup 1)
2754 (clobber (reg:DI 18))
2755 (clobber (reg:QI 26))])]
2757 { gcc_unreachable(); }
2759 [(set (reg:PSI 22) (match_dup 1))
2760 (set (reg:PSI 18) (match_dup 2))
2761 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2762 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2763 (clobber (reg:QI 21))
2764 (clobber (reg:QI 25))
2765 (clobber (reg:QI 26))])
2766 (set (match_dup 0) (reg:PSI 22))
2767 (set (match_dup 3) (reg:PSI 18))])
2769 (define_insn "*udivmodpsi4_call"
2770 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2771 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2772 (clobber (reg:QI 21))
2773 (clobber (reg:QI 25))
2774 (clobber (reg:QI 26))]
2776 "%~call __udivmodpsi4"
2777 [(set_attr "type" "xcall")
2778 (set_attr "cc" "clobber")])
2780 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2782 (define_insn_and_split "divmodsi4"
2783 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2784 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2785 (match_operand:SI 2 "pseudo_register_operand" "")))
2786 (set (match_operand:SI 3 "pseudo_register_operand" "")
2787 (mod:SI (match_dup 1) (match_dup 2)))
2788 (clobber (reg:SI 18))
2789 (clobber (reg:SI 22))
2790 (clobber (reg:HI 26))
2791 (clobber (reg:HI 30))])]
2793 "this divmodsi4 pattern should have been splitted;"
2795 [(set (reg:SI 22) (match_dup 1))
2796 (set (reg:SI 18) (match_dup 2))
2797 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2798 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2799 (clobber (reg:HI 26))
2800 (clobber (reg:HI 30))])
2801 (set (match_dup 0) (reg:SI 18))
2802 (set (match_dup 3) (reg:SI 22))]
2805 (define_insn "*divmodsi4_call"
2806 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2807 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2808 (clobber (reg:HI 26))
2809 (clobber (reg:HI 30))]
2811 "%~call __divmodsi4"
2812 [(set_attr "type" "xcall")
2813 (set_attr "cc" "clobber")])
2815 (define_insn_and_split "udivmodsi4"
2816 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2817 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2818 (match_operand:SI 2 "pseudo_register_operand" "")))
2819 (set (match_operand:SI 3 "pseudo_register_operand" "")
2820 (umod:SI (match_dup 1) (match_dup 2)))
2821 (clobber (reg:SI 18))
2822 (clobber (reg:SI 22))
2823 (clobber (reg:HI 26))
2824 (clobber (reg:HI 30))])]
2826 "this udivmodsi4 pattern should have been splitted;"
2828 [(set (reg:SI 22) (match_dup 1))
2829 (set (reg:SI 18) (match_dup 2))
2830 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2831 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2832 (clobber (reg:HI 26))
2833 (clobber (reg:HI 30))])
2834 (set (match_dup 0) (reg:SI 18))
2835 (set (match_dup 3) (reg:SI 22))]
2838 (define_insn "*udivmodsi4_call"
2839 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2840 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2841 (clobber (reg:HI 26))
2842 (clobber (reg:HI 30))]
2844 "%~call __udivmodsi4"
2845 [(set_attr "type" "xcall")
2846 (set_attr "cc" "clobber")])
2848 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2851 (define_insn "andqi3"
2852 [(set (match_operand:QI 0 "register_operand" "=r,d")
2853 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2854 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2859 [(set_attr "length" "1,1")
2860 (set_attr "cc" "set_zn,set_zn")])
2862 (define_insn "andhi3"
2863 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2864 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2865 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2866 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2869 if (which_alternative == 0)
2870 return "and %A0,%A2\;and %B0,%B2";
2871 else if (which_alternative == 1)
2872 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2874 return avr_out_bitop (insn, operands, NULL);
2876 [(set_attr "length" "2,2,2,4,4")
2877 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2878 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2880 (define_insn "andpsi3"
2881 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2882 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2883 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2884 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2887 if (which_alternative == 0)
2888 return "and %A0,%A2" CR_TAB
2889 "and %B0,%B2" CR_TAB
2892 return avr_out_bitop (insn, operands, NULL);
2894 [(set_attr "length" "3,3,6,6")
2895 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2896 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2898 (define_insn "andsi3"
2899 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2900 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2901 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2902 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2905 if (which_alternative == 0)
2906 return "and %0,%2" CR_TAB
2907 "and %B0,%B2" CR_TAB
2908 "and %C0,%C2" CR_TAB
2911 return avr_out_bitop (insn, operands, NULL);
2913 [(set_attr "length" "4,4,8,8")
2914 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2915 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2917 (define_peephole2 ; andi
2918 [(set (match_operand:QI 0 "d_register_operand" "")
2919 (and:QI (match_dup 0)
2920 (match_operand:QI 1 "const_int_operand" "")))
2922 (and:QI (match_dup 0)
2923 (match_operand:QI 2 "const_int_operand" "")))]
2925 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2927 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2930 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2933 (define_insn "iorqi3"
2934 [(set (match_operand:QI 0 "register_operand" "=r,d")
2935 (ior: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 "iorhi3"
2945 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2946 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2947 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2948 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2951 if (which_alternative == 0)
2952 return "or %A0,%A2\;or %B0,%B2";
2953 else if (which_alternative == 1)
2954 return "ori %A0,lo8(%2)\;ori %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 "iorpsi3"
2963 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2964 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2965 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
2966 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2969 if (which_alternative == 0)
2970 return "or %A0,%A2" 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 "iorsi3"
2981 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2982 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2983 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2984 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2987 if (which_alternative == 0)
2988 return "or %0,%2" 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 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3002 (define_insn "xorqi3"
3003 [(set (match_operand:QI 0 "register_operand" "=r")
3004 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3005 (match_operand:QI 2 "register_operand" "r")))]
3008 [(set_attr "length" "1")
3009 (set_attr "cc" "set_zn")])
3011 (define_insn "xorhi3"
3012 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
3013 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3014 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3015 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3018 if (which_alternative == 0)
3019 return "eor %A0,%A2\;eor %B0,%B2";
3021 return avr_out_bitop (insn, operands, NULL);
3023 [(set_attr "length" "2,2,4")
3024 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3025 (set_attr "cc" "set_n,clobber,clobber")])
3027 (define_insn "xorpsi3"
3028 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3029 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3030 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3031 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3034 if (which_alternative == 0)
3035 return "eor %A0,%A2" CR_TAB
3036 "eor %B0,%B2" CR_TAB
3039 return avr_out_bitop (insn, operands, NULL);
3041 [(set_attr "length" "3,6,6")
3042 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3043 (set_attr "cc" "set_n,clobber,clobber")])
3045 (define_insn "xorsi3"
3046 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3047 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3048 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3049 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3052 if (which_alternative == 0)
3053 return "eor %0,%2" CR_TAB
3054 "eor %B0,%B2" CR_TAB
3055 "eor %C0,%C2" CR_TAB
3058 return avr_out_bitop (insn, operands, NULL);
3060 [(set_attr "length" "4,8,8")
3061 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3062 (set_attr "cc" "set_n,clobber,clobber")])
3064 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3067 (define_expand "rotlqi3"
3068 [(set (match_operand:QI 0 "register_operand" "")
3069 (rotate:QI (match_operand:QI 1 "register_operand" "")
3070 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3073 if (!CONST_INT_P (operands[2]))
3076 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3079 ;; Expander used by __builtin_avr_swap
3080 (define_expand "rotlqi3_4"
3081 [(set (match_operand:QI 0 "register_operand" "")
3082 (rotate:QI (match_operand:QI 1 "register_operand" "")
3085 (define_insn "*rotlqi3"
3086 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3087 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3088 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3091 lsl %0\;adc %0,__zero_reg__
3092 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3093 swap %0\;bst %0,0\;ror %0\;bld %0,7
3095 swap %0\;lsl %0\;adc %0,__zero_reg__
3096 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3097 bst %0,0\;ror %0\;bld %0,7
3099 [(set_attr "length" "2,4,4,1,3,5,3,0")
3100 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3102 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3103 ;; a whole number of bytes. The split creates the appropriate moves and
3104 ;; considers all overlap situations.
3106 ;; HImode does not need scratch. Use attribute for this constraint.
3108 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3109 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3114 (define_expand "rotl<mode>3"
3115 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3116 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3117 (match_operand:VOID 2 "const_int_operand" "")))
3118 (clobber (match_dup 3))])]
3123 if (!CONST_INT_P (operands[2]))
3126 offset = INTVAL (operands[2]);
3128 if (0 == offset % 8)
3130 if (AVR_HAVE_MOVW && 0 == offset % 16)
3131 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3133 operands[3] = gen_rtx_SCRATCH (QImode);
3135 else if (offset == 1
3136 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3138 /*; Support rotate left/right by 1 */
3140 emit_move_insn (operands[0],
3141 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3148 (define_insn "*rotlhi2.1"
3149 [(set (match_operand:HI 0 "register_operand" "=r")
3150 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3153 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3154 [(set_attr "length" "3")
3155 (set_attr "cc" "clobber")])
3157 (define_insn "*rotlhi2.15"
3158 [(set (match_operand:HI 0 "register_operand" "=r")
3159 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3162 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3163 [(set_attr "length" "4")
3164 (set_attr "cc" "clobber")])
3166 (define_insn "*rotlpsi2.1"
3167 [(set (match_operand:PSI 0 "register_operand" "=r")
3168 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3171 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3172 [(set_attr "length" "4")
3173 (set_attr "cc" "clobber")])
3175 (define_insn "*rotlpsi2.23"
3176 [(set (match_operand:PSI 0 "register_operand" "=r")
3177 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3180 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3181 [(set_attr "length" "5")
3182 (set_attr "cc" "clobber")])
3184 (define_insn "*rotlsi2.1"
3185 [(set (match_operand:SI 0 "register_operand" "=r")
3186 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3189 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3190 [(set_attr "length" "5")
3191 (set_attr "cc" "clobber")])
3193 (define_insn "*rotlsi2.31"
3194 [(set (match_operand:SI 0 "register_operand" "=r")
3195 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3198 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3199 [(set_attr "length" "6")
3200 (set_attr "cc" "clobber")])
3202 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3203 ;; The best we can do is use early clobber alternative "#&r" so that
3204 ;; completely non-overlapping operands dont get a scratch but # so register
3205 ;; allocation does not prefer non-overlapping.
3208 ;; Split word aligned rotates using scratch that is mode dependent.
3212 (define_insn_and_split "*rotw<mode>"
3213 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3214 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3215 (match_operand 2 "const_int_operand" "n,n,n")))
3216 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3218 && CONST_INT_P (operands[2])
3219 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3220 && 0 == INTVAL (operands[2]) % 16"
3222 "&& reload_completed"
3225 avr_rotate_bytes (operands);
3230 ;; Split byte aligned rotates using scratch that is always QI mode.
3235 (define_insn_and_split "*rotb<mode>"
3236 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3237 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3238 (match_operand 2 "const_int_operand" "n,n,n")))
3239 (clobber (match_scratch:QI 3 "=<rotx>"))]
3240 "CONST_INT_P (operands[2])
3241 && (8 == INTVAL (operands[2]) % 16
3243 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3244 && 0 == INTVAL (operands[2]) % 16))"
3246 "&& reload_completed"
3249 avr_rotate_bytes (operands);
3254 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3255 ;; arithmetic shift left
3257 (define_expand "ashlqi3"
3258 [(set (match_operand:QI 0 "register_operand" "")
3259 (ashift:QI (match_operand:QI 1 "register_operand" "")
3260 (match_operand:QI 2 "nop_general_operand" "")))])
3262 (define_split ; ashlqi3_const4
3263 [(set (match_operand:QI 0 "d_register_operand" "")
3264 (ashift:QI (match_dup 0)
3267 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3268 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
3271 (define_split ; ashlqi3_const5
3272 [(set (match_operand:QI 0 "d_register_operand" "")
3273 (ashift:QI (match_dup 0)
3276 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3277 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3278 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
3281 (define_split ; ashlqi3_const6
3282 [(set (match_operand:QI 0 "d_register_operand" "")
3283 (ashift:QI (match_dup 0)
3286 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3287 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3288 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
3291 (define_insn "*ashlqi3"
3292 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3293 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3294 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3297 return ashlqi3_out (insn, operands, NULL);
3299 [(set_attr "length" "5,0,1,2,4,6,9")
3300 (set_attr "adjust_len" "ashlqi")
3301 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3303 (define_insn "ashlhi3"
3304 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3305 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3306 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3309 return ashlhi3_out (insn, operands, NULL);
3311 [(set_attr "length" "6,0,2,2,4,10,10")
3312 (set_attr "adjust_len" "ashlhi")
3313 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3316 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3317 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3321 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3322 [(set (match_operand:QI 0 "register_operand" "=r")
3323 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3324 (match_operand:QI 2 "register_operand" "r"))
3330 (ashift:QI (match_dup 1)
3334 ;; ??? Combiner does not recognize that it could split the following insn;
3335 ;; presumably because he has no register handy?
3337 ;; "*ashluqihiqi3.mem"
3338 ;; "*ashlsqihiqi3.mem"
3339 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3340 [(set (match_operand:QI 0 "memory_operand" "=m")
3341 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3342 (match_operand:QI 2 "register_operand" "r"))
3345 { gcc_unreachable(); }
3348 (ashift:QI (match_dup 1)
3353 operands[3] = gen_reg_rtx (QImode);
3358 (define_insn_and_split "*ashlhiqi3"
3359 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3360 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3361 (match_operand:QI 2 "register_operand" "r")) 0))]
3363 { gcc_unreachable(); }
3366 (ashift:QI (match_dup 3)
3371 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3372 operands[4] = gen_reg_rtx (QImode);
3375 ;; High part of 16-bit shift is unused after the instruction:
3376 ;; No need to compute it, map to 8-bit shift.
3379 [(set (match_operand:HI 0 "register_operand" "")
3380 (ashift:HI (match_dup 0)
3381 (match_operand:QI 1 "register_operand" "")))]
3384 (ashift:QI (match_dup 2)
3386 (clobber (match_dup 3))]
3388 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3390 if (!peep2_reg_dead_p (1, operands[3]))
3393 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3397 (define_insn "ashlsi3"
3398 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3399 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3400 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3403 return ashlsi3_out (insn, operands, NULL);
3405 [(set_attr "length" "8,0,4,4,8,10,12")
3406 (set_attr "adjust_len" "ashlsi")
3407 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3409 ;; Optimize if a scratch register from LD_REGS happens to be available.
3411 (define_peephole2 ; ashlqi3_l_const4
3412 [(set (match_operand:QI 0 "l_register_operand" "")
3413 (ashift:QI (match_dup 0)
3415 (match_scratch:QI 1 "d")]
3417 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3418 (set (match_dup 1) (const_int -16))
3419 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3422 (define_peephole2 ; ashlqi3_l_const5
3423 [(set (match_operand:QI 0 "l_register_operand" "")
3424 (ashift:QI (match_dup 0)
3426 (match_scratch:QI 1 "d")]
3428 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3429 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3430 (set (match_dup 1) (const_int -32))
3431 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3434 (define_peephole2 ; ashlqi3_l_const6
3435 [(set (match_operand:QI 0 "l_register_operand" "")
3436 (ashift:QI (match_dup 0)
3438 (match_scratch:QI 1 "d")]
3440 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3441 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3442 (set (match_dup 1) (const_int -64))
3443 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3447 [(match_scratch:QI 3 "d")
3448 (set (match_operand:HI 0 "register_operand" "")
3449 (ashift:HI (match_operand:HI 1 "register_operand" "")
3450 (match_operand:QI 2 "const_int_operand" "")))]
3452 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3453 (clobber (match_dup 3))])]
3456 (define_insn "*ashlhi3_const"
3457 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3458 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3459 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3460 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3463 return ashlhi3_out (insn, operands, NULL);
3465 [(set_attr "length" "0,2,2,4,10")
3466 (set_attr "adjust_len" "ashlhi")
3467 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3470 [(match_scratch:QI 3 "d")
3471 (set (match_operand:SI 0 "register_operand" "")
3472 (ashift:SI (match_operand:SI 1 "register_operand" "")
3473 (match_operand:QI 2 "const_int_operand" "")))]
3475 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3476 (clobber (match_dup 3))])]
3479 (define_insn "*ashlsi3_const"
3480 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3481 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3482 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3483 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3486 return ashlsi3_out (insn, operands, NULL);
3488 [(set_attr "length" "0,4,4,10")
3489 (set_attr "adjust_len" "ashlsi")
3490 (set_attr "cc" "none,set_n,clobber,clobber")])
3492 (define_expand "ashlpsi3"
3493 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3494 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3495 (match_operand:QI 2 "nonmemory_operand" "")))
3496 (clobber (scratch:QI))])]
3500 && CONST_INT_P (operands[2]))
3502 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3504 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3505 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3508 else if (optimize_insn_for_speed_p ()
3509 && INTVAL (operands[2]) != 16
3510 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3512 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3513 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3519 (define_insn "*ashlpsi3"
3520 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3521 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3522 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3523 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3526 return avr_out_ashlpsi3 (insn, operands, NULL);
3528 [(set_attr "adjust_len" "ashlpsi")
3529 (set_attr "cc" "clobber")])
3531 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3532 ;; arithmetic shift right
3534 (define_insn "ashrqi3"
3535 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3536 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3537 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3540 return ashrqi3_out (insn, operands, NULL);
3542 [(set_attr "length" "5,0,1,2,5,4,9")
3543 (set_attr "adjust_len" "ashrqi")
3544 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3546 (define_insn "ashrhi3"
3547 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3548 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3549 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3552 return ashrhi3_out (insn, operands, NULL);
3554 [(set_attr "length" "6,0,2,4,4,10,10")
3555 (set_attr "adjust_len" "ashrhi")
3556 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3558 (define_insn "ashrpsi3"
3559 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3560 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3561 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3562 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3565 return avr_out_ashrpsi3 (insn, operands, NULL);
3567 [(set_attr "adjust_len" "ashrpsi")
3568 (set_attr "cc" "clobber")])
3570 (define_insn "ashrsi3"
3571 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3572 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3573 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3576 return ashrsi3_out (insn, operands, NULL);
3578 [(set_attr "length" "8,0,4,6,8,10,12")
3579 (set_attr "adjust_len" "ashrsi")
3580 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3582 ;; Optimize if a scratch register from LD_REGS happens to be available.
3585 [(match_scratch:QI 3 "d")
3586 (set (match_operand:HI 0 "register_operand" "")
3587 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3588 (match_operand:QI 2 "const_int_operand" "")))]
3590 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3591 (clobber (match_dup 3))])]
3594 (define_insn "*ashrhi3_const"
3595 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3596 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3597 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3598 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3601 return ashrhi3_out (insn, operands, NULL);
3603 [(set_attr "length" "0,2,4,4,10")
3604 (set_attr "adjust_len" "ashrhi")
3605 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3608 [(match_scratch:QI 3 "d")
3609 (set (match_operand:SI 0 "register_operand" "")
3610 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3611 (match_operand:QI 2 "const_int_operand" "")))]
3613 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3614 (clobber (match_dup 3))])]
3617 (define_insn "*ashrsi3_const"
3618 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3619 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3620 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3621 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3624 return ashrsi3_out (insn, operands, NULL);
3626 [(set_attr "length" "0,4,4,10")
3627 (set_attr "adjust_len" "ashrsi")
3628 (set_attr "cc" "none,clobber,set_n,clobber")])
3630 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3631 ;; logical shift right
3633 (define_expand "lshrqi3"
3634 [(set (match_operand:QI 0 "register_operand" "")
3635 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3636 (match_operand:QI 2 "nop_general_operand" "")))])
3638 (define_split ; lshrqi3_const4
3639 [(set (match_operand:QI 0 "d_register_operand" "")
3640 (lshiftrt:QI (match_dup 0)
3643 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3644 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3647 (define_split ; lshrqi3_const5
3648 [(set (match_operand:QI 0 "d_register_operand" "")
3649 (lshiftrt:QI (match_dup 0)
3652 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3653 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3654 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3657 (define_split ; lshrqi3_const6
3658 [(set (match_operand:QI 0 "d_register_operand" "")
3659 (lshiftrt:QI (match_dup 0)
3662 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3663 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3664 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3667 (define_insn "*lshrqi3"
3668 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3669 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3670 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3673 return lshrqi3_out (insn, operands, NULL);
3675 [(set_attr "length" "5,0,1,2,4,6,9")
3676 (set_attr "adjust_len" "lshrqi")
3677 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3679 (define_insn "lshrhi3"
3680 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3681 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3682 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3685 return lshrhi3_out (insn, operands, NULL);
3687 [(set_attr "length" "6,0,2,2,4,10,10")
3688 (set_attr "adjust_len" "lshrhi")
3689 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3691 (define_insn "lshrpsi3"
3692 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3693 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3694 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3695 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3698 return avr_out_lshrpsi3 (insn, operands, NULL);
3700 [(set_attr "adjust_len" "lshrpsi")
3701 (set_attr "cc" "clobber")])
3703 (define_insn "lshrsi3"
3704 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3705 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3706 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3709 return lshrsi3_out (insn, operands, NULL);
3711 [(set_attr "length" "8,0,4,4,8,10,12")
3712 (set_attr "adjust_len" "lshrsi")
3713 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3715 ;; Optimize if a scratch register from LD_REGS happens to be available.
3717 (define_peephole2 ; lshrqi3_l_const4
3718 [(set (match_operand:QI 0 "l_register_operand" "")
3719 (lshiftrt:QI (match_dup 0)
3721 (match_scratch:QI 1 "d")]
3723 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3724 (set (match_dup 1) (const_int 15))
3725 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3728 (define_peephole2 ; lshrqi3_l_const5
3729 [(set (match_operand:QI 0 "l_register_operand" "")
3730 (lshiftrt:QI (match_dup 0)
3732 (match_scratch:QI 1 "d")]
3734 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3735 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3736 (set (match_dup 1) (const_int 7))
3737 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3740 (define_peephole2 ; lshrqi3_l_const6
3741 [(set (match_operand:QI 0 "l_register_operand" "")
3742 (lshiftrt:QI (match_dup 0)
3744 (match_scratch:QI 1 "d")]
3746 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3747 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3748 (set (match_dup 1) (const_int 3))
3749 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3753 [(match_scratch:QI 3 "d")
3754 (set (match_operand:HI 0 "register_operand" "")
3755 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3756 (match_operand:QI 2 "const_int_operand" "")))]
3758 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3759 (clobber (match_dup 3))])]
3762 (define_insn "*lshrhi3_const"
3763 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3764 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3765 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3766 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3769 return lshrhi3_out (insn, operands, NULL);
3771 [(set_attr "length" "0,2,2,4,10")
3772 (set_attr "adjust_len" "lshrhi")
3773 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3776 [(match_scratch:QI 3 "d")
3777 (set (match_operand:SI 0 "register_operand" "")
3778 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3779 (match_operand:QI 2 "const_int_operand" "")))]
3781 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3782 (clobber (match_dup 3))])]
3785 (define_insn "*lshrsi3_const"
3786 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3787 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3788 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3789 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3792 return lshrsi3_out (insn, operands, NULL);
3794 [(set_attr "length" "0,4,4,10")
3795 (set_attr "adjust_len" "lshrsi")
3796 (set_attr "cc" "none,clobber,clobber,clobber")])
3798 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3801 (define_insn "absqi2"
3802 [(set (match_operand:QI 0 "register_operand" "=r")
3803 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3807 [(set_attr "length" "2")
3808 (set_attr "cc" "clobber")])
3811 (define_insn "abssf2"
3812 [(set (match_operand:SF 0 "register_operand" "=d,r")
3813 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3818 [(set_attr "length" "1,2")
3819 (set_attr "cc" "set_n,clobber")])
3821 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3824 (define_insn "negqi2"
3825 [(set (match_operand:QI 0 "register_operand" "=r")
3826 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3829 [(set_attr "length" "1")
3830 (set_attr "cc" "set_zn")])
3832 (define_insn "*negqihi2"
3833 [(set (match_operand:HI 0 "register_operand" "=r")
3834 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3836 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3837 [(set_attr "length" "4")
3838 (set_attr "cc" "set_n")])
3840 (define_insn "neghi2"
3841 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
3842 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
3845 com %B0\;neg %A0\;sbci %B0,lo8(-1)
3846 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
3847 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3848 [(set_attr "length" "3,4,4")
3849 (set_attr "cc" "set_czn,set_n,set_czn")])
3851 (define_insn "negpsi2"
3852 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3853 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3856 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3857 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3858 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3859 [(set_attr "length" "5,6,6")
3860 (set_attr "cc" "set_czn,set_n,set_czn")])
3862 (define_insn "negsi2"
3863 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3864 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
3867 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3868 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3869 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3870 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3871 [(set_attr "length" "7,8,8,7")
3872 (set_attr "isa" "*,*,mov,movw")
3873 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
3875 (define_insn "negsf2"
3876 [(set (match_operand:SF 0 "register_operand" "=d,r")
3877 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3881 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3882 [(set_attr "length" "1,4")
3883 (set_attr "cc" "set_n,set_n")])
3885 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3888 (define_insn "one_cmplqi2"
3889 [(set (match_operand:QI 0 "register_operand" "=r")
3890 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3893 [(set_attr "length" "1")
3894 (set_attr "cc" "set_czn")])
3896 (define_insn "one_cmplhi2"
3897 [(set (match_operand:HI 0 "register_operand" "=r")
3898 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3902 [(set_attr "length" "2")
3903 (set_attr "cc" "set_n")])
3905 (define_insn "one_cmplpsi2"
3906 [(set (match_operand:PSI 0 "register_operand" "=r")
3907 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3909 "com %0\;com %B0\;com %C0"
3910 [(set_attr "length" "3")
3911 (set_attr "cc" "set_n")])
3913 (define_insn "one_cmplsi2"
3914 [(set (match_operand:SI 0 "register_operand" "=r")
3915 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3921 [(set_attr "length" "4")
3922 (set_attr "cc" "set_n")])
3924 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3927 ;; We keep combiner from inserting hard registers into the input of sign- and
3928 ;; zero-extends. A hard register in the input operand is not wanted because
3929 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3930 ;; hard register that overlaps these clobbers won't be combined to a widening
3931 ;; multiplication. There is no need for combine to propagate hard registers,
3932 ;; register allocation can do it just as well.
3934 (define_insn "extendqihi2"
3935 [(set (match_operand:HI 0 "register_operand" "=r,r")
3936 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3939 clr %B0\;sbrc %0,7\;com %B0
3940 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3941 [(set_attr "length" "3,4")
3942 (set_attr "cc" "set_n,set_n")])
3944 (define_insn "extendqipsi2"
3945 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3946 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3949 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3950 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3951 [(set_attr "length" "4,5")
3952 (set_attr "cc" "set_n,set_n")])
3954 (define_insn "extendqisi2"
3955 [(set (match_operand:SI 0 "register_operand" "=r,r")
3956 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3959 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3960 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3961 [(set_attr "length" "5,6")
3962 (set_attr "cc" "set_n,set_n")])
3964 (define_insn "extendhipsi2"
3965 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3966 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3969 clr %C0\;sbrc %B0,7\;com %C0
3970 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
3971 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
3972 [(set_attr "length" "3,5,4")
3973 (set_attr "isa" "*,mov,movw")
3974 (set_attr "cc" "set_n")])
3976 (define_insn "extendhisi2"
3977 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3978 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3981 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3982 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3983 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3984 [(set_attr "length" "4,6,5")
3985 (set_attr "isa" "*,mov,movw")
3986 (set_attr "cc" "set_n")])
3988 (define_insn "extendpsisi2"
3989 [(set (match_operand:SI 0 "register_operand" "=r")
3990 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
3992 "clr %D0\;sbrc %C0,7\;com %D0"
3993 [(set_attr "length" "3")
3994 (set_attr "cc" "set_n")])
3996 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3999 (define_insn_and_split "zero_extendqihi2"
4000 [(set (match_operand:HI 0 "register_operand" "=r")
4001 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4005 [(set (match_dup 2) (match_dup 1))
4006 (set (match_dup 3) (const_int 0))]
4008 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4009 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4011 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4012 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4015 (define_insn_and_split "zero_extendqipsi2"
4016 [(set (match_operand:PSI 0 "register_operand" "=r")
4017 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4021 [(set (match_dup 2) (match_dup 1))
4022 (set (match_dup 3) (const_int 0))
4023 (set (match_dup 4) (const_int 0))]
4025 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4026 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4027 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4030 (define_insn_and_split "zero_extendqisi2"
4031 [(set (match_operand:SI 0 "register_operand" "=r")
4032 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4036 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4037 (set (match_dup 3) (const_int 0))]
4039 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4040 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4042 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4043 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4046 (define_insn_and_split "zero_extendhipsi2"
4047 [(set (match_operand:PSI 0 "register_operand" "=r")
4048 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4052 [(set (match_dup 2) (match_dup 1))
4053 (set (match_dup 3) (const_int 0))]
4055 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4056 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4059 (define_insn_and_split "n_extendhipsi2"
4060 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4061 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4062 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4063 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4067 [(set (match_dup 4) (match_dup 2))
4068 (set (match_dup 3) (match_dup 6))
4069 ; no-op move in the case where no scratch is needed
4070 (set (match_dup 5) (match_dup 3))]
4072 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4073 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4074 operands[6] = operands[1];
4076 if (GET_CODE (operands[3]) == SCRATCH)
4077 operands[3] = operands[5];
4080 (define_insn_and_split "zero_extendhisi2"
4081 [(set (match_operand:SI 0 "register_operand" "=r")
4082 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4086 [(set (match_dup 2) (match_dup 1))
4087 (set (match_dup 3) (const_int 0))]
4089 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4090 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4092 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4093 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4096 (define_insn_and_split "zero_extendpsisi2"
4097 [(set (match_operand:SI 0 "register_operand" "=r")
4098 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4102 [(set (match_dup 2) (match_dup 1))
4103 (set (match_dup 3) (const_int 0))]
4105 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4106 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4109 (define_insn_and_split "zero_extendqidi2"
4110 [(set (match_operand:DI 0 "register_operand" "=r")
4111 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4115 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4116 (set (match_dup 3) (const_int 0))]
4118 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4119 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4121 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4122 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4125 (define_insn_and_split "zero_extendhidi2"
4126 [(set (match_operand:DI 0 "register_operand" "=r")
4127 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4131 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4132 (set (match_dup 3) (const_int 0))]
4134 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4135 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4137 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4138 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4141 (define_insn_and_split "zero_extendsidi2"
4142 [(set (match_operand:DI 0 "register_operand" "=r")
4143 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4147 [(set (match_dup 2) (match_dup 1))
4148 (set (match_dup 3) (const_int 0))]
4150 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4151 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4153 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4154 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4157 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4160 ; Optimize negated tests into reverse compare if overflow is undefined.
4161 (define_insn "*negated_tstqi"
4163 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4165 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4166 "cp __zero_reg__,%0"
4167 [(set_attr "cc" "compare")
4168 (set_attr "length" "1")])
4170 (define_insn "*reversed_tstqi"
4172 (compare (const_int 0)
4173 (match_operand:QI 0 "register_operand" "r")))]
4175 "cp __zero_reg__,%0"
4176 [(set_attr "cc" "compare")
4177 (set_attr "length" "2")])
4179 (define_insn "*negated_tsthi"
4181 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4183 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4184 "cp __zero_reg__,%A0
4185 cpc __zero_reg__,%B0"
4186 [(set_attr "cc" "compare")
4187 (set_attr "length" "2")])
4189 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4190 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4191 (define_insn "*reversed_tsthi"
4193 (compare (const_int 0)
4194 (match_operand:HI 0 "register_operand" "r")))
4195 (clobber (match_scratch:QI 1 "=X"))]
4197 "cp __zero_reg__,%A0
4198 cpc __zero_reg__,%B0"
4199 [(set_attr "cc" "compare")
4200 (set_attr "length" "2")])
4202 (define_insn "*negated_tstpsi"
4204 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4206 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4207 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4208 [(set_attr "cc" "compare")
4209 (set_attr "length" "3")])
4211 (define_insn "*reversed_tstpsi"
4213 (compare (const_int 0)
4214 (match_operand:PSI 0 "register_operand" "r")))
4215 (clobber (match_scratch:QI 1 "=X"))]
4217 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4218 [(set_attr "cc" "compare")
4219 (set_attr "length" "3")])
4221 (define_insn "*negated_tstsi"
4223 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4225 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4226 "cp __zero_reg__,%A0
4227 cpc __zero_reg__,%B0
4228 cpc __zero_reg__,%C0
4229 cpc __zero_reg__,%D0"
4230 [(set_attr "cc" "compare")
4231 (set_attr "length" "4")])
4233 (define_insn "*reversed_tstsi"
4235 (compare (const_int 0)
4236 (match_operand:SI 0 "register_operand" "r")))
4237 (clobber (match_scratch:QI 1 "=X"))]
4239 "cp __zero_reg__,%A0
4240 cpc __zero_reg__,%B0
4241 cpc __zero_reg__,%C0
4242 cpc __zero_reg__,%D0"
4243 [(set_attr "cc" "compare")
4244 (set_attr "length" "4")])
4247 (define_insn "*cmpqi"
4249 (compare (match_operand:QI 0 "register_operand" "r,r,d")
4250 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
4256 [(set_attr "cc" "compare,compare,compare")
4257 (set_attr "length" "1,1,1")])
4259 (define_insn "*cmpqi_sign_extend"
4261 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4262 (match_operand:HI 1 "s8_operand" "n")))]
4265 [(set_attr "cc" "compare")
4266 (set_attr "length" "1")])
4268 (define_insn "*cmphi"
4270 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
4271 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
4272 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
4275 switch (which_alternative)
4279 return avr_out_tsthi (insn, operands, NULL);
4282 return "cp %A0,%A1\;cpc %B0,%B1";
4285 return reg_unused_after (insn, operands[0])
4286 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4287 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4290 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4293 return avr_out_compare (insn, operands, NULL);
4295 [(set_attr "cc" "compare")
4296 (set_attr "length" "1,2,2,3,4,2,4")
4297 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4299 (define_insn "*cmppsi"
4301 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4302 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4303 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4306 switch (which_alternative)
4309 return avr_out_tstpsi (insn, operands, NULL);
4312 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4315 return reg_unused_after (insn, operands[0])
4316 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4317 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4320 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4323 return avr_out_compare (insn, operands, NULL);
4325 [(set_attr "cc" "compare")
4326 (set_attr "length" "3,3,5,6,3,7")
4327 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4329 (define_insn "*cmpsi"
4331 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
4332 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
4333 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
4336 if (0 == which_alternative)
4337 return avr_out_tstsi (insn, operands, NULL);
4338 else if (1 == which_alternative)
4339 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4341 return avr_out_compare (insn, operands, NULL);
4343 [(set_attr "cc" "compare")
4344 (set_attr "length" "4,4,4,5,8")
4345 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4348 ;; ----------------------------------------------------------------------
4349 ;; JUMP INSTRUCTIONS
4350 ;; ----------------------------------------------------------------------
4351 ;; Conditional jump instructions
4353 (define_expand "cbranchsi4"
4354 [(parallel [(set (cc0)
4355 (compare (match_operand:SI 1 "register_operand" "")
4356 (match_operand:SI 2 "nonmemory_operand" "")))
4357 (clobber (match_scratch:QI 4 ""))])
4360 (match_operator 0 "ordered_comparison_operator" [(cc0)
4362 (label_ref (match_operand 3 "" ""))
4366 (define_expand "cbranchpsi4"
4367 [(parallel [(set (cc0)
4368 (compare (match_operand:PSI 1 "register_operand" "")
4369 (match_operand:PSI 2 "nonmemory_operand" "")))
4370 (clobber (match_scratch:QI 4 ""))])
4372 (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0)
4374 (label_ref (match_operand 3 "" ""))
4378 (define_expand "cbranchhi4"
4379 [(parallel [(set (cc0)
4380 (compare (match_operand:HI 1 "register_operand" "")
4381 (match_operand:HI 2 "nonmemory_operand" "")))
4382 (clobber (match_scratch:QI 4 ""))])
4385 (match_operator 0 "ordered_comparison_operator" [(cc0)
4387 (label_ref (match_operand 3 "" ""))
4391 (define_expand "cbranchqi4"
4393 (compare (match_operand:QI 1 "register_operand" "")
4394 (match_operand:QI 2 "nonmemory_operand" "")))
4397 (match_operator 0 "ordered_comparison_operator" [(cc0)
4399 (label_ref (match_operand 3 "" ""))
4404 ;; Test a single bit in a QI/HI/SImode register.
4405 ;; Combine will create zero extract patterns for single bit tests.
4406 ;; permit any mode in source pattern by using VOIDmode.
4408 (define_insn "*sbrx_branch<mode>"
4411 (match_operator 0 "eqne_operator"
4413 (match_operand:VOID 1 "register_operand" "r")
4415 (match_operand 2 "const_int_operand" "n"))
4417 (label_ref (match_operand 3 "" ""))
4420 "* return avr_out_sbxx_branch (insn, operands);"
4421 [(set (attr "length")
4422 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4423 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4425 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4428 (set_attr "cc" "clobber")])
4430 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
4431 ;; or for old peepholes.
4432 ;; Fixme - bitwise Mask will not work for DImode
4434 (define_insn "*sbrx_and_branch<mode>"
4437 (match_operator 0 "eqne_operator"
4439 (match_operand:QISI 1 "register_operand" "r")
4440 (match_operand:QISI 2 "single_one_operand" "n"))
4442 (label_ref (match_operand 3 "" ""))
4446 HOST_WIDE_INT bitnumber;
4447 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4448 operands[2] = GEN_INT (bitnumber);
4449 return avr_out_sbxx_branch (insn, operands);
4451 [(set (attr "length")
4452 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4453 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4455 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4458 (set_attr "cc" "clobber")])
4460 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4462 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4464 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4465 (label_ref (match_operand 1 "" ""))
4468 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4472 (label_ref (match_dup 1))
4477 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4479 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4480 (label_ref (match_operand 1 "" ""))
4483 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4487 (label_ref (match_dup 1))
4492 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4494 (clobber (match_operand:HI 2 ""))])
4495 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4496 (label_ref (match_operand 1 "" ""))
4499 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4501 (label_ref (match_dup 1))
4506 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4508 (clobber (match_operand:HI 2 ""))])
4509 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4510 (label_ref (match_operand 1 "" ""))
4513 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4515 (label_ref (match_dup 1))
4520 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4522 (clobber (match_operand:SI 2 ""))])
4523 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4524 (label_ref (match_operand 1 "" ""))
4527 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4529 (label_ref (match_dup 1))
4531 "operands[2] = GEN_INT (-2147483647 - 1);")
4534 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4536 (clobber (match_operand:SI 2 ""))])
4537 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4538 (label_ref (match_operand 1 "" ""))
4541 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4543 (label_ref (match_dup 1))
4545 "operands[2] = GEN_INT (-2147483647 - 1);")
4547 ;; ************************************************************************
4548 ;; Implementation of conditional jumps here.
4549 ;; Compare with 0 (test) jumps
4550 ;; ************************************************************************
4552 (define_insn "branch"
4554 (if_then_else (match_operator 1 "simple_comparison_operator"
4557 (label_ref (match_operand 0 "" ""))
4561 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4563 [(set_attr "type" "branch")
4564 (set_attr "cc" "clobber")])
4567 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4568 ;; or optimized in the remainder.
4570 (define_insn "branch_unspec"
4572 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4575 (label_ref (match_operand 0 "" ""))
4577 ] UNSPEC_IDENTITY))]
4580 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4582 [(set_attr "type" "branch")
4583 (set_attr "cc" "none")])
4585 ;; ****************************************************************
4586 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4587 ;; Convert them all to proper jumps.
4588 ;; ****************************************************************/
4590 (define_insn "difficult_branch"
4592 (if_then_else (match_operator 1 "difficult_comparison_operator"
4595 (label_ref (match_operand 0 "" ""))
4599 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
4600 [(set_attr "type" "branch1")
4601 (set_attr "cc" "clobber")])
4605 (define_insn "rvbranch"
4607 (if_then_else (match_operator 1 "simple_comparison_operator"
4611 (label_ref (match_operand 0 "" ""))))]
4614 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
4615 [(set_attr "type" "branch1")
4616 (set_attr "cc" "clobber")])
4618 (define_insn "difficult_rvbranch"
4620 (if_then_else (match_operator 1 "difficult_comparison_operator"
4624 (label_ref (match_operand 0 "" ""))))]
4627 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
4628 [(set_attr "type" "branch")
4629 (set_attr "cc" "clobber")])
4631 ;; **************************************************************************
4632 ;; Unconditional and other jump instructions.
4636 (label_ref (match_operand 0 "" "")))]
4639 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4643 [(set (attr "length")
4644 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4645 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4648 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4649 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4652 (set_attr "cc" "none")])
4656 (define_expand "call"
4657 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4658 (match_operand:HI 1 "general_operand" ""))
4659 (use (const_int 0))])]
4660 ;; Operand 1 not used on the AVR.
4661 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4665 (define_expand "sibcall"
4666 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4667 (match_operand:HI 1 "general_operand" ""))
4668 (use (const_int 1))])]
4669 ;; Operand 1 not used on the AVR.
4670 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4676 (define_expand "call_value"
4677 [(parallel[(set (match_operand 0 "register_operand" "")
4678 (call (match_operand:HI 1 "call_insn_operand" "")
4679 (match_operand:HI 2 "general_operand" "")))
4680 (use (const_int 0))])]
4681 ;; Operand 2 not used on the AVR.
4682 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4686 (define_expand "sibcall_value"
4687 [(parallel[(set (match_operand 0 "register_operand" "")
4688 (call (match_operand:HI 1 "call_insn_operand" "")
4689 (match_operand:HI 2 "general_operand" "")))
4690 (use (const_int 1))])]
4691 ;; Operand 2 not used on the AVR.
4692 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4696 (define_insn "call_insn"
4697 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4698 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4699 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4700 ;; Operand 1 not used on the AVR.
4701 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4708 [(set_attr "cc" "clobber")
4709 (set_attr "length" "1,*,1,*")
4710 (set_attr "adjust_len" "*,call,*,call")])
4712 (define_insn "call_value_insn"
4713 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4714 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4715 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4716 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4717 ;; Operand 2 not used on the AVR.
4718 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4725 [(set_attr "cc" "clobber")
4726 (set_attr "length" "1,*,1,*")
4727 (set_attr "adjust_len" "*,call,*,call")])
4733 [(set_attr "cc" "none")
4734 (set_attr "length" "1")])
4738 (define_expand "indirect_jump"
4740 (match_operand:HI 0 "nonmemory_operand" ""))]
4743 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4745 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4750 (define_insn "*indirect_jump"
4752 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4758 push %A0\;push %B0\;ret
4760 [(set_attr "length" "1,2,1,3,1")
4761 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4762 (set_attr "cc" "none")])
4765 ;; For entries in jump table see avr_output_addr_vec_elt.
4768 ;; "rjmp .L<n>" instructions for <= 8K devices
4769 ;; ".word gs(.L<n>)" addresses for > 8K devices
4770 (define_insn "*tablejump"
4772 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4774 (use (label_ref (match_operand 1 "" "")))
4775 (clobber (match_dup 0))]
4779 push %A0\;push %B0\;ret
4781 [(set_attr "length" "1,3,2")
4782 (set_attr "isa" "rjmp,rjmp,jmp")
4783 (set_attr "cc" "none,none,clobber")])
4786 (define_expand "casesi"
4788 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4789 (match_operand:HI 1 "register_operand" "")))
4790 (parallel [(set (cc0)
4791 (compare (match_dup 6)
4792 (match_operand:HI 2 "register_operand" "")))
4793 (clobber (match_scratch:QI 9 ""))])
4796 (if_then_else (gtu (cc0)
4798 (label_ref (match_operand 4 "" ""))
4802 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4804 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4805 (use (label_ref (match_dup 3)))
4806 (clobber (match_dup 6))])]
4810 operands[6] = gen_reg_rtx (HImode);
4814 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4815 ;; This instruction sets Z flag
4818 [(set (cc0) (const_int 0))]
4821 [(set_attr "length" "1")
4822 (set_attr "cc" "compare")])
4824 ;; Clear/set/test a single bit in I/O address space.
4827 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4828 (and:QI (mem:QI (match_dup 0))
4829 (match_operand:QI 1 "single_zero_operand" "n")))]
4832 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4833 return "cbi %i0,%2";
4835 [(set_attr "length" "1")
4836 (set_attr "cc" "none")])
4839 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4840 (ior:QI (mem:QI (match_dup 0))
4841 (match_operand:QI 1 "single_one_operand" "n")))]
4844 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4845 return "sbi %i0,%2";
4847 [(set_attr "length" "1")
4848 (set_attr "cc" "none")])
4850 ;; Lower half of the I/O space - use sbic/sbis directly.
4851 (define_insn "*sbix_branch"
4854 (match_operator 0 "eqne_operator"
4856 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
4858 (match_operand 2 "const_int_operand" "n"))
4860 (label_ref (match_operand 3 "" ""))
4863 "* return avr_out_sbxx_branch (insn, operands);"
4864 [(set (attr "length")
4865 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4866 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4868 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4871 (set_attr "cc" "clobber")])
4873 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4874 (define_insn "*sbix_branch_bit7"
4877 (match_operator 0 "gelt_operator"
4878 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
4880 (label_ref (match_operand 2 "" ""))
4884 operands[3] = operands[2];
4885 operands[2] = GEN_INT (7);
4886 return avr_out_sbxx_branch (insn, operands);
4888 [(set (attr "length")
4889 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4890 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4892 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4895 (set_attr "cc" "clobber")])
4897 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4898 (define_insn "*sbix_branch_tmp"
4901 (match_operator 0 "eqne_operator"
4903 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
4905 (match_operand 2 "const_int_operand" "n"))
4907 (label_ref (match_operand 3 "" ""))
4910 "* return avr_out_sbxx_branch (insn, operands);"
4911 [(set (attr "length")
4912 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4913 (le (minus (pc) (match_dup 3)) (const_int 2045)))
4915 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4918 (set_attr "cc" "clobber")])
4920 (define_insn "*sbix_branch_tmp_bit7"
4923 (match_operator 0 "gelt_operator"
4924 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
4926 (label_ref (match_operand 2 "" ""))
4930 operands[3] = operands[2];
4931 operands[2] = GEN_INT (7);
4932 return avr_out_sbxx_branch (insn, operands);
4934 [(set (attr "length")
4935 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4936 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4938 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4941 (set_attr "cc" "clobber")])
4943 ;; ************************* Peepholes ********************************
4946 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
4947 (plus:SI (match_dup 0)
4949 (clobber (scratch:QI))])
4950 (parallel [(set (cc0)
4951 (compare (match_dup 0)
4953 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4955 (if_then_else (ne (cc0)
4957 (label_ref (match_operand 2 "" ""))
4962 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4963 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
4964 AS2 (sbc,%C0,__zero_reg__) CR_TAB
4965 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
4967 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
4968 AS2 (sbc,%B0,__zero_reg__) CR_TAB
4969 AS2 (sbc,%C0,__zero_reg__) CR_TAB
4970 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
4972 switch (avr_jump_mode (operands[2], insn))
4975 return AS1 (brcc,%2);
4977 return (AS1 (brcs,.+2) CR_TAB
4981 return (AS1 (brcs,.+4) CR_TAB
4986 [(set (match_operand:HI 0 "d_register_operand" "")
4987 (plus:HI (match_dup 0)
4991 (compare (match_dup 0)
4993 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4995 (if_then_else (ne (cc0) (const_int 0))
4996 (label_ref (match_operand 2 "" ""))
5002 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5003 output_asm_insn (AS2 (sbiw,%0,1), operands);
5005 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
5006 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
5007 switch (avr_jump_mode (operands[2],insn))
5010 return AS1 (brcc,%2);
5012 return (AS1 (brcs,.+2) CR_TAB
5015 return (AS1 (brcs,.+4) CR_TAB
5020 [(set (match_operand:QI 0 "d_register_operand" "")
5021 (plus:QI (match_dup 0)
5024 (compare (match_dup 0)
5027 (if_then_else (ne (cc0) (const_int 0))
5028 (label_ref (match_operand 1 "" ""))
5034 cc_status.value1 = operands[0];
5035 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5036 output_asm_insn (AS2 (subi,%A0,1), operands);
5037 switch (avr_jump_mode (operands[1],insn))
5040 return AS1 (brcc,%1);
5042 return (AS1 (brcs,.+2) CR_TAB
5045 return (AS1 (brcs,.+4) CR_TAB
5051 (compare (match_operand:QI 0 "register_operand" "")
5054 (if_then_else (eq (cc0) (const_int 0))
5055 (label_ref (match_operand 1 "" ""))
5057 "jump_over_one_insn_p (insn, operands[1])"
5058 "cpse %0,__zero_reg__")
5062 (compare (match_operand:QI 0 "register_operand" "")
5063 (match_operand:QI 1 "register_operand" "")))
5065 (if_then_else (eq (cc0) (const_int 0))
5066 (label_ref (match_operand 2 "" ""))
5068 "jump_over_one_insn_p (insn, operands[2])"
5071 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5072 ;;prologue/epilogue support instructions
5074 (define_insn "popqi"
5075 [(set (match_operand:QI 0 "register_operand" "=r")
5076 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5079 [(set_attr "cc" "none")
5080 (set_attr "length" "1")])
5082 ;; Enable Interrupts
5083 (define_insn "enable_interrupt"
5084 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
5087 [(set_attr "length" "1")
5088 (set_attr "cc" "none")])
5090 ;; Disable Interrupts
5091 (define_insn "disable_interrupt"
5092 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
5095 [(set_attr "length" "1")
5096 (set_attr "cc" "none")])
5098 ;; Library prologue saves
5099 (define_insn "call_prologue_saves"
5100 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5101 (match_operand:HI 0 "immediate_operand" "i,i")
5102 (set (reg:HI REG_SP)
5103 (minus:HI (reg:HI REG_SP)
5104 (match_operand:HI 1 "immediate_operand" "i,i")))
5105 (use (reg:HI REG_X))
5106 (clobber (reg:HI REG_Z))]
5108 "ldi r30,lo8(gs(1f))
5110 %~jmp __prologue_saves__+((18 - %0) * 2)
5112 [(set_attr "length" "5,6")
5113 (set_attr "cc" "clobber")
5114 (set_attr "isa" "rjmp,jmp")])
5116 ; epilogue restores using library
5117 (define_insn "epilogue_restores"
5118 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5120 (plus:HI (reg:HI REG_Y)
5121 (match_operand:HI 0 "immediate_operand" "i,i")))
5122 (set (reg:HI REG_SP)
5123 (plus:HI (reg:HI REG_Y)
5125 (clobber (reg:QI REG_Z))]
5128 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5129 [(set_attr "length" "2,3")
5130 (set_attr "cc" "clobber")
5131 (set_attr "isa" "rjmp,jmp")])
5134 (define_insn "return"
5136 "reload_completed && avr_simple_epilogue ()"
5138 [(set_attr "cc" "none")
5139 (set_attr "length" "1")])
5141 (define_insn "return_from_epilogue"
5145 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5146 && !cfun->machine->is_naked)"
5148 [(set_attr "cc" "none")
5149 (set_attr "length" "1")])
5151 (define_insn "return_from_interrupt_epilogue"
5155 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5156 && !cfun->machine->is_naked)"
5158 [(set_attr "cc" "none")
5159 (set_attr "length" "1")])
5161 (define_insn "return_from_naked_epilogue"
5165 && cfun->machine->is_naked)"
5167 [(set_attr "cc" "none")
5168 (set_attr "length" "0")])
5170 (define_expand "prologue"
5178 (define_expand "epilogue"
5182 expand_epilogue (false /* sibcall_p */);
5186 (define_expand "sibcall_epilogue"
5190 expand_epilogue (true /* sibcall_p */);
5194 ;; Some instructions resp. instruction sequences available
5197 (define_insn "delay_cycles_1"
5198 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5200 UNSPECV_DELAY_CYCLES)
5201 (clobber (match_scratch:QI 1 "=&d"))]
5206 [(set_attr "length" "3")
5207 (set_attr "cc" "clobber")])
5209 (define_insn "delay_cycles_2"
5210 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5212 UNSPECV_DELAY_CYCLES)
5213 (clobber (match_scratch:HI 1 "=&w"))]
5219 [(set_attr "length" "4")
5220 (set_attr "cc" "clobber")])
5222 (define_insn "delay_cycles_3"
5223 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5225 UNSPECV_DELAY_CYCLES)
5226 (clobber (match_scratch:QI 1 "=&d"))
5227 (clobber (match_scratch:QI 2 "=&d"))
5228 (clobber (match_scratch:QI 3 "=&d"))]
5237 [(set_attr "length" "7")
5238 (set_attr "cc" "clobber")])
5240 (define_insn "delay_cycles_4"
5241 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5243 UNSPECV_DELAY_CYCLES)
5244 (clobber (match_scratch:QI 1 "=&d"))
5245 (clobber (match_scratch:QI 2 "=&d"))
5246 (clobber (match_scratch:QI 3 "=&d"))
5247 (clobber (match_scratch:QI 4 "=&d"))]
5258 [(set_attr "length" "9")
5259 (set_attr "cc" "clobber")])
5261 (define_insn "map_bitsqi"
5262 [(set (match_operand:QI 0 "register_operand" "=d")
5263 (unspec:QI [(match_operand:SI 1 "const_int_operand" "n")
5264 (match_operand:QI 2 "register_operand" "r")]
5268 return avr_out_map_bits (insn, operands, NULL);
5270 [(set_attr "adjust_len" "map_bits")
5271 (set_attr "cc" "clobber")])
5273 (define_insn "map_bitshi"
5274 [(set (match_operand:HI 0 "register_operand" "=&r")
5275 (unspec:HI [(match_operand:DI 1 "const_double_operand" "n")
5276 (match_operand:HI 2 "register_operand" "r")]
5280 return avr_out_map_bits (insn, operands, NULL);
5282 [(set_attr "adjust_len" "map_bits")
5283 (set_attr "cc" "clobber")])
5288 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5289 ;; better 8-bit parity recognition.
5291 (define_expand "parityhi2"
5292 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5293 (parity:HI (match_operand:HI 1 "register_operand" "")))
5294 (clobber (reg:HI 24))])])
5296 (define_insn_and_split "*parityhi2"
5297 [(set (match_operand:HI 0 "register_operand" "=r")
5298 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5299 (clobber (reg:HI 24))]
5301 { gcc_unreachable(); }
5306 (parity:HI (reg:HI 24)))
5310 (define_insn_and_split "*parityqihi2"
5311 [(set (match_operand:HI 0 "register_operand" "=r")
5312 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5313 (clobber (reg:HI 24))]
5315 { gcc_unreachable(); }
5320 (zero_extend:HI (parity:QI (reg:QI 24))))
5324 (define_expand "paritysi2"
5326 (match_operand:SI 1 "register_operand" ""))
5328 (truncate:HI (parity:SI (reg:SI 22))))
5331 (set (match_operand:SI 0 "register_operand" "")
5332 (zero_extend:SI (match_dup 2)))]
5335 operands[2] = gen_reg_rtx (HImode);
5338 (define_insn "*parityhi2.libgcc"
5340 (parity:HI (reg:HI 24)))]
5342 "%~call __parityhi2"
5343 [(set_attr "type" "xcall")
5344 (set_attr "cc" "clobber")])
5346 (define_insn "*parityqihi2.libgcc"
5348 (zero_extend:HI (parity:QI (reg:QI 24))))]
5350 "%~call __parityqi2"
5351 [(set_attr "type" "xcall")
5352 (set_attr "cc" "clobber")])
5354 (define_insn "*paritysihi2.libgcc"
5356 (truncate:HI (parity:SI (reg:SI 22))))]
5358 "%~call __paritysi2"
5359 [(set_attr "type" "xcall")
5360 (set_attr "cc" "clobber")])
5365 (define_expand "popcounthi2"
5367 (match_operand:HI 1 "register_operand" ""))
5369 (popcount:HI (reg:HI 24)))
5370 (set (match_operand:HI 0 "register_operand" "")
5375 (define_expand "popcountsi2"
5377 (match_operand:SI 1 "register_operand" ""))
5379 (truncate:HI (popcount:SI (reg:SI 22))))
5382 (set (match_operand:SI 0 "register_operand" "")
5383 (zero_extend:SI (match_dup 2)))]
5386 operands[2] = gen_reg_rtx (HImode);
5389 (define_insn "*popcounthi2.libgcc"
5391 (popcount:HI (reg:HI 24)))]
5393 "%~call __popcounthi2"
5394 [(set_attr "type" "xcall")
5395 (set_attr "cc" "clobber")])
5397 (define_insn "*popcountsi2.libgcc"
5399 (truncate:HI (popcount:SI (reg:SI 22))))]
5401 "%~call __popcountsi2"
5402 [(set_attr "type" "xcall")
5403 (set_attr "cc" "clobber")])
5405 (define_insn "*popcountqi2.libgcc"
5407 (popcount:QI (reg:QI 24)))]
5409 "%~call __popcountqi2"
5410 [(set_attr "type" "xcall")
5411 (set_attr "cc" "clobber")])
5413 (define_insn_and_split "*popcountqihi2.libgcc"
5415 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5420 (popcount:QI (reg:QI 24)))
5425 ;; Count Leading Zeros
5427 (define_expand "clzhi2"
5429 (match_operand:HI 1 "register_operand" ""))
5430 (parallel [(set (reg:HI 24)
5431 (clz:HI (reg:HI 24)))
5432 (clobber (reg:QI 26))])
5433 (set (match_operand:HI 0 "register_operand" "")
5438 (define_expand "clzsi2"
5440 (match_operand:SI 1 "register_operand" ""))
5441 (parallel [(set (reg:HI 24)
5442 (truncate:HI (clz:SI (reg:SI 22))))
5443 (clobber (reg:QI 26))])
5446 (set (match_operand:SI 0 "register_operand" "")
5447 (zero_extend:SI (match_dup 2)))]
5450 operands[2] = gen_reg_rtx (HImode);
5453 (define_insn "*clzhi2.libgcc"
5455 (clz:HI (reg:HI 24)))
5456 (clobber (reg:QI 26))]
5459 [(set_attr "type" "xcall")
5460 (set_attr "cc" "clobber")])
5462 (define_insn "*clzsihi2.libgcc"
5464 (truncate:HI (clz:SI (reg:SI 22))))
5465 (clobber (reg:QI 26))]
5468 [(set_attr "type" "xcall")
5469 (set_attr "cc" "clobber")])
5471 ;; Count Trailing Zeros
5473 (define_expand "ctzhi2"
5475 (match_operand:HI 1 "register_operand" ""))
5476 (parallel [(set (reg:HI 24)
5477 (ctz:HI (reg:HI 24)))
5478 (clobber (reg:QI 26))])
5479 (set (match_operand:HI 0 "register_operand" "")
5484 (define_expand "ctzsi2"
5486 (match_operand:SI 1 "register_operand" ""))
5487 (parallel [(set (reg:HI 24)
5488 (truncate:HI (ctz:SI (reg:SI 22))))
5489 (clobber (reg:QI 22))
5490 (clobber (reg:QI 26))])
5493 (set (match_operand:SI 0 "register_operand" "")
5494 (zero_extend:SI (match_dup 2)))]
5497 operands[2] = gen_reg_rtx (HImode);
5500 (define_insn "*ctzhi2.libgcc"
5502 (ctz:HI (reg:HI 24)))
5503 (clobber (reg:QI 26))]
5506 [(set_attr "type" "xcall")
5507 (set_attr "cc" "clobber")])
5509 (define_insn "*ctzsihi2.libgcc"
5511 (truncate:HI (ctz:SI (reg:SI 22))))
5512 (clobber (reg:QI 22))
5513 (clobber (reg:QI 26))]
5516 [(set_attr "type" "xcall")
5517 (set_attr "cc" "clobber")])
5521 (define_expand "ffshi2"
5523 (match_operand:HI 1 "register_operand" ""))
5524 (parallel [(set (reg:HI 24)
5525 (ffs:HI (reg:HI 24)))
5526 (clobber (reg:QI 26))])
5527 (set (match_operand:HI 0 "register_operand" "")
5532 (define_expand "ffssi2"
5534 (match_operand:SI 1 "register_operand" ""))
5535 (parallel [(set (reg:HI 24)
5536 (truncate:HI (ffs:SI (reg:SI 22))))
5537 (clobber (reg:QI 22))
5538 (clobber (reg:QI 26))])
5541 (set (match_operand:SI 0 "register_operand" "")
5542 (zero_extend:SI (match_dup 2)))]
5545 operands[2] = gen_reg_rtx (HImode);
5548 (define_insn "*ffshi2.libgcc"
5550 (ffs:HI (reg:HI 24)))
5551 (clobber (reg:QI 26))]
5554 [(set_attr "type" "xcall")
5555 (set_attr "cc" "clobber")])
5557 (define_insn "*ffssihi2.libgcc"
5559 (truncate:HI (ffs:SI (reg:SI 22))))
5560 (clobber (reg:QI 22))
5561 (clobber (reg:QI 26))]
5564 [(set_attr "type" "xcall")
5565 (set_attr "cc" "clobber")])
5569 (define_insn "copysignsf3"
5570 [(set (match_operand:SF 0 "register_operand" "=r")
5571 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5572 (match_operand:SF 2 "register_operand" "r")]
5575 "bst %D2,7\;bld %D0,7"
5576 [(set_attr "length" "2")
5577 (set_attr "cc" "none")])
5579 ;; Swap Bytes (change byte-endianess)
5581 (define_expand "bswapsi2"
5583 (match_operand:SI 1 "register_operand" ""))
5585 (bswap:SI (reg:SI 22)))
5586 (set (match_operand:SI 0 "register_operand" "")
5591 (define_insn "*bswapsi2.libgcc"
5593 (bswap:SI (reg:SI 22)))]
5596 [(set_attr "type" "xcall")
5597 (set_attr "cc" "clobber")])
5602 ;; NOP taking 1 or 2 Ticks
5604 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5610 [(set_attr "length" "1")
5611 (set_attr "cc" "none")])
5614 (define_insn "sleep"
5615 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
5618 [(set_attr "length" "1")
5619 (set_attr "cc" "none")])
5623 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
5626 [(set_attr "length" "1")
5627 (set_attr "cc" "none")])
5630 (define_expand "fmul"
5632 (match_operand:QI 1 "register_operand" ""))
5634 (match_operand:QI 2 "register_operand" ""))
5635 (parallel [(set (reg:HI 22)
5636 (unspec:HI [(reg:QI 24)
5637 (reg:QI 25)] UNSPEC_FMUL))
5638 (clobber (reg:HI 24))])
5639 (set (match_operand:HI 0 "register_operand" "")
5645 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
5650 (define_insn "fmul_insn"
5651 [(set (match_operand:HI 0 "register_operand" "=r")
5652 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5653 (match_operand:QI 2 "register_operand" "a")]
5659 [(set_attr "length" "3")
5660 (set_attr "cc" "clobber")])
5662 (define_insn "*fmul.call"
5664 (unspec:HI [(reg:QI 24)
5665 (reg:QI 25)] UNSPEC_FMUL))
5666 (clobber (reg:HI 24))]
5669 [(set_attr "type" "xcall")
5670 (set_attr "cc" "clobber")])
5673 (define_expand "fmuls"
5675 (match_operand:QI 1 "register_operand" ""))
5677 (match_operand:QI 2 "register_operand" ""))
5678 (parallel [(set (reg:HI 22)
5679 (unspec:HI [(reg:QI 24)
5680 (reg:QI 25)] UNSPEC_FMULS))
5681 (clobber (reg:HI 24))])
5682 (set (match_operand:HI 0 "register_operand" "")
5688 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
5693 (define_insn "fmuls_insn"
5694 [(set (match_operand:HI 0 "register_operand" "=r")
5695 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5696 (match_operand:QI 2 "register_operand" "a")]
5702 [(set_attr "length" "3")
5703 (set_attr "cc" "clobber")])
5705 (define_insn "*fmuls.call"
5707 (unspec:HI [(reg:QI 24)
5708 (reg:QI 25)] UNSPEC_FMULS))
5709 (clobber (reg:HI 24))]
5712 [(set_attr "type" "xcall")
5713 (set_attr "cc" "clobber")])
5716 (define_expand "fmulsu"
5718 (match_operand:QI 1 "register_operand" ""))
5720 (match_operand:QI 2 "register_operand" ""))
5721 (parallel [(set (reg:HI 22)
5722 (unspec:HI [(reg:QI 24)
5723 (reg:QI 25)] UNSPEC_FMULSU))
5724 (clobber (reg:HI 24))])
5725 (set (match_operand:HI 0 "register_operand" "")
5731 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
5736 (define_insn "fmulsu_insn"
5737 [(set (match_operand:HI 0 "register_operand" "=r")
5738 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5739 (match_operand:QI 2 "register_operand" "a")]
5745 [(set_attr "length" "3")
5746 (set_attr "cc" "clobber")])
5748 (define_insn "*fmulsu.call"
5750 (unspec:HI [(reg:QI 24)
5751 (reg:QI 25)] UNSPEC_FMULSU))
5752 (clobber (reg:HI 24))]
5755 [(set_attr "type" "xcall")
5756 (set_attr "cc" "clobber")])
5759 ;; Some combiner patterns dealing with bits.
5762 ;; Move bit $3.0 into bit $0.$4
5763 (define_insn "*movbitqi.1-6.a"
5764 [(set (match_operand:QI 0 "register_operand" "=r")
5765 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5766 (match_operand:QI 2 "single_zero_operand" "n"))
5767 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
5768 (match_operand:QI 4 "const_0_to_7_operand" "n"))
5769 (match_operand:QI 5 "single_one_operand" "n"))))]
5770 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
5771 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
5772 "bst %3,0\;bld %0,%4"
5773 [(set_attr "length" "2")
5774 (set_attr "cc" "none")])
5776 ;; Move bit $3.0 into bit $0.$4
5777 ;; Variation of above. Unfortunately, there is no canonicalized representation
5778 ;; of moving around bits. So what we see here depends on how user writes down
5779 ;; bit manipulations.
5780 (define_insn "*movbitqi.1-6.b"
5781 [(set (match_operand:QI 0 "register_operand" "=r")
5782 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5783 (match_operand:QI 2 "single_zero_operand" "n"))
5784 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
5786 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
5787 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5788 "bst %3,0\;bld %0,%4"
5789 [(set_attr "length" "2")
5790 (set_attr "cc" "none")])
5792 ;; Move bit $3.0 into bit $0.0.
5793 ;; For bit 0, combiner generates slightly different pattern.
5794 (define_insn "*movbitqi.0"
5795 [(set (match_operand:QI 0 "register_operand" "=r")
5796 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5797 (match_operand:QI 2 "single_zero_operand" "n"))
5798 (and:QI (match_operand:QI 3 "register_operand" "r")
5800 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5801 "bst %3,0\;bld %0,0"
5802 [(set_attr "length" "2")
5803 (set_attr "cc" "none")])
5805 ;; Move bit $2.0 into bit $0.7.
5806 ;; For bit 7, combiner generates slightly different pattern
5807 (define_insn "*movbitqi.7"
5808 [(set (match_operand:QI 0 "register_operand" "=r")
5809 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5811 (ashift:QI (match_operand:QI 2 "register_operand" "r")
5814 "bst %2,0\;bld %0,7"
5815 [(set_attr "length" "2")
5816 (set_attr "cc" "none")])
5818 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
5819 ;; and input/output match. We provide a special pattern for this, because
5820 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
5821 ;; operation on I/O is atomic.
5822 (define_insn "*insv.io"
5823 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
5825 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
5826 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
5831 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
5832 [(set_attr "length" "1,1,4")
5833 (set_attr "cc" "none")])
5835 (define_insn "*insv.not.io"
5836 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5838 (match_operand:QI 1 "const_0_to_7_operand" "n"))
5839 (not:QI (match_operand:QI 2 "register_operand" "r")))]
5841 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
5842 [(set_attr "length" "4")
5843 (set_attr "cc" "none")])
5845 ;; The insv expander.
5846 ;; We only support 1-bit inserts
5847 (define_expand "insv"
5848 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
5849 (match_operand:QI 1 "const1_operand" "") ; width
5850 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
5851 (match_operand:QI 3 "nonmemory_operand" ""))]
5855 ;; Insert bit $2.0 into $0.$1
5856 (define_insn "*insv.reg"
5857 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
5859 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
5860 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
5864 andi %0,lo8(~(1<<%1))
5868 [(set_attr "length" "2,1,1,2,2")
5869 (set_attr "cc" "none,set_zn,set_zn,none,none")])
5872 ;; Some combine patterns that try to fix bad code when a value is composed
5873 ;; from byte parts like in PR27663.
5874 ;; The patterns give some release but the code still is not optimal,
5875 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
5876 ;; That switch obfuscates things here and in many other places.
5878 (define_insn_and_split "*ior<mode>qi.byte0"
5879 [(set (match_operand:HISI 0 "register_operand" "=r")
5881 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5882 (match_operand:HISI 2 "register_operand" "0")))]
5887 (ior:QI (match_dup 3)
5890 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
5893 (define_insn_and_split "*ior<mode>qi.byte1-3"
5894 [(set (match_operand:HISI 0 "register_operand" "=r")
5896 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5897 (match_operand:QI 2 "const_8_16_24_operand" "n"))
5898 (match_operand:HISI 3 "register_operand" "0")))]
5899 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5901 "&& reload_completed"
5903 (ior:QI (match_dup 4)
5906 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
5907 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
5910 (define_expand "extzv"
5911 [(set (match_operand:QI 0 "register_operand" "")
5912 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
5913 (match_operand:QI 2 "const1_operand" "")
5914 (match_operand:QI 3 "const_0_to_7_operand" "")))]
5918 (define_insn "*extzv"
5919 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
5920 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
5922 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
5926 mov %0,%1\;andi %0,1
5929 bst %1,%2\;clr %0\;bld %0,0"
5930 [(set_attr "length" "1,2,2,2,3")
5931 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
5933 (define_insn_and_split "*extzv.qihi1"
5934 [(set (match_operand:HI 0 "register_operand" "=r")
5935 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
5937 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
5942 (zero_extract:QI (match_dup 1)
5948 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5949 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5952 (include "avr-dimode.md")
5954 (define_insn_and_split "*extzv.qihi2"
5955 [(set (match_operand:HI 0 "register_operand" "=r")
5957 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
5959 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
5964 (zero_extract:QI (match_dup 1)
5970 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5971 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);