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,ldi"
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" "ldi,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)