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 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"
61 (define_c_enum "unspecv"
62 [UNSPECV_PROLOGUE_SAVES
63 UNSPECV_EPILOGUE_RESTORES
64 UNSPECV_WRITE_SP_IRQ_ON
65 UNSPECV_WRITE_SP_IRQ_OFF
75 (include "predicates.md")
76 (include "constraints.md")
78 ;; Condition code settings.
79 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
80 (const_string "none"))
82 (define_attr "type" "branch,branch1,arith,xcall"
83 (const_string "arith"))
85 (define_attr "mcu_have_movw" "yes,no"
86 (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
88 (const_string "no"))))
90 (define_attr "mcu_mega" "yes,no"
91 (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
93 (const_string "no"))))
96 ;; The size of instructions in bytes.
97 ;; XXX may depend from "cc"
99 (define_attr "length" ""
100 (cond [(eq_attr "type" "branch")
101 (if_then_else (and (ge (minus (pc) (match_dup 0))
103 (le (minus (pc) (match_dup 0))
106 (if_then_else (and (ge (minus (pc) (match_dup 0))
108 (le (minus (pc) (match_dup 0))
112 (eq_attr "type" "branch1")
113 (if_then_else (and (ge (minus (pc) (match_dup 0))
115 (le (minus (pc) (match_dup 0))
118 (if_then_else (and (ge (minus (pc) (match_dup 0))
120 (le (minus (pc) (match_dup 0))
124 (eq_attr "type" "xcall")
125 (if_then_else (eq_attr "mcu_mega" "no")
130 ;; Define mode iterators
131 (define_mode_iterator QIHI [(QI "") (HI "")])
132 (define_mode_iterator QIHI2 [(QI "") (HI "")])
133 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
134 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
135 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
136 (define_mode_iterator HISI [(HI "") (SI "")])
138 ;; Define code iterators
139 ;; Define two incarnations so that we can build the cross product.
140 (define_code_iterator any_extend [sign_extend zero_extend])
141 (define_code_iterator any_extend2 [sign_extend zero_extend])
143 ;; Define code attributes
144 (define_code_attr extend_su
148 (define_code_attr extend_u
153 ;;========================================================================
154 ;; The following is used by nonlocal_goto and setjmp.
155 ;; The receiver pattern will create no instructions since internally
156 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
157 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
158 ;; The 'null' receiver also avoids problems with optimisation
159 ;; not recognising incoming jmp and removing code that resets frame_pointer.
160 ;; The code derived from builtins.c.
162 (define_expand "nonlocal_goto_receiver"
164 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
167 emit_move_insn (virtual_stack_vars_rtx,
168 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
169 gen_int_mode (STARTING_FRAME_OFFSET,
171 /* This might change the hard frame pointer in ways that aren't
172 apparent to early optimization passes, so force a clobber. */
173 emit_clobber (hard_frame_pointer_rtx);
178 ;; Defining nonlocal_goto_receiver means we must also define this.
179 ;; even though its function is identical to that in builtins.c
181 (define_expand "nonlocal_goto"
183 (use (match_operand 0 "general_operand"))
184 (use (match_operand 1 "general_operand"))
185 (use (match_operand 2 "general_operand"))
186 (use (match_operand 3 "general_operand"))
190 rtx r_label = copy_to_reg (operands[1]);
191 rtx r_fp = operands[3];
192 rtx r_sp = operands[2];
194 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
196 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
198 emit_move_insn (hard_frame_pointer_rtx, r_fp);
199 emit_stack_restore (SAVE_NONLOCAL, r_sp);
201 emit_use (hard_frame_pointer_rtx);
202 emit_use (stack_pointer_rtx);
204 emit_indirect_jump (r_label);
209 (define_insn "pushqi1"
210 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
211 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
216 [(set_attr "length" "1,1")])
218 ;; All modes for a multi-byte push. We must include complex modes here too,
219 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
220 (define_mode_iterator MPUSH
227 (define_expand "push<mode>1"
228 [(match_operand:MPUSH 0 "" "")]
232 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
234 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
235 if (part != const0_rtx)
236 part = force_reg (QImode, part);
237 emit_insn (gen_pushqi1 (part));
242 ;; Notice a special-case when adding N to SP where N results in a
243 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
245 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
247 && frame_pointer_needed
248 && !cfun->calls_alloca
249 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
250 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
253 ;;========================================================================
255 ;; The last alternative (any immediate constant to any register) is
256 ;; very expensive. It should be optimized by peephole2 if a scratch
257 ;; register is available, but then that register could just as well be
258 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
259 ;; are call-saved registers, and most of LD_REGS are call-used registers,
260 ;; so this may still be a win for registers live across function calls.
262 (define_expand "movqi"
263 [(set (match_operand:QI 0 "nonimmediate_operand" "")
264 (match_operand:QI 1 "general_operand" ""))]
266 "/* One of the ops has to be in a register. */
267 if (!register_operand(operand0, QImode)
268 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
269 operands[1] = copy_to_mode_reg(QImode, operand1);
272 (define_insn "*movqi"
273 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
274 (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))]
275 "(register_operand (operands[0],QImode)
276 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
277 "* return output_movqi (insn, operands, NULL);"
278 [(set_attr "length" "1,1,5,5,1,1,4")
279 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
281 ;; This is used in peephole2 to optimize loading immediate constants
282 ;; if a scratch register from LD_REGS happens to be available.
284 (define_insn "*reload_inqi"
285 [(set (match_operand:QI 0 "register_operand" "=l")
286 (match_operand:QI 1 "immediate_operand" "i"))
287 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
291 [(set_attr "length" "2")
292 (set_attr "cc" "none")])
295 [(match_scratch:QI 2 "d")
296 (set (match_operand:QI 0 "l_register_operand" "")
297 (match_operand:QI 1 "immediate_operand" ""))]
298 "(operands[1] != const0_rtx
299 && operands[1] != const1_rtx
300 && operands[1] != constm1_rtx)"
301 [(parallel [(set (match_dup 0) (match_dup 1))
302 (clobber (match_dup 2))])]
305 ;;============================================================================
306 ;; move word (16 bit)
308 (define_expand "movhi"
309 [(set (match_operand:HI 0 "nonimmediate_operand" "")
310 (match_operand:HI 1 "general_operand" ""))]
314 /* One of the ops has to be in a register. */
315 if (!register_operand(operand0, HImode)
316 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
318 operands[1] = copy_to_mode_reg(HImode, operand1);
322 (define_insn "*movhi_sp"
323 [(set (match_operand:HI 0 "register_operand" "=q,r")
324 (match_operand:HI 1 "register_operand" "r,q"))]
325 "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
326 || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
327 "* return output_movhi (insn, operands, NULL);"
328 [(set_attr "length" "5,2")
329 (set_attr "cc" "none,none")])
331 (define_insn "movhi_sp_r_irq_off"
332 [(set (match_operand:HI 0 "stack_register_operand" "=q")
333 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
334 UNSPECV_WRITE_SP_IRQ_OFF))]
338 [(set_attr "length" "2")
339 (set_attr "cc" "none")])
341 (define_insn "movhi_sp_r_irq_on"
342 [(set (match_operand:HI 0 "stack_register_operand" "=q")
343 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
344 UNSPECV_WRITE_SP_IRQ_ON))]
350 [(set_attr "length" "4")
351 (set_attr "cc" "none")])
354 [(match_scratch:QI 2 "d")
355 (set (match_operand:HI 0 "l_register_operand" "")
356 (match_operand:HI 1 "immediate_operand" ""))]
357 "(operands[1] != const0_rtx
358 && operands[1] != constm1_rtx)"
359 [(parallel [(set (match_dup 0) (match_dup 1))
360 (clobber (match_dup 2))])]
363 ;; '*' because it is not used in rtl generation, only in above peephole
364 (define_insn "*reload_inhi"
365 [(set (match_operand:HI 0 "register_operand" "=r")
366 (match_operand:HI 1 "immediate_operand" "i"))
367 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
369 "* return output_reload_inhi (insn, operands, NULL);"
370 [(set_attr "length" "4")
371 (set_attr "cc" "none")])
373 (define_insn "*movhi"
374 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
375 (match_operand:HI 1 "general_operand" "rL,m,rL,i,i,r,q"))]
376 "(register_operand (operands[0],HImode)
377 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
378 "* return output_movhi (insn, operands, NULL);"
379 [(set_attr "length" "2,6,7,2,6,5,2")
380 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
382 (define_peephole2 ; movw
383 [(set (match_operand:QI 0 "even_register_operand" "")
384 (match_operand:QI 1 "even_register_operand" ""))
385 (set (match_operand:QI 2 "odd_register_operand" "")
386 (match_operand:QI 3 "odd_register_operand" ""))]
388 && REGNO (operands[0]) == REGNO (operands[2]) - 1
389 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
390 [(set (match_dup 4) (match_dup 5))]
392 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
393 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
396 (define_peephole2 ; movw_r
397 [(set (match_operand:QI 0 "odd_register_operand" "")
398 (match_operand:QI 1 "odd_register_operand" ""))
399 (set (match_operand:QI 2 "even_register_operand" "")
400 (match_operand:QI 3 "even_register_operand" ""))]
402 && REGNO (operands[2]) == REGNO (operands[0]) - 1
403 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
404 [(set (match_dup 4) (match_dup 5))]
406 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
407 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
410 ;;==========================================================================
411 ;; move double word (32 bit)
413 (define_expand "movsi"
414 [(set (match_operand:SI 0 "nonimmediate_operand" "")
415 (match_operand:SI 1 "general_operand" ""))]
419 /* One of the ops has to be in a register. */
420 if (!register_operand (operand0, SImode)
421 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
423 operands[1] = copy_to_mode_reg (SImode, operand1);
429 (define_peephole2 ; *reload_insi
430 [(match_scratch:QI 2 "d")
431 (set (match_operand:SI 0 "l_register_operand" "")
432 (match_operand:SI 1 "const_int_operand" ""))
434 "(operands[1] != const0_rtx
435 && operands[1] != constm1_rtx)"
436 [(parallel [(set (match_dup 0) (match_dup 1))
437 (clobber (match_dup 2))])]
440 ;; '*' because it is not used in rtl generation.
441 (define_insn "*reload_insi"
442 [(set (match_operand:SI 0 "register_operand" "=r")
443 (match_operand:SI 1 "const_int_operand" "n"))
444 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
447 return output_reload_insisf (insn, operands, operands[2], NULL);
449 [(set_attr "length" "8")
450 (set_attr "cc" "clobber")])
453 (define_insn "*movsi"
454 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
455 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
456 "(register_operand (operands[0],SImode)
457 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
459 return output_movsisf (insn, operands, NULL_RTX, NULL);
461 [(set_attr "length" "4,4,8,9,4,10")
462 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
464 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
465 ;; move floating point numbers (32 bit)
467 (define_expand "movsf"
468 [(set (match_operand:SF 0 "nonimmediate_operand" "")
469 (match_operand:SF 1 "general_operand" ""))]
473 /* One of the ops has to be in a register. */
474 if (!register_operand (operand1, SFmode)
475 && !register_operand (operand0, SFmode))
477 operands[1] = copy_to_mode_reg (SFmode, operand1);
481 (define_insn "*movsf"
482 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
483 (match_operand:SF 1 "general_operand" "r,G,Qm,rG,F,F"))]
484 "register_operand (operands[0], SFmode)
485 || register_operand (operands[1], SFmode)
486 || operands[1] == CONST0_RTX (SFmode)"
488 return output_movsisf (insn, operands, NULL_RTX, NULL);
490 [(set_attr "length" "4,4,8,9,4,10")
491 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
493 (define_peephole2 ; *reload_insf
494 [(match_scratch:QI 2 "d")
495 (set (match_operand:SF 0 "l_register_operand" "")
496 (match_operand:SF 1 "const_double_operand" ""))
498 "operands[1] != CONST0_RTX (SFmode)"
499 [(parallel [(set (match_dup 0)
501 (clobber (match_dup 2))])]
504 ;; '*' because it is not used in rtl generation.
505 (define_insn "*reload_insf"
506 [(set (match_operand:SF 0 "register_operand" "=r")
507 (match_operand:SF 1 "const_double_operand" "F"))
508 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
511 return output_reload_insisf (insn, operands, operands[2], NULL);
513 [(set_attr "length" "8")
514 (set_attr "cc" "clobber")])
516 ;;=========================================================================
517 ;; move string (like memcpy)
518 ;; implement as RTL loop
520 (define_expand "movmemhi"
521 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
522 (match_operand:BLK 1 "memory_operand" ""))
523 (use (match_operand:HI 2 "const_int_operand" ""))
524 (use (match_operand:HI 3 "const_int_operand" ""))])]
529 enum machine_mode mode;
530 rtx label = gen_label_rtx ();
534 /* Copy pointers into new psuedos - they will be changed. */
535 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
536 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
538 /* Create rtx for tmp register - we use this as scratch. */
539 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
541 if (GET_CODE (operands[2]) != CONST_INT)
544 count = INTVAL (operands[2]);
548 /* Work out branch probability for latter use. */
549 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
551 /* See if constant fit 8 bits. */
552 mode = (count < 0x100) ? QImode : HImode;
553 /* Create loop counter register. */
554 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
556 /* Now create RTL code for move loop. */
557 /* Label at top of loop. */
560 /* Move one byte into scratch and inc pointer. */
561 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
562 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
564 /* Move to mem and inc pointer. */
565 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
566 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
568 /* Decrement count. */
569 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
571 /* Compare with zero and jump if not equal. */
572 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
574 /* Set jump probability based on loop count. */
575 jump = get_last_insn ();
576 add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
580 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
581 ;; memset (%0, %2, %1)
583 (define_expand "setmemhi"
584 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
585 (match_operand 2 "const_int_operand" ""))
586 (use (match_operand:HI 1 "const_int_operand" ""))
587 (use (match_operand:HI 3 "const_int_operand" "n"))
588 (clobber (match_scratch:HI 4 ""))
589 (clobber (match_dup 5))])]
594 enum machine_mode mode;
596 /* If value to set is not zero, use the library routine. */
597 if (operands[2] != const0_rtx)
600 if (GET_CODE (operands[1]) != CONST_INT)
603 cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
604 mode = cnt8 ? QImode : HImode;
605 operands[5] = gen_rtx_SCRATCH (mode);
606 operands[1] = copy_to_mode_reg (mode,
607 gen_int_mode (INTVAL (operands[1]), mode));
608 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
609 operands[0] = gen_rtx_MEM (BLKmode, addr0);
612 (define_insn "*clrmemqi"
613 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
615 (use (match_operand:QI 1 "register_operand" "r"))
616 (use (match_operand:QI 2 "const_int_operand" "n"))
617 (clobber (match_scratch:HI 3 "=0"))
618 (clobber (match_scratch:QI 4 "=&1"))]
620 "st %a0+,__zero_reg__
623 [(set_attr "length" "3")
624 (set_attr "cc" "clobber")])
626 (define_insn "*clrmemhi"
627 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
629 (use (match_operand:HI 1 "register_operand" "!w,d"))
630 (use (match_operand:HI 2 "const_int_operand" "n,n"))
631 (clobber (match_scratch:HI 3 "=0,0"))
632 (clobber (match_scratch:HI 4 "=&1,&1"))]
635 if (which_alternative==0)
636 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
637 AS2 (sbiw,%A1,1) CR_TAB
640 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
641 AS2 (subi,%A1,1) CR_TAB
642 AS2 (sbci,%B1,0) CR_TAB
645 [(set_attr "length" "3,4")
646 (set_attr "cc" "clobber,clobber")])
648 (define_expand "strlenhi"
650 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
651 (match_operand:QI 2 "const_int_operand" "")
652 (match_operand:HI 3 "immediate_operand" "")]
654 (set (match_dup 4) (plus:HI (match_dup 4)
656 (set (match_operand:HI 0 "register_operand" "")
657 (minus:HI (match_dup 4)
662 if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
664 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
665 operands[1] = gen_rtx_MEM (BLKmode, addr);
667 operands[4] = gen_reg_rtx (HImode);
670 (define_insn "*strlenhi"
671 [(set (match_operand:HI 0 "register_operand" "=e")
672 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
674 (match_operand:HI 2 "immediate_operand" "i")]
680 [(set_attr "length" "3")
681 (set_attr "cc" "clobber")])
683 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
686 (define_insn "addqi3"
687 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
688 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
689 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
696 [(set_attr "length" "1,1,1,1")
697 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
700 (define_expand "addhi3"
701 [(set (match_operand:HI 0 "register_operand" "")
702 (plus:HI (match_operand:HI 1 "register_operand" "")
703 (match_operand:HI 2 "nonmemory_operand" "")))]
707 if (GET_CODE (operands[2]) == CONST_INT)
709 short tmp = INTVAL (operands[2]);
710 operands[2] = GEN_INT(tmp);
715 (define_insn "*addhi3_zero_extend"
716 [(set (match_operand:HI 0 "register_operand" "=r")
717 (plus:HI (zero_extend:HI
718 (match_operand:QI 1 "register_operand" "r"))
719 (match_operand:HI 2 "register_operand" "0")))]
722 adc %B0,__zero_reg__"
723 [(set_attr "length" "2")
724 (set_attr "cc" "set_n")])
726 (define_insn "*addhi3_zero_extend1"
727 [(set (match_operand:HI 0 "register_operand" "=r")
728 (plus:HI (match_operand:HI 1 "register_operand" "%0")
730 (match_operand:QI 2 "register_operand" "r"))))]
733 adc %B0,__zero_reg__"
734 [(set_attr "length" "2")
735 (set_attr "cc" "set_n")])
737 (define_insn "*addhi3_sp_R_pc2"
738 [(set (match_operand:HI 1 "stack_register_operand" "=q")
739 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
740 (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
743 if (CONST_INT_P (operands[0]))
745 switch(INTVAL (operands[0]))
748 return \"rcall .\" CR_TAB
752 return \"rcall .\" CR_TAB
754 \"push __tmp_reg__\";
756 return \"rcall .\" CR_TAB
759 return \"rcall .\" CR_TAB
760 \"push __tmp_reg__\";
764 return \"push __tmp_reg__\";
768 return \"pop __tmp_reg__\";
770 return \"pop __tmp_reg__\" CR_TAB
773 return \"pop __tmp_reg__\" CR_TAB
774 \"pop __tmp_reg__\" CR_TAB
777 return \"pop __tmp_reg__\" CR_TAB
778 \"pop __tmp_reg__\" CR_TAB
779 \"pop __tmp_reg__\" CR_TAB
782 return \"pop __tmp_reg__\" CR_TAB
783 \"pop __tmp_reg__\" CR_TAB
784 \"pop __tmp_reg__\" CR_TAB
785 \"pop __tmp_reg__\" CR_TAB
791 [(set (attr "length")
792 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
793 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
794 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
795 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
796 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
797 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
798 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
799 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
800 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
801 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
802 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
803 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
806 (define_insn "*addhi3_sp_R_pc3"
807 [(set (match_operand:HI 1 "stack_register_operand" "=q")
808 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
809 (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
812 if (CONST_INT_P (operands[0]))
814 switch(INTVAL (operands[0]))
817 return \"rcall .\" CR_TAB
820 return \"rcall .\" CR_TAB
821 \"push __tmp_reg__\" CR_TAB
822 \"push __tmp_reg__\";
824 return \"rcall .\" CR_TAB
825 \"push __tmp_reg__\";
829 return \"push __tmp_reg__\" CR_TAB
830 \"push __tmp_reg__\";
832 return \"push __tmp_reg__\";
836 return \"pop __tmp_reg__\";
838 return \"pop __tmp_reg__\" CR_TAB
841 return \"pop __tmp_reg__\" CR_TAB
842 \"pop __tmp_reg__\" CR_TAB
845 return \"pop __tmp_reg__\" CR_TAB
846 \"pop __tmp_reg__\" CR_TAB
847 \"pop __tmp_reg__\" CR_TAB
850 return \"pop __tmp_reg__\" CR_TAB
851 \"pop __tmp_reg__\" CR_TAB
852 \"pop __tmp_reg__\" CR_TAB
853 \"pop __tmp_reg__\" CR_TAB
859 [(set (attr "length")
860 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
861 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
862 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
863 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
864 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
865 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
866 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
867 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
868 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
869 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
870 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
871 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
874 (define_insn "*addhi3"
875 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
877 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
878 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
881 add %A0,%A2\;adc %B0,%B2
884 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
885 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
886 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
887 [(set_attr "length" "2,1,1,2,3,3")
888 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
890 (define_insn "addsi3"
891 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
893 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
894 (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
897 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
898 adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
899 sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
900 subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
901 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
902 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
903 [(set_attr "length" "4,3,3,4,5,5")
904 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
906 (define_insn "*addsi3_zero_extend"
907 [(set (match_operand:SI 0 "register_operand" "=r")
908 (plus:SI (zero_extend:SI
909 (match_operand:QI 1 "register_operand" "r"))
910 (match_operand:SI 2 "register_operand" "0")))]
915 adc %D0,__zero_reg__"
916 [(set_attr "length" "4")
917 (set_attr "cc" "set_n")])
919 ;-----------------------------------------------------------------------------
921 (define_insn "subqi3"
922 [(set (match_operand:QI 0 "register_operand" "=r,d")
923 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
924 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
929 [(set_attr "length" "1,1")
930 (set_attr "cc" "set_czn,set_czn")])
932 (define_insn "subhi3"
933 [(set (match_operand:HI 0 "register_operand" "=r,d")
934 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
935 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
938 sub %A0,%A2\;sbc %B0,%B2
939 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
940 [(set_attr "length" "2,2")
941 (set_attr "cc" "set_czn,set_czn")])
943 (define_insn "*subhi3_zero_extend1"
944 [(set (match_operand:HI 0 "register_operand" "=r")
945 (minus:HI (match_operand:HI 1 "register_operand" "0")
947 (match_operand:QI 2 "register_operand" "r"))))]
950 sbc %B0,__zero_reg__"
951 [(set_attr "length" "2")
952 (set_attr "cc" "set_n")])
954 (define_insn "subsi3"
955 [(set (match_operand:SI 0 "register_operand" "=r,d")
956 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
957 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
960 sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
961 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
962 [(set_attr "length" "4,4")
963 (set_attr "cc" "set_czn,set_czn")])
965 (define_insn "*subsi3_zero_extend"
966 [(set (match_operand:SI 0 "register_operand" "=r")
967 (minus:SI (match_operand:SI 1 "register_operand" "0")
969 (match_operand:QI 2 "register_operand" "r"))))]
974 sbc %D0,__zero_reg__"
975 [(set_attr "length" "4")
976 (set_attr "cc" "set_n")])
978 ;******************************************************************************
981 (define_expand "mulqi3"
982 [(set (match_operand:QI 0 "register_operand" "")
983 (mult:QI (match_operand:QI 1 "register_operand" "")
984 (match_operand:QI 2 "register_operand" "")))]
989 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
994 (define_insn "*mulqi3_enh"
995 [(set (match_operand:QI 0 "register_operand" "=r")
996 (mult:QI (match_operand:QI 1 "register_operand" "r")
997 (match_operand:QI 2 "register_operand" "r")))]
1002 [(set_attr "length" "3")
1003 (set_attr "cc" "clobber")])
1005 (define_expand "mulqi3_call"
1006 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1007 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1008 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1009 (clobber (reg:QI 22))])
1010 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1014 (define_insn "*mulqi3_call"
1015 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1016 (clobber (reg:QI 22))]
1019 [(set_attr "type" "xcall")
1020 (set_attr "cc" "clobber")])
1022 (define_insn "smulqi3_highpart"
1023 [(set (match_operand:QI 0 "register_operand" "=r")
1025 (lshiftrt:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1026 (sign_extend:HI (match_operand:QI 2 "register_operand" "d")))
1032 [(set_attr "length" "3")
1033 (set_attr "cc" "clobber")])
1035 (define_insn "umulqi3_highpart"
1036 [(set (match_operand:QI 0 "register_operand" "=r")
1038 (lshiftrt:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1039 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))
1045 [(set_attr "length" "3")
1046 (set_attr "cc" "clobber")])
1048 ;; Used when expanding div or mod inline for some special values
1049 (define_insn "*subqi3.ashiftrt7"
1050 [(set (match_operand:QI 0 "register_operand" "=r")
1051 (minus:QI (match_operand:QI 1 "register_operand" "0")
1052 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1056 [(set_attr "length" "2")
1057 (set_attr "cc" "clobber")])
1059 (define_insn "mulqihi3"
1060 [(set (match_operand:HI 0 "register_operand" "=r")
1061 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1062 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
1067 [(set_attr "length" "3")
1068 (set_attr "cc" "clobber")])
1070 (define_insn "umulqihi3"
1071 [(set (match_operand:HI 0 "register_operand" "=r")
1072 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1073 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1078 [(set_attr "length" "3")
1079 (set_attr "cc" "clobber")])
1081 (define_insn "usmulqihi3"
1082 [(set (match_operand:HI 0 "register_operand" "=r")
1083 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1084 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1089 [(set_attr "length" "3")
1090 (set_attr "cc" "clobber")])
1092 ;; Above insn is not canonicalized by insn combine, so here is a version with
1093 ;; operands swapped.
1095 (define_insn "*sumulqihi3"
1096 [(set (match_operand:HI 0 "register_operand" "=r")
1097 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1098 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1103 [(set_attr "length" "3")
1104 (set_attr "cc" "clobber")])
1106 ;; One-extend operand 1
1108 (define_insn "*osmulqihi3"
1109 [(set (match_operand:HI 0 "register_operand" "=&r")
1110 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1111 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1117 [(set_attr "length" "4")
1118 (set_attr "cc" "clobber")])
1120 (define_insn "*oumulqihi3"
1121 [(set (match_operand:HI 0 "register_operand" "=&r")
1122 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1123 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1129 [(set_attr "length" "4")
1130 (set_attr "cc" "clobber")])
1133 ;******************************************************************************
1134 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1135 ;******************************************************************************
1137 (define_insn_and_split "*muluqihi3.uconst"
1138 [(set (match_operand:HI 0 "register_operand" "=r")
1139 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1140 (match_operand:HI 2 "u8_operand" "M")))
1141 (clobber (match_scratch:QI 3 "=&d"))]
1144 "&& reload_completed"
1149 (mult:HI (zero_extend:HI (match_dup 1))
1150 (zero_extend:HI (match_dup 3))))]
1152 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1155 (define_insn_and_split "*muluqihi3.sconst"
1156 [(set (match_operand:HI 0 "register_operand" "=r")
1157 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1158 (match_operand:HI 2 "s8_operand" "n")))
1159 (clobber (match_scratch:QI 3 "=&a"))]
1162 "&& reload_completed"
1167 (mult:HI (zero_extend:HI (match_dup 1))
1168 (sign_extend:HI (match_dup 3))))]
1170 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1173 (define_insn_and_split "*mulsqihi3.sconst"
1174 [(set (match_operand:HI 0 "register_operand" "=r")
1175 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1176 (match_operand:HI 2 "s8_operand" "n")))
1177 (clobber (match_scratch:QI 3 "=&d"))]
1180 "&& reload_completed"
1185 (mult:HI (sign_extend:HI (match_dup 1))
1186 (sign_extend:HI (match_dup 3))))]
1188 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1191 (define_insn_and_split "*mulsqihi3.uconst"
1192 [(set (match_operand:HI 0 "register_operand" "=r")
1193 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1194 (match_operand:HI 2 "u8_operand" "M")))
1195 (clobber (match_scratch:QI 3 "=&a"))]
1198 "&& reload_completed"
1203 (mult:HI (zero_extend:HI (match_dup 3))
1204 (sign_extend:HI (match_dup 1))))]
1206 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1209 (define_insn_and_split "*mulsqihi3.oconst"
1210 [(set (match_operand:HI 0 "register_operand" "=&r")
1211 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1212 (match_operand:HI 2 "o8_operand" "n")))
1213 (clobber (match_scratch:QI 3 "=&a"))]
1216 "&& reload_completed"
1221 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1222 (sign_extend:HI (match_dup 1))))]
1224 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1227 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1228 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1229 ;; at that time. Fix that.
1231 (define_insn_and_split "*ashifthi3.signx.const"
1232 [(set (match_operand:HI 0 "register_operand" "=r")
1233 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1234 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1235 (clobber (match_scratch:QI 3 "=&d"))]
1238 "&& reload_completed"
1243 (mult:HI (sign_extend:HI (match_dup 1))
1244 (sign_extend:HI (match_dup 3))))]
1246 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1249 (define_insn_and_split "*ashifthi3.signx.const7"
1250 [(set (match_operand:HI 0 "register_operand" "=r")
1251 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1253 (clobber (match_scratch:QI 2 "=&a"))]
1256 "&& reload_completed"
1261 (mult:HI (zero_extend:HI (match_dup 2))
1262 (sign_extend:HI (match_dup 1))))]
1264 operands[3] = gen_int_mode (1 << 7, QImode);
1267 (define_insn_and_split "*ashifthi3.zerox.const"
1268 [(set (match_operand:HI 0 "register_operand" "=r")
1269 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1270 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1271 (clobber (match_scratch:QI 3 "=&d"))]
1274 "&& reload_completed"
1279 (mult:HI (zero_extend:HI (match_dup 1))
1280 (zero_extend:HI (match_dup 3))))]
1282 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1285 ;******************************************************************************
1286 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1287 ;******************************************************************************
1289 (define_insn "mulsqihi3"
1290 [(set (match_operand:HI 0 "register_operand" "=&r")
1291 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1292 (match_operand:HI 2 "register_operand" "a")))]
1299 [(set_attr "length" "5")
1300 (set_attr "cc" "clobber")])
1302 (define_insn "muluqihi3"
1303 [(set (match_operand:HI 0 "register_operand" "=&r")
1304 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1305 (match_operand:HI 2 "register_operand" "r")))]
1312 [(set_attr "length" "5")
1313 (set_attr "cc" "clobber")])
1315 ;; one-extend operand 1
1317 (define_insn "muloqihi3"
1318 [(set (match_operand:HI 0 "register_operand" "=&r")
1319 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1320 (match_operand:HI 2 "register_operand" "r")))]
1328 [(set_attr "length" "6")
1329 (set_attr "cc" "clobber")])
1331 ;******************************************************************************
1333 (define_expand "mulhi3"
1334 [(set (match_operand:HI 0 "register_operand" "")
1335 (mult:HI (match_operand:HI 1 "register_operand" "")
1336 (match_operand:HI 2 "register_or_s9_operand" "")))]
1341 if (!register_operand (operands[2], HImode))
1342 operands[2] = force_reg (HImode, operands[2]);
1344 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1348 /* For small constants we can do better by extending them on the fly.
1349 The constant can be loaded in one instruction and the widening
1350 multiplication is shorter. First try the unsigned variant because it
1351 allows constraint "d" instead of "a" for the signed version. */
1353 if (s9_operand (operands[2], HImode))
1355 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1357 if (u8_operand (operands[2], HImode))
1359 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1361 else if (s8_operand (operands[2], HImode))
1363 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1367 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1373 if (!register_operand (operands[2], HImode))
1374 operands[2] = force_reg (HImode, operands[2]);
1377 (define_insn "*mulhi3_enh"
1378 [(set (match_operand:HI 0 "register_operand" "=&r")
1379 (mult:HI (match_operand:HI 1 "register_operand" "r")
1380 (match_operand:HI 2 "register_operand" "r")))]
1389 [(set_attr "length" "7")
1390 (set_attr "cc" "clobber")])
1392 (define_expand "mulhi3_call"
1393 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1394 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1395 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1396 (clobber (reg:HI 22))
1397 (clobber (reg:QI 21))])
1398 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1402 (define_insn "*mulhi3_call"
1403 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1404 (clobber (reg:HI 22))
1405 (clobber (reg:QI 21))]
1408 [(set_attr "type" "xcall")
1409 (set_attr "cc" "clobber")])
1411 ;; To support widening multiplicatioon with constant we postpone
1412 ;; expanding to the implicit library call until post combine and
1413 ;; prior to register allocation. Clobber all hard registers that
1414 ;; might be used by the (widening) multiply until it is split and
1415 ;; it's final register footprint is worked out.
1417 (define_expand "mulsi3"
1418 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1419 (mult:SI (match_operand:SI 1 "register_operand" "")
1420 (match_operand:SI 2 "nonmemory_operand" "")))
1421 (clobber (reg:HI 26))
1422 (clobber (reg:DI 18))])]
1425 if (u16_operand (operands[2], SImode))
1427 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1428 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1432 if (o16_operand (operands[2], SImode))
1434 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1435 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1440 (define_insn_and_split "*mulsi3"
1441 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1442 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
1443 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1444 (clobber (reg:HI 26))
1445 (clobber (reg:DI 18))]
1446 "AVR_HAVE_MUL && !reload_completed"
1447 { gcc_unreachable(); }
1453 (parallel [(set (reg:SI 22)
1454 (mult:SI (reg:SI 22)
1456 (clobber (reg:HI 26))])
1460 if (u16_operand (operands[2], SImode))
1462 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1463 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1467 if (o16_operand (operands[2], SImode))
1469 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1470 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1477 (define_insn_and_split "mulu<mode>si3"
1478 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1479 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1480 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1481 (clobber (reg:HI 26))
1482 (clobber (reg:DI 18))]
1483 "AVR_HAVE_MUL && !reload_completed"
1484 { gcc_unreachable(); }
1491 (mult:SI (zero_extend:SI (reg:HI 26))
1496 /* Do the QI -> HI extension explicitely before the multiplication. */
1497 /* Do the HI -> SI extension implicitely and after the multiplication. */
1499 if (QImode == <MODE>mode)
1500 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
1502 if (u16_operand (operands[2], SImode))
1504 operands[1] = force_reg (HImode, operands[1]);
1505 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1506 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
1513 (define_insn_and_split "muls<mode>si3"
1514 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1515 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1516 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1517 (clobber (reg:HI 26))
1518 (clobber (reg:DI 18))]
1519 "AVR_HAVE_MUL && !reload_completed"
1520 { gcc_unreachable(); }
1527 (mult:SI (sign_extend:SI (reg:HI 26))
1532 /* Do the QI -> HI extension explicitely before the multiplication. */
1533 /* Do the HI -> SI extension implicitely and after the multiplication. */
1535 if (QImode == <MODE>mode)
1536 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
1538 if (u16_operand (operands[2], SImode)
1539 || s16_operand (operands[2], SImode))
1541 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1543 operands[1] = force_reg (HImode, operands[1]);
1545 if (u16_operand (operands[2], SImode))
1546 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
1548 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
1554 ;; One-extend operand 1
1556 (define_insn_and_split "mulohisi3"
1557 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1558 (mult:SI (not:SI (zero_extend:SI
1559 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
1560 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1561 (clobber (reg:HI 26))
1562 (clobber (reg:DI 18))]
1563 "AVR_HAVE_MUL && !reload_completed"
1564 { gcc_unreachable(); }
1571 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1579 (define_expand "<extend_u>mulhisi3"
1580 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1581 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
1582 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
1583 (clobber (reg:HI 26))
1584 (clobber (reg:DI 18))])]
1588 (define_expand "usmulhisi3"
1589 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1590 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1591 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1592 (clobber (reg:HI 26))
1593 (clobber (reg:DI 18))])]
1597 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
1598 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
1599 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
1600 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
1601 (define_insn_and_split
1602 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
1603 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1604 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1605 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
1606 (clobber (reg:HI 26))
1607 (clobber (reg:DI 18))]
1608 "AVR_HAVE_MUL && !reload_completed"
1609 { gcc_unreachable(); }
1616 (mult:SI (match_dup 3)
1621 rtx xop1 = operands[1];
1622 rtx xop2 = operands[2];
1624 /* Do the QI -> HI extension explicitely before the multiplication. */
1625 /* Do the HI -> SI extension implicitely and after the multiplication. */
1627 if (QImode == <QIHI:MODE>mode)
1628 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
1630 if (QImode == <QIHI2:MODE>mode)
1631 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
1633 if (<any_extend:CODE> == <any_extend2:CODE>
1634 || <any_extend:CODE> == ZERO_EXTEND)
1638 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
1639 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
1643 /* <any_extend:CODE> = SIGN_EXTEND */
1644 /* <any_extend2:CODE> = ZERO_EXTEND */
1648 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
1649 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
1653 ;; "smulhi3_highpart"
1654 ;; "umulhi3_highpart"
1655 (define_expand "<extend_su>mulhi3_highpart"
1657 (match_operand:HI 1 "nonmemory_operand" ""))
1659 (match_operand:HI 2 "nonmemory_operand" ""))
1660 (parallel [(set (reg:HI 24)
1661 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1662 (any_extend:SI (reg:HI 26)))
1664 (clobber (reg:HI 22))])
1665 (set (match_operand:HI 0 "register_operand" "")
1671 (define_insn "*mulsi3_call"
1673 (mult:SI (reg:SI 22)
1675 (clobber (reg:HI 26))]
1678 [(set_attr "type" "xcall")
1679 (set_attr "cc" "clobber")])
1682 ;; "*umulhisi3_call"
1683 (define_insn "*<extend_u>mulhisi3_call"
1685 (mult:SI (any_extend:SI (reg:HI 18))
1686 (any_extend:SI (reg:HI 26))))]
1688 "%~call __<extend_u>mulhisi3"
1689 [(set_attr "type" "xcall")
1690 (set_attr "cc" "clobber")])
1692 ;; "*umulhi3_highpart_call"
1693 ;; "*smulhi3_highpart_call"
1694 (define_insn "*<extend_su>mulhi3_highpart_call"
1696 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1697 (any_extend:SI (reg:HI 26)))
1699 (clobber (reg:HI 22))]
1701 "%~call __<extend_u>mulhisi3"
1702 [(set_attr "type" "xcall")
1703 (set_attr "cc" "clobber")])
1705 (define_insn "*usmulhisi3_call"
1707 (mult:SI (zero_extend:SI (reg:HI 18))
1708 (sign_extend:SI (reg:HI 26))))]
1710 "%~call __usmulhisi3"
1711 [(set_attr "type" "xcall")
1712 (set_attr "cc" "clobber")])
1714 (define_insn "*mul<extend_su>hisi3_call"
1716 (mult:SI (any_extend:SI (reg:HI 26))
1719 "%~call __mul<extend_su>hisi3"
1720 [(set_attr "type" "xcall")
1721 (set_attr "cc" "clobber")])
1723 (define_insn "*mulohisi3_call"
1725 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1728 "%~call __mulohisi3"
1729 [(set_attr "type" "xcall")
1730 (set_attr "cc" "clobber")])
1732 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1735 ;; Generate libgcc.S calls ourselves, because:
1736 ;; - we know exactly which registers are clobbered (for QI and HI
1737 ;; modes, some of the call-used registers are preserved)
1738 ;; - we get both the quotient and the remainder at no extra cost
1739 ;; - we split the patterns only after the first CSE passes because
1740 ;; CSE has problems to operate on hard regs.
1742 (define_insn_and_split "divmodqi4"
1743 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1744 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
1745 (match_operand:QI 2 "pseudo_register_operand" "")))
1746 (set (match_operand:QI 3 "pseudo_register_operand" "")
1747 (mod:QI (match_dup 1) (match_dup 2)))
1748 (clobber (reg:QI 22))
1749 (clobber (reg:QI 23))
1750 (clobber (reg:QI 24))
1751 (clobber (reg:QI 25))])]
1753 "this divmodqi4 pattern should have been splitted;"
1755 [(set (reg:QI 24) (match_dup 1))
1756 (set (reg:QI 22) (match_dup 2))
1757 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1758 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1759 (clobber (reg:QI 22))
1760 (clobber (reg:QI 23))])
1761 (set (match_dup 0) (reg:QI 24))
1762 (set (match_dup 3) (reg:QI 25))]
1765 (define_insn "*divmodqi4_call"
1766 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1767 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1768 (clobber (reg:QI 22))
1769 (clobber (reg:QI 23))]
1771 "%~call __divmodqi4"
1772 [(set_attr "type" "xcall")
1773 (set_attr "cc" "clobber")])
1775 (define_insn_and_split "udivmodqi4"
1776 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1777 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
1778 (match_operand:QI 2 "pseudo_register_operand" "")))
1779 (set (match_operand:QI 3 "pseudo_register_operand" "")
1780 (umod:QI (match_dup 1) (match_dup 2)))
1781 (clobber (reg:QI 22))
1782 (clobber (reg:QI 23))
1783 (clobber (reg:QI 24))
1784 (clobber (reg:QI 25))])]
1786 "this udivmodqi4 pattern should have been splitted;"
1788 [(set (reg:QI 24) (match_dup 1))
1789 (set (reg:QI 22) (match_dup 2))
1790 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1791 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1792 (clobber (reg:QI 23))])
1793 (set (match_dup 0) (reg:QI 24))
1794 (set (match_dup 3) (reg:QI 25))]
1797 (define_insn "*udivmodqi4_call"
1798 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1799 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1800 (clobber (reg:QI 23))]
1802 "%~call __udivmodqi4"
1803 [(set_attr "type" "xcall")
1804 (set_attr "cc" "clobber")])
1806 (define_insn_and_split "divmodhi4"
1807 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1808 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
1809 (match_operand:HI 2 "pseudo_register_operand" "")))
1810 (set (match_operand:HI 3 "pseudo_register_operand" "")
1811 (mod:HI (match_dup 1) (match_dup 2)))
1812 (clobber (reg:QI 21))
1813 (clobber (reg:HI 22))
1814 (clobber (reg:HI 24))
1815 (clobber (reg:HI 26))])]
1817 "this should have been splitted;"
1819 [(set (reg:HI 24) (match_dup 1))
1820 (set (reg:HI 22) (match_dup 2))
1821 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1822 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1823 (clobber (reg:HI 26))
1824 (clobber (reg:QI 21))])
1825 (set (match_dup 0) (reg:HI 22))
1826 (set (match_dup 3) (reg:HI 24))]
1829 (define_insn "*divmodhi4_call"
1830 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1831 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1832 (clobber (reg:HI 26))
1833 (clobber (reg:QI 21))]
1835 "%~call __divmodhi4"
1836 [(set_attr "type" "xcall")
1837 (set_attr "cc" "clobber")])
1839 (define_insn_and_split "udivmodhi4"
1840 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1841 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
1842 (match_operand:HI 2 "pseudo_register_operand" "")))
1843 (set (match_operand:HI 3 "pseudo_register_operand" "")
1844 (umod:HI (match_dup 1) (match_dup 2)))
1845 (clobber (reg:QI 21))
1846 (clobber (reg:HI 22))
1847 (clobber (reg:HI 24))
1848 (clobber (reg:HI 26))])]
1850 "this udivmodhi4 pattern should have been splitted.;"
1852 [(set (reg:HI 24) (match_dup 1))
1853 (set (reg:HI 22) (match_dup 2))
1854 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1855 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1856 (clobber (reg:HI 26))
1857 (clobber (reg:QI 21))])
1858 (set (match_dup 0) (reg:HI 22))
1859 (set (match_dup 3) (reg:HI 24))]
1862 (define_insn "*udivmodhi4_call"
1863 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1864 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1865 (clobber (reg:HI 26))
1866 (clobber (reg:QI 21))]
1868 "%~call __udivmodhi4"
1869 [(set_attr "type" "xcall")
1870 (set_attr "cc" "clobber")])
1872 (define_insn_and_split "divmodsi4"
1873 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1874 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
1875 (match_operand:SI 2 "pseudo_register_operand" "")))
1876 (set (match_operand:SI 3 "pseudo_register_operand" "")
1877 (mod:SI (match_dup 1) (match_dup 2)))
1878 (clobber (reg:SI 18))
1879 (clobber (reg:SI 22))
1880 (clobber (reg:HI 26))
1881 (clobber (reg:HI 30))])]
1883 "this divmodsi4 pattern should have been splitted;"
1885 [(set (reg:SI 22) (match_dup 1))
1886 (set (reg:SI 18) (match_dup 2))
1887 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1888 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1889 (clobber (reg:HI 26))
1890 (clobber (reg:HI 30))])
1891 (set (match_dup 0) (reg:SI 18))
1892 (set (match_dup 3) (reg:SI 22))]
1895 (define_insn "*divmodsi4_call"
1896 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1897 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1898 (clobber (reg:HI 26))
1899 (clobber (reg:HI 30))]
1901 "%~call __divmodsi4"
1902 [(set_attr "type" "xcall")
1903 (set_attr "cc" "clobber")])
1905 (define_insn_and_split "udivmodsi4"
1906 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1907 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
1908 (match_operand:SI 2 "pseudo_register_operand" "")))
1909 (set (match_operand:SI 3 "pseudo_register_operand" "")
1910 (umod:SI (match_dup 1) (match_dup 2)))
1911 (clobber (reg:SI 18))
1912 (clobber (reg:SI 22))
1913 (clobber (reg:HI 26))
1914 (clobber (reg:HI 30))])]
1916 "this udivmodsi4 pattern should have been splitted;"
1918 [(set (reg:SI 22) (match_dup 1))
1919 (set (reg:SI 18) (match_dup 2))
1920 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1921 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1922 (clobber (reg:HI 26))
1923 (clobber (reg:HI 30))])
1924 (set (match_dup 0) (reg:SI 18))
1925 (set (match_dup 3) (reg:SI 22))]
1928 (define_insn "*udivmodsi4_call"
1929 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1930 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1931 (clobber (reg:HI 26))
1932 (clobber (reg:HI 30))]
1934 "%~call __udivmodsi4"
1935 [(set_attr "type" "xcall")
1936 (set_attr "cc" "clobber")])
1938 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1941 (define_insn "andqi3"
1942 [(set (match_operand:QI 0 "register_operand" "=r,d")
1943 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1944 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1949 [(set_attr "length" "1,1")
1950 (set_attr "cc" "set_zn,set_zn")])
1952 (define_insn "andhi3"
1953 [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1954 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1955 (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1956 (clobber (match_scratch:QI 3 "=X,X,&d"))]
1959 if (which_alternative==0)
1960 return ("and %A0,%A2" CR_TAB
1962 else if (which_alternative==1)
1964 if (GET_CODE (operands[2]) == CONST_INT)
1966 int mask = INTVAL (operands[2]);
1967 if ((mask & 0xff) != 0xff)
1968 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1969 if ((mask & 0xff00) != 0xff00)
1970 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1973 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1974 AS2 (andi,%B0,hi8(%2)));
1976 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1980 [(set_attr "length" "2,2,3")
1981 (set_attr "cc" "set_n,clobber,set_n")])
1983 (define_insn "andsi3"
1984 [(set (match_operand:SI 0 "register_operand" "=r,d")
1985 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1986 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1989 if (which_alternative==0)
1990 return ("and %0,%2" CR_TAB
1991 "and %B0,%B2" CR_TAB
1992 "and %C0,%C2" CR_TAB
1994 else if (which_alternative==1)
1996 if (GET_CODE (operands[2]) == CONST_INT)
1998 HOST_WIDE_INT mask = INTVAL (operands[2]);
1999 if ((mask & 0xff) != 0xff)
2000 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
2001 if ((mask & 0xff00) != 0xff00)
2002 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
2003 if ((mask & 0xff0000L) != 0xff0000L)
2004 output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
2005 if ((mask & 0xff000000L) != 0xff000000L)
2006 output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
2009 return (AS2 (andi, %A0,lo8(%2)) CR_TAB
2010 AS2 (andi, %B0,hi8(%2)) CR_TAB
2011 AS2 (andi, %C0,hlo8(%2)) CR_TAB
2012 AS2 (andi, %D0,hhi8(%2)));
2016 [(set_attr "length" "4,4")
2017 (set_attr "cc" "set_n,clobber")])
2019 (define_peephole2 ; andi
2020 [(set (match_operand:QI 0 "d_register_operand" "")
2021 (and:QI (match_dup 0)
2022 (match_operand:QI 1 "const_int_operand" "")))
2024 (and:QI (match_dup 0)
2025 (match_operand:QI 2 "const_int_operand" "")))]
2027 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2029 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2032 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2035 (define_insn "iorqi3"
2036 [(set (match_operand:QI 0 "register_operand" "=r,d")
2037 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2038 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2043 [(set_attr "length" "1,1")
2044 (set_attr "cc" "set_zn,set_zn")])
2046 (define_insn "iorhi3"
2047 [(set (match_operand:HI 0 "register_operand" "=r,d")
2048 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2049 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
2052 if (which_alternative==0)
2053 return ("or %A0,%A2" CR_TAB
2055 if (GET_CODE (operands[2]) == CONST_INT)
2057 int mask = INTVAL (operands[2]);
2059 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2061 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2064 return (AS2 (ori,%0,lo8(%2)) CR_TAB
2065 AS2 (ori,%B0,hi8(%2)));
2067 [(set_attr "length" "2,2")
2068 (set_attr "cc" "set_n,clobber")])
2070 (define_insn "*iorhi3_clobber"
2071 [(set (match_operand:HI 0 "register_operand" "=r,r")
2072 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2073 (match_operand:HI 2 "immediate_operand" "M,i")))
2074 (clobber (match_scratch:QI 3 "=&d,&d"))]
2077 ldi %3,lo8(%2)\;or %A0,%3
2078 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
2079 [(set_attr "length" "2,4")
2080 (set_attr "cc" "clobber,set_n")])
2082 (define_insn "iorsi3"
2083 [(set (match_operand:SI 0 "register_operand" "=r,d")
2084 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2085 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
2088 if (which_alternative==0)
2089 return ("or %0,%2" CR_TAB
2093 if (GET_CODE (operands[2]) == CONST_INT)
2095 HOST_WIDE_INT mask = INTVAL (operands[2]);
2097 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2099 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2100 if (mask & 0xff0000L)
2101 output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
2102 if (mask & 0xff000000L)
2103 output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
2106 return (AS2 (ori, %A0,lo8(%2)) CR_TAB
2107 AS2 (ori, %B0,hi8(%2)) CR_TAB
2108 AS2 (ori, %C0,hlo8(%2)) CR_TAB
2109 AS2 (ori, %D0,hhi8(%2)));
2111 [(set_attr "length" "4,4")
2112 (set_attr "cc" "set_n,clobber")])
2114 (define_insn "*iorsi3_clobber"
2115 [(set (match_operand:SI 0 "register_operand" "=r,r")
2116 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2117 (match_operand:SI 2 "immediate_operand" "M,i")))
2118 (clobber (match_scratch:QI 3 "=&d,&d"))]
2121 ldi %3,lo8(%2)\;or %A0,%3
2122 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"
2123 [(set_attr "length" "2,8")
2124 (set_attr "cc" "clobber,set_n")])
2126 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2129 (define_insn "xorqi3"
2130 [(set (match_operand:QI 0 "register_operand" "=r")
2131 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2132 (match_operand:QI 2 "register_operand" "r")))]
2135 [(set_attr "length" "1")
2136 (set_attr "cc" "set_zn")])
2138 (define_insn "xorhi3"
2139 [(set (match_operand:HI 0 "register_operand" "=r")
2140 (xor:HI (match_operand:HI 1 "register_operand" "%0")
2141 (match_operand:HI 2 "register_operand" "r")))]
2145 [(set_attr "length" "2")
2146 (set_attr "cc" "set_n")])
2148 (define_insn "xorsi3"
2149 [(set (match_operand:SI 0 "register_operand" "=r")
2150 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2151 (match_operand:SI 2 "register_operand" "r")))]
2157 [(set_attr "length" "4")
2158 (set_attr "cc" "set_n")])
2160 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
2163 (define_expand "rotlqi3"
2164 [(set (match_operand:QI 0 "register_operand" "")
2165 (rotate:QI (match_operand:QI 1 "register_operand" "")
2166 (match_operand:QI 2 "const_int_operand" "")))]
2170 if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
2174 (define_insn "rotlqi3_4"
2175 [(set (match_operand:QI 0 "register_operand" "=r")
2176 (rotate:QI (match_operand:QI 1 "register_operand" "0")
2180 [(set_attr "length" "1")
2181 (set_attr "cc" "none")])
2183 ;; Split all rotates of HI,SI and DImode registers where rotation is by
2184 ;; a whole number of bytes. The split creates the appropriate moves and
2185 ;; considers all overlap situations. DImode is split before reload.
2187 ;; HImode does not need scratch. Use attribute for this constraint.
2188 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
2190 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
2191 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
2193 (define_expand "rotl<mode>3"
2194 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
2195 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2196 (match_operand:VOID 2 "const_int_operand" "")))
2197 (clobber (match_dup 3))])]
2200 if (CONST_INT_P (operands[2])
2201 && 0 == INTVAL (operands[2]) % 8)
2203 if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
2204 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2206 operands[3] = gen_rtx_SCRATCH (QImode);
2213 ;; Overlapping non-HImode registers often (but not always) need a scratch.
2214 ;; The best we can do is use early clobber alternative "#&r" so that
2215 ;; completely non-overlapping operands dont get a scratch but # so register
2216 ;; allocation does not prefer non-overlapping.
2219 ; Split word aligned rotates using scratch that is mode dependent.
2220 (define_insn_and_split "*rotw<mode>"
2221 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2222 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2223 (match_operand 2 "const_int_operand" "n,n,n")))
2224 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2226 && CONST_INT_P (operands[2])
2227 && 0 == INTVAL (operands[2]) % 16"
2229 "&& (reload_completed || <MODE>mode == DImode)"
2232 avr_rotate_bytes (operands);
2237 ; Split byte aligned rotates using scratch that is always QI mode.
2238 (define_insn_and_split "*rotb<mode>"
2239 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2240 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2241 (match_operand 2 "const_int_operand" "n,n,n")))
2242 (clobber (match_scratch:QI 3 "=<rotx>"))]
2243 "CONST_INT_P (operands[2])
2244 && (8 == INTVAL (operands[2]) % 16
2246 && 0 == INTVAL (operands[2]) % 16))"
2248 "&& (reload_completed || <MODE>mode == DImode)"
2251 avr_rotate_bytes (operands);
2256 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2257 ;; arithmetic shift left
2259 (define_expand "ashlqi3"
2260 [(set (match_operand:QI 0 "register_operand" "")
2261 (ashift:QI (match_operand:QI 1 "register_operand" "")
2262 (match_operand:QI 2 "general_operand" "")))]
2266 (define_split ; ashlqi3_const4
2267 [(set (match_operand:QI 0 "d_register_operand" "")
2268 (ashift:QI (match_dup 0)
2271 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2272 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2275 (define_split ; ashlqi3_const5
2276 [(set (match_operand:QI 0 "d_register_operand" "")
2277 (ashift:QI (match_dup 0)
2280 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2281 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2282 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2285 (define_split ; ashlqi3_const6
2286 [(set (match_operand:QI 0 "d_register_operand" "")
2287 (ashift:QI (match_dup 0)
2290 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2291 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2292 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2295 (define_insn "*ashlqi3"
2296 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2297 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2298 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2300 "* return ashlqi3_out (insn, operands, NULL);"
2301 [(set_attr "length" "5,0,1,2,4,6,9")
2302 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2304 (define_insn "ashlhi3"
2305 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2306 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2307 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2309 "* return ashlhi3_out (insn, operands, NULL);"
2310 [(set_attr "length" "6,0,2,2,4,10,10")
2311 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2314 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
2315 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
2319 (define_insn_and_split "*ashl<extend_su>qihiqi3"
2320 [(set (match_operand:QI 0 "register_operand" "=r")
2321 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
2322 (match_operand:QI 2 "register_operand" "r"))
2328 (ashift:QI (match_dup 1)
2332 ;; ??? Combiner does not recognize that it could split the following insn;
2333 ;; presumably because he has no register handy?
2335 ;; "*ashluqihiqi3.mem"
2336 ;; "*ashlsqihiqi3.mem"
2337 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
2338 [(set (match_operand:QI 0 "memory_operand" "=m")
2339 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
2340 (match_operand:QI 2 "register_operand" "r"))
2343 { gcc_unreachable(); }
2346 (ashift:QI (match_dup 1)
2351 operands[3] = gen_reg_rtx (QImode);
2356 (define_insn_and_split "*ashlhiqi3"
2357 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
2358 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
2359 (match_operand:QI 2 "register_operand" "r")) 0))]
2361 { gcc_unreachable(); }
2364 (ashift:QI (match_dup 3)
2369 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
2370 operands[4] = gen_reg_rtx (QImode);
2373 ;; High part of 16-bit shift is unused after the instruction:
2374 ;; No need to compute it, map to 8-bit shift.
2377 [(set (match_operand:HI 0 "register_operand" "")
2378 (ashift:HI (match_dup 0)
2379 (match_operand:QI 1 "register_operand" "")))]
2382 (ashift:QI (match_dup 2)
2384 (clobber (match_dup 3))]
2386 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
2388 if (!peep2_reg_dead_p (1, operands[3]))
2391 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
2395 (define_insn "ashlsi3"
2396 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2397 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2398 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2400 "* return ashlsi3_out (insn, operands, NULL);"
2401 [(set_attr "length" "8,0,4,4,8,10,12")
2402 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2404 ;; Optimize if a scratch register from LD_REGS happens to be available.
2406 (define_peephole2 ; ashlqi3_l_const4
2407 [(set (match_operand:QI 0 "l_register_operand" "")
2408 (ashift:QI (match_dup 0)
2410 (match_scratch:QI 1 "d")]
2412 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2413 (set (match_dup 1) (const_int -16))
2414 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2417 (define_peephole2 ; ashlqi3_l_const5
2418 [(set (match_operand:QI 0 "l_register_operand" "")
2419 (ashift:QI (match_dup 0)
2421 (match_scratch:QI 1 "d")]
2423 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2424 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2425 (set (match_dup 1) (const_int -32))
2426 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2429 (define_peephole2 ; ashlqi3_l_const6
2430 [(set (match_operand:QI 0 "l_register_operand" "")
2431 (ashift:QI (match_dup 0)
2433 (match_scratch:QI 1 "d")]
2435 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2436 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2437 (set (match_dup 1) (const_int -64))
2438 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2442 [(match_scratch:QI 3 "d")
2443 (set (match_operand:HI 0 "register_operand" "")
2444 (ashift:HI (match_operand:HI 1 "register_operand" "")
2445 (match_operand:QI 2 "const_int_operand" "")))]
2447 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
2448 (clobber (match_dup 3))])]
2451 (define_insn "*ashlhi3_const"
2452 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2453 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2454 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2455 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2457 "* return ashlhi3_out (insn, operands, NULL);"
2458 [(set_attr "length" "0,2,2,4,10")
2459 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
2462 [(match_scratch:QI 3 "d")
2463 (set (match_operand:SI 0 "register_operand" "")
2464 (ashift:SI (match_operand:SI 1 "register_operand" "")
2465 (match_operand:QI 2 "const_int_operand" "")))]
2467 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2468 (clobber (match_dup 3))])]
2471 (define_insn "*ashlsi3_const"
2472 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2473 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2474 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2475 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2477 "* return ashlsi3_out (insn, operands, NULL);"
2478 [(set_attr "length" "0,4,4,10")
2479 (set_attr "cc" "none,set_n,clobber,clobber")])
2481 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2482 ;; arithmetic shift right
2484 (define_insn "ashrqi3"
2485 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
2486 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
2487 (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))]
2489 "* return ashrqi3_out (insn, operands, NULL);"
2490 [(set_attr "length" "5,0,1,2,5,9")
2491 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
2493 (define_insn "ashrhi3"
2494 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2495 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2496 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2498 "* return ashrhi3_out (insn, operands, NULL);"
2499 [(set_attr "length" "6,0,2,4,4,10,10")
2500 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2502 (define_insn "ashrsi3"
2503 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2504 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2505 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2507 "* return ashrsi3_out (insn, operands, NULL);"
2508 [(set_attr "length" "8,0,4,6,8,10,12")
2509 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2511 ;; Optimize if a scratch register from LD_REGS happens to be available.
2514 [(match_scratch:QI 3 "d")
2515 (set (match_operand:HI 0 "register_operand" "")
2516 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2517 (match_operand:QI 2 "const_int_operand" "")))]
2519 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
2520 (clobber (match_dup 3))])]
2523 (define_insn "*ashrhi3_const"
2524 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2525 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2526 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2527 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2529 "* return ashrhi3_out (insn, operands, NULL);"
2530 [(set_attr "length" "0,2,4,4,10")
2531 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
2534 [(match_scratch:QI 3 "d")
2535 (set (match_operand:SI 0 "register_operand" "")
2536 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2537 (match_operand:QI 2 "const_int_operand" "")))]
2539 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2540 (clobber (match_dup 3))])]
2543 (define_insn "*ashrsi3_const"
2544 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2545 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2546 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2547 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2549 "* return ashrsi3_out (insn, operands, NULL);"
2550 [(set_attr "length" "0,4,4,10")
2551 (set_attr "cc" "none,clobber,set_n,clobber")])
2553 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2554 ;; logical shift right
2556 (define_expand "lshrqi3"
2557 [(set (match_operand:QI 0 "register_operand" "")
2558 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2559 (match_operand:QI 2 "general_operand" "")))]
2563 (define_split ; lshrqi3_const4
2564 [(set (match_operand:QI 0 "d_register_operand" "")
2565 (lshiftrt:QI (match_dup 0)
2568 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2569 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
2572 (define_split ; lshrqi3_const5
2573 [(set (match_operand:QI 0 "d_register_operand" "")
2574 (lshiftrt:QI (match_dup 0)
2577 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2578 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2579 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
2582 (define_split ; lshrqi3_const6
2583 [(set (match_operand:QI 0 "d_register_operand" "")
2584 (lshiftrt:QI (match_dup 0)
2587 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2588 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2589 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
2592 (define_insn "*lshrqi3"
2593 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2594 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2595 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2597 "* return lshrqi3_out (insn, operands, NULL);"
2598 [(set_attr "length" "5,0,1,2,4,6,9")
2599 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2601 (define_insn "lshrhi3"
2602 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2603 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2604 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2606 "* return lshrhi3_out (insn, operands, NULL);"
2607 [(set_attr "length" "6,0,2,2,4,10,10")
2608 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2610 (define_insn "lshrsi3"
2611 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2612 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2613 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2615 "* return lshrsi3_out (insn, operands, NULL);"
2616 [(set_attr "length" "8,0,4,4,8,10,12")
2617 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2619 ;; Optimize if a scratch register from LD_REGS happens to be available.
2621 (define_peephole2 ; lshrqi3_l_const4
2622 [(set (match_operand:QI 0 "l_register_operand" "")
2623 (lshiftrt:QI (match_dup 0)
2625 (match_scratch:QI 1 "d")]
2627 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2628 (set (match_dup 1) (const_int 15))
2629 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2632 (define_peephole2 ; lshrqi3_l_const5
2633 [(set (match_operand:QI 0 "l_register_operand" "")
2634 (lshiftrt:QI (match_dup 0)
2636 (match_scratch:QI 1 "d")]
2638 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2639 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2640 (set (match_dup 1) (const_int 7))
2641 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2644 (define_peephole2 ; lshrqi3_l_const6
2645 [(set (match_operand:QI 0 "l_register_operand" "")
2646 (lshiftrt:QI (match_dup 0)
2648 (match_scratch:QI 1 "d")]
2650 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2651 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2652 (set (match_dup 1) (const_int 3))
2653 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2657 [(match_scratch:QI 3 "d")
2658 (set (match_operand:HI 0 "register_operand" "")
2659 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2660 (match_operand:QI 2 "const_int_operand" "")))]
2662 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
2663 (clobber (match_dup 3))])]
2666 (define_insn "*lshrhi3_const"
2667 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2668 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2669 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2670 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2672 "* return lshrhi3_out (insn, operands, NULL);"
2673 [(set_attr "length" "0,2,2,4,10")
2674 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
2677 [(match_scratch:QI 3 "d")
2678 (set (match_operand:SI 0 "register_operand" "")
2679 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2680 (match_operand:QI 2 "const_int_operand" "")))]
2682 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2683 (clobber (match_dup 3))])]
2686 (define_insn "*lshrsi3_const"
2687 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2688 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2689 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2690 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2692 "* return lshrsi3_out (insn, operands, NULL);"
2693 [(set_attr "length" "0,4,4,10")
2694 (set_attr "cc" "none,clobber,clobber,clobber")])
2696 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2699 (define_insn "absqi2"
2700 [(set (match_operand:QI 0 "register_operand" "=r")
2701 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2705 [(set_attr "length" "2")
2706 (set_attr "cc" "clobber")])
2709 (define_insn "abssf2"
2710 [(set (match_operand:SF 0 "register_operand" "=d,r")
2711 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
2716 [(set_attr "length" "1,2")
2717 (set_attr "cc" "set_n,clobber")])
2719 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
2722 (define_insn "negqi2"
2723 [(set (match_operand:QI 0 "register_operand" "=r")
2724 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
2727 [(set_attr "length" "1")
2728 (set_attr "cc" "set_zn")])
2730 (define_insn "neghi2"
2731 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
2732 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
2735 com %B0\;neg %A0\;sbci %B0,lo8(-1)
2736 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
2737 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
2738 [(set_attr "length" "3,4,4")
2739 (set_attr "cc" "set_czn,set_n,set_czn")])
2741 (define_insn "negsi2"
2742 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
2743 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
2746 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
2747 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
2748 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
2749 [(set_attr_alternative "length"
2752 (if_then_else (eq_attr "mcu_have_movw" "yes")
2755 (set_attr "cc" "set_czn,set_n,set_czn")])
2757 (define_insn "negsf2"
2758 [(set (match_operand:SF 0 "register_operand" "=d,r")
2759 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
2763 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
2764 [(set_attr "length" "1,4")
2765 (set_attr "cc" "set_n,set_n")])
2767 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2770 (define_insn "one_cmplqi2"
2771 [(set (match_operand:QI 0 "register_operand" "=r")
2772 (not:QI (match_operand:QI 1 "register_operand" "0")))]
2775 [(set_attr "length" "1")
2776 (set_attr "cc" "set_czn")])
2778 (define_insn "one_cmplhi2"
2779 [(set (match_operand:HI 0 "register_operand" "=r")
2780 (not:HI (match_operand:HI 1 "register_operand" "0")))]
2784 [(set_attr "length" "2")
2785 (set_attr "cc" "set_n")])
2787 (define_insn "one_cmplsi2"
2788 [(set (match_operand:SI 0 "register_operand" "=r")
2789 (not:SI (match_operand:SI 1 "register_operand" "0")))]
2795 [(set_attr "length" "4")
2796 (set_attr "cc" "set_n")])
2798 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2801 ;; We keep combiner from inserting hard registers into the input of sign- and
2802 ;; zero-extends. A hard register in the input operand is not wanted because
2803 ;; 32-bit multiply patterns clobber some hard registers and extends with a
2804 ;; hard register that overlaps these clobbers won't be combined to a widening
2805 ;; multiplication. There is no need for combine to propagate hard registers,
2806 ;; register allocation can do it just as well.
2808 (define_insn "extendqihi2"
2809 [(set (match_operand:HI 0 "register_operand" "=r,r")
2810 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2813 clr %B0\;sbrc %0,7\;com %B0
2814 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
2815 [(set_attr "length" "3,4")
2816 (set_attr "cc" "set_n,set_n")])
2818 (define_insn "extendqisi2"
2819 [(set (match_operand:SI 0 "register_operand" "=r,r")
2820 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2823 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
2824 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
2825 [(set_attr "length" "5,6")
2826 (set_attr "cc" "set_n,set_n")])
2828 (define_insn "extendhisi2"
2829 [(set (match_operand:SI 0 "register_operand" "=r,r")
2830 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
2833 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
2834 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
2835 [(set_attr_alternative "length"
2837 (if_then_else (eq_attr "mcu_have_movw" "yes")
2840 (set_attr "cc" "set_n,set_n")])
2842 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2845 (define_insn_and_split "zero_extendqihi2"
2846 [(set (match_operand:HI 0 "register_operand" "=r")
2847 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2851 [(set (match_dup 2) (match_dup 1))
2852 (set (match_dup 3) (const_int 0))]
2854 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
2855 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
2857 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
2858 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
2861 (define_insn_and_split "zero_extendqisi2"
2862 [(set (match_operand:SI 0 "register_operand" "=r")
2863 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2867 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
2868 (set (match_dup 3) (const_int 0))]
2870 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2871 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2873 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2874 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2877 (define_insn_and_split "zero_extendhisi2"
2878 [(set (match_operand:SI 0 "register_operand" "=r")
2879 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
2883 [(set (match_dup 2) (match_dup 1))
2884 (set (match_dup 3) (const_int 0))]
2886 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2887 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2889 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2890 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2893 (define_insn_and_split "zero_extendqidi2"
2894 [(set (match_operand:DI 0 "register_operand" "=r")
2895 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2899 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2900 (set (match_dup 3) (const_int 0))]
2902 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2903 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2905 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2906 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2909 (define_insn_and_split "zero_extendhidi2"
2910 [(set (match_operand:DI 0 "register_operand" "=r")
2911 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2915 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2916 (set (match_dup 3) (const_int 0))]
2918 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2919 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2921 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2922 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2925 (define_insn_and_split "zero_extendsidi2"
2926 [(set (match_operand:DI 0 "register_operand" "=r")
2927 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2931 [(set (match_dup 2) (match_dup 1))
2932 (set (match_dup 3) (const_int 0))]
2934 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2935 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2937 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2938 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2941 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
2944 ; Optimize negated tests into reverse compare if overflow is undefined.
2945 (define_insn "*negated_tstqi"
2947 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
2949 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2950 "cp __zero_reg__,%0"
2951 [(set_attr "cc" "compare")
2952 (set_attr "length" "1")])
2954 (define_insn "*reversed_tstqi"
2956 (compare (const_int 0)
2957 (match_operand:QI 0 "register_operand" "r")))]
2959 "cp __zero_reg__,%0"
2960 [(set_attr "cc" "compare")
2961 (set_attr "length" "2")])
2963 (define_insn "*negated_tsthi"
2965 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
2967 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2968 "cp __zero_reg__,%A0
2969 cpc __zero_reg__,%B0"
2970 [(set_attr "cc" "compare")
2971 (set_attr "length" "2")])
2973 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
2974 ;; though it is unused, because this pattern is synthesized by avr_reorg.
2975 (define_insn "*reversed_tsthi"
2977 (compare (const_int 0)
2978 (match_operand:HI 0 "register_operand" "r")))
2979 (clobber (match_scratch:QI 1 "=X"))]
2981 "cp __zero_reg__,%A0
2982 cpc __zero_reg__,%B0"
2983 [(set_attr "cc" "compare")
2984 (set_attr "length" "2")])
2986 (define_insn "*negated_tstsi"
2988 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
2990 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2991 "cp __zero_reg__,%A0
2992 cpc __zero_reg__,%B0
2993 cpc __zero_reg__,%C0
2994 cpc __zero_reg__,%D0"
2995 [(set_attr "cc" "compare")
2996 (set_attr "length" "4")])
2998 (define_insn "*reversed_tstsi"
3000 (compare (const_int 0)
3001 (match_operand:SI 0 "register_operand" "r")))
3002 (clobber (match_scratch:QI 1 "=X"))]
3004 "cp __zero_reg__,%A0
3005 cpc __zero_reg__,%B0
3006 cpc __zero_reg__,%C0
3007 cpc __zero_reg__,%D0"
3008 [(set_attr "cc" "compare")
3009 (set_attr "length" "4")])
3012 (define_insn "*cmpqi"
3014 (compare (match_operand:QI 0 "register_operand" "r,r,d")
3015 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
3021 [(set_attr "cc" "compare,compare,compare")
3022 (set_attr "length" "1,1,1")])
3024 (define_insn "*cmpqi_sign_extend"
3026 (compare (sign_extend:HI
3027 (match_operand:QI 0 "register_operand" "d"))
3028 (match_operand:HI 1 "const_int_operand" "n")))]
3029 "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
3031 [(set_attr "cc" "compare")
3032 (set_attr "length" "1")])
3034 (define_insn "*cmphi"
3036 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d,d,r,r")
3037 (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
3038 (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
3041 switch (which_alternative)
3044 return out_tsthi (insn, operands[0], NULL);
3047 return (AS2 (cp,%A0,%A1) CR_TAB
3050 if (reg_unused_after (insn, operands[0])
3051 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
3052 && test_hard_reg_class (ADDW_REGS, operands[0]))
3053 return AS2 (sbiw,%0,%1);
3055 return (AS2 (cpi,%0,%1) CR_TAB
3056 AS2 (cpc,%B0,__zero_reg__));
3058 if (reg_unused_after (insn, operands[0]))
3059 return (AS2 (subi,%0,lo8(%1)) CR_TAB
3060 AS2 (sbci,%B0,hi8(%1)));
3062 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
3063 AS2 (cpi, %A0,lo8(%1)) CR_TAB
3066 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3067 AS2 (cp, %A0,%2) CR_TAB
3068 AS2 (cpc, %B0,__zero_reg__));
3071 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3072 AS2 (cp, %A0,%2) CR_TAB
3073 AS2 (ldi, %2,hi8(%1)) CR_TAB
3078 [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
3079 (set_attr "length" "1,2,2,2,3,3,4")])
3082 (define_insn "*cmpsi"
3084 (compare (match_operand:SI 0 "register_operand" "r,r,d,d,r,r")
3085 (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
3086 (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
3089 switch (which_alternative)
3092 return out_tstsi (insn, operands[0], NULL);
3095 return (AS2 (cp,%A0,%A1) CR_TAB
3096 AS2 (cpc,%B0,%B1) CR_TAB
3097 AS2 (cpc,%C0,%C1) CR_TAB
3100 if (reg_unused_after (insn, operands[0])
3101 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
3102 && test_hard_reg_class (ADDW_REGS, operands[0]))
3103 return (AS2 (sbiw,%0,%1) CR_TAB
3104 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3105 AS2 (cpc,%D0,__zero_reg__));
3107 return (AS2 (cpi,%A0,lo8(%1)) CR_TAB
3108 AS2 (cpc,%B0,__zero_reg__) CR_TAB
3109 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3110 AS2 (cpc,%D0,__zero_reg__));
3112 if (reg_unused_after (insn, operands[0]))
3113 return (AS2 (subi,%A0,lo8(%1)) CR_TAB
3114 AS2 (sbci,%B0,hi8(%1)) CR_TAB
3115 AS2 (sbci,%C0,hlo8(%1)) CR_TAB
3116 AS2 (sbci,%D0,hhi8(%1)));
3118 return (AS2 (cpi, %A0,lo8(%1)) CR_TAB
3119 AS2 (ldi, %2,hi8(%1)) CR_TAB
3120 AS2 (cpc, %B0,%2) CR_TAB
3121 AS2 (ldi, %2,hlo8(%1)) CR_TAB
3122 AS2 (cpc, %C0,%2) CR_TAB
3123 AS2 (ldi, %2,hhi8(%1)) CR_TAB
3126 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
3127 AS2 (cp,%A0,%2) CR_TAB
3128 AS2 (cpc,%B0,__zero_reg__) CR_TAB
3129 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3130 AS2 (cpc,%D0,__zero_reg__));
3132 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3133 AS2 (cp, %A0,%2) CR_TAB
3134 AS2 (ldi, %2,hi8(%1)) CR_TAB
3135 AS2 (cpc, %B0,%2) CR_TAB
3136 AS2 (ldi, %2,hlo8(%1)) CR_TAB
3137 AS2 (cpc, %C0,%2) CR_TAB
3138 AS2 (ldi, %2,hhi8(%1)) CR_TAB
3143 [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
3144 (set_attr "length" "4,4,4,7,5,8")])
3147 ;; ----------------------------------------------------------------------
3148 ;; JUMP INSTRUCTIONS
3149 ;; ----------------------------------------------------------------------
3150 ;; Conditional jump instructions
3152 (define_expand "cbranchsi4"
3153 [(parallel [(set (cc0)
3154 (compare (match_operand:SI 1 "register_operand" "")
3155 (match_operand:SI 2 "nonmemory_operand" "")))
3156 (clobber (match_scratch:QI 4 ""))])
3159 (match_operator 0 "ordered_comparison_operator" [(cc0)
3161 (label_ref (match_operand 3 "" ""))
3165 (define_expand "cbranchhi4"
3166 [(parallel [(set (cc0)
3167 (compare (match_operand:HI 1 "register_operand" "")
3168 (match_operand:HI 2 "nonmemory_operand" "")))
3169 (clobber (match_scratch:QI 4 ""))])
3172 (match_operator 0 "ordered_comparison_operator" [(cc0)
3174 (label_ref (match_operand 3 "" ""))
3178 (define_expand "cbranchqi4"
3180 (compare (match_operand:QI 1 "register_operand" "")
3181 (match_operand:QI 2 "nonmemory_operand" "")))
3184 (match_operator 0 "ordered_comparison_operator" [(cc0)
3186 (label_ref (match_operand 3 "" ""))
3191 ;; Test a single bit in a QI/HI/SImode register.
3192 ;; Combine will create zero extract patterns for single bit tests.
3193 ;; permit any mode in source pattern by using VOIDmode.
3195 (define_insn "*sbrx_branch<mode>"
3198 (match_operator 0 "eqne_operator"
3200 (match_operand:VOID 1 "register_operand" "r")
3202 (match_operand 2 "const_int_operand" "n"))
3204 (label_ref (match_operand 3 "" ""))
3207 "* return avr_out_sbxx_branch (insn, operands);"
3208 [(set (attr "length")
3209 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3210 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3212 (if_then_else (eq_attr "mcu_mega" "no")
3215 (set_attr "cc" "clobber")])
3217 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
3218 ;; or for old peepholes.
3219 ;; Fixme - bitwise Mask will not work for DImode
3221 (define_insn "*sbrx_and_branch<mode>"
3224 (match_operator 0 "eqne_operator"
3226 (match_operand:QISI 1 "register_operand" "r")
3227 (match_operand:QISI 2 "single_one_operand" "n"))
3229 (label_ref (match_operand 3 "" ""))
3233 HOST_WIDE_INT bitnumber;
3234 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
3235 operands[2] = GEN_INT (bitnumber);
3236 return avr_out_sbxx_branch (insn, operands);
3238 [(set (attr "length")
3239 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3240 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3242 (if_then_else (eq_attr "mcu_mega" "no")
3245 (set_attr "cc" "clobber")])
3247 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
3249 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3251 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3252 (label_ref (match_operand 1 "" ""))
3255 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
3259 (label_ref (match_dup 1))
3264 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3266 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3267 (label_ref (match_operand 1 "" ""))
3270 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
3274 (label_ref (match_dup 1))
3279 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3281 (clobber (match_operand:HI 2 ""))])
3282 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3283 (label_ref (match_operand 1 "" ""))
3286 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
3288 (label_ref (match_dup 1))
3293 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3295 (clobber (match_operand:HI 2 ""))])
3296 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3297 (label_ref (match_operand 1 "" ""))
3300 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
3302 (label_ref (match_dup 1))
3307 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3309 (clobber (match_operand:SI 2 ""))])
3310 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3311 (label_ref (match_operand 1 "" ""))
3314 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
3316 (label_ref (match_dup 1))
3318 "operands[2] = GEN_INT (-2147483647 - 1);")
3321 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3323 (clobber (match_operand:SI 2 ""))])
3324 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3325 (label_ref (match_operand 1 "" ""))
3328 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
3330 (label_ref (match_dup 1))
3332 "operands[2] = GEN_INT (-2147483647 - 1);")
3334 ;; ************************************************************************
3335 ;; Implementation of conditional jumps here.
3336 ;; Compare with 0 (test) jumps
3337 ;; ************************************************************************
3339 (define_insn "branch"
3341 (if_then_else (match_operator 1 "simple_comparison_operator"
3344 (label_ref (match_operand 0 "" ""))
3348 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3349 [(set_attr "type" "branch")
3350 (set_attr "cc" "clobber")])
3352 ;; ****************************************************************
3353 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
3354 ;; Convert them all to proper jumps.
3355 ;; ****************************************************************/
3357 (define_insn "difficult_branch"
3359 (if_then_else (match_operator 1 "difficult_comparison_operator"
3362 (label_ref (match_operand 0 "" ""))
3366 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3367 [(set_attr "type" "branch1")
3368 (set_attr "cc" "clobber")])
3372 (define_insn "rvbranch"
3374 (if_then_else (match_operator 1 "simple_comparison_operator"
3378 (label_ref (match_operand 0 "" ""))))]
3381 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3382 [(set_attr "type" "branch1")
3383 (set_attr "cc" "clobber")])
3385 (define_insn "difficult_rvbranch"
3387 (if_then_else (match_operator 1 "difficult_comparison_operator"
3391 (label_ref (match_operand 0 "" ""))))]
3394 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3395 [(set_attr "type" "branch")
3396 (set_attr "cc" "clobber")])
3398 ;; **************************************************************************
3399 ;; Unconditional and other jump instructions.
3403 (label_ref (match_operand 0 "" "")))]
3406 if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
3407 return AS1 (jmp,%x0);
3408 return AS1 (rjmp,%x0);
3410 [(set (attr "length")
3411 (if_then_else (match_operand 0 "symbol_ref_operand" "")
3412 (if_then_else (eq_attr "mcu_mega" "no")
3415 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
3416 (le (minus (pc) (match_dup 0)) (const_int 2047)))
3419 (set_attr "cc" "none")])
3423 (define_expand "call"
3424 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3425 (match_operand:HI 1 "general_operand" ""))
3426 (use (const_int 0))])]
3427 ;; Operand 1 not used on the AVR.
3428 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3432 (define_expand "sibcall"
3433 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3434 (match_operand:HI 1 "general_operand" ""))
3435 (use (const_int 1))])]
3436 ;; Operand 1 not used on the AVR.
3437 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3443 (define_expand "call_value"
3444 [(parallel[(set (match_operand 0 "register_operand" "")
3445 (call (match_operand:HI 1 "call_insn_operand" "")
3446 (match_operand:HI 2 "general_operand" "")))
3447 (use (const_int 0))])]
3448 ;; Operand 2 not used on the AVR.
3449 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3453 (define_expand "sibcall_value"
3454 [(parallel[(set (match_operand 0 "register_operand" "")
3455 (call (match_operand:HI 1 "call_insn_operand" "")
3456 (match_operand:HI 2 "general_operand" "")))
3457 (use (const_int 1))])]
3458 ;; Operand 2 not used on the AVR.
3459 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3463 (define_insn "*call_insn"
3464 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
3465 (match_operand:HI 1 "general_operand" "X,X,X,X"))
3466 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
3467 ;; Operand 1 not used on the AVR.
3468 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3475 [(set_attr "cc" "clobber")
3476 (set_attr_alternative "length"
3478 (if_then_else (eq_attr "mcu_mega" "yes")
3482 (if_then_else (eq_attr "mcu_mega" "yes")
3486 (define_insn "*call_value_insn"
3487 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
3488 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
3489 (match_operand:HI 2 "general_operand" "X,X,X,X")))
3490 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
3491 ;; Operand 2 not used on the AVR.
3492 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3499 [(set_attr "cc" "clobber")
3500 (set_attr_alternative "length"
3502 (if_then_else (eq_attr "mcu_mega" "yes")
3506 (if_then_else (eq_attr "mcu_mega" "yes")
3514 [(set_attr "cc" "none")
3515 (set_attr "length" "1")])
3519 (define_expand "indirect_jump"
3520 [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
3522 " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
3524 operands[0] = copy_to_mode_reg(HImode, operand0);
3529 (define_insn "*jcindirect_jump"
3530 [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
3533 [(set_attr "length" "2")
3534 (set_attr "cc" "none")])
3537 (define_insn "*njcindirect_jump"
3538 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
3539 "!AVR_HAVE_EIJMP_EICALL"
3542 push %A0\;push %B0\;ret"
3543 [(set_attr "length" "1,3")
3544 (set_attr "cc" "none,none")])
3546 (define_insn "*indirect_jump_avr6"
3547 [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
3548 "AVR_HAVE_EIJMP_EICALL"
3550 [(set_attr "length" "1")
3551 (set_attr "cc" "none")])
3555 ;; Table made from "rjmp" instructions for <=8K devices.
3556 (define_insn "*tablejump_rjmp"
3557 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
3559 (use (label_ref (match_operand 1 "" "")))
3560 (clobber (match_dup 0))]
3561 "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
3564 push %A0\;push %B0\;ret"
3565 [(set_attr "length" "1,3")
3566 (set_attr "cc" "none,none")])
3568 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
3569 (define_insn "*tablejump_lib"
3570 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3572 (use (label_ref (match_operand 1 "" "")))
3573 (clobber (match_dup 0))]
3574 "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
3575 "%~jmp __tablejump2__"
3576 [(set_attr "length" "2")
3577 (set_attr "cc" "clobber")])
3579 (define_insn "*tablejump_enh"
3580 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3582 (use (label_ref (match_operand 1 "" "")))
3583 (clobber (match_dup 0))]
3584 "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
3591 [(set_attr "length" "6")
3592 (set_attr "cc" "clobber")])
3594 (define_insn "*tablejump"
3595 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3597 (use (label_ref (match_operand 1 "" "")))
3598 (clobber (match_dup 0))]
3599 "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
3608 [(set_attr "length" "8")
3609 (set_attr "cc" "clobber")])
3611 (define_expand "casesi"
3613 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
3614 (match_operand:HI 1 "register_operand" "")))
3615 (parallel [(set (cc0)
3616 (compare (match_dup 6)
3617 (match_operand:HI 2 "register_operand" "")))
3618 (clobber (match_scratch:QI 9 ""))])
3621 (if_then_else (gtu (cc0)
3623 (label_ref (match_operand 4 "" ""))
3627 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
3629 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
3630 (use (label_ref (match_dup 3)))
3631 (clobber (match_dup 6))])]
3635 operands[6] = gen_reg_rtx (HImode);
3639 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3640 ;; This instruction sets Z flag
3643 [(set (cc0) (const_int 0))]
3646 [(set_attr "length" "1")
3647 (set_attr "cc" "compare")])
3649 ;; Clear/set/test a single bit in I/O address space.
3652 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3653 (and:QI (mem:QI (match_dup 0))
3654 (match_operand:QI 1 "single_zero_operand" "n")))]
3657 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
3658 return AS2 (cbi,%m0-0x20,%2);
3660 [(set_attr "length" "1")
3661 (set_attr "cc" "none")])
3664 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3665 (ior:QI (mem:QI (match_dup 0))
3666 (match_operand:QI 1 "single_one_operand" "n")))]
3669 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
3670 return AS2 (sbi,%m0-0x20,%2);
3672 [(set_attr "length" "1")
3673 (set_attr "cc" "none")])
3675 ;; Lower half of the I/O space - use sbic/sbis directly.
3676 (define_insn "*sbix_branch"
3679 (match_operator 0 "eqne_operator"
3681 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
3683 (match_operand 2 "const_int_operand" "n"))
3685 (label_ref (match_operand 3 "" ""))
3688 "* return avr_out_sbxx_branch (insn, operands);"
3689 [(set (attr "length")
3690 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3691 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3693 (if_then_else (eq_attr "mcu_mega" "no")
3696 (set_attr "cc" "clobber")])
3698 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
3699 (define_insn "*sbix_branch_bit7"
3702 (match_operator 0 "gelt_operator"
3703 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
3705 (label_ref (match_operand 2 "" ""))
3709 operands[3] = operands[2];
3710 operands[2] = GEN_INT (7);
3711 return avr_out_sbxx_branch (insn, operands);
3713 [(set (attr "length")
3714 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3715 (le (minus (pc) (match_dup 2)) (const_int 2046)))
3717 (if_then_else (eq_attr "mcu_mega" "no")
3720 (set_attr "cc" "clobber")])
3722 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
3723 (define_insn "*sbix_branch_tmp"
3726 (match_operator 0 "eqne_operator"
3728 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
3730 (match_operand 2 "const_int_operand" "n"))
3732 (label_ref (match_operand 3 "" ""))
3735 "* return avr_out_sbxx_branch (insn, operands);"
3736 [(set (attr "length")
3737 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3738 (le (minus (pc) (match_dup 3)) (const_int 2045)))
3740 (if_then_else (eq_attr "mcu_mega" "no")
3743 (set_attr "cc" "clobber")])
3745 (define_insn "*sbix_branch_tmp_bit7"
3748 (match_operator 0 "gelt_operator"
3749 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
3751 (label_ref (match_operand 2 "" ""))
3755 operands[3] = operands[2];
3756 operands[2] = GEN_INT (7);
3757 return avr_out_sbxx_branch (insn, operands);
3759 [(set (attr "length")
3760 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3761 (le (minus (pc) (match_dup 2)) (const_int 2045)))
3763 (if_then_else (eq_attr "mcu_mega" "no")
3766 (set_attr "cc" "clobber")])
3768 ;; ************************* Peepholes ********************************
3771 [(set (match_operand:SI 0 "d_register_operand" "")
3772 (plus:SI (match_dup 0)
3776 (compare (match_dup 0)
3778 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3780 (if_then_else (ne (cc0) (const_int 0))
3781 (label_ref (match_operand 2 "" ""))
3787 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3788 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3789 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3790 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3792 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3793 AS2 (sbc,%B0,__zero_reg__) CR_TAB
3794 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3795 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3796 switch (avr_jump_mode (operands[2],insn))
3799 return AS1 (brcc,%2);
3801 return (AS1 (brcs,.+2) CR_TAB
3804 return (AS1 (brcs,.+4) CR_TAB
3809 [(set (match_operand:HI 0 "d_register_operand" "")
3810 (plus:HI (match_dup 0)
3814 (compare (match_dup 0)
3816 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3818 (if_then_else (ne (cc0) (const_int 0))
3819 (label_ref (match_operand 2 "" ""))
3825 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3826 output_asm_insn (AS2 (sbiw,%0,1), operands);
3828 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3829 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3830 switch (avr_jump_mode (operands[2],insn))
3833 return AS1 (brcc,%2);
3835 return (AS1 (brcs,.+2) CR_TAB
3838 return (AS1 (brcs,.+4) CR_TAB
3843 [(set (match_operand:QI 0 "d_register_operand" "")
3844 (plus:QI (match_dup 0)
3847 (compare (match_dup 0)
3850 (if_then_else (ne (cc0) (const_int 0))
3851 (label_ref (match_operand 1 "" ""))
3857 cc_status.value1 = operands[0];
3858 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
3859 output_asm_insn (AS2 (subi,%A0,1), operands);
3860 switch (avr_jump_mode (operands[1],insn))
3863 return AS1 (brcc,%1);
3865 return (AS1 (brcs,.+2) CR_TAB
3868 return (AS1 (brcs,.+4) CR_TAB
3874 (compare (match_operand:QI 0 "register_operand" "")
3877 (if_then_else (eq (cc0) (const_int 0))
3878 (label_ref (match_operand 1 "" ""))
3880 "jump_over_one_insn_p (insn, operands[1])"
3881 "cpse %0,__zero_reg__")
3885 (compare (match_operand:QI 0 "register_operand" "")
3886 (match_operand:QI 1 "register_operand" "")))
3888 (if_then_else (eq (cc0) (const_int 0))
3889 (label_ref (match_operand 2 "" ""))
3891 "jump_over_one_insn_p (insn, operands[2])"
3894 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
3895 ;;prologue/epilogue support instructions
3897 (define_insn "popqi"
3898 [(set (match_operand:QI 0 "register_operand" "=r")
3899 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
3902 [(set_attr "cc" "none")
3903 (set_attr "length" "1")])
3905 ;; Enable Interrupts
3906 (define_insn "enable_interrupt"
3907 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
3910 [(set_attr "length" "1")
3911 (set_attr "cc" "none")])
3913 ;; Disable Interrupts
3914 (define_insn "disable_interrupt"
3915 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
3918 [(set_attr "length" "1")
3919 (set_attr "cc" "none")])
3921 ;; Library prologue saves
3922 (define_insn "call_prologue_saves"
3923 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
3924 (match_operand:HI 0 "immediate_operand" "")
3925 (set (reg:HI REG_SP) (minus:HI
3927 (match_operand:HI 1 "immediate_operand" "")))
3928 (use (reg:HI REG_X))
3929 (clobber (reg:HI REG_Z))]
3931 "ldi r30,lo8(gs(1f))
3933 %~jmp __prologue_saves__+((18 - %0) * 2)
3935 [(set_attr_alternative "length"
3936 [(if_then_else (eq_attr "mcu_mega" "yes")
3939 (set_attr "cc" "clobber")
3942 ; epilogue restores using library
3943 (define_insn "epilogue_restores"
3944 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
3945 (set (reg:HI REG_Y ) (plus:HI
3947 (match_operand:HI 0 "immediate_operand" "")))
3948 (set (reg:HI REG_SP) (reg:HI REG_Y))
3949 (clobber (reg:QI REG_Z))]
3952 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
3953 [(set_attr_alternative "length"
3954 [(if_then_else (eq_attr "mcu_mega" "yes")
3957 (set_attr "cc" "clobber")
3961 (define_insn "return"
3963 "reload_completed && avr_simple_epilogue ()"
3965 [(set_attr "cc" "none")
3966 (set_attr "length" "1")])
3968 (define_insn "return_from_epilogue"
3972 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
3973 && !cfun->machine->is_naked)"
3975 [(set_attr "cc" "none")
3976 (set_attr "length" "1")])
3978 (define_insn "return_from_interrupt_epilogue"
3982 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
3983 && !cfun->machine->is_naked)"
3985 [(set_attr "cc" "none")
3986 (set_attr "length" "1")])
3988 (define_insn "return_from_naked_epilogue"
3992 && cfun->machine->is_naked)"
3994 [(set_attr "cc" "none")
3995 (set_attr "length" "0")])
3997 (define_expand "prologue"
4006 (define_expand "epilogue"
4010 expand_epilogue (false /* sibcall_p */);
4014 (define_expand "sibcall_epilogue"
4018 expand_epilogue (true /* sibcall_p */);
4022 ;; Some instructions resp. instruction sequences available
4025 (define_insn "delay_cycles_1"
4026 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
4028 UNSPECV_DELAY_CYCLES)
4029 (clobber (match_scratch:QI 1 "=&d"))]
4034 [(set_attr "length" "3")
4035 (set_attr "cc" "clobber")])
4037 (define_insn "delay_cycles_2"
4038 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
4040 UNSPECV_DELAY_CYCLES)
4041 (clobber (match_scratch:HI 1 "=&w"))]
4047 [(set_attr "length" "4")
4048 (set_attr "cc" "clobber")])
4050 (define_insn "delay_cycles_3"
4051 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4053 UNSPECV_DELAY_CYCLES)
4054 (clobber (match_scratch:QI 1 "=&d"))
4055 (clobber (match_scratch:QI 2 "=&d"))
4056 (clobber (match_scratch:QI 3 "=&d"))]
4065 [(set_attr "length" "7")
4066 (set_attr "cc" "clobber")])
4068 (define_insn "delay_cycles_4"
4069 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4071 UNSPECV_DELAY_CYCLES)
4072 (clobber (match_scratch:QI 1 "=&d"))
4073 (clobber (match_scratch:QI 2 "=&d"))
4074 (clobber (match_scratch:QI 3 "=&d"))
4075 (clobber (match_scratch:QI 4 "=&d"))]
4086 [(set_attr "length" "9")
4087 (set_attr "cc" "clobber")])
4092 (define_expand "parityhi2"
4094 (match_operand:HI 1 "register_operand" ""))
4096 (parity:HI (reg:HI 24)))
4097 (set (match_operand:HI 0 "register_operand" "")
4102 (define_expand "paritysi2"
4104 (match_operand:SI 1 "register_operand" ""))
4106 (parity:HI (reg:SI 22)))
4109 (set (match_operand:SI 0 "register_operand" "")
4110 (zero_extend:SI (match_dup 2)))]
4113 operands[2] = gen_reg_rtx (HImode);
4116 (define_insn "*parityhi2.libgcc"
4118 (parity:HI (reg:HI 24)))]
4120 "%~call __parityhi2"
4121 [(set_attr "type" "xcall")
4122 (set_attr "cc" "clobber")])
4124 (define_insn "*parityqihi2.libgcc"
4126 (parity:HI (reg:QI 24)))]
4128 "%~call __parityqi2"
4129 [(set_attr "type" "xcall")
4130 (set_attr "cc" "clobber")])
4132 (define_insn "*paritysihi2.libgcc"
4134 (parity:HI (reg:SI 22)))]
4136 "%~call __paritysi2"
4137 [(set_attr "type" "xcall")
4138 (set_attr "cc" "clobber")])
4143 (define_expand "popcounthi2"
4145 (match_operand:HI 1 "register_operand" ""))
4147 (popcount:HI (reg:HI 24)))
4148 (set (match_operand:HI 0 "register_operand" "")
4153 (define_expand "popcountsi2"
4155 (match_operand:SI 1 "register_operand" ""))
4157 (popcount:HI (reg:SI 22)))
4160 (set (match_operand:SI 0 "register_operand" "")
4161 (zero_extend:SI (match_dup 2)))]
4164 operands[2] = gen_reg_rtx (HImode);
4167 (define_insn "*popcounthi2.libgcc"
4169 (popcount:HI (reg:HI 24)))]
4171 "%~call __popcounthi2"
4172 [(set_attr "type" "xcall")
4173 (set_attr "cc" "clobber")])
4175 (define_insn "*popcountsi2.libgcc"
4177 (popcount:HI (reg:SI 22)))]
4179 "%~call __popcountsi2"
4180 [(set_attr "type" "xcall")
4181 (set_attr "cc" "clobber")])
4183 (define_insn "*popcountqi2.libgcc"
4185 (popcount:QI (reg:QI 24)))]
4187 "%~call __popcountqi2"
4188 [(set_attr "type" "xcall")
4189 (set_attr "cc" "clobber")])
4191 (define_insn_and_split "*popcountqihi2.libgcc"
4193 (popcount:HI (reg:QI 24)))]
4198 (popcount:QI (reg:QI 24)))
4203 ;; Count Leading Zeros
4205 (define_expand "clzhi2"
4207 (match_operand:HI 1 "register_operand" ""))
4208 (parallel [(set (reg:HI 24)
4209 (clz:HI (reg:HI 24)))
4210 (clobber (reg:QI 26))])
4211 (set (match_operand:HI 0 "register_operand" "")
4216 (define_expand "clzsi2"
4218 (match_operand:SI 1 "register_operand" ""))
4219 (parallel [(set (reg:HI 24)
4220 (clz:HI (reg:SI 22)))
4221 (clobber (reg:QI 26))])
4224 (set (match_operand:SI 0 "register_operand" "")
4225 (zero_extend:SI (match_dup 2)))]
4228 operands[2] = gen_reg_rtx (HImode);
4231 (define_insn "*clzhi2.libgcc"
4233 (clz:HI (reg:HI 24)))
4234 (clobber (reg:QI 26))]
4237 [(set_attr "type" "xcall")
4238 (set_attr "cc" "clobber")])
4240 (define_insn "*clzsihi2.libgcc"
4242 (clz:HI (reg:SI 22)))
4243 (clobber (reg:QI 26))]
4246 [(set_attr "type" "xcall")
4247 (set_attr "cc" "clobber")])
4249 ;; Count Trailing Zeros
4251 (define_expand "ctzhi2"
4253 (match_operand:HI 1 "register_operand" ""))
4254 (parallel [(set (reg:HI 24)
4255 (ctz:HI (reg:HI 24)))
4256 (clobber (reg:QI 26))])
4257 (set (match_operand:HI 0 "register_operand" "")
4262 (define_expand "ctzsi2"
4264 (match_operand:SI 1 "register_operand" ""))
4265 (parallel [(set (reg:HI 24)
4266 (ctz:HI (reg:SI 22)))
4267 (clobber (reg:QI 22))
4268 (clobber (reg:QI 26))])
4271 (set (match_operand:SI 0 "register_operand" "")
4272 (zero_extend:SI (match_dup 2)))]
4275 operands[2] = gen_reg_rtx (HImode);
4278 (define_insn "*ctzhi2.libgcc"
4280 (ctz:HI (reg:HI 24)))
4281 (clobber (reg:QI 26))]
4284 [(set_attr "type" "xcall")
4285 (set_attr "cc" "clobber")])
4287 (define_insn "*ctzsihi2.libgcc"
4289 (ctz:HI (reg:SI 22)))
4290 (clobber (reg:QI 22))
4291 (clobber (reg:QI 26))]
4294 [(set_attr "type" "xcall")
4295 (set_attr "cc" "clobber")])
4299 (define_expand "ffshi2"
4301 (match_operand:HI 1 "register_operand" ""))
4302 (parallel [(set (reg:HI 24)
4303 (ffs:HI (reg:HI 24)))
4304 (clobber (reg:QI 26))])
4305 (set (match_operand:HI 0 "register_operand" "")
4310 (define_expand "ffssi2"
4312 (match_operand:SI 1 "register_operand" ""))
4313 (parallel [(set (reg:HI 24)
4314 (ffs:HI (reg:SI 22)))
4315 (clobber (reg:QI 22))
4316 (clobber (reg:QI 26))])
4319 (set (match_operand:SI 0 "register_operand" "")
4320 (zero_extend:SI (match_dup 2)))]
4323 operands[2] = gen_reg_rtx (HImode);
4326 (define_insn "*ffshi2.libgcc"
4328 (ffs:HI (reg:HI 24)))
4329 (clobber (reg:QI 26))]
4332 [(set_attr "type" "xcall")
4333 (set_attr "cc" "clobber")])
4335 (define_insn "*ffssihi2.libgcc"
4337 (ffs:HI (reg:SI 22)))
4338 (clobber (reg:QI 22))
4339 (clobber (reg:QI 26))]
4342 [(set_attr "type" "xcall")
4343 (set_attr "cc" "clobber")])
4347 (define_insn "copysignsf3"
4348 [(set (match_operand:SF 0 "register_operand" "=r")
4349 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
4350 (match_operand:SF 2 "register_operand" "r")]
4353 "bst %D2,7\;bld %D0,7"
4354 [(set_attr "length" "2")
4355 (set_attr "cc" "none")])
4357 ;; Swap Bytes (change byte-endianess)
4359 (define_expand "bswapsi2"
4361 (match_operand:SI 1 "register_operand" ""))
4363 (bswap:SI (reg:SI 22)))
4364 (set (match_operand:SI 0 "register_operand" "")
4369 (define_insn "*bswapsi2.libgcc"
4371 (bswap:SI (reg:SI 22)))]
4374 [(set_attr "type" "xcall")
4375 (set_attr "cc" "clobber")])
4380 ;; NOP taking 1 or 2 Ticks
4382 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
4388 [(set_attr "length" "1")
4389 (set_attr "cc" "none")])
4392 (define_insn "sleep"
4393 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
4396 [(set_attr "length" "1")
4397 (set_attr "cc" "none")])
4401 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
4404 [(set_attr "length" "1")
4405 (set_attr "cc" "none")])
4408 (define_expand "fmul"
4410 (match_operand:QI 1 "register_operand" ""))
4412 (match_operand:QI 2 "register_operand" ""))
4413 (parallel [(set (reg:HI 22)
4414 (unspec:HI [(reg:QI 24)
4415 (reg:QI 25)] UNSPEC_FMUL))
4416 (clobber (reg:HI 24))])
4417 (set (match_operand:HI 0 "register_operand" "")
4423 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
4428 (define_insn "fmul_insn"
4429 [(set (match_operand:HI 0 "register_operand" "=r")
4430 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4431 (match_operand:QI 2 "register_operand" "a")]
4437 [(set_attr "length" "3")
4438 (set_attr "cc" "clobber")])
4440 (define_insn "*fmul.call"
4442 (unspec:HI [(reg:QI 24)
4443 (reg:QI 25)] UNSPEC_FMUL))
4444 (clobber (reg:HI 24))]
4447 [(set_attr "type" "xcall")
4448 (set_attr "cc" "clobber")])
4451 (define_expand "fmuls"
4453 (match_operand:QI 1 "register_operand" ""))
4455 (match_operand:QI 2 "register_operand" ""))
4456 (parallel [(set (reg:HI 22)
4457 (unspec:HI [(reg:QI 24)
4458 (reg:QI 25)] UNSPEC_FMULS))
4459 (clobber (reg:HI 24))])
4460 (set (match_operand:HI 0 "register_operand" "")
4466 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
4471 (define_insn "fmuls_insn"
4472 [(set (match_operand:HI 0 "register_operand" "=r")
4473 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4474 (match_operand:QI 2 "register_operand" "a")]
4480 [(set_attr "length" "3")
4481 (set_attr "cc" "clobber")])
4483 (define_insn "*fmuls.call"
4485 (unspec:HI [(reg:QI 24)
4486 (reg:QI 25)] UNSPEC_FMULS))
4487 (clobber (reg:HI 24))]
4490 [(set_attr "type" "xcall")
4491 (set_attr "cc" "clobber")])
4494 (define_expand "fmulsu"
4496 (match_operand:QI 1 "register_operand" ""))
4498 (match_operand:QI 2 "register_operand" ""))
4499 (parallel [(set (reg:HI 22)
4500 (unspec:HI [(reg:QI 24)
4501 (reg:QI 25)] UNSPEC_FMULSU))
4502 (clobber (reg:HI 24))])
4503 (set (match_operand:HI 0 "register_operand" "")
4509 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
4514 (define_insn "fmulsu_insn"
4515 [(set (match_operand:HI 0 "register_operand" "=r")
4516 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4517 (match_operand:QI 2 "register_operand" "a")]
4523 [(set_attr "length" "3")
4524 (set_attr "cc" "clobber")])
4526 (define_insn "*fmulsu.call"
4528 (unspec:HI [(reg:QI 24)
4529 (reg:QI 25)] UNSPEC_FMULSU))
4530 (clobber (reg:HI 24))]
4533 [(set_attr "type" "xcall")
4534 (set_attr "cc" "clobber")])
4537 ;; Some combiner patterns dealing with bits.
4540 ;; Move bit $3.0 into bit $0.$4
4541 (define_insn "*movbitqi.1-6.a"
4542 [(set (match_operand:QI 0 "register_operand" "=r")
4543 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4544 (match_operand:QI 2 "single_zero_operand" "n"))
4545 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
4546 (match_operand:QI 4 "const_0_to_7_operand" "n"))
4547 (match_operand:QI 5 "single_one_operand" "n"))))]
4548 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
4549 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
4550 "bst %3,0\;bld %0,%4"
4551 [(set_attr "length" "2")
4552 (set_attr "cc" "none")])
4554 ;; Move bit $3.0 into bit $0.$4
4555 ;; Variation of above. Unfortunately, there is no canonicalized representation
4556 ;; of moving around bits. So what we see here depends on how user writes down
4557 ;; bit manipulations.
4558 (define_insn "*movbitqi.1-6.b"
4559 [(set (match_operand:QI 0 "register_operand" "=r")
4560 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4561 (match_operand:QI 2 "single_zero_operand" "n"))
4562 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
4564 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
4565 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4566 "bst %3,0\;bld %0,%4"
4567 [(set_attr "length" "2")
4568 (set_attr "cc" "none")])
4570 ;; Move bit $3.0 into bit $0.0.
4571 ;; For bit 0, combiner generates slightly different pattern.
4572 (define_insn "*movbitqi.0"
4573 [(set (match_operand:QI 0 "register_operand" "=r")
4574 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4575 (match_operand:QI 2 "single_zero_operand" "n"))
4576 (and:QI (match_operand:QI 3 "register_operand" "r")
4578 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4579 "bst %3,0\;bld %0,0"
4580 [(set_attr "length" "2")
4581 (set_attr "cc" "none")])
4583 ;; Move bit $2.0 into bit $0.7.
4584 ;; For bit 7, combiner generates slightly different pattern
4585 (define_insn "*movbitqi.7"
4586 [(set (match_operand:QI 0 "register_operand" "=r")
4587 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4589 (ashift:QI (match_operand:QI 2 "register_operand" "r")
4592 "bst %2,0\;bld %0,7"
4593 [(set_attr "length" "2")
4594 (set_attr "cc" "none")])
4596 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
4597 ;; and input/output match. We provide a special pattern for this, because
4598 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
4599 ;; operation on I/O is atomic.
4600 (define_insn "*insv.io"
4601 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
4603 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
4604 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
4609 sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
4610 [(set_attr "length" "1,1,4")
4611 (set_attr "cc" "none")])
4613 (define_insn "*insv.not.io"
4614 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4616 (match_operand:QI 1 "const_0_to_7_operand" "n"))
4617 (not:QI (match_operand:QI 2 "register_operand" "r")))]
4619 "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
4620 [(set_attr "length" "4")
4621 (set_attr "cc" "none")])
4623 ;; The insv expander.
4624 ;; We only support 1-bit inserts
4625 (define_expand "insv"
4626 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
4627 (match_operand:QI 1 "const1_operand" "") ; width
4628 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
4629 (match_operand:QI 3 "nonmemory_operand" ""))]
4633 ;; Insert bit $2.0 into $0.$1
4634 (define_insn "*insv.reg"
4635 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
4637 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
4638 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
4642 andi %0,lo8(~(1<<%1))
4646 [(set_attr "length" "2,1,1,2,2")
4647 (set_attr "cc" "none,set_zn,set_zn,none,none")])
4650 ;; Some combine patterns that try to fix bad code when a value is composed
4651 ;; from byte parts like in PR27663.
4652 ;; The patterns give some release but the code still is not optimal,
4653 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
4654 ;; That switch obfuscates things here and in many other places.
4656 (define_insn_and_split "*ior<mode>qi.byte0"
4657 [(set (match_operand:HISI 0 "register_operand" "=r")
4659 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4660 (match_operand:HISI 2 "register_operand" "0")))]
4665 (ior:QI (match_dup 3)
4668 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
4671 (define_insn_and_split "*ior<mode>qi.byte1-3"
4672 [(set (match_operand:HISI 0 "register_operand" "=r")
4674 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4675 (match_operand:QI 2 "const_8_16_24_operand" "n"))
4676 (match_operand:HISI 3 "register_operand" "0")))]
4677 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
4679 "&& reload_completed"
4681 (ior:QI (match_dup 4)
4684 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
4685 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
4688 (define_expand "extzv"
4689 [(set (match_operand:QI 0 "register_operand" "")
4690 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
4691 (match_operand:QI 2 "const1_operand" "")
4692 (match_operand:QI 3 "const_0_to_7_operand" "")))]
4696 (define_insn "*extzv"
4697 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
4698 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
4700 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
4704 mov %0,%1\;andi %0,1
4707 bst %1,%2\;clr %0\;bld %0,0"
4708 [(set_attr "length" "1,2,2,2,3")
4709 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
4711 (define_insn_and_split "*extzv.qihi1"
4712 [(set (match_operand:HI 0 "register_operand" "=r")
4713 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
4715 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
4720 (zero_extract:QI (match_dup 1)
4726 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4727 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4730 (define_insn_and_split "*extzv.qihi2"
4731 [(set (match_operand:HI 0 "register_operand" "=r")
4733 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
4735 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
4740 (zero_extract:QI (match_dup 1)
4746 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4747 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);