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 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
32 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
33 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
34 ;;..x..Constant Direct Program memory address.
35 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
36 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
45 (TMP_REGNO 0) ; temporary register r0
46 (ZERO_REGNO 1) ; zero register r1
52 (define_c_enum "unspec"
62 (define_c_enum "unspecv"
63 [UNSPECV_PROLOGUE_SAVES
64 UNSPECV_EPILOGUE_RESTORES
65 UNSPECV_WRITE_SP_IRQ_ON
66 UNSPECV_WRITE_SP_IRQ_OFF
76 (include "predicates.md")
77 (include "constraints.md")
79 ;; Condition code settings.
80 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
81 (const_string "none"))
83 (define_attr "type" "branch,branch1,arith,xcall"
84 (const_string "arith"))
86 (define_attr "mcu_have_movw" "yes,no"
87 (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
89 (const_string "no"))))
91 (define_attr "mcu_mega" "yes,no"
92 (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
94 (const_string "no"))))
97 ;; The size of instructions in bytes.
98 ;; XXX may depend from "cc"
100 (define_attr "length" ""
101 (cond [(eq_attr "type" "branch")
102 (if_then_else (and (ge (minus (pc) (match_dup 0))
104 (le (minus (pc) (match_dup 0))
107 (if_then_else (and (ge (minus (pc) (match_dup 0))
109 (le (minus (pc) (match_dup 0))
113 (eq_attr "type" "branch1")
114 (if_then_else (and (ge (minus (pc) (match_dup 0))
116 (le (minus (pc) (match_dup 0))
119 (if_then_else (and (ge (minus (pc) (match_dup 0))
121 (le (minus (pc) (match_dup 0))
125 (eq_attr "type" "xcall")
126 (if_then_else (eq_attr "mcu_mega" "no")
131 ;; Define mode iterators
132 (define_mode_iterator QIHI [(QI "") (HI "")])
133 (define_mode_iterator QIHI2 [(QI "") (HI "")])
134 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
135 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
136 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
137 (define_mode_iterator HISI [(HI "") (SI "")])
139 ;; Define code iterators
140 ;; Define two incarnations so that we can build the cross product.
141 (define_code_iterator any_extend [sign_extend zero_extend])
142 (define_code_iterator any_extend2 [sign_extend zero_extend])
144 ;; Define code attributes
145 (define_code_attr extend_su
149 (define_code_attr extend_u
154 ;;========================================================================
155 ;; The following is used by nonlocal_goto and setjmp.
156 ;; The receiver pattern will create no instructions since internally
157 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
158 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
159 ;; The 'null' receiver also avoids problems with optimisation
160 ;; not recognising incoming jmp and removing code that resets frame_pointer.
161 ;; The code derived from builtins.c.
163 (define_expand "nonlocal_goto_receiver"
165 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
168 emit_move_insn (virtual_stack_vars_rtx,
169 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
170 gen_int_mode (STARTING_FRAME_OFFSET,
172 /* This might change the hard frame pointer in ways that aren't
173 apparent to early optimization passes, so force a clobber. */
174 emit_clobber (hard_frame_pointer_rtx);
179 ;; Defining nonlocal_goto_receiver means we must also define this.
180 ;; even though its function is identical to that in builtins.c
182 (define_expand "nonlocal_goto"
184 (use (match_operand 0 "general_operand"))
185 (use (match_operand 1 "general_operand"))
186 (use (match_operand 2 "general_operand"))
187 (use (match_operand 3 "general_operand"))
191 rtx r_label = copy_to_reg (operands[1]);
192 rtx r_fp = operands[3];
193 rtx r_sp = operands[2];
195 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
197 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
199 emit_move_insn (hard_frame_pointer_rtx, r_fp);
200 emit_stack_restore (SAVE_NONLOCAL, r_sp);
202 emit_use (hard_frame_pointer_rtx);
203 emit_use (stack_pointer_rtx);
205 emit_indirect_jump (r_label);
210 (define_insn "pushqi1"
211 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
212 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
217 [(set_attr "length" "1,1")])
219 ;; All modes for a multi-byte push. We must include complex modes here too,
220 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
221 (define_mode_iterator MPUSH
228 (define_expand "push<mode>1"
229 [(match_operand:MPUSH 0 "" "")]
233 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
235 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
236 if (part != const0_rtx)
237 part = force_reg (QImode, part);
238 emit_insn (gen_pushqi1 (part));
243 ;; Notice a special-case when adding N to SP where N results in a
244 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
246 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
248 && frame_pointer_needed
249 && !cfun->calls_alloca
250 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
251 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
254 ;;========================================================================
256 ;; The last alternative (any immediate constant to any register) is
257 ;; very expensive. It should be optimized by peephole2 if a scratch
258 ;; register is available, but then that register could just as well be
259 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
260 ;; are call-saved registers, and most of LD_REGS are call-used registers,
261 ;; so this may still be a win for registers live across function calls.
263 (define_expand "movqi"
264 [(set (match_operand:QI 0 "nonimmediate_operand" "")
265 (match_operand:QI 1 "general_operand" ""))]
267 "/* One of the ops has to be in a register. */
268 if (!register_operand(operand0, QImode)
269 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
270 operands[1] = copy_to_mode_reg(QImode, operand1);
273 (define_insn "*movqi"
274 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
275 (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))]
276 "(register_operand (operands[0],QImode)
277 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
278 "* return output_movqi (insn, operands, NULL);"
279 [(set_attr "length" "1,1,5,5,1,1,4")
280 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
282 ;; This is used in peephole2 to optimize loading immediate constants
283 ;; if a scratch register from LD_REGS happens to be available.
285 (define_insn "*reload_inqi"
286 [(set (match_operand:QI 0 "register_operand" "=l")
287 (match_operand:QI 1 "immediate_operand" "i"))
288 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
292 [(set_attr "length" "2")
293 (set_attr "cc" "none")])
296 [(match_scratch:QI 2 "d")
297 (set (match_operand:QI 0 "l_register_operand" "")
298 (match_operand:QI 1 "immediate_operand" ""))]
299 "(operands[1] != const0_rtx
300 && operands[1] != const1_rtx
301 && operands[1] != constm1_rtx)"
302 [(parallel [(set (match_dup 0) (match_dup 1))
303 (clobber (match_dup 2))])]
306 ;;============================================================================
307 ;; move word (16 bit)
309 (define_expand "movhi"
310 [(set (match_operand:HI 0 "nonimmediate_operand" "")
311 (match_operand:HI 1 "general_operand" ""))]
315 /* One of the ops has to be in a register. */
316 if (!register_operand(operand0, HImode)
317 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
319 operands[1] = copy_to_mode_reg(HImode, operand1);
323 (define_insn "*movhi_sp"
324 [(set (match_operand:HI 0 "register_operand" "=q,r")
325 (match_operand:HI 1 "register_operand" "r,q"))]
326 "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
327 || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
328 "* return output_movhi (insn, operands, NULL);"
329 [(set_attr "length" "5,2")
330 (set_attr "cc" "none,none")])
332 (define_insn "movhi_sp_r_irq_off"
333 [(set (match_operand:HI 0 "stack_register_operand" "=q")
334 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
335 UNSPECV_WRITE_SP_IRQ_OFF))]
339 [(set_attr "length" "2")
340 (set_attr "cc" "none")])
342 (define_insn "movhi_sp_r_irq_on"
343 [(set (match_operand:HI 0 "stack_register_operand" "=q")
344 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
345 UNSPECV_WRITE_SP_IRQ_ON))]
351 [(set_attr "length" "4")
352 (set_attr "cc" "none")])
355 [(match_scratch:QI 2 "d")
356 (set (match_operand:HI 0 "l_register_operand" "")
357 (match_operand:HI 1 "immediate_operand" ""))]
358 "(operands[1] != const0_rtx
359 && operands[1] != constm1_rtx)"
360 [(parallel [(set (match_dup 0) (match_dup 1))
361 (clobber (match_dup 2))])]
364 ;; '*' because it is not used in rtl generation, only in above peephole
365 (define_insn "*reload_inhi"
366 [(set (match_operand:HI 0 "register_operand" "=r")
367 (match_operand:HI 1 "immediate_operand" "i"))
368 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
370 "* return output_reload_inhi (insn, operands, NULL);"
371 [(set_attr "length" "4")
372 (set_attr "cc" "none")])
374 (define_insn "*movhi"
375 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
376 (match_operand:HI 1 "general_operand" "rL,m,rL,i,i,r,q"))]
377 "(register_operand (operands[0],HImode)
378 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
379 "* return output_movhi (insn, operands, NULL);"
380 [(set_attr "length" "2,6,7,2,6,5,2")
381 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
383 (define_peephole2 ; movw
384 [(set (match_operand:QI 0 "even_register_operand" "")
385 (match_operand:QI 1 "even_register_operand" ""))
386 (set (match_operand:QI 2 "odd_register_operand" "")
387 (match_operand:QI 3 "odd_register_operand" ""))]
389 && REGNO (operands[0]) == REGNO (operands[2]) - 1
390 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
391 [(set (match_dup 4) (match_dup 5))]
393 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
394 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
397 (define_peephole2 ; movw_r
398 [(set (match_operand:QI 0 "odd_register_operand" "")
399 (match_operand:QI 1 "odd_register_operand" ""))
400 (set (match_operand:QI 2 "even_register_operand" "")
401 (match_operand:QI 3 "even_register_operand" ""))]
403 && REGNO (operands[2]) == REGNO (operands[0]) - 1
404 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
405 [(set (match_dup 4) (match_dup 5))]
407 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
408 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
411 ;;==========================================================================
412 ;; move double word (32 bit)
414 (define_expand "movsi"
415 [(set (match_operand:SI 0 "nonimmediate_operand" "")
416 (match_operand:SI 1 "general_operand" ""))]
420 /* One of the ops has to be in a register. */
421 if (!register_operand (operand0, SImode)
422 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
424 operands[1] = copy_to_mode_reg (SImode, operand1);
430 (define_peephole2 ; *reload_insi
431 [(match_scratch:QI 2 "d")
432 (set (match_operand:SI 0 "l_register_operand" "")
433 (match_operand:SI 1 "const_int_operand" ""))
435 "(operands[1] != const0_rtx
436 && operands[1] != constm1_rtx)"
437 [(parallel [(set (match_dup 0) (match_dup 1))
438 (clobber (match_dup 2))])]
441 ;; '*' because it is not used in rtl generation.
442 (define_insn "*reload_insi"
443 [(set (match_operand:SI 0 "register_operand" "=r")
444 (match_operand:SI 1 "const_int_operand" "n"))
445 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
448 return output_reload_insisf (insn, operands, operands[2], NULL);
450 [(set_attr "length" "8")
451 (set_attr "cc" "clobber")])
454 (define_insn "*movsi"
455 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
456 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
457 "(register_operand (operands[0],SImode)
458 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
460 return output_movsisf (insn, operands, NULL_RTX, NULL);
462 [(set_attr "length" "4,4,8,9,4,10")
463 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
465 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
466 ;; move floating point numbers (32 bit)
468 (define_expand "movsf"
469 [(set (match_operand:SF 0 "nonimmediate_operand" "")
470 (match_operand:SF 1 "general_operand" ""))]
474 /* One of the ops has to be in a register. */
475 if (!register_operand (operand1, SFmode)
476 && !register_operand (operand0, SFmode))
478 operands[1] = copy_to_mode_reg (SFmode, operand1);
482 (define_insn "*movsf"
483 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
484 (match_operand:SF 1 "general_operand" "r,G,Qm,rG,F,F"))]
485 "register_operand (operands[0], SFmode)
486 || register_operand (operands[1], SFmode)
487 || operands[1] == CONST0_RTX (SFmode)"
489 return output_movsisf (insn, operands, NULL_RTX, NULL);
491 [(set_attr "length" "4,4,8,9,4,10")
492 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
494 (define_peephole2 ; *reload_insf
495 [(match_scratch:QI 2 "d")
496 (set (match_operand:SF 0 "l_register_operand" "")
497 (match_operand:SF 1 "const_double_operand" ""))
499 "operands[1] != CONST0_RTX (SFmode)"
500 [(parallel [(set (match_dup 0)
502 (clobber (match_dup 2))])]
505 ;; '*' because it is not used in rtl generation.
506 (define_insn "*reload_insf"
507 [(set (match_operand:SF 0 "register_operand" "=r")
508 (match_operand:SF 1 "const_double_operand" "F"))
509 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
512 return output_reload_insisf (insn, operands, operands[2], NULL);
514 [(set_attr "length" "8")
515 (set_attr "cc" "clobber")])
517 ;;=========================================================================
518 ;; move string (like memcpy)
519 ;; implement as RTL loop
521 (define_expand "movmemhi"
522 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
523 (match_operand:BLK 1 "memory_operand" ""))
524 (use (match_operand:HI 2 "const_int_operand" ""))
525 (use (match_operand:HI 3 "const_int_operand" ""))])]
530 enum machine_mode mode;
531 rtx label = gen_label_rtx ();
535 /* Copy pointers into new psuedos - they will be changed. */
536 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
537 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
539 /* Create rtx for tmp register - we use this as scratch. */
540 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
542 if (GET_CODE (operands[2]) != CONST_INT)
545 count = INTVAL (operands[2]);
549 /* Work out branch probability for latter use. */
550 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
552 /* See if constant fit 8 bits. */
553 mode = (count < 0x100) ? QImode : HImode;
554 /* Create loop counter register. */
555 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
557 /* Now create RTL code for move loop. */
558 /* Label at top of loop. */
561 /* Move one byte into scratch and inc pointer. */
562 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
563 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
565 /* Move to mem and inc pointer. */
566 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
567 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
569 /* Decrement count. */
570 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
572 /* Compare with zero and jump if not equal. */
573 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
575 /* Set jump probability based on loop count. */
576 jump = get_last_insn ();
577 add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
581 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
582 ;; memset (%0, %2, %1)
584 (define_expand "setmemhi"
585 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
586 (match_operand 2 "const_int_operand" ""))
587 (use (match_operand:HI 1 "const_int_operand" ""))
588 (use (match_operand:HI 3 "const_int_operand" "n"))
589 (clobber (match_scratch:HI 4 ""))
590 (clobber (match_dup 5))])]
595 enum machine_mode mode;
597 /* If value to set is not zero, use the library routine. */
598 if (operands[2] != const0_rtx)
601 if (GET_CODE (operands[1]) != CONST_INT)
604 cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
605 mode = cnt8 ? QImode : HImode;
606 operands[5] = gen_rtx_SCRATCH (mode);
607 operands[1] = copy_to_mode_reg (mode,
608 gen_int_mode (INTVAL (operands[1]), mode));
609 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
610 operands[0] = gen_rtx_MEM (BLKmode, addr0);
613 (define_insn "*clrmemqi"
614 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
616 (use (match_operand:QI 1 "register_operand" "r"))
617 (use (match_operand:QI 2 "const_int_operand" "n"))
618 (clobber (match_scratch:HI 3 "=0"))
619 (clobber (match_scratch:QI 4 "=&1"))]
621 "st %a0+,__zero_reg__
624 [(set_attr "length" "3")
625 (set_attr "cc" "clobber")])
627 (define_insn "*clrmemhi"
628 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
630 (use (match_operand:HI 1 "register_operand" "!w,d"))
631 (use (match_operand:HI 2 "const_int_operand" "n,n"))
632 (clobber (match_scratch:HI 3 "=0,0"))
633 (clobber (match_scratch:HI 4 "=&1,&1"))]
636 if (which_alternative==0)
637 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
638 AS2 (sbiw,%A1,1) CR_TAB
641 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
642 AS2 (subi,%A1,1) CR_TAB
643 AS2 (sbci,%B1,0) CR_TAB
646 [(set_attr "length" "3,4")
647 (set_attr "cc" "clobber,clobber")])
649 (define_expand "strlenhi"
651 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
652 (match_operand:QI 2 "const_int_operand" "")
653 (match_operand:HI 3 "immediate_operand" "")]
655 (set (match_dup 4) (plus:HI (match_dup 4)
657 (set (match_operand:HI 0 "register_operand" "")
658 (minus:HI (match_dup 4)
663 if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
665 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
666 operands[1] = gen_rtx_MEM (BLKmode, addr);
668 operands[4] = gen_reg_rtx (HImode);
671 (define_insn "*strlenhi"
672 [(set (match_operand:HI 0 "register_operand" "=e")
673 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
675 (match_operand:HI 2 "immediate_operand" "i")]
681 [(set_attr "length" "3")
682 (set_attr "cc" "clobber")])
684 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
687 (define_insn "addqi3"
688 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
689 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
690 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
697 [(set_attr "length" "1,1,1,1")
698 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
701 (define_expand "addhi3"
702 [(set (match_operand:HI 0 "register_operand" "")
703 (plus:HI (match_operand:HI 1 "register_operand" "")
704 (match_operand:HI 2 "nonmemory_operand" "")))]
708 if (GET_CODE (operands[2]) == CONST_INT)
710 short tmp = INTVAL (operands[2]);
711 operands[2] = GEN_INT(tmp);
716 (define_insn "*addhi3_zero_extend"
717 [(set (match_operand:HI 0 "register_operand" "=r")
718 (plus:HI (zero_extend:HI
719 (match_operand:QI 1 "register_operand" "r"))
720 (match_operand:HI 2 "register_operand" "0")))]
723 adc %B0,__zero_reg__"
724 [(set_attr "length" "2")
725 (set_attr "cc" "set_n")])
727 (define_insn "*addhi3_zero_extend1"
728 [(set (match_operand:HI 0 "register_operand" "=r")
729 (plus:HI (match_operand:HI 1 "register_operand" "%0")
731 (match_operand:QI 2 "register_operand" "r"))))]
734 adc %B0,__zero_reg__"
735 [(set_attr "length" "2")
736 (set_attr "cc" "set_n")])
738 (define_insn "*addhi3_sp_R_pc2"
739 [(set (match_operand:HI 1 "stack_register_operand" "=q")
740 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
741 (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
744 if (CONST_INT_P (operands[0]))
746 switch(INTVAL (operands[0]))
749 return \"rcall .\" CR_TAB
753 return \"rcall .\" CR_TAB
755 \"push __tmp_reg__\";
757 return \"rcall .\" CR_TAB
760 return \"rcall .\" CR_TAB
761 \"push __tmp_reg__\";
765 return \"push __tmp_reg__\";
769 return \"pop __tmp_reg__\";
771 return \"pop __tmp_reg__\" CR_TAB
774 return \"pop __tmp_reg__\" CR_TAB
775 \"pop __tmp_reg__\" CR_TAB
778 return \"pop __tmp_reg__\" CR_TAB
779 \"pop __tmp_reg__\" CR_TAB
780 \"pop __tmp_reg__\" CR_TAB
783 return \"pop __tmp_reg__\" CR_TAB
784 \"pop __tmp_reg__\" CR_TAB
785 \"pop __tmp_reg__\" CR_TAB
786 \"pop __tmp_reg__\" CR_TAB
792 [(set (attr "length")
793 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
794 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
795 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
796 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
797 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
798 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
799 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
800 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
801 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
802 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
803 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
804 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
807 (define_insn "*addhi3_sp_R_pc3"
808 [(set (match_operand:HI 1 "stack_register_operand" "=q")
809 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
810 (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
813 if (CONST_INT_P (operands[0]))
815 switch(INTVAL (operands[0]))
818 return \"rcall .\" CR_TAB
821 return \"rcall .\" CR_TAB
822 \"push __tmp_reg__\" CR_TAB
823 \"push __tmp_reg__\";
825 return \"rcall .\" CR_TAB
826 \"push __tmp_reg__\";
830 return \"push __tmp_reg__\" CR_TAB
831 \"push __tmp_reg__\";
833 return \"push __tmp_reg__\";
837 return \"pop __tmp_reg__\";
839 return \"pop __tmp_reg__\" CR_TAB
842 return \"pop __tmp_reg__\" CR_TAB
843 \"pop __tmp_reg__\" CR_TAB
846 return \"pop __tmp_reg__\" CR_TAB
847 \"pop __tmp_reg__\" CR_TAB
848 \"pop __tmp_reg__\" CR_TAB
851 return \"pop __tmp_reg__\" CR_TAB
852 \"pop __tmp_reg__\" CR_TAB
853 \"pop __tmp_reg__\" CR_TAB
854 \"pop __tmp_reg__\" CR_TAB
860 [(set (attr "length")
861 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
862 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
863 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
864 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
865 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
866 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
867 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
868 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
869 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
870 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
871 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
872 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
875 (define_insn "*addhi3"
876 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
878 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
879 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
882 add %A0,%A2\;adc %B0,%B2
885 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
886 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
887 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
888 [(set_attr "length" "2,1,1,2,3,3")
889 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
891 (define_insn "addsi3"
892 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
894 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
895 (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
898 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
899 adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
900 sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
901 subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
902 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
903 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
904 [(set_attr "length" "4,3,3,4,5,5")
905 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
907 (define_insn "*addsi3_zero_extend"
908 [(set (match_operand:SI 0 "register_operand" "=r")
909 (plus:SI (zero_extend:SI
910 (match_operand:QI 1 "register_operand" "r"))
911 (match_operand:SI 2 "register_operand" "0")))]
916 adc %D0,__zero_reg__"
917 [(set_attr "length" "4")
918 (set_attr "cc" "set_n")])
920 ;-----------------------------------------------------------------------------
922 (define_insn "subqi3"
923 [(set (match_operand:QI 0 "register_operand" "=r,d")
924 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
925 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
930 [(set_attr "length" "1,1")
931 (set_attr "cc" "set_czn,set_czn")])
933 (define_insn "subhi3"
934 [(set (match_operand:HI 0 "register_operand" "=r,d")
935 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
936 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
939 sub %A0,%A2\;sbc %B0,%B2
940 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
941 [(set_attr "length" "2,2")
942 (set_attr "cc" "set_czn,set_czn")])
944 (define_insn "*subhi3_zero_extend1"
945 [(set (match_operand:HI 0 "register_operand" "=r")
946 (minus:HI (match_operand:HI 1 "register_operand" "0")
948 (match_operand:QI 2 "register_operand" "r"))))]
951 sbc %B0,__zero_reg__"
952 [(set_attr "length" "2")
953 (set_attr "cc" "set_n")])
955 (define_insn "subsi3"
956 [(set (match_operand:SI 0 "register_operand" "=r,d")
957 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
958 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
961 sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
962 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
963 [(set_attr "length" "4,4")
964 (set_attr "cc" "set_czn,set_czn")])
966 (define_insn "*subsi3_zero_extend"
967 [(set (match_operand:SI 0 "register_operand" "=r")
968 (minus:SI (match_operand:SI 1 "register_operand" "0")
970 (match_operand:QI 2 "register_operand" "r"))))]
975 sbc %D0,__zero_reg__"
976 [(set_attr "length" "4")
977 (set_attr "cc" "set_n")])
979 ;******************************************************************************
982 (define_expand "mulqi3"
983 [(set (match_operand:QI 0 "register_operand" "")
984 (mult:QI (match_operand:QI 1 "register_operand" "")
985 (match_operand:QI 2 "register_operand" "")))]
990 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
995 (define_insn "*mulqi3_enh"
996 [(set (match_operand:QI 0 "register_operand" "=r")
997 (mult:QI (match_operand:QI 1 "register_operand" "r")
998 (match_operand:QI 2 "register_operand" "r")))]
1003 [(set_attr "length" "3")
1004 (set_attr "cc" "clobber")])
1006 (define_expand "mulqi3_call"
1007 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1008 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1009 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1010 (clobber (reg:QI 22))])
1011 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1015 (define_insn "*mulqi3_call"
1016 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1017 (clobber (reg:QI 22))]
1020 [(set_attr "type" "xcall")
1021 (set_attr "cc" "clobber")])
1023 (define_insn "smulqi3_highpart"
1024 [(set (match_operand:QI 0 "register_operand" "=r")
1026 (lshiftrt:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1027 (sign_extend:HI (match_operand:QI 2 "register_operand" "d")))
1033 [(set_attr "length" "3")
1034 (set_attr "cc" "clobber")])
1036 (define_insn "umulqi3_highpart"
1037 [(set (match_operand:QI 0 "register_operand" "=r")
1039 (lshiftrt:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1040 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))
1046 [(set_attr "length" "3")
1047 (set_attr "cc" "clobber")])
1049 ;; Used when expanding div or mod inline for some special values
1050 (define_insn "*subqi3.ashiftrt7"
1051 [(set (match_operand:QI 0 "register_operand" "=r")
1052 (minus:QI (match_operand:QI 1 "register_operand" "0")
1053 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1057 [(set_attr "length" "2")
1058 (set_attr "cc" "clobber")])
1060 (define_insn "mulqihi3"
1061 [(set (match_operand:HI 0 "register_operand" "=r")
1062 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1063 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
1068 [(set_attr "length" "3")
1069 (set_attr "cc" "clobber")])
1071 (define_insn "umulqihi3"
1072 [(set (match_operand:HI 0 "register_operand" "=r")
1073 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1074 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1079 [(set_attr "length" "3")
1080 (set_attr "cc" "clobber")])
1082 (define_insn "usmulqihi3"
1083 [(set (match_operand:HI 0 "register_operand" "=r")
1084 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1085 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1090 [(set_attr "length" "3")
1091 (set_attr "cc" "clobber")])
1093 ;; Above insn is not canonicalized by insn combine, so here is a version with
1094 ;; operands swapped.
1096 (define_insn "*sumulqihi3"
1097 [(set (match_operand:HI 0 "register_operand" "=r")
1098 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1099 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1104 [(set_attr "length" "3")
1105 (set_attr "cc" "clobber")])
1107 ;; One-extend operand 1
1109 (define_insn "*osmulqihi3"
1110 [(set (match_operand:HI 0 "register_operand" "=&r")
1111 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1112 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1118 [(set_attr "length" "4")
1119 (set_attr "cc" "clobber")])
1121 (define_insn "*oumulqihi3"
1122 [(set (match_operand:HI 0 "register_operand" "=&r")
1123 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1124 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1130 [(set_attr "length" "4")
1131 (set_attr "cc" "clobber")])
1134 ;******************************************************************************
1135 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1136 ;******************************************************************************
1138 (define_insn_and_split "*muluqihi3.uconst"
1139 [(set (match_operand:HI 0 "register_operand" "=r")
1140 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1141 (match_operand:HI 2 "u8_operand" "M")))
1142 (clobber (match_scratch:QI 3 "=&d"))]
1145 "&& reload_completed"
1150 (mult:HI (zero_extend:HI (match_dup 1))
1151 (zero_extend:HI (match_dup 3))))]
1153 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1156 (define_insn_and_split "*muluqihi3.sconst"
1157 [(set (match_operand:HI 0 "register_operand" "=r")
1158 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1159 (match_operand:HI 2 "s8_operand" "n")))
1160 (clobber (match_scratch:QI 3 "=&a"))]
1163 "&& reload_completed"
1168 (mult:HI (zero_extend:HI (match_dup 1))
1169 (sign_extend:HI (match_dup 3))))]
1171 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1174 (define_insn_and_split "*mulsqihi3.sconst"
1175 [(set (match_operand:HI 0 "register_operand" "=r")
1176 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1177 (match_operand:HI 2 "s8_operand" "n")))
1178 (clobber (match_scratch:QI 3 "=&d"))]
1181 "&& reload_completed"
1186 (mult:HI (sign_extend:HI (match_dup 1))
1187 (sign_extend:HI (match_dup 3))))]
1189 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1192 (define_insn_and_split "*mulsqihi3.uconst"
1193 [(set (match_operand:HI 0 "register_operand" "=r")
1194 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1195 (match_operand:HI 2 "u8_operand" "M")))
1196 (clobber (match_scratch:QI 3 "=&a"))]
1199 "&& reload_completed"
1204 (mult:HI (zero_extend:HI (match_dup 3))
1205 (sign_extend:HI (match_dup 1))))]
1207 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1210 (define_insn_and_split "*mulsqihi3.oconst"
1211 [(set (match_operand:HI 0 "register_operand" "=&r")
1212 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1213 (match_operand:HI 2 "o8_operand" "n")))
1214 (clobber (match_scratch:QI 3 "=&a"))]
1217 "&& reload_completed"
1222 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1223 (sign_extend:HI (match_dup 1))))]
1225 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1228 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1229 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1230 ;; at that time. Fix that.
1232 (define_insn_and_split "*ashifthi3.signx.const"
1233 [(set (match_operand:HI 0 "register_operand" "=r")
1234 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1235 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1236 (clobber (match_scratch:QI 3 "=&d"))]
1239 "&& reload_completed"
1244 (mult:HI (sign_extend:HI (match_dup 1))
1245 (sign_extend:HI (match_dup 3))))]
1247 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1250 (define_insn_and_split "*ashifthi3.signx.const7"
1251 [(set (match_operand:HI 0 "register_operand" "=r")
1252 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1254 (clobber (match_scratch:QI 2 "=&a"))]
1257 "&& reload_completed"
1262 (mult:HI (zero_extend:HI (match_dup 2))
1263 (sign_extend:HI (match_dup 1))))]
1265 operands[3] = gen_int_mode (1 << 7, QImode);
1268 (define_insn_and_split "*ashifthi3.zerox.const"
1269 [(set (match_operand:HI 0 "register_operand" "=r")
1270 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1271 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1272 (clobber (match_scratch:QI 3 "=&d"))]
1275 "&& reload_completed"
1280 (mult:HI (zero_extend:HI (match_dup 1))
1281 (zero_extend:HI (match_dup 3))))]
1283 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1286 ;******************************************************************************
1287 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1288 ;******************************************************************************
1290 (define_insn "mulsqihi3"
1291 [(set (match_operand:HI 0 "register_operand" "=&r")
1292 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1293 (match_operand:HI 2 "register_operand" "a")))]
1300 [(set_attr "length" "5")
1301 (set_attr "cc" "clobber")])
1303 (define_insn "muluqihi3"
1304 [(set (match_operand:HI 0 "register_operand" "=&r")
1305 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1306 (match_operand:HI 2 "register_operand" "r")))]
1313 [(set_attr "length" "5")
1314 (set_attr "cc" "clobber")])
1316 ;; one-extend operand 1
1318 (define_insn "muloqihi3"
1319 [(set (match_operand:HI 0 "register_operand" "=&r")
1320 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1321 (match_operand:HI 2 "register_operand" "r")))]
1329 [(set_attr "length" "6")
1330 (set_attr "cc" "clobber")])
1332 ;******************************************************************************
1334 (define_expand "mulhi3"
1335 [(set (match_operand:HI 0 "register_operand" "")
1336 (mult:HI (match_operand:HI 1 "register_operand" "")
1337 (match_operand:HI 2 "register_or_s9_operand" "")))]
1342 if (!register_operand (operands[2], HImode))
1343 operands[2] = force_reg (HImode, operands[2]);
1345 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1349 /* For small constants we can do better by extending them on the fly.
1350 The constant can be loaded in one instruction and the widening
1351 multiplication is shorter. First try the unsigned variant because it
1352 allows constraint "d" instead of "a" for the signed version. */
1354 if (s9_operand (operands[2], HImode))
1356 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1358 if (u8_operand (operands[2], HImode))
1360 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1362 else if (s8_operand (operands[2], HImode))
1364 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1368 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1374 if (!register_operand (operands[2], HImode))
1375 operands[2] = force_reg (HImode, operands[2]);
1378 (define_insn "*mulhi3_enh"
1379 [(set (match_operand:HI 0 "register_operand" "=&r")
1380 (mult:HI (match_operand:HI 1 "register_operand" "r")
1381 (match_operand:HI 2 "register_operand" "r")))]
1390 [(set_attr "length" "7")
1391 (set_attr "cc" "clobber")])
1393 (define_expand "mulhi3_call"
1394 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1395 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1396 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1397 (clobber (reg:HI 22))
1398 (clobber (reg:QI 21))])
1399 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1403 (define_insn "*mulhi3_call"
1404 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1405 (clobber (reg:HI 22))
1406 (clobber (reg:QI 21))]
1409 [(set_attr "type" "xcall")
1410 (set_attr "cc" "clobber")])
1412 ;; To support widening multiplicatioon with constant we postpone
1413 ;; expanding to the implicit library call until post combine and
1414 ;; prior to register allocation. Clobber all hard registers that
1415 ;; might be used by the (widening) multiply until it is split and
1416 ;; it's final register footprint is worked out.
1418 (define_expand "mulsi3"
1419 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1420 (mult:SI (match_operand:SI 1 "register_operand" "")
1421 (match_operand:SI 2 "nonmemory_operand" "")))
1422 (clobber (reg:HI 26))
1423 (clobber (reg:DI 18))])]
1426 if (u16_operand (operands[2], SImode))
1428 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1429 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1433 if (o16_operand (operands[2], SImode))
1435 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1436 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1441 (define_insn_and_split "*mulsi3"
1442 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1443 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
1444 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1445 (clobber (reg:HI 26))
1446 (clobber (reg:DI 18))]
1447 "AVR_HAVE_MUL && !reload_completed"
1448 { gcc_unreachable(); }
1454 (parallel [(set (reg:SI 22)
1455 (mult:SI (reg:SI 22)
1457 (clobber (reg:HI 26))])
1461 if (u16_operand (operands[2], SImode))
1463 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1464 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1468 if (o16_operand (operands[2], SImode))
1470 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1471 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1478 (define_insn_and_split "mulu<mode>si3"
1479 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1480 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1481 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1482 (clobber (reg:HI 26))
1483 (clobber (reg:DI 18))]
1484 "AVR_HAVE_MUL && !reload_completed"
1485 { gcc_unreachable(); }
1492 (mult:SI (zero_extend:SI (reg:HI 26))
1497 /* Do the QI -> HI extension explicitely before the multiplication. */
1498 /* Do the HI -> SI extension implicitely and after the multiplication. */
1500 if (QImode == <MODE>mode)
1501 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
1503 if (u16_operand (operands[2], SImode))
1505 operands[1] = force_reg (HImode, operands[1]);
1506 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1507 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
1514 (define_insn_and_split "muls<mode>si3"
1515 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1516 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1517 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1518 (clobber (reg:HI 26))
1519 (clobber (reg:DI 18))]
1520 "AVR_HAVE_MUL && !reload_completed"
1521 { gcc_unreachable(); }
1528 (mult:SI (sign_extend:SI (reg:HI 26))
1533 /* Do the QI -> HI extension explicitely before the multiplication. */
1534 /* Do the HI -> SI extension implicitely and after the multiplication. */
1536 if (QImode == <MODE>mode)
1537 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
1539 if (u16_operand (operands[2], SImode)
1540 || s16_operand (operands[2], SImode))
1542 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1544 operands[1] = force_reg (HImode, operands[1]);
1546 if (u16_operand (operands[2], SImode))
1547 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
1549 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
1555 ;; One-extend operand 1
1557 (define_insn_and_split "mulohisi3"
1558 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1559 (mult:SI (not:SI (zero_extend:SI
1560 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
1561 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1562 (clobber (reg:HI 26))
1563 (clobber (reg:DI 18))]
1564 "AVR_HAVE_MUL && !reload_completed"
1565 { gcc_unreachable(); }
1572 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1580 (define_expand "<extend_u>mulhisi3"
1581 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1582 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
1583 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
1584 (clobber (reg:HI 26))
1585 (clobber (reg:DI 18))])]
1589 (define_expand "usmulhisi3"
1590 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1591 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1592 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1593 (clobber (reg:HI 26))
1594 (clobber (reg:DI 18))])]
1598 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
1599 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
1600 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
1601 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
1602 (define_insn_and_split
1603 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
1604 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1605 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1606 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
1607 (clobber (reg:HI 26))
1608 (clobber (reg:DI 18))]
1609 "AVR_HAVE_MUL && !reload_completed"
1610 { gcc_unreachable(); }
1617 (mult:SI (match_dup 3)
1622 rtx xop1 = operands[1];
1623 rtx xop2 = operands[2];
1625 /* Do the QI -> HI extension explicitely before the multiplication. */
1626 /* Do the HI -> SI extension implicitely and after the multiplication. */
1628 if (QImode == <QIHI:MODE>mode)
1629 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
1631 if (QImode == <QIHI2:MODE>mode)
1632 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
1634 if (<any_extend:CODE> == <any_extend2:CODE>
1635 || <any_extend:CODE> == ZERO_EXTEND)
1639 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
1640 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
1644 /* <any_extend:CODE> = SIGN_EXTEND */
1645 /* <any_extend2:CODE> = ZERO_EXTEND */
1649 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
1650 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
1654 ;; "smulhi3_highpart"
1655 ;; "umulhi3_highpart"
1656 (define_expand "<extend_su>mulhi3_highpart"
1658 (match_operand:HI 1 "nonmemory_operand" ""))
1660 (match_operand:HI 2 "nonmemory_operand" ""))
1661 (parallel [(set (reg:HI 24)
1662 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1663 (any_extend:SI (reg:HI 26)))
1665 (clobber (reg:HI 22))])
1666 (set (match_operand:HI 0 "register_operand" "")
1672 (define_insn "*mulsi3_call"
1674 (mult:SI (reg:SI 22)
1676 (clobber (reg:HI 26))]
1679 [(set_attr "type" "xcall")
1680 (set_attr "cc" "clobber")])
1683 ;; "*umulhisi3_call"
1684 (define_insn "*<extend_u>mulhisi3_call"
1686 (mult:SI (any_extend:SI (reg:HI 18))
1687 (any_extend:SI (reg:HI 26))))]
1689 "%~call __<extend_u>mulhisi3"
1690 [(set_attr "type" "xcall")
1691 (set_attr "cc" "clobber")])
1693 ;; "*umulhi3_highpart_call"
1694 ;; "*smulhi3_highpart_call"
1695 (define_insn "*<extend_su>mulhi3_highpart_call"
1697 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1698 (any_extend:SI (reg:HI 26)))
1700 (clobber (reg:HI 22))]
1702 "%~call __<extend_u>mulhisi3"
1703 [(set_attr "type" "xcall")
1704 (set_attr "cc" "clobber")])
1706 (define_insn "*usmulhisi3_call"
1708 (mult:SI (zero_extend:SI (reg:HI 18))
1709 (sign_extend:SI (reg:HI 26))))]
1711 "%~call __usmulhisi3"
1712 [(set_attr "type" "xcall")
1713 (set_attr "cc" "clobber")])
1715 (define_insn "*mul<extend_su>hisi3_call"
1717 (mult:SI (any_extend:SI (reg:HI 26))
1720 "%~call __mul<extend_su>hisi3"
1721 [(set_attr "type" "xcall")
1722 (set_attr "cc" "clobber")])
1724 (define_insn "*mulohisi3_call"
1726 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1729 "%~call __mulohisi3"
1730 [(set_attr "type" "xcall")
1731 (set_attr "cc" "clobber")])
1733 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1736 ;; Generate libgcc.S calls ourselves, because:
1737 ;; - we know exactly which registers are clobbered (for QI and HI
1738 ;; modes, some of the call-used registers are preserved)
1739 ;; - we get both the quotient and the remainder at no extra cost
1740 ;; - we split the patterns only after the first CSE passes because
1741 ;; CSE has problems to operate on hard regs.
1743 (define_insn_and_split "divmodqi4"
1744 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1745 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
1746 (match_operand:QI 2 "pseudo_register_operand" "")))
1747 (set (match_operand:QI 3 "pseudo_register_operand" "")
1748 (mod:QI (match_dup 1) (match_dup 2)))
1749 (clobber (reg:QI 22))
1750 (clobber (reg:QI 23))
1751 (clobber (reg:QI 24))
1752 (clobber (reg:QI 25))])]
1754 "this divmodqi4 pattern should have been splitted;"
1756 [(set (reg:QI 24) (match_dup 1))
1757 (set (reg:QI 22) (match_dup 2))
1758 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1759 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1760 (clobber (reg:QI 22))
1761 (clobber (reg:QI 23))])
1762 (set (match_dup 0) (reg:QI 24))
1763 (set (match_dup 3) (reg:QI 25))]
1766 (define_insn "*divmodqi4_call"
1767 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1768 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1769 (clobber (reg:QI 22))
1770 (clobber (reg:QI 23))]
1772 "%~call __divmodqi4"
1773 [(set_attr "type" "xcall")
1774 (set_attr "cc" "clobber")])
1776 (define_insn_and_split "udivmodqi4"
1777 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1778 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
1779 (match_operand:QI 2 "pseudo_register_operand" "")))
1780 (set (match_operand:QI 3 "pseudo_register_operand" "")
1781 (umod:QI (match_dup 1) (match_dup 2)))
1782 (clobber (reg:QI 22))
1783 (clobber (reg:QI 23))
1784 (clobber (reg:QI 24))
1785 (clobber (reg:QI 25))])]
1787 "this udivmodqi4 pattern should have been splitted;"
1789 [(set (reg:QI 24) (match_dup 1))
1790 (set (reg:QI 22) (match_dup 2))
1791 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1792 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1793 (clobber (reg:QI 23))])
1794 (set (match_dup 0) (reg:QI 24))
1795 (set (match_dup 3) (reg:QI 25))]
1798 (define_insn "*udivmodqi4_call"
1799 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1800 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1801 (clobber (reg:QI 23))]
1803 "%~call __udivmodqi4"
1804 [(set_attr "type" "xcall")
1805 (set_attr "cc" "clobber")])
1807 (define_insn_and_split "divmodhi4"
1808 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1809 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
1810 (match_operand:HI 2 "pseudo_register_operand" "")))
1811 (set (match_operand:HI 3 "pseudo_register_operand" "")
1812 (mod:HI (match_dup 1) (match_dup 2)))
1813 (clobber (reg:QI 21))
1814 (clobber (reg:HI 22))
1815 (clobber (reg:HI 24))
1816 (clobber (reg:HI 26))])]
1818 "this should have been splitted;"
1820 [(set (reg:HI 24) (match_dup 1))
1821 (set (reg:HI 22) (match_dup 2))
1822 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1823 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1824 (clobber (reg:HI 26))
1825 (clobber (reg:QI 21))])
1826 (set (match_dup 0) (reg:HI 22))
1827 (set (match_dup 3) (reg:HI 24))]
1830 (define_insn "*divmodhi4_call"
1831 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1832 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1833 (clobber (reg:HI 26))
1834 (clobber (reg:QI 21))]
1836 "%~call __divmodhi4"
1837 [(set_attr "type" "xcall")
1838 (set_attr "cc" "clobber")])
1840 (define_insn_and_split "udivmodhi4"
1841 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1842 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
1843 (match_operand:HI 2 "pseudo_register_operand" "")))
1844 (set (match_operand:HI 3 "pseudo_register_operand" "")
1845 (umod:HI (match_dup 1) (match_dup 2)))
1846 (clobber (reg:QI 21))
1847 (clobber (reg:HI 22))
1848 (clobber (reg:HI 24))
1849 (clobber (reg:HI 26))])]
1851 "this udivmodhi4 pattern should have been splitted.;"
1853 [(set (reg:HI 24) (match_dup 1))
1854 (set (reg:HI 22) (match_dup 2))
1855 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1856 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1857 (clobber (reg:HI 26))
1858 (clobber (reg:QI 21))])
1859 (set (match_dup 0) (reg:HI 22))
1860 (set (match_dup 3) (reg:HI 24))]
1863 (define_insn "*udivmodhi4_call"
1864 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1865 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1866 (clobber (reg:HI 26))
1867 (clobber (reg:QI 21))]
1869 "%~call __udivmodhi4"
1870 [(set_attr "type" "xcall")
1871 (set_attr "cc" "clobber")])
1873 (define_insn_and_split "divmodsi4"
1874 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1875 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
1876 (match_operand:SI 2 "pseudo_register_operand" "")))
1877 (set (match_operand:SI 3 "pseudo_register_operand" "")
1878 (mod:SI (match_dup 1) (match_dup 2)))
1879 (clobber (reg:SI 18))
1880 (clobber (reg:SI 22))
1881 (clobber (reg:HI 26))
1882 (clobber (reg:HI 30))])]
1884 "this divmodsi4 pattern should have been splitted;"
1886 [(set (reg:SI 22) (match_dup 1))
1887 (set (reg:SI 18) (match_dup 2))
1888 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1889 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1890 (clobber (reg:HI 26))
1891 (clobber (reg:HI 30))])
1892 (set (match_dup 0) (reg:SI 18))
1893 (set (match_dup 3) (reg:SI 22))]
1896 (define_insn "*divmodsi4_call"
1897 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1898 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1899 (clobber (reg:HI 26))
1900 (clobber (reg:HI 30))]
1902 "%~call __divmodsi4"
1903 [(set_attr "type" "xcall")
1904 (set_attr "cc" "clobber")])
1906 (define_insn_and_split "udivmodsi4"
1907 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1908 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
1909 (match_operand:SI 2 "pseudo_register_operand" "")))
1910 (set (match_operand:SI 3 "pseudo_register_operand" "")
1911 (umod:SI (match_dup 1) (match_dup 2)))
1912 (clobber (reg:SI 18))
1913 (clobber (reg:SI 22))
1914 (clobber (reg:HI 26))
1915 (clobber (reg:HI 30))])]
1917 "this udivmodsi4 pattern should have been splitted;"
1919 [(set (reg:SI 22) (match_dup 1))
1920 (set (reg:SI 18) (match_dup 2))
1921 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1922 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1923 (clobber (reg:HI 26))
1924 (clobber (reg:HI 30))])
1925 (set (match_dup 0) (reg:SI 18))
1926 (set (match_dup 3) (reg:SI 22))]
1929 (define_insn "*udivmodsi4_call"
1930 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1931 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1932 (clobber (reg:HI 26))
1933 (clobber (reg:HI 30))]
1935 "%~call __udivmodsi4"
1936 [(set_attr "type" "xcall")
1937 (set_attr "cc" "clobber")])
1939 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1942 (define_insn "andqi3"
1943 [(set (match_operand:QI 0 "register_operand" "=r,d")
1944 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1945 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1950 [(set_attr "length" "1,1")
1951 (set_attr "cc" "set_zn,set_zn")])
1953 (define_insn "andhi3"
1954 [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1955 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1956 (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1957 (clobber (match_scratch:QI 3 "=X,X,&d"))]
1960 if (which_alternative==0)
1961 return ("and %A0,%A2" CR_TAB
1963 else if (which_alternative==1)
1965 if (GET_CODE (operands[2]) == CONST_INT)
1967 int mask = INTVAL (operands[2]);
1968 if ((mask & 0xff) != 0xff)
1969 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1970 if ((mask & 0xff00) != 0xff00)
1971 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1974 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1975 AS2 (andi,%B0,hi8(%2)));
1977 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1981 [(set_attr "length" "2,2,3")
1982 (set_attr "cc" "set_n,clobber,set_n")])
1984 (define_insn "andsi3"
1985 [(set (match_operand:SI 0 "register_operand" "=r,d")
1986 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1987 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1990 if (which_alternative==0)
1991 return ("and %0,%2" CR_TAB
1992 "and %B0,%B2" CR_TAB
1993 "and %C0,%C2" CR_TAB
1995 else if (which_alternative==1)
1997 if (GET_CODE (operands[2]) == CONST_INT)
1999 HOST_WIDE_INT mask = INTVAL (operands[2]);
2000 if ((mask & 0xff) != 0xff)
2001 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
2002 if ((mask & 0xff00) != 0xff00)
2003 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
2004 if ((mask & 0xff0000L) != 0xff0000L)
2005 output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
2006 if ((mask & 0xff000000L) != 0xff000000L)
2007 output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
2010 return (AS2 (andi, %A0,lo8(%2)) CR_TAB
2011 AS2 (andi, %B0,hi8(%2)) CR_TAB
2012 AS2 (andi, %C0,hlo8(%2)) CR_TAB
2013 AS2 (andi, %D0,hhi8(%2)));
2017 [(set_attr "length" "4,4")
2018 (set_attr "cc" "set_n,clobber")])
2020 (define_peephole2 ; andi
2021 [(set (match_operand:QI 0 "d_register_operand" "")
2022 (and:QI (match_dup 0)
2023 (match_operand:QI 1 "const_int_operand" "")))
2025 (and:QI (match_dup 0)
2026 (match_operand:QI 2 "const_int_operand" "")))]
2028 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2030 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2033 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2036 (define_insn "iorqi3"
2037 [(set (match_operand:QI 0 "register_operand" "=r,d")
2038 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2039 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2044 [(set_attr "length" "1,1")
2045 (set_attr "cc" "set_zn,set_zn")])
2047 (define_insn "iorhi3"
2048 [(set (match_operand:HI 0 "register_operand" "=r,d")
2049 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2050 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
2053 if (which_alternative==0)
2054 return ("or %A0,%A2" CR_TAB
2056 if (GET_CODE (operands[2]) == CONST_INT)
2058 int mask = INTVAL (operands[2]);
2060 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2062 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2065 return (AS2 (ori,%0,lo8(%2)) CR_TAB
2066 AS2 (ori,%B0,hi8(%2)));
2068 [(set_attr "length" "2,2")
2069 (set_attr "cc" "set_n,clobber")])
2071 (define_insn "*iorhi3_clobber"
2072 [(set (match_operand:HI 0 "register_operand" "=r,r")
2073 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2074 (match_operand:HI 2 "immediate_operand" "M,i")))
2075 (clobber (match_scratch:QI 3 "=&d,&d"))]
2078 ldi %3,lo8(%2)\;or %A0,%3
2079 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
2080 [(set_attr "length" "2,4")
2081 (set_attr "cc" "clobber,set_n")])
2083 (define_insn "iorsi3"
2084 [(set (match_operand:SI 0 "register_operand" "=r,d")
2085 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2086 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
2089 if (which_alternative==0)
2090 return ("or %0,%2" CR_TAB
2094 if (GET_CODE (operands[2]) == CONST_INT)
2096 HOST_WIDE_INT mask = INTVAL (operands[2]);
2098 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2100 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2101 if (mask & 0xff0000L)
2102 output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
2103 if (mask & 0xff000000L)
2104 output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
2107 return (AS2 (ori, %A0,lo8(%2)) CR_TAB
2108 AS2 (ori, %B0,hi8(%2)) CR_TAB
2109 AS2 (ori, %C0,hlo8(%2)) CR_TAB
2110 AS2 (ori, %D0,hhi8(%2)));
2112 [(set_attr "length" "4,4")
2113 (set_attr "cc" "set_n,clobber")])
2115 (define_insn "*iorsi3_clobber"
2116 [(set (match_operand:SI 0 "register_operand" "=r,r")
2117 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2118 (match_operand:SI 2 "immediate_operand" "M,i")))
2119 (clobber (match_scratch:QI 3 "=&d,&d"))]
2122 ldi %3,lo8(%2)\;or %A0,%3
2123 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3"
2124 [(set_attr "length" "2,8")
2125 (set_attr "cc" "clobber,set_n")])
2127 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2130 (define_insn "xorqi3"
2131 [(set (match_operand:QI 0 "register_operand" "=r")
2132 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2133 (match_operand:QI 2 "register_operand" "r")))]
2136 [(set_attr "length" "1")
2137 (set_attr "cc" "set_zn")])
2139 (define_insn "xorhi3"
2140 [(set (match_operand:HI 0 "register_operand" "=r")
2141 (xor:HI (match_operand:HI 1 "register_operand" "%0")
2142 (match_operand:HI 2 "register_operand" "r")))]
2146 [(set_attr "length" "2")
2147 (set_attr "cc" "set_n")])
2149 (define_insn "xorsi3"
2150 [(set (match_operand:SI 0 "register_operand" "=r")
2151 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2152 (match_operand:SI 2 "register_operand" "r")))]
2158 [(set_attr "length" "4")
2159 (set_attr "cc" "set_n")])
2161 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
2164 (define_expand "rotlqi3"
2165 [(set (match_operand:QI 0 "register_operand" "")
2166 (rotate:QI (match_operand:QI 1 "register_operand" "")
2167 (match_operand:QI 2 "const_int_operand" "")))]
2171 if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
2175 (define_insn "rotlqi3_4"
2176 [(set (match_operand:QI 0 "register_operand" "=r")
2177 (rotate:QI (match_operand:QI 1 "register_operand" "0")
2181 [(set_attr "length" "1")
2182 (set_attr "cc" "none")])
2184 ;; Split all rotates of HI,SI and DImode registers where rotation is by
2185 ;; a whole number of bytes. The split creates the appropriate moves and
2186 ;; considers all overlap situations. DImode is split before reload.
2188 ;; HImode does not need scratch. Use attribute for this constraint.
2189 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
2191 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
2192 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
2194 (define_expand "rotl<mode>3"
2195 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
2196 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2197 (match_operand:VOID 2 "const_int_operand" "")))
2198 (clobber (match_dup 3))])]
2201 if (CONST_INT_P (operands[2])
2202 && 0 == INTVAL (operands[2]) % 8)
2204 if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
2205 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2207 operands[3] = gen_rtx_SCRATCH (QImode);
2214 ;; Overlapping non-HImode registers often (but not always) need a scratch.
2215 ;; The best we can do is use early clobber alternative "#&r" so that
2216 ;; completely non-overlapping operands dont get a scratch but # so register
2217 ;; allocation does not prefer non-overlapping.
2220 ; Split word aligned rotates using scratch that is mode dependent.
2221 (define_insn_and_split "*rotw<mode>"
2222 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2223 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2224 (match_operand 2 "const_int_operand" "n,n,n")))
2225 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2227 && CONST_INT_P (operands[2])
2228 && 0 == INTVAL (operands[2]) % 16"
2230 "&& (reload_completed || <MODE>mode == DImode)"
2233 avr_rotate_bytes (operands);
2238 ; Split byte aligned rotates using scratch that is always QI mode.
2239 (define_insn_and_split "*rotb<mode>"
2240 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2241 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2242 (match_operand 2 "const_int_operand" "n,n,n")))
2243 (clobber (match_scratch:QI 3 "=<rotx>"))]
2244 "CONST_INT_P (operands[2])
2245 && (8 == INTVAL (operands[2]) % 16
2247 && 0 == INTVAL (operands[2]) % 16))"
2249 "&& (reload_completed || <MODE>mode == DImode)"
2252 avr_rotate_bytes (operands);
2257 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2258 ;; arithmetic shift left
2260 (define_expand "ashlqi3"
2261 [(set (match_operand:QI 0 "register_operand" "")
2262 (ashift:QI (match_operand:QI 1 "register_operand" "")
2263 (match_operand:QI 2 "general_operand" "")))]
2267 (define_split ; ashlqi3_const4
2268 [(set (match_operand:QI 0 "d_register_operand" "")
2269 (ashift:QI (match_dup 0)
2272 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2273 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2276 (define_split ; ashlqi3_const5
2277 [(set (match_operand:QI 0 "d_register_operand" "")
2278 (ashift:QI (match_dup 0)
2281 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2282 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2283 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2286 (define_split ; ashlqi3_const6
2287 [(set (match_operand:QI 0 "d_register_operand" "")
2288 (ashift:QI (match_dup 0)
2291 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2292 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2293 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2296 (define_insn "*ashlqi3"
2297 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2298 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2299 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2301 "* return ashlqi3_out (insn, operands, NULL);"
2302 [(set_attr "length" "5,0,1,2,4,6,9")
2303 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2305 (define_insn "ashlhi3"
2306 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2307 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2308 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2310 "* return ashlhi3_out (insn, operands, NULL);"
2311 [(set_attr "length" "6,0,2,2,4,10,10")
2312 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2315 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
2316 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
2320 (define_insn_and_split "*ashl<extend_su>qihiqi3"
2321 [(set (match_operand:QI 0 "register_operand" "=r")
2322 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
2323 (match_operand:QI 2 "register_operand" "r"))
2329 (ashift:QI (match_dup 1)
2333 ;; ??? Combiner does not recognize that it could split the following insn;
2334 ;; presumably because he has no register handy?
2336 ;; "*ashluqihiqi3.mem"
2337 ;; "*ashlsqihiqi3.mem"
2338 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
2339 [(set (match_operand:QI 0 "memory_operand" "=m")
2340 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
2341 (match_operand:QI 2 "register_operand" "r"))
2344 { gcc_unreachable(); }
2347 (ashift:QI (match_dup 1)
2352 operands[3] = gen_reg_rtx (QImode);
2357 (define_insn_and_split "*ashlhiqi3"
2358 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
2359 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
2360 (match_operand:QI 2 "register_operand" "r")) 0))]
2362 { gcc_unreachable(); }
2365 (ashift:QI (match_dup 3)
2370 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
2371 operands[4] = gen_reg_rtx (QImode);
2374 ;; High part of 16-bit shift is unused after the instruction:
2375 ;; No need to compute it, map to 8-bit shift.
2378 [(set (match_operand:HI 0 "register_operand" "")
2379 (ashift:HI (match_dup 0)
2380 (match_operand:QI 1 "register_operand" "")))]
2383 (ashift:QI (match_dup 2)
2385 (clobber (match_dup 3))]
2387 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
2389 if (!peep2_reg_dead_p (1, operands[3]))
2392 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
2396 (define_insn "ashlsi3"
2397 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2398 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2399 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2401 "* return ashlsi3_out (insn, operands, NULL);"
2402 [(set_attr "length" "8,0,4,4,8,10,12")
2403 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2405 ;; Optimize if a scratch register from LD_REGS happens to be available.
2407 (define_peephole2 ; ashlqi3_l_const4
2408 [(set (match_operand:QI 0 "l_register_operand" "")
2409 (ashift:QI (match_dup 0)
2411 (match_scratch:QI 1 "d")]
2413 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2414 (set (match_dup 1) (const_int -16))
2415 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2418 (define_peephole2 ; ashlqi3_l_const5
2419 [(set (match_operand:QI 0 "l_register_operand" "")
2420 (ashift:QI (match_dup 0)
2422 (match_scratch:QI 1 "d")]
2424 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2425 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2426 (set (match_dup 1) (const_int -32))
2427 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2430 (define_peephole2 ; ashlqi3_l_const6
2431 [(set (match_operand:QI 0 "l_register_operand" "")
2432 (ashift:QI (match_dup 0)
2434 (match_scratch:QI 1 "d")]
2436 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2437 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2438 (set (match_dup 1) (const_int -64))
2439 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2443 [(match_scratch:QI 3 "d")
2444 (set (match_operand:HI 0 "register_operand" "")
2445 (ashift:HI (match_operand:HI 1 "register_operand" "")
2446 (match_operand:QI 2 "const_int_operand" "")))]
2448 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
2449 (clobber (match_dup 3))])]
2452 (define_insn "*ashlhi3_const"
2453 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2454 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2455 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2456 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2458 "* return ashlhi3_out (insn, operands, NULL);"
2459 [(set_attr "length" "0,2,2,4,10")
2460 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
2463 [(match_scratch:QI 3 "d")
2464 (set (match_operand:SI 0 "register_operand" "")
2465 (ashift:SI (match_operand:SI 1 "register_operand" "")
2466 (match_operand:QI 2 "const_int_operand" "")))]
2468 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2469 (clobber (match_dup 3))])]
2472 (define_insn "*ashlsi3_const"
2473 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2474 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2475 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2476 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2478 "* return ashlsi3_out (insn, operands, NULL);"
2479 [(set_attr "length" "0,4,4,10")
2480 (set_attr "cc" "none,set_n,clobber,clobber")])
2482 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2483 ;; arithmetic shift right
2485 (define_insn "ashrqi3"
2486 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
2487 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
2488 (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))]
2490 "* return ashrqi3_out (insn, operands, NULL);"
2491 [(set_attr "length" "5,0,1,2,5,9")
2492 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
2494 (define_insn "ashrhi3"
2495 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2496 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2497 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2499 "* return ashrhi3_out (insn, operands, NULL);"
2500 [(set_attr "length" "6,0,2,4,4,10,10")
2501 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2503 (define_insn "ashrsi3"
2504 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2505 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2506 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2508 "* return ashrsi3_out (insn, operands, NULL);"
2509 [(set_attr "length" "8,0,4,6,8,10,12")
2510 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2512 ;; Optimize if a scratch register from LD_REGS happens to be available.
2515 [(match_scratch:QI 3 "d")
2516 (set (match_operand:HI 0 "register_operand" "")
2517 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2518 (match_operand:QI 2 "const_int_operand" "")))]
2520 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
2521 (clobber (match_dup 3))])]
2524 (define_insn "*ashrhi3_const"
2525 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2526 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2527 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2528 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2530 "* return ashrhi3_out (insn, operands, NULL);"
2531 [(set_attr "length" "0,2,4,4,10")
2532 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
2535 [(match_scratch:QI 3 "d")
2536 (set (match_operand:SI 0 "register_operand" "")
2537 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2538 (match_operand:QI 2 "const_int_operand" "")))]
2540 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2541 (clobber (match_dup 3))])]
2544 (define_insn "*ashrsi3_const"
2545 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2546 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2547 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2548 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2550 "* return ashrsi3_out (insn, operands, NULL);"
2551 [(set_attr "length" "0,4,4,10")
2552 (set_attr "cc" "none,clobber,set_n,clobber")])
2554 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2555 ;; logical shift right
2557 (define_expand "lshrqi3"
2558 [(set (match_operand:QI 0 "register_operand" "")
2559 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2560 (match_operand:QI 2 "general_operand" "")))]
2564 (define_split ; lshrqi3_const4
2565 [(set (match_operand:QI 0 "d_register_operand" "")
2566 (lshiftrt:QI (match_dup 0)
2569 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2570 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
2573 (define_split ; lshrqi3_const5
2574 [(set (match_operand:QI 0 "d_register_operand" "")
2575 (lshiftrt:QI (match_dup 0)
2578 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2579 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2580 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
2583 (define_split ; lshrqi3_const6
2584 [(set (match_operand:QI 0 "d_register_operand" "")
2585 (lshiftrt:QI (match_dup 0)
2588 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2589 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2590 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
2593 (define_insn "*lshrqi3"
2594 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2595 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2596 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2598 "* return lshrqi3_out (insn, operands, NULL);"
2599 [(set_attr "length" "5,0,1,2,4,6,9")
2600 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2602 (define_insn "lshrhi3"
2603 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2604 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2605 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2607 "* return lshrhi3_out (insn, operands, NULL);"
2608 [(set_attr "length" "6,0,2,2,4,10,10")
2609 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2611 (define_insn "lshrsi3"
2612 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2613 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2614 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2616 "* return lshrsi3_out (insn, operands, NULL);"
2617 [(set_attr "length" "8,0,4,4,8,10,12")
2618 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2620 ;; Optimize if a scratch register from LD_REGS happens to be available.
2622 (define_peephole2 ; lshrqi3_l_const4
2623 [(set (match_operand:QI 0 "l_register_operand" "")
2624 (lshiftrt:QI (match_dup 0)
2626 (match_scratch:QI 1 "d")]
2628 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2629 (set (match_dup 1) (const_int 15))
2630 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2633 (define_peephole2 ; lshrqi3_l_const5
2634 [(set (match_operand:QI 0 "l_register_operand" "")
2635 (lshiftrt:QI (match_dup 0)
2637 (match_scratch:QI 1 "d")]
2639 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2640 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2641 (set (match_dup 1) (const_int 7))
2642 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2645 (define_peephole2 ; lshrqi3_l_const6
2646 [(set (match_operand:QI 0 "l_register_operand" "")
2647 (lshiftrt:QI (match_dup 0)
2649 (match_scratch:QI 1 "d")]
2651 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2652 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2653 (set (match_dup 1) (const_int 3))
2654 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2658 [(match_scratch:QI 3 "d")
2659 (set (match_operand:HI 0 "register_operand" "")
2660 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2661 (match_operand:QI 2 "const_int_operand" "")))]
2663 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
2664 (clobber (match_dup 3))])]
2667 (define_insn "*lshrhi3_const"
2668 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2669 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2670 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2671 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2673 "* return lshrhi3_out (insn, operands, NULL);"
2674 [(set_attr "length" "0,2,2,4,10")
2675 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
2678 [(match_scratch:QI 3 "d")
2679 (set (match_operand:SI 0 "register_operand" "")
2680 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2681 (match_operand:QI 2 "const_int_operand" "")))]
2683 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2684 (clobber (match_dup 3))])]
2687 (define_insn "*lshrsi3_const"
2688 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2689 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2690 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2691 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2693 "* return lshrsi3_out (insn, operands, NULL);"
2694 [(set_attr "length" "0,4,4,10")
2695 (set_attr "cc" "none,clobber,clobber,clobber")])
2697 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2700 (define_insn "absqi2"
2701 [(set (match_operand:QI 0 "register_operand" "=r")
2702 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2706 [(set_attr "length" "2")
2707 (set_attr "cc" "clobber")])
2710 (define_insn "abssf2"
2711 [(set (match_operand:SF 0 "register_operand" "=d,r")
2712 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
2717 [(set_attr "length" "1,2")
2718 (set_attr "cc" "set_n,clobber")])
2720 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
2723 (define_insn "negqi2"
2724 [(set (match_operand:QI 0 "register_operand" "=r")
2725 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
2728 [(set_attr "length" "1")
2729 (set_attr "cc" "set_zn")])
2731 (define_insn "neghi2"
2732 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
2733 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
2736 com %B0\;neg %A0\;sbci %B0,lo8(-1)
2737 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
2738 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
2739 [(set_attr "length" "3,4,4")
2740 (set_attr "cc" "set_czn,set_n,set_czn")])
2742 (define_insn "negsi2"
2743 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
2744 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
2747 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
2748 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
2749 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
2750 [(set_attr_alternative "length"
2753 (if_then_else (eq_attr "mcu_have_movw" "yes")
2756 (set_attr "cc" "set_czn,set_n,set_czn")])
2758 (define_insn "negsf2"
2759 [(set (match_operand:SF 0 "register_operand" "=d,r")
2760 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
2764 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
2765 [(set_attr "length" "1,4")
2766 (set_attr "cc" "set_n,set_n")])
2768 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2771 (define_insn "one_cmplqi2"
2772 [(set (match_operand:QI 0 "register_operand" "=r")
2773 (not:QI (match_operand:QI 1 "register_operand" "0")))]
2776 [(set_attr "length" "1")
2777 (set_attr "cc" "set_czn")])
2779 (define_insn "one_cmplhi2"
2780 [(set (match_operand:HI 0 "register_operand" "=r")
2781 (not:HI (match_operand:HI 1 "register_operand" "0")))]
2785 [(set_attr "length" "2")
2786 (set_attr "cc" "set_n")])
2788 (define_insn "one_cmplsi2"
2789 [(set (match_operand:SI 0 "register_operand" "=r")
2790 (not:SI (match_operand:SI 1 "register_operand" "0")))]
2796 [(set_attr "length" "4")
2797 (set_attr "cc" "set_n")])
2799 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2802 ;; We keep combiner from inserting hard registers into the input of sign- and
2803 ;; zero-extends. A hard register in the input operand is not wanted because
2804 ;; 32-bit multiply patterns clobber some hard registers and extends with a
2805 ;; hard register that overlaps these clobbers won't be combined to a widening
2806 ;; multiplication. There is no need for combine to propagate hard registers,
2807 ;; register allocation can do it just as well.
2809 (define_insn "extendqihi2"
2810 [(set (match_operand:HI 0 "register_operand" "=r,r")
2811 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2814 clr %B0\;sbrc %0,7\;com %B0
2815 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
2816 [(set_attr "length" "3,4")
2817 (set_attr "cc" "set_n,set_n")])
2819 (define_insn "extendqisi2"
2820 [(set (match_operand:SI 0 "register_operand" "=r,r")
2821 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2824 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
2825 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
2826 [(set_attr "length" "5,6")
2827 (set_attr "cc" "set_n,set_n")])
2829 (define_insn "extendhisi2"
2830 [(set (match_operand:SI 0 "register_operand" "=r,r")
2831 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
2834 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
2835 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
2836 [(set_attr_alternative "length"
2838 (if_then_else (eq_attr "mcu_have_movw" "yes")
2841 (set_attr "cc" "set_n,set_n")])
2843 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2846 (define_insn_and_split "zero_extendqihi2"
2847 [(set (match_operand:HI 0 "register_operand" "=r")
2848 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2852 [(set (match_dup 2) (match_dup 1))
2853 (set (match_dup 3) (const_int 0))]
2855 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
2856 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
2858 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
2859 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
2862 (define_insn_and_split "zero_extendqisi2"
2863 [(set (match_operand:SI 0 "register_operand" "=r")
2864 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2868 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
2869 (set (match_dup 3) (const_int 0))]
2871 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2872 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2874 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2875 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2878 (define_insn_and_split "zero_extendhisi2"
2879 [(set (match_operand:SI 0 "register_operand" "=r")
2880 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
2884 [(set (match_dup 2) (match_dup 1))
2885 (set (match_dup 3) (const_int 0))]
2887 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2888 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2890 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2891 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2894 (define_insn_and_split "zero_extendqidi2"
2895 [(set (match_operand:DI 0 "register_operand" "=r")
2896 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2900 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2901 (set (match_dup 3) (const_int 0))]
2903 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2904 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2906 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2907 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2910 (define_insn_and_split "zero_extendhidi2"
2911 [(set (match_operand:DI 0 "register_operand" "=r")
2912 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2916 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2917 (set (match_dup 3) (const_int 0))]
2919 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2920 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2922 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2923 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2926 (define_insn_and_split "zero_extendsidi2"
2927 [(set (match_operand:DI 0 "register_operand" "=r")
2928 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2932 [(set (match_dup 2) (match_dup 1))
2933 (set (match_dup 3) (const_int 0))]
2935 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2936 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2938 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2939 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2942 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
2945 ; Optimize negated tests into reverse compare if overflow is undefined.
2946 (define_insn "*negated_tstqi"
2948 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
2950 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2951 "cp __zero_reg__,%0"
2952 [(set_attr "cc" "compare")
2953 (set_attr "length" "1")])
2955 (define_insn "*reversed_tstqi"
2957 (compare (const_int 0)
2958 (match_operand:QI 0 "register_operand" "r")))]
2960 "cp __zero_reg__,%0"
2961 [(set_attr "cc" "compare")
2962 (set_attr "length" "2")])
2964 (define_insn "*negated_tsthi"
2966 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
2968 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2969 "cp __zero_reg__,%A0
2970 cpc __zero_reg__,%B0"
2971 [(set_attr "cc" "compare")
2972 (set_attr "length" "2")])
2974 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
2975 ;; though it is unused, because this pattern is synthesized by avr_reorg.
2976 (define_insn "*reversed_tsthi"
2978 (compare (const_int 0)
2979 (match_operand:HI 0 "register_operand" "r")))
2980 (clobber (match_scratch:QI 1 "=X"))]
2982 "cp __zero_reg__,%A0
2983 cpc __zero_reg__,%B0"
2984 [(set_attr "cc" "compare")
2985 (set_attr "length" "2")])
2987 (define_insn "*negated_tstsi"
2989 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
2991 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2992 "cp __zero_reg__,%A0
2993 cpc __zero_reg__,%B0
2994 cpc __zero_reg__,%C0
2995 cpc __zero_reg__,%D0"
2996 [(set_attr "cc" "compare")
2997 (set_attr "length" "4")])
2999 (define_insn "*reversed_tstsi"
3001 (compare (const_int 0)
3002 (match_operand:SI 0 "register_operand" "r")))
3003 (clobber (match_scratch:QI 1 "=X"))]
3005 "cp __zero_reg__,%A0
3006 cpc __zero_reg__,%B0
3007 cpc __zero_reg__,%C0
3008 cpc __zero_reg__,%D0"
3009 [(set_attr "cc" "compare")
3010 (set_attr "length" "4")])
3013 (define_insn "*cmpqi"
3015 (compare (match_operand:QI 0 "register_operand" "r,r,d")
3016 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
3022 [(set_attr "cc" "compare,compare,compare")
3023 (set_attr "length" "1,1,1")])
3025 (define_insn "*cmpqi_sign_extend"
3027 (compare (sign_extend:HI
3028 (match_operand:QI 0 "register_operand" "d"))
3029 (match_operand:HI 1 "const_int_operand" "n")))]
3030 "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
3032 [(set_attr "cc" "compare")
3033 (set_attr "length" "1")])
3035 (define_insn "*cmphi"
3037 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d,d,r,r")
3038 (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
3039 (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
3042 switch (which_alternative)
3045 return out_tsthi (insn, operands[0], NULL);
3048 return (AS2 (cp,%A0,%A1) CR_TAB
3051 if (reg_unused_after (insn, operands[0])
3052 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
3053 && test_hard_reg_class (ADDW_REGS, operands[0]))
3054 return AS2 (sbiw,%0,%1);
3056 return (AS2 (cpi,%0,%1) CR_TAB
3057 AS2 (cpc,%B0,__zero_reg__));
3059 if (reg_unused_after (insn, operands[0]))
3060 return (AS2 (subi,%0,lo8(%1)) CR_TAB
3061 AS2 (sbci,%B0,hi8(%1)));
3063 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
3064 AS2 (cpi, %A0,lo8(%1)) CR_TAB
3067 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3068 AS2 (cp, %A0,%2) CR_TAB
3069 AS2 (cpc, %B0,__zero_reg__));
3072 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3073 AS2 (cp, %A0,%2) CR_TAB
3074 AS2 (ldi, %2,hi8(%1)) CR_TAB
3079 [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
3080 (set_attr "length" "1,2,2,2,3,3,4")])
3083 (define_insn "*cmpsi"
3085 (compare (match_operand:SI 0 "register_operand" "r,r,d,d,r,r")
3086 (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
3087 (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
3090 switch (which_alternative)
3093 return out_tstsi (insn, operands[0], NULL);
3096 return (AS2 (cp,%A0,%A1) CR_TAB
3097 AS2 (cpc,%B0,%B1) CR_TAB
3098 AS2 (cpc,%C0,%C1) CR_TAB
3101 if (reg_unused_after (insn, operands[0])
3102 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
3103 && test_hard_reg_class (ADDW_REGS, operands[0]))
3104 return (AS2 (sbiw,%0,%1) CR_TAB
3105 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3106 AS2 (cpc,%D0,__zero_reg__));
3108 return (AS2 (cpi,%A0,lo8(%1)) CR_TAB
3109 AS2 (cpc,%B0,__zero_reg__) CR_TAB
3110 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3111 AS2 (cpc,%D0,__zero_reg__));
3113 if (reg_unused_after (insn, operands[0]))
3114 return (AS2 (subi,%A0,lo8(%1)) CR_TAB
3115 AS2 (sbci,%B0,hi8(%1)) CR_TAB
3116 AS2 (sbci,%C0,hlo8(%1)) CR_TAB
3117 AS2 (sbci,%D0,hhi8(%1)));
3119 return (AS2 (cpi, %A0,lo8(%1)) CR_TAB
3120 AS2 (ldi, %2,hi8(%1)) CR_TAB
3121 AS2 (cpc, %B0,%2) CR_TAB
3122 AS2 (ldi, %2,hlo8(%1)) CR_TAB
3123 AS2 (cpc, %C0,%2) CR_TAB
3124 AS2 (ldi, %2,hhi8(%1)) CR_TAB
3127 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
3128 AS2 (cp,%A0,%2) CR_TAB
3129 AS2 (cpc,%B0,__zero_reg__) CR_TAB
3130 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3131 AS2 (cpc,%D0,__zero_reg__));
3133 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3134 AS2 (cp, %A0,%2) CR_TAB
3135 AS2 (ldi, %2,hi8(%1)) CR_TAB
3136 AS2 (cpc, %B0,%2) CR_TAB
3137 AS2 (ldi, %2,hlo8(%1)) CR_TAB
3138 AS2 (cpc, %C0,%2) CR_TAB
3139 AS2 (ldi, %2,hhi8(%1)) CR_TAB
3144 [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
3145 (set_attr "length" "4,4,4,7,5,8")])
3148 ;; ----------------------------------------------------------------------
3149 ;; JUMP INSTRUCTIONS
3150 ;; ----------------------------------------------------------------------
3151 ;; Conditional jump instructions
3153 (define_expand "cbranchsi4"
3154 [(parallel [(set (cc0)
3155 (compare (match_operand:SI 1 "register_operand" "")
3156 (match_operand:SI 2 "nonmemory_operand" "")))
3157 (clobber (match_scratch:QI 4 ""))])
3160 (match_operator 0 "ordered_comparison_operator" [(cc0)
3162 (label_ref (match_operand 3 "" ""))
3166 (define_expand "cbranchhi4"
3167 [(parallel [(set (cc0)
3168 (compare (match_operand:HI 1 "register_operand" "")
3169 (match_operand:HI 2 "nonmemory_operand" "")))
3170 (clobber (match_scratch:QI 4 ""))])
3173 (match_operator 0 "ordered_comparison_operator" [(cc0)
3175 (label_ref (match_operand 3 "" ""))
3179 (define_expand "cbranchqi4"
3181 (compare (match_operand:QI 1 "register_operand" "")
3182 (match_operand:QI 2 "nonmemory_operand" "")))
3185 (match_operator 0 "ordered_comparison_operator" [(cc0)
3187 (label_ref (match_operand 3 "" ""))
3192 ;; Test a single bit in a QI/HI/SImode register.
3193 ;; Combine will create zero extract patterns for single bit tests.
3194 ;; permit any mode in source pattern by using VOIDmode.
3196 (define_insn "*sbrx_branch<mode>"
3199 (match_operator 0 "eqne_operator"
3201 (match_operand:VOID 1 "register_operand" "r")
3203 (match_operand 2 "const_int_operand" "n"))
3205 (label_ref (match_operand 3 "" ""))
3208 "* return avr_out_sbxx_branch (insn, operands);"
3209 [(set (attr "length")
3210 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3211 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3213 (if_then_else (eq_attr "mcu_mega" "no")
3216 (set_attr "cc" "clobber")])
3218 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
3219 ;; or for old peepholes.
3220 ;; Fixme - bitwise Mask will not work for DImode
3222 (define_insn "*sbrx_and_branch<mode>"
3225 (match_operator 0 "eqne_operator"
3227 (match_operand:QISI 1 "register_operand" "r")
3228 (match_operand:QISI 2 "single_one_operand" "n"))
3230 (label_ref (match_operand 3 "" ""))
3234 HOST_WIDE_INT bitnumber;
3235 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
3236 operands[2] = GEN_INT (bitnumber);
3237 return avr_out_sbxx_branch (insn, operands);
3239 [(set (attr "length")
3240 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3241 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3243 (if_then_else (eq_attr "mcu_mega" "no")
3246 (set_attr "cc" "clobber")])
3248 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
3250 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3252 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3253 (label_ref (match_operand 1 "" ""))
3256 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
3260 (label_ref (match_dup 1))
3265 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3267 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3268 (label_ref (match_operand 1 "" ""))
3271 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
3275 (label_ref (match_dup 1))
3280 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3282 (clobber (match_operand:HI 2 ""))])
3283 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3284 (label_ref (match_operand 1 "" ""))
3287 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
3289 (label_ref (match_dup 1))
3294 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3296 (clobber (match_operand:HI 2 ""))])
3297 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3298 (label_ref (match_operand 1 "" ""))
3301 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
3303 (label_ref (match_dup 1))
3308 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3310 (clobber (match_operand:SI 2 ""))])
3311 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3312 (label_ref (match_operand 1 "" ""))
3315 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
3317 (label_ref (match_dup 1))
3319 "operands[2] = GEN_INT (-2147483647 - 1);")
3322 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3324 (clobber (match_operand:SI 2 ""))])
3325 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3326 (label_ref (match_operand 1 "" ""))
3329 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
3331 (label_ref (match_dup 1))
3333 "operands[2] = GEN_INT (-2147483647 - 1);")
3335 ;; ************************************************************************
3336 ;; Implementation of conditional jumps here.
3337 ;; Compare with 0 (test) jumps
3338 ;; ************************************************************************
3340 (define_insn "branch"
3342 (if_then_else (match_operator 1 "simple_comparison_operator"
3345 (label_ref (match_operand 0 "" ""))
3349 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3351 [(set_attr "type" "branch")
3352 (set_attr "cc" "clobber")])
3355 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
3356 ;; or optimized in the remainder.
3358 (define_insn "branch_unspec"
3360 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
3363 (label_ref (match_operand 0 "" ""))
3365 ] UNSPEC_IDENTITY))]
3368 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3370 [(set_attr "type" "branch")
3371 (set_attr "cc" "none")])
3373 ;; ****************************************************************
3374 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
3375 ;; Convert them all to proper jumps.
3376 ;; ****************************************************************/
3378 (define_insn "difficult_branch"
3380 (if_then_else (match_operator 1 "difficult_comparison_operator"
3383 (label_ref (match_operand 0 "" ""))
3387 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3388 [(set_attr "type" "branch1")
3389 (set_attr "cc" "clobber")])
3393 (define_insn "rvbranch"
3395 (if_then_else (match_operator 1 "simple_comparison_operator"
3399 (label_ref (match_operand 0 "" ""))))]
3402 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3403 [(set_attr "type" "branch1")
3404 (set_attr "cc" "clobber")])
3406 (define_insn "difficult_rvbranch"
3408 (if_then_else (match_operator 1 "difficult_comparison_operator"
3412 (label_ref (match_operand 0 "" ""))))]
3415 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3416 [(set_attr "type" "branch")
3417 (set_attr "cc" "clobber")])
3419 ;; **************************************************************************
3420 ;; Unconditional and other jump instructions.
3424 (label_ref (match_operand 0 "" "")))]
3427 if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
3428 return AS1 (jmp,%x0);
3429 return AS1 (rjmp,%x0);
3431 [(set (attr "length")
3432 (if_then_else (match_operand 0 "symbol_ref_operand" "")
3433 (if_then_else (eq_attr "mcu_mega" "no")
3436 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
3437 (le (minus (pc) (match_dup 0)) (const_int 2047)))
3440 (set_attr "cc" "none")])
3444 (define_expand "call"
3445 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3446 (match_operand:HI 1 "general_operand" ""))
3447 (use (const_int 0))])]
3448 ;; Operand 1 not used on the AVR.
3449 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3453 (define_expand "sibcall"
3454 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3455 (match_operand:HI 1 "general_operand" ""))
3456 (use (const_int 1))])]
3457 ;; Operand 1 not used on the AVR.
3458 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3464 (define_expand "call_value"
3465 [(parallel[(set (match_operand 0 "register_operand" "")
3466 (call (match_operand:HI 1 "call_insn_operand" "")
3467 (match_operand:HI 2 "general_operand" "")))
3468 (use (const_int 0))])]
3469 ;; Operand 2 not used on the AVR.
3470 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3474 (define_expand "sibcall_value"
3475 [(parallel[(set (match_operand 0 "register_operand" "")
3476 (call (match_operand:HI 1 "call_insn_operand" "")
3477 (match_operand:HI 2 "general_operand" "")))
3478 (use (const_int 1))])]
3479 ;; Operand 2 not used on the AVR.
3480 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3484 (define_insn "*call_insn"
3485 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
3486 (match_operand:HI 1 "general_operand" "X,X,X,X"))
3487 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
3488 ;; Operand 1 not used on the AVR.
3489 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3496 [(set_attr "cc" "clobber")
3497 (set_attr_alternative "length"
3499 (if_then_else (eq_attr "mcu_mega" "yes")
3503 (if_then_else (eq_attr "mcu_mega" "yes")
3507 (define_insn "*call_value_insn"
3508 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
3509 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
3510 (match_operand:HI 2 "general_operand" "X,X,X,X")))
3511 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
3512 ;; Operand 2 not used on the AVR.
3513 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3520 [(set_attr "cc" "clobber")
3521 (set_attr_alternative "length"
3523 (if_then_else (eq_attr "mcu_mega" "yes")
3527 (if_then_else (eq_attr "mcu_mega" "yes")
3535 [(set_attr "cc" "none")
3536 (set_attr "length" "1")])
3540 (define_expand "indirect_jump"
3541 [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
3543 " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
3545 operands[0] = copy_to_mode_reg(HImode, operand0);
3550 (define_insn "*jcindirect_jump"
3551 [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
3554 [(set_attr "length" "2")
3555 (set_attr "cc" "none")])
3558 (define_insn "*njcindirect_jump"
3559 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
3560 "!AVR_HAVE_EIJMP_EICALL"
3563 push %A0\;push %B0\;ret"
3564 [(set_attr "length" "1,3")
3565 (set_attr "cc" "none,none")])
3567 (define_insn "*indirect_jump_avr6"
3568 [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
3569 "AVR_HAVE_EIJMP_EICALL"
3571 [(set_attr "length" "1")
3572 (set_attr "cc" "none")])
3576 ;; Table made from "rjmp" instructions for <=8K devices.
3577 (define_insn "*tablejump_rjmp"
3578 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
3580 (use (label_ref (match_operand 1 "" "")))
3581 (clobber (match_dup 0))]
3582 "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
3585 push %A0\;push %B0\;ret"
3586 [(set_attr "length" "1,3")
3587 (set_attr "cc" "none,none")])
3589 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
3590 (define_insn "*tablejump_lib"
3591 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3593 (use (label_ref (match_operand 1 "" "")))
3594 (clobber (match_dup 0))]
3595 "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
3596 "%~jmp __tablejump2__"
3597 [(set_attr "length" "2")
3598 (set_attr "cc" "clobber")])
3600 (define_insn "*tablejump_enh"
3601 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3603 (use (label_ref (match_operand 1 "" "")))
3604 (clobber (match_dup 0))]
3605 "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
3612 [(set_attr "length" "6")
3613 (set_attr "cc" "clobber")])
3615 (define_insn "*tablejump"
3616 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3618 (use (label_ref (match_operand 1 "" "")))
3619 (clobber (match_dup 0))]
3620 "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
3629 [(set_attr "length" "8")
3630 (set_attr "cc" "clobber")])
3632 (define_expand "casesi"
3634 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
3635 (match_operand:HI 1 "register_operand" "")))
3636 (parallel [(set (cc0)
3637 (compare (match_dup 6)
3638 (match_operand:HI 2 "register_operand" "")))
3639 (clobber (match_scratch:QI 9 ""))])
3642 (if_then_else (gtu (cc0)
3644 (label_ref (match_operand 4 "" ""))
3648 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
3650 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
3651 (use (label_ref (match_dup 3)))
3652 (clobber (match_dup 6))])]
3656 operands[6] = gen_reg_rtx (HImode);
3660 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3661 ;; This instruction sets Z flag
3664 [(set (cc0) (const_int 0))]
3667 [(set_attr "length" "1")
3668 (set_attr "cc" "compare")])
3670 ;; Clear/set/test a single bit in I/O address space.
3673 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3674 (and:QI (mem:QI (match_dup 0))
3675 (match_operand:QI 1 "single_zero_operand" "n")))]
3678 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
3679 return AS2 (cbi,%m0-0x20,%2);
3681 [(set_attr "length" "1")
3682 (set_attr "cc" "none")])
3685 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3686 (ior:QI (mem:QI (match_dup 0))
3687 (match_operand:QI 1 "single_one_operand" "n")))]
3690 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
3691 return AS2 (sbi,%m0-0x20,%2);
3693 [(set_attr "length" "1")
3694 (set_attr "cc" "none")])
3696 ;; Lower half of the I/O space - use sbic/sbis directly.
3697 (define_insn "*sbix_branch"
3700 (match_operator 0 "eqne_operator"
3702 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
3704 (match_operand 2 "const_int_operand" "n"))
3706 (label_ref (match_operand 3 "" ""))
3709 "* return avr_out_sbxx_branch (insn, operands);"
3710 [(set (attr "length")
3711 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3712 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3714 (if_then_else (eq_attr "mcu_mega" "no")
3717 (set_attr "cc" "clobber")])
3719 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
3720 (define_insn "*sbix_branch_bit7"
3723 (match_operator 0 "gelt_operator"
3724 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
3726 (label_ref (match_operand 2 "" ""))
3730 operands[3] = operands[2];
3731 operands[2] = GEN_INT (7);
3732 return avr_out_sbxx_branch (insn, operands);
3734 [(set (attr "length")
3735 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3736 (le (minus (pc) (match_dup 2)) (const_int 2046)))
3738 (if_then_else (eq_attr "mcu_mega" "no")
3741 (set_attr "cc" "clobber")])
3743 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
3744 (define_insn "*sbix_branch_tmp"
3747 (match_operator 0 "eqne_operator"
3749 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
3751 (match_operand 2 "const_int_operand" "n"))
3753 (label_ref (match_operand 3 "" ""))
3756 "* return avr_out_sbxx_branch (insn, operands);"
3757 [(set (attr "length")
3758 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3759 (le (minus (pc) (match_dup 3)) (const_int 2045)))
3761 (if_then_else (eq_attr "mcu_mega" "no")
3764 (set_attr "cc" "clobber")])
3766 (define_insn "*sbix_branch_tmp_bit7"
3769 (match_operator 0 "gelt_operator"
3770 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
3772 (label_ref (match_operand 2 "" ""))
3776 operands[3] = operands[2];
3777 operands[2] = GEN_INT (7);
3778 return avr_out_sbxx_branch (insn, operands);
3780 [(set (attr "length")
3781 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3782 (le (minus (pc) (match_dup 2)) (const_int 2045)))
3784 (if_then_else (eq_attr "mcu_mega" "no")
3787 (set_attr "cc" "clobber")])
3789 ;; ************************* Peepholes ********************************
3792 [(set (match_operand:SI 0 "d_register_operand" "")
3793 (plus:SI (match_dup 0)
3797 (compare (match_dup 0)
3799 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3801 (if_then_else (ne (cc0) (const_int 0))
3802 (label_ref (match_operand 2 "" ""))
3808 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3809 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3810 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3811 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3813 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3814 AS2 (sbc,%B0,__zero_reg__) CR_TAB
3815 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3816 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3817 switch (avr_jump_mode (operands[2],insn))
3820 return AS1 (brcc,%2);
3822 return (AS1 (brcs,.+2) CR_TAB
3825 return (AS1 (brcs,.+4) CR_TAB
3830 [(set (match_operand:HI 0 "d_register_operand" "")
3831 (plus:HI (match_dup 0)
3835 (compare (match_dup 0)
3837 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3839 (if_then_else (ne (cc0) (const_int 0))
3840 (label_ref (match_operand 2 "" ""))
3846 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3847 output_asm_insn (AS2 (sbiw,%0,1), operands);
3849 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3850 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3851 switch (avr_jump_mode (operands[2],insn))
3854 return AS1 (brcc,%2);
3856 return (AS1 (brcs,.+2) CR_TAB
3859 return (AS1 (brcs,.+4) CR_TAB
3864 [(set (match_operand:QI 0 "d_register_operand" "")
3865 (plus:QI (match_dup 0)
3868 (compare (match_dup 0)
3871 (if_then_else (ne (cc0) (const_int 0))
3872 (label_ref (match_operand 1 "" ""))
3878 cc_status.value1 = operands[0];
3879 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
3880 output_asm_insn (AS2 (subi,%A0,1), operands);
3881 switch (avr_jump_mode (operands[1],insn))
3884 return AS1 (brcc,%1);
3886 return (AS1 (brcs,.+2) CR_TAB
3889 return (AS1 (brcs,.+4) CR_TAB
3895 (compare (match_operand:QI 0 "register_operand" "")
3898 (if_then_else (eq (cc0) (const_int 0))
3899 (label_ref (match_operand 1 "" ""))
3901 "jump_over_one_insn_p (insn, operands[1])"
3902 "cpse %0,__zero_reg__")
3906 (compare (match_operand:QI 0 "register_operand" "")
3907 (match_operand:QI 1 "register_operand" "")))
3909 (if_then_else (eq (cc0) (const_int 0))
3910 (label_ref (match_operand 2 "" ""))
3912 "jump_over_one_insn_p (insn, operands[2])"
3915 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
3916 ;;prologue/epilogue support instructions
3918 (define_insn "popqi"
3919 [(set (match_operand:QI 0 "register_operand" "=r")
3920 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
3923 [(set_attr "cc" "none")
3924 (set_attr "length" "1")])
3926 ;; Enable Interrupts
3927 (define_insn "enable_interrupt"
3928 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
3931 [(set_attr "length" "1")
3932 (set_attr "cc" "none")])
3934 ;; Disable Interrupts
3935 (define_insn "disable_interrupt"
3936 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
3939 [(set_attr "length" "1")
3940 (set_attr "cc" "none")])
3942 ;; Library prologue saves
3943 (define_insn "call_prologue_saves"
3944 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
3945 (match_operand:HI 0 "immediate_operand" "")
3946 (set (reg:HI REG_SP) (minus:HI
3948 (match_operand:HI 1 "immediate_operand" "")))
3949 (use (reg:HI REG_X))
3950 (clobber (reg:HI REG_Z))]
3952 "ldi r30,lo8(gs(1f))
3954 %~jmp __prologue_saves__+((18 - %0) * 2)
3956 [(set_attr_alternative "length"
3957 [(if_then_else (eq_attr "mcu_mega" "yes")
3960 (set_attr "cc" "clobber")
3963 ; epilogue restores using library
3964 (define_insn "epilogue_restores"
3965 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
3966 (set (reg:HI REG_Y ) (plus:HI
3968 (match_operand:HI 0 "immediate_operand" "")))
3969 (set (reg:HI REG_SP) (reg:HI REG_Y))
3970 (clobber (reg:QI REG_Z))]
3973 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
3974 [(set_attr_alternative "length"
3975 [(if_then_else (eq_attr "mcu_mega" "yes")
3978 (set_attr "cc" "clobber")
3982 (define_insn "return"
3984 "reload_completed && avr_simple_epilogue ()"
3986 [(set_attr "cc" "none")
3987 (set_attr "length" "1")])
3989 (define_insn "return_from_epilogue"
3993 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
3994 && !cfun->machine->is_naked)"
3996 [(set_attr "cc" "none")
3997 (set_attr "length" "1")])
3999 (define_insn "return_from_interrupt_epilogue"
4003 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
4004 && !cfun->machine->is_naked)"
4006 [(set_attr "cc" "none")
4007 (set_attr "length" "1")])
4009 (define_insn "return_from_naked_epilogue"
4013 && cfun->machine->is_naked)"
4015 [(set_attr "cc" "none")
4016 (set_attr "length" "0")])
4018 (define_expand "prologue"
4027 (define_expand "epilogue"
4031 expand_epilogue (false /* sibcall_p */);
4035 (define_expand "sibcall_epilogue"
4039 expand_epilogue (true /* sibcall_p */);
4043 ;; Some instructions resp. instruction sequences available
4046 (define_insn "delay_cycles_1"
4047 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
4049 UNSPECV_DELAY_CYCLES)
4050 (clobber (match_scratch:QI 1 "=&d"))]
4055 [(set_attr "length" "3")
4056 (set_attr "cc" "clobber")])
4058 (define_insn "delay_cycles_2"
4059 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
4061 UNSPECV_DELAY_CYCLES)
4062 (clobber (match_scratch:HI 1 "=&w"))]
4068 [(set_attr "length" "4")
4069 (set_attr "cc" "clobber")])
4071 (define_insn "delay_cycles_3"
4072 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4074 UNSPECV_DELAY_CYCLES)
4075 (clobber (match_scratch:QI 1 "=&d"))
4076 (clobber (match_scratch:QI 2 "=&d"))
4077 (clobber (match_scratch:QI 3 "=&d"))]
4086 [(set_attr "length" "7")
4087 (set_attr "cc" "clobber")])
4089 (define_insn "delay_cycles_4"
4090 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4092 UNSPECV_DELAY_CYCLES)
4093 (clobber (match_scratch:QI 1 "=&d"))
4094 (clobber (match_scratch:QI 2 "=&d"))
4095 (clobber (match_scratch:QI 3 "=&d"))
4096 (clobber (match_scratch:QI 4 "=&d"))]
4107 [(set_attr "length" "9")
4108 (set_attr "cc" "clobber")])
4113 (define_expand "parityhi2"
4115 (match_operand:HI 1 "register_operand" ""))
4117 (parity:HI (reg:HI 24)))
4118 (set (match_operand:HI 0 "register_operand" "")
4123 (define_expand "paritysi2"
4125 (match_operand:SI 1 "register_operand" ""))
4127 (truncate:HI (parity:SI (reg:SI 22))))
4130 (set (match_operand:SI 0 "register_operand" "")
4131 (zero_extend:SI (match_dup 2)))]
4134 operands[2] = gen_reg_rtx (HImode);
4137 (define_insn "*parityhi2.libgcc"
4139 (parity:HI (reg:HI 24)))]
4141 "%~call __parityhi2"
4142 [(set_attr "type" "xcall")
4143 (set_attr "cc" "clobber")])
4145 (define_insn "*parityqihi2.libgcc"
4147 (zero_extend:HI (parity:QI (reg:QI 24))))]
4149 "%~call __parityqi2"
4150 [(set_attr "type" "xcall")
4151 (set_attr "cc" "clobber")])
4153 (define_insn "*paritysihi2.libgcc"
4155 (truncate:HI (parity:SI (reg:SI 22))))]
4157 "%~call __paritysi2"
4158 [(set_attr "type" "xcall")
4159 (set_attr "cc" "clobber")])
4164 (define_expand "popcounthi2"
4166 (match_operand:HI 1 "register_operand" ""))
4168 (popcount:HI (reg:HI 24)))
4169 (set (match_operand:HI 0 "register_operand" "")
4174 (define_expand "popcountsi2"
4176 (match_operand:SI 1 "register_operand" ""))
4178 (truncate:HI (popcount:SI (reg:SI 22))))
4181 (set (match_operand:SI 0 "register_operand" "")
4182 (zero_extend:SI (match_dup 2)))]
4185 operands[2] = gen_reg_rtx (HImode);
4188 (define_insn "*popcounthi2.libgcc"
4190 (popcount:HI (reg:HI 24)))]
4192 "%~call __popcounthi2"
4193 [(set_attr "type" "xcall")
4194 (set_attr "cc" "clobber")])
4196 (define_insn "*popcountsi2.libgcc"
4198 (truncate:HI (popcount:SI (reg:SI 22))))]
4200 "%~call __popcountsi2"
4201 [(set_attr "type" "xcall")
4202 (set_attr "cc" "clobber")])
4204 (define_insn "*popcountqi2.libgcc"
4206 (popcount:QI (reg:QI 24)))]
4208 "%~call __popcountqi2"
4209 [(set_attr "type" "xcall")
4210 (set_attr "cc" "clobber")])
4212 (define_insn_and_split "*popcountqihi2.libgcc"
4214 (zero_extend:HI (popcount:QI (reg:QI 24))))]
4219 (popcount:QI (reg:QI 24)))
4224 ;; Count Leading Zeros
4226 (define_expand "clzhi2"
4228 (match_operand:HI 1 "register_operand" ""))
4229 (parallel [(set (reg:HI 24)
4230 (clz:HI (reg:HI 24)))
4231 (clobber (reg:QI 26))])
4232 (set (match_operand:HI 0 "register_operand" "")
4237 (define_expand "clzsi2"
4239 (match_operand:SI 1 "register_operand" ""))
4240 (parallel [(set (reg:HI 24)
4241 (truncate:HI (clz:SI (reg:SI 22))))
4242 (clobber (reg:QI 26))])
4245 (set (match_operand:SI 0 "register_operand" "")
4246 (zero_extend:SI (match_dup 2)))]
4249 operands[2] = gen_reg_rtx (HImode);
4252 (define_insn "*clzhi2.libgcc"
4254 (clz:HI (reg:HI 24)))
4255 (clobber (reg:QI 26))]
4258 [(set_attr "type" "xcall")
4259 (set_attr "cc" "clobber")])
4261 (define_insn "*clzsihi2.libgcc"
4263 (truncate:HI (clz:SI (reg:SI 22))))
4264 (clobber (reg:QI 26))]
4267 [(set_attr "type" "xcall")
4268 (set_attr "cc" "clobber")])
4270 ;; Count Trailing Zeros
4272 (define_expand "ctzhi2"
4274 (match_operand:HI 1 "register_operand" ""))
4275 (parallel [(set (reg:HI 24)
4276 (ctz:HI (reg:HI 24)))
4277 (clobber (reg:QI 26))])
4278 (set (match_operand:HI 0 "register_operand" "")
4283 (define_expand "ctzsi2"
4285 (match_operand:SI 1 "register_operand" ""))
4286 (parallel [(set (reg:HI 24)
4287 (truncate:HI (ctz:SI (reg:SI 22))))
4288 (clobber (reg:QI 22))
4289 (clobber (reg:QI 26))])
4292 (set (match_operand:SI 0 "register_operand" "")
4293 (zero_extend:SI (match_dup 2)))]
4296 operands[2] = gen_reg_rtx (HImode);
4299 (define_insn "*ctzhi2.libgcc"
4301 (ctz:HI (reg:HI 24)))
4302 (clobber (reg:QI 26))]
4305 [(set_attr "type" "xcall")
4306 (set_attr "cc" "clobber")])
4308 (define_insn "*ctzsihi2.libgcc"
4310 (truncate:HI (ctz:SI (reg:SI 22))))
4311 (clobber (reg:QI 22))
4312 (clobber (reg:QI 26))]
4315 [(set_attr "type" "xcall")
4316 (set_attr "cc" "clobber")])
4320 (define_expand "ffshi2"
4322 (match_operand:HI 1 "register_operand" ""))
4323 (parallel [(set (reg:HI 24)
4324 (ffs:HI (reg:HI 24)))
4325 (clobber (reg:QI 26))])
4326 (set (match_operand:HI 0 "register_operand" "")
4331 (define_expand "ffssi2"
4333 (match_operand:SI 1 "register_operand" ""))
4334 (parallel [(set (reg:HI 24)
4335 (truncate:HI (ffs:SI (reg:SI 22))))
4336 (clobber (reg:QI 22))
4337 (clobber (reg:QI 26))])
4340 (set (match_operand:SI 0 "register_operand" "")
4341 (zero_extend:SI (match_dup 2)))]
4344 operands[2] = gen_reg_rtx (HImode);
4347 (define_insn "*ffshi2.libgcc"
4349 (ffs:HI (reg:HI 24)))
4350 (clobber (reg:QI 26))]
4353 [(set_attr "type" "xcall")
4354 (set_attr "cc" "clobber")])
4356 (define_insn "*ffssihi2.libgcc"
4358 (truncate:HI (ffs:SI (reg:SI 22))))
4359 (clobber (reg:QI 22))
4360 (clobber (reg:QI 26))]
4363 [(set_attr "type" "xcall")
4364 (set_attr "cc" "clobber")])
4368 (define_insn "copysignsf3"
4369 [(set (match_operand:SF 0 "register_operand" "=r")
4370 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
4371 (match_operand:SF 2 "register_operand" "r")]
4374 "bst %D2,7\;bld %D0,7"
4375 [(set_attr "length" "2")
4376 (set_attr "cc" "none")])
4378 ;; Swap Bytes (change byte-endianess)
4380 (define_expand "bswapsi2"
4382 (match_operand:SI 1 "register_operand" ""))
4384 (bswap:SI (reg:SI 22)))
4385 (set (match_operand:SI 0 "register_operand" "")
4390 (define_insn "*bswapsi2.libgcc"
4392 (bswap:SI (reg:SI 22)))]
4395 [(set_attr "type" "xcall")
4396 (set_attr "cc" "clobber")])
4401 ;; NOP taking 1 or 2 Ticks
4403 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
4409 [(set_attr "length" "1")
4410 (set_attr "cc" "none")])
4413 (define_insn "sleep"
4414 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
4417 [(set_attr "length" "1")
4418 (set_attr "cc" "none")])
4422 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
4425 [(set_attr "length" "1")
4426 (set_attr "cc" "none")])
4429 (define_expand "fmul"
4431 (match_operand:QI 1 "register_operand" ""))
4433 (match_operand:QI 2 "register_operand" ""))
4434 (parallel [(set (reg:HI 22)
4435 (unspec:HI [(reg:QI 24)
4436 (reg:QI 25)] UNSPEC_FMUL))
4437 (clobber (reg:HI 24))])
4438 (set (match_operand:HI 0 "register_operand" "")
4444 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
4449 (define_insn "fmul_insn"
4450 [(set (match_operand:HI 0 "register_operand" "=r")
4451 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4452 (match_operand:QI 2 "register_operand" "a")]
4458 [(set_attr "length" "3")
4459 (set_attr "cc" "clobber")])
4461 (define_insn "*fmul.call"
4463 (unspec:HI [(reg:QI 24)
4464 (reg:QI 25)] UNSPEC_FMUL))
4465 (clobber (reg:HI 24))]
4468 [(set_attr "type" "xcall")
4469 (set_attr "cc" "clobber")])
4472 (define_expand "fmuls"
4474 (match_operand:QI 1 "register_operand" ""))
4476 (match_operand:QI 2 "register_operand" ""))
4477 (parallel [(set (reg:HI 22)
4478 (unspec:HI [(reg:QI 24)
4479 (reg:QI 25)] UNSPEC_FMULS))
4480 (clobber (reg:HI 24))])
4481 (set (match_operand:HI 0 "register_operand" "")
4487 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
4492 (define_insn "fmuls_insn"
4493 [(set (match_operand:HI 0 "register_operand" "=r")
4494 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4495 (match_operand:QI 2 "register_operand" "a")]
4501 [(set_attr "length" "3")
4502 (set_attr "cc" "clobber")])
4504 (define_insn "*fmuls.call"
4506 (unspec:HI [(reg:QI 24)
4507 (reg:QI 25)] UNSPEC_FMULS))
4508 (clobber (reg:HI 24))]
4511 [(set_attr "type" "xcall")
4512 (set_attr "cc" "clobber")])
4515 (define_expand "fmulsu"
4517 (match_operand:QI 1 "register_operand" ""))
4519 (match_operand:QI 2 "register_operand" ""))
4520 (parallel [(set (reg:HI 22)
4521 (unspec:HI [(reg:QI 24)
4522 (reg:QI 25)] UNSPEC_FMULSU))
4523 (clobber (reg:HI 24))])
4524 (set (match_operand:HI 0 "register_operand" "")
4530 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
4535 (define_insn "fmulsu_insn"
4536 [(set (match_operand:HI 0 "register_operand" "=r")
4537 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4538 (match_operand:QI 2 "register_operand" "a")]
4544 [(set_attr "length" "3")
4545 (set_attr "cc" "clobber")])
4547 (define_insn "*fmulsu.call"
4549 (unspec:HI [(reg:QI 24)
4550 (reg:QI 25)] UNSPEC_FMULSU))
4551 (clobber (reg:HI 24))]
4554 [(set_attr "type" "xcall")
4555 (set_attr "cc" "clobber")])
4558 ;; Some combiner patterns dealing with bits.
4561 ;; Move bit $3.0 into bit $0.$4
4562 (define_insn "*movbitqi.1-6.a"
4563 [(set (match_operand:QI 0 "register_operand" "=r")
4564 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4565 (match_operand:QI 2 "single_zero_operand" "n"))
4566 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
4567 (match_operand:QI 4 "const_0_to_7_operand" "n"))
4568 (match_operand:QI 5 "single_one_operand" "n"))))]
4569 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
4570 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
4571 "bst %3,0\;bld %0,%4"
4572 [(set_attr "length" "2")
4573 (set_attr "cc" "none")])
4575 ;; Move bit $3.0 into bit $0.$4
4576 ;; Variation of above. Unfortunately, there is no canonicalized representation
4577 ;; of moving around bits. So what we see here depends on how user writes down
4578 ;; bit manipulations.
4579 (define_insn "*movbitqi.1-6.b"
4580 [(set (match_operand:QI 0 "register_operand" "=r")
4581 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4582 (match_operand:QI 2 "single_zero_operand" "n"))
4583 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
4585 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
4586 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4587 "bst %3,0\;bld %0,%4"
4588 [(set_attr "length" "2")
4589 (set_attr "cc" "none")])
4591 ;; Move bit $3.0 into bit $0.0.
4592 ;; For bit 0, combiner generates slightly different pattern.
4593 (define_insn "*movbitqi.0"
4594 [(set (match_operand:QI 0 "register_operand" "=r")
4595 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4596 (match_operand:QI 2 "single_zero_operand" "n"))
4597 (and:QI (match_operand:QI 3 "register_operand" "r")
4599 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4600 "bst %3,0\;bld %0,0"
4601 [(set_attr "length" "2")
4602 (set_attr "cc" "none")])
4604 ;; Move bit $2.0 into bit $0.7.
4605 ;; For bit 7, combiner generates slightly different pattern
4606 (define_insn "*movbitqi.7"
4607 [(set (match_operand:QI 0 "register_operand" "=r")
4608 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4610 (ashift:QI (match_operand:QI 2 "register_operand" "r")
4613 "bst %2,0\;bld %0,7"
4614 [(set_attr "length" "2")
4615 (set_attr "cc" "none")])
4617 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
4618 ;; and input/output match. We provide a special pattern for this, because
4619 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
4620 ;; operation on I/O is atomic.
4621 (define_insn "*insv.io"
4622 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
4624 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
4625 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
4630 sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
4631 [(set_attr "length" "1,1,4")
4632 (set_attr "cc" "none")])
4634 (define_insn "*insv.not.io"
4635 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4637 (match_operand:QI 1 "const_0_to_7_operand" "n"))
4638 (not:QI (match_operand:QI 2 "register_operand" "r")))]
4640 "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
4641 [(set_attr "length" "4")
4642 (set_attr "cc" "none")])
4644 ;; The insv expander.
4645 ;; We only support 1-bit inserts
4646 (define_expand "insv"
4647 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
4648 (match_operand:QI 1 "const1_operand" "") ; width
4649 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
4650 (match_operand:QI 3 "nonmemory_operand" ""))]
4654 ;; Insert bit $2.0 into $0.$1
4655 (define_insn "*insv.reg"
4656 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
4658 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
4659 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
4663 andi %0,lo8(~(1<<%1))
4667 [(set_attr "length" "2,1,1,2,2")
4668 (set_attr "cc" "none,set_zn,set_zn,none,none")])
4671 ;; Some combine patterns that try to fix bad code when a value is composed
4672 ;; from byte parts like in PR27663.
4673 ;; The patterns give some release but the code still is not optimal,
4674 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
4675 ;; That switch obfuscates things here and in many other places.
4677 (define_insn_and_split "*ior<mode>qi.byte0"
4678 [(set (match_operand:HISI 0 "register_operand" "=r")
4680 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4681 (match_operand:HISI 2 "register_operand" "0")))]
4686 (ior:QI (match_dup 3)
4689 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
4692 (define_insn_and_split "*ior<mode>qi.byte1-3"
4693 [(set (match_operand:HISI 0 "register_operand" "=r")
4695 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4696 (match_operand:QI 2 "const_8_16_24_operand" "n"))
4697 (match_operand:HISI 3 "register_operand" "0")))]
4698 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
4700 "&& reload_completed"
4702 (ior:QI (match_dup 4)
4705 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
4706 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
4709 (define_expand "extzv"
4710 [(set (match_operand:QI 0 "register_operand" "")
4711 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
4712 (match_operand:QI 2 "const1_operand" "")
4713 (match_operand:QI 3 "const_0_to_7_operand" "")))]
4717 (define_insn "*extzv"
4718 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
4719 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
4721 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
4725 mov %0,%1\;andi %0,1
4728 bst %1,%2\;clr %0\;bld %0,0"
4729 [(set_attr "length" "1,2,2,2,3")
4730 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
4732 (define_insn_and_split "*extzv.qihi1"
4733 [(set (match_operand:HI 0 "register_operand" "=r")
4734 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
4736 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
4741 (zero_extract:QI (match_dup 1)
4747 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4748 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4751 (define_insn_and_split "*extzv.qihi2"
4752 [(set (match_operand:HI 0 "register_operand" "=r")
4754 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
4756 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
4761 (zero_extract:QI (match_dup 1)
4767 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4768 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);