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_FLASH);
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_xload_libgcc_p (QImode)
394 && avr_mem_memx_p (operands[1])
395 && REG_P (XEXP (operands[1], 0))"
396 { gcc_unreachable(); }
398 [(clobber (const_int 0))]
400 rtx insn, addr = XEXP (operands[1], 0);
401 rtx hi8 = gen_reg_rtx (QImode);
402 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
404 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
405 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
407 insn = emit_insn (gen_xload_8 (operands[0], hi8));
408 set_mem_addr_space (SET_SRC (single_set (insn)),
409 MEM_ADDR_SPACE (operands[1]));
413 (define_insn_and_split "xload<mode>_A"
414 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
415 (match_operand:MOVMODE 1 "memory_operand" "m"))
416 (clobber (reg:QI 21))
417 (clobber (reg:HI REG_Z))]
418 "can_create_pseudo_p()
419 && avr_mem_memx_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 /* Split the address to R21:Z */
432 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
433 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
435 /* Load with code from libgcc */
436 insn = emit_insn (gen_xload_<mode>_libgcc ());
437 set_mem_addr_space (SET_SRC (single_set (insn)), as);
439 /* Move to destination */
440 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
445 ;; Move value from address space memx to a register
446 ;; These insns must be prior to respective generic move insn.
448 (define_insn "xload_8"
449 [(set (match_operand:QI 0 "register_operand" "=&r,r")
450 (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
452 "!avr_xload_libgcc_p (QImode)"
454 return avr_out_xload (insn, operands, NULL);
456 [(set_attr "length" "3,4")
457 (set_attr "adjust_len" "*,xload")
458 (set_attr "isa" "lpmx,lpm")
459 (set_attr "cc" "none")])
463 ;; "xload_psi_libgcc"
466 (define_insn "xload_<mode>_libgcc"
467 [(set (reg:MOVMODE 22)
468 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
470 (clobber (reg:QI 21))
471 (clobber (reg:HI REG_Z))]
472 "avr_xload_libgcc_p (<MODE>mode)"
474 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
476 output_asm_insn ("%~call __xload_%0", &x_bytes);
479 [(set_attr "type" "xcall")
480 (set_attr "cc" "clobber")])
483 ;; General move expanders
490 (define_expand "mov<mode>"
491 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
492 (match_operand:MOVMODE 1 "general_operand" ""))]
495 rtx dest = operands[0];
496 rtx src = operands[1];
498 if (avr_mem_flash_p (dest))
501 /* One of the operands has to be in a register. */
502 if (!register_operand (dest, <MODE>mode)
503 && !(register_operand (src, <MODE>mode)
504 || src == CONST0_RTX (<MODE>mode)))
506 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
509 if (avr_mem_memx_p (src))
511 rtx addr = XEXP (src, 0);
514 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
516 if (!avr_xload_libgcc_p (<MODE>mode))
517 emit_insn (gen_xload8_A (dest, src));
519 emit_insn (gen_xload<mode>_A (dest, src));
524 if (avr_load_libgcc_p (src))
526 /* For the small devices, do loads per libgcc call. */
527 emit_insn (gen_load<mode>_libgcc (dest, src));
532 ;;========================================================================
534 ;; The last alternative (any immediate constant to any register) is
535 ;; very expensive. It should be optimized by peephole2 if a scratch
536 ;; register is available, but then that register could just as well be
537 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
538 ;; are call-saved registers, and most of LD_REGS are call-used registers,
539 ;; so this may still be a win for registers live across function calls.
541 (define_insn "movqi_insn"
542 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
543 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
544 "register_operand (operands[0], QImode)
545 || register_operand (operands[1], QImode)
546 || const0_rtx == operands[1]"
548 return output_movqi (insn, operands, NULL);
550 [(set_attr "length" "1,1,5,5,1,1,4")
551 (set_attr "adjust_len" "mov8")
552 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
554 ;; This is used in peephole2 to optimize loading immediate constants
555 ;; if a scratch register from LD_REGS happens to be available.
557 (define_insn "*reload_inqi"
558 [(set (match_operand:QI 0 "register_operand" "=l")
559 (match_operand:QI 1 "immediate_operand" "i"))
560 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
564 [(set_attr "length" "2")
565 (set_attr "cc" "none")])
568 [(match_scratch:QI 2 "d")
569 (set (match_operand:QI 0 "l_register_operand" "")
570 (match_operand:QI 1 "immediate_operand" ""))]
571 "(operands[1] != const0_rtx
572 && operands[1] != const1_rtx
573 && operands[1] != constm1_rtx)"
574 [(parallel [(set (match_dup 0) (match_dup 1))
575 (clobber (match_dup 2))])]
578 ;;============================================================================
579 ;; move word (16 bit)
581 ;; Move register $1 to the Stack Pointer register SP.
582 ;; This insn is emit during function prologue/epilogue generation.
583 ;; $2 = 0: We know that IRQs are off
584 ;; $2 = 1: We know that IRQs are on
585 ;; Remaining cases when the state of the I-Flag is unknown are
586 ;; handled by generic movhi insn.
588 (define_insn "movhi_sp_r"
589 [(set (match_operand:HI 0 "stack_register_operand" "=q,q")
590 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r")
591 (match_operand:HI 2 "const_int_operand" "L,P")]
595 out __SP_H__,%B1\;out __SP_L__,%A1
596 cli\;out __SP_H__,%B1\;sei\;out __SP_L__,%A1"
597 [(set_attr "length" "2,4")
598 (set_attr "cc" "none")])
601 [(match_scratch:QI 2 "d")
602 (set (match_operand:HI 0 "l_register_operand" "")
603 (match_operand:HI 1 "immediate_operand" ""))]
604 "(operands[1] != const0_rtx
605 && operands[1] != constm1_rtx)"
606 [(parallel [(set (match_dup 0) (match_dup 1))
607 (clobber (match_dup 2))])]
610 ;; '*' because it is not used in rtl generation, only in above peephole
611 (define_insn "*reload_inhi"
612 [(set (match_operand:HI 0 "register_operand" "=r")
613 (match_operand:HI 1 "immediate_operand" "i"))
614 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
617 return output_reload_inhi (operands, operands[2], NULL);
619 [(set_attr "length" "4")
620 (set_attr "adjust_len" "reload_in16")
621 (set_attr "cc" "none")])
623 (define_insn "*movhi"
624 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
625 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
626 "register_operand (operands[0], HImode)
627 || register_operand (operands[1], HImode)
628 || const0_rtx == operands[1]"
630 return output_movhi (insn, operands, NULL);
632 [(set_attr "length" "2,2,6,7,2,6,5,2")
633 (set_attr "adjust_len" "mov16")
634 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
636 (define_peephole2 ; movw
637 [(set (match_operand:QI 0 "even_register_operand" "")
638 (match_operand:QI 1 "even_register_operand" ""))
639 (set (match_operand:QI 2 "odd_register_operand" "")
640 (match_operand:QI 3 "odd_register_operand" ""))]
642 && REGNO (operands[0]) == REGNO (operands[2]) - 1
643 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
644 [(set (match_dup 4) (match_dup 5))]
646 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
647 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
650 (define_peephole2 ; movw_r
651 [(set (match_operand:QI 0 "odd_register_operand" "")
652 (match_operand:QI 1 "odd_register_operand" ""))
653 (set (match_operand:QI 2 "even_register_operand" "")
654 (match_operand:QI 3 "even_register_operand" ""))]
656 && REGNO (operands[2]) == REGNO (operands[0]) - 1
657 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
658 [(set (match_dup 4) (match_dup 5))]
660 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
661 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
664 ;; For LPM loads from AS1 we split
668 ;; Z = Z - sizeof (R)
670 ;; so that the second instruction can be optimized out.
672 (define_split ; "split-lpmx"
673 [(set (match_operand:HISI 0 "register_operand" "")
674 (match_operand:HISI 1 "memory_operand" ""))]
680 (plus:HI (match_dup 3)
683 rtx addr = XEXP (operands[1], 0);
685 if (!avr_mem_flash_p (operands[1])
687 || reg_overlap_mentioned_p (addr, operands[0]))
692 operands[2] = replace_equiv_address (operands[1],
693 gen_rtx_POST_INC (Pmode, addr));
695 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
698 ;;==========================================================================
699 ;; xpointer move (24 bit)
701 (define_peephole2 ; *reload_inpsi
702 [(match_scratch:QI 2 "d")
703 (set (match_operand:PSI 0 "l_register_operand" "")
704 (match_operand:PSI 1 "immediate_operand" ""))
706 "operands[1] != const0_rtx
707 && operands[1] != constm1_rtx"
708 [(parallel [(set (match_dup 0)
710 (clobber (match_dup 2))])]
713 ;; '*' because it is not used in rtl generation.
714 (define_insn "*reload_inpsi"
715 [(set (match_operand:PSI 0 "register_operand" "=r")
716 (match_operand:PSI 1 "immediate_operand" "i"))
717 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
720 return avr_out_reload_inpsi (operands, operands[2], NULL);
722 [(set_attr "length" "6")
723 (set_attr "adjust_len" "reload_in24")
724 (set_attr "cc" "clobber")])
726 (define_insn "*movpsi"
727 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
728 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
729 "register_operand (operands[0], PSImode)
730 || register_operand (operands[1], PSImode)
731 || const0_rtx == operands[1]"
733 return avr_out_movpsi (insn, operands, NULL);
735 [(set_attr "length" "3,3,8,9,4,10")
736 (set_attr "adjust_len" "mov24")
737 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
739 ;;==========================================================================
740 ;; move double word (32 bit)
742 (define_peephole2 ; *reload_insi
743 [(match_scratch:QI 2 "d")
744 (set (match_operand:SI 0 "l_register_operand" "")
745 (match_operand:SI 1 "const_int_operand" ""))
747 "(operands[1] != const0_rtx
748 && operands[1] != constm1_rtx)"
749 [(parallel [(set (match_dup 0) (match_dup 1))
750 (clobber (match_dup 2))])]
753 ;; '*' because it is not used in rtl generation.
754 (define_insn "*reload_insi"
755 [(set (match_operand:SI 0 "register_operand" "=r")
756 (match_operand:SI 1 "const_int_operand" "n"))
757 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
760 return output_reload_insisf (operands, operands[2], NULL);
762 [(set_attr "length" "8")
763 (set_attr "adjust_len" "reload_in32")
764 (set_attr "cc" "clobber")])
767 (define_insn "*movsi"
768 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
769 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
770 "register_operand (operands[0], SImode)
771 || register_operand (operands[1], SImode)
772 || const0_rtx == operands[1]"
774 return output_movsisf (insn, operands, NULL);
776 [(set_attr "length" "4,4,8,9,4,10")
777 (set_attr "adjust_len" "mov32")
778 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
780 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
781 ;; move floating point numbers (32 bit)
783 (define_insn "*movsf"
784 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
785 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
786 "register_operand (operands[0], SFmode)
787 || register_operand (operands[1], SFmode)
788 || operands[1] == CONST0_RTX (SFmode)"
790 return output_movsisf (insn, operands, NULL);
792 [(set_attr "length" "4,4,8,9,4,10")
793 (set_attr "adjust_len" "mov32")
794 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
796 (define_peephole2 ; *reload_insf
797 [(match_scratch:QI 2 "d")
798 (set (match_operand:SF 0 "l_register_operand" "")
799 (match_operand:SF 1 "const_double_operand" ""))
801 "operands[1] != CONST0_RTX (SFmode)"
802 [(parallel [(set (match_dup 0)
804 (clobber (match_dup 2))])]
807 ;; '*' because it is not used in rtl generation.
808 (define_insn "*reload_insf"
809 [(set (match_operand:SF 0 "register_operand" "=r")
810 (match_operand:SF 1 "const_double_operand" "F"))
811 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
814 return output_reload_insisf (operands, operands[2], NULL);
816 [(set_attr "length" "8")
817 (set_attr "adjust_len" "reload_in32")
818 (set_attr "cc" "clobber")])
820 ;;=========================================================================
821 ;; move string (like memcpy)
823 (define_expand "movmemhi"
824 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
825 (match_operand:BLK 1 "memory_operand" ""))
826 (use (match_operand:HI 2 "const_int_operand" ""))
827 (use (match_operand:HI 3 "const_int_operand" ""))])]
830 if (avr_emit_movmemhi (operands))
836 (define_mode_attr MOVMEM_r_d [(QI "r")
839 ;; $0, $4 : & dest (REG_X)
840 ;; $1, $5 : & src (REG_Z)
841 ;; $2 : Address Space
842 ;; $3, $7 : Loop register
843 ;; $6 : Scratch register
847 (define_insn "movmem_<mode>"
848 [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
849 (mem:BLK (match_operand:HI 1 "register_operand" "z")))
850 (unspec [(match_operand:QI 2 "const_int_operand" "n")]
852 (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>"))
853 (clobber (match_operand:HI 4 "register_operand" "=0"))
854 (clobber (match_operand:HI 5 "register_operand" "=1"))
855 (clobber (match_operand:QI 6 "register_operand" "=&r"))
856 (clobber (match_operand:QIHI 7 "register_operand" "=3"))]
859 return avr_out_movmem (insn, operands, NULL);
861 [(set_attr "adjust_len" "movmem")
862 (set_attr "cc" "clobber")])
865 ;; $3, $7 : Loop register = R24
866 ;; $8, $9 : hh8 (& src) = R23
871 (define_insn "movmemx_<mode>"
872 [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
873 (mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r")
874 (match_operand:HI 1 "register_operand" "z"))))
875 (unspec [(match_operand:QI 2 "const_int_operand" "n")]
877 (use (match_operand:QIHI 3 "register_operand" "w"))
878 (clobber (match_operand:HI 4 "register_operand" "=0"))
879 (clobber (match_operand:HI 5 "register_operand" "=1"))
880 (clobber (match_operand:QI 6 "register_operand" "=&r"))
881 (clobber (match_operand:HI 7 "register_operand" "=3"))
882 (clobber (match_operand:QI 9 "register_operand" "=8"))
883 (clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))]
885 "%~call __movmemx_<mode>"
886 [(set_attr "type" "xcall")
887 (set_attr "cc" "clobber")])
890 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
891 ;; memset (%0, %2, %1)
893 (define_expand "setmemhi"
894 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
895 (match_operand 2 "const_int_operand" ""))
896 (use (match_operand:HI 1 "const_int_operand" ""))
897 (use (match_operand:HI 3 "const_int_operand" ""))
898 (clobber (match_scratch:HI 4 ""))
899 (clobber (match_dup 5))])]
903 enum machine_mode mode;
905 /* If value to set is not zero, use the library routine. */
906 if (operands[2] != const0_rtx)
909 if (!CONST_INT_P (operands[1]))
912 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
913 operands[5] = gen_rtx_SCRATCH (mode);
914 operands[1] = copy_to_mode_reg (mode,
915 gen_int_mode (INTVAL (operands[1]), mode));
916 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
917 operands[0] = gen_rtx_MEM (BLKmode, addr0);
921 (define_insn "*clrmemqi"
922 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
924 (use (match_operand:QI 1 "register_operand" "r"))
925 (use (match_operand:QI 2 "const_int_operand" "n"))
926 (clobber (match_scratch:HI 3 "=0"))
927 (clobber (match_scratch:QI 4 "=&1"))]
929 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
930 [(set_attr "length" "3")
931 (set_attr "cc" "clobber")])
934 (define_insn "*clrmemhi"
935 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
937 (use (match_operand:HI 1 "register_operand" "!w,d"))
938 (use (match_operand:HI 2 "const_int_operand" "n,n"))
939 (clobber (match_scratch:HI 3 "=0,0"))
940 (clobber (match_scratch:HI 4 "=&1,&1"))]
943 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
944 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
945 [(set_attr "length" "3,4")
946 (set_attr "cc" "clobber,clobber")])
948 (define_expand "strlenhi"
950 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
951 (match_operand:QI 2 "const_int_operand" "")
952 (match_operand:HI 3 "immediate_operand" "")]
955 (plus:HI (match_dup 4)
957 (set (match_operand:HI 0 "register_operand" "")
958 (minus:HI (match_dup 4)
963 if (operands[2] != const0_rtx)
965 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
966 operands[1] = gen_rtx_MEM (BLKmode, addr);
968 operands[4] = gen_reg_rtx (HImode);
971 (define_insn "*strlenhi"
972 [(set (match_operand:HI 0 "register_operand" "=e")
973 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
975 (match_operand:HI 2 "immediate_operand" "i")]
978 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
979 [(set_attr "length" "3")
980 (set_attr "cc" "clobber")])
982 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
985 (define_insn "addqi3"
986 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
987 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
988 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
997 [(set_attr "length" "1,1,1,1,2,2")
998 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1001 (define_expand "addhi3"
1002 [(set (match_operand:HI 0 "register_operand" "")
1003 (plus:HI (match_operand:HI 1 "register_operand" "")
1004 (match_operand:HI 2 "nonmemory_operand" "")))]
1007 if (CONST_INT_P (operands[2]))
1009 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1011 if (can_create_pseudo_p()
1012 && !stack_register_operand (operands[0], HImode)
1013 && !stack_register_operand (operands[1], HImode)
1014 && !d_register_operand (operands[0], HImode)
1015 && !d_register_operand (operands[1], HImode))
1017 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1024 (define_insn "*addhi3_zero_extend"
1025 [(set (match_operand:HI 0 "register_operand" "=r")
1026 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1027 (match_operand:HI 2 "register_operand" "0")))]
1029 "add %A0,%1\;adc %B0,__zero_reg__"
1030 [(set_attr "length" "2")
1031 (set_attr "cc" "set_n")])
1033 (define_insn "*addhi3_zero_extend1"
1034 [(set (match_operand:HI 0 "register_operand" "=r")
1035 (plus:HI (match_operand:HI 1 "register_operand" "0")
1036 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1038 "add %A0,%2\;adc %B0,__zero_reg__"
1039 [(set_attr "length" "2")
1040 (set_attr "cc" "set_n")])
1042 (define_insn "*addhi3.sign_extend1"
1043 [(set (match_operand:HI 0 "register_operand" "=r")
1044 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1045 (match_operand:HI 2 "register_operand" "0")))]
1048 return reg_overlap_mentioned_p (operands[0], operands[1])
1049 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1050 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1052 [(set_attr "length" "5")
1053 (set_attr "cc" "clobber")])
1055 (define_insn "*addhi3_sp"
1056 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1057 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1058 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1061 return avr_out_addto_sp (operands, NULL);
1063 [(set_attr "length" "6")
1064 (set_attr "adjust_len" "addto_sp")])
1066 (define_insn "*addhi3"
1067 [(set (match_operand:HI 0 "register_operand" "=r,d,d")
1068 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1069 (match_operand:HI 2 "nonmemory_operand" "r,s,n")))]
1072 static const char * const asm_code[] =
1074 "add %A0,%A2\;adc %B0,%B2",
1075 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
1079 if (*asm_code[which_alternative])
1080 return asm_code[which_alternative];
1082 return avr_out_plus_noclobber (operands, NULL, NULL);
1084 [(set_attr "length" "2,2,2")
1085 (set_attr "adjust_len" "*,*,out_plus_noclobber")
1086 (set_attr "cc" "set_n,set_czn,out_plus_noclobber")])
1088 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1089 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1090 ;; itself because that insn is special to reload.
1092 (define_peephole2 ; addhi3_clobber
1093 [(set (match_operand:HI 0 "d_register_operand" "")
1094 (match_operand:HI 1 "const_int_operand" ""))
1095 (set (match_operand:HI 2 "l_register_operand" "")
1096 (plus:HI (match_dup 2)
1098 "peep2_reg_dead_p (2, operands[0])"
1099 [(parallel [(set (match_dup 2)
1100 (plus:HI (match_dup 2)
1102 (clobber (match_dup 3))])]
1104 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
1107 ;; Same, but with reload to NO_LD_REGS
1108 ;; Combine *reload_inhi with *addhi3
1110 (define_peephole2 ; addhi3_clobber
1111 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
1112 (match_operand:HI 1 "const_int_operand" ""))
1113 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1114 (set (match_operand:HI 3 "l_register_operand" "")
1115 (plus:HI (match_dup 3)
1117 "peep2_reg_dead_p (2, operands[0])"
1118 [(parallel [(set (match_dup 3)
1119 (plus:HI (match_dup 3)
1121 (clobber (match_dup 2))])])
1123 (define_insn "addhi3_clobber"
1124 [(set (match_operand:HI 0 "register_operand" "=d,l")
1125 (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
1126 (match_operand:HI 2 "const_int_operand" "n,n")))
1127 (clobber (match_scratch:QI 3 "=X,&d"))]
1130 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1132 return avr_out_plus (operands, NULL, NULL);
1134 [(set_attr "length" "4")
1135 (set_attr "adjust_len" "out_plus")
1136 (set_attr "cc" "out_plus")])
1139 (define_insn "addsi3"
1140 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1141 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1142 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1143 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1146 static const char * const asm_code[] =
1148 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
1149 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
1154 if (*asm_code[which_alternative])
1155 return asm_code [which_alternative];
1157 return avr_out_plus (operands, NULL, NULL);
1159 [(set_attr "length" "4,4,4,8")
1160 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1161 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1163 (define_insn "*addpsi3_zero_extend.qi"
1164 [(set (match_operand:PSI 0 "register_operand" "=r")
1165 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1166 (match_operand:PSI 2 "register_operand" "0")))]
1168 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1169 [(set_attr "length" "3")
1170 (set_attr "cc" "set_n")])
1172 (define_insn "*addpsi3_zero_extend.hi"
1173 [(set (match_operand:PSI 0 "register_operand" "=r")
1174 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1175 (match_operand:PSI 2 "register_operand" "0")))]
1177 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1178 [(set_attr "length" "3")
1179 (set_attr "cc" "set_n")])
1181 (define_insn "*addpsi3_sign_extend.hi"
1182 [(set (match_operand:PSI 0 "register_operand" "=r")
1183 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1184 (match_operand:PSI 2 "register_operand" "0")))]
1186 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1187 [(set_attr "length" "5")
1188 (set_attr "cc" "set_n")])
1190 (define_insn "*addsi3_zero_extend"
1191 [(set (match_operand:SI 0 "register_operand" "=r")
1192 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1193 (match_operand:SI 2 "register_operand" "0")))]
1195 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1196 [(set_attr "length" "4")
1197 (set_attr "cc" "set_n")])
1199 (define_insn "*addsi3_zero_extend.hi"
1200 [(set (match_operand:SI 0 "register_operand" "=r")
1201 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1202 (match_operand:SI 2 "register_operand" "0")))]
1204 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1205 [(set_attr "length" "4")
1206 (set_attr "cc" "set_n")])
1208 (define_insn "addpsi3"
1209 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1210 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1211 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1212 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1215 static const char * const asm_code[] =
1217 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1218 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1223 if (*asm_code[which_alternative])
1224 return asm_code [which_alternative];
1226 return avr_out_plus (operands, NULL, NULL);
1228 [(set_attr "length" "3,3,3,6")
1229 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1230 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1232 (define_insn "subpsi3"
1233 [(set (match_operand:PSI 0 "register_operand" "=r")
1234 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1235 (match_operand:PSI 2 "register_operand" "r")))]
1237 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1238 [(set_attr "length" "3")
1239 (set_attr "cc" "set_czn")])
1241 (define_insn "*subpsi3_zero_extend.qi"
1242 [(set (match_operand:PSI 0 "register_operand" "=r")
1243 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1244 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1246 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1247 [(set_attr "length" "3")
1248 (set_attr "cc" "set_czn")])
1250 (define_insn "*subpsi3_zero_extend.hi"
1251 [(set (match_operand:PSI 0 "register_operand" "=r")
1252 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1253 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1255 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1256 [(set_attr "length" "3")
1257 (set_attr "cc" "set_czn")])
1259 (define_insn "*subpsi3_sign_extend.hi"
1260 [(set (match_operand:PSI 0 "register_operand" "=r")
1261 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1262 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1264 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1265 [(set_attr "length" "5")
1266 (set_attr "cc" "set_czn")])
1268 ;-----------------------------------------------------------------------------
1270 (define_insn "subqi3"
1271 [(set (match_operand:QI 0 "register_operand" "=r,d")
1272 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1273 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1278 [(set_attr "length" "1,1")
1279 (set_attr "cc" "set_czn,set_czn")])
1281 (define_insn "subhi3"
1282 [(set (match_operand:HI 0 "register_operand" "=r,d")
1283 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1284 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1287 sub %A0,%A2\;sbc %B0,%B2
1288 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1289 [(set_attr "length" "2,2")
1290 (set_attr "cc" "set_czn,set_czn")])
1292 (define_insn "*subhi3_zero_extend1"
1293 [(set (match_operand:HI 0 "register_operand" "=r")
1294 (minus:HI (match_operand:HI 1 "register_operand" "0")
1295 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1297 "sub %A0,%2\;sbc %B0,__zero_reg__"
1298 [(set_attr "length" "2")
1299 (set_attr "cc" "set_czn")])
1301 (define_insn "*subhi3.sign_extend2"
1302 [(set (match_operand:HI 0 "register_operand" "=r")
1303 (minus:HI (match_operand:HI 1 "register_operand" "0")
1304 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1307 return reg_overlap_mentioned_p (operands[0], operands[2])
1308 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1309 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1311 [(set_attr "length" "5")
1312 (set_attr "cc" "clobber")])
1314 (define_insn "subsi3"
1315 [(set (match_operand:SI 0 "register_operand" "=r")
1316 (minus:SI (match_operand:SI 1 "register_operand" "0")
1317 (match_operand:SI 2 "register_operand" "r")))]
1319 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1320 [(set_attr "length" "4")
1321 (set_attr "cc" "set_czn")])
1323 (define_insn "*subsi3_zero_extend"
1324 [(set (match_operand:SI 0 "register_operand" "=r")
1325 (minus:SI (match_operand:SI 1 "register_operand" "0")
1326 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1328 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1329 [(set_attr "length" "4")
1330 (set_attr "cc" "set_czn")])
1332 (define_insn "*subsi3_zero_extend.hi"
1333 [(set (match_operand:SI 0 "register_operand" "=r")
1334 (minus:SI (match_operand:SI 1 "register_operand" "0")
1335 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1337 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1338 [(set_attr "length" "4")
1339 (set_attr "cc" "set_czn")])
1341 ;******************************************************************************
1344 (define_expand "mulqi3"
1345 [(set (match_operand:QI 0 "register_operand" "")
1346 (mult:QI (match_operand:QI 1 "register_operand" "")
1347 (match_operand:QI 2 "register_operand" "")))]
1352 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1357 (define_insn "*mulqi3_enh"
1358 [(set (match_operand:QI 0 "register_operand" "=r")
1359 (mult:QI (match_operand:QI 1 "register_operand" "r")
1360 (match_operand:QI 2 "register_operand" "r")))]
1365 [(set_attr "length" "3")
1366 (set_attr "cc" "clobber")])
1368 (define_expand "mulqi3_call"
1369 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1370 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1371 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1372 (clobber (reg:QI 22))])
1373 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1377 (define_insn "*mulqi3_call"
1378 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1379 (clobber (reg:QI 22))]
1382 [(set_attr "type" "xcall")
1383 (set_attr "cc" "clobber")])
1385 ;; "umulqi3_highpart"
1386 ;; "smulqi3_highpart"
1387 (define_insn "<extend_su>mulqi3_highpart"
1388 [(set (match_operand:QI 0 "register_operand" "=r")
1390 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1391 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1394 "mul<extend_s> %1,%2
1397 [(set_attr "length" "3")
1398 (set_attr "cc" "clobber")])
1401 ;; Used when expanding div or mod inline for some special values
1402 (define_insn "*subqi3.ashiftrt7"
1403 [(set (match_operand:QI 0 "register_operand" "=r")
1404 (minus:QI (match_operand:QI 1 "register_operand" "0")
1405 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1409 [(set_attr "length" "2")
1410 (set_attr "cc" "clobber")])
1412 (define_insn "*addqi3.lt0"
1413 [(set (match_operand:QI 0 "register_operand" "=r")
1414 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1416 (match_operand:QI 2 "register_operand" "0")))]
1419 [(set_attr "length" "2")
1420 (set_attr "cc" "clobber")])
1422 (define_insn "*addhi3.lt0"
1423 [(set (match_operand:HI 0 "register_operand" "=w,r")
1424 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1426 (match_operand:HI 2 "register_operand" "0,0")))
1427 (clobber (match_scratch:QI 3 "=X,&1"))]
1430 sbrc %1,7\;adiw %0,1
1431 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1432 [(set_attr "length" "2,3")
1433 (set_attr "cc" "clobber")])
1435 (define_insn "*addpsi3.lt0"
1436 [(set (match_operand:PSI 0 "register_operand" "=r")
1437 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1439 (match_operand:PSI 2 "register_operand" "0")))]
1441 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1442 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1443 [(set_attr "length" "5")
1444 (set_attr "cc" "clobber")])
1446 (define_insn "*addsi3.lt0"
1447 [(set (match_operand:SI 0 "register_operand" "=r")
1448 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1450 (match_operand:SI 2 "register_operand" "0")))]
1452 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1453 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1454 [(set_attr "length" "6")
1455 (set_attr "cc" "clobber")])
1460 (define_insn "<extend_u>mulqihi3"
1461 [(set (match_operand:HI 0 "register_operand" "=r")
1462 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1463 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1465 "mul<extend_s> %1,%2
1468 [(set_attr "length" "3")
1469 (set_attr "cc" "clobber")])
1471 (define_insn "usmulqihi3"
1472 [(set (match_operand:HI 0 "register_operand" "=r")
1473 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1474 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1479 [(set_attr "length" "3")
1480 (set_attr "cc" "clobber")])
1482 ;; Above insn is not canonicalized by insn combine, so here is a version with
1483 ;; operands swapped.
1485 (define_insn "*sumulqihi3"
1486 [(set (match_operand:HI 0 "register_operand" "=r")
1487 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1488 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1493 [(set_attr "length" "3")
1494 (set_attr "cc" "clobber")])
1496 ;; One-extend operand 1
1498 (define_insn "*osmulqihi3"
1499 [(set (match_operand:HI 0 "register_operand" "=&r")
1500 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1501 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1507 [(set_attr "length" "4")
1508 (set_attr "cc" "clobber")])
1510 (define_insn "*oumulqihi3"
1511 [(set (match_operand:HI 0 "register_operand" "=&r")
1512 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1513 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1519 [(set_attr "length" "4")
1520 (set_attr "cc" "clobber")])
1522 ;******************************************************************************
1523 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1524 ;******************************************************************************
1526 (define_insn "*maddqi4"
1527 [(set (match_operand:QI 0 "register_operand" "=r")
1528 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1529 (match_operand:QI 2 "register_operand" "r"))
1530 (match_operand:QI 3 "register_operand" "0")))]
1536 [(set_attr "length" "4")
1537 (set_attr "cc" "clobber")])
1539 (define_insn "*msubqi4"
1540 [(set (match_operand:QI 0 "register_operand" "=r")
1541 (minus:QI (match_operand:QI 3 "register_operand" "0")
1542 (mult:QI (match_operand:QI 1 "register_operand" "r")
1543 (match_operand:QI 2 "register_operand" "r"))))]
1548 [(set_attr "length" "4")
1549 (set_attr "cc" "clobber")])
1551 (define_insn_and_split "*maddqi4.const"
1552 [(set (match_operand:QI 0 "register_operand" "=r")
1553 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1554 (match_operand:QI 2 "const_int_operand" "n"))
1555 (match_operand:QI 3 "register_operand" "0")))
1556 (clobber (match_scratch:QI 4 "=&d"))]
1559 "&& reload_completed"
1564 (plus:QI (mult:QI (match_dup 1)
1569 (define_insn_and_split "*msubqi4.const"
1570 [(set (match_operand:QI 0 "register_operand" "=r")
1571 (minus:QI (match_operand:QI 3 "register_operand" "0")
1572 (mult:QI (match_operand:QI 1 "register_operand" "r")
1573 (match_operand:QI 2 "const_int_operand" "n"))))
1574 (clobber (match_scratch:QI 4 "=&d"))]
1577 "&& reload_completed"
1582 (minus:QI (match_dup 3)
1583 (mult:QI (match_dup 1)
1588 ;******************************************************************************
1589 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1590 ;******************************************************************************
1592 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1595 ;; int foo (unsigned char z)
1597 ;; extern int aInt[];
1598 ;; return aInt[3*z+2];
1601 ;; because the constant +4 then is added explicitely instead of consuming it
1602 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1603 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1604 ;; The implementational effort is the same so we are fine with that approach.
1609 (define_insn "*<extend_u>maddqihi4"
1610 [(set (match_operand:HI 0 "register_operand" "=r")
1611 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1612 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1613 (match_operand:HI 3 "register_operand" "0")))]
1616 "mul<extend_s> %1,%2
1620 [(set_attr "length" "4")
1621 (set_attr "cc" "clobber")])
1625 (define_insn "*<extend_u>msubqihi4"
1626 [(set (match_operand:HI 0 "register_operand" "=r")
1627 (minus:HI (match_operand:HI 3 "register_operand" "0")
1628 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1629 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1631 "mul<extend_s> %1,%2
1635 [(set_attr "length" "4")
1636 (set_attr "cc" "clobber")])
1640 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1641 [(set (match_operand:HI 0 "register_operand" "=r")
1642 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1643 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1644 (match_operand:HI 3 "register_operand" "0")))]
1647 && <any_extend:CODE> != <any_extend2:CODE>"
1649 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1650 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1652 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1654 [(set_attr "length" "4")
1655 (set_attr "cc" "clobber")])
1659 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1660 [(set (match_operand:HI 0 "register_operand" "=r")
1661 (minus:HI (match_operand:HI 3 "register_operand" "0")
1662 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1663 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1666 && <any_extend:CODE> != <any_extend2:CODE>"
1668 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1669 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1671 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1673 [(set_attr "length" "4")
1674 (set_attr "cc" "clobber")])
1676 ;; Handle small constants
1678 ;; "umaddqihi4.uconst"
1679 ;; "maddqihi4.sconst"
1680 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1681 [(set (match_operand:HI 0 "register_operand" "=r")
1682 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1683 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1684 (match_operand:HI 3 "register_operand" "0")))
1685 (clobber (match_scratch:QI 4 "=&d"))]
1688 "&& reload_completed"
1691 ; *umaddqihi4 resp. *maddqihi4
1693 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1694 (any_extend:HI (match_dup 4)))
1697 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1700 ;; "*umsubqihi4.uconst"
1701 ;; "*msubqihi4.sconst"
1702 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1703 [(set (match_operand:HI 0 "register_operand" "=r")
1704 (minus:HI (match_operand:HI 3 "register_operand" "0")
1705 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1706 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1707 (clobber (match_scratch:QI 4 "=&d"))]
1710 "&& reload_completed"
1713 ; *umsubqihi4 resp. *msubqihi4
1715 (minus:HI (match_dup 3)
1716 (mult:HI (any_extend:HI (match_dup 1))
1717 (any_extend:HI (match_dup 4)))))]
1719 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1722 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1723 ;; for MULT with power of 2 and skips trying MULT insn above.
1725 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1726 [(set (match_operand:HI 0 "register_operand" "=r")
1727 (minus:HI (match_operand:HI 3 "register_operand" "0")
1728 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1729 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1730 (clobber (match_scratch:QI 4 "=&d"))]
1733 "&& reload_completed"
1738 (minus:HI (match_dup 3)
1739 (mult:HI (zero_extend:HI (match_dup 1))
1740 (zero_extend:HI (match_dup 4)))))]
1742 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1745 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1746 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1747 ;; because this would require an extra pattern for just one value.
1749 (define_insn_and_split "*msubqihi4.sconst.ashift"
1750 [(set (match_operand:HI 0 "register_operand" "=r")
1751 (minus:HI (match_operand:HI 3 "register_operand" "0")
1752 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1753 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1754 (clobber (match_scratch:QI 4 "=&d"))]
1757 "&& reload_completed"
1762 (minus:HI (match_dup 3)
1763 (mult:HI (sign_extend:HI (match_dup 1))
1764 (sign_extend:HI (match_dup 4)))))]
1766 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1769 ;; For signed/unsigned combinations that require narrow constraint "a"
1770 ;; just provide a pattern if signed/unsigned combination is actually needed.
1772 (define_insn_and_split "*sumaddqihi4.uconst"
1773 [(set (match_operand:HI 0 "register_operand" "=r")
1774 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1775 (match_operand:HI 2 "u8_operand" "M"))
1776 (match_operand:HI 3 "register_operand" "0")))
1777 (clobber (match_scratch:QI 4 "=&a"))]
1779 && !s8_operand (operands[2], VOIDmode)"
1781 "&& reload_completed"
1786 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1787 (zero_extend:HI (match_dup 4)))
1790 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1793 (define_insn_and_split "*sumsubqihi4.uconst"
1794 [(set (match_operand:HI 0 "register_operand" "=r")
1795 (minus:HI (match_operand:HI 3 "register_operand" "0")
1796 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1797 (match_operand:HI 2 "u8_operand" "M"))))
1798 (clobber (match_scratch:QI 4 "=&a"))]
1800 && !s8_operand (operands[2], VOIDmode)"
1802 "&& reload_completed"
1807 (minus:HI (match_dup 3)
1808 (mult:HI (sign_extend:HI (match_dup 1))
1809 (zero_extend:HI (match_dup 4)))))]
1811 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1814 ;******************************************************************************
1815 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1816 ;******************************************************************************
1818 ;; "*muluqihi3.uconst"
1819 ;; "*mulsqihi3.sconst"
1820 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1821 [(set (match_operand:HI 0 "register_operand" "=r")
1822 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1823 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1824 (clobber (match_scratch:QI 3 "=&d"))]
1827 "&& reload_completed"
1830 ; umulqihi3 resp. mulqihi3
1832 (mult:HI (any_extend:HI (match_dup 1))
1833 (any_extend:HI (match_dup 3))))]
1835 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1838 (define_insn_and_split "*muluqihi3.sconst"
1839 [(set (match_operand:HI 0 "register_operand" "=r")
1840 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1841 (match_operand:HI 2 "s8_operand" "n")))
1842 (clobber (match_scratch:QI 3 "=&a"))]
1845 "&& reload_completed"
1850 (mult:HI (zero_extend:HI (match_dup 1))
1851 (sign_extend:HI (match_dup 3))))]
1853 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1856 (define_insn_and_split "*mulsqihi3.uconst"
1857 [(set (match_operand:HI 0 "register_operand" "=r")
1858 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1859 (match_operand:HI 2 "u8_operand" "M")))
1860 (clobber (match_scratch:QI 3 "=&a"))]
1863 "&& reload_completed"
1868 (mult:HI (zero_extend:HI (match_dup 3))
1869 (sign_extend:HI (match_dup 1))))]
1871 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1874 (define_insn_and_split "*mulsqihi3.oconst"
1875 [(set (match_operand:HI 0 "register_operand" "=&r")
1876 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1877 (match_operand:HI 2 "o8_operand" "n")))
1878 (clobber (match_scratch:QI 3 "=&a"))]
1881 "&& reload_completed"
1886 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1887 (sign_extend:HI (match_dup 1))))]
1889 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1892 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1893 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1894 ;; at that time. Fix that.
1896 (define_insn "*ashiftqihi2.signx.1"
1897 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1898 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1902 lsl %A0\;sbc %B0,%B0
1903 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1904 [(set_attr "length" "2,3")
1905 (set_attr "cc" "clobber")])
1907 (define_insn_and_split "*ashifthi3.signx.const"
1908 [(set (match_operand:HI 0 "register_operand" "=r")
1909 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1910 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1911 (clobber (match_scratch:QI 3 "=&d"))]
1914 "&& reload_completed"
1919 (mult:HI (sign_extend:HI (match_dup 1))
1920 (sign_extend:HI (match_dup 3))))]
1922 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1925 (define_insn_and_split "*ashifthi3.signx.const7"
1926 [(set (match_operand:HI 0 "register_operand" "=r")
1927 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1929 (clobber (match_scratch:QI 2 "=&a"))]
1932 "&& reload_completed"
1937 (mult:HI (zero_extend:HI (match_dup 2))
1938 (sign_extend:HI (match_dup 1))))]
1940 operands[3] = gen_int_mode (1 << 7, QImode);
1943 (define_insn_and_split "*ashifthi3.zerox.const"
1944 [(set (match_operand:HI 0 "register_operand" "=r")
1945 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1946 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1947 (clobber (match_scratch:QI 3 "=&d"))]
1950 "&& reload_completed"
1955 (mult:HI (zero_extend:HI (match_dup 1))
1956 (zero_extend:HI (match_dup 3))))]
1958 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1961 ;******************************************************************************
1962 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1963 ;******************************************************************************
1965 (define_insn "mulsqihi3"
1966 [(set (match_operand:HI 0 "register_operand" "=&r")
1967 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1968 (match_operand:HI 2 "register_operand" "a")))]
1975 [(set_attr "length" "5")
1976 (set_attr "cc" "clobber")])
1978 (define_insn "muluqihi3"
1979 [(set (match_operand:HI 0 "register_operand" "=&r")
1980 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1981 (match_operand:HI 2 "register_operand" "r")))]
1988 [(set_attr "length" "5")
1989 (set_attr "cc" "clobber")])
1991 ;; one-extend operand 1
1993 (define_insn "muloqihi3"
1994 [(set (match_operand:HI 0 "register_operand" "=&r")
1995 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1996 (match_operand:HI 2 "register_operand" "r")))]
2004 [(set_attr "length" "6")
2005 (set_attr "cc" "clobber")])
2007 ;******************************************************************************
2009 (define_expand "mulhi3"
2010 [(set (match_operand:HI 0 "register_operand" "")
2011 (mult:HI (match_operand:HI 1 "register_operand" "")
2012 (match_operand:HI 2 "register_or_s9_operand" "")))]
2017 if (!register_operand (operands[2], HImode))
2018 operands[2] = force_reg (HImode, operands[2]);
2020 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2024 /* For small constants we can do better by extending them on the fly.
2025 The constant can be loaded in one instruction and the widening
2026 multiplication is shorter. First try the unsigned variant because it
2027 allows constraint "d" instead of "a" for the signed version. */
2029 if (s9_operand (operands[2], HImode))
2031 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2033 if (u8_operand (operands[2], HImode))
2035 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2037 else if (s8_operand (operands[2], HImode))
2039 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2043 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2049 if (!register_operand (operands[2], HImode))
2050 operands[2] = force_reg (HImode, operands[2]);
2053 (define_insn "*mulhi3_enh"
2054 [(set (match_operand:HI 0 "register_operand" "=&r")
2055 (mult:HI (match_operand:HI 1 "register_operand" "r")
2056 (match_operand:HI 2 "register_operand" "r")))]
2059 return REGNO (operands[1]) == REGNO (operands[2])
2060 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2061 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2063 [(set_attr "length" "7")
2064 (set_attr "cc" "clobber")])
2066 (define_expand "mulhi3_call"
2067 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2068 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2069 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2070 (clobber (reg:HI 22))
2071 (clobber (reg:QI 21))])
2072 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2076 (define_insn "*mulhi3_call"
2077 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2078 (clobber (reg:HI 22))
2079 (clobber (reg:QI 21))]
2082 [(set_attr "type" "xcall")
2083 (set_attr "cc" "clobber")])
2085 ;; To support widening multiplication with constant we postpone
2086 ;; expanding to the implicit library call until post combine and
2087 ;; prior to register allocation. Clobber all hard registers that
2088 ;; might be used by the (widening) multiply until it is split and
2089 ;; it's final register footprint is worked out.
2091 (define_expand "mulsi3"
2092 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2093 (mult:SI (match_operand:SI 1 "register_operand" "")
2094 (match_operand:SI 2 "nonmemory_operand" "")))
2095 (clobber (reg:HI 26))
2096 (clobber (reg:DI 18))])]
2099 if (u16_operand (operands[2], SImode))
2101 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2102 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2106 if (o16_operand (operands[2], SImode))
2108 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2109 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2114 (define_insn_and_split "*mulsi3"
2115 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2116 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2117 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2118 (clobber (reg:HI 26))
2119 (clobber (reg:DI 18))]
2120 "AVR_HAVE_MUL && !reload_completed"
2121 { gcc_unreachable(); }
2127 (parallel [(set (reg:SI 22)
2128 (mult:SI (reg:SI 22)
2130 (clobber (reg:HI 26))])
2134 if (u16_operand (operands[2], SImode))
2136 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2137 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2141 if (o16_operand (operands[2], SImode))
2143 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2144 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2151 (define_insn_and_split "mulu<mode>si3"
2152 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2153 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2154 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2155 (clobber (reg:HI 26))
2156 (clobber (reg:DI 18))]
2157 "AVR_HAVE_MUL && !reload_completed"
2158 { gcc_unreachable(); }
2165 (mult:SI (zero_extend:SI (reg:HI 26))
2170 /* Do the QI -> HI extension explicitely before the multiplication. */
2171 /* Do the HI -> SI extension implicitely and after the multiplication. */
2173 if (QImode == <MODE>mode)
2174 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2176 if (u16_operand (operands[2], SImode))
2178 operands[1] = force_reg (HImode, operands[1]);
2179 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2180 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2187 (define_insn_and_split "muls<mode>si3"
2188 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2189 (mult:SI (sign_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 (sign_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_SIGN_EXTEND (HImode, operands[1]);
2212 if (u16_operand (operands[2], SImode)
2213 || s16_operand (operands[2], SImode))
2215 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2217 operands[1] = force_reg (HImode, operands[1]);
2219 if (u16_operand (operands[2], SImode))
2220 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2222 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2228 ;; One-extend operand 1
2230 (define_insn_and_split "mulohisi3"
2231 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2232 (mult:SI (not:SI (zero_extend:SI
2233 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2234 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2235 (clobber (reg:HI 26))
2236 (clobber (reg:DI 18))]
2237 "AVR_HAVE_MUL && !reload_completed"
2238 { gcc_unreachable(); }
2245 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2253 (define_expand "<extend_u>mulhisi3"
2254 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2255 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2256 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2257 (clobber (reg:HI 26))
2258 (clobber (reg:DI 18))])]
2262 (define_expand "usmulhisi3"
2263 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2264 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2265 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2266 (clobber (reg:HI 26))
2267 (clobber (reg:DI 18))])]
2271 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2272 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2273 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2274 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2275 (define_insn_and_split
2276 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2277 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2278 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2279 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2280 (clobber (reg:HI 26))
2281 (clobber (reg:DI 18))]
2282 "AVR_HAVE_MUL && !reload_completed"
2283 { gcc_unreachable(); }
2290 (mult:SI (match_dup 3)
2295 rtx xop1 = operands[1];
2296 rtx xop2 = operands[2];
2298 /* Do the QI -> HI extension explicitely before the multiplication. */
2299 /* Do the HI -> SI extension implicitely and after the multiplication. */
2301 if (QImode == <QIHI:MODE>mode)
2302 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2304 if (QImode == <QIHI2:MODE>mode)
2305 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2307 if (<any_extend:CODE> == <any_extend2:CODE>
2308 || <any_extend:CODE> == ZERO_EXTEND)
2312 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2313 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2317 /* <any_extend:CODE> = SIGN_EXTEND */
2318 /* <any_extend2:CODE> = ZERO_EXTEND */
2322 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2323 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2327 ;; "smulhi3_highpart"
2328 ;; "umulhi3_highpart"
2329 (define_expand "<extend_su>mulhi3_highpart"
2331 (match_operand:HI 1 "nonmemory_operand" ""))
2333 (match_operand:HI 2 "nonmemory_operand" ""))
2334 (parallel [(set (reg:HI 24)
2335 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2336 (any_extend:SI (reg:HI 26)))
2338 (clobber (reg:HI 22))])
2339 (set (match_operand:HI 0 "register_operand" "")
2345 (define_insn "*mulsi3_call"
2347 (mult:SI (reg:SI 22)
2349 (clobber (reg:HI 26))]
2352 [(set_attr "type" "xcall")
2353 (set_attr "cc" "clobber")])
2356 ;; "*umulhisi3_call"
2357 (define_insn "*<extend_u>mulhisi3_call"
2359 (mult:SI (any_extend:SI (reg:HI 18))
2360 (any_extend:SI (reg:HI 26))))]
2362 "%~call __<extend_u>mulhisi3"
2363 [(set_attr "type" "xcall")
2364 (set_attr "cc" "clobber")])
2366 ;; "*umulhi3_highpart_call"
2367 ;; "*smulhi3_highpart_call"
2368 (define_insn "*<extend_su>mulhi3_highpart_call"
2370 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2371 (any_extend:SI (reg:HI 26)))
2373 (clobber (reg:HI 22))]
2375 "%~call __<extend_u>mulhisi3"
2376 [(set_attr "type" "xcall")
2377 (set_attr "cc" "clobber")])
2379 (define_insn "*usmulhisi3_call"
2381 (mult:SI (zero_extend:SI (reg:HI 18))
2382 (sign_extend:SI (reg:HI 26))))]
2384 "%~call __usmulhisi3"
2385 [(set_attr "type" "xcall")
2386 (set_attr "cc" "clobber")])
2388 (define_insn "*mul<extend_su>hisi3_call"
2390 (mult:SI (any_extend:SI (reg:HI 26))
2393 "%~call __mul<extend_su>hisi3"
2394 [(set_attr "type" "xcall")
2395 (set_attr "cc" "clobber")])
2397 (define_insn "*mulohisi3_call"
2399 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2402 "%~call __mulohisi3"
2403 [(set_attr "type" "xcall")
2404 (set_attr "cc" "clobber")])
2406 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2409 ;; Generate lib1funcs.S calls ourselves, because:
2410 ;; - we know exactly which registers are clobbered (for QI and HI
2411 ;; modes, some of the call-used registers are preserved)
2412 ;; - we get both the quotient and the remainder at no extra cost
2413 ;; - we split the patterns only after the first CSE passes because
2414 ;; CSE has problems to operate on hard regs.
2416 (define_insn_and_split "divmodqi4"
2417 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2418 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2419 (match_operand:QI 2 "pseudo_register_operand" "")))
2420 (set (match_operand:QI 3 "pseudo_register_operand" "")
2421 (mod:QI (match_dup 1) (match_dup 2)))
2422 (clobber (reg:QI 22))
2423 (clobber (reg:QI 23))
2424 (clobber (reg:QI 24))
2425 (clobber (reg:QI 25))])]
2427 "this divmodqi4 pattern should have been splitted;"
2429 [(set (reg:QI 24) (match_dup 1))
2430 (set (reg:QI 22) (match_dup 2))
2431 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2432 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2433 (clobber (reg:QI 22))
2434 (clobber (reg:QI 23))])
2435 (set (match_dup 0) (reg:QI 24))
2436 (set (match_dup 3) (reg:QI 25))]
2439 (define_insn "*divmodqi4_call"
2440 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2441 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2442 (clobber (reg:QI 22))
2443 (clobber (reg:QI 23))]
2445 "%~call __divmodqi4"
2446 [(set_attr "type" "xcall")
2447 (set_attr "cc" "clobber")])
2449 (define_insn_and_split "udivmodqi4"
2450 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2451 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2452 (match_operand:QI 2 "pseudo_register_operand" "")))
2453 (set (match_operand:QI 3 "pseudo_register_operand" "")
2454 (umod:QI (match_dup 1) (match_dup 2)))
2455 (clobber (reg:QI 22))
2456 (clobber (reg:QI 23))
2457 (clobber (reg:QI 24))
2458 (clobber (reg:QI 25))])]
2460 "this udivmodqi4 pattern should have been splitted;"
2462 [(set (reg:QI 24) (match_dup 1))
2463 (set (reg:QI 22) (match_dup 2))
2464 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2465 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2466 (clobber (reg:QI 23))])
2467 (set (match_dup 0) (reg:QI 24))
2468 (set (match_dup 3) (reg:QI 25))]
2471 (define_insn "*udivmodqi4_call"
2472 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2473 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2474 (clobber (reg:QI 23))]
2476 "%~call __udivmodqi4"
2477 [(set_attr "type" "xcall")
2478 (set_attr "cc" "clobber")])
2480 (define_insn_and_split "divmodhi4"
2481 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2482 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2483 (match_operand:HI 2 "pseudo_register_operand" "")))
2484 (set (match_operand:HI 3 "pseudo_register_operand" "")
2485 (mod:HI (match_dup 1) (match_dup 2)))
2486 (clobber (reg:QI 21))
2487 (clobber (reg:HI 22))
2488 (clobber (reg:HI 24))
2489 (clobber (reg:HI 26))])]
2491 "this should have been splitted;"
2493 [(set (reg:HI 24) (match_dup 1))
2494 (set (reg:HI 22) (match_dup 2))
2495 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2496 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2497 (clobber (reg:HI 26))
2498 (clobber (reg:QI 21))])
2499 (set (match_dup 0) (reg:HI 22))
2500 (set (match_dup 3) (reg:HI 24))]
2503 (define_insn "*divmodhi4_call"
2504 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2505 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2506 (clobber (reg:HI 26))
2507 (clobber (reg:QI 21))]
2509 "%~call __divmodhi4"
2510 [(set_attr "type" "xcall")
2511 (set_attr "cc" "clobber")])
2513 (define_insn_and_split "udivmodhi4"
2514 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2515 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2516 (match_operand:HI 2 "pseudo_register_operand" "")))
2517 (set (match_operand:HI 3 "pseudo_register_operand" "")
2518 (umod:HI (match_dup 1) (match_dup 2)))
2519 (clobber (reg:QI 21))
2520 (clobber (reg:HI 22))
2521 (clobber (reg:HI 24))
2522 (clobber (reg:HI 26))])]
2524 "this udivmodhi4 pattern should have been splitted.;"
2526 [(set (reg:HI 24) (match_dup 1))
2527 (set (reg:HI 22) (match_dup 2))
2528 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2529 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2530 (clobber (reg:HI 26))
2531 (clobber (reg:QI 21))])
2532 (set (match_dup 0) (reg:HI 22))
2533 (set (match_dup 3) (reg:HI 24))]
2536 (define_insn "*udivmodhi4_call"
2537 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2538 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2539 (clobber (reg:HI 26))
2540 (clobber (reg:QI 21))]
2542 "%~call __udivmodhi4"
2543 [(set_attr "type" "xcall")
2544 (set_attr "cc" "clobber")])
2546 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2549 ;; To support widening multiplication with constant we postpone
2550 ;; expanding to the implicit library call until post combine and
2551 ;; prior to register allocation. Clobber all hard registers that
2552 ;; might be used by the (widening) multiply until it is split and
2553 ;; it's final register footprint is worked out.
2555 (define_expand "mulpsi3"
2556 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2557 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2558 (match_operand:PSI 2 "nonmemory_operand" "")))
2559 (clobber (reg:HI 26))
2560 (clobber (reg:DI 18))])]
2563 if (s8_operand (operands[2], PSImode))
2565 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2566 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2571 (define_insn "*umulqihipsi3"
2572 [(set (match_operand:PSI 0 "register_operand" "=&r")
2573 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2574 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2583 [(set_attr "length" "7")
2584 (set_attr "cc" "clobber")])
2586 (define_insn "*umulhiqipsi3"
2587 [(set (match_operand:PSI 0 "register_operand" "=&r")
2588 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2589 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2597 adc %C0,__zero_reg__"
2598 [(set_attr "length" "7")
2599 (set_attr "cc" "clobber")])
2601 (define_insn_and_split "mulsqipsi3"
2602 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2603 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2604 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2605 (clobber (reg:HI 26))
2606 (clobber (reg:DI 18))]
2607 "AVR_HAVE_MUL && !reload_completed"
2608 { gcc_unreachable(); }
2615 (mult:PSI (sign_extend:PSI (reg:QI 25))
2620 (define_insn_and_split "*mulpsi3"
2621 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2622 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2623 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2624 (clobber (reg:HI 26))
2625 (clobber (reg:DI 18))]
2626 "AVR_HAVE_MUL && !reload_completed"
2627 { gcc_unreachable(); }
2633 (parallel [(set (reg:PSI 22)
2634 (mult:PSI (reg:PSI 22)
2636 (clobber (reg:QI 21))
2637 (clobber (reg:QI 25))
2638 (clobber (reg:HI 26))])
2642 if (s8_operand (operands[2], PSImode))
2644 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2645 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2650 (define_insn "*mulsqipsi3.libgcc"
2652 (mult:PSI (sign_extend:PSI (reg:QI 25))
2655 "%~call __mulsqipsi3"
2656 [(set_attr "type" "xcall")
2657 (set_attr "cc" "clobber")])
2659 (define_insn "*mulpsi3.libgcc"
2661 (mult:PSI (reg:PSI 22)
2663 (clobber (reg:QI 21))
2664 (clobber (reg:QI 25))
2665 (clobber (reg:HI 26))]
2668 [(set_attr "type" "xcall")
2669 (set_attr "cc" "clobber")])
2672 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2673 ;; 24-bit signed/unsigned division and modulo.
2674 ;; Notice that the libgcc implementation return the quotient in R22
2675 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2676 ;; implementation works the other way round.
2678 (define_insn_and_split "divmodpsi4"
2679 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2680 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2681 (match_operand:PSI 2 "pseudo_register_operand" "")))
2682 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2683 (mod:PSI (match_dup 1)
2685 (clobber (reg:DI 18))
2686 (clobber (reg:QI 26))])]
2688 { gcc_unreachable(); }
2690 [(set (reg:PSI 22) (match_dup 1))
2691 (set (reg:PSI 18) (match_dup 2))
2692 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2693 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2694 (clobber (reg:QI 21))
2695 (clobber (reg:QI 25))
2696 (clobber (reg:QI 26))])
2697 (set (match_dup 0) (reg:PSI 22))
2698 (set (match_dup 3) (reg:PSI 18))])
2700 (define_insn "*divmodpsi4_call"
2701 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2702 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2703 (clobber (reg:QI 21))
2704 (clobber (reg:QI 25))
2705 (clobber (reg:QI 26))]
2707 "%~call __divmodpsi4"
2708 [(set_attr "type" "xcall")
2709 (set_attr "cc" "clobber")])
2711 (define_insn_and_split "udivmodpsi4"
2712 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2713 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2714 (match_operand:PSI 2 "pseudo_register_operand" "")))
2715 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2716 (umod:PSI (match_dup 1)
2718 (clobber (reg:DI 18))
2719 (clobber (reg:QI 26))])]
2721 { gcc_unreachable(); }
2723 [(set (reg:PSI 22) (match_dup 1))
2724 (set (reg:PSI 18) (match_dup 2))
2725 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2726 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2727 (clobber (reg:QI 21))
2728 (clobber (reg:QI 25))
2729 (clobber (reg:QI 26))])
2730 (set (match_dup 0) (reg:PSI 22))
2731 (set (match_dup 3) (reg:PSI 18))])
2733 (define_insn "*udivmodpsi4_call"
2734 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2735 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2736 (clobber (reg:QI 21))
2737 (clobber (reg:QI 25))
2738 (clobber (reg:QI 26))]
2740 "%~call __udivmodpsi4"
2741 [(set_attr "type" "xcall")
2742 (set_attr "cc" "clobber")])
2744 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2746 (define_insn_and_split "divmodsi4"
2747 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2748 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2749 (match_operand:SI 2 "pseudo_register_operand" "")))
2750 (set (match_operand:SI 3 "pseudo_register_operand" "")
2751 (mod:SI (match_dup 1) (match_dup 2)))
2752 (clobber (reg:SI 18))
2753 (clobber (reg:SI 22))
2754 (clobber (reg:HI 26))
2755 (clobber (reg:HI 30))])]
2757 "this divmodsi4 pattern should have been splitted;"
2759 [(set (reg:SI 22) (match_dup 1))
2760 (set (reg:SI 18) (match_dup 2))
2761 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2762 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2763 (clobber (reg:HI 26))
2764 (clobber (reg:HI 30))])
2765 (set (match_dup 0) (reg:SI 18))
2766 (set (match_dup 3) (reg:SI 22))]
2769 (define_insn "*divmodsi4_call"
2770 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2771 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2772 (clobber (reg:HI 26))
2773 (clobber (reg:HI 30))]
2775 "%~call __divmodsi4"
2776 [(set_attr "type" "xcall")
2777 (set_attr "cc" "clobber")])
2779 (define_insn_and_split "udivmodsi4"
2780 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2781 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2782 (match_operand:SI 2 "pseudo_register_operand" "")))
2783 (set (match_operand:SI 3 "pseudo_register_operand" "")
2784 (umod:SI (match_dup 1) (match_dup 2)))
2785 (clobber (reg:SI 18))
2786 (clobber (reg:SI 22))
2787 (clobber (reg:HI 26))
2788 (clobber (reg:HI 30))])]
2790 "this udivmodsi4 pattern should have been splitted;"
2792 [(set (reg:SI 22) (match_dup 1))
2793 (set (reg:SI 18) (match_dup 2))
2794 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2795 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2796 (clobber (reg:HI 26))
2797 (clobber (reg:HI 30))])
2798 (set (match_dup 0) (reg:SI 18))
2799 (set (match_dup 3) (reg:SI 22))]
2802 (define_insn "*udivmodsi4_call"
2803 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2804 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2805 (clobber (reg:HI 26))
2806 (clobber (reg:HI 30))]
2808 "%~call __udivmodsi4"
2809 [(set_attr "type" "xcall")
2810 (set_attr "cc" "clobber")])
2812 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2815 (define_insn "andqi3"
2816 [(set (match_operand:QI 0 "register_operand" "=r,d")
2817 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2818 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2823 [(set_attr "length" "1,1")
2824 (set_attr "cc" "set_zn,set_zn")])
2826 (define_insn "andhi3"
2827 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2828 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2829 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2830 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2833 if (which_alternative == 0)
2834 return "and %A0,%A2\;and %B0,%B2";
2835 else if (which_alternative == 1)
2836 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2838 return avr_out_bitop (insn, operands, NULL);
2840 [(set_attr "length" "2,2,2,4,4")
2841 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2842 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2844 (define_insn "andpsi3"
2845 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2846 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2847 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2848 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2851 if (which_alternative == 0)
2852 return "and %A0,%A2" CR_TAB
2853 "and %B0,%B2" CR_TAB
2856 return avr_out_bitop (insn, operands, NULL);
2858 [(set_attr "length" "3,3,6,6")
2859 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2860 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2862 (define_insn "andsi3"
2863 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2864 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2865 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2866 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2869 if (which_alternative == 0)
2870 return "and %0,%2" CR_TAB
2871 "and %B0,%B2" CR_TAB
2872 "and %C0,%C2" CR_TAB
2875 return avr_out_bitop (insn, operands, NULL);
2877 [(set_attr "length" "4,4,8,8")
2878 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2879 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2881 (define_peephole2 ; andi
2882 [(set (match_operand:QI 0 "d_register_operand" "")
2883 (and:QI (match_dup 0)
2884 (match_operand:QI 1 "const_int_operand" "")))
2886 (and:QI (match_dup 0)
2887 (match_operand:QI 2 "const_int_operand" "")))]
2889 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2891 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2894 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2897 (define_insn "iorqi3"
2898 [(set (match_operand:QI 0 "register_operand" "=r,d")
2899 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2900 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2905 [(set_attr "length" "1,1")
2906 (set_attr "cc" "set_zn,set_zn")])
2908 (define_insn "iorhi3"
2909 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2910 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2911 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2912 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2915 if (which_alternative == 0)
2916 return "or %A0,%A2\;or %B0,%B2";
2917 else if (which_alternative == 1)
2918 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
2920 return avr_out_bitop (insn, operands, NULL);
2922 [(set_attr "length" "2,2,2,4,4")
2923 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2924 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2926 (define_insn "iorpsi3"
2927 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2928 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2929 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
2930 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2933 if (which_alternative == 0)
2934 return "or %A0,%A2" CR_TAB
2938 return avr_out_bitop (insn, operands, NULL);
2940 [(set_attr "length" "3,3,6,6")
2941 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2942 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2944 (define_insn "iorsi3"
2945 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2946 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2947 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2948 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2951 if (which_alternative == 0)
2952 return "or %0,%2" CR_TAB
2957 return avr_out_bitop (insn, operands, NULL);
2959 [(set_attr "length" "4,4,8,8")
2960 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2961 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2963 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2966 (define_insn "xorqi3"
2967 [(set (match_operand:QI 0 "register_operand" "=r")
2968 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2969 (match_operand:QI 2 "register_operand" "r")))]
2972 [(set_attr "length" "1")
2973 (set_attr "cc" "set_zn")])
2975 (define_insn "xorhi3"
2976 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
2977 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
2978 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
2979 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2982 if (which_alternative == 0)
2983 return "eor %A0,%A2\;eor %B0,%B2";
2985 return avr_out_bitop (insn, operands, NULL);
2987 [(set_attr "length" "2,2,4")
2988 (set_attr "adjust_len" "*,out_bitop,out_bitop")
2989 (set_attr "cc" "set_n,clobber,clobber")])
2991 (define_insn "xorpsi3"
2992 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
2993 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
2994 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
2995 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2998 if (which_alternative == 0)
2999 return "eor %A0,%A2" CR_TAB
3000 "eor %B0,%B2" CR_TAB
3003 return avr_out_bitop (insn, operands, NULL);
3005 [(set_attr "length" "3,6,6")
3006 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3007 (set_attr "cc" "set_n,clobber,clobber")])
3009 (define_insn "xorsi3"
3010 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3011 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3012 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3013 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3016 if (which_alternative == 0)
3017 return "eor %0,%2" CR_TAB
3018 "eor %B0,%B2" CR_TAB
3019 "eor %C0,%C2" CR_TAB
3022 return avr_out_bitop (insn, operands, NULL);
3024 [(set_attr "length" "4,8,8")
3025 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3026 (set_attr "cc" "set_n,clobber,clobber")])
3028 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3031 (define_expand "rotlqi3"
3032 [(set (match_operand:QI 0 "register_operand" "")
3033 (rotate:QI (match_operand:QI 1 "register_operand" "")
3034 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3037 if (!CONST_INT_P (operands[2]))
3040 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3043 ;; Expander used by __builtin_avr_swap
3044 (define_expand "rotlqi3_4"
3045 [(set (match_operand:QI 0 "register_operand" "")
3046 (rotate:QI (match_operand:QI 1 "register_operand" "")
3049 (define_insn "*rotlqi3"
3050 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3051 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3052 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3055 lsl %0\;adc %0,__zero_reg__
3056 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3057 swap %0\;bst %0,0\;ror %0\;bld %0,7
3059 swap %0\;lsl %0\;adc %0,__zero_reg__
3060 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3061 bst %0,0\;ror %0\;bld %0,7
3063 [(set_attr "length" "2,4,4,1,3,5,3,0")
3064 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3066 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3067 ;; a whole number of bytes. The split creates the appropriate moves and
3068 ;; considers all overlap situations.
3070 ;; HImode does not need scratch. Use attribute for this constraint.
3072 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3073 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3078 (define_expand "rotl<mode>3"
3079 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3080 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3081 (match_operand:VOID 2 "const_int_operand" "")))
3082 (clobber (match_dup 3))])]
3087 if (!CONST_INT_P (operands[2]))
3090 offset = INTVAL (operands[2]);
3092 if (0 == offset % 8)
3094 if (AVR_HAVE_MOVW && 0 == offset % 16)
3095 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3097 operands[3] = gen_rtx_SCRATCH (QImode);
3099 else if (offset == 1
3100 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3102 /*; Support rotate left/right by 1 */
3104 emit_move_insn (operands[0],
3105 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3112 (define_insn "*rotlhi2.1"
3113 [(set (match_operand:HI 0 "register_operand" "=r")
3114 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3117 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3118 [(set_attr "length" "3")
3119 (set_attr "cc" "clobber")])
3121 (define_insn "*rotlhi2.15"
3122 [(set (match_operand:HI 0 "register_operand" "=r")
3123 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3126 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3127 [(set_attr "length" "4")
3128 (set_attr "cc" "clobber")])
3130 (define_insn "*rotlpsi2.1"
3131 [(set (match_operand:PSI 0 "register_operand" "=r")
3132 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3135 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3136 [(set_attr "length" "4")
3137 (set_attr "cc" "clobber")])
3139 (define_insn "*rotlpsi2.23"
3140 [(set (match_operand:PSI 0 "register_operand" "=r")
3141 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3144 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3145 [(set_attr "length" "5")
3146 (set_attr "cc" "clobber")])
3148 (define_insn "*rotlsi2.1"
3149 [(set (match_operand:SI 0 "register_operand" "=r")
3150 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3153 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3154 [(set_attr "length" "5")
3155 (set_attr "cc" "clobber")])
3157 (define_insn "*rotlsi2.31"
3158 [(set (match_operand:SI 0 "register_operand" "=r")
3159 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3162 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3163 [(set_attr "length" "6")
3164 (set_attr "cc" "clobber")])
3166 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3167 ;; The best we can do is use early clobber alternative "#&r" so that
3168 ;; completely non-overlapping operands dont get a scratch but # so register
3169 ;; allocation does not prefer non-overlapping.
3172 ;; Split word aligned rotates using scratch that is mode dependent.
3176 (define_insn_and_split "*rotw<mode>"
3177 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3178 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3179 (match_operand 2 "const_int_operand" "n,n,n")))
3180 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3182 && CONST_INT_P (operands[2])
3183 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3184 && 0 == INTVAL (operands[2]) % 16"
3186 "&& reload_completed"
3189 avr_rotate_bytes (operands);
3194 ;; Split byte aligned rotates using scratch that is always QI mode.
3199 (define_insn_and_split "*rotb<mode>"
3200 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3201 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3202 (match_operand 2 "const_int_operand" "n,n,n")))
3203 (clobber (match_scratch:QI 3 "=<rotx>"))]
3204 "CONST_INT_P (operands[2])
3205 && (8 == INTVAL (operands[2]) % 16
3207 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3208 && 0 == INTVAL (operands[2]) % 16))"
3210 "&& reload_completed"
3213 avr_rotate_bytes (operands);
3218 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3219 ;; arithmetic shift left
3221 (define_expand "ashlqi3"
3222 [(set (match_operand:QI 0 "register_operand" "")
3223 (ashift:QI (match_operand:QI 1 "register_operand" "")
3224 (match_operand:QI 2 "nop_general_operand" "")))])
3226 (define_split ; ashlqi3_const4
3227 [(set (match_operand:QI 0 "d_register_operand" "")
3228 (ashift:QI (match_dup 0)
3231 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3232 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
3235 (define_split ; ashlqi3_const5
3236 [(set (match_operand:QI 0 "d_register_operand" "")
3237 (ashift:QI (match_dup 0)
3240 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3241 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3242 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
3245 (define_split ; ashlqi3_const6
3246 [(set (match_operand:QI 0 "d_register_operand" "")
3247 (ashift:QI (match_dup 0)
3250 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3251 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3252 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
3255 (define_insn "*ashlqi3"
3256 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3257 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3258 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3261 return ashlqi3_out (insn, operands, NULL);
3263 [(set_attr "length" "5,0,1,2,4,6,9")
3264 (set_attr "adjust_len" "ashlqi")
3265 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3267 (define_insn "ashlhi3"
3268 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3269 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3270 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3273 return ashlhi3_out (insn, operands, NULL);
3275 [(set_attr "length" "6,0,2,2,4,10,10")
3276 (set_attr "adjust_len" "ashlhi")
3277 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3280 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3281 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3285 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3286 [(set (match_operand:QI 0 "register_operand" "=r")
3287 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3288 (match_operand:QI 2 "register_operand" "r"))
3294 (ashift:QI (match_dup 1)
3298 ;; ??? Combiner does not recognize that it could split the following insn;
3299 ;; presumably because he has no register handy?
3301 ;; "*ashluqihiqi3.mem"
3302 ;; "*ashlsqihiqi3.mem"
3303 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3304 [(set (match_operand:QI 0 "memory_operand" "=m")
3305 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3306 (match_operand:QI 2 "register_operand" "r"))
3309 { gcc_unreachable(); }
3312 (ashift:QI (match_dup 1)
3317 operands[3] = gen_reg_rtx (QImode);
3322 (define_insn_and_split "*ashlhiqi3"
3323 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3324 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3325 (match_operand:QI 2 "register_operand" "r")) 0))]
3327 { gcc_unreachable(); }
3330 (ashift:QI (match_dup 3)
3335 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3336 operands[4] = gen_reg_rtx (QImode);
3339 ;; High part of 16-bit shift is unused after the instruction:
3340 ;; No need to compute it, map to 8-bit shift.
3343 [(set (match_operand:HI 0 "register_operand" "")
3344 (ashift:HI (match_dup 0)
3345 (match_operand:QI 1 "register_operand" "")))]
3348 (ashift:QI (match_dup 2)
3350 (clobber (match_dup 3))]
3352 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3354 if (!peep2_reg_dead_p (1, operands[3]))
3357 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3361 (define_insn "ashlsi3"
3362 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3363 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3364 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3367 return ashlsi3_out (insn, operands, NULL);
3369 [(set_attr "length" "8,0,4,4,8,10,12")
3370 (set_attr "adjust_len" "ashlsi")
3371 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3373 ;; Optimize if a scratch register from LD_REGS happens to be available.
3375 (define_peephole2 ; ashlqi3_l_const4
3376 [(set (match_operand:QI 0 "l_register_operand" "")
3377 (ashift:QI (match_dup 0)
3379 (match_scratch:QI 1 "d")]
3381 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3382 (set (match_dup 1) (const_int -16))
3383 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3386 (define_peephole2 ; ashlqi3_l_const5
3387 [(set (match_operand:QI 0 "l_register_operand" "")
3388 (ashift:QI (match_dup 0)
3390 (match_scratch:QI 1 "d")]
3392 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3393 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3394 (set (match_dup 1) (const_int -32))
3395 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3398 (define_peephole2 ; ashlqi3_l_const6
3399 [(set (match_operand:QI 0 "l_register_operand" "")
3400 (ashift:QI (match_dup 0)
3402 (match_scratch:QI 1 "d")]
3404 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3405 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3406 (set (match_dup 1) (const_int -64))
3407 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3411 [(match_scratch:QI 3 "d")
3412 (set (match_operand:HI 0 "register_operand" "")
3413 (ashift:HI (match_operand:HI 1 "register_operand" "")
3414 (match_operand:QI 2 "const_int_operand" "")))]
3416 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3417 (clobber (match_dup 3))])]
3420 (define_insn "*ashlhi3_const"
3421 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3422 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3423 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3424 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3427 return ashlhi3_out (insn, operands, NULL);
3429 [(set_attr "length" "0,2,2,4,10")
3430 (set_attr "adjust_len" "ashlhi")
3431 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3434 [(match_scratch:QI 3 "d")
3435 (set (match_operand:SI 0 "register_operand" "")
3436 (ashift:SI (match_operand:SI 1 "register_operand" "")
3437 (match_operand:QI 2 "const_int_operand" "")))]
3439 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3440 (clobber (match_dup 3))])]
3443 (define_insn "*ashlsi3_const"
3444 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3445 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3446 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3447 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3450 return ashlsi3_out (insn, operands, NULL);
3452 [(set_attr "length" "0,4,4,10")
3453 (set_attr "adjust_len" "ashlsi")
3454 (set_attr "cc" "none,set_n,clobber,clobber")])
3456 (define_expand "ashlpsi3"
3457 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3458 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3459 (match_operand:QI 2 "nonmemory_operand" "")))
3460 (clobber (scratch:QI))])]
3464 && CONST_INT_P (operands[2]))
3466 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3468 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3469 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3472 else if (optimize_insn_for_speed_p ()
3473 && INTVAL (operands[2]) != 16
3474 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3476 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3477 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3483 (define_insn "*ashlpsi3"
3484 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3485 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3486 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3487 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3490 return avr_out_ashlpsi3 (insn, operands, NULL);
3492 [(set_attr "adjust_len" "ashlpsi")
3493 (set_attr "cc" "clobber")])
3495 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3496 ;; arithmetic shift right
3498 (define_insn "ashrqi3"
3499 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3500 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3501 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3504 return ashrqi3_out (insn, operands, NULL);
3506 [(set_attr "length" "5,0,1,2,5,4,9")
3507 (set_attr "adjust_len" "ashrqi")
3508 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3510 (define_insn "ashrhi3"
3511 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3512 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3513 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3516 return ashrhi3_out (insn, operands, NULL);
3518 [(set_attr "length" "6,0,2,4,4,10,10")
3519 (set_attr "adjust_len" "ashrhi")
3520 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3522 (define_insn "ashrpsi3"
3523 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3524 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3525 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3526 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3529 return avr_out_ashrpsi3 (insn, operands, NULL);
3531 [(set_attr "adjust_len" "ashrpsi")
3532 (set_attr "cc" "clobber")])
3534 (define_insn "ashrsi3"
3535 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3536 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3537 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3540 return ashrsi3_out (insn, operands, NULL);
3542 [(set_attr "length" "8,0,4,6,8,10,12")
3543 (set_attr "adjust_len" "ashrsi")
3544 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3546 ;; Optimize if a scratch register from LD_REGS happens to be available.
3549 [(match_scratch:QI 3 "d")
3550 (set (match_operand:HI 0 "register_operand" "")
3551 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3552 (match_operand:QI 2 "const_int_operand" "")))]
3554 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3555 (clobber (match_dup 3))])]
3558 (define_insn "*ashrhi3_const"
3559 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3560 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3561 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3562 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3565 return ashrhi3_out (insn, operands, NULL);
3567 [(set_attr "length" "0,2,4,4,10")
3568 (set_attr "adjust_len" "ashrhi")
3569 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3572 [(match_scratch:QI 3 "d")
3573 (set (match_operand:SI 0 "register_operand" "")
3574 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3575 (match_operand:QI 2 "const_int_operand" "")))]
3577 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3578 (clobber (match_dup 3))])]
3581 (define_insn "*ashrsi3_const"
3582 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3583 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3584 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3585 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3588 return ashrsi3_out (insn, operands, NULL);
3590 [(set_attr "length" "0,4,4,10")
3591 (set_attr "adjust_len" "ashrsi")
3592 (set_attr "cc" "none,clobber,set_n,clobber")])
3594 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3595 ;; logical shift right
3597 (define_expand "lshrqi3"
3598 [(set (match_operand:QI 0 "register_operand" "")
3599 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3600 (match_operand:QI 2 "nop_general_operand" "")))])
3602 (define_split ; lshrqi3_const4
3603 [(set (match_operand:QI 0 "d_register_operand" "")
3604 (lshiftrt:QI (match_dup 0)
3607 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3608 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3611 (define_split ; lshrqi3_const5
3612 [(set (match_operand:QI 0 "d_register_operand" "")
3613 (lshiftrt:QI (match_dup 0)
3616 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3617 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3618 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3621 (define_split ; lshrqi3_const6
3622 [(set (match_operand:QI 0 "d_register_operand" "")
3623 (lshiftrt:QI (match_dup 0)
3626 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3627 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3628 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3631 (define_insn "*lshrqi3"
3632 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3633 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3634 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3637 return lshrqi3_out (insn, operands, NULL);
3639 [(set_attr "length" "5,0,1,2,4,6,9")
3640 (set_attr "adjust_len" "lshrqi")
3641 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3643 (define_insn "lshrhi3"
3644 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3645 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3646 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3649 return lshrhi3_out (insn, operands, NULL);
3651 [(set_attr "length" "6,0,2,2,4,10,10")
3652 (set_attr "adjust_len" "lshrhi")
3653 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3655 (define_insn "lshrpsi3"
3656 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3657 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3658 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3659 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3662 return avr_out_lshrpsi3 (insn, operands, NULL);
3664 [(set_attr "adjust_len" "lshrpsi")
3665 (set_attr "cc" "clobber")])
3667 (define_insn "lshrsi3"
3668 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3669 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3670 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3673 return lshrsi3_out (insn, operands, NULL);
3675 [(set_attr "length" "8,0,4,4,8,10,12")
3676 (set_attr "adjust_len" "lshrsi")
3677 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3679 ;; Optimize if a scratch register from LD_REGS happens to be available.
3681 (define_peephole2 ; lshrqi3_l_const4
3682 [(set (match_operand:QI 0 "l_register_operand" "")
3683 (lshiftrt:QI (match_dup 0)
3685 (match_scratch:QI 1 "d")]
3687 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3688 (set (match_dup 1) (const_int 15))
3689 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3692 (define_peephole2 ; lshrqi3_l_const5
3693 [(set (match_operand:QI 0 "l_register_operand" "")
3694 (lshiftrt:QI (match_dup 0)
3696 (match_scratch:QI 1 "d")]
3698 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3699 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3700 (set (match_dup 1) (const_int 7))
3701 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3704 (define_peephole2 ; lshrqi3_l_const6
3705 [(set (match_operand:QI 0 "l_register_operand" "")
3706 (lshiftrt:QI (match_dup 0)
3708 (match_scratch:QI 1 "d")]
3710 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3711 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3712 (set (match_dup 1) (const_int 3))
3713 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3717 [(match_scratch:QI 3 "d")
3718 (set (match_operand:HI 0 "register_operand" "")
3719 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3720 (match_operand:QI 2 "const_int_operand" "")))]
3722 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3723 (clobber (match_dup 3))])]
3726 (define_insn "*lshrhi3_const"
3727 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3728 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3729 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3730 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3733 return lshrhi3_out (insn, operands, NULL);
3735 [(set_attr "length" "0,2,2,4,10")
3736 (set_attr "adjust_len" "lshrhi")
3737 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3740 [(match_scratch:QI 3 "d")
3741 (set (match_operand:SI 0 "register_operand" "")
3742 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3743 (match_operand:QI 2 "const_int_operand" "")))]
3745 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3746 (clobber (match_dup 3))])]
3749 (define_insn "*lshrsi3_const"
3750 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3751 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3752 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3753 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3756 return lshrsi3_out (insn, operands, NULL);
3758 [(set_attr "length" "0,4,4,10")
3759 (set_attr "adjust_len" "lshrsi")
3760 (set_attr "cc" "none,clobber,clobber,clobber")])
3762 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3765 (define_insn "absqi2"
3766 [(set (match_operand:QI 0 "register_operand" "=r")
3767 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3771 [(set_attr "length" "2")
3772 (set_attr "cc" "clobber")])
3775 (define_insn "abssf2"
3776 [(set (match_operand:SF 0 "register_operand" "=d,r")
3777 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3782 [(set_attr "length" "1,2")
3783 (set_attr "cc" "set_n,clobber")])
3785 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3788 (define_insn "negqi2"
3789 [(set (match_operand:QI 0 "register_operand" "=r")
3790 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3793 [(set_attr "length" "1")
3794 (set_attr "cc" "set_zn")])
3796 (define_insn "*negqihi2"
3797 [(set (match_operand:HI 0 "register_operand" "=r")
3798 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3800 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3801 [(set_attr "length" "4")
3802 (set_attr "cc" "set_n")])
3804 (define_insn "neghi2"
3805 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
3806 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
3809 com %B0\;neg %A0\;sbci %B0,lo8(-1)
3810 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
3811 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3812 [(set_attr "length" "3,4,4")
3813 (set_attr "cc" "set_czn,set_n,set_czn")])
3815 (define_insn "negpsi2"
3816 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3817 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3820 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3821 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3822 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3823 [(set_attr "length" "5,6,6")
3824 (set_attr "cc" "set_czn,set_n,set_czn")])
3826 (define_insn "negsi2"
3827 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3828 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
3831 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3832 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3833 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3834 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3835 [(set_attr "length" "7,8,8,7")
3836 (set_attr "isa" "*,*,mov,movw")
3837 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
3839 (define_insn "negsf2"
3840 [(set (match_operand:SF 0 "register_operand" "=d,r")
3841 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3845 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3846 [(set_attr "length" "1,4")
3847 (set_attr "cc" "set_n,set_n")])
3849 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3852 (define_insn "one_cmplqi2"
3853 [(set (match_operand:QI 0 "register_operand" "=r")
3854 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3857 [(set_attr "length" "1")
3858 (set_attr "cc" "set_czn")])
3860 (define_insn "one_cmplhi2"
3861 [(set (match_operand:HI 0 "register_operand" "=r")
3862 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3866 [(set_attr "length" "2")
3867 (set_attr "cc" "set_n")])
3869 (define_insn "one_cmplpsi2"
3870 [(set (match_operand:PSI 0 "register_operand" "=r")
3871 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3873 "com %0\;com %B0\;com %C0"
3874 [(set_attr "length" "3")
3875 (set_attr "cc" "set_n")])
3877 (define_insn "one_cmplsi2"
3878 [(set (match_operand:SI 0 "register_operand" "=r")
3879 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3885 [(set_attr "length" "4")
3886 (set_attr "cc" "set_n")])
3888 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3891 ;; We keep combiner from inserting hard registers into the input of sign- and
3892 ;; zero-extends. A hard register in the input operand is not wanted because
3893 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3894 ;; hard register that overlaps these clobbers won't be combined to a widening
3895 ;; multiplication. There is no need for combine to propagate hard registers,
3896 ;; register allocation can do it just as well.
3898 (define_insn "extendqihi2"
3899 [(set (match_operand:HI 0 "register_operand" "=r,r")
3900 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3903 clr %B0\;sbrc %0,7\;com %B0
3904 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3905 [(set_attr "length" "3,4")
3906 (set_attr "cc" "set_n,set_n")])
3908 (define_insn "extendqipsi2"
3909 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3910 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3913 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3914 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3915 [(set_attr "length" "4,5")
3916 (set_attr "cc" "set_n,set_n")])
3918 (define_insn "extendqisi2"
3919 [(set (match_operand:SI 0 "register_operand" "=r,r")
3920 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3923 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3924 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"