1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
4 ;; 2009, 2010, 2011 Free Software Foundation, Inc.
5 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;; Special characters after '%':
24 ;; A No effect (add 0).
25 ;; B Add 1 to REG number, MEM address or CONST_INT.
28 ;; j Branch condition.
29 ;; k Reverse branch condition.
30 ;;..m..Constant Direct Data memory address.
31 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
32 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
33 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
34 ;;..x..Constant Direct Program memory address.
35 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
36 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
45 (TMP_REGNO 0) ; temporary register r0
46 (ZERO_REGNO 1) ; zero register r1
52 (define_c_enum "unspec"
62 (define_c_enum "unspecv"
63 [UNSPECV_PROLOGUE_SAVES
64 UNSPECV_EPILOGUE_RESTORES
65 UNSPECV_WRITE_SP_IRQ_ON
66 UNSPECV_WRITE_SP_IRQ_OFF
76 (include "predicates.md")
77 (include "constraints.md")
79 ;; Condition code settings.
80 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
81 (const_string "none"))
83 (define_attr "type" "branch,branch1,arith,xcall"
84 (const_string "arith"))
86 (define_attr "mcu_have_movw" "yes,no"
87 (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
89 (const_string "no"))))
91 (define_attr "mcu_mega" "yes,no"
92 (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
94 (const_string "no"))))
97 ;; The size of instructions in bytes.
98 ;; XXX may depend from "cc"
100 (define_attr "length" ""
101 (cond [(eq_attr "type" "branch")
102 (if_then_else (and (ge (minus (pc) (match_dup 0))
104 (le (minus (pc) (match_dup 0))
107 (if_then_else (and (ge (minus (pc) (match_dup 0))
109 (le (minus (pc) (match_dup 0))
113 (eq_attr "type" "branch1")
114 (if_then_else (and (ge (minus (pc) (match_dup 0))
116 (le (minus (pc) (match_dup 0))
119 (if_then_else (and (ge (minus (pc) (match_dup 0))
121 (le (minus (pc) (match_dup 0))
125 (eq_attr "type" "xcall")
126 (if_then_else (eq_attr "mcu_mega" "no")
131 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
132 ;; Following insn attribute tells if and how the adjustment has to be
134 ;; no No adjustment needed; attribute "length" is fine.
135 ;; yes Analyse pattern in adjust_insn_length by hand.
136 ;; Otherwise do special processing depending on the attribute.
138 (define_attr "adjust_len"
139 "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare,
140 mov8, mov16, mov32, reload_in16, reload_in32,
141 ashlqi, ashrqi, lshrqi,
142 ashlhi, ashrhi, lshrhi,
143 ashlsi, ashrsi, lshrsi,
147 ;; Define mode iterators
148 (define_mode_iterator QIHI [(QI "") (HI "")])
149 (define_mode_iterator QIHI2 [(QI "") (HI "")])
150 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
151 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
152 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
153 (define_mode_iterator HISI [(HI "") (SI "")])
155 ;; Define code iterators
156 ;; Define two incarnations so that we can build the cross product.
157 (define_code_iterator any_extend [sign_extend zero_extend])
158 (define_code_iterator any_extend2 [sign_extend zero_extend])
160 ;; Define code attributes
161 (define_code_attr extend_su
165 (define_code_attr extend_u
169 (define_code_attr extend_s
173 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
174 (define_code_attr mul_r_d
179 ;;========================================================================
180 ;; The following is used by nonlocal_goto and setjmp.
181 ;; The receiver pattern will create no instructions since internally
182 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
183 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
184 ;; The 'null' receiver also avoids problems with optimisation
185 ;; not recognising incoming jmp and removing code that resets frame_pointer.
186 ;; The code derived from builtins.c.
188 (define_expand "nonlocal_goto_receiver"
190 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
193 emit_move_insn (virtual_stack_vars_rtx,
194 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
195 gen_int_mode (STARTING_FRAME_OFFSET,
197 /* This might change the hard frame pointer in ways that aren't
198 apparent to early optimization passes, so force a clobber. */
199 emit_clobber (hard_frame_pointer_rtx);
204 ;; Defining nonlocal_goto_receiver means we must also define this.
205 ;; even though its function is identical to that in builtins.c
207 (define_expand "nonlocal_goto"
209 (use (match_operand 0 "general_operand"))
210 (use (match_operand 1 "general_operand"))
211 (use (match_operand 2 "general_operand"))
212 (use (match_operand 3 "general_operand"))
216 rtx r_label = copy_to_reg (operands[1]);
217 rtx r_fp = operands[3];
218 rtx r_sp = operands[2];
220 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
222 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
224 emit_move_insn (hard_frame_pointer_rtx, r_fp);
225 emit_stack_restore (SAVE_NONLOCAL, r_sp);
227 emit_use (hard_frame_pointer_rtx);
228 emit_use (stack_pointer_rtx);
230 emit_indirect_jump (r_label);
235 (define_insn "pushqi1"
236 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
237 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
242 [(set_attr "length" "1,1")])
244 ;; All modes for a multi-byte push. We must include complex modes here too,
245 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
246 (define_mode_iterator MPUSH
253 (define_expand "push<mode>1"
254 [(match_operand:MPUSH 0 "" "")]
258 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
260 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
261 if (part != const0_rtx)
262 part = force_reg (QImode, part);
263 emit_insn (gen_pushqi1 (part));
268 ;; Notice a special-case when adding N to SP where N results in a
269 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
271 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
273 && frame_pointer_needed
274 && !cfun->calls_alloca
275 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
276 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
279 ;;========================================================================
281 ;; The last alternative (any immediate constant to any register) is
282 ;; very expensive. It should be optimized by peephole2 if a scratch
283 ;; register is available, but then that register could just as well be
284 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
285 ;; are call-saved registers, and most of LD_REGS are call-used registers,
286 ;; so this may still be a win for registers live across function calls.
288 (define_expand "movqi"
289 [(set (match_operand:QI 0 "nonimmediate_operand" "")
290 (match_operand:QI 1 "general_operand" ""))]
292 "/* One of the ops has to be in a register. */
293 if (!register_operand(operand0, QImode)
294 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
295 operands[1] = copy_to_mode_reg(QImode, operand1);
298 (define_insn "*movqi"
299 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
300 (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))]
301 "(register_operand (operands[0],QImode)
302 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
303 "* return output_movqi (insn, operands, NULL);"
304 [(set_attr "length" "1,1,5,5,1,1,4")
305 (set_attr "adjust_len" "mov8")
306 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
308 ;; This is used in peephole2 to optimize loading immediate constants
309 ;; if a scratch register from LD_REGS happens to be available.
311 (define_insn "*reload_inqi"
312 [(set (match_operand:QI 0 "register_operand" "=l")
313 (match_operand:QI 1 "immediate_operand" "i"))
314 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
318 [(set_attr "length" "2")
319 (set_attr "cc" "none")])
322 [(match_scratch:QI 2 "d")
323 (set (match_operand:QI 0 "l_register_operand" "")
324 (match_operand:QI 1 "immediate_operand" ""))]
325 "(operands[1] != const0_rtx
326 && operands[1] != const1_rtx
327 && operands[1] != constm1_rtx)"
328 [(parallel [(set (match_dup 0) (match_dup 1))
329 (clobber (match_dup 2))])]
332 ;;============================================================================
333 ;; move word (16 bit)
335 (define_expand "movhi"
336 [(set (match_operand:HI 0 "nonimmediate_operand" "")
337 (match_operand:HI 1 "general_operand" ""))]
341 /* One of the ops has to be in a register. */
342 if (!register_operand(operand0, HImode)
343 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
345 operands[1] = copy_to_mode_reg(HImode, operand1);
349 (define_insn "movhi_sp_r_irq_off"
350 [(set (match_operand:HI 0 "stack_register_operand" "=q")
351 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
352 UNSPECV_WRITE_SP_IRQ_OFF))]
356 [(set_attr "length" "2")
357 (set_attr "cc" "none")])
359 (define_insn "movhi_sp_r_irq_on"
360 [(set (match_operand:HI 0 "stack_register_operand" "=q")
361 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
362 UNSPECV_WRITE_SP_IRQ_ON))]
368 [(set_attr "length" "4")
369 (set_attr "cc" "none")])
372 [(match_scratch:QI 2 "d")
373 (set (match_operand:HI 0 "l_register_operand" "")
374 (match_operand:HI 1 "immediate_operand" ""))]
375 "(operands[1] != const0_rtx
376 && operands[1] != constm1_rtx)"
377 [(parallel [(set (match_dup 0) (match_dup 1))
378 (clobber (match_dup 2))])]
381 ;; '*' because it is not used in rtl generation, only in above peephole
382 (define_insn "*reload_inhi"
383 [(set (match_operand:HI 0 "register_operand" "=r")
384 (match_operand:HI 1 "immediate_operand" "i"))
385 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
388 return output_reload_inhi (operands, operands[2], NULL);
390 [(set_attr "length" "4")
391 (set_attr "adjust_len" "reload_in16")
392 (set_attr "cc" "none")])
394 (define_insn "*movhi"
395 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,d,*r,q,r")
396 (match_operand:HI 1 "general_operand" "r,L,m,rL,i,i,r,q"))]
397 "(register_operand (operands[0],HImode)
398 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
399 "* return output_movhi (insn, operands, NULL);"
400 [(set_attr "length" "2,2,6,7,2,6,5,2")
401 (set_attr "adjust_len" "mov16")
402 (set_attr "cc" "none,clobber,clobber,clobber,none,clobber,none,none")])
404 (define_peephole2 ; movw
405 [(set (match_operand:QI 0 "even_register_operand" "")
406 (match_operand:QI 1 "even_register_operand" ""))
407 (set (match_operand:QI 2 "odd_register_operand" "")
408 (match_operand:QI 3 "odd_register_operand" ""))]
410 && REGNO (operands[0]) == REGNO (operands[2]) - 1
411 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
412 [(set (match_dup 4) (match_dup 5))]
414 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
415 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
418 (define_peephole2 ; movw_r
419 [(set (match_operand:QI 0 "odd_register_operand" "")
420 (match_operand:QI 1 "odd_register_operand" ""))
421 (set (match_operand:QI 2 "even_register_operand" "")
422 (match_operand:QI 3 "even_register_operand" ""))]
424 && REGNO (operands[2]) == REGNO (operands[0]) - 1
425 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
426 [(set (match_dup 4) (match_dup 5))]
428 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
429 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
432 ;;==========================================================================
433 ;; move double word (32 bit)
435 (define_expand "movsi"
436 [(set (match_operand:SI 0 "nonimmediate_operand" "")
437 (match_operand:SI 1 "general_operand" ""))]
441 /* One of the ops has to be in a register. */
442 if (!register_operand (operand0, SImode)
443 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
445 operands[1] = copy_to_mode_reg (SImode, operand1);
451 (define_peephole2 ; *reload_insi
452 [(match_scratch:QI 2 "d")
453 (set (match_operand:SI 0 "l_register_operand" "")
454 (match_operand:SI 1 "const_int_operand" ""))
456 "(operands[1] != const0_rtx
457 && operands[1] != constm1_rtx)"
458 [(parallel [(set (match_dup 0) (match_dup 1))
459 (clobber (match_dup 2))])]
462 ;; '*' because it is not used in rtl generation.
463 (define_insn "*reload_insi"
464 [(set (match_operand:SI 0 "register_operand" "=r")
465 (match_operand:SI 1 "const_int_operand" "n"))
466 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
469 return output_reload_insisf (operands, operands[2], NULL);
471 [(set_attr "length" "8")
472 (set_attr "adjust_len" "reload_in32")
473 (set_attr "cc" "clobber")])
476 (define_insn "*movsi"
477 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
478 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
479 "(register_operand (operands[0],SImode)
480 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
482 return output_movsisf (insn, operands, NULL);
484 [(set_attr "length" "4,4,8,9,4,10")
485 (set_attr "adjust_len" "mov32")
486 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
488 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
489 ;; move floating point numbers (32 bit)
491 (define_expand "movsf"
492 [(set (match_operand:SF 0 "nonimmediate_operand" "")
493 (match_operand:SF 1 "general_operand" ""))]
497 /* One of the ops has to be in a register. */
498 if (!register_operand (operand1, SFmode)
499 && !register_operand (operand0, SFmode))
501 operands[1] = copy_to_mode_reg (SFmode, operand1);
505 (define_insn "*movsf"
506 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
507 (match_operand:SF 1 "general_operand" "r,G,Qm,rG,F,F"))]
508 "register_operand (operands[0], SFmode)
509 || register_operand (operands[1], SFmode)
510 || operands[1] == CONST0_RTX (SFmode)"
512 return output_movsisf (insn, operands, NULL);
514 [(set_attr "length" "4,4,8,9,4,10")
515 (set_attr "adjust_len" "mov32")
516 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
518 (define_peephole2 ; *reload_insf
519 [(match_scratch:QI 2 "d")
520 (set (match_operand:SF 0 "l_register_operand" "")
521 (match_operand:SF 1 "const_double_operand" ""))
523 "operands[1] != CONST0_RTX (SFmode)"
524 [(parallel [(set (match_dup 0)
526 (clobber (match_dup 2))])]
529 ;; '*' because it is not used in rtl generation.
530 (define_insn "*reload_insf"
531 [(set (match_operand:SF 0 "register_operand" "=r")
532 (match_operand:SF 1 "const_double_operand" "F"))
533 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
536 return output_reload_insisf (operands, operands[2], NULL);
538 [(set_attr "length" "8")
539 (set_attr "adjust_len" "reload_in32")
540 (set_attr "cc" "clobber")])
542 ;;=========================================================================
543 ;; move string (like memcpy)
544 ;; implement as RTL loop
546 (define_expand "movmemhi"
547 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
548 (match_operand:BLK 1 "memory_operand" ""))
549 (use (match_operand:HI 2 "const_int_operand" ""))
550 (use (match_operand:HI 3 "const_int_operand" ""))])]
555 enum machine_mode mode;
556 rtx label = gen_label_rtx ();
560 /* Copy pointers into new psuedos - they will be changed. */
561 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
562 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
564 /* Create rtx for tmp register - we use this as scratch. */
565 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
567 if (GET_CODE (operands[2]) != CONST_INT)
570 count = INTVAL (operands[2]);
574 /* Work out branch probability for latter use. */
575 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
577 /* See if constant fit 8 bits. */
578 mode = (count < 0x100) ? QImode : HImode;
579 /* Create loop counter register. */
580 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
582 /* Now create RTL code for move loop. */
583 /* Label at top of loop. */
586 /* Move one byte into scratch and inc pointer. */
587 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
588 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
590 /* Move to mem and inc pointer. */
591 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
592 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
594 /* Decrement count. */
595 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
597 /* Compare with zero and jump if not equal. */
598 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
600 /* Set jump probability based on loop count. */
601 jump = get_last_insn ();
602 add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
606 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
607 ;; memset (%0, %2, %1)
609 (define_expand "setmemhi"
610 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
611 (match_operand 2 "const_int_operand" ""))
612 (use (match_operand:HI 1 "const_int_operand" ""))
613 (use (match_operand:HI 3 "const_int_operand" "n"))
614 (clobber (match_scratch:HI 4 ""))
615 (clobber (match_dup 5))])]
619 enum machine_mode mode;
621 /* If value to set is not zero, use the library routine. */
622 if (operands[2] != const0_rtx)
625 if (!CONST_INT_P (operands[1]))
628 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
629 operands[5] = gen_rtx_SCRATCH (mode);
630 operands[1] = copy_to_mode_reg (mode,
631 gen_int_mode (INTVAL (operands[1]), mode));
632 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
633 operands[0] = gen_rtx_MEM (BLKmode, addr0);
636 (define_insn "*clrmemqi"
637 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
639 (use (match_operand:QI 1 "register_operand" "r"))
640 (use (match_operand:QI 2 "const_int_operand" "n"))
641 (clobber (match_scratch:HI 3 "=0"))
642 (clobber (match_scratch:QI 4 "=&1"))]
644 "st %a0+,__zero_reg__
647 [(set_attr "length" "3")
648 (set_attr "cc" "clobber")])
650 (define_insn "*clrmemhi"
651 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
653 (use (match_operand:HI 1 "register_operand" "!w,d"))
654 (use (match_operand:HI 2 "const_int_operand" "n,n"))
655 (clobber (match_scratch:HI 3 "=0,0"))
656 (clobber (match_scratch:HI 4 "=&1,&1"))]
659 if (which_alternative==0)
660 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
661 AS2 (sbiw,%A1,1) CR_TAB
664 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
665 AS2 (subi,%A1,1) CR_TAB
666 AS2 (sbci,%B1,0) CR_TAB
669 [(set_attr "length" "3,4")
670 (set_attr "cc" "clobber,clobber")])
672 (define_expand "strlenhi"
674 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
675 (match_operand:QI 2 "const_int_operand" "")
676 (match_operand:HI 3 "immediate_operand" "")]
678 (set (match_dup 4) (plus:HI (match_dup 4)
680 (set (match_operand:HI 0 "register_operand" "")
681 (minus:HI (match_dup 4)
686 if (operands[2] != const0_rtx)
688 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
689 operands[1] = gen_rtx_MEM (BLKmode, addr);
691 operands[4] = gen_reg_rtx (HImode);
694 (define_insn "*strlenhi"
695 [(set (match_operand:HI 0 "register_operand" "=e")
696 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
698 (match_operand:HI 2 "immediate_operand" "i")]
704 [(set_attr "length" "3")
705 (set_attr "cc" "clobber")])
707 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
710 (define_insn "addqi3"
711 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
712 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
713 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
720 [(set_attr "length" "1,1,1,1")
721 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
724 (define_expand "addhi3"
725 [(set (match_operand:HI 0 "register_operand" "")
726 (plus:HI (match_operand:HI 1 "register_operand" "")
727 (match_operand:HI 2 "nonmemory_operand" "")))]
731 if (GET_CODE (operands[2]) == CONST_INT)
733 short tmp = INTVAL (operands[2]);
734 operands[2] = GEN_INT(tmp);
739 (define_insn "*addhi3_zero_extend"
740 [(set (match_operand:HI 0 "register_operand" "=r")
741 (plus:HI (zero_extend:HI
742 (match_operand:QI 1 "register_operand" "r"))
743 (match_operand:HI 2 "register_operand" "0")))]
746 adc %B0,__zero_reg__"
747 [(set_attr "length" "2")
748 (set_attr "cc" "set_n")])
750 (define_insn "*addhi3_zero_extend1"
751 [(set (match_operand:HI 0 "register_operand" "=r")
752 (plus:HI (match_operand:HI 1 "register_operand" "%0")
754 (match_operand:QI 2 "register_operand" "r"))))]
757 adc %B0,__zero_reg__"
758 [(set_attr "length" "2")
759 (set_attr "cc" "set_n")])
761 (define_insn "*addhi3_sp_R"
762 [(set (match_operand:HI 1 "stack_register_operand" "=q")
763 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
764 (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
767 return avr_out_addto_sp (operands, NULL);
769 [(set_attr "length" "5")
770 (set_attr "adjust_len" "addto_sp")])
772 (define_insn "*addhi3"
773 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
775 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
776 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
779 add %A0,%A2\;adc %B0,%B2
782 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
783 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
784 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
785 [(set_attr "length" "2,1,1,2,3,3")
786 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
788 (define_insn "addsi3"
789 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,l,l ,d,r")
790 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0 ,0,0,0 ,0,0")
791 (match_operand:SI 2 "nonmemory_operand" "r,I ,J ,s,P,N ,n,n")))
792 (clobber (match_scratch:QI 3 "=X,X ,X ,X,X,X ,X,&d"))]
795 static const char * const asm_code[] =
797 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
798 "adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__",
799 "sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__",
800 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
801 "sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__",
802 "sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
805 if (which_alternative >= (signed) (sizeof (asm_code) / sizeof (*asm_code)))
806 return avr_out_plus (operands, NULL);
808 return asm_code [which_alternative];
810 [(set_attr "length" "4,3,3,4,5,5,8,8")
811 (set_attr "adjust_len" "*,*,*,*,*,*,out_plus,out_plus")
812 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n,clobber,clobber")])
814 (define_insn "*addsi3_zero_extend"
815 [(set (match_operand:SI 0 "register_operand" "=r")
816 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
817 (match_operand:SI 2 "register_operand" "0")))]
819 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
820 [(set_attr "length" "4")
821 (set_attr "cc" "set_n")])
823 (define_insn "*addsi3_zero_extend.hi"
824 [(set (match_operand:SI 0 "register_operand" "=r")
825 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
826 (match_operand:SI 2 "register_operand" "0")))]
828 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
829 [(set_attr "length" "4")
830 (set_attr "cc" "set_n")])
832 ;-----------------------------------------------------------------------------
834 (define_insn "subqi3"
835 [(set (match_operand:QI 0 "register_operand" "=r,d")
836 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
837 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
842 [(set_attr "length" "1,1")
843 (set_attr "cc" "set_czn,set_czn")])
845 (define_insn "subhi3"
846 [(set (match_operand:HI 0 "register_operand" "=r,d")
847 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
848 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
851 sub %A0,%A2\;sbc %B0,%B2
852 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
853 [(set_attr "length" "2,2")
854 (set_attr "cc" "set_czn,set_czn")])
856 (define_insn "*subhi3_zero_extend1"
857 [(set (match_operand:HI 0 "register_operand" "=r")
858 (minus:HI (match_operand:HI 1 "register_operand" "0")
859 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
861 "sub %A0,%2\;sbc %B0,__zero_reg__"
862 [(set_attr "length" "2")
863 (set_attr "cc" "set_czn")])
865 (define_insn "subsi3"
866 [(set (match_operand:SI 0 "register_operand" "=r")
867 (minus:SI (match_operand:SI 1 "register_operand" "0")
868 (match_operand:SI 2 "register_operand" "r")))]
870 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
871 [(set_attr "length" "4")
872 (set_attr "cc" "set_czn")])
874 (define_insn "*subsi3_zero_extend"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (minus:SI (match_operand:SI 1 "register_operand" "0")
877 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
879 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
880 [(set_attr "length" "4")
881 (set_attr "cc" "set_czn")])
883 (define_insn "*subsi3_zero_extend.hi"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (minus:SI (match_operand:SI 1 "register_operand" "0")
886 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
888 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
889 [(set_attr "length" "4")
890 (set_attr "cc" "set_czn")])
892 ;******************************************************************************
895 (define_expand "mulqi3"
896 [(set (match_operand:QI 0 "register_operand" "")
897 (mult:QI (match_operand:QI 1 "register_operand" "")
898 (match_operand:QI 2 "register_operand" "")))]
903 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
908 (define_insn "*mulqi3_enh"
909 [(set (match_operand:QI 0 "register_operand" "=r")
910 (mult:QI (match_operand:QI 1 "register_operand" "r")
911 (match_operand:QI 2 "register_operand" "r")))]
916 [(set_attr "length" "3")
917 (set_attr "cc" "clobber")])
919 (define_expand "mulqi3_call"
920 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
921 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
922 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
923 (clobber (reg:QI 22))])
924 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
928 (define_insn "*mulqi3_call"
929 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
930 (clobber (reg:QI 22))]
933 [(set_attr "type" "xcall")
934 (set_attr "cc" "clobber")])
936 ;; "umulqi3_highpart"
937 ;; "smulqi3_highpart"
938 (define_insn "<extend_su>mulqi3_highpart"
939 [(set (match_operand:QI 0 "register_operand" "=r")
941 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
942 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
948 [(set_attr "length" "3")
949 (set_attr "cc" "clobber")])
952 ;; Used when expanding div or mod inline for some special values
953 (define_insn "*subqi3.ashiftrt7"
954 [(set (match_operand:QI 0 "register_operand" "=r")
955 (minus:QI (match_operand:QI 1 "register_operand" "0")
956 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
960 [(set_attr "length" "2")
961 (set_attr "cc" "clobber")])
965 (define_insn "<extend_u>mulqihi3"
966 [(set (match_operand:HI 0 "register_operand" "=r")
967 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
968 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
973 [(set_attr "length" "3")
974 (set_attr "cc" "clobber")])
976 (define_insn "usmulqihi3"
977 [(set (match_operand:HI 0 "register_operand" "=r")
978 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
979 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
984 [(set_attr "length" "3")
985 (set_attr "cc" "clobber")])
987 ;; Above insn is not canonicalized by insn combine, so here is a version with
990 (define_insn "*sumulqihi3"
991 [(set (match_operand:HI 0 "register_operand" "=r")
992 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
993 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
998 [(set_attr "length" "3")
999 (set_attr "cc" "clobber")])
1001 ;; One-extend operand 1
1003 (define_insn "*osmulqihi3"
1004 [(set (match_operand:HI 0 "register_operand" "=&r")
1005 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1006 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1012 [(set_attr "length" "4")
1013 (set_attr "cc" "clobber")])
1015 (define_insn "*oumulqihi3"
1016 [(set (match_operand:HI 0 "register_operand" "=&r")
1017 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1018 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1024 [(set_attr "length" "4")
1025 (set_attr "cc" "clobber")])
1027 ;******************************************************************************
1028 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1029 ;******************************************************************************
1031 (define_insn "*maddqi4"
1032 [(set (match_operand:QI 0 "register_operand" "=r")
1033 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1034 (match_operand:QI 2 "register_operand" "r"))
1035 (match_operand:QI 3 "register_operand" "0")))]
1041 [(set_attr "length" "4")
1042 (set_attr "cc" "clobber")])
1044 (define_insn "*msubqi4"
1045 [(set (match_operand:QI 0 "register_operand" "=r")
1046 (minus:QI (match_operand:QI 3 "register_operand" "0")
1047 (mult:QI (match_operand:QI 1 "register_operand" "r")
1048 (match_operand:QI 2 "register_operand" "r"))))]
1053 [(set_attr "length" "4")
1054 (set_attr "cc" "clobber")])
1056 (define_insn_and_split "*maddqi4.const"
1057 [(set (match_operand:QI 0 "register_operand" "=r")
1058 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1059 (match_operand:QI 2 "const_int_operand" "n"))
1060 (match_operand:QI 3 "register_operand" "0")))
1061 (clobber (match_scratch:QI 4 "=&d"))]
1064 "&& reload_completed"
1069 (plus:QI (mult:QI (match_dup 1)
1074 (define_insn_and_split "*msubqi4.const"
1075 [(set (match_operand:QI 0 "register_operand" "=r")
1076 (minus:QI (match_operand:QI 3 "register_operand" "0")
1077 (mult:QI (match_operand:QI 1 "register_operand" "r")
1078 (match_operand:QI 2 "const_int_operand" "n"))))
1079 (clobber (match_scratch:QI 4 "=&d"))]
1082 "&& reload_completed"
1087 (minus:QI (match_dup 3)
1088 (mult:QI (match_dup 1)
1093 ;******************************************************************************
1094 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1095 ;******************************************************************************
1097 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1100 ;; int foo (unsigned char z)
1102 ;; extern int aInt[];
1103 ;; return aInt[3*z+2];
1106 ;; because the constant +4 then is added explicitely instead of consuming it
1107 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1108 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1109 ;; The implementational effort is the same so we are fine with that approach.
1114 (define_insn "*<extend_u>maddqihi4"
1115 [(set (match_operand:HI 0 "register_operand" "=r")
1116 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1117 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1118 (match_operand:HI 3 "register_operand" "0")))]
1121 "mul<extend_s> %1,%2
1125 [(set_attr "length" "4")
1126 (set_attr "cc" "clobber")])
1130 (define_insn "*<extend_u>msubqihi4"
1131 [(set (match_operand:HI 0 "register_operand" "=r")
1132 (minus:HI (match_operand:HI 3 "register_operand" "0")
1133 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1134 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1136 "mul<extend_s> %1,%2
1140 [(set_attr "length" "4")
1141 (set_attr "cc" "clobber")])
1145 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1146 [(set (match_operand:HI 0 "register_operand" "=r")
1147 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1148 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1149 (match_operand:HI 3 "register_operand" "0")))]
1152 && <any_extend:CODE> != <any_extend2:CODE>"
1154 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1155 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1157 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1159 [(set_attr "length" "4")
1160 (set_attr "cc" "clobber")])
1164 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1165 [(set (match_operand:HI 0 "register_operand" "=r")
1166 (minus:HI (match_operand:HI 3 "register_operand" "0")
1167 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1168 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1171 && <any_extend:CODE> != <any_extend2:CODE>"
1173 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1174 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1176 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1178 [(set_attr "length" "4")
1179 (set_attr "cc" "clobber")])
1181 ;; Handle small constants
1183 ;; "umaddqihi4.uconst"
1184 ;; "maddqihi4.sconst"
1185 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1186 [(set (match_operand:HI 0 "register_operand" "=r")
1187 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1188 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1189 (match_operand:HI 3 "register_operand" "0")))
1190 (clobber (match_scratch:QI 4 "=&d"))]
1193 "&& reload_completed"
1196 ; *umaddqihi4 resp. *maddqihi4
1198 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1199 (any_extend:HI (match_dup 4)))
1202 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1205 ;; "*umsubqihi4.uconst"
1206 ;; "*msubqihi4.sconst"
1207 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1208 [(set (match_operand:HI 0 "register_operand" "=r")
1209 (minus:HI (match_operand:HI 3 "register_operand" "0")
1210 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1211 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1212 (clobber (match_scratch:QI 4 "=&d"))]
1215 "&& reload_completed"
1218 ; *umsubqihi4 resp. *msubqihi4
1220 (minus:HI (match_dup 3)
1221 (mult:HI (any_extend:HI (match_dup 1))
1222 (any_extend:HI (match_dup 4)))))]
1224 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1227 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1228 ;; for MULT with power of 2 and skips trying MULT insn above.
1230 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1231 [(set (match_operand:HI 0 "register_operand" "=r")
1232 (minus:HI (match_operand:HI 3 "register_operand" "0")
1233 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1234 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1235 (clobber (match_scratch:QI 4 "=&d"))]
1238 "&& reload_completed"
1243 (minus:HI (match_dup 3)
1244 (mult:HI (zero_extend:HI (match_dup 1))
1245 (zero_extend:HI (match_dup 4)))))]
1247 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1250 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1251 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1252 ;; because this would require an extra pattern for just one value.
1254 (define_insn_and_split "*msubqihi4.sconst.ashift"
1255 [(set (match_operand:HI 0 "register_operand" "=r")
1256 (minus:HI (match_operand:HI 3 "register_operand" "0")
1257 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1258 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1259 (clobber (match_scratch:QI 4 "=&d"))]
1262 "&& reload_completed"
1267 (minus:HI (match_dup 3)
1268 (mult:HI (sign_extend:HI (match_dup 1))
1269 (sign_extend:HI (match_dup 4)))))]
1271 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1274 ;; For signed/unsigned combinations that require narrow constraint "a"
1275 ;; just provide a pattern if signed/unsigned combination is actually needed.
1277 (define_insn_and_split "*sumaddqihi4.uconst"
1278 [(set (match_operand:HI 0 "register_operand" "=r")
1279 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1280 (match_operand:HI 2 "u8_operand" "M"))
1281 (match_operand:HI 3 "register_operand" "0")))
1282 (clobber (match_scratch:QI 4 "=&a"))]
1284 && !s8_operand (operands[2], VOIDmode)"
1286 "&& reload_completed"
1291 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1292 (zero_extend:HI (match_dup 4)))
1295 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1298 (define_insn_and_split "*sumsubqihi4.uconst"
1299 [(set (match_operand:HI 0 "register_operand" "=r")
1300 (minus:HI (match_operand:HI 3 "register_operand" "0")
1301 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1302 (match_operand:HI 2 "u8_operand" "M"))))
1303 (clobber (match_scratch:QI 4 "=&a"))]
1305 && !s8_operand (operands[2], VOIDmode)"
1307 "&& reload_completed"
1312 (minus:HI (match_dup 3)
1313 (mult:HI (sign_extend:HI (match_dup 1))
1314 (zero_extend:HI (match_dup 4)))))]
1316 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1319 ;******************************************************************************
1320 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1321 ;******************************************************************************
1323 ;; "*muluqihi3.uconst"
1324 ;; "*mulsqihi3.sconst"
1325 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1326 [(set (match_operand:HI 0 "register_operand" "=r")
1327 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1328 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1329 (clobber (match_scratch:QI 3 "=&d"))]
1332 "&& reload_completed"
1335 ; umulqihi3 resp. mulqihi3
1337 (mult:HI (any_extend:HI (match_dup 1))
1338 (any_extend:HI (match_dup 3))))]
1340 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1343 (define_insn_and_split "*muluqihi3.sconst"
1344 [(set (match_operand:HI 0 "register_operand" "=r")
1345 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1346 (match_operand:HI 2 "s8_operand" "n")))
1347 (clobber (match_scratch:QI 3 "=&a"))]
1350 "&& reload_completed"
1355 (mult:HI (zero_extend:HI (match_dup 1))
1356 (sign_extend:HI (match_dup 3))))]
1358 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1361 (define_insn_and_split "*mulsqihi3.uconst"
1362 [(set (match_operand:HI 0 "register_operand" "=r")
1363 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1364 (match_operand:HI 2 "u8_operand" "M")))
1365 (clobber (match_scratch:QI 3 "=&a"))]
1368 "&& reload_completed"
1373 (mult:HI (zero_extend:HI (match_dup 3))
1374 (sign_extend:HI (match_dup 1))))]
1376 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1379 (define_insn_and_split "*mulsqihi3.oconst"
1380 [(set (match_operand:HI 0 "register_operand" "=&r")
1381 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1382 (match_operand:HI 2 "o8_operand" "n")))
1383 (clobber (match_scratch:QI 3 "=&a"))]
1386 "&& reload_completed"
1391 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1392 (sign_extend:HI (match_dup 1))))]
1394 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1397 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1398 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1399 ;; at that time. Fix that.
1401 (define_insn "*ashiftqihi2.signx.1"
1402 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1403 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1407 lsl %A0\;sbc %B0,%B0
1408 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1409 [(set_attr "length" "2,3")
1410 (set_attr "cc" "clobber")])
1412 (define_insn_and_split "*ashifthi3.signx.const"
1413 [(set (match_operand:HI 0 "register_operand" "=r")
1414 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1415 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1416 (clobber (match_scratch:QI 3 "=&d"))]
1419 "&& reload_completed"
1424 (mult:HI (sign_extend:HI (match_dup 1))
1425 (sign_extend:HI (match_dup 3))))]
1427 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1430 (define_insn_and_split "*ashifthi3.signx.const7"
1431 [(set (match_operand:HI 0 "register_operand" "=r")
1432 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1434 (clobber (match_scratch:QI 2 "=&a"))]
1437 "&& reload_completed"
1442 (mult:HI (zero_extend:HI (match_dup 2))
1443 (sign_extend:HI (match_dup 1))))]
1445 operands[3] = gen_int_mode (1 << 7, QImode);
1448 (define_insn_and_split "*ashifthi3.zerox.const"
1449 [(set (match_operand:HI 0 "register_operand" "=r")
1450 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1451 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1452 (clobber (match_scratch:QI 3 "=&d"))]
1455 "&& reload_completed"
1460 (mult:HI (zero_extend:HI (match_dup 1))
1461 (zero_extend:HI (match_dup 3))))]
1463 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1466 ;******************************************************************************
1467 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1468 ;******************************************************************************
1470 (define_insn "mulsqihi3"
1471 [(set (match_operand:HI 0 "register_operand" "=&r")
1472 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1473 (match_operand:HI 2 "register_operand" "a")))]
1480 [(set_attr "length" "5")
1481 (set_attr "cc" "clobber")])
1483 (define_insn "muluqihi3"
1484 [(set (match_operand:HI 0 "register_operand" "=&r")
1485 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1486 (match_operand:HI 2 "register_operand" "r")))]
1493 [(set_attr "length" "5")
1494 (set_attr "cc" "clobber")])
1496 ;; one-extend operand 1
1498 (define_insn "muloqihi3"
1499 [(set (match_operand:HI 0 "register_operand" "=&r")
1500 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1501 (match_operand:HI 2 "register_operand" "r")))]
1509 [(set_attr "length" "6")
1510 (set_attr "cc" "clobber")])
1512 ;******************************************************************************
1514 (define_expand "mulhi3"
1515 [(set (match_operand:HI 0 "register_operand" "")
1516 (mult:HI (match_operand:HI 1 "register_operand" "")
1517 (match_operand:HI 2 "register_or_s9_operand" "")))]
1522 if (!register_operand (operands[2], HImode))
1523 operands[2] = force_reg (HImode, operands[2]);
1525 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1529 /* For small constants we can do better by extending them on the fly.
1530 The constant can be loaded in one instruction and the widening
1531 multiplication is shorter. First try the unsigned variant because it
1532 allows constraint "d" instead of "a" for the signed version. */
1534 if (s9_operand (operands[2], HImode))
1536 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1538 if (u8_operand (operands[2], HImode))
1540 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1542 else if (s8_operand (operands[2], HImode))
1544 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1548 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1554 if (!register_operand (operands[2], HImode))
1555 operands[2] = force_reg (HImode, operands[2]);
1558 (define_insn "*mulhi3_enh"
1559 [(set (match_operand:HI 0 "register_operand" "=&r")
1560 (mult:HI (match_operand:HI 1 "register_operand" "r")
1561 (match_operand:HI 2 "register_operand" "r")))]
1570 [(set_attr "length" "7")
1571 (set_attr "cc" "clobber")])
1573 (define_expand "mulhi3_call"
1574 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1575 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1576 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1577 (clobber (reg:HI 22))
1578 (clobber (reg:QI 21))])
1579 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1583 (define_insn "*mulhi3_call"
1584 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1585 (clobber (reg:HI 22))
1586 (clobber (reg:QI 21))]
1589 [(set_attr "type" "xcall")
1590 (set_attr "cc" "clobber")])
1592 ;; To support widening multiplicatioon with constant we postpone
1593 ;; expanding to the implicit library call until post combine and
1594 ;; prior to register allocation. Clobber all hard registers that
1595 ;; might be used by the (widening) multiply until it is split and
1596 ;; it's final register footprint is worked out.
1598 (define_expand "mulsi3"
1599 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1600 (mult:SI (match_operand:SI 1 "register_operand" "")
1601 (match_operand:SI 2 "nonmemory_operand" "")))
1602 (clobber (reg:HI 26))
1603 (clobber (reg:DI 18))])]
1606 if (u16_operand (operands[2], SImode))
1608 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1609 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1613 if (o16_operand (operands[2], SImode))
1615 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1616 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1621 (define_insn_and_split "*mulsi3"
1622 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1623 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
1624 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1625 (clobber (reg:HI 26))
1626 (clobber (reg:DI 18))]
1627 "AVR_HAVE_MUL && !reload_completed"
1628 { gcc_unreachable(); }
1634 (parallel [(set (reg:SI 22)
1635 (mult:SI (reg:SI 22)
1637 (clobber (reg:HI 26))])
1641 if (u16_operand (operands[2], SImode))
1643 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1644 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1648 if (o16_operand (operands[2], SImode))
1650 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1651 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1658 (define_insn_and_split "mulu<mode>si3"
1659 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1660 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1661 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1662 (clobber (reg:HI 26))
1663 (clobber (reg:DI 18))]
1664 "AVR_HAVE_MUL && !reload_completed"
1665 { gcc_unreachable(); }
1672 (mult:SI (zero_extend:SI (reg:HI 26))
1677 /* Do the QI -> HI extension explicitely before the multiplication. */
1678 /* Do the HI -> SI extension implicitely and after the multiplication. */
1680 if (QImode == <MODE>mode)
1681 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
1683 if (u16_operand (operands[2], SImode))
1685 operands[1] = force_reg (HImode, operands[1]);
1686 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1687 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
1694 (define_insn_and_split "muls<mode>si3"
1695 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1696 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1697 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1698 (clobber (reg:HI 26))
1699 (clobber (reg:DI 18))]
1700 "AVR_HAVE_MUL && !reload_completed"
1701 { gcc_unreachable(); }
1708 (mult:SI (sign_extend:SI (reg:HI 26))
1713 /* Do the QI -> HI extension explicitely before the multiplication. */
1714 /* Do the HI -> SI extension implicitely and after the multiplication. */
1716 if (QImode == <MODE>mode)
1717 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
1719 if (u16_operand (operands[2], SImode)
1720 || s16_operand (operands[2], SImode))
1722 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1724 operands[1] = force_reg (HImode, operands[1]);
1726 if (u16_operand (operands[2], SImode))
1727 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
1729 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
1735 ;; One-extend operand 1
1737 (define_insn_and_split "mulohisi3"
1738 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1739 (mult:SI (not:SI (zero_extend:SI
1740 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
1741 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1742 (clobber (reg:HI 26))
1743 (clobber (reg:DI 18))]
1744 "AVR_HAVE_MUL && !reload_completed"
1745 { gcc_unreachable(); }
1752 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1760 (define_expand "<extend_u>mulhisi3"
1761 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1762 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
1763 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
1764 (clobber (reg:HI 26))
1765 (clobber (reg:DI 18))])]
1769 (define_expand "usmulhisi3"
1770 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1771 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1772 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1773 (clobber (reg:HI 26))
1774 (clobber (reg:DI 18))])]
1778 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
1779 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
1780 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
1781 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
1782 (define_insn_and_split
1783 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
1784 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1785 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1786 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
1787 (clobber (reg:HI 26))
1788 (clobber (reg:DI 18))]
1789 "AVR_HAVE_MUL && !reload_completed"
1790 { gcc_unreachable(); }
1797 (mult:SI (match_dup 3)
1802 rtx xop1 = operands[1];
1803 rtx xop2 = operands[2];
1805 /* Do the QI -> HI extension explicitely before the multiplication. */
1806 /* Do the HI -> SI extension implicitely and after the multiplication. */
1808 if (QImode == <QIHI:MODE>mode)
1809 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
1811 if (QImode == <QIHI2:MODE>mode)
1812 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
1814 if (<any_extend:CODE> == <any_extend2:CODE>
1815 || <any_extend:CODE> == ZERO_EXTEND)
1819 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
1820 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
1824 /* <any_extend:CODE> = SIGN_EXTEND */
1825 /* <any_extend2:CODE> = ZERO_EXTEND */
1829 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
1830 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
1834 ;; "smulhi3_highpart"
1835 ;; "umulhi3_highpart"
1836 (define_expand "<extend_su>mulhi3_highpart"
1838 (match_operand:HI 1 "nonmemory_operand" ""))
1840 (match_operand:HI 2 "nonmemory_operand" ""))
1841 (parallel [(set (reg:HI 24)
1842 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1843 (any_extend:SI (reg:HI 26)))
1845 (clobber (reg:HI 22))])
1846 (set (match_operand:HI 0 "register_operand" "")
1852 (define_insn "*mulsi3_call"
1854 (mult:SI (reg:SI 22)
1856 (clobber (reg:HI 26))]
1859 [(set_attr "type" "xcall")
1860 (set_attr "cc" "clobber")])
1863 ;; "*umulhisi3_call"
1864 (define_insn "*<extend_u>mulhisi3_call"
1866 (mult:SI (any_extend:SI (reg:HI 18))
1867 (any_extend:SI (reg:HI 26))))]
1869 "%~call __<extend_u>mulhisi3"
1870 [(set_attr "type" "xcall")
1871 (set_attr "cc" "clobber")])
1873 ;; "*umulhi3_highpart_call"
1874 ;; "*smulhi3_highpart_call"
1875 (define_insn "*<extend_su>mulhi3_highpart_call"
1877 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1878 (any_extend:SI (reg:HI 26)))
1880 (clobber (reg:HI 22))]
1882 "%~call __<extend_u>mulhisi3"
1883 [(set_attr "type" "xcall")
1884 (set_attr "cc" "clobber")])
1886 (define_insn "*usmulhisi3_call"
1888 (mult:SI (zero_extend:SI (reg:HI 18))
1889 (sign_extend:SI (reg:HI 26))))]
1891 "%~call __usmulhisi3"
1892 [(set_attr "type" "xcall")
1893 (set_attr "cc" "clobber")])
1895 (define_insn "*mul<extend_su>hisi3_call"
1897 (mult:SI (any_extend:SI (reg:HI 26))
1900 "%~call __mul<extend_su>hisi3"
1901 [(set_attr "type" "xcall")
1902 (set_attr "cc" "clobber")])
1904 (define_insn "*mulohisi3_call"
1906 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1909 "%~call __mulohisi3"
1910 [(set_attr "type" "xcall")
1911 (set_attr "cc" "clobber")])
1913 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1916 ;; Generate libgcc.S calls ourselves, because:
1917 ;; - we know exactly which registers are clobbered (for QI and HI
1918 ;; modes, some of the call-used registers are preserved)
1919 ;; - we get both the quotient and the remainder at no extra cost
1920 ;; - we split the patterns only after the first CSE passes because
1921 ;; CSE has problems to operate on hard regs.
1923 (define_insn_and_split "divmodqi4"
1924 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1925 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
1926 (match_operand:QI 2 "pseudo_register_operand" "")))
1927 (set (match_operand:QI 3 "pseudo_register_operand" "")
1928 (mod:QI (match_dup 1) (match_dup 2)))
1929 (clobber (reg:QI 22))
1930 (clobber (reg:QI 23))
1931 (clobber (reg:QI 24))
1932 (clobber (reg:QI 25))])]
1934 "this divmodqi4 pattern should have been splitted;"
1936 [(set (reg:QI 24) (match_dup 1))
1937 (set (reg:QI 22) (match_dup 2))
1938 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1939 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1940 (clobber (reg:QI 22))
1941 (clobber (reg:QI 23))])
1942 (set (match_dup 0) (reg:QI 24))
1943 (set (match_dup 3) (reg:QI 25))]
1946 (define_insn "*divmodqi4_call"
1947 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1948 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1949 (clobber (reg:QI 22))
1950 (clobber (reg:QI 23))]
1952 "%~call __divmodqi4"
1953 [(set_attr "type" "xcall")
1954 (set_attr "cc" "clobber")])
1956 (define_insn_and_split "udivmodqi4"
1957 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1958 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
1959 (match_operand:QI 2 "pseudo_register_operand" "")))
1960 (set (match_operand:QI 3 "pseudo_register_operand" "")
1961 (umod:QI (match_dup 1) (match_dup 2)))
1962 (clobber (reg:QI 22))
1963 (clobber (reg:QI 23))
1964 (clobber (reg:QI 24))
1965 (clobber (reg:QI 25))])]
1967 "this udivmodqi4 pattern should have been splitted;"
1969 [(set (reg:QI 24) (match_dup 1))
1970 (set (reg:QI 22) (match_dup 2))
1971 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1972 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1973 (clobber (reg:QI 23))])
1974 (set (match_dup 0) (reg:QI 24))
1975 (set (match_dup 3) (reg:QI 25))]
1978 (define_insn "*udivmodqi4_call"
1979 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1980 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1981 (clobber (reg:QI 23))]
1983 "%~call __udivmodqi4"
1984 [(set_attr "type" "xcall")
1985 (set_attr "cc" "clobber")])
1987 (define_insn_and_split "divmodhi4"
1988 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1989 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
1990 (match_operand:HI 2 "pseudo_register_operand" "")))
1991 (set (match_operand:HI 3 "pseudo_register_operand" "")
1992 (mod:HI (match_dup 1) (match_dup 2)))
1993 (clobber (reg:QI 21))
1994 (clobber (reg:HI 22))
1995 (clobber (reg:HI 24))
1996 (clobber (reg:HI 26))])]
1998 "this should have been splitted;"
2000 [(set (reg:HI 24) (match_dup 1))
2001 (set (reg:HI 22) (match_dup 2))
2002 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2003 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2004 (clobber (reg:HI 26))
2005 (clobber (reg:QI 21))])
2006 (set (match_dup 0) (reg:HI 22))
2007 (set (match_dup 3) (reg:HI 24))]
2010 (define_insn "*divmodhi4_call"
2011 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2012 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2013 (clobber (reg:HI 26))
2014 (clobber (reg:QI 21))]
2016 "%~call __divmodhi4"
2017 [(set_attr "type" "xcall")
2018 (set_attr "cc" "clobber")])
2020 (define_insn_and_split "udivmodhi4"
2021 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2022 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2023 (match_operand:HI 2 "pseudo_register_operand" "")))
2024 (set (match_operand:HI 3 "pseudo_register_operand" "")
2025 (umod:HI (match_dup 1) (match_dup 2)))
2026 (clobber (reg:QI 21))
2027 (clobber (reg:HI 22))
2028 (clobber (reg:HI 24))
2029 (clobber (reg:HI 26))])]
2031 "this udivmodhi4 pattern should have been splitted.;"
2033 [(set (reg:HI 24) (match_dup 1))
2034 (set (reg:HI 22) (match_dup 2))
2035 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2036 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2037 (clobber (reg:HI 26))
2038 (clobber (reg:QI 21))])
2039 (set (match_dup 0) (reg:HI 22))
2040 (set (match_dup 3) (reg:HI 24))]
2043 (define_insn "*udivmodhi4_call"
2044 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2045 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2046 (clobber (reg:HI 26))
2047 (clobber (reg:QI 21))]
2049 "%~call __udivmodhi4"
2050 [(set_attr "type" "xcall")
2051 (set_attr "cc" "clobber")])
2053 (define_insn_and_split "divmodsi4"
2054 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2055 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2056 (match_operand:SI 2 "pseudo_register_operand" "")))
2057 (set (match_operand:SI 3 "pseudo_register_operand" "")
2058 (mod:SI (match_dup 1) (match_dup 2)))
2059 (clobber (reg:SI 18))
2060 (clobber (reg:SI 22))
2061 (clobber (reg:HI 26))
2062 (clobber (reg:HI 30))])]
2064 "this divmodsi4 pattern should have been splitted;"
2066 [(set (reg:SI 22) (match_dup 1))
2067 (set (reg:SI 18) (match_dup 2))
2068 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2069 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2070 (clobber (reg:HI 26))
2071 (clobber (reg:HI 30))])
2072 (set (match_dup 0) (reg:SI 18))
2073 (set (match_dup 3) (reg:SI 22))]
2076 (define_insn "*divmodsi4_call"
2077 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2078 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2079 (clobber (reg:HI 26))
2080 (clobber (reg:HI 30))]
2082 "%~call __divmodsi4"
2083 [(set_attr "type" "xcall")
2084 (set_attr "cc" "clobber")])
2086 (define_insn_and_split "udivmodsi4"
2087 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2088 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2089 (match_operand:SI 2 "pseudo_register_operand" "")))
2090 (set (match_operand:SI 3 "pseudo_register_operand" "")
2091 (umod:SI (match_dup 1) (match_dup 2)))
2092 (clobber (reg:SI 18))
2093 (clobber (reg:SI 22))
2094 (clobber (reg:HI 26))
2095 (clobber (reg:HI 30))])]
2097 "this udivmodsi4 pattern should have been splitted;"
2099 [(set (reg:SI 22) (match_dup 1))
2100 (set (reg:SI 18) (match_dup 2))
2101 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2102 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2103 (clobber (reg:HI 26))
2104 (clobber (reg:HI 30))])
2105 (set (match_dup 0) (reg:SI 18))
2106 (set (match_dup 3) (reg:SI 22))]
2109 (define_insn "*udivmodsi4_call"
2110 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2111 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2112 (clobber (reg:HI 26))
2113 (clobber (reg:HI 30))]
2115 "%~call __udivmodsi4"
2116 [(set_attr "type" "xcall")
2117 (set_attr "cc" "clobber")])
2119 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2122 (define_insn "andqi3"
2123 [(set (match_operand:QI 0 "register_operand" "=r,d")
2124 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2125 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2130 [(set_attr "length" "1,1")
2131 (set_attr "cc" "set_zn,set_zn")])
2133 (define_insn "andhi3"
2134 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2135 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2136 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2137 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2140 if (which_alternative == 0)
2141 return "and %A0,%A2\;and %B0,%B2";
2142 else if (which_alternative == 1)
2143 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2145 return avr_out_bitop (insn, operands, NULL);
2147 [(set_attr "length" "2,2,2,4,4")
2148 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2149 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2151 (define_insn "andsi3"
2152 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2153 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2154 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2155 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2158 if (which_alternative == 0)
2159 return "and %0,%2" CR_TAB
2160 "and %B0,%B2" CR_TAB
2161 "and %C0,%C2" CR_TAB
2164 return avr_out_bitop (insn, operands, NULL);
2166 [(set_attr "length" "4,4,8,8")
2167 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2168 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2170 (define_peephole2 ; andi
2171 [(set (match_operand:QI 0 "d_register_operand" "")
2172 (and:QI (match_dup 0)
2173 (match_operand:QI 1 "const_int_operand" "")))
2175 (and:QI (match_dup 0)
2176 (match_operand:QI 2 "const_int_operand" "")))]
2178 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2180 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2183 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2186 (define_insn "iorqi3"
2187 [(set (match_operand:QI 0 "register_operand" "=r,d")
2188 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2189 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2194 [(set_attr "length" "1,1")
2195 (set_attr "cc" "set_zn,set_zn")])
2197 (define_insn "iorhi3"
2198 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2199 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2200 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2201 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2204 if (which_alternative == 0)
2205 return "or %A0,%A2\;or %B0,%B2";
2206 else if (which_alternative == 1)
2207 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
2209 return avr_out_bitop (insn, operands, NULL);
2211 [(set_attr "length" "2,2,2,4,4")
2212 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2213 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2215 (define_insn "iorsi3"
2216 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2217 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2218 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2219 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2222 if (which_alternative == 0)
2223 return "or %0,%2" CR_TAB
2228 return avr_out_bitop (insn, operands, NULL);
2230 [(set_attr "length" "4,4,8,8")
2231 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2232 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2234 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2237 (define_insn "xorqi3"
2238 [(set (match_operand:QI 0 "register_operand" "=r")
2239 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2240 (match_operand:QI 2 "register_operand" "r")))]
2243 [(set_attr "length" "1")
2244 (set_attr "cc" "set_zn")])
2246 (define_insn "xorhi3"
2247 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
2248 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
2249 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
2250 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2253 if (which_alternative == 0)
2254 return "eor %A0,%A2\;eor %B0,%B2";
2256 return avr_out_bitop (insn, operands, NULL);
2258 [(set_attr "length" "2,2,4")
2259 (set_attr "adjust_len" "*,out_bitop,out_bitop")
2260 (set_attr "cc" "set_n,clobber,clobber")])
2262 (define_insn "xorsi3"
2263 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
2264 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
2265 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
2266 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2269 if (which_alternative == 0)
2270 return "eor %0,%2" CR_TAB
2271 "eor %B0,%B2" CR_TAB
2272 "eor %C0,%C2" CR_TAB
2275 return avr_out_bitop (insn, operands, NULL);
2277 [(set_attr "length" "4,8,8")
2278 (set_attr "adjust_len" "*,out_bitop,out_bitop")
2279 (set_attr "cc" "set_n,clobber,clobber")])
2281 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
2284 (define_expand "rotlqi3"
2285 [(set (match_operand:QI 0 "register_operand" "")
2286 (rotate:QI (match_operand:QI 1 "register_operand" "")
2287 (match_operand:QI 2 "const_0_to_7_operand" "")))]
2290 if (!CONST_INT_P (operands[2]))
2293 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
2296 ;; Expander used by __builtin_avr_swap
2297 (define_expand "rotlqi3_4"
2298 [(set (match_operand:QI 0 "register_operand" "")
2299 (rotate:QI (match_operand:QI 1 "register_operand" "")
2302 (define_insn "*rotlqi3"
2303 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
2304 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
2305 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
2308 lsl %0\;adc %0,__zero_reg__
2309 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
2310 swap %0\;bst %0,0\;ror %0\;bld %0,7
2312 swap %0\;lsl %0\;adc %0,__zero_reg__
2313 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
2314 bst %0,0\;ror %0\;bld %0,7
2316 [(set_attr "length" "2,4,4,1,3,5,3,0")
2317 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
2319 ;; Split all rotates of HI,SI and DImode registers where rotation is by
2320 ;; a whole number of bytes. The split creates the appropriate moves and
2321 ;; considers all overlap situations. DImode is split before reload.
2323 ;; HImode does not need scratch. Use attribute for this constraint.
2324 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
2326 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
2327 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
2332 (define_expand "rotl<mode>3"
2333 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
2334 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2335 (match_operand:VOID 2 "const_int_operand" "")))
2336 (clobber (match_dup 3))])]
2341 if (!CONST_INT_P (operands[2]))
2344 offset = INTVAL (operands[2]);
2346 if (0 == offset % 8)
2348 if (AVR_HAVE_MOVW && 0 == offset % 16)
2349 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2351 operands[3] = gen_rtx_SCRATCH (QImode);
2353 else if (<MODE>mode != DImode
2355 || offset == GET_MODE_BITSIZE (<MODE>mode) -1))
2357 /*; Support rotate left/right by 1 */
2359 emit_move_insn (operands[0],
2360 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
2367 (define_insn "*rotlhi2.1"
2368 [(set (match_operand:HI 0 "register_operand" "=r")
2369 (rotate:HI (match_operand:HI 1 "register_operand" "0")
2372 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
2373 [(set_attr "length" "3")
2374 (set_attr "cc" "clobber")])
2376 (define_insn "*rotlhi2.15"
2377 [(set (match_operand:HI 0 "register_operand" "=r")
2378 (rotate:HI (match_operand:HI 1 "register_operand" "0")
2381 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
2382 [(set_attr "length" "3")
2383 (set_attr "cc" "clobber")])
2385 (define_insn "*rotlsi2.1"
2386 [(set (match_operand:SI 0 "register_operand" "=r")
2387 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2390 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
2391 [(set_attr "length" "5")
2392 (set_attr "cc" "clobber")])
2394 (define_insn "*rotlsi2.31"
2395 [(set (match_operand:SI 0 "register_operand" "=r")
2396 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2399 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
2400 [(set_attr "length" "6")
2401 (set_attr "cc" "clobber")])
2403 ;; Overlapping non-HImode registers often (but not always) need a scratch.
2404 ;; The best we can do is use early clobber alternative "#&r" so that
2405 ;; completely non-overlapping operands dont get a scratch but # so register
2406 ;; allocation does not prefer non-overlapping.
2409 ;; Split word aligned rotates using scratch that is mode dependent.
2414 (define_insn_and_split "*rotw<mode>"
2415 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2416 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2417 (match_operand 2 "const_int_operand" "n,n,n")))
2418 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2420 && CONST_INT_P (operands[2])
2421 && 0 == INTVAL (operands[2]) % 16"
2423 "&& (reload_completed || <MODE>mode == DImode)"
2426 avr_rotate_bytes (operands);
2431 ;; Split byte aligned rotates using scratch that is always QI mode.
2436 (define_insn_and_split "*rotb<mode>"
2437 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2438 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2439 (match_operand 2 "const_int_operand" "n,n,n")))
2440 (clobber (match_scratch:QI 3 "=<rotx>"))]
2441 "CONST_INT_P (operands[2])
2442 && (8 == INTVAL (operands[2]) % 16
2444 && 0 == INTVAL (operands[2]) % 16))"
2446 "&& (reload_completed || <MODE>mode == DImode)"
2449 avr_rotate_bytes (operands);
2454 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2455 ;; arithmetic shift left
2457 (define_expand "ashlqi3"
2458 [(set (match_operand:QI 0 "register_operand" "")
2459 (ashift:QI (match_operand:QI 1 "register_operand" "")
2460 (match_operand:QI 2 "general_operand" "")))]
2464 (define_split ; ashlqi3_const4
2465 [(set (match_operand:QI 0 "d_register_operand" "")
2466 (ashift:QI (match_dup 0)
2469 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2470 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2473 (define_split ; ashlqi3_const5
2474 [(set (match_operand:QI 0 "d_register_operand" "")
2475 (ashift:QI (match_dup 0)
2478 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2479 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2480 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2483 (define_split ; ashlqi3_const6
2484 [(set (match_operand:QI 0 "d_register_operand" "")
2485 (ashift:QI (match_dup 0)
2488 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2489 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2490 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2493 (define_insn "*ashlqi3"
2494 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2495 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2496 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2498 "* return ashlqi3_out (insn, operands, NULL);"
2499 [(set_attr "length" "5,0,1,2,4,6,9")
2500 (set_attr "adjust_len" "ashlqi")
2501 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2503 (define_insn "ashlhi3"
2504 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2505 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2506 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2508 "* return ashlhi3_out (insn, operands, NULL);"
2509 [(set_attr "length" "6,0,2,2,4,10,10")
2510 (set_attr "adjust_len" "ashlhi")
2511 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2514 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
2515 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
2519 (define_insn_and_split "*ashl<extend_su>qihiqi3"
2520 [(set (match_operand:QI 0 "register_operand" "=r")
2521 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
2522 (match_operand:QI 2 "register_operand" "r"))
2528 (ashift:QI (match_dup 1)
2532 ;; ??? Combiner does not recognize that it could split the following insn;
2533 ;; presumably because he has no register handy?
2535 ;; "*ashluqihiqi3.mem"
2536 ;; "*ashlsqihiqi3.mem"
2537 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
2538 [(set (match_operand:QI 0 "memory_operand" "=m")
2539 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
2540 (match_operand:QI 2 "register_operand" "r"))
2543 { gcc_unreachable(); }
2546 (ashift:QI (match_dup 1)
2551 operands[3] = gen_reg_rtx (QImode);
2556 (define_insn_and_split "*ashlhiqi3"
2557 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
2558 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
2559 (match_operand:QI 2 "register_operand" "r")) 0))]
2561 { gcc_unreachable(); }
2564 (ashift:QI (match_dup 3)
2569 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
2570 operands[4] = gen_reg_rtx (QImode);
2573 ;; High part of 16-bit shift is unused after the instruction:
2574 ;; No need to compute it, map to 8-bit shift.
2577 [(set (match_operand:HI 0 "register_operand" "")
2578 (ashift:HI (match_dup 0)
2579 (match_operand:QI 1 "register_operand" "")))]
2582 (ashift:QI (match_dup 2)
2584 (clobber (match_dup 3))]
2586 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
2588 if (!peep2_reg_dead_p (1, operands[3]))
2591 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
2595 (define_insn "ashlsi3"
2596 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2597 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2598 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2600 "* return ashlsi3_out (insn, operands, NULL);"
2601 [(set_attr "length" "8,0,4,4,8,10,12")
2602 (set_attr "adjust_len" "ashlsi")
2603 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2605 ;; Optimize if a scratch register from LD_REGS happens to be available.
2607 (define_peephole2 ; ashlqi3_l_const4
2608 [(set (match_operand:QI 0 "l_register_operand" "")
2609 (ashift:QI (match_dup 0)
2611 (match_scratch:QI 1 "d")]
2613 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2614 (set (match_dup 1) (const_int -16))
2615 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2618 (define_peephole2 ; ashlqi3_l_const5
2619 [(set (match_operand:QI 0 "l_register_operand" "")
2620 (ashift:QI (match_dup 0)
2622 (match_scratch:QI 1 "d")]
2624 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2625 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2626 (set (match_dup 1) (const_int -32))
2627 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2630 (define_peephole2 ; ashlqi3_l_const6
2631 [(set (match_operand:QI 0 "l_register_operand" "")
2632 (ashift:QI (match_dup 0)
2634 (match_scratch:QI 1 "d")]
2636 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2637 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2638 (set (match_dup 1) (const_int -64))
2639 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2643 [(match_scratch:QI 3 "d")
2644 (set (match_operand:HI 0 "register_operand" "")
2645 (ashift:HI (match_operand:HI 1 "register_operand" "")
2646 (match_operand:QI 2 "const_int_operand" "")))]
2648 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
2649 (clobber (match_dup 3))])]
2652 (define_insn "*ashlhi3_const"
2653 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2654 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2655 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2656 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2658 "* return ashlhi3_out (insn, operands, NULL);"
2659 [(set_attr "length" "0,2,2,4,10")
2660 (set_attr "adjust_len" "ashlhi")
2661 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
2664 [(match_scratch:QI 3 "d")
2665 (set (match_operand:SI 0 "register_operand" "")
2666 (ashift:SI (match_operand:SI 1 "register_operand" "")
2667 (match_operand:QI 2 "const_int_operand" "")))]
2669 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2670 (clobber (match_dup 3))])]
2673 (define_insn "*ashlsi3_const"
2674 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2675 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2676 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2677 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2679 "* return ashlsi3_out (insn, operands, NULL);"
2680 [(set_attr "length" "0,4,4,10")
2681 (set_attr "adjust_len" "ashlsi")
2682 (set_attr "cc" "none,set_n,clobber,clobber")])
2684 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2685 ;; arithmetic shift right
2687 (define_insn "ashrqi3"
2688 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
2689 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
2690 (match_operand:QI 2 "general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
2692 "* return ashrqi3_out (insn, operands, NULL);"
2693 [(set_attr "length" "5,0,1,2,5,4,9")
2694 (set_attr "adjust_len" "ashrqi")
2695 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
2697 (define_insn "ashrhi3"
2698 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2699 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2700 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2702 "* return ashrhi3_out (insn, operands, NULL);"
2703 [(set_attr "length" "6,0,2,4,4,10,10")
2704 (set_attr "adjust_len" "ashrhi")
2705 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2707 (define_insn "ashrsi3"
2708 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2710 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2712 "* return ashrsi3_out (insn, operands, NULL);"
2713 [(set_attr "length" "8,0,4,6,8,10,12")
2714 (set_attr "adjust_len" "ashrsi")
2715 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2717 ;; Optimize if a scratch register from LD_REGS happens to be available.
2720 [(match_scratch:QI 3 "d")
2721 (set (match_operand:HI 0 "register_operand" "")
2722 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2723 (match_operand:QI 2 "const_int_operand" "")))]
2725 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
2726 (clobber (match_dup 3))])]
2729 (define_insn "*ashrhi3_const"
2730 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2731 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2732 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2733 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2735 "* return ashrhi3_out (insn, operands, NULL);"
2736 [(set_attr "length" "0,2,4,4,10")
2737 (set_attr "adjust_len" "ashrhi")
2738 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
2741 [(match_scratch:QI 3 "d")
2742 (set (match_operand:SI 0 "register_operand" "")
2743 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2744 (match_operand:QI 2 "const_int_operand" "")))]
2746 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2747 (clobber (match_dup 3))])]
2750 (define_insn "*ashrsi3_const"
2751 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2752 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2753 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2754 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2756 "* return ashrsi3_out (insn, operands, NULL);"
2757 [(set_attr "length" "0,4,4,10")
2758 (set_attr "adjust_len" "ashrsi")
2759 (set_attr "cc" "none,clobber,set_n,clobber")])
2761 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2762 ;; logical shift right
2764 (define_expand "lshrqi3"
2765 [(set (match_operand:QI 0 "register_operand" "")
2766 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2767 (match_operand:QI 2 "general_operand" "")))]
2771 (define_split ; lshrqi3_const4
2772 [(set (match_operand:QI 0 "d_register_operand" "")
2773 (lshiftrt:QI (match_dup 0)
2776 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2777 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
2780 (define_split ; lshrqi3_const5
2781 [(set (match_operand:QI 0 "d_register_operand" "")
2782 (lshiftrt:QI (match_dup 0)
2785 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2786 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2787 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
2790 (define_split ; lshrqi3_const6
2791 [(set (match_operand:QI 0 "d_register_operand" "")
2792 (lshiftrt:QI (match_dup 0)
2795 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2796 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2797 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
2800 (define_insn "*lshrqi3"
2801 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2802 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2803 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2805 "* return lshrqi3_out (insn, operands, NULL);"
2806 [(set_attr "length" "5,0,1,2,4,6,9")
2807 (set_attr "adjust_len" "lshrqi")
2808 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2810 (define_insn "lshrhi3"
2811 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2812 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2813 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2815 "* return lshrhi3_out (insn, operands, NULL);"
2816 [(set_attr "length" "6,0,2,2,4,10,10")
2817 (set_attr "adjust_len" "lshrhi")
2818 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2820 (define_insn "lshrsi3"
2821 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2822 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2823 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2825 "* return lshrsi3_out (insn, operands, NULL);"
2826 [(set_attr "length" "8,0,4,4,8,10,12")
2827 (set_attr "adjust_len" "lshrsi")
2828 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2830 ;; Optimize if a scratch register from LD_REGS happens to be available.
2832 (define_peephole2 ; lshrqi3_l_const4
2833 [(set (match_operand:QI 0 "l_register_operand" "")
2834 (lshiftrt:QI (match_dup 0)
2836 (match_scratch:QI 1 "d")]
2838 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2839 (set (match_dup 1) (const_int 15))
2840 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2843 (define_peephole2 ; lshrqi3_l_const5
2844 [(set (match_operand:QI 0 "l_register_operand" "")
2845 (lshiftrt:QI (match_dup 0)
2847 (match_scratch:QI 1 "d")]
2849 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2850 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2851 (set (match_dup 1) (const_int 7))
2852 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2855 (define_peephole2 ; lshrqi3_l_const6
2856 [(set (match_operand:QI 0 "l_register_operand" "")
2857 (lshiftrt:QI (match_dup 0)
2859 (match_scratch:QI 1 "d")]
2861 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2862 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2863 (set (match_dup 1) (const_int 3))
2864 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2868 [(match_scratch:QI 3 "d")
2869 (set (match_operand:HI 0 "register_operand" "")
2870 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2871 (match_operand:QI 2 "const_int_operand" "")))]
2873 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
2874 (clobber (match_dup 3))])]
2877 (define_insn "*lshrhi3_const"
2878 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2879 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2880 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2881 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2883 "* return lshrhi3_out (insn, operands, NULL);"
2884 [(set_attr "length" "0,2,2,4,10")
2885 (set_attr "adjust_len" "lshrhi")
2886 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
2889 [(match_scratch:QI 3 "d")
2890 (set (match_operand:SI 0 "register_operand" "")
2891 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2892 (match_operand:QI 2 "const_int_operand" "")))]
2894 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2895 (clobber (match_dup 3))])]
2898 (define_insn "*lshrsi3_const"
2899 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2900 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2901 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2902 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2904 "* return lshrsi3_out (insn, operands, NULL);"
2905 [(set_attr "length" "0,4,4,10")
2906 (set_attr "adjust_len" "lshrsi")
2907 (set_attr "cc" "none,clobber,clobber,clobber")])
2909 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2912 (define_insn "absqi2"
2913 [(set (match_operand:QI 0 "register_operand" "=r")
2914 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2918 [(set_attr "length" "2")
2919 (set_attr "cc" "clobber")])
2922 (define_insn "abssf2"
2923 [(set (match_operand:SF 0 "register_operand" "=d,r")
2924 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
2929 [(set_attr "length" "1,2")
2930 (set_attr "cc" "set_n,clobber")])
2932 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
2935 (define_insn "negqi2"
2936 [(set (match_operand:QI 0 "register_operand" "=r")
2937 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
2940 [(set_attr "length" "1")
2941 (set_attr "cc" "set_zn")])
2943 (define_insn "neghi2"
2944 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
2945 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
2948 com %B0\;neg %A0\;sbci %B0,lo8(-1)
2949 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
2950 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
2951 [(set_attr "length" "3,4,4")
2952 (set_attr "cc" "set_czn,set_n,set_czn")])
2954 (define_insn "negsi2"
2955 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
2956 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
2959 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
2960 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
2961 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
2962 [(set_attr_alternative "length"
2965 (if_then_else (eq_attr "mcu_have_movw" "yes")
2968 (set_attr "cc" "set_czn,set_n,set_czn")])
2970 (define_insn "negsf2"
2971 [(set (match_operand:SF 0 "register_operand" "=d,r")
2972 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
2976 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
2977 [(set_attr "length" "1,4")
2978 (set_attr "cc" "set_n,set_n")])
2980 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2983 (define_insn "one_cmplqi2"
2984 [(set (match_operand:QI 0 "register_operand" "=r")
2985 (not:QI (match_operand:QI 1 "register_operand" "0")))]
2988 [(set_attr "length" "1")
2989 (set_attr "cc" "set_czn")])
2991 (define_insn "one_cmplhi2"
2992 [(set (match_operand:HI 0 "register_operand" "=r")
2993 (not:HI (match_operand:HI 1 "register_operand" "0")))]
2997 [(set_attr "length" "2")
2998 (set_attr "cc" "set_n")])
3000 (define_insn "one_cmplsi2"
3001 [(set (match_operand:SI 0 "register_operand" "=r")
3002 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3008 [(set_attr "length" "4")
3009 (set_attr "cc" "set_n")])
3011 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3014 ;; We keep combiner from inserting hard registers into the input of sign- and
3015 ;; zero-extends. A hard register in the input operand is not wanted because
3016 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3017 ;; hard register that overlaps these clobbers won't be combined to a widening
3018 ;; multiplication. There is no need for combine to propagate hard registers,
3019 ;; register allocation can do it just as well.
3021 (define_insn "extendqihi2"
3022 [(set (match_operand:HI 0 "register_operand" "=r,r")
3023 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3026 clr %B0\;sbrc %0,7\;com %B0
3027 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3028 [(set_attr "length" "3,4")
3029 (set_attr "cc" "set_n,set_n")])
3031 (define_insn "extendqisi2"
3032 [(set (match_operand:SI 0 "register_operand" "=r,r")
3033 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3036 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3037 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3038 [(set_attr "length" "5,6")
3039 (set_attr "cc" "set_n,set_n")])
3041 (define_insn "extendhisi2"
3042 [(set (match_operand:SI 0 "register_operand" "=r,r")
3043 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
3046 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3047 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3048 [(set_attr_alternative "length"
3050 (if_then_else (eq_attr "mcu_have_movw" "yes")
3053 (set_attr "cc" "set_n,set_n")])
3055 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3058 (define_insn_and_split "zero_extendqihi2"
3059 [(set (match_operand:HI 0 "register_operand" "=r")
3060 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3064 [(set (match_dup 2) (match_dup 1))
3065 (set (match_dup 3) (const_int 0))]
3067 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
3068 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
3070 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
3071 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
3074 (define_insn_and_split "zero_extendqisi2"
3075 [(set (match_operand:SI 0 "register_operand" "=r")
3076 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3080 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
3081 (set (match_dup 3) (const_int 0))]
3083 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3084 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3086 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3087 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3090 (define_insn_and_split "zero_extendhisi2"
3091 [(set (match_operand:SI 0 "register_operand" "=r")
3092 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
3096 [(set (match_dup 2) (match_dup 1))
3097 (set (match_dup 3) (const_int 0))]
3099 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3100 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3102 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3103 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3106 (define_insn_and_split "zero_extendqidi2"
3107 [(set (match_operand:DI 0 "register_operand" "=r")
3108 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3112 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3113 (set (match_dup 3) (const_int 0))]
3115 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3116 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3118 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3119 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3122 (define_insn_and_split "zero_extendhidi2"
3123 [(set (match_operand:DI 0 "register_operand" "=r")
3124 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3128 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3129 (set (match_dup 3) (const_int 0))]
3131 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3132 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3134 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3135 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3138 (define_insn_and_split "zero_extendsidi2"
3139 [(set (match_operand:DI 0 "register_operand" "=r")
3140 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3144 [(set (match_dup 2) (match_dup 1))
3145 (set (match_dup 3) (const_int 0))]
3147 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3148 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3150 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3151 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3154 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
3157 ; Optimize negated tests into reverse compare if overflow is undefined.
3158 (define_insn "*negated_tstqi"
3160 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
3162 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3163 "cp __zero_reg__,%0"
3164 [(set_attr "cc" "compare")
3165 (set_attr "length" "1")])
3167 (define_insn "*reversed_tstqi"
3169 (compare (const_int 0)
3170 (match_operand:QI 0 "register_operand" "r")))]
3172 "cp __zero_reg__,%0"
3173 [(set_attr "cc" "compare")
3174 (set_attr "length" "2")])
3176 (define_insn "*negated_tsthi"
3178 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
3180 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3181 "cp __zero_reg__,%A0
3182 cpc __zero_reg__,%B0"
3183 [(set_attr "cc" "compare")
3184 (set_attr "length" "2")])
3186 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
3187 ;; though it is unused, because this pattern is synthesized by avr_reorg.
3188 (define_insn "*reversed_tsthi"
3190 (compare (const_int 0)
3191 (match_operand:HI 0 "register_operand" "r")))
3192 (clobber (match_scratch:QI 1 "=X"))]
3194 "cp __zero_reg__,%A0
3195 cpc __zero_reg__,%B0"
3196 [(set_attr "cc" "compare")
3197 (set_attr "length" "2")])
3199 (define_insn "*negated_tstsi"
3201 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
3203 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3204 "cp __zero_reg__,%A0
3205 cpc __zero_reg__,%B0
3206 cpc __zero_reg__,%C0
3207 cpc __zero_reg__,%D0"
3208 [(set_attr "cc" "compare")
3209 (set_attr "length" "4")])
3211 (define_insn "*reversed_tstsi"
3213 (compare (const_int 0)
3214 (match_operand:SI 0 "register_operand" "r")))
3215 (clobber (match_scratch:QI 1 "=X"))]
3217 "cp __zero_reg__,%A0
3218 cpc __zero_reg__,%B0
3219 cpc __zero_reg__,%C0
3220 cpc __zero_reg__,%D0"
3221 [(set_attr "cc" "compare")
3222 (set_attr "length" "4")])
3225 (define_insn "*cmpqi"
3227 (compare (match_operand:QI 0 "register_operand" "r,r,d")
3228 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
3234 [(set_attr "cc" "compare,compare,compare")
3235 (set_attr "length" "1,1,1")])
3237 (define_insn "*cmpqi_sign_extend"
3239 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
3240 (match_operand:HI 1 "s8_operand" "n")))]
3243 [(set_attr "cc" "compare")
3244 (set_attr "length" "1")])
3246 (define_insn "*cmphi"
3248 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
3249 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
3250 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
3253 switch (which_alternative)
3257 return avr_out_tsthi (insn, operands, NULL);
3260 return "cp %A0,%A1\;cpc %B0,%B1";
3263 return reg_unused_after (insn, operands[0])
3264 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
3265 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
3268 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
3271 return avr_out_compare (insn, operands, NULL);
3273 [(set_attr "cc" "compare")
3274 (set_attr "length" "1,2,2,3,4,2,4")
3275 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
3278 (define_insn "*cmpsi"
3280 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
3281 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
3282 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
3285 if (0 == which_alternative)
3286 return avr_out_tstsi (insn, operands, NULL);
3287 else if (1 == which_alternative)
3288 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
3290 return avr_out_compare (insn, operands, NULL);
3292 [(set_attr "cc" "compare")
3293 (set_attr "length" "4,4,4,5,8")
3294 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
3297 ;; ----------------------------------------------------------------------
3298 ;; JUMP INSTRUCTIONS
3299 ;; ----------------------------------------------------------------------
3300 ;; Conditional jump instructions
3302 (define_expand "cbranchsi4"
3303 [(parallel [(set (cc0)
3304 (compare (match_operand:SI 1 "register_operand" "")
3305 (match_operand:SI 2 "nonmemory_operand" "")))
3306 (clobber (match_scratch:QI 4 ""))])
3309 (match_operator 0 "ordered_comparison_operator" [(cc0)
3311 (label_ref (match_operand 3 "" ""))
3315 (define_expand "cbranchhi4"
3316 [(parallel [(set (cc0)
3317 (compare (match_operand:HI 1 "register_operand" "")
3318 (match_operand:HI 2 "nonmemory_operand" "")))
3319 (clobber (match_scratch:QI 4 ""))])
3322 (match_operator 0 "ordered_comparison_operator" [(cc0)
3324 (label_ref (match_operand 3 "" ""))
3328 (define_expand "cbranchqi4"
3330 (compare (match_operand:QI 1 "register_operand" "")
3331 (match_operand:QI 2 "nonmemory_operand" "")))
3334 (match_operator 0 "ordered_comparison_operator" [(cc0)
3336 (label_ref (match_operand 3 "" ""))
3341 ;; Test a single bit in a QI/HI/SImode register.
3342 ;; Combine will create zero extract patterns for single bit tests.
3343 ;; permit any mode in source pattern by using VOIDmode.
3345 (define_insn "*sbrx_branch<mode>"
3348 (match_operator 0 "eqne_operator"
3350 (match_operand:VOID 1 "register_operand" "r")
3352 (match_operand 2 "const_int_operand" "n"))
3354 (label_ref (match_operand 3 "" ""))
3357 "* return avr_out_sbxx_branch (insn, operands);"
3358 [(set (attr "length")
3359 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3360 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3362 (if_then_else (eq_attr "mcu_mega" "no")
3365 (set_attr "cc" "clobber")])
3367 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
3368 ;; or for old peepholes.
3369 ;; Fixme - bitwise Mask will not work for DImode
3371 (define_insn "*sbrx_and_branch<mode>"
3374 (match_operator 0 "eqne_operator"
3376 (match_operand:QISI 1 "register_operand" "r")
3377 (match_operand:QISI 2 "single_one_operand" "n"))
3379 (label_ref (match_operand 3 "" ""))
3383 HOST_WIDE_INT bitnumber;
3384 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
3385 operands[2] = GEN_INT (bitnumber);
3386 return avr_out_sbxx_branch (insn, operands);
3388 [(set (attr "length")
3389 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3390 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3392 (if_then_else (eq_attr "mcu_mega" "no")
3395 (set_attr "cc" "clobber")])
3397 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
3399 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3401 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3402 (label_ref (match_operand 1 "" ""))
3405 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
3409 (label_ref (match_dup 1))
3414 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3416 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3417 (label_ref (match_operand 1 "" ""))
3420 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
3424 (label_ref (match_dup 1))
3429 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3431 (clobber (match_operand:HI 2 ""))])
3432 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3433 (label_ref (match_operand 1 "" ""))
3436 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
3438 (label_ref (match_dup 1))
3443 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3445 (clobber (match_operand:HI 2 ""))])
3446 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3447 (label_ref (match_operand 1 "" ""))
3450 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
3452 (label_ref (match_dup 1))
3457 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3459 (clobber (match_operand:SI 2 ""))])
3460 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3461 (label_ref (match_operand 1 "" ""))
3464 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
3466 (label_ref (match_dup 1))
3468 "operands[2] = GEN_INT (-2147483647 - 1);")
3471 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3473 (clobber (match_operand:SI 2 ""))])
3474 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3475 (label_ref (match_operand 1 "" ""))
3478 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
3480 (label_ref (match_dup 1))
3482 "operands[2] = GEN_INT (-2147483647 - 1);")
3484 ;; ************************************************************************
3485 ;; Implementation of conditional jumps here.
3486 ;; Compare with 0 (test) jumps
3487 ;; ************************************************************************
3489 (define_insn "branch"
3491 (if_then_else (match_operator 1 "simple_comparison_operator"
3494 (label_ref (match_operand 0 "" ""))
3498 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3500 [(set_attr "type" "branch")
3501 (set_attr "cc" "clobber")])
3504 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
3505 ;; or optimized in the remainder.
3507 (define_insn "branch_unspec"
3509 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
3512 (label_ref (match_operand 0 "" ""))
3514 ] UNSPEC_IDENTITY))]
3517 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3519 [(set_attr "type" "branch")
3520 (set_attr "cc" "none")])
3522 ;; ****************************************************************
3523 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
3524 ;; Convert them all to proper jumps.
3525 ;; ****************************************************************/
3527 (define_insn "difficult_branch"
3529 (if_then_else (match_operator 1 "difficult_comparison_operator"
3532 (label_ref (match_operand 0 "" ""))
3536 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3537 [(set_attr "type" "branch1")
3538 (set_attr "cc" "clobber")])
3542 (define_insn "rvbranch"
3544 (if_then_else (match_operator 1 "simple_comparison_operator"
3548 (label_ref (match_operand 0 "" ""))))]
3551 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3552 [(set_attr "type" "branch1")
3553 (set_attr "cc" "clobber")])
3555 (define_insn "difficult_rvbranch"
3557 (if_then_else (match_operator 1 "difficult_comparison_operator"
3561 (label_ref (match_operand 0 "" ""))))]
3564 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3565 [(set_attr "type" "branch")
3566 (set_attr "cc" "clobber")])
3568 ;; **************************************************************************
3569 ;; Unconditional and other jump instructions.
3573 (label_ref (match_operand 0 "" "")))]
3576 if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
3577 return AS1 (jmp,%x0);
3578 return AS1 (rjmp,%x0);
3580 [(set (attr "length")
3581 (if_then_else (match_operand 0 "symbol_ref_operand" "")
3582 (if_then_else (eq_attr "mcu_mega" "no")
3585 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
3586 (le (minus (pc) (match_dup 0)) (const_int 2047)))
3589 (set_attr "cc" "none")])
3593 (define_expand "call"
3594 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3595 (match_operand:HI 1 "general_operand" ""))
3596 (use (const_int 0))])]
3597 ;; Operand 1 not used on the AVR.
3598 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3602 (define_expand "sibcall"
3603 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3604 (match_operand:HI 1 "general_operand" ""))
3605 (use (const_int 1))])]
3606 ;; Operand 1 not used on the AVR.
3607 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3613 (define_expand "call_value"
3614 [(parallel[(set (match_operand 0 "register_operand" "")
3615 (call (match_operand:HI 1 "call_insn_operand" "")
3616 (match_operand:HI 2 "general_operand" "")))
3617 (use (const_int 0))])]
3618 ;; Operand 2 not used on the AVR.
3619 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3623 (define_expand "sibcall_value"
3624 [(parallel[(set (match_operand 0 "register_operand" "")
3625 (call (match_operand:HI 1 "call_insn_operand" "")
3626 (match_operand:HI 2 "general_operand" "")))
3627 (use (const_int 1))])]
3628 ;; Operand 2 not used on the AVR.
3629 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3633 (define_insn "*call_insn"
3634 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
3635 (match_operand:HI 1 "general_operand" "X,X,X,X"))
3636 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
3637 ;; Operand 1 not used on the AVR.
3638 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3645 [(set_attr "cc" "clobber")
3646 (set_attr_alternative "length"
3648 (if_then_else (eq_attr "mcu_mega" "yes")
3652 (if_then_else (eq_attr "mcu_mega" "yes")
3656 (define_insn "*call_value_insn"
3657 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
3658 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
3659 (match_operand:HI 2 "general_operand" "X,X,X,X")))
3660 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
3661 ;; Operand 2 not used on the AVR.
3662 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3669 [(set_attr "cc" "clobber")
3670 (set_attr_alternative "length"
3672 (if_then_else (eq_attr "mcu_mega" "yes")
3676 (if_then_else (eq_attr "mcu_mega" "yes")
3684 [(set_attr "cc" "none")
3685 (set_attr "length" "1")])
3689 (define_expand "indirect_jump"
3690 [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
3692 " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
3694 operands[0] = copy_to_mode_reg(HImode, operand0);
3699 (define_insn "*jcindirect_jump"
3700 [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
3703 [(set_attr "length" "2")
3704 (set_attr "cc" "none")])
3707 (define_insn "*njcindirect_jump"
3708 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
3709 "!AVR_HAVE_EIJMP_EICALL"
3712 push %A0\;push %B0\;ret"
3713 [(set_attr "length" "1,3")
3714 (set_attr "cc" "none,none")])
3716 (define_insn "*indirect_jump_avr6"
3717 [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
3718 "AVR_HAVE_EIJMP_EICALL"
3720 [(set_attr "length" "1")
3721 (set_attr "cc" "none")])
3725 ;; Table made from "rjmp" instructions for <=8K devices.
3726 (define_insn "*tablejump_rjmp"
3727 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
3729 (use (label_ref (match_operand 1 "" "")))
3730 (clobber (match_dup 0))]
3731 "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
3734 push %A0\;push %B0\;ret"
3735 [(set_attr "length" "1,3")
3736 (set_attr "cc" "none,none")])
3738 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
3739 (define_insn "*tablejump_lib"
3740 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3742 (use (label_ref (match_operand 1 "" "")))
3743 (clobber (match_dup 0))]
3744 "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
3745 "%~jmp __tablejump2__"
3746 [(set_attr "length" "2")
3747 (set_attr "cc" "clobber")])
3749 (define_insn "*tablejump_enh"
3750 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3752 (use (label_ref (match_operand 1 "" "")))
3753 (clobber (match_dup 0))]
3754 "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
3761 [(set_attr "length" "6")
3762 (set_attr "cc" "clobber")])
3764 (define_insn "*tablejump"
3765 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3767 (use (label_ref (match_operand 1 "" "")))
3768 (clobber (match_dup 0))]
3769 "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
3778 [(set_attr "length" "8")
3779 (set_attr "cc" "clobber")])
3781 (define_expand "casesi"
3783 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
3784 (match_operand:HI 1 "register_operand" "")))
3785 (parallel [(set (cc0)
3786 (compare (match_dup 6)
3787 (match_operand:HI 2 "register_operand" "")))
3788 (clobber (match_scratch:QI 9 ""))])
3791 (if_then_else (gtu (cc0)
3793 (label_ref (match_operand 4 "" ""))
3797 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
3799 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
3800 (use (label_ref (match_dup 3)))
3801 (clobber (match_dup 6))])]
3805 operands[6] = gen_reg_rtx (HImode);
3809 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3810 ;; This instruction sets Z flag
3813 [(set (cc0) (const_int 0))]
3816 [(set_attr "length" "1")
3817 (set_attr "cc" "compare")])
3819 ;; Clear/set/test a single bit in I/O address space.
3822 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3823 (and:QI (mem:QI (match_dup 0))
3824 (match_operand:QI 1 "single_zero_operand" "n")))]
3827 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
3828 return AS2 (cbi,%m0-0x20,%2);
3830 [(set_attr "length" "1")
3831 (set_attr "cc" "none")])
3834 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3835 (ior:QI (mem:QI (match_dup 0))
3836 (match_operand:QI 1 "single_one_operand" "n")))]
3839 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
3840 return AS2 (sbi,%m0-0x20,%2);
3842 [(set_attr "length" "1")
3843 (set_attr "cc" "none")])
3845 ;; Lower half of the I/O space - use sbic/sbis directly.
3846 (define_insn "*sbix_branch"
3849 (match_operator 0 "eqne_operator"
3851 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
3853 (match_operand 2 "const_int_operand" "n"))
3855 (label_ref (match_operand 3 "" ""))
3858 "* return avr_out_sbxx_branch (insn, operands);"
3859 [(set (attr "length")
3860 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3861 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3863 (if_then_else (eq_attr "mcu_mega" "no")
3866 (set_attr "cc" "clobber")])
3868 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
3869 (define_insn "*sbix_branch_bit7"
3872 (match_operator 0 "gelt_operator"
3873 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
3875 (label_ref (match_operand 2 "" ""))
3879 operands[3] = operands[2];
3880 operands[2] = GEN_INT (7);
3881 return avr_out_sbxx_branch (insn, operands);
3883 [(set (attr "length")
3884 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3885 (le (minus (pc) (match_dup 2)) (const_int 2046)))
3887 (if_then_else (eq_attr "mcu_mega" "no")
3890 (set_attr "cc" "clobber")])
3892 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
3893 (define_insn "*sbix_branch_tmp"
3896 (match_operator 0 "eqne_operator"
3898 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
3900 (match_operand 2 "const_int_operand" "n"))
3902 (label_ref (match_operand 3 "" ""))
3905 "* return avr_out_sbxx_branch (insn, operands);"
3906 [(set (attr "length")
3907 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3908 (le (minus (pc) (match_dup 3)) (const_int 2045)))
3910 (if_then_else (eq_attr "mcu_mega" "no")
3913 (set_attr "cc" "clobber")])
3915 (define_insn "*sbix_branch_tmp_bit7"
3918 (match_operator 0 "gelt_operator"
3919 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
3921 (label_ref (match_operand 2 "" ""))
3925 operands[3] = operands[2];
3926 operands[2] = GEN_INT (7);
3927 return avr_out_sbxx_branch (insn, operands);
3929 [(set (attr "length")
3930 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3931 (le (minus (pc) (match_dup 2)) (const_int 2045)))
3933 (if_then_else (eq_attr "mcu_mega" "no")
3936 (set_attr "cc" "clobber")])
3938 ;; ************************* Peepholes ********************************
3941 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
3942 (plus:SI (match_dup 0)
3944 (clobber (scratch:QI))])
3945 (parallel [(set (cc0)
3946 (compare (match_dup 0)
3948 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3950 (if_then_else (ne (cc0)
3952 (label_ref (match_operand 2 "" ""))
3957 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3958 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3959 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3960 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
3962 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3963 AS2 (sbc,%B0,__zero_reg__) CR_TAB
3964 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3965 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
3967 switch (avr_jump_mode (operands[2], insn))
3970 return AS1 (brcc,%2);
3972 return (AS1 (brcs,.+2) CR_TAB
3976 return (AS1 (brcs,.+4) CR_TAB
3981 [(set (match_operand:HI 0 "d_register_operand" "")
3982 (plus:HI (match_dup 0)
3986 (compare (match_dup 0)
3988 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3990 (if_then_else (ne (cc0) (const_int 0))
3991 (label_ref (match_operand 2 "" ""))
3997 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3998 output_asm_insn (AS2 (sbiw,%0,1), operands);
4000 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
4001 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
4002 switch (avr_jump_mode (operands[2],insn))
4005 return AS1 (brcc,%2);
4007 return (AS1 (brcs,.+2) CR_TAB
4010 return (AS1 (brcs,.+4) CR_TAB
4015 [(set (match_operand:QI 0 "d_register_operand" "")
4016 (plus:QI (match_dup 0)
4019 (compare (match_dup 0)
4022 (if_then_else (ne (cc0) (const_int 0))
4023 (label_ref (match_operand 1 "" ""))
4029 cc_status.value1 = operands[0];
4030 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
4031 output_asm_insn (AS2 (subi,%A0,1), operands);
4032 switch (avr_jump_mode (operands[1],insn))
4035 return AS1 (brcc,%1);
4037 return (AS1 (brcs,.+2) CR_TAB
4040 return (AS1 (brcs,.+4) CR_TAB
4046 (compare (match_operand:QI 0 "register_operand" "")
4049 (if_then_else (eq (cc0) (const_int 0))
4050 (label_ref (match_operand 1 "" ""))
4052 "jump_over_one_insn_p (insn, operands[1])"
4053 "cpse %0,__zero_reg__")
4057 (compare (match_operand:QI 0 "register_operand" "")
4058 (match_operand:QI 1 "register_operand" "")))
4060 (if_then_else (eq (cc0) (const_int 0))
4061 (label_ref (match_operand 2 "" ""))
4063 "jump_over_one_insn_p (insn, operands[2])"
4066 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
4067 ;;prologue/epilogue support instructions
4069 (define_insn "popqi"
4070 [(set (match_operand:QI 0 "register_operand" "=r")
4071 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
4074 [(set_attr "cc" "none")
4075 (set_attr "length" "1")])
4077 ;; Enable Interrupts
4078 (define_insn "enable_interrupt"
4079 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
4082 [(set_attr "length" "1")
4083 (set_attr "cc" "none")])
4085 ;; Disable Interrupts
4086 (define_insn "disable_interrupt"
4087 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
4090 [(set_attr "length" "1")
4091 (set_attr "cc" "none")])
4093 ;; Library prologue saves
4094 (define_insn "call_prologue_saves"
4095 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
4096 (match_operand:HI 0 "immediate_operand" "")
4097 (set (reg:HI REG_SP) (minus:HI
4099 (match_operand:HI 1 "immediate_operand" "")))
4100 (use (reg:HI REG_X))
4101 (clobber (reg:HI REG_Z))]
4103 "ldi r30,lo8(gs(1f))
4105 %~jmp __prologue_saves__+((18 - %0) * 2)
4107 [(set_attr_alternative "length"
4108 [(if_then_else (eq_attr "mcu_mega" "yes")
4111 (set_attr "cc" "clobber")
4114 ; epilogue restores using library
4115 (define_insn "epilogue_restores"
4116 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
4117 (set (reg:HI REG_Y ) (plus:HI
4119 (match_operand:HI 0 "immediate_operand" "")))
4120 (set (reg:HI REG_SP) (reg:HI REG_Y))
4121 (clobber (reg:QI REG_Z))]
4124 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
4125 [(set_attr_alternative "length"
4126 [(if_then_else (eq_attr "mcu_mega" "yes")
4129 (set_attr "cc" "clobber")
4133 (define_insn "return"
4135 "reload_completed && avr_simple_epilogue ()"
4137 [(set_attr "cc" "none")
4138 (set_attr "length" "1")])
4140 (define_insn "return_from_epilogue"
4144 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
4145 && !cfun->machine->is_naked)"
4147 [(set_attr "cc" "none")
4148 (set_attr "length" "1")])
4150 (define_insn "return_from_interrupt_epilogue"
4154 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
4155 && !cfun->machine->is_naked)"
4157 [(set_attr "cc" "none")
4158 (set_attr "length" "1")])
4160 (define_insn "return_from_naked_epilogue"
4164 && cfun->machine->is_naked)"
4166 [(set_attr "cc" "none")
4167 (set_attr "length" "0")])
4169 (define_expand "prologue"
4178 (define_expand "epilogue"
4182 expand_epilogue (false /* sibcall_p */);
4186 (define_expand "sibcall_epilogue"
4190 expand_epilogue (true /* sibcall_p */);
4194 ;; Some instructions resp. instruction sequences available
4197 (define_insn "delay_cycles_1"
4198 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
4200 UNSPECV_DELAY_CYCLES)
4201 (clobber (match_scratch:QI 1 "=&d"))]
4206 [(set_attr "length" "3")
4207 (set_attr "cc" "clobber")])
4209 (define_insn "delay_cycles_2"
4210 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
4212 UNSPECV_DELAY_CYCLES)
4213 (clobber (match_scratch:HI 1 "=&w"))]
4219 [(set_attr "length" "4")
4220 (set_attr "cc" "clobber")])
4222 (define_insn "delay_cycles_3"
4223 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4225 UNSPECV_DELAY_CYCLES)
4226 (clobber (match_scratch:QI 1 "=&d"))
4227 (clobber (match_scratch:QI 2 "=&d"))
4228 (clobber (match_scratch:QI 3 "=&d"))]
4237 [(set_attr "length" "7")
4238 (set_attr "cc" "clobber")])
4240 (define_insn "delay_cycles_4"
4241 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4243 UNSPECV_DELAY_CYCLES)
4244 (clobber (match_scratch:QI 1 "=&d"))
4245 (clobber (match_scratch:QI 2 "=&d"))
4246 (clobber (match_scratch:QI 3 "=&d"))
4247 (clobber (match_scratch:QI 4 "=&d"))]
4258 [(set_attr "length" "9")
4259 (set_attr "cc" "clobber")])
4264 (define_expand "parityhi2"
4266 (match_operand:HI 1 "register_operand" ""))
4268 (parity:HI (reg:HI 24)))
4269 (set (match_operand:HI 0 "register_operand" "")
4274 (define_expand "paritysi2"
4276 (match_operand:SI 1 "register_operand" ""))
4278 (truncate:HI (parity:SI (reg:SI 22))))
4281 (set (match_operand:SI 0 "register_operand" "")
4282 (zero_extend:SI (match_dup 2)))]
4285 operands[2] = gen_reg_rtx (HImode);
4288 (define_insn "*parityhi2.libgcc"
4290 (parity:HI (reg:HI 24)))]
4292 "%~call __parityhi2"
4293 [(set_attr "type" "xcall")
4294 (set_attr "cc" "clobber")])
4296 (define_insn "*parityqihi2.libgcc"
4298 (zero_extend:HI (parity:QI (reg:QI 24))))]
4300 "%~call __parityqi2"
4301 [(set_attr "type" "xcall")
4302 (set_attr "cc" "clobber")])
4304 (define_insn "*paritysihi2.libgcc"
4306 (truncate:HI (parity:SI (reg:SI 22))))]
4308 "%~call __paritysi2"
4309 [(set_attr "type" "xcall")
4310 (set_attr "cc" "clobber")])
4315 (define_expand "popcounthi2"
4317 (match_operand:HI 1 "register_operand" ""))
4319 (popcount:HI (reg:HI 24)))
4320 (set (match_operand:HI 0 "register_operand" "")
4325 (define_expand "popcountsi2"
4327 (match_operand:SI 1 "register_operand" ""))
4329 (truncate:HI (popcount:SI (reg:SI 22))))
4332 (set (match_operand:SI 0 "register_operand" "")
4333 (zero_extend:SI (match_dup 2)))]
4336 operands[2] = gen_reg_rtx (HImode);
4339 (define_insn "*popcounthi2.libgcc"
4341 (popcount:HI (reg:HI 24)))]
4343 "%~call __popcounthi2"
4344 [(set_attr "type" "xcall")
4345 (set_attr "cc" "clobber")])
4347 (define_insn "*popcountsi2.libgcc"
4349 (truncate:HI (popcount:SI (reg:SI 22))))]
4351 "%~call __popcountsi2"
4352 [(set_attr "type" "xcall")
4353 (set_attr "cc" "clobber")])
4355 (define_insn "*popcountqi2.libgcc"
4357 (popcount:QI (reg:QI 24)))]
4359 "%~call __popcountqi2"
4360 [(set_attr "type" "xcall")
4361 (set_attr "cc" "clobber")])
4363 (define_insn_and_split "*popcountqihi2.libgcc"
4365 (zero_extend:HI (popcount:QI (reg:QI 24))))]
4370 (popcount:QI (reg:QI 24)))
4375 ;; Count Leading Zeros
4377 (define_expand "clzhi2"
4379 (match_operand:HI 1 "register_operand" ""))
4380 (parallel [(set (reg:HI 24)
4381 (clz:HI (reg:HI 24)))
4382 (clobber (reg:QI 26))])
4383 (set (match_operand:HI 0 "register_operand" "")
4388 (define_expand "clzsi2"
4390 (match_operand:SI 1 "register_operand" ""))
4391 (parallel [(set (reg:HI 24)
4392 (truncate:HI (clz:SI (reg:SI 22))))
4393 (clobber (reg:QI 26))])
4396 (set (match_operand:SI 0 "register_operand" "")
4397 (zero_extend:SI (match_dup 2)))]
4400 operands[2] = gen_reg_rtx (HImode);
4403 (define_insn "*clzhi2.libgcc"
4405 (clz:HI (reg:HI 24)))
4406 (clobber (reg:QI 26))]
4409 [(set_attr "type" "xcall")
4410 (set_attr "cc" "clobber")])
4412 (define_insn "*clzsihi2.libgcc"
4414 (truncate:HI (clz:SI (reg:SI 22))))
4415 (clobber (reg:QI 26))]
4418 [(set_attr "type" "xcall")
4419 (set_attr "cc" "clobber")])
4421 ;; Count Trailing Zeros
4423 (define_expand "ctzhi2"
4425 (match_operand:HI 1 "register_operand" ""))
4426 (parallel [(set (reg:HI 24)
4427 (ctz:HI (reg:HI 24)))
4428 (clobber (reg:QI 26))])
4429 (set (match_operand:HI 0 "register_operand" "")
4434 (define_expand "ctzsi2"
4436 (match_operand:SI 1 "register_operand" ""))
4437 (parallel [(set (reg:HI 24)
4438 (truncate:HI (ctz:SI (reg:SI 22))))
4439 (clobber (reg:QI 22))
4440 (clobber (reg:QI 26))])
4443 (set (match_operand:SI 0 "register_operand" "")
4444 (zero_extend:SI (match_dup 2)))]
4447 operands[2] = gen_reg_rtx (HImode);
4450 (define_insn "*ctzhi2.libgcc"
4452 (ctz:HI (reg:HI 24)))
4453 (clobber (reg:QI 26))]
4456 [(set_attr "type" "xcall")
4457 (set_attr "cc" "clobber")])
4459 (define_insn "*ctzsihi2.libgcc"
4461 (truncate:HI (ctz:SI (reg:SI 22))))
4462 (clobber (reg:QI 22))
4463 (clobber (reg:QI 26))]
4466 [(set_attr "type" "xcall")
4467 (set_attr "cc" "clobber")])
4471 (define_expand "ffshi2"
4473 (match_operand:HI 1 "register_operand" ""))
4474 (parallel [(set (reg:HI 24)
4475 (ffs:HI (reg:HI 24)))
4476 (clobber (reg:QI 26))])
4477 (set (match_operand:HI 0 "register_operand" "")
4482 (define_expand "ffssi2"
4484 (match_operand:SI 1 "register_operand" ""))
4485 (parallel [(set (reg:HI 24)
4486 (truncate:HI (ffs:SI (reg:SI 22))))
4487 (clobber (reg:QI 22))
4488 (clobber (reg:QI 26))])
4491 (set (match_operand:SI 0 "register_operand" "")
4492 (zero_extend:SI (match_dup 2)))]
4495 operands[2] = gen_reg_rtx (HImode);
4498 (define_insn "*ffshi2.libgcc"
4500 (ffs:HI (reg:HI 24)))
4501 (clobber (reg:QI 26))]
4504 [(set_attr "type" "xcall")
4505 (set_attr "cc" "clobber")])
4507 (define_insn "*ffssihi2.libgcc"
4509 (truncate:HI (ffs:SI (reg:SI 22))))
4510 (clobber (reg:QI 22))
4511 (clobber (reg:QI 26))]
4514 [(set_attr "type" "xcall")
4515 (set_attr "cc" "clobber")])
4519 (define_insn "copysignsf3"
4520 [(set (match_operand:SF 0 "register_operand" "=r")
4521 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
4522 (match_operand:SF 2 "register_operand" "r")]
4525 "bst %D2,7\;bld %D0,7"
4526 [(set_attr "length" "2")
4527 (set_attr "cc" "none")])
4529 ;; Swap Bytes (change byte-endianess)
4531 (define_expand "bswapsi2"
4533 (match_operand:SI 1 "register_operand" ""))
4535 (bswap:SI (reg:SI 22)))
4536 (set (match_operand:SI 0 "register_operand" "")
4541 (define_insn "*bswapsi2.libgcc"
4543 (bswap:SI (reg:SI 22)))]
4546 [(set_attr "type" "xcall")
4547 (set_attr "cc" "clobber")])
4552 ;; NOP taking 1 or 2 Ticks
4554 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
4560 [(set_attr "length" "1")
4561 (set_attr "cc" "none")])
4564 (define_insn "sleep"
4565 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
4568 [(set_attr "length" "1")
4569 (set_attr "cc" "none")])
4573 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
4576 [(set_attr "length" "1")
4577 (set_attr "cc" "none")])
4580 (define_expand "fmul"
4582 (match_operand:QI 1 "register_operand" ""))
4584 (match_operand:QI 2 "register_operand" ""))
4585 (parallel [(set (reg:HI 22)
4586 (unspec:HI [(reg:QI 24)
4587 (reg:QI 25)] UNSPEC_FMUL))
4588 (clobber (reg:HI 24))])
4589 (set (match_operand:HI 0 "register_operand" "")
4595 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
4600 (define_insn "fmul_insn"
4601 [(set (match_operand:HI 0 "register_operand" "=r")
4602 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4603 (match_operand:QI 2 "register_operand" "a")]
4609 [(set_attr "length" "3")
4610 (set_attr "cc" "clobber")])
4612 (define_insn "*fmul.call"
4614 (unspec:HI [(reg:QI 24)
4615 (reg:QI 25)] UNSPEC_FMUL))
4616 (clobber (reg:HI 24))]
4619 [(set_attr "type" "xcall")
4620 (set_attr "cc" "clobber")])
4623 (define_expand "fmuls"
4625 (match_operand:QI 1 "register_operand" ""))
4627 (match_operand:QI 2 "register_operand" ""))
4628 (parallel [(set (reg:HI 22)
4629 (unspec:HI [(reg:QI 24)
4630 (reg:QI 25)] UNSPEC_FMULS))
4631 (clobber (reg:HI 24))])
4632 (set (match_operand:HI 0 "register_operand" "")
4638 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
4643 (define_insn "fmuls_insn"
4644 [(set (match_operand:HI 0 "register_operand" "=r")
4645 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4646 (match_operand:QI 2 "register_operand" "a")]
4652 [(set_attr "length" "3")
4653 (set_attr "cc" "clobber")])
4655 (define_insn "*fmuls.call"
4657 (unspec:HI [(reg:QI 24)
4658 (reg:QI 25)] UNSPEC_FMULS))
4659 (clobber (reg:HI 24))]
4662 [(set_attr "type" "xcall")
4663 (set_attr "cc" "clobber")])
4666 (define_expand "fmulsu"
4668 (match_operand:QI 1 "register_operand" ""))
4670 (match_operand:QI 2 "register_operand" ""))
4671 (parallel [(set (reg:HI 22)
4672 (unspec:HI [(reg:QI 24)
4673 (reg:QI 25)] UNSPEC_FMULSU))
4674 (clobber (reg:HI 24))])
4675 (set (match_operand:HI 0 "register_operand" "")
4681 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
4686 (define_insn "fmulsu_insn"
4687 [(set (match_operand:HI 0 "register_operand" "=r")
4688 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4689 (match_operand:QI 2 "register_operand" "a")]
4695 [(set_attr "length" "3")
4696 (set_attr "cc" "clobber")])
4698 (define_insn "*fmulsu.call"
4700 (unspec:HI [(reg:QI 24)
4701 (reg:QI 25)] UNSPEC_FMULSU))
4702 (clobber (reg:HI 24))]
4705 [(set_attr "type" "xcall")
4706 (set_attr "cc" "clobber")])
4709 ;; Some combiner patterns dealing with bits.
4712 ;; Move bit $3.0 into bit $0.$4
4713 (define_insn "*movbitqi.1-6.a"
4714 [(set (match_operand:QI 0 "register_operand" "=r")
4715 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4716 (match_operand:QI 2 "single_zero_operand" "n"))
4717 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
4718 (match_operand:QI 4 "const_0_to_7_operand" "n"))
4719 (match_operand:QI 5 "single_one_operand" "n"))))]
4720 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
4721 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
4722 "bst %3,0\;bld %0,%4"
4723 [(set_attr "length" "2")
4724 (set_attr "cc" "none")])
4726 ;; Move bit $3.0 into bit $0.$4
4727 ;; Variation of above. Unfortunately, there is no canonicalized representation
4728 ;; of moving around bits. So what we see here depends on how user writes down
4729 ;; bit manipulations.
4730 (define_insn "*movbitqi.1-6.b"
4731 [(set (match_operand:QI 0 "register_operand" "=r")
4732 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4733 (match_operand:QI 2 "single_zero_operand" "n"))
4734 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
4736 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
4737 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4738 "bst %3,0\;bld %0,%4"
4739 [(set_attr "length" "2")
4740 (set_attr "cc" "none")])
4742 ;; Move bit $3.0 into bit $0.0.
4743 ;; For bit 0, combiner generates slightly different pattern.
4744 (define_insn "*movbitqi.0"
4745 [(set (match_operand:QI 0 "register_operand" "=r")
4746 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4747 (match_operand:QI 2 "single_zero_operand" "n"))
4748 (and:QI (match_operand:QI 3 "register_operand" "r")
4750 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4751 "bst %3,0\;bld %0,0"
4752 [(set_attr "length" "2")
4753 (set_attr "cc" "none")])
4755 ;; Move bit $2.0 into bit $0.7.
4756 ;; For bit 7, combiner generates slightly different pattern
4757 (define_insn "*movbitqi.7"
4758 [(set (match_operand:QI 0 "register_operand" "=r")
4759 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4761 (ashift:QI (match_operand:QI 2 "register_operand" "r")
4764 "bst %2,0\;bld %0,7"
4765 [(set_attr "length" "2")
4766 (set_attr "cc" "none")])
4768 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
4769 ;; and input/output match. We provide a special pattern for this, because
4770 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
4771 ;; operation on I/O is atomic.
4772 (define_insn "*insv.io"
4773 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
4775 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
4776 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
4781 sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
4782 [(set_attr "length" "1,1,4")
4783 (set_attr "cc" "none")])
4785 (define_insn "*insv.not.io"
4786 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4788 (match_operand:QI 1 "const_0_to_7_operand" "n"))
4789 (not:QI (match_operand:QI 2 "register_operand" "r")))]
4791 "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
4792 [(set_attr "length" "4")
4793 (set_attr "cc" "none")])
4795 ;; The insv expander.
4796 ;; We only support 1-bit inserts
4797 (define_expand "insv"
4798 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
4799 (match_operand:QI 1 "const1_operand" "") ; width
4800 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
4801 (match_operand:QI 3 "nonmemory_operand" ""))]
4805 ;; Insert bit $2.0 into $0.$1
4806 (define_insn "*insv.reg"
4807 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
4809 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
4810 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
4814 andi %0,lo8(~(1<<%1))
4818 [(set_attr "length" "2,1,1,2,2")
4819 (set_attr "cc" "none,set_zn,set_zn,none,none")])
4822 ;; Some combine patterns that try to fix bad code when a value is composed
4823 ;; from byte parts like in PR27663.
4824 ;; The patterns give some release but the code still is not optimal,
4825 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
4826 ;; That switch obfuscates things here and in many other places.
4828 (define_insn_and_split "*ior<mode>qi.byte0"
4829 [(set (match_operand:HISI 0 "register_operand" "=r")
4831 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4832 (match_operand:HISI 2 "register_operand" "0")))]
4837 (ior:QI (match_dup 3)
4840 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
4843 (define_insn_and_split "*ior<mode>qi.byte1-3"
4844 [(set (match_operand:HISI 0 "register_operand" "=r")
4846 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4847 (match_operand:QI 2 "const_8_16_24_operand" "n"))
4848 (match_operand:HISI 3 "register_operand" "0")))]
4849 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
4851 "&& reload_completed"
4853 (ior:QI (match_dup 4)
4856 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
4857 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
4860 (define_expand "extzv"
4861 [(set (match_operand:QI 0 "register_operand" "")
4862 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
4863 (match_operand:QI 2 "const1_operand" "")
4864 (match_operand:QI 3 "const_0_to_7_operand" "")))]
4868 (define_insn "*extzv"
4869 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
4870 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
4872 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
4876 mov %0,%1\;andi %0,1
4879 bst %1,%2\;clr %0\;bld %0,0"
4880 [(set_attr "length" "1,2,2,2,3")
4881 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
4883 (define_insn_and_split "*extzv.qihi1"
4884 [(set (match_operand:HI 0 "register_operand" "=r")
4885 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
4887 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
4892 (zero_extract:QI (match_dup 1)
4898 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4899 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4902 (define_insn_and_split "*extzv.qihi2"
4903 [(set (match_operand:HI 0 "register_operand" "=r")
4905 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
4907 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
4912 (zero_extract:QI (match_dup 1)
4918 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4919 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);