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_prefix
149 ;;========================================================================
150 ;; The following is used by nonlocal_goto and setjmp.
151 ;; The receiver pattern will create no instructions since internally
152 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
153 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
154 ;; The 'null' receiver also avoids problems with optimisation
155 ;; not recognising incoming jmp and removing code that resets frame_pointer.
156 ;; The code derived from builtins.c.
158 (define_expand "nonlocal_goto_receiver"
160 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
163 emit_move_insn (virtual_stack_vars_rtx,
164 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
165 gen_int_mode (STARTING_FRAME_OFFSET,
167 /* This might change the hard frame pointer in ways that aren't
168 apparent to early optimization passes, so force a clobber. */
169 emit_clobber (hard_frame_pointer_rtx);
174 ;; Defining nonlocal_goto_receiver means we must also define this.
175 ;; even though its function is identical to that in builtins.c
177 (define_expand "nonlocal_goto"
179 (use (match_operand 0 "general_operand"))
180 (use (match_operand 1 "general_operand"))
181 (use (match_operand 2 "general_operand"))
182 (use (match_operand 3 "general_operand"))
186 rtx r_label = copy_to_reg (operands[1]);
187 rtx r_fp = operands[3];
188 rtx r_sp = operands[2];
190 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
192 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
194 emit_move_insn (hard_frame_pointer_rtx, r_fp);
195 emit_stack_restore (SAVE_NONLOCAL, r_sp);
197 emit_use (hard_frame_pointer_rtx);
198 emit_use (stack_pointer_rtx);
200 emit_indirect_jump (r_label);
205 (define_insn "pushqi1"
206 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
207 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
212 [(set_attr "length" "1,1")])
214 ;; All modes for a multi-byte push. We must include complex modes here too,
215 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
216 (define_mode_iterator MPUSH
223 (define_expand "push<mode>1"
224 [(match_operand:MPUSH 0 "" "")]
228 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
230 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
231 if (part != const0_rtx)
232 part = force_reg (QImode, part);
233 emit_insn (gen_pushqi1 (part));
238 ;;========================================================================
240 ;; The last alternative (any immediate constant to any register) is
241 ;; very expensive. It should be optimized by peephole2 if a scratch
242 ;; register is available, but then that register could just as well be
243 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
244 ;; are call-saved registers, and most of LD_REGS are call-used registers,
245 ;; so this may still be a win for registers live across function calls.
247 (define_expand "movqi"
248 [(set (match_operand:QI 0 "nonimmediate_operand" "")
249 (match_operand:QI 1 "general_operand" ""))]
251 "/* One of the ops has to be in a register. */
252 if (!register_operand(operand0, QImode)
253 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
254 operands[1] = copy_to_mode_reg(QImode, operand1);
257 (define_insn "*movqi"
258 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
259 (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))]
260 "(register_operand (operands[0],QImode)
261 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
262 "* return output_movqi (insn, operands, NULL);"
263 [(set_attr "length" "1,1,5,5,1,1,4")
264 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
266 ;; This is used in peephole2 to optimize loading immediate constants
267 ;; if a scratch register from LD_REGS happens to be available.
269 (define_insn "*reload_inqi"
270 [(set (match_operand:QI 0 "register_operand" "=l")
271 (match_operand:QI 1 "immediate_operand" "i"))
272 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
276 [(set_attr "length" "2")
277 (set_attr "cc" "none")])
280 [(match_scratch:QI 2 "d")
281 (set (match_operand:QI 0 "l_register_operand" "")
282 (match_operand:QI 1 "immediate_operand" ""))]
283 "(operands[1] != const0_rtx
284 && operands[1] != const1_rtx
285 && operands[1] != constm1_rtx)"
286 [(parallel [(set (match_dup 0) (match_dup 1))
287 (clobber (match_dup 2))])]
290 ;;============================================================================
291 ;; move word (16 bit)
293 (define_expand "movhi"
294 [(set (match_operand:HI 0 "nonimmediate_operand" "")
295 (match_operand:HI 1 "general_operand" ""))]
299 /* One of the ops has to be in a register. */
300 if (!register_operand(operand0, HImode)
301 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
303 operands[1] = copy_to_mode_reg(HImode, operand1);
307 (define_insn "*movhi_sp"
308 [(set (match_operand:HI 0 "register_operand" "=q,r")
309 (match_operand:HI 1 "register_operand" "r,q"))]
310 "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
311 || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
312 "* return output_movhi (insn, operands, NULL);"
313 [(set_attr "length" "5,2")
314 (set_attr "cc" "none,none")])
316 (define_insn "movhi_sp_r_irq_off"
317 [(set (match_operand:HI 0 "stack_register_operand" "=q")
318 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
319 UNSPECV_WRITE_SP_IRQ_OFF))]
323 [(set_attr "length" "2")
324 (set_attr "cc" "none")])
326 (define_insn "movhi_sp_r_irq_on"
327 [(set (match_operand:HI 0 "stack_register_operand" "=q")
328 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
329 UNSPECV_WRITE_SP_IRQ_ON))]
335 [(set_attr "length" "4")
336 (set_attr "cc" "none")])
339 [(match_scratch:QI 2 "d")
340 (set (match_operand:HI 0 "l_register_operand" "")
341 (match_operand:HI 1 "immediate_operand" ""))]
342 "(operands[1] != const0_rtx
343 && operands[1] != constm1_rtx)"
344 [(parallel [(set (match_dup 0) (match_dup 1))
345 (clobber (match_dup 2))])]
348 ;; '*' because it is not used in rtl generation, only in above peephole
349 (define_insn "*reload_inhi"
350 [(set (match_operand:HI 0 "register_operand" "=r")
351 (match_operand:HI 1 "immediate_operand" "i"))
352 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
354 "* return output_reload_inhi (insn, operands, NULL);"
355 [(set_attr "length" "4")
356 (set_attr "cc" "none")])
358 (define_insn "*movhi"
359 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
360 (match_operand:HI 1 "general_operand" "rL,m,rL,i,i,r,q"))]
361 "(register_operand (operands[0],HImode)
362 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
363 "* return output_movhi (insn, operands, NULL);"
364 [(set_attr "length" "2,6,7,2,6,5,2")
365 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
367 (define_peephole2 ; movw
368 [(set (match_operand:QI 0 "even_register_operand" "")
369 (match_operand:QI 1 "even_register_operand" ""))
370 (set (match_operand:QI 2 "odd_register_operand" "")
371 (match_operand:QI 3 "odd_register_operand" ""))]
373 && REGNO (operands[0]) == REGNO (operands[2]) - 1
374 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
375 [(set (match_dup 4) (match_dup 5))]
377 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
378 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
381 (define_peephole2 ; movw_r
382 [(set (match_operand:QI 0 "odd_register_operand" "")
383 (match_operand:QI 1 "odd_register_operand" ""))
384 (set (match_operand:QI 2 "even_register_operand" "")
385 (match_operand:QI 3 "even_register_operand" ""))]
387 && REGNO (operands[2]) == REGNO (operands[0]) - 1
388 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
389 [(set (match_dup 4) (match_dup 5))]
391 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
392 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
395 ;;==========================================================================
396 ;; move double word (32 bit)
398 (define_expand "movsi"
399 [(set (match_operand:SI 0 "nonimmediate_operand" "")
400 (match_operand:SI 1 "general_operand" ""))]
404 /* One of the ops has to be in a register. */
405 if (!register_operand (operand0, SImode)
406 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
408 operands[1] = copy_to_mode_reg (SImode, operand1);
414 (define_peephole2 ; *reload_insi
415 [(match_scratch:QI 2 "d")
416 (set (match_operand:SI 0 "l_register_operand" "")
417 (match_operand:SI 1 "const_int_operand" ""))
419 "(operands[1] != const0_rtx
420 && operands[1] != constm1_rtx)"
421 [(parallel [(set (match_dup 0) (match_dup 1))
422 (clobber (match_dup 2))])]
425 ;; '*' because it is not used in rtl generation.
426 (define_insn "*reload_insi"
427 [(set (match_operand:SI 0 "register_operand" "=r")
428 (match_operand:SI 1 "const_int_operand" "n"))
429 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
432 return output_reload_insisf (insn, operands, operands[2], NULL);
434 [(set_attr "length" "8")
435 (set_attr "cc" "clobber")])
438 (define_insn "*movsi"
439 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
440 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
441 "(register_operand (operands[0],SImode)
442 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
444 return output_movsisf (insn, operands, NULL_RTX, NULL);
446 [(set_attr "length" "4,4,8,9,4,10")
447 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
449 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
450 ;; move floating point numbers (32 bit)
452 (define_expand "movsf"
453 [(set (match_operand:SF 0 "nonimmediate_operand" "")
454 (match_operand:SF 1 "general_operand" ""))]
458 /* One of the ops has to be in a register. */
459 if (!register_operand (operand1, SFmode)
460 && !register_operand (operand0, SFmode))
462 operands[1] = copy_to_mode_reg (SFmode, operand1);
466 (define_insn "*movsf"
467 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
468 (match_operand:SF 1 "general_operand" "r,G,Qm,rG,F,F"))]
469 "register_operand (operands[0], SFmode)
470 || register_operand (operands[1], SFmode)
471 || operands[1] == CONST0_RTX (SFmode)"
473 return output_movsisf (insn, operands, NULL_RTX, NULL);
475 [(set_attr "length" "4,4,8,9,4,10")
476 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
478 (define_peephole2 ; *reload_insf
479 [(match_scratch:QI 2 "d")
480 (set (match_operand:SF 0 "l_register_operand" "")
481 (match_operand:SF 1 "const_double_operand" ""))
483 "operands[1] != CONST0_RTX (SFmode)"
484 [(parallel [(set (match_dup 0)
486 (clobber (match_dup 2))])]
489 ;; '*' because it is not used in rtl generation.
490 (define_insn "*reload_insf"
491 [(set (match_operand:SF 0 "register_operand" "=r")
492 (match_operand:SF 1 "const_double_operand" "F"))
493 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
496 return output_reload_insisf (insn, operands, operands[2], NULL);
498 [(set_attr "length" "8")
499 (set_attr "cc" "clobber")])
501 ;;=========================================================================
502 ;; move string (like memcpy)
503 ;; implement as RTL loop
505 (define_expand "movmemhi"
506 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
507 (match_operand:BLK 1 "memory_operand" ""))
508 (use (match_operand:HI 2 "const_int_operand" ""))
509 (use (match_operand:HI 3 "const_int_operand" ""))])]
514 enum machine_mode mode;
515 rtx label = gen_label_rtx ();
519 /* Copy pointers into new psuedos - they will be changed. */
520 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
521 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
523 /* Create rtx for tmp register - we use this as scratch. */
524 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
526 if (GET_CODE (operands[2]) != CONST_INT)
529 count = INTVAL (operands[2]);
533 /* Work out branch probability for latter use. */
534 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
536 /* See if constant fit 8 bits. */
537 mode = (count < 0x100) ? QImode : HImode;
538 /* Create loop counter register. */
539 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
541 /* Now create RTL code for move loop. */
542 /* Label at top of loop. */
545 /* Move one byte into scratch and inc pointer. */
546 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
547 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
549 /* Move to mem and inc pointer. */
550 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
551 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
553 /* Decrement count. */
554 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
556 /* Compare with zero and jump if not equal. */
557 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
559 /* Set jump probability based on loop count. */
560 jump = get_last_insn ();
561 add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
565 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
566 ;; memset (%0, %2, %1)
568 (define_expand "setmemhi"
569 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
570 (match_operand 2 "const_int_operand" ""))
571 (use (match_operand:HI 1 "const_int_operand" ""))
572 (use (match_operand:HI 3 "const_int_operand" "n"))
573 (clobber (match_scratch:HI 4 ""))
574 (clobber (match_dup 5))])]
579 enum machine_mode mode;
581 /* If value to set is not zero, use the library routine. */
582 if (operands[2] != const0_rtx)
585 if (GET_CODE (operands[1]) != CONST_INT)
588 cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
589 mode = cnt8 ? QImode : HImode;
590 operands[5] = gen_rtx_SCRATCH (mode);
591 operands[1] = copy_to_mode_reg (mode,
592 gen_int_mode (INTVAL (operands[1]), mode));
593 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
594 operands[0] = gen_rtx_MEM (BLKmode, addr0);
597 (define_insn "*clrmemqi"
598 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
600 (use (match_operand:QI 1 "register_operand" "r"))
601 (use (match_operand:QI 2 "const_int_operand" "n"))
602 (clobber (match_scratch:HI 3 "=0"))
603 (clobber (match_scratch:QI 4 "=&1"))]
605 "st %a0+,__zero_reg__
608 [(set_attr "length" "3")
609 (set_attr "cc" "clobber")])
611 (define_insn "*clrmemhi"
612 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
614 (use (match_operand:HI 1 "register_operand" "!w,d"))
615 (use (match_operand:HI 2 "const_int_operand" "n,n"))
616 (clobber (match_scratch:HI 3 "=0,0"))
617 (clobber (match_scratch:HI 4 "=&1,&1"))]
620 if (which_alternative==0)
621 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
622 AS2 (sbiw,%A1,1) CR_TAB
625 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
626 AS2 (subi,%A1,1) CR_TAB
627 AS2 (sbci,%B1,0) CR_TAB
630 [(set_attr "length" "3,4")
631 (set_attr "cc" "clobber,clobber")])
633 (define_expand "strlenhi"
635 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
636 (match_operand:QI 2 "const_int_operand" "")
637 (match_operand:HI 3 "immediate_operand" "")]
639 (set (match_dup 4) (plus:HI (match_dup 4)
641 (set (match_operand:HI 0 "register_operand" "")
642 (minus:HI (match_dup 4)
647 if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
649 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
650 operands[1] = gen_rtx_MEM (BLKmode, addr);
652 operands[4] = gen_reg_rtx (HImode);
655 (define_insn "*strlenhi"
656 [(set (match_operand:HI 0 "register_operand" "=e")
657 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
659 (match_operand:HI 2 "immediate_operand" "i")]
665 [(set_attr "length" "3")
666 (set_attr "cc" "clobber")])
668 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
671 (define_insn "addqi3"
672 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
673 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
674 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
681 [(set_attr "length" "1,1,1,1")
682 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
685 (define_expand "addhi3"
686 [(set (match_operand:HI 0 "register_operand" "")
687 (plus:HI (match_operand:HI 1 "register_operand" "")
688 (match_operand:HI 2 "nonmemory_operand" "")))]
692 if (GET_CODE (operands[2]) == CONST_INT)
694 short tmp = INTVAL (operands[2]);
695 operands[2] = GEN_INT(tmp);
700 (define_insn "*addhi3_zero_extend"
701 [(set (match_operand:HI 0 "register_operand" "=r")
702 (plus:HI (zero_extend:HI
703 (match_operand:QI 1 "register_operand" "r"))
704 (match_operand:HI 2 "register_operand" "0")))]
707 adc %B0,__zero_reg__"
708 [(set_attr "length" "2")
709 (set_attr "cc" "set_n")])
711 (define_insn "*addhi3_zero_extend1"
712 [(set (match_operand:HI 0 "register_operand" "=r")
713 (plus:HI (match_operand:HI 1 "register_operand" "%0")
715 (match_operand:QI 2 "register_operand" "r"))))]
718 adc %B0,__zero_reg__"
719 [(set_attr "length" "2")
720 (set_attr "cc" "set_n")])
722 (define_insn "*addhi3_sp_R_pc2"
723 [(set (match_operand:HI 1 "stack_register_operand" "=q")
724 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
725 (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
728 if (CONST_INT_P (operands[0]))
730 switch(INTVAL (operands[0]))
733 return \"rcall .\" CR_TAB
737 return \"rcall .\" CR_TAB
739 \"push __tmp_reg__\";
741 return \"rcall .\" CR_TAB
744 return \"rcall .\" CR_TAB
745 \"push __tmp_reg__\";
749 return \"push __tmp_reg__\";
753 return \"pop __tmp_reg__\";
755 return \"pop __tmp_reg__\" CR_TAB
758 return \"pop __tmp_reg__\" CR_TAB
759 \"pop __tmp_reg__\" CR_TAB
762 return \"pop __tmp_reg__\" CR_TAB
763 \"pop __tmp_reg__\" CR_TAB
764 \"pop __tmp_reg__\" CR_TAB
767 return \"pop __tmp_reg__\" CR_TAB
768 \"pop __tmp_reg__\" CR_TAB
769 \"pop __tmp_reg__\" CR_TAB
770 \"pop __tmp_reg__\" CR_TAB
776 [(set (attr "length")
777 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
778 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
779 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
780 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
781 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
782 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
783 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
784 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
785 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
786 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
787 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
788 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
791 (define_insn "*addhi3_sp_R_pc3"
792 [(set (match_operand:HI 1 "stack_register_operand" "=q")
793 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
794 (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
797 if (CONST_INT_P (operands[0]))
799 switch(INTVAL (operands[0]))
802 return \"rcall .\" CR_TAB
805 return \"rcall .\" CR_TAB
806 \"push __tmp_reg__\" CR_TAB
807 \"push __tmp_reg__\";
809 return \"rcall .\" CR_TAB
810 \"push __tmp_reg__\";
814 return \"push __tmp_reg__\" CR_TAB
815 \"push __tmp_reg__\";
817 return \"push __tmp_reg__\";
821 return \"pop __tmp_reg__\";
823 return \"pop __tmp_reg__\" CR_TAB
826 return \"pop __tmp_reg__\" CR_TAB
827 \"pop __tmp_reg__\" CR_TAB
830 return \"pop __tmp_reg__\" CR_TAB
831 \"pop __tmp_reg__\" CR_TAB
832 \"pop __tmp_reg__\" CR_TAB
835 return \"pop __tmp_reg__\" CR_TAB
836 \"pop __tmp_reg__\" CR_TAB
837 \"pop __tmp_reg__\" CR_TAB
838 \"pop __tmp_reg__\" CR_TAB
844 [(set (attr "length")
845 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
846 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
847 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
848 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
849 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
850 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
851 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
852 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
853 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
854 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
855 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
856 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
859 (define_insn "*addhi3"
860 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
862 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
863 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
866 add %A0,%A2\;adc %B0,%B2
869 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
870 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
871 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
872 [(set_attr "length" "2,1,1,2,3,3")
873 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
875 (define_insn "addsi3"
876 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
878 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
879 (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
882 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
883 adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
884 sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
885 subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
886 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
887 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
888 [(set_attr "length" "4,3,3,4,5,5")
889 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
891 (define_insn "*addsi3_zero_extend"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (plus:SI (zero_extend:SI
894 (match_operand:QI 1 "register_operand" "r"))
895 (match_operand:SI 2 "register_operand" "0")))]
900 adc %D0,__zero_reg__"
901 [(set_attr "length" "4")
902 (set_attr "cc" "set_n")])
904 ;-----------------------------------------------------------------------------
906 (define_insn "subqi3"
907 [(set (match_operand:QI 0 "register_operand" "=r,d")
908 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
909 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
914 [(set_attr "length" "1,1")
915 (set_attr "cc" "set_czn,set_czn")])
917 (define_insn "subhi3"
918 [(set (match_operand:HI 0 "register_operand" "=r,d")
919 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
920 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
923 sub %A0,%A2\;sbc %B0,%B2
924 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
925 [(set_attr "length" "2,2")
926 (set_attr "cc" "set_czn,set_czn")])
928 (define_insn "*subhi3_zero_extend1"
929 [(set (match_operand:HI 0 "register_operand" "=r")
930 (minus:HI (match_operand:HI 1 "register_operand" "0")
932 (match_operand:QI 2 "register_operand" "r"))))]
935 sbc %B0,__zero_reg__"
936 [(set_attr "length" "2")
937 (set_attr "cc" "set_n")])
939 (define_insn "subsi3"
940 [(set (match_operand:SI 0 "register_operand" "=r,d")
941 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
942 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
945 sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
946 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
947 [(set_attr "length" "4,4")
948 (set_attr "cc" "set_czn,set_czn")])
950 (define_insn "*subsi3_zero_extend"
951 [(set (match_operand:SI 0 "register_operand" "=r")
952 (minus:SI (match_operand:SI 1 "register_operand" "0")
954 (match_operand:QI 2 "register_operand" "r"))))]
959 sbc %D0,__zero_reg__"
960 [(set_attr "length" "4")
961 (set_attr "cc" "set_n")])
963 ;******************************************************************************
966 (define_expand "mulqi3"
967 [(set (match_operand:QI 0 "register_operand" "")
968 (mult:QI (match_operand:QI 1 "register_operand" "")
969 (match_operand:QI 2 "register_operand" "")))]
974 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
979 (define_insn "*mulqi3_enh"
980 [(set (match_operand:QI 0 "register_operand" "=r")
981 (mult:QI (match_operand:QI 1 "register_operand" "r")
982 (match_operand:QI 2 "register_operand" "r")))]
987 [(set_attr "length" "3")
988 (set_attr "cc" "clobber")])
990 (define_expand "mulqi3_call"
991 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
992 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
993 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
994 (clobber (reg:QI 22))])
995 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
999 (define_insn "*mulqi3_call"
1000 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1001 (clobber (reg:QI 22))]
1004 [(set_attr "type" "xcall")
1005 (set_attr "cc" "clobber")])
1007 (define_insn "mulqihi3"
1008 [(set (match_operand:HI 0 "register_operand" "=r")
1009 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1010 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
1015 [(set_attr "length" "3")
1016 (set_attr "cc" "clobber")])
1018 (define_insn "umulqihi3"
1019 [(set (match_operand:HI 0 "register_operand" "=r")
1020 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1021 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1026 [(set_attr "length" "3")
1027 (set_attr "cc" "clobber")])
1029 (define_insn "usmulqihi3"
1030 [(set (match_operand:HI 0 "register_operand" "=r")
1031 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1032 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1037 [(set_attr "length" "3")
1038 (set_attr "cc" "clobber")])
1040 ;; Above insn is not canonicalized by insn combine, so here is a version with
1041 ;; operands swapped.
1043 (define_insn "*sumulqihi3"
1044 [(set (match_operand:HI 0 "register_operand" "=r")
1045 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1046 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1051 [(set_attr "length" "3")
1052 (set_attr "cc" "clobber")])
1054 ;; One-extend operand 1
1056 (define_insn "*osmulqihi3"
1057 [(set (match_operand:HI 0 "register_operand" "=&r")
1058 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1059 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1065 [(set_attr "length" "4")
1066 (set_attr "cc" "clobber")])
1068 (define_insn "*oumulqihi3"
1069 [(set (match_operand:HI 0 "register_operand" "=&r")
1070 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1071 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1077 [(set_attr "length" "4")
1078 (set_attr "cc" "clobber")])
1081 ;******************************************************************************
1082 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1083 ;******************************************************************************
1085 (define_insn_and_split "*muluqihi3.uconst"
1086 [(set (match_operand:HI 0 "register_operand" "=r")
1087 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1088 (match_operand:HI 2 "u8_operand" "M")))
1089 (clobber (match_scratch:QI 3 "=&d"))]
1092 "&& reload_completed"
1097 (mult:HI (zero_extend:HI (match_dup 1))
1098 (zero_extend:HI (match_dup 3))))]
1100 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1103 (define_insn_and_split "*muluqihi3.sconst"
1104 [(set (match_operand:HI 0 "register_operand" "=r")
1105 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1106 (match_operand:HI 2 "s8_operand" "n")))
1107 (clobber (match_scratch:QI 3 "=&a"))]
1110 "&& reload_completed"
1115 (mult:HI (zero_extend:HI (match_dup 1))
1116 (sign_extend:HI (match_dup 3))))]
1118 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1121 (define_insn_and_split "*mulsqihi3.sconst"
1122 [(set (match_operand:HI 0 "register_operand" "=r")
1123 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1124 (match_operand:HI 2 "s8_operand" "n")))
1125 (clobber (match_scratch:QI 3 "=&d"))]
1128 "&& reload_completed"
1133 (mult:HI (sign_extend:HI (match_dup 1))
1134 (sign_extend:HI (match_dup 3))))]
1136 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1139 (define_insn_and_split "*mulsqihi3.uconst"
1140 [(set (match_operand:HI 0 "register_operand" "=r")
1141 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1142 (match_operand:HI 2 "u8_operand" "M")))
1143 (clobber (match_scratch:QI 3 "=&a"))]
1146 "&& reload_completed"
1151 (mult:HI (zero_extend:HI (match_dup 3))
1152 (sign_extend:HI (match_dup 1))))]
1154 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1157 (define_insn_and_split "*mulsqihi3.oconst"
1158 [(set (match_operand:HI 0 "register_operand" "=&r")
1159 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1160 (match_operand:HI 2 "o8_operand" "n")))
1161 (clobber (match_scratch:QI 3 "=&a"))]
1164 "&& reload_completed"
1169 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1170 (sign_extend:HI (match_dup 1))))]
1172 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1175 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1176 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1177 ;; at that time. Fix that.
1179 (define_insn_and_split "*ashifthi3.signx.const"
1180 [(set (match_operand:HI 0 "register_operand" "=r")
1181 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1182 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1183 (clobber (match_scratch:QI 3 "=&d"))]
1186 "&& reload_completed"
1191 (mult:HI (sign_extend:HI (match_dup 1))
1192 (sign_extend:HI (match_dup 3))))]
1194 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1197 (define_insn_and_split "*ashifthi3.signx.const7"
1198 [(set (match_operand:HI 0 "register_operand" "=r")
1199 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1201 (clobber (match_scratch:QI 2 "=&a"))]
1204 "&& reload_completed"
1209 (mult:HI (zero_extend:HI (match_dup 2))
1210 (sign_extend:HI (match_dup 1))))]
1212 operands[3] = gen_int_mode (1 << 7, QImode);
1215 (define_insn_and_split "*ashifthi3.zerox.const"
1216 [(set (match_operand:HI 0 "register_operand" "=r")
1217 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1218 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1219 (clobber (match_scratch:QI 3 "=&d"))]
1222 "&& reload_completed"
1227 (mult:HI (zero_extend:HI (match_dup 1))
1228 (zero_extend:HI (match_dup 3))))]
1230 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1233 ;******************************************************************************
1234 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1235 ;******************************************************************************
1237 (define_insn "mulsqihi3"
1238 [(set (match_operand:HI 0 "register_operand" "=&r")
1239 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1240 (match_operand:HI 2 "register_operand" "a")))]
1247 [(set_attr "length" "5")
1248 (set_attr "cc" "clobber")])
1250 (define_insn "muluqihi3"
1251 [(set (match_operand:HI 0 "register_operand" "=&r")
1252 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1253 (match_operand:HI 2 "register_operand" "r")))]
1260 [(set_attr "length" "5")
1261 (set_attr "cc" "clobber")])
1263 ;; one-extend operand 1
1265 (define_insn "muloqihi3"
1266 [(set (match_operand:HI 0 "register_operand" "=&r")
1267 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1268 (match_operand:HI 2 "register_operand" "r")))]
1276 [(set_attr "length" "6")
1277 (set_attr "cc" "clobber")])
1279 ;******************************************************************************
1281 (define_expand "mulhi3"
1282 [(set (match_operand:HI 0 "register_operand" "")
1283 (mult:HI (match_operand:HI 1 "register_operand" "")
1284 (match_operand:HI 2 "register_or_s9_operand" "")))]
1289 if (!register_operand (operands[2], HImode))
1290 operands[2] = force_reg (HImode, operands[2]);
1292 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1296 /* For small constants we can do better by extending them on the fly.
1297 The constant can be loaded in one instruction and the widening
1298 multiplication is shorter. First try the unsigned variant because it
1299 allows constraint "d" instead of "a" for the signed version. */
1301 if (s9_operand (operands[2], HImode))
1303 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1305 if (u8_operand (operands[2], HImode))
1307 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1309 else if (s8_operand (operands[2], HImode))
1311 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1315 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1321 if (!register_operand (operands[2], HImode))
1322 operands[2] = force_reg (HImode, operands[2]);
1325 (define_insn "*mulhi3_enh"
1326 [(set (match_operand:HI 0 "register_operand" "=&r")
1327 (mult:HI (match_operand:HI 1 "register_operand" "r")
1328 (match_operand:HI 2 "register_operand" "r")))]
1337 [(set_attr "length" "7")
1338 (set_attr "cc" "clobber")])
1340 (define_expand "mulhi3_call"
1341 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1342 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1343 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1344 (clobber (reg:HI 22))
1345 (clobber (reg:QI 21))])
1346 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1350 (define_insn "*mulhi3_call"
1351 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1352 (clobber (reg:HI 22))
1353 (clobber (reg:QI 21))]
1356 [(set_attr "type" "xcall")
1357 (set_attr "cc" "clobber")])
1359 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
1360 ;; All call-used registers clobbered otherwise - normal library call.
1361 ;; To support widening multiplicatioon with constant we postpone
1362 ;; expanding to the implicit library call until post combine and
1363 ;; prior to register allocation. Clobber all hard registers that
1364 ;; might be used by the (widening) multiply until it is split and
1365 ;; it's final register footprint is worked out.
1367 (define_expand "mulsi3"
1368 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1369 (mult:SI (match_operand:SI 1 "register_operand" "")
1370 (match_operand:SI 2 "nonmemory_operand" "")))
1371 (clobber (reg:HI 26))
1372 (clobber (reg:DI 18))])]
1375 if (u16_operand (operands[2], SImode))
1377 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1378 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1382 if (o16_operand (operands[2], SImode))
1384 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1385 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1390 (define_insn_and_split "*mulsi3"
1391 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1392 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
1393 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1394 (clobber (reg:HI 26))
1395 (clobber (reg:DI 18))]
1396 "AVR_HAVE_MUL && !reload_completed"
1397 { gcc_unreachable(); }
1403 (parallel [(set (reg:SI 22)
1404 (mult:SI (reg:SI 22)
1406 (clobber (reg:HI 26))])
1410 if (u16_operand (operands[2], SImode))
1412 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1413 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1417 if (o16_operand (operands[2], SImode))
1419 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1420 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1427 (define_insn_and_split "mulu<mode>si3"
1428 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1429 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1430 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1431 (clobber (reg:HI 26))
1432 (clobber (reg:DI 18))]
1433 "AVR_HAVE_MUL && !reload_completed"
1434 { gcc_unreachable(); }
1441 (mult:SI (zero_extend:SI (reg:HI 26))
1446 /* Do the QI -> HI extension explicitely before the multiplication. */
1447 /* Do the HI -> SI extension implicitely and after the multiplication. */
1449 if (QImode == <MODE>mode)
1450 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
1452 if (u16_operand (operands[2], SImode))
1454 operands[1] = force_reg (HImode, operands[1]);
1455 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1456 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
1463 (define_insn_and_split "muls<mode>si3"
1464 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1465 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1466 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1467 (clobber (reg:HI 26))
1468 (clobber (reg:DI 18))]
1469 "AVR_HAVE_MUL && !reload_completed"
1470 { gcc_unreachable(); }
1477 (mult:SI (sign_extend:SI (reg:HI 26))
1482 /* Do the QI -> HI extension explicitely before the multiplication. */
1483 /* Do the HI -> SI extension implicitely and after the multiplication. */
1485 if (QImode == <MODE>mode)
1486 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
1488 if (u16_operand (operands[2], SImode)
1489 || s16_operand (operands[2], SImode))
1491 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1493 operands[1] = force_reg (HImode, operands[1]);
1495 if (u16_operand (operands[2], SImode))
1496 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
1498 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
1504 ;; One-extend operand 1
1506 (define_insn_and_split "mulohisi3"
1507 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1508 (mult:SI (not:SI (zero_extend:SI
1509 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
1510 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1511 (clobber (reg:HI 26))
1512 (clobber (reg:DI 18))]
1513 "AVR_HAVE_MUL && !reload_completed"
1514 { gcc_unreachable(); }
1521 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1527 (define_expand "mulhisi3"
1528 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1529 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1530 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1531 (clobber (reg:HI 26))
1532 (clobber (reg:DI 18))])]
1536 (define_expand "umulhisi3"
1537 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1538 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1539 (zero_extend:SI (match_operand:HI 2 "register_operand" ""))))
1540 (clobber (reg:HI 26))
1541 (clobber (reg:DI 18))])]
1545 (define_expand "usmulhisi3"
1546 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1547 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1548 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1549 (clobber (reg:HI 26))
1550 (clobber (reg:DI 18))])]
1554 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
1555 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
1556 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
1557 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
1558 (define_insn_and_split
1559 "*<any_extend:extend_prefix><any_extend2:extend_prefix>mul<QIHI:mode><QIHI2:mode>si3"
1560 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1561 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1562 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
1563 (clobber (reg:HI 26))
1564 (clobber (reg:DI 18))]
1565 "AVR_HAVE_MUL && !reload_completed"
1566 { gcc_unreachable(); }
1573 (mult:SI (match_dup 3)
1578 rtx xop1 = operands[1];
1579 rtx xop2 = operands[2];
1581 /* Do the QI -> HI extension explicitely before the multiplication. */
1582 /* Do the HI -> SI extension implicitely and after the multiplication. */
1584 if (QImode == <QIHI:MODE>mode)
1585 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
1587 if (QImode == <QIHI2:MODE>mode)
1588 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
1590 if (<any_extend:CODE> == <any_extend2:CODE>
1591 || <any_extend:CODE> == ZERO_EXTEND)
1595 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
1596 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
1600 /* <any_extend:CODE> = SIGN_EXTEND */
1601 /* <any_extend2:CODE> = ZERO_EXTEND */
1605 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
1606 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
1610 (define_insn "*mulsi3_call"
1612 (mult:SI (reg:SI 22)
1614 (clobber (reg:HI 26))]
1617 [(set_attr "type" "xcall")
1618 (set_attr "cc" "clobber")])
1620 (define_insn "*mulhisi3_call"
1622 (mult:SI (sign_extend:SI (reg:HI 18))
1623 (sign_extend:SI (reg:HI 26))))]
1626 [(set_attr "type" "xcall")
1627 (set_attr "cc" "clobber")])
1629 (define_insn "*umulhisi3_call"
1631 (mult:SI (zero_extend:SI (reg:HI 18))
1632 (zero_extend:SI (reg:HI 26))))]
1634 "%~call __umulhisi3"
1635 [(set_attr "type" "xcall")
1636 (set_attr "cc" "clobber")])
1638 (define_insn "*usmulhisi3_call"
1640 (mult:SI (zero_extend:SI (reg:HI 18))
1641 (sign_extend:SI (reg:HI 26))))]
1643 "%~call __usmulhisi3"
1644 [(set_attr "type" "xcall")
1645 (set_attr "cc" "clobber")])
1647 (define_insn "*muluhisi3_call"
1649 (mult:SI (zero_extend:SI (reg:HI 26))
1652 "%~call __muluhisi3"
1653 [(set_attr "type" "xcall")
1654 (set_attr "cc" "clobber")])
1656 (define_insn "*mulshisi3_call"
1658 (mult:SI (sign_extend:SI (reg:HI 26))
1661 "%~call __mulshisi3"
1662 [(set_attr "type" "xcall")
1663 (set_attr "cc" "clobber")])
1665 (define_insn "*mulohisi3_call"
1667 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1670 "%~call __mulohisi3"
1671 [(set_attr "type" "xcall")
1672 (set_attr "cc" "clobber")])
1674 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1677 ;; Generate libgcc.S calls ourselves, because:
1678 ;; - we know exactly which registers are clobbered (for QI and HI
1679 ;; modes, some of the call-used registers are preserved)
1680 ;; - we get both the quotient and the remainder at no extra cost
1681 ;; - we split the patterns only after the first CSE passes because
1682 ;; CSE has problems to operate on hard regs.
1684 (define_insn_and_split "divmodqi4"
1685 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1686 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
1687 (match_operand:QI 2 "pseudo_register_operand" "")))
1688 (set (match_operand:QI 3 "pseudo_register_operand" "")
1689 (mod:QI (match_dup 1) (match_dup 2)))
1690 (clobber (reg:QI 22))
1691 (clobber (reg:QI 23))
1692 (clobber (reg:QI 24))
1693 (clobber (reg:QI 25))])]
1695 "this divmodqi4 pattern should have been splitted;"
1697 [(set (reg:QI 24) (match_dup 1))
1698 (set (reg:QI 22) (match_dup 2))
1699 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1700 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1701 (clobber (reg:QI 22))
1702 (clobber (reg:QI 23))])
1703 (set (match_dup 0) (reg:QI 24))
1704 (set (match_dup 3) (reg:QI 25))]
1707 (define_insn "*divmodqi4_call"
1708 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1709 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1710 (clobber (reg:QI 22))
1711 (clobber (reg:QI 23))]
1713 "%~call __divmodqi4"
1714 [(set_attr "type" "xcall")
1715 (set_attr "cc" "clobber")])
1717 (define_insn_and_split "udivmodqi4"
1718 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1719 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
1720 (match_operand:QI 2 "pseudo_register_operand" "")))
1721 (set (match_operand:QI 3 "pseudo_register_operand" "")
1722 (umod:QI (match_dup 1) (match_dup 2)))
1723 (clobber (reg:QI 22))
1724 (clobber (reg:QI 23))
1725 (clobber (reg:QI 24))
1726 (clobber (reg:QI 25))])]
1728 "this udivmodqi4 pattern should have been splitted;"
1730 [(set (reg:QI 24) (match_dup 1))
1731 (set (reg:QI 22) (match_dup 2))
1732 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1733 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1734 (clobber (reg:QI 23))])
1735 (set (match_dup 0) (reg:QI 24))
1736 (set (match_dup 3) (reg:QI 25))]
1739 (define_insn "*udivmodqi4_call"
1740 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1741 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1742 (clobber (reg:QI 23))]
1744 "%~call __udivmodqi4"
1745 [(set_attr "type" "xcall")
1746 (set_attr "cc" "clobber")])
1748 (define_insn_and_split "divmodhi4"
1749 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1750 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
1751 (match_operand:HI 2 "pseudo_register_operand" "")))
1752 (set (match_operand:HI 3 "pseudo_register_operand" "")
1753 (mod:HI (match_dup 1) (match_dup 2)))
1754 (clobber (reg:QI 21))
1755 (clobber (reg:HI 22))
1756 (clobber (reg:HI 24))
1757 (clobber (reg:HI 26))])]
1759 "this should have been splitted;"
1761 [(set (reg:HI 24) (match_dup 1))
1762 (set (reg:HI 22) (match_dup 2))
1763 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1764 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1765 (clobber (reg:HI 26))
1766 (clobber (reg:QI 21))])
1767 (set (match_dup 0) (reg:HI 22))
1768 (set (match_dup 3) (reg:HI 24))]
1771 (define_insn "*divmodhi4_call"
1772 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1773 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1774 (clobber (reg:HI 26))
1775 (clobber (reg:QI 21))]
1777 "%~call __divmodhi4"
1778 [(set_attr "type" "xcall")
1779 (set_attr "cc" "clobber")])
1781 (define_insn_and_split "udivmodhi4"
1782 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1783 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
1784 (match_operand:HI 2 "pseudo_register_operand" "")))
1785 (set (match_operand:HI 3 "pseudo_register_operand" "")
1786 (umod:HI (match_dup 1) (match_dup 2)))
1787 (clobber (reg:QI 21))
1788 (clobber (reg:HI 22))
1789 (clobber (reg:HI 24))
1790 (clobber (reg:HI 26))])]
1792 "this udivmodhi4 pattern should have been splitted.;"
1794 [(set (reg:HI 24) (match_dup 1))
1795 (set (reg:HI 22) (match_dup 2))
1796 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1797 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1798 (clobber (reg:HI 26))
1799 (clobber (reg:QI 21))])
1800 (set (match_dup 0) (reg:HI 22))
1801 (set (match_dup 3) (reg:HI 24))]
1804 (define_insn "*udivmodhi4_call"
1805 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1806 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1807 (clobber (reg:HI 26))
1808 (clobber (reg:QI 21))]
1810 "%~call __udivmodhi4"
1811 [(set_attr "type" "xcall")
1812 (set_attr "cc" "clobber")])
1814 (define_insn_and_split "divmodsi4"
1815 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1816 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
1817 (match_operand:SI 2 "pseudo_register_operand" "")))
1818 (set (match_operand:SI 3 "pseudo_register_operand" "")
1819 (mod:SI (match_dup 1) (match_dup 2)))
1820 (clobber (reg:SI 18))
1821 (clobber (reg:SI 22))
1822 (clobber (reg:HI 26))
1823 (clobber (reg:HI 30))])]
1825 "this divmodsi4 pattern should have been splitted;"
1827 [(set (reg:SI 22) (match_dup 1))
1828 (set (reg:SI 18) (match_dup 2))
1829 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1830 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1831 (clobber (reg:HI 26))
1832 (clobber (reg:HI 30))])
1833 (set (match_dup 0) (reg:SI 18))
1834 (set (match_dup 3) (reg:SI 22))]
1837 (define_insn "*divmodsi4_call"
1838 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1839 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1840 (clobber (reg:HI 26))
1841 (clobber (reg:HI 30))]
1843 "%~call __divmodsi4"
1844 [(set_attr "type" "xcall")
1845 (set_attr "cc" "clobber")])
1847 (define_insn_and_split "udivmodsi4"
1848 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1849 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
1850 (match_operand:SI 2 "pseudo_register_operand" "")))
1851 (set (match_operand:SI 3 "pseudo_register_operand" "")
1852 (umod:SI (match_dup 1) (match_dup 2)))
1853 (clobber (reg:SI 18))
1854 (clobber (reg:SI 22))
1855 (clobber (reg:HI 26))
1856 (clobber (reg:HI 30))])]
1858 "this udivmodsi4 pattern should have been splitted;"
1860 [(set (reg:SI 22) (match_dup 1))
1861 (set (reg:SI 18) (match_dup 2))
1862 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1863 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1864 (clobber (reg:HI 26))
1865 (clobber (reg:HI 30))])
1866 (set (match_dup 0) (reg:SI 18))
1867 (set (match_dup 3) (reg:SI 22))]
1870 (define_insn "*udivmodsi4_call"
1871 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1872 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1873 (clobber (reg:HI 26))
1874 (clobber (reg:HI 30))]
1876 "%~call __udivmodsi4"
1877 [(set_attr "type" "xcall")
1878 (set_attr "cc" "clobber")])
1880 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1883 (define_insn "andqi3"
1884 [(set (match_operand:QI 0 "register_operand" "=r,d")
1885 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1886 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1891 [(set_attr "length" "1,1")
1892 (set_attr "cc" "set_zn,set_zn")])
1894 (define_insn "andhi3"
1895 [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1896 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1897 (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1898 (clobber (match_scratch:QI 3 "=X,X,&d"))]
1901 if (which_alternative==0)
1902 return ("and %A0,%A2" CR_TAB
1904 else if (which_alternative==1)
1906 if (GET_CODE (operands[2]) == CONST_INT)
1908 int mask = INTVAL (operands[2]);
1909 if ((mask & 0xff) != 0xff)
1910 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1911 if ((mask & 0xff00) != 0xff00)
1912 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1915 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1916 AS2 (andi,%B0,hi8(%2)));
1918 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1922 [(set_attr "length" "2,2,3")
1923 (set_attr "cc" "set_n,clobber,set_n")])
1925 (define_insn "andsi3"
1926 [(set (match_operand:SI 0 "register_operand" "=r,d")
1927 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1928 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1931 if (which_alternative==0)
1932 return ("and %0,%2" CR_TAB
1933 "and %B0,%B2" CR_TAB
1934 "and %C0,%C2" CR_TAB
1936 else if (which_alternative==1)
1938 if (GET_CODE (operands[2]) == CONST_INT)
1940 HOST_WIDE_INT mask = INTVAL (operands[2]);
1941 if ((mask & 0xff) != 0xff)
1942 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1943 if ((mask & 0xff00) != 0xff00)
1944 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1945 if ((mask & 0xff0000L) != 0xff0000L)
1946 output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1947 if ((mask & 0xff000000L) != 0xff000000L)
1948 output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1951 return (AS2 (andi, %A0,lo8(%2)) CR_TAB
1952 AS2 (andi, %B0,hi8(%2)) CR_TAB
1953 AS2 (andi, %C0,hlo8(%2)) CR_TAB
1954 AS2 (andi, %D0,hhi8(%2)));
1958 [(set_attr "length" "4,4")
1959 (set_attr "cc" "set_n,clobber")])
1961 (define_peephole2 ; andi
1962 [(set (match_operand:QI 0 "d_register_operand" "")
1963 (and:QI (match_dup 0)
1964 (match_operand:QI 1 "const_int_operand" "")))
1966 (and:QI (match_dup 0)
1967 (match_operand:QI 2 "const_int_operand" "")))]
1969 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1971 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
1974 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1977 (define_insn "iorqi3"
1978 [(set (match_operand:QI 0 "register_operand" "=r,d")
1979 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1980 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1985 [(set_attr "length" "1,1")
1986 (set_attr "cc" "set_zn,set_zn")])
1988 (define_insn "iorhi3"
1989 [(set (match_operand:HI 0 "register_operand" "=r,d")
1990 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1991 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1994 if (which_alternative==0)
1995 return ("or %A0,%A2" CR_TAB
1997 if (GET_CODE (operands[2]) == CONST_INT)
1999 int mask = INTVAL (operands[2]);
2001 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2003 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2006 return (AS2 (ori,%0,lo8(%2)) CR_TAB
2007 AS2 (ori,%B0,hi8(%2)));
2009 [(set_attr "length" "2,2")
2010 (set_attr "cc" "set_n,clobber")])
2012 (define_insn "*iorhi3_clobber"
2013 [(set (match_operand:HI 0 "register_operand" "=r,r")
2014 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2015 (match_operand:HI 2 "immediate_operand" "M,i")))
2016 (clobber (match_scratch:QI 3 "=&d,&d"))]
2019 ldi %3,lo8(%2)\;or %A0,%3
2020 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
2021 [(set_attr "length" "2,4")
2022 (set_attr "cc" "clobber,set_n")])
2024 (define_insn "iorsi3"
2025 [(set (match_operand:SI 0 "register_operand" "=r,d")
2026 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2027 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
2030 if (which_alternative==0)
2031 return ("or %0,%2" CR_TAB
2035 if (GET_CODE (operands[2]) == CONST_INT)
2037 HOST_WIDE_INT mask = INTVAL (operands[2]);
2039 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2041 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2042 if (mask & 0xff0000L)
2043 output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
2044 if (mask & 0xff000000L)
2045 output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
2048 return (AS2 (ori, %A0,lo8(%2)) CR_TAB
2049 AS2 (ori, %B0,hi8(%2)) CR_TAB
2050 AS2 (ori, %C0,hlo8(%2)) CR_TAB
2051 AS2 (ori, %D0,hhi8(%2)));
2053 [(set_attr "length" "4,4")
2054 (set_attr "cc" "set_n,clobber")])
2056 (define_insn "*iorsi3_clobber"
2057 [(set (match_operand:SI 0 "register_operand" "=r,r")
2058 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2059 (match_operand:SI 2 "immediate_operand" "M,i")))
2060 (clobber (match_scratch:QI 3 "=&d,&d"))]
2063 ldi %3,lo8(%2)\;or %A0,%3
2064 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"
2065 [(set_attr "length" "2,8")
2066 (set_attr "cc" "clobber,set_n")])
2068 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2071 (define_insn "xorqi3"
2072 [(set (match_operand:QI 0 "register_operand" "=r")
2073 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2074 (match_operand:QI 2 "register_operand" "r")))]
2077 [(set_attr "length" "1")
2078 (set_attr "cc" "set_zn")])
2080 (define_insn "xorhi3"
2081 [(set (match_operand:HI 0 "register_operand" "=r")
2082 (xor:HI (match_operand:HI 1 "register_operand" "%0")
2083 (match_operand:HI 2 "register_operand" "r")))]
2087 [(set_attr "length" "2")
2088 (set_attr "cc" "set_n")])
2090 (define_insn "xorsi3"
2091 [(set (match_operand:SI 0 "register_operand" "=r")
2092 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2093 (match_operand:SI 2 "register_operand" "r")))]
2099 [(set_attr "length" "4")
2100 (set_attr "cc" "set_n")])
2102 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
2105 (define_expand "rotlqi3"
2106 [(set (match_operand:QI 0 "register_operand" "")
2107 (rotate:QI (match_operand:QI 1 "register_operand" "")
2108 (match_operand:QI 2 "const_int_operand" "")))]
2112 if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
2116 (define_insn "rotlqi3_4"
2117 [(set (match_operand:QI 0 "register_operand" "=r")
2118 (rotate:QI (match_operand:QI 1 "register_operand" "0")
2122 [(set_attr "length" "1")
2123 (set_attr "cc" "none")])
2125 ;; Split all rotates of HI,SI and DImode registers where rotation is by
2126 ;; a whole number of bytes. The split creates the appropriate moves and
2127 ;; considers all overlap situations. DImode is split before reload.
2129 ;; HImode does not need scratch. Use attribute for this constraint.
2130 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
2132 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
2133 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
2135 (define_expand "rotl<mode>3"
2136 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
2137 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2138 (match_operand:VOID 2 "const_int_operand" "")))
2139 (clobber (match_dup 3))])]
2142 if (CONST_INT_P (operands[2])
2143 && 0 == INTVAL (operands[2]) % 8)
2145 if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
2146 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2148 operands[3] = gen_rtx_SCRATCH (QImode);
2155 ;; Overlapping non-HImode registers often (but not always) need a scratch.
2156 ;; The best we can do is use early clobber alternative "#&r" so that
2157 ;; completely non-overlapping operands dont get a scratch but # so register
2158 ;; allocation does not prefer non-overlapping.
2161 ; Split word aligned rotates using scratch that is mode dependent.
2162 (define_insn_and_split "*rotw<mode>"
2163 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2164 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2165 (match_operand 2 "const_int_operand" "n,n,n")))
2166 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2168 && CONST_INT_P (operands[2])
2169 && 0 == INTVAL (operands[2]) % 16"
2171 "&& (reload_completed || <MODE>mode == DImode)"
2174 avr_rotate_bytes (operands);
2179 ; Split byte aligned rotates using scratch that is always QI mode.
2180 (define_insn_and_split "*rotb<mode>"
2181 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2182 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2183 (match_operand 2 "const_int_operand" "n,n,n")))
2184 (clobber (match_scratch:QI 3 "=<rotx>"))]
2185 "CONST_INT_P (operands[2])
2186 && (8 == INTVAL (operands[2]) % 16
2188 && 0 == INTVAL (operands[2]) % 16))"
2190 "&& (reload_completed || <MODE>mode == DImode)"
2193 avr_rotate_bytes (operands);
2198 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2199 ;; arithmetic shift left
2201 (define_expand "ashlqi3"
2202 [(set (match_operand:QI 0 "register_operand" "")
2203 (ashift:QI (match_operand:QI 1 "register_operand" "")
2204 (match_operand:QI 2 "general_operand" "")))]
2208 (define_split ; ashlqi3_const4
2209 [(set (match_operand:QI 0 "d_register_operand" "")
2210 (ashift:QI (match_dup 0)
2213 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2214 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2217 (define_split ; ashlqi3_const5
2218 [(set (match_operand:QI 0 "d_register_operand" "")
2219 (ashift:QI (match_dup 0)
2222 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2223 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2224 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2227 (define_split ; ashlqi3_const6
2228 [(set (match_operand:QI 0 "d_register_operand" "")
2229 (ashift:QI (match_dup 0)
2232 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2233 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2234 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2237 (define_insn "*ashlqi3"
2238 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2239 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2240 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2242 "* return ashlqi3_out (insn, operands, NULL);"
2243 [(set_attr "length" "5,0,1,2,4,6,9")
2244 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2246 (define_insn "ashlhi3"
2247 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2248 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2249 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2251 "* return ashlhi3_out (insn, operands, NULL);"
2252 [(set_attr "length" "6,0,2,2,4,10,10")
2253 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2255 (define_insn "ashlsi3"
2256 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2257 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2258 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2260 "* return ashlsi3_out (insn, operands, NULL);"
2261 [(set_attr "length" "8,0,4,4,8,10,12")
2262 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2264 ;; Optimize if a scratch register from LD_REGS happens to be available.
2266 (define_peephole2 ; ashlqi3_l_const4
2267 [(set (match_operand:QI 0 "l_register_operand" "")
2268 (ashift:QI (match_dup 0)
2270 (match_scratch:QI 1 "d")]
2272 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2273 (set (match_dup 1) (const_int -16))
2274 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2277 (define_peephole2 ; ashlqi3_l_const5
2278 [(set (match_operand:QI 0 "l_register_operand" "")
2279 (ashift:QI (match_dup 0)
2281 (match_scratch:QI 1 "d")]
2283 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2284 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2285 (set (match_dup 1) (const_int -32))
2286 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2289 (define_peephole2 ; ashlqi3_l_const6
2290 [(set (match_operand:QI 0 "l_register_operand" "")
2291 (ashift:QI (match_dup 0)
2293 (match_scratch:QI 1 "d")]
2295 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2296 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2297 (set (match_dup 1) (const_int -64))
2298 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2302 [(match_scratch:QI 3 "d")
2303 (set (match_operand:HI 0 "register_operand" "")
2304 (ashift:HI (match_operand:HI 1 "register_operand" "")
2305 (match_operand:QI 2 "const_int_operand" "")))]
2307 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
2308 (clobber (match_dup 3))])]
2311 (define_insn "*ashlhi3_const"
2312 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2313 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2314 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2315 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2317 "* return ashlhi3_out (insn, operands, NULL);"
2318 [(set_attr "length" "0,2,2,4,10")
2319 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
2322 [(match_scratch:QI 3 "d")
2323 (set (match_operand:SI 0 "register_operand" "")
2324 (ashift:SI (match_operand:SI 1 "register_operand" "")
2325 (match_operand:QI 2 "const_int_operand" "")))]
2327 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2328 (clobber (match_dup 3))])]
2331 (define_insn "*ashlsi3_const"
2332 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2333 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2334 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2335 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2337 "* return ashlsi3_out (insn, operands, NULL);"
2338 [(set_attr "length" "0,4,4,10")
2339 (set_attr "cc" "none,set_n,clobber,clobber")])
2341 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2342 ;; arithmetic shift right
2344 (define_insn "ashrqi3"
2345 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
2346 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
2347 (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))]
2349 "* return ashrqi3_out (insn, operands, NULL);"
2350 [(set_attr "length" "5,0,1,2,5,9")
2351 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
2353 (define_insn "ashrhi3"
2354 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2355 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2356 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2358 "* return ashrhi3_out (insn, operands, NULL);"
2359 [(set_attr "length" "6,0,2,4,4,10,10")
2360 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2362 (define_insn "ashrsi3"
2363 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2364 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2365 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2367 "* return ashrsi3_out (insn, operands, NULL);"
2368 [(set_attr "length" "8,0,4,6,8,10,12")
2369 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2371 ;; Optimize if a scratch register from LD_REGS happens to be available.
2374 [(match_scratch:QI 3 "d")
2375 (set (match_operand:HI 0 "register_operand" "")
2376 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2377 (match_operand:QI 2 "const_int_operand" "")))]
2379 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
2380 (clobber (match_dup 3))])]
2383 (define_insn "*ashrhi3_const"
2384 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2385 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2386 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2387 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2389 "* return ashrhi3_out (insn, operands, NULL);"
2390 [(set_attr "length" "0,2,4,4,10")
2391 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
2394 [(match_scratch:QI 3 "d")
2395 (set (match_operand:SI 0 "register_operand" "")
2396 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2397 (match_operand:QI 2 "const_int_operand" "")))]
2399 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2400 (clobber (match_dup 3))])]
2403 (define_insn "*ashrsi3_const"
2404 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2405 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2406 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2407 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2409 "* return ashrsi3_out (insn, operands, NULL);"
2410 [(set_attr "length" "0,4,4,10")
2411 (set_attr "cc" "none,clobber,set_n,clobber")])
2413 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2414 ;; logical shift right
2416 (define_expand "lshrqi3"
2417 [(set (match_operand:QI 0 "register_operand" "")
2418 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2419 (match_operand:QI 2 "general_operand" "")))]
2423 (define_split ; lshrqi3_const4
2424 [(set (match_operand:QI 0 "d_register_operand" "")
2425 (lshiftrt:QI (match_dup 0)
2428 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2429 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
2432 (define_split ; lshrqi3_const5
2433 [(set (match_operand:QI 0 "d_register_operand" "")
2434 (lshiftrt:QI (match_dup 0)
2437 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2438 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2439 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
2442 (define_split ; lshrqi3_const6
2443 [(set (match_operand:QI 0 "d_register_operand" "")
2444 (lshiftrt:QI (match_dup 0)
2447 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2448 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2449 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
2452 (define_insn "*lshrqi3"
2453 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2454 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2455 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2457 "* return lshrqi3_out (insn, operands, NULL);"
2458 [(set_attr "length" "5,0,1,2,4,6,9")
2459 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2461 (define_insn "lshrhi3"
2462 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2463 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2464 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2466 "* return lshrhi3_out (insn, operands, NULL);"
2467 [(set_attr "length" "6,0,2,2,4,10,10")
2468 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2470 (define_insn "lshrsi3"
2471 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2472 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2473 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2475 "* return lshrsi3_out (insn, operands, NULL);"
2476 [(set_attr "length" "8,0,4,4,8,10,12")
2477 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2479 ;; Optimize if a scratch register from LD_REGS happens to be available.
2481 (define_peephole2 ; lshrqi3_l_const4
2482 [(set (match_operand:QI 0 "l_register_operand" "")
2483 (lshiftrt:QI (match_dup 0)
2485 (match_scratch:QI 1 "d")]
2487 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2488 (set (match_dup 1) (const_int 15))
2489 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2492 (define_peephole2 ; lshrqi3_l_const5
2493 [(set (match_operand:QI 0 "l_register_operand" "")
2494 (lshiftrt:QI (match_dup 0)
2496 (match_scratch:QI 1 "d")]
2498 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2499 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2500 (set (match_dup 1) (const_int 7))
2501 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2504 (define_peephole2 ; lshrqi3_l_const6
2505 [(set (match_operand:QI 0 "l_register_operand" "")
2506 (lshiftrt:QI (match_dup 0)
2508 (match_scratch:QI 1 "d")]
2510 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2511 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2512 (set (match_dup 1) (const_int 3))
2513 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2517 [(match_scratch:QI 3 "d")
2518 (set (match_operand:HI 0 "register_operand" "")
2519 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2520 (match_operand:QI 2 "const_int_operand" "")))]
2522 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
2523 (clobber (match_dup 3))])]
2526 (define_insn "*lshrhi3_const"
2527 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2528 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2529 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2530 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2532 "* return lshrhi3_out (insn, operands, NULL);"
2533 [(set_attr "length" "0,2,2,4,10")
2534 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
2537 [(match_scratch:QI 3 "d")
2538 (set (match_operand:SI 0 "register_operand" "")
2539 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2540 (match_operand:QI 2 "const_int_operand" "")))]
2542 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2543 (clobber (match_dup 3))])]
2546 (define_insn "*lshrsi3_const"
2547 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2548 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2549 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2550 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2552 "* return lshrsi3_out (insn, operands, NULL);"
2553 [(set_attr "length" "0,4,4,10")
2554 (set_attr "cc" "none,clobber,clobber,clobber")])
2556 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2559 (define_insn "absqi2"
2560 [(set (match_operand:QI 0 "register_operand" "=r")
2561 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2565 [(set_attr "length" "2")
2566 (set_attr "cc" "clobber")])
2569 (define_insn "abssf2"
2570 [(set (match_operand:SF 0 "register_operand" "=d,r")
2571 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
2576 [(set_attr "length" "1,2")
2577 (set_attr "cc" "set_n,clobber")])
2579 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
2582 (define_insn "negqi2"
2583 [(set (match_operand:QI 0 "register_operand" "=r")
2584 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
2587 [(set_attr "length" "1")
2588 (set_attr "cc" "set_zn")])
2590 (define_insn "neghi2"
2591 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
2592 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
2595 com %B0\;neg %A0\;sbci %B0,lo8(-1)
2596 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
2597 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
2598 [(set_attr "length" "3,4,4")
2599 (set_attr "cc" "set_czn,set_n,set_czn")])
2601 (define_insn "negsi2"
2602 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
2603 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
2606 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
2607 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
2608 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
2609 [(set_attr_alternative "length"
2612 (if_then_else (eq_attr "mcu_have_movw" "yes")
2615 (set_attr "cc" "set_czn,set_n,set_czn")])
2617 (define_insn "negsf2"
2618 [(set (match_operand:SF 0 "register_operand" "=d,r")
2619 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
2623 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
2624 [(set_attr "length" "1,4")
2625 (set_attr "cc" "set_n,set_n")])
2627 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2630 (define_insn "one_cmplqi2"
2631 [(set (match_operand:QI 0 "register_operand" "=r")
2632 (not:QI (match_operand:QI 1 "register_operand" "0")))]
2635 [(set_attr "length" "1")
2636 (set_attr "cc" "set_czn")])
2638 (define_insn "one_cmplhi2"
2639 [(set (match_operand:HI 0 "register_operand" "=r")
2640 (not:HI (match_operand:HI 1 "register_operand" "0")))]
2644 [(set_attr "length" "2")
2645 (set_attr "cc" "set_n")])
2647 (define_insn "one_cmplsi2"
2648 [(set (match_operand:SI 0 "register_operand" "=r")
2649 (not:SI (match_operand:SI 1 "register_operand" "0")))]
2655 [(set_attr "length" "4")
2656 (set_attr "cc" "set_n")])
2658 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2661 ;; We keep combiner from inserting hard registers into the input of sign- and
2662 ;; zero-extends. A hard register in the input operand is not wanted because
2663 ;; 32-bit multiply patterns clobber some hard registers and extends with a
2664 ;; hard register that overlaps these clobbers won't be combined to a widening
2665 ;; multiplication. There is no need for combine to propagate hard registers,
2666 ;; register allocation can do it just as well.
2668 (define_insn "extendqihi2"
2669 [(set (match_operand:HI 0 "register_operand" "=r,r")
2670 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2673 clr %B0\;sbrc %0,7\;com %B0
2674 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
2675 [(set_attr "length" "3,4")
2676 (set_attr "cc" "set_n,set_n")])
2678 (define_insn "extendqisi2"
2679 [(set (match_operand:SI 0 "register_operand" "=r,r")
2680 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2683 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
2684 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
2685 [(set_attr "length" "5,6")
2686 (set_attr "cc" "set_n,set_n")])
2688 (define_insn "extendhisi2"
2689 [(set (match_operand:SI 0 "register_operand" "=r,r")
2690 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
2693 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
2694 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
2695 [(set_attr_alternative "length"
2697 (if_then_else (eq_attr "mcu_have_movw" "yes")
2700 (set_attr "cc" "set_n,set_n")])
2702 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2705 (define_insn_and_split "zero_extendqihi2"
2706 [(set (match_operand:HI 0 "register_operand" "=r")
2707 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2711 [(set (match_dup 2) (match_dup 1))
2712 (set (match_dup 3) (const_int 0))]
2714 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
2715 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
2717 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
2718 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
2721 (define_insn_and_split "zero_extendqisi2"
2722 [(set (match_operand:SI 0 "register_operand" "=r")
2723 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2727 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
2728 (set (match_dup 3) (const_int 0))]
2730 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2731 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2733 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2734 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2737 (define_insn_and_split "zero_extendhisi2"
2738 [(set (match_operand:SI 0 "register_operand" "=r")
2739 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
2743 [(set (match_dup 2) (match_dup 1))
2744 (set (match_dup 3) (const_int 0))]
2746 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2747 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2749 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2750 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2753 (define_insn_and_split "zero_extendqidi2"
2754 [(set (match_operand:DI 0 "register_operand" "=r")
2755 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2759 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2760 (set (match_dup 3) (const_int 0))]
2762 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2763 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2765 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2766 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2769 (define_insn_and_split "zero_extendhidi2"
2770 [(set (match_operand:DI 0 "register_operand" "=r")
2771 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2775 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2776 (set (match_dup 3) (const_int 0))]
2778 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2779 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2781 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2782 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2785 (define_insn_and_split "zero_extendsidi2"
2786 [(set (match_operand:DI 0 "register_operand" "=r")
2787 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2791 [(set (match_dup 2) (match_dup 1))
2792 (set (match_dup 3) (const_int 0))]
2794 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2795 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2797 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2798 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2801 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
2804 ; Optimize negated tests into reverse compare if overflow is undefined.
2805 (define_insn "*negated_tstqi"
2807 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
2809 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2810 "cp __zero_reg__,%0"
2811 [(set_attr "cc" "compare")
2812 (set_attr "length" "1")])
2814 (define_insn "*reversed_tstqi"
2816 (compare (const_int 0)
2817 (match_operand:QI 0 "register_operand" "r")))]
2819 "cp __zero_reg__,%0"
2820 [(set_attr "cc" "compare")
2821 (set_attr "length" "2")])
2823 (define_insn "*negated_tsthi"
2825 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
2827 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2828 "cp __zero_reg__,%A0
2829 cpc __zero_reg__,%B0"
2830 [(set_attr "cc" "compare")
2831 (set_attr "length" "2")])
2833 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
2834 ;; though it is unused, because this pattern is synthesized by avr_reorg.
2835 (define_insn "*reversed_tsthi"
2837 (compare (const_int 0)
2838 (match_operand:HI 0 "register_operand" "r")))
2839 (clobber (match_scratch:QI 1 "=X"))]
2841 "cp __zero_reg__,%A0
2842 cpc __zero_reg__,%B0"
2843 [(set_attr "cc" "compare")
2844 (set_attr "length" "2")])
2846 (define_insn "*negated_tstsi"
2848 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
2850 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2851 "cp __zero_reg__,%A0
2852 cpc __zero_reg__,%B0
2853 cpc __zero_reg__,%C0
2854 cpc __zero_reg__,%D0"
2855 [(set_attr "cc" "compare")
2856 (set_attr "length" "4")])
2858 (define_insn "*reversed_tstsi"
2860 (compare (const_int 0)
2861 (match_operand:SI 0 "register_operand" "r")))
2862 (clobber (match_scratch:QI 1 "=X"))]
2864 "cp __zero_reg__,%A0
2865 cpc __zero_reg__,%B0
2866 cpc __zero_reg__,%C0
2867 cpc __zero_reg__,%D0"
2868 [(set_attr "cc" "compare")
2869 (set_attr "length" "4")])
2872 (define_insn "*cmpqi"
2874 (compare (match_operand:QI 0 "register_operand" "r,r,d")
2875 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
2881 [(set_attr "cc" "compare,compare,compare")
2882 (set_attr "length" "1,1,1")])
2884 (define_insn "*cmpqi_sign_extend"
2886 (compare (sign_extend:HI
2887 (match_operand:QI 0 "register_operand" "d"))
2888 (match_operand:HI 1 "const_int_operand" "n")))]
2889 "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
2891 [(set_attr "cc" "compare")
2892 (set_attr "length" "1")])
2894 (define_insn "*cmphi"
2896 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d,d,r,r")
2897 (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
2898 (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
2901 switch (which_alternative)
2904 return out_tsthi (insn, operands[0], NULL);
2907 return (AS2 (cp,%A0,%A1) CR_TAB
2910 if (reg_unused_after (insn, operands[0])
2911 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2912 && test_hard_reg_class (ADDW_REGS, operands[0]))
2913 return AS2 (sbiw,%0,%1);
2915 return (AS2 (cpi,%0,%1) CR_TAB
2916 AS2 (cpc,%B0,__zero_reg__));
2918 if (reg_unused_after (insn, operands[0]))
2919 return (AS2 (subi,%0,lo8(%1)) CR_TAB
2920 AS2 (sbci,%B0,hi8(%1)));
2922 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
2923 AS2 (cpi, %A0,lo8(%1)) CR_TAB
2926 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
2927 AS2 (cp, %A0,%2) CR_TAB
2928 AS2 (cpc, %B0,__zero_reg__));
2931 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
2932 AS2 (cp, %A0,%2) CR_TAB
2933 AS2 (ldi, %2,hi8(%1)) CR_TAB
2938 [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
2939 (set_attr "length" "1,2,2,2,3,3,4")])
2942 (define_insn "*cmpsi"
2944 (compare (match_operand:SI 0 "register_operand" "r,r,d,d,r,r")
2945 (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
2946 (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
2949 switch (which_alternative)
2952 return out_tstsi (insn, operands[0], NULL);
2955 return (AS2 (cp,%A0,%A1) CR_TAB
2956 AS2 (cpc,%B0,%B1) CR_TAB
2957 AS2 (cpc,%C0,%C1) CR_TAB
2960 if (reg_unused_after (insn, operands[0])
2961 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2962 && test_hard_reg_class (ADDW_REGS, operands[0]))
2963 return (AS2 (sbiw,%0,%1) CR_TAB
2964 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2965 AS2 (cpc,%D0,__zero_reg__));
2967 return (AS2 (cpi,%A0,lo8(%1)) CR_TAB
2968 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2969 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2970 AS2 (cpc,%D0,__zero_reg__));
2972 if (reg_unused_after (insn, operands[0]))
2973 return (AS2 (subi,%A0,lo8(%1)) CR_TAB
2974 AS2 (sbci,%B0,hi8(%1)) CR_TAB
2975 AS2 (sbci,%C0,hlo8(%1)) CR_TAB
2976 AS2 (sbci,%D0,hhi8(%1)));
2978 return (AS2 (cpi, %A0,lo8(%1)) CR_TAB
2979 AS2 (ldi, %2,hi8(%1)) CR_TAB
2980 AS2 (cpc, %B0,%2) CR_TAB
2981 AS2 (ldi, %2,hlo8(%1)) CR_TAB
2982 AS2 (cpc, %C0,%2) CR_TAB
2983 AS2 (ldi, %2,hhi8(%1)) CR_TAB
2986 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
2987 AS2 (cp,%A0,%2) CR_TAB
2988 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2989 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2990 AS2 (cpc,%D0,__zero_reg__));
2992 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
2993 AS2 (cp, %A0,%2) CR_TAB
2994 AS2 (ldi, %2,hi8(%1)) CR_TAB
2995 AS2 (cpc, %B0,%2) CR_TAB
2996 AS2 (ldi, %2,hlo8(%1)) CR_TAB
2997 AS2 (cpc, %C0,%2) CR_TAB
2998 AS2 (ldi, %2,hhi8(%1)) CR_TAB
3003 [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
3004 (set_attr "length" "4,4,4,7,5,8")])
3007 ;; ----------------------------------------------------------------------
3008 ;; JUMP INSTRUCTIONS
3009 ;; ----------------------------------------------------------------------
3010 ;; Conditional jump instructions
3012 (define_expand "cbranchsi4"
3013 [(parallel [(set (cc0)
3014 (compare (match_operand:SI 1 "register_operand" "")
3015 (match_operand:SI 2 "nonmemory_operand" "")))
3016 (clobber (match_scratch:QI 4 ""))])
3019 (match_operator 0 "ordered_comparison_operator" [(cc0)
3021 (label_ref (match_operand 3 "" ""))
3025 (define_expand "cbranchhi4"
3026 [(parallel [(set (cc0)
3027 (compare (match_operand:HI 1 "register_operand" "")
3028 (match_operand:HI 2 "nonmemory_operand" "")))
3029 (clobber (match_scratch:QI 4 ""))])
3032 (match_operator 0 "ordered_comparison_operator" [(cc0)
3034 (label_ref (match_operand 3 "" ""))
3038 (define_expand "cbranchqi4"
3040 (compare (match_operand:QI 1 "register_operand" "")
3041 (match_operand:QI 2 "nonmemory_operand" "")))
3044 (match_operator 0 "ordered_comparison_operator" [(cc0)
3046 (label_ref (match_operand 3 "" ""))
3051 ;; Test a single bit in a QI/HI/SImode register.
3052 ;; Combine will create zero extract patterns for single bit tests.
3053 ;; permit any mode in source pattern by using VOIDmode.
3055 (define_insn "*sbrx_branch<mode>"
3058 (match_operator 0 "eqne_operator"
3060 (match_operand:VOID 1 "register_operand" "r")
3062 (match_operand 2 "const_int_operand" "n"))
3064 (label_ref (match_operand 3 "" ""))
3067 "* return avr_out_sbxx_branch (insn, operands);"
3068 [(set (attr "length")
3069 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3070 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3072 (if_then_else (eq_attr "mcu_mega" "no")
3075 (set_attr "cc" "clobber")])
3077 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
3078 ;; or for old peepholes.
3079 ;; Fixme - bitwise Mask will not work for DImode
3081 (define_insn "*sbrx_and_branch<mode>"
3084 (match_operator 0 "eqne_operator"
3086 (match_operand:QISI 1 "register_operand" "r")
3087 (match_operand:QISI 2 "single_one_operand" "n"))
3089 (label_ref (match_operand 3 "" ""))
3093 HOST_WIDE_INT bitnumber;
3094 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
3095 operands[2] = GEN_INT (bitnumber);
3096 return avr_out_sbxx_branch (insn, operands);
3098 [(set (attr "length")
3099 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3100 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3102 (if_then_else (eq_attr "mcu_mega" "no")
3105 (set_attr "cc" "clobber")])
3107 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
3109 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3111 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3112 (label_ref (match_operand 1 "" ""))
3115 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
3119 (label_ref (match_dup 1))
3124 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3126 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3127 (label_ref (match_operand 1 "" ""))
3130 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
3134 (label_ref (match_dup 1))
3139 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3141 (clobber (match_operand:HI 2 ""))])
3142 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3143 (label_ref (match_operand 1 "" ""))
3146 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
3148 (label_ref (match_dup 1))
3153 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3155 (clobber (match_operand:HI 2 ""))])
3156 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3157 (label_ref (match_operand 1 "" ""))
3160 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
3162 (label_ref (match_dup 1))
3167 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3169 (clobber (match_operand:SI 2 ""))])
3170 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3171 (label_ref (match_operand 1 "" ""))
3174 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
3176 (label_ref (match_dup 1))
3178 "operands[2] = GEN_INT (-2147483647 - 1);")
3181 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3183 (clobber (match_operand:SI 2 ""))])
3184 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3185 (label_ref (match_operand 1 "" ""))
3188 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
3190 (label_ref (match_dup 1))
3192 "operands[2] = GEN_INT (-2147483647 - 1);")
3194 ;; ************************************************************************
3195 ;; Implementation of conditional jumps here.
3196 ;; Compare with 0 (test) jumps
3197 ;; ************************************************************************
3199 (define_insn "branch"
3201 (if_then_else (match_operator 1 "simple_comparison_operator"
3204 (label_ref (match_operand 0 "" ""))
3208 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3209 [(set_attr "type" "branch")
3210 (set_attr "cc" "clobber")])
3212 ;; ****************************************************************
3213 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
3214 ;; Convert them all to proper jumps.
3215 ;; ****************************************************************/
3217 (define_insn "difficult_branch"
3219 (if_then_else (match_operator 1 "difficult_comparison_operator"
3222 (label_ref (match_operand 0 "" ""))
3226 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3227 [(set_attr "type" "branch1")
3228 (set_attr "cc" "clobber")])
3232 (define_insn "rvbranch"
3234 (if_then_else (match_operator 1 "simple_comparison_operator"
3238 (label_ref (match_operand 0 "" ""))))]
3241 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3242 [(set_attr "type" "branch1")
3243 (set_attr "cc" "clobber")])
3245 (define_insn "difficult_rvbranch"
3247 (if_then_else (match_operator 1 "difficult_comparison_operator"
3251 (label_ref (match_operand 0 "" ""))))]
3254 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3255 [(set_attr "type" "branch")
3256 (set_attr "cc" "clobber")])
3258 ;; **************************************************************************
3259 ;; Unconditional and other jump instructions.
3263 (label_ref (match_operand 0 "" "")))]
3266 if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
3267 return AS1 (jmp,%x0);
3268 return AS1 (rjmp,%x0);
3270 [(set (attr "length")
3271 (if_then_else (match_operand 0 "symbol_ref_operand" "")
3272 (if_then_else (eq_attr "mcu_mega" "no")
3275 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
3276 (le (minus (pc) (match_dup 0)) (const_int 2047)))
3279 (set_attr "cc" "none")])
3283 (define_expand "call"
3284 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3285 (match_operand:HI 1 "general_operand" ""))
3286 (use (const_int 0))])]
3287 ;; Operand 1 not used on the AVR.
3288 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3292 (define_expand "sibcall"
3293 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3294 (match_operand:HI 1 "general_operand" ""))
3295 (use (const_int 1))])]
3296 ;; Operand 1 not used on the AVR.
3297 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3303 (define_expand "call_value"
3304 [(parallel[(set (match_operand 0 "register_operand" "")
3305 (call (match_operand:HI 1 "call_insn_operand" "")
3306 (match_operand:HI 2 "general_operand" "")))
3307 (use (const_int 0))])]
3308 ;; Operand 2 not used on the AVR.
3309 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3313 (define_expand "sibcall_value"
3314 [(parallel[(set (match_operand 0 "register_operand" "")
3315 (call (match_operand:HI 1 "call_insn_operand" "")
3316 (match_operand:HI 2 "general_operand" "")))
3317 (use (const_int 1))])]
3318 ;; Operand 2 not used on the AVR.
3319 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3323 (define_insn "*call_insn"
3324 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
3325 (match_operand:HI 1 "general_operand" "X,X,X,X"))
3326 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
3327 ;; Operand 1 not used on the AVR.
3328 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3335 [(set_attr "cc" "clobber")
3336 (set_attr_alternative "length"
3338 (if_then_else (eq_attr "mcu_mega" "yes")
3342 (if_then_else (eq_attr "mcu_mega" "yes")
3346 (define_insn "*call_value_insn"
3347 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
3348 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
3349 (match_operand:HI 2 "general_operand" "X,X,X,X")))
3350 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
3351 ;; Operand 2 not used on the AVR.
3352 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3359 [(set_attr "cc" "clobber")
3360 (set_attr_alternative "length"
3362 (if_then_else (eq_attr "mcu_mega" "yes")
3366 (if_then_else (eq_attr "mcu_mega" "yes")
3374 [(set_attr "cc" "none")
3375 (set_attr "length" "1")])
3379 (define_expand "indirect_jump"
3380 [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
3382 " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
3384 operands[0] = copy_to_mode_reg(HImode, operand0);
3389 (define_insn "*jcindirect_jump"
3390 [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
3393 [(set_attr "length" "2")
3394 (set_attr "cc" "none")])
3397 (define_insn "*njcindirect_jump"
3398 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
3399 "!AVR_HAVE_EIJMP_EICALL"
3402 push %A0\;push %B0\;ret"
3403 [(set_attr "length" "1,3")
3404 (set_attr "cc" "none,none")])
3406 (define_insn "*indirect_jump_avr6"
3407 [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
3408 "AVR_HAVE_EIJMP_EICALL"
3410 [(set_attr "length" "1")
3411 (set_attr "cc" "none")])
3415 ;; Table made from "rjmp" instructions for <=8K devices.
3416 (define_insn "*tablejump_rjmp"
3417 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
3419 (use (label_ref (match_operand 1 "" "")))
3420 (clobber (match_dup 0))]
3421 "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
3424 push %A0\;push %B0\;ret"
3425 [(set_attr "length" "1,3")
3426 (set_attr "cc" "none,none")])
3428 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
3429 (define_insn "*tablejump_lib"
3430 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3432 (use (label_ref (match_operand 1 "" "")))
3433 (clobber (match_dup 0))]
3434 "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
3435 "%~jmp __tablejump2__"
3436 [(set_attr "length" "2")
3437 (set_attr "cc" "clobber")])
3439 (define_insn "*tablejump_enh"
3440 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3442 (use (label_ref (match_operand 1 "" "")))
3443 (clobber (match_dup 0))]
3444 "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
3451 [(set_attr "length" "6")
3452 (set_attr "cc" "clobber")])
3454 (define_insn "*tablejump"
3455 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3457 (use (label_ref (match_operand 1 "" "")))
3458 (clobber (match_dup 0))]
3459 "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
3468 [(set_attr "length" "8")
3469 (set_attr "cc" "clobber")])
3471 (define_expand "casesi"
3473 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
3474 (match_operand:HI 1 "register_operand" "")))
3475 (parallel [(set (cc0)
3476 (compare (match_dup 6)
3477 (match_operand:HI 2 "register_operand" "")))
3478 (clobber (match_scratch:QI 9 ""))])
3481 (if_then_else (gtu (cc0)
3483 (label_ref (match_operand 4 "" ""))
3487 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
3489 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
3490 (use (label_ref (match_dup 3)))
3491 (clobber (match_dup 6))])]
3495 operands[6] = gen_reg_rtx (HImode);
3499 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3500 ;; This instruction sets Z flag
3503 [(set (cc0) (const_int 0))]
3506 [(set_attr "length" "1")
3507 (set_attr "cc" "compare")])
3509 ;; Clear/set/test a single bit in I/O address space.
3512 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3513 (and:QI (mem:QI (match_dup 0))
3514 (match_operand:QI 1 "single_zero_operand" "n")))]
3517 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
3518 return AS2 (cbi,%m0-0x20,%2);
3520 [(set_attr "length" "1")
3521 (set_attr "cc" "none")])
3524 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3525 (ior:QI (mem:QI (match_dup 0))
3526 (match_operand:QI 1 "single_one_operand" "n")))]
3529 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
3530 return AS2 (sbi,%m0-0x20,%2);
3532 [(set_attr "length" "1")
3533 (set_attr "cc" "none")])
3535 ;; Lower half of the I/O space - use sbic/sbis directly.
3536 (define_insn "*sbix_branch"
3539 (match_operator 0 "eqne_operator"
3541 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
3543 (match_operand 2 "const_int_operand" "n"))
3545 (label_ref (match_operand 3 "" ""))
3548 "* return avr_out_sbxx_branch (insn, operands);"
3549 [(set (attr "length")
3550 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3551 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3553 (if_then_else (eq_attr "mcu_mega" "no")
3556 (set_attr "cc" "clobber")])
3558 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
3559 (define_insn "*sbix_branch_bit7"
3562 (match_operator 0 "gelt_operator"
3563 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
3565 (label_ref (match_operand 2 "" ""))
3569 operands[3] = operands[2];
3570 operands[2] = GEN_INT (7);
3571 return avr_out_sbxx_branch (insn, operands);
3573 [(set (attr "length")
3574 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3575 (le (minus (pc) (match_dup 2)) (const_int 2046)))
3577 (if_then_else (eq_attr "mcu_mega" "no")
3580 (set_attr "cc" "clobber")])
3582 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
3583 (define_insn "*sbix_branch_tmp"
3586 (match_operator 0 "eqne_operator"
3588 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
3590 (match_operand 2 "const_int_operand" "n"))
3592 (label_ref (match_operand 3 "" ""))
3595 "* return avr_out_sbxx_branch (insn, operands);"
3596 [(set (attr "length")
3597 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3598 (le (minus (pc) (match_dup 3)) (const_int 2045)))
3600 (if_then_else (eq_attr "mcu_mega" "no")
3603 (set_attr "cc" "clobber")])
3605 (define_insn "*sbix_branch_tmp_bit7"
3608 (match_operator 0 "gelt_operator"
3609 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
3611 (label_ref (match_operand 2 "" ""))
3615 operands[3] = operands[2];
3616 operands[2] = GEN_INT (7);
3617 return avr_out_sbxx_branch (insn, operands);
3619 [(set (attr "length")
3620 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3621 (le (minus (pc) (match_dup 2)) (const_int 2045)))
3623 (if_then_else (eq_attr "mcu_mega" "no")
3626 (set_attr "cc" "clobber")])
3628 ;; ************************* Peepholes ********************************
3631 [(set (match_operand:SI 0 "d_register_operand" "")
3632 (plus:SI (match_dup 0)
3636 (compare (match_dup 0)
3638 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3640 (if_then_else (ne (cc0) (const_int 0))
3641 (label_ref (match_operand 2 "" ""))
3647 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3648 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3649 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3650 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3652 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3653 AS2 (sbc,%B0,__zero_reg__) CR_TAB
3654 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3655 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3656 switch (avr_jump_mode (operands[2],insn))
3659 return AS1 (brcc,%2);
3661 return (AS1 (brcs,.+2) CR_TAB
3664 return (AS1 (brcs,.+4) CR_TAB
3669 [(set (match_operand:HI 0 "d_register_operand" "")
3670 (plus:HI (match_dup 0)
3674 (compare (match_dup 0)
3676 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3678 (if_then_else (ne (cc0) (const_int 0))
3679 (label_ref (match_operand 2 "" ""))
3685 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3686 output_asm_insn (AS2 (sbiw,%0,1), operands);
3688 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3689 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3690 switch (avr_jump_mode (operands[2],insn))
3693 return AS1 (brcc,%2);
3695 return (AS1 (brcs,.+2) CR_TAB
3698 return (AS1 (brcs,.+4) CR_TAB
3703 [(set (match_operand:QI 0 "d_register_operand" "")
3704 (plus:QI (match_dup 0)
3707 (compare (match_dup 0)
3710 (if_then_else (ne (cc0) (const_int 0))
3711 (label_ref (match_operand 1 "" ""))
3717 cc_status.value1 = operands[0];
3718 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
3719 output_asm_insn (AS2 (subi,%A0,1), operands);
3720 switch (avr_jump_mode (operands[1],insn))
3723 return AS1 (brcc,%1);
3725 return (AS1 (brcs,.+2) CR_TAB
3728 return (AS1 (brcs,.+4) CR_TAB
3734 (compare (match_operand:QI 0 "register_operand" "")
3737 (if_then_else (eq (cc0) (const_int 0))
3738 (label_ref (match_operand 1 "" ""))
3740 "jump_over_one_insn_p (insn, operands[1])"
3741 "cpse %0,__zero_reg__")
3745 (compare (match_operand:QI 0 "register_operand" "")
3746 (match_operand:QI 1 "register_operand" "")))
3748 (if_then_else (eq (cc0) (const_int 0))
3749 (label_ref (match_operand 2 "" ""))
3751 "jump_over_one_insn_p (insn, operands[2])"
3754 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
3755 ;;prologue/epilogue support instructions
3757 (define_insn "popqi"
3758 [(set (match_operand:QI 0 "register_operand" "=r")
3759 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
3762 [(set_attr "cc" "none")
3763 (set_attr "length" "1")])
3765 ;; Enable Interrupts
3766 (define_insn "enable_interrupt"
3767 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
3770 [(set_attr "length" "1")
3771 (set_attr "cc" "none")])
3773 ;; Disable Interrupts
3774 (define_insn "disable_interrupt"
3775 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
3778 [(set_attr "length" "1")
3779 (set_attr "cc" "none")])
3781 ;; Library prologue saves
3782 (define_insn "call_prologue_saves"
3783 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
3784 (match_operand:HI 0 "immediate_operand" "")
3785 (set (reg:HI REG_SP) (minus:HI
3787 (match_operand:HI 1 "immediate_operand" "")))
3788 (use (reg:HI REG_X))
3789 (clobber (reg:HI REG_Z))]
3791 "ldi r30,lo8(gs(1f))
3793 %~jmp __prologue_saves__+((18 - %0) * 2)
3795 [(set_attr_alternative "length"
3796 [(if_then_else (eq_attr "mcu_mega" "yes")
3799 (set_attr "cc" "clobber")
3802 ; epilogue restores using library
3803 (define_insn "epilogue_restores"
3804 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
3805 (set (reg:HI REG_Y ) (plus:HI
3807 (match_operand:HI 0 "immediate_operand" "")))
3808 (set (reg:HI REG_SP) (reg:HI REG_Y))
3809 (clobber (reg:QI REG_Z))]
3812 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
3813 [(set_attr_alternative "length"
3814 [(if_then_else (eq_attr "mcu_mega" "yes")
3817 (set_attr "cc" "clobber")
3821 (define_insn "return"
3823 "reload_completed && avr_simple_epilogue ()"
3825 [(set_attr "cc" "none")
3826 (set_attr "length" "1")])
3828 (define_insn "return_from_epilogue"
3832 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
3833 && !cfun->machine->is_naked)"
3835 [(set_attr "cc" "none")
3836 (set_attr "length" "1")])
3838 (define_insn "return_from_interrupt_epilogue"
3842 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
3843 && !cfun->machine->is_naked)"
3845 [(set_attr "cc" "none")
3846 (set_attr "length" "1")])
3848 (define_insn "return_from_naked_epilogue"
3852 && cfun->machine->is_naked)"
3854 [(set_attr "cc" "none")
3855 (set_attr "length" "0")])
3857 (define_expand "prologue"
3866 (define_expand "epilogue"
3870 expand_epilogue (false /* sibcall_p */);
3874 (define_expand "sibcall_epilogue"
3878 expand_epilogue (true /* sibcall_p */);
3882 ;; Some instructions resp. instruction sequences available
3885 (define_insn "delay_cycles_1"
3886 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
3888 UNSPECV_DELAY_CYCLES)
3889 (clobber (match_scratch:QI 1 "=&d"))]
3894 [(set_attr "length" "3")
3895 (set_attr "cc" "clobber")])
3897 (define_insn "delay_cycles_2"
3898 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
3900 UNSPECV_DELAY_CYCLES)
3901 (clobber (match_scratch:HI 1 "=&w"))]
3907 [(set_attr "length" "4")
3908 (set_attr "cc" "clobber")])
3910 (define_insn "delay_cycles_3"
3911 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
3913 UNSPECV_DELAY_CYCLES)
3914 (clobber (match_scratch:QI 1 "=&d"))
3915 (clobber (match_scratch:QI 2 "=&d"))
3916 (clobber (match_scratch:QI 3 "=&d"))]
3925 [(set_attr "length" "7")
3926 (set_attr "cc" "clobber")])
3928 (define_insn "delay_cycles_4"
3929 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
3931 UNSPECV_DELAY_CYCLES)
3932 (clobber (match_scratch:QI 1 "=&d"))
3933 (clobber (match_scratch:QI 2 "=&d"))
3934 (clobber (match_scratch:QI 3 "=&d"))
3935 (clobber (match_scratch:QI 4 "=&d"))]
3946 [(set_attr "length" "9")
3947 (set_attr "cc" "clobber")])
3952 (define_expand "parityhi2"
3954 (match_operand:HI 1 "register_operand" ""))
3956 (parity:HI (reg:HI 24)))
3957 (set (match_operand:HI 0 "register_operand" "")
3962 (define_expand "paritysi2"
3964 (match_operand:SI 1 "register_operand" ""))
3966 (parity:HI (reg:SI 22)))
3969 (set (match_operand:SI 0 "register_operand" "")
3970 (zero_extend:SI (match_dup 2)))]
3973 operands[2] = gen_reg_rtx (HImode);
3976 (define_insn "*parityhi2.libgcc"
3978 (parity:HI (reg:HI 24)))]
3980 "%~call __parityhi2"
3981 [(set_attr "type" "xcall")
3982 (set_attr "cc" "clobber")])
3984 (define_insn "*parityqihi2.libgcc"
3986 (parity:HI (reg:QI 24)))]
3988 "%~call __parityqi2"
3989 [(set_attr "type" "xcall")
3990 (set_attr "cc" "clobber")])
3992 (define_insn "*paritysihi2.libgcc"
3994 (parity:HI (reg:SI 22)))]
3996 "%~call __paritysi2"
3997 [(set_attr "type" "xcall")
3998 (set_attr "cc" "clobber")])
4003 (define_expand "popcounthi2"
4005 (match_operand:HI 1 "register_operand" ""))
4007 (popcount:HI (reg:HI 24)))
4008 (set (match_operand:HI 0 "register_operand" "")
4013 (define_expand "popcountsi2"
4015 (match_operand:SI 1 "register_operand" ""))
4017 (popcount:HI (reg:SI 22)))
4020 (set (match_operand:SI 0 "register_operand" "")
4021 (zero_extend:SI (match_dup 2)))]
4024 operands[2] = gen_reg_rtx (HImode);
4027 (define_insn "*popcounthi2.libgcc"
4029 (popcount:HI (reg:HI 24)))]
4031 "%~call __popcounthi2"
4032 [(set_attr "type" "xcall")
4033 (set_attr "cc" "clobber")])
4035 (define_insn "*popcountsi2.libgcc"
4037 (popcount:HI (reg:SI 22)))]
4039 "%~call __popcountsi2"
4040 [(set_attr "type" "xcall")
4041 (set_attr "cc" "clobber")])
4043 (define_insn "*popcountqi2.libgcc"
4045 (popcount:QI (reg:QI 24)))]
4047 "%~call __popcountqi2"
4048 [(set_attr "type" "xcall")
4049 (set_attr "cc" "clobber")])
4051 (define_insn_and_split "*popcountqihi2.libgcc"
4053 (popcount:HI (reg:QI 24)))]
4058 (popcount:QI (reg:QI 24)))
4063 ;; Count Leading Zeros
4065 (define_expand "clzhi2"
4067 (match_operand:HI 1 "register_operand" ""))
4068 (parallel [(set (reg:HI 24)
4069 (clz:HI (reg:HI 24)))
4070 (clobber (reg:QI 26))])
4071 (set (match_operand:HI 0 "register_operand" "")
4076 (define_expand "clzsi2"
4078 (match_operand:SI 1 "register_operand" ""))
4079 (parallel [(set (reg:HI 24)
4080 (clz:HI (reg:SI 22)))
4081 (clobber (reg:QI 26))])
4084 (set (match_operand:SI 0 "register_operand" "")
4085 (zero_extend:SI (match_dup 2)))]
4088 operands[2] = gen_reg_rtx (HImode);
4091 (define_insn "*clzhi2.libgcc"
4093 (clz:HI (reg:HI 24)))
4094 (clobber (reg:QI 26))]
4097 [(set_attr "type" "xcall")
4098 (set_attr "cc" "clobber")])
4100 (define_insn "*clzsihi2.libgcc"
4102 (clz:HI (reg:SI 22)))
4103 (clobber (reg:QI 26))]
4106 [(set_attr "type" "xcall")
4107 (set_attr "cc" "clobber")])
4109 ;; Count Trailing Zeros
4111 (define_expand "ctzhi2"
4113 (match_operand:HI 1 "register_operand" ""))
4114 (parallel [(set (reg:HI 24)
4115 (ctz:HI (reg:HI 24)))
4116 (clobber (reg:QI 26))])
4117 (set (match_operand:HI 0 "register_operand" "")
4122 (define_expand "ctzsi2"
4124 (match_operand:SI 1 "register_operand" ""))
4125 (parallel [(set (reg:HI 24)
4126 (ctz:HI (reg:SI 22)))
4127 (clobber (reg:QI 22))
4128 (clobber (reg:QI 26))])
4131 (set (match_operand:SI 0 "register_operand" "")
4132 (zero_extend:SI (match_dup 2)))]
4135 operands[2] = gen_reg_rtx (HImode);
4138 (define_insn "*ctzhi2.libgcc"
4140 (ctz:HI (reg:HI 24)))
4141 (clobber (reg:QI 26))]
4144 [(set_attr "type" "xcall")
4145 (set_attr "cc" "clobber")])
4147 (define_insn "*ctzsihi2.libgcc"
4149 (ctz:HI (reg:SI 22)))
4150 (clobber (reg:QI 22))
4151 (clobber (reg:QI 26))]
4154 [(set_attr "type" "xcall")
4155 (set_attr "cc" "clobber")])
4159 (define_expand "ffshi2"
4161 (match_operand:HI 1 "register_operand" ""))
4162 (parallel [(set (reg:HI 24)
4163 (ffs:HI (reg:HI 24)))
4164 (clobber (reg:QI 26))])
4165 (set (match_operand:HI 0 "register_operand" "")
4170 (define_expand "ffssi2"
4172 (match_operand:SI 1 "register_operand" ""))
4173 (parallel [(set (reg:HI 24)
4174 (ffs:HI (reg:SI 22)))
4175 (clobber (reg:QI 22))
4176 (clobber (reg:QI 26))])
4179 (set (match_operand:SI 0 "register_operand" "")
4180 (zero_extend:SI (match_dup 2)))]
4183 operands[2] = gen_reg_rtx (HImode);
4186 (define_insn "*ffshi2.libgcc"
4188 (ffs:HI (reg:HI 24)))
4189 (clobber (reg:QI 26))]
4192 [(set_attr "type" "xcall")
4193 (set_attr "cc" "clobber")])
4195 (define_insn "*ffssihi2.libgcc"
4197 (ffs:HI (reg:SI 22)))
4198 (clobber (reg:QI 22))
4199 (clobber (reg:QI 26))]
4202 [(set_attr "type" "xcall")
4203 (set_attr "cc" "clobber")])
4207 (define_insn "copysignsf3"
4208 [(set (match_operand:SF 0 "register_operand" "=r")
4209 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
4210 (match_operand:SF 2 "register_operand" "r")]
4213 "bst %D2,7\;bld %D0,7"
4214 [(set_attr "length" "2")
4215 (set_attr "cc" "none")])
4217 ;; Swap Bytes (change byte-endianess)
4219 (define_expand "bswapsi2"
4221 (match_operand:SI 1 "register_operand" ""))
4223 (bswap:SI (reg:SI 22)))
4224 (set (match_operand:SI 0 "register_operand" "")
4229 (define_insn "*bswapsi2.libgcc"
4231 (bswap:SI (reg:SI 22)))]
4234 [(set_attr "type" "xcall")
4235 (set_attr "cc" "clobber")])
4240 ;; NOP taking 1 or 2 Ticks
4242 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
4248 [(set_attr "length" "1")
4249 (set_attr "cc" "none")])
4252 (define_insn "sleep"
4253 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
4256 [(set_attr "length" "1")
4257 (set_attr "cc" "none")])
4261 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
4264 [(set_attr "length" "1")
4265 (set_attr "cc" "none")])
4268 (define_expand "fmul"
4270 (match_operand:QI 1 "register_operand" ""))
4272 (match_operand:QI 2 "register_operand" ""))
4273 (parallel [(set (reg:HI 22)
4274 (unspec:HI [(reg:QI 24)
4275 (reg:QI 25)] UNSPEC_FMUL))
4276 (clobber (reg:HI 24))])
4277 (set (match_operand:HI 0 "register_operand" "")
4283 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
4288 (define_insn "fmul_insn"
4289 [(set (match_operand:HI 0 "register_operand" "=r")
4290 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4291 (match_operand:QI 2 "register_operand" "a")]
4297 [(set_attr "length" "3")
4298 (set_attr "cc" "clobber")])
4300 (define_insn "*fmul.call"
4302 (unspec:HI [(reg:QI 24)
4303 (reg:QI 25)] UNSPEC_FMUL))
4304 (clobber (reg:HI 24))]
4307 [(set_attr "type" "xcall")
4308 (set_attr "cc" "clobber")])
4311 (define_expand "fmuls"
4313 (match_operand:QI 1 "register_operand" ""))
4315 (match_operand:QI 2 "register_operand" ""))
4316 (parallel [(set (reg:HI 22)
4317 (unspec:HI [(reg:QI 24)
4318 (reg:QI 25)] UNSPEC_FMULS))
4319 (clobber (reg:HI 24))])
4320 (set (match_operand:HI 0 "register_operand" "")
4326 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
4331 (define_insn "fmuls_insn"
4332 [(set (match_operand:HI 0 "register_operand" "=r")
4333 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4334 (match_operand:QI 2 "register_operand" "a")]
4340 [(set_attr "length" "3")
4341 (set_attr "cc" "clobber")])
4343 (define_insn "*fmuls.call"
4345 (unspec:HI [(reg:QI 24)
4346 (reg:QI 25)] UNSPEC_FMULS))
4347 (clobber (reg:HI 24))]
4350 [(set_attr "type" "xcall")
4351 (set_attr "cc" "clobber")])
4354 (define_expand "fmulsu"
4356 (match_operand:QI 1 "register_operand" ""))
4358 (match_operand:QI 2 "register_operand" ""))
4359 (parallel [(set (reg:HI 22)
4360 (unspec:HI [(reg:QI 24)
4361 (reg:QI 25)] UNSPEC_FMULSU))
4362 (clobber (reg:HI 24))])
4363 (set (match_operand:HI 0 "register_operand" "")
4369 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
4374 (define_insn "fmulsu_insn"
4375 [(set (match_operand:HI 0 "register_operand" "=r")
4376 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4377 (match_operand:QI 2 "register_operand" "a")]
4383 [(set_attr "length" "3")
4384 (set_attr "cc" "clobber")])
4386 (define_insn "*fmulsu.call"
4388 (unspec:HI [(reg:QI 24)
4389 (reg:QI 25)] UNSPEC_FMULSU))
4390 (clobber (reg:HI 24))]
4393 [(set_attr "type" "xcall")
4394 (set_attr "cc" "clobber")])
4397 ;; Some combiner patterns dealing with bits.
4400 ;; Move bit $3.0 into bit $0.$4
4401 (define_insn "*movbitqi.1-6.a"
4402 [(set (match_operand:QI 0 "register_operand" "=r")
4403 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4404 (match_operand:QI 2 "single_zero_operand" "n"))
4405 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
4406 (match_operand:QI 4 "const_0_to_7_operand" "n"))
4407 (match_operand:QI 5 "single_one_operand" "n"))))]
4408 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
4409 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
4410 "bst %3,0\;bld %0,%4"
4411 [(set_attr "length" "2")
4412 (set_attr "cc" "none")])
4414 ;; Move bit $3.0 into bit $0.$4
4415 ;; Variation of above. Unfortunately, there is no canonicalized representation
4416 ;; of moving around bits. So what we see here depends on how user writes down
4417 ;; bit manipulations.
4418 (define_insn "*movbitqi.1-6.b"
4419 [(set (match_operand:QI 0 "register_operand" "=r")
4420 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4421 (match_operand:QI 2 "single_zero_operand" "n"))
4422 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
4424 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
4425 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4426 "bst %3,0\;bld %0,%4"
4427 [(set_attr "length" "2")
4428 (set_attr "cc" "none")])
4430 ;; Move bit $3.0 into bit $0.0.
4431 ;; For bit 0, combiner generates slightly different pattern.
4432 (define_insn "*movbitqi.0"
4433 [(set (match_operand:QI 0 "register_operand" "=r")
4434 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4435 (match_operand:QI 2 "single_zero_operand" "n"))
4436 (and:QI (match_operand:QI 3 "register_operand" "r")
4438 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4439 "bst %3,0\;bld %0,0"
4440 [(set_attr "length" "2")
4441 (set_attr "cc" "none")])
4443 ;; Move bit $2.0 into bit $0.7.
4444 ;; For bit 7, combiner generates slightly different pattern
4445 (define_insn "*movbitqi.7"
4446 [(set (match_operand:QI 0 "register_operand" "=r")
4447 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4449 (ashift:QI (match_operand:QI 2 "register_operand" "r")
4452 "bst %2,0\;bld %0,7"
4453 [(set_attr "length" "2")
4454 (set_attr "cc" "none")])
4456 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
4457 ;; and input/output match. We provide a special pattern for this, because
4458 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
4459 ;; operation on I/O is atomic.
4460 (define_insn "*insv.io"
4461 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
4463 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
4464 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
4469 sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
4470 [(set_attr "length" "1,1,4")
4471 (set_attr "cc" "none")])
4473 (define_insn "*insv.not.io"
4474 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4476 (match_operand:QI 1 "const_0_to_7_operand" "n"))
4477 (not:QI (match_operand:QI 2 "register_operand" "r")))]
4479 "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
4480 [(set_attr "length" "4")
4481 (set_attr "cc" "none")])
4483 ;; The insv expander.
4484 ;; We only support 1-bit inserts
4485 (define_expand "insv"
4486 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
4487 (match_operand:QI 1 "const1_operand" "") ; width
4488 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
4489 (match_operand:QI 3 "nonmemory_operand" ""))]
4493 ;; Insert bit $2.0 into $0.$1
4494 (define_insn "*insv.reg"
4495 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
4497 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
4498 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
4502 andi %0,lo8(~(1<<%1))
4506 [(set_attr "length" "2,1,1,2,2")
4507 (set_attr "cc" "none,set_zn,set_zn,none,none")])
4510 ;; Some combine patterns that try to fix bad code when a value is composed
4511 ;; from byte parts like in PR27663.
4512 ;; The patterns give some release but the code still is not optimal,
4513 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
4514 ;; That switch obfuscates things here and in many other places.
4516 (define_insn_and_split "*ior<mode>qi.byte0"
4517 [(set (match_operand:HISI 0 "register_operand" "=r")
4519 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4520 (match_operand:HISI 2 "register_operand" "0")))]
4525 (ior:QI (match_dup 3)
4528 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
4531 (define_insn_and_split "*ior<mode>qi.byte1-3"
4532 [(set (match_operand:HISI 0 "register_operand" "=r")
4534 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4535 (match_operand:QI 2 "const_8_16_24_operand" "n"))
4536 (match_operand:HISI 3 "register_operand" "0")))]
4537 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
4539 "&& reload_completed"
4541 (ior:QI (match_dup 4)
4544 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
4545 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
4548 (define_expand "extzv"
4549 [(set (match_operand:QI 0 "register_operand" "")
4550 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
4551 (match_operand:QI 2 "const1_operand" "")
4552 (match_operand:QI 3 "const_0_to_7_operand" "")))]
4556 (define_insn "*extzv"
4557 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
4558 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
4560 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
4564 mov %0,%1\;andi %0,1
4567 bst %1,%2\;clr %0\;bld %0,0"
4568 [(set_attr "length" "1,2,2,2,3")
4569 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
4571 (define_insn_and_split "*extzv.qihi1"
4572 [(set (match_operand:HI 0 "register_operand" "=r")
4573 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
4575 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
4580 (zero_extract:QI (match_dup 1)
4586 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4587 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4590 (define_insn_and_split "*extzv.qihi2"
4591 [(set (match_operand:HI 0 "register_operand" "=r")
4593 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
4595 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
4600 (zero_extract:QI (match_dup 1)
4606 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4607 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);