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"
140 (const_string "yes"))
142 ;; Define mode iterators
143 (define_mode_iterator QIHI [(QI "") (HI "")])
144 (define_mode_iterator QIHI2 [(QI "") (HI "")])
145 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
146 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
147 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
148 (define_mode_iterator HISI [(HI "") (SI "")])
150 ;; Define code iterators
151 ;; Define two incarnations so that we can build the cross product.
152 (define_code_iterator any_extend [sign_extend zero_extend])
153 (define_code_iterator any_extend2 [sign_extend zero_extend])
155 ;; Define code attributes
156 (define_code_attr extend_su
160 (define_code_attr extend_u
164 (define_code_attr extend_s
168 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
169 (define_code_attr mul_r_d
174 ;;========================================================================
175 ;; The following is used by nonlocal_goto and setjmp.
176 ;; The receiver pattern will create no instructions since internally
177 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
178 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
179 ;; The 'null' receiver also avoids problems with optimisation
180 ;; not recognising incoming jmp and removing code that resets frame_pointer.
181 ;; The code derived from builtins.c.
183 (define_expand "nonlocal_goto_receiver"
185 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
188 emit_move_insn (virtual_stack_vars_rtx,
189 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
190 gen_int_mode (STARTING_FRAME_OFFSET,
192 /* This might change the hard frame pointer in ways that aren't
193 apparent to early optimization passes, so force a clobber. */
194 emit_clobber (hard_frame_pointer_rtx);
199 ;; Defining nonlocal_goto_receiver means we must also define this.
200 ;; even though its function is identical to that in builtins.c
202 (define_expand "nonlocal_goto"
204 (use (match_operand 0 "general_operand"))
205 (use (match_operand 1 "general_operand"))
206 (use (match_operand 2 "general_operand"))
207 (use (match_operand 3 "general_operand"))
211 rtx r_label = copy_to_reg (operands[1]);
212 rtx r_fp = operands[3];
213 rtx r_sp = operands[2];
215 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
217 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
219 emit_move_insn (hard_frame_pointer_rtx, r_fp);
220 emit_stack_restore (SAVE_NONLOCAL, r_sp);
222 emit_use (hard_frame_pointer_rtx);
223 emit_use (stack_pointer_rtx);
225 emit_indirect_jump (r_label);
230 (define_insn "pushqi1"
231 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
232 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
237 [(set_attr "length" "1,1")])
239 ;; All modes for a multi-byte push. We must include complex modes here too,
240 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
241 (define_mode_iterator MPUSH
248 (define_expand "push<mode>1"
249 [(match_operand:MPUSH 0 "" "")]
253 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
255 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
256 if (part != const0_rtx)
257 part = force_reg (QImode, part);
258 emit_insn (gen_pushqi1 (part));
263 ;; Notice a special-case when adding N to SP where N results in a
264 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
266 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
268 && frame_pointer_needed
269 && !cfun->calls_alloca
270 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
271 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
274 ;;========================================================================
276 ;; The last alternative (any immediate constant to any register) is
277 ;; very expensive. It should be optimized by peephole2 if a scratch
278 ;; register is available, but then that register could just as well be
279 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
280 ;; are call-saved registers, and most of LD_REGS are call-used registers,
281 ;; so this may still be a win for registers live across function calls.
283 (define_expand "movqi"
284 [(set (match_operand:QI 0 "nonimmediate_operand" "")
285 (match_operand:QI 1 "general_operand" ""))]
287 "/* One of the ops has to be in a register. */
288 if (!register_operand(operand0, QImode)
289 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
290 operands[1] = copy_to_mode_reg(QImode, operand1);
293 (define_insn "*movqi"
294 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
295 (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))]
296 "(register_operand (operands[0],QImode)
297 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
298 "* return output_movqi (insn, operands, NULL);"
299 [(set_attr "length" "1,1,5,5,1,1,4")
300 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
302 ;; This is used in peephole2 to optimize loading immediate constants
303 ;; if a scratch register from LD_REGS happens to be available.
305 (define_insn "*reload_inqi"
306 [(set (match_operand:QI 0 "register_operand" "=l")
307 (match_operand:QI 1 "immediate_operand" "i"))
308 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
312 [(set_attr "length" "2")
313 (set_attr "cc" "none")])
316 [(match_scratch:QI 2 "d")
317 (set (match_operand:QI 0 "l_register_operand" "")
318 (match_operand:QI 1 "immediate_operand" ""))]
319 "(operands[1] != const0_rtx
320 && operands[1] != const1_rtx
321 && operands[1] != constm1_rtx)"
322 [(parallel [(set (match_dup 0) (match_dup 1))
323 (clobber (match_dup 2))])]
326 ;;============================================================================
327 ;; move word (16 bit)
329 (define_expand "movhi"
330 [(set (match_operand:HI 0 "nonimmediate_operand" "")
331 (match_operand:HI 1 "general_operand" ""))]
335 /* One of the ops has to be in a register. */
336 if (!register_operand(operand0, HImode)
337 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
339 operands[1] = copy_to_mode_reg(HImode, operand1);
343 (define_insn "*movhi_sp"
344 [(set (match_operand:HI 0 "register_operand" "=q,r")
345 (match_operand:HI 1 "register_operand" "r,q"))]
346 "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
347 || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
348 "* return output_movhi (insn, operands, NULL);"
349 [(set_attr "length" "5,2")
350 (set_attr "cc" "none,none")])
352 (define_insn "movhi_sp_r_irq_off"
353 [(set (match_operand:HI 0 "stack_register_operand" "=q")
354 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
355 UNSPECV_WRITE_SP_IRQ_OFF))]
359 [(set_attr "length" "2")
360 (set_attr "cc" "none")])
362 (define_insn "movhi_sp_r_irq_on"
363 [(set (match_operand:HI 0 "stack_register_operand" "=q")
364 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
365 UNSPECV_WRITE_SP_IRQ_ON))]
371 [(set_attr "length" "4")
372 (set_attr "cc" "none")])
375 [(match_scratch:QI 2 "d")
376 (set (match_operand:HI 0 "l_register_operand" "")
377 (match_operand:HI 1 "immediate_operand" ""))]
378 "(operands[1] != const0_rtx
379 && operands[1] != constm1_rtx)"
380 [(parallel [(set (match_dup 0) (match_dup 1))
381 (clobber (match_dup 2))])]
384 ;; '*' because it is not used in rtl generation, only in above peephole
385 (define_insn "*reload_inhi"
386 [(set (match_operand:HI 0 "register_operand" "=r")
387 (match_operand:HI 1 "immediate_operand" "i"))
388 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
390 "* return output_reload_inhi (insn, operands, NULL);"
391 [(set_attr "length" "4")
392 (set_attr "cc" "none")])
394 (define_insn "*movhi"
395 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
396 (match_operand:HI 1 "general_operand" "rL,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,6,7,2,6,5,2")
401 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
403 (define_peephole2 ; movw
404 [(set (match_operand:QI 0 "even_register_operand" "")
405 (match_operand:QI 1 "even_register_operand" ""))
406 (set (match_operand:QI 2 "odd_register_operand" "")
407 (match_operand:QI 3 "odd_register_operand" ""))]
409 && REGNO (operands[0]) == REGNO (operands[2]) - 1
410 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
411 [(set (match_dup 4) (match_dup 5))]
413 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
414 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
417 (define_peephole2 ; movw_r
418 [(set (match_operand:QI 0 "odd_register_operand" "")
419 (match_operand:QI 1 "odd_register_operand" ""))
420 (set (match_operand:QI 2 "even_register_operand" "")
421 (match_operand:QI 3 "even_register_operand" ""))]
423 && REGNO (operands[2]) == REGNO (operands[0]) - 1
424 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
425 [(set (match_dup 4) (match_dup 5))]
427 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
428 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
431 ;;==========================================================================
432 ;; move double word (32 bit)
434 (define_expand "movsi"
435 [(set (match_operand:SI 0 "nonimmediate_operand" "")
436 (match_operand:SI 1 "general_operand" ""))]
440 /* One of the ops has to be in a register. */
441 if (!register_operand (operand0, SImode)
442 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
444 operands[1] = copy_to_mode_reg (SImode, operand1);
450 (define_peephole2 ; *reload_insi
451 [(match_scratch:QI 2 "d")
452 (set (match_operand:SI 0 "l_register_operand" "")
453 (match_operand:SI 1 "const_int_operand" ""))
455 "(operands[1] != const0_rtx
456 && operands[1] != constm1_rtx)"
457 [(parallel [(set (match_dup 0) (match_dup 1))
458 (clobber (match_dup 2))])]
461 ;; '*' because it is not used in rtl generation.
462 (define_insn "*reload_insi"
463 [(set (match_operand:SI 0 "register_operand" "=r")
464 (match_operand:SI 1 "const_int_operand" "n"))
465 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
468 return output_reload_insisf (insn, operands, operands[2], NULL);
470 [(set_attr "length" "8")
471 (set_attr "adjust_len" "reload_in32")
472 (set_attr "cc" "clobber")])
475 (define_insn "*movsi"
476 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
477 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
478 "(register_operand (operands[0],SImode)
479 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
481 return output_movsisf (insn, operands, NULL);
483 [(set_attr "length" "4,4,8,9,4,10")
484 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
486 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
487 ;; move floating point numbers (32 bit)
489 (define_expand "movsf"
490 [(set (match_operand:SF 0 "nonimmediate_operand" "")
491 (match_operand:SF 1 "general_operand" ""))]
495 /* One of the ops has to be in a register. */
496 if (!register_operand (operand1, SFmode)
497 && !register_operand (operand0, SFmode))
499 operands[1] = copy_to_mode_reg (SFmode, operand1);
503 (define_insn "*movsf"
504 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
505 (match_operand:SF 1 "general_operand" "r,G,Qm,rG,F,F"))]
506 "register_operand (operands[0], SFmode)
507 || register_operand (operands[1], SFmode)
508 || operands[1] == CONST0_RTX (SFmode)"
510 return output_movsisf (insn, operands, NULL);
512 [(set_attr "length" "4,4,8,9,4,10")
513 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
515 (define_peephole2 ; *reload_insf
516 [(match_scratch:QI 2 "d")
517 (set (match_operand:SF 0 "l_register_operand" "")
518 (match_operand:SF 1 "const_double_operand" ""))
520 "operands[1] != CONST0_RTX (SFmode)"
521 [(parallel [(set (match_dup 0)
523 (clobber (match_dup 2))])]
526 ;; '*' because it is not used in rtl generation.
527 (define_insn "*reload_insf"
528 [(set (match_operand:SF 0 "register_operand" "=r")
529 (match_operand:SF 1 "const_double_operand" "F"))
530 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
533 return output_reload_insisf (insn, operands, operands[2], NULL);
535 [(set_attr "length" "8")
536 (set_attr "adjust_len" "reload_in32")
537 (set_attr "cc" "clobber")])
539 ;;=========================================================================
540 ;; move string (like memcpy)
541 ;; implement as RTL loop
543 (define_expand "movmemhi"
544 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
545 (match_operand:BLK 1 "memory_operand" ""))
546 (use (match_operand:HI 2 "const_int_operand" ""))
547 (use (match_operand:HI 3 "const_int_operand" ""))])]
552 enum machine_mode mode;
553 rtx label = gen_label_rtx ();
557 /* Copy pointers into new psuedos - they will be changed. */
558 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
559 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
561 /* Create rtx for tmp register - we use this as scratch. */
562 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
564 if (GET_CODE (operands[2]) != CONST_INT)
567 count = INTVAL (operands[2]);
571 /* Work out branch probability for latter use. */
572 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
574 /* See if constant fit 8 bits. */
575 mode = (count < 0x100) ? QImode : HImode;
576 /* Create loop counter register. */
577 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
579 /* Now create RTL code for move loop. */
580 /* Label at top of loop. */
583 /* Move one byte into scratch and inc pointer. */
584 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
585 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
587 /* Move to mem and inc pointer. */
588 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
589 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
591 /* Decrement count. */
592 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
594 /* Compare with zero and jump if not equal. */
595 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
597 /* Set jump probability based on loop count. */
598 jump = get_last_insn ();
599 add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
603 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
604 ;; memset (%0, %2, %1)
606 (define_expand "setmemhi"
607 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
608 (match_operand 2 "const_int_operand" ""))
609 (use (match_operand:HI 1 "const_int_operand" ""))
610 (use (match_operand:HI 3 "const_int_operand" "n"))
611 (clobber (match_scratch:HI 4 ""))
612 (clobber (match_dup 5))])]
616 enum machine_mode mode;
618 /* If value to set is not zero, use the library routine. */
619 if (operands[2] != const0_rtx)
622 if (!CONST_INT_P (operands[1]))
625 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
626 operands[5] = gen_rtx_SCRATCH (mode);
627 operands[1] = copy_to_mode_reg (mode,
628 gen_int_mode (INTVAL (operands[1]), mode));
629 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
630 operands[0] = gen_rtx_MEM (BLKmode, addr0);
633 (define_insn "*clrmemqi"
634 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
636 (use (match_operand:QI 1 "register_operand" "r"))
637 (use (match_operand:QI 2 "const_int_operand" "n"))
638 (clobber (match_scratch:HI 3 "=0"))
639 (clobber (match_scratch:QI 4 "=&1"))]
641 "st %a0+,__zero_reg__
644 [(set_attr "length" "3")
645 (set_attr "cc" "clobber")])
647 (define_insn "*clrmemhi"
648 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
650 (use (match_operand:HI 1 "register_operand" "!w,d"))
651 (use (match_operand:HI 2 "const_int_operand" "n,n"))
652 (clobber (match_scratch:HI 3 "=0,0"))
653 (clobber (match_scratch:HI 4 "=&1,&1"))]
656 if (which_alternative==0)
657 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
658 AS2 (sbiw,%A1,1) CR_TAB
661 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
662 AS2 (subi,%A1,1) CR_TAB
663 AS2 (sbci,%B1,0) CR_TAB
666 [(set_attr "length" "3,4")
667 (set_attr "cc" "clobber,clobber")])
669 (define_expand "strlenhi"
671 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
672 (match_operand:QI 2 "const_int_operand" "")
673 (match_operand:HI 3 "immediate_operand" "")]
675 (set (match_dup 4) (plus:HI (match_dup 4)
677 (set (match_operand:HI 0 "register_operand" "")
678 (minus:HI (match_dup 4)
683 if (operands[2] != const0_rtx)
685 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
686 operands[1] = gen_rtx_MEM (BLKmode, addr);
688 operands[4] = gen_reg_rtx (HImode);
691 (define_insn "*strlenhi"
692 [(set (match_operand:HI 0 "register_operand" "=e")
693 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
695 (match_operand:HI 2 "immediate_operand" "i")]
701 [(set_attr "length" "3")
702 (set_attr "cc" "clobber")])
704 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
707 (define_insn "addqi3"
708 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
709 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
710 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
717 [(set_attr "length" "1,1,1,1")
718 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
721 (define_expand "addhi3"
722 [(set (match_operand:HI 0 "register_operand" "")
723 (plus:HI (match_operand:HI 1 "register_operand" "")
724 (match_operand:HI 2 "nonmemory_operand" "")))]
728 if (GET_CODE (operands[2]) == CONST_INT)
730 short tmp = INTVAL (operands[2]);
731 operands[2] = GEN_INT(tmp);
736 (define_insn "*addhi3_zero_extend"
737 [(set (match_operand:HI 0 "register_operand" "=r")
738 (plus:HI (zero_extend:HI
739 (match_operand:QI 1 "register_operand" "r"))
740 (match_operand:HI 2 "register_operand" "0")))]
743 adc %B0,__zero_reg__"
744 [(set_attr "length" "2")
745 (set_attr "cc" "set_n")])
747 (define_insn "*addhi3_zero_extend1"
748 [(set (match_operand:HI 0 "register_operand" "=r")
749 (plus:HI (match_operand:HI 1 "register_operand" "%0")
751 (match_operand:QI 2 "register_operand" "r"))))]
754 adc %B0,__zero_reg__"
755 [(set_attr "length" "2")
756 (set_attr "cc" "set_n")])
758 (define_insn "*addhi3_sp_R_pc2"
759 [(set (match_operand:HI 1 "stack_register_operand" "=q")
760 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
761 (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
764 if (CONST_INT_P (operands[0]))
766 switch(INTVAL (operands[0]))
769 return \"rcall .\" CR_TAB
773 return \"rcall .\" CR_TAB
775 \"push __tmp_reg__\";
777 return \"rcall .\" CR_TAB
780 return \"rcall .\" CR_TAB
781 \"push __tmp_reg__\";
785 return \"push __tmp_reg__\";
789 return \"pop __tmp_reg__\";
791 return \"pop __tmp_reg__\" CR_TAB
794 return \"pop __tmp_reg__\" CR_TAB
795 \"pop __tmp_reg__\" CR_TAB
798 return \"pop __tmp_reg__\" CR_TAB
799 \"pop __tmp_reg__\" CR_TAB
800 \"pop __tmp_reg__\" CR_TAB
803 return \"pop __tmp_reg__\" CR_TAB
804 \"pop __tmp_reg__\" CR_TAB
805 \"pop __tmp_reg__\" CR_TAB
806 \"pop __tmp_reg__\" CR_TAB
812 [(set (attr "length")
813 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
814 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
815 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
816 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
817 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
818 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
819 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
820 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
821 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
822 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
823 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
824 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
827 (define_insn "*addhi3_sp_R_pc3"
828 [(set (match_operand:HI 1 "stack_register_operand" "=q")
829 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
830 (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
833 if (CONST_INT_P (operands[0]))
835 switch(INTVAL (operands[0]))
838 return \"rcall .\" CR_TAB
841 return \"rcall .\" CR_TAB
842 \"push __tmp_reg__\" CR_TAB
843 \"push __tmp_reg__\";
845 return \"rcall .\" CR_TAB
846 \"push __tmp_reg__\";
850 return \"push __tmp_reg__\" CR_TAB
851 \"push __tmp_reg__\";
853 return \"push __tmp_reg__\";
857 return \"pop __tmp_reg__\";
859 return \"pop __tmp_reg__\" CR_TAB
862 return \"pop __tmp_reg__\" CR_TAB
863 \"pop __tmp_reg__\" CR_TAB
866 return \"pop __tmp_reg__\" CR_TAB
867 \"pop __tmp_reg__\" CR_TAB
868 \"pop __tmp_reg__\" CR_TAB
871 return \"pop __tmp_reg__\" CR_TAB
872 \"pop __tmp_reg__\" CR_TAB
873 \"pop __tmp_reg__\" CR_TAB
874 \"pop __tmp_reg__\" CR_TAB
880 [(set (attr "length")
881 (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
882 (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
883 (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
884 (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
885 (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
886 (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
887 (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
888 (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
889 (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
890 (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
891 (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
892 (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
895 (define_insn "*addhi3"
896 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
898 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
899 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
902 add %A0,%A2\;adc %B0,%B2
905 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
906 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
907 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
908 [(set_attr "length" "2,1,1,2,3,3")
909 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
911 (define_insn "addsi3"
912 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
914 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
915 (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
918 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
919 adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
920 sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
921 subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
922 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
923 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
924 [(set_attr "length" "4,3,3,4,5,5")
925 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
927 (define_insn "*addsi3_zero_extend"
928 [(set (match_operand:SI 0 "register_operand" "=r")
929 (plus:SI (zero_extend:SI
930 (match_operand:QI 1 "register_operand" "r"))
931 (match_operand:SI 2 "register_operand" "0")))]
936 adc %D0,__zero_reg__"
937 [(set_attr "length" "4")
938 (set_attr "cc" "set_n")])
940 ;-----------------------------------------------------------------------------
942 (define_insn "subqi3"
943 [(set (match_operand:QI 0 "register_operand" "=r,d")
944 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
945 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
950 [(set_attr "length" "1,1")
951 (set_attr "cc" "set_czn,set_czn")])
953 (define_insn "subhi3"
954 [(set (match_operand:HI 0 "register_operand" "=r,d")
955 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
956 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
959 sub %A0,%A2\;sbc %B0,%B2
960 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
961 [(set_attr "length" "2,2")
962 (set_attr "cc" "set_czn,set_czn")])
964 (define_insn "*subhi3_zero_extend1"
965 [(set (match_operand:HI 0 "register_operand" "=r")
966 (minus:HI (match_operand:HI 1 "register_operand" "0")
968 (match_operand:QI 2 "register_operand" "r"))))]
971 sbc %B0,__zero_reg__"
972 [(set_attr "length" "2")
973 (set_attr "cc" "set_n")])
975 (define_insn "subsi3"
976 [(set (match_operand:SI 0 "register_operand" "=r,d")
977 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
978 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
981 sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
982 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
983 [(set_attr "length" "4,4")
984 (set_attr "cc" "set_czn,set_czn")])
986 (define_insn "*subsi3_zero_extend"
987 [(set (match_operand:SI 0 "register_operand" "=r")
988 (minus:SI (match_operand:SI 1 "register_operand" "0")
990 (match_operand:QI 2 "register_operand" "r"))))]
995 sbc %D0,__zero_reg__"
996 [(set_attr "length" "4")
997 (set_attr "cc" "set_n")])
999 ;******************************************************************************
1002 (define_expand "mulqi3"
1003 [(set (match_operand:QI 0 "register_operand" "")
1004 (mult:QI (match_operand:QI 1 "register_operand" "")
1005 (match_operand:QI 2 "register_operand" "")))]
1010 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1015 (define_insn "*mulqi3_enh"
1016 [(set (match_operand:QI 0 "register_operand" "=r")
1017 (mult:QI (match_operand:QI 1 "register_operand" "r")
1018 (match_operand:QI 2 "register_operand" "r")))]
1023 [(set_attr "length" "3")
1024 (set_attr "cc" "clobber")])
1026 (define_expand "mulqi3_call"
1027 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1028 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1029 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1030 (clobber (reg:QI 22))])
1031 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1035 (define_insn "*mulqi3_call"
1036 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1037 (clobber (reg:QI 22))]
1040 [(set_attr "type" "xcall")
1041 (set_attr "cc" "clobber")])
1043 ;; "umulqi3_highpart"
1044 ;; "smulqi3_highpart"
1045 (define_insn "<extend_su>mulqi3_highpart"
1046 [(set (match_operand:QI 0 "register_operand" "=r")
1048 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1049 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1052 "mul<extend_s> %1,%2
1055 [(set_attr "length" "3")
1056 (set_attr "cc" "clobber")])
1059 ;; Used when expanding div or mod inline for some special values
1060 (define_insn "*subqi3.ashiftrt7"
1061 [(set (match_operand:QI 0 "register_operand" "=r")
1062 (minus:QI (match_operand:QI 1 "register_operand" "0")
1063 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1067 [(set_attr "length" "2")
1068 (set_attr "cc" "clobber")])
1072 (define_insn "<extend_u>mulqihi3"
1073 [(set (match_operand:HI 0 "register_operand" "=r")
1074 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1075 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1077 "mul<extend_s> %1,%2
1080 [(set_attr "length" "3")
1081 (set_attr "cc" "clobber")])
1083 (define_insn "usmulqihi3"
1084 [(set (match_operand:HI 0 "register_operand" "=r")
1085 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1086 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1091 [(set_attr "length" "3")
1092 (set_attr "cc" "clobber")])
1094 ;; Above insn is not canonicalized by insn combine, so here is a version with
1095 ;; operands swapped.
1097 (define_insn "*sumulqihi3"
1098 [(set (match_operand:HI 0 "register_operand" "=r")
1099 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1100 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1105 [(set_attr "length" "3")
1106 (set_attr "cc" "clobber")])
1108 ;; One-extend operand 1
1110 (define_insn "*osmulqihi3"
1111 [(set (match_operand:HI 0 "register_operand" "=&r")
1112 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1113 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1119 [(set_attr "length" "4")
1120 (set_attr "cc" "clobber")])
1122 (define_insn "*oumulqihi3"
1123 [(set (match_operand:HI 0 "register_operand" "=&r")
1124 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1125 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1131 [(set_attr "length" "4")
1132 (set_attr "cc" "clobber")])
1134 ;******************************************************************************
1135 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1136 ;******************************************************************************
1138 (define_insn "*maddqi4"
1139 [(set (match_operand:QI 0 "register_operand" "=r")
1140 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1141 (match_operand:QI 2 "register_operand" "r"))
1142 (match_operand:QI 3 "register_operand" "0")))]
1148 [(set_attr "length" "4")
1149 (set_attr "cc" "clobber")])
1151 (define_insn "*msubqi4"
1152 [(set (match_operand:QI 0 "register_operand" "=r")
1153 (minus:QI (match_operand:QI 3 "register_operand" "0")
1154 (mult:QI (match_operand:QI 1 "register_operand" "r")
1155 (match_operand:QI 2 "register_operand" "r"))))]
1160 [(set_attr "length" "4")
1161 (set_attr "cc" "clobber")])
1163 (define_insn_and_split "*maddqi4.const"
1164 [(set (match_operand:QI 0 "register_operand" "=r")
1165 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1166 (match_operand:QI 2 "const_int_operand" "n"))
1167 (match_operand:QI 3 "register_operand" "0")))
1168 (clobber (match_scratch:QI 4 "=&d"))]
1171 "&& reload_completed"
1176 (plus:QI (mult:QI (match_dup 1)
1181 (define_insn_and_split "*msubqi4.const"
1182 [(set (match_operand:QI 0 "register_operand" "=r")
1183 (minus:QI (match_operand:QI 3 "register_operand" "0")
1184 (mult:QI (match_operand:QI 1 "register_operand" "r")
1185 (match_operand:QI 2 "const_int_operand" "n"))))
1186 (clobber (match_scratch:QI 4 "=&d"))]
1189 "&& reload_completed"
1194 (minus:QI (match_dup 3)
1195 (mult:QI (match_dup 1)
1200 ;******************************************************************************
1201 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1202 ;******************************************************************************
1204 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1207 ;; int foo (unsigned char z)
1209 ;; extern int aInt[];
1210 ;; return aInt[3*z+2];
1213 ;; because the constant +4 then is added explicitely instead of consuming it
1214 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1215 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1216 ;; The implementational effort is the same so we are fine with that approach.
1221 (define_insn "*<extend_u>maddqihi4"
1222 [(set (match_operand:HI 0 "register_operand" "=r")
1223 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1224 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1225 (match_operand:HI 3 "register_operand" "0")))]
1228 "mul<extend_s> %1,%2
1232 [(set_attr "length" "4")
1233 (set_attr "cc" "clobber")])
1237 (define_insn "*<extend_u>msubqihi4"
1238 [(set (match_operand:HI 0 "register_operand" "=r")
1239 (minus:HI (match_operand:HI 3 "register_operand" "0")
1240 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1241 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1243 "mul<extend_s> %1,%2
1247 [(set_attr "length" "4")
1248 (set_attr "cc" "clobber")])
1252 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1253 [(set (match_operand:HI 0 "register_operand" "=r")
1254 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1255 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1256 (match_operand:HI 3 "register_operand" "0")))]
1259 && <any_extend:CODE> != <any_extend2:CODE>"
1261 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1262 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1264 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1266 [(set_attr "length" "4")
1267 (set_attr "cc" "clobber")])
1271 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1272 [(set (match_operand:HI 0 "register_operand" "=r")
1273 (minus:HI (match_operand:HI 3 "register_operand" "0")
1274 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1275 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1278 && <any_extend:CODE> != <any_extend2:CODE>"
1280 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1281 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1283 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1285 [(set_attr "length" "4")
1286 (set_attr "cc" "clobber")])
1288 ;; Handle small constants
1290 ;; "umaddqihi4.uconst"
1291 ;; "maddqihi4.sconst"
1292 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1293 [(set (match_operand:HI 0 "register_operand" "=r")
1294 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1295 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1296 (match_operand:HI 3 "register_operand" "0")))
1297 (clobber (match_scratch:QI 4 "=&d"))]
1300 "&& reload_completed"
1303 ; *umaddqihi4 resp. *maddqihi4
1305 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1306 (any_extend:HI (match_dup 4)))
1309 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1312 ;; "*umsubqihi4.uconst"
1313 ;; "*msubqihi4.sconst"
1314 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1315 [(set (match_operand:HI 0 "register_operand" "=r")
1316 (minus:HI (match_operand:HI 3 "register_operand" "0")
1317 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1318 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1319 (clobber (match_scratch:QI 4 "=&d"))]
1322 "&& reload_completed"
1325 ; *umsubqihi4 resp. *msubqihi4
1327 (minus:HI (match_dup 3)
1328 (mult:HI (any_extend:HI (match_dup 1))
1329 (any_extend:HI (match_dup 4)))))]
1331 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1334 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1335 ;; for MULT with power of 2 and skips trying MULT insn above.
1337 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1338 [(set (match_operand:HI 0 "register_operand" "=r")
1339 (minus:HI (match_operand:HI 3 "register_operand" "0")
1340 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1341 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1342 (clobber (match_scratch:QI 4 "=&d"))]
1345 "&& reload_completed"
1350 (minus:HI (match_dup 3)
1351 (mult:HI (zero_extend:HI (match_dup 1))
1352 (zero_extend:HI (match_dup 4)))))]
1354 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1357 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1358 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1359 ;; because this would require an extra pattern for just one value.
1361 (define_insn_and_split "*msubqihi4.sconst.ashift"
1362 [(set (match_operand:HI 0 "register_operand" "=r")
1363 (minus:HI (match_operand:HI 3 "register_operand" "0")
1364 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1365 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1366 (clobber (match_scratch:QI 4 "=&d"))]
1369 "&& reload_completed"
1374 (minus:HI (match_dup 3)
1375 (mult:HI (sign_extend:HI (match_dup 1))
1376 (sign_extend:HI (match_dup 4)))))]
1378 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1381 ;; For signed/unsigned combinations that require narrow constraint "a"
1382 ;; just provide a pattern if signed/unsigned combination is actually needed.
1384 (define_insn_and_split "*sumaddqihi4.uconst"
1385 [(set (match_operand:HI 0 "register_operand" "=r")
1386 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1387 (match_operand:HI 2 "u8_operand" "M"))
1388 (match_operand:HI 3 "register_operand" "0")))
1389 (clobber (match_scratch:QI 4 "=&a"))]
1391 && !s8_operand (operands[2], VOIDmode)"
1393 "&& reload_completed"
1398 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1399 (zero_extend:HI (match_dup 4)))
1402 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1405 (define_insn_and_split "*sumsubqihi4.uconst"
1406 [(set (match_operand:HI 0 "register_operand" "=r")
1407 (minus:HI (match_operand:HI 3 "register_operand" "0")
1408 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1409 (match_operand:HI 2 "u8_operand" "M"))))
1410 (clobber (match_scratch:QI 4 "=&a"))]
1412 && !s8_operand (operands[2], VOIDmode)"
1414 "&& reload_completed"
1419 (minus:HI (match_dup 3)
1420 (mult:HI (sign_extend:HI (match_dup 1))
1421 (zero_extend:HI (match_dup 4)))))]
1423 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1426 ;******************************************************************************
1427 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1428 ;******************************************************************************
1430 ;; "*muluqihi3.uconst"
1431 ;; "*mulsqihi3.sconst"
1432 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1433 [(set (match_operand:HI 0 "register_operand" "=r")
1434 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1435 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1436 (clobber (match_scratch:QI 3 "=&d"))]
1439 "&& reload_completed"
1442 ; umulqihi3 resp. mulqihi3
1444 (mult:HI (any_extend:HI (match_dup 1))
1445 (any_extend:HI (match_dup 3))))]
1447 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1450 (define_insn_and_split "*muluqihi3.sconst"
1451 [(set (match_operand:HI 0 "register_operand" "=r")
1452 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1453 (match_operand:HI 2 "s8_operand" "n")))
1454 (clobber (match_scratch:QI 3 "=&a"))]
1457 "&& reload_completed"
1462 (mult:HI (zero_extend:HI (match_dup 1))
1463 (sign_extend:HI (match_dup 3))))]
1465 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1468 (define_insn_and_split "*mulsqihi3.uconst"
1469 [(set (match_operand:HI 0 "register_operand" "=r")
1470 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1471 (match_operand:HI 2 "u8_operand" "M")))
1472 (clobber (match_scratch:QI 3 "=&a"))]
1475 "&& reload_completed"
1480 (mult:HI (zero_extend:HI (match_dup 3))
1481 (sign_extend:HI (match_dup 1))))]
1483 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1486 (define_insn_and_split "*mulsqihi3.oconst"
1487 [(set (match_operand:HI 0 "register_operand" "=&r")
1488 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1489 (match_operand:HI 2 "o8_operand" "n")))
1490 (clobber (match_scratch:QI 3 "=&a"))]
1493 "&& reload_completed"
1498 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1499 (sign_extend:HI (match_dup 1))))]
1501 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1504 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1505 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1506 ;; at that time. Fix that.
1508 (define_insn "*ashiftqihi2.signx.1"
1509 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1510 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1514 lsl %A0\;sbc %B0,%B0
1515 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1516 [(set_attr "length" "2,3")
1517 (set_attr "cc" "clobber")])
1519 (define_insn_and_split "*ashifthi3.signx.const"
1520 [(set (match_operand:HI 0 "register_operand" "=r")
1521 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1522 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1523 (clobber (match_scratch:QI 3 "=&d"))]
1526 "&& reload_completed"
1531 (mult:HI (sign_extend:HI (match_dup 1))
1532 (sign_extend:HI (match_dup 3))))]
1534 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1537 (define_insn_and_split "*ashifthi3.signx.const7"
1538 [(set (match_operand:HI 0 "register_operand" "=r")
1539 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1541 (clobber (match_scratch:QI 2 "=&a"))]
1544 "&& reload_completed"
1549 (mult:HI (zero_extend:HI (match_dup 2))
1550 (sign_extend:HI (match_dup 1))))]
1552 operands[3] = gen_int_mode (1 << 7, QImode);
1555 (define_insn_and_split "*ashifthi3.zerox.const"
1556 [(set (match_operand:HI 0 "register_operand" "=r")
1557 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1558 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1559 (clobber (match_scratch:QI 3 "=&d"))]
1562 "&& reload_completed"
1567 (mult:HI (zero_extend:HI (match_dup 1))
1568 (zero_extend:HI (match_dup 3))))]
1570 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1573 ;******************************************************************************
1574 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1575 ;******************************************************************************
1577 (define_insn "mulsqihi3"
1578 [(set (match_operand:HI 0 "register_operand" "=&r")
1579 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1580 (match_operand:HI 2 "register_operand" "a")))]
1587 [(set_attr "length" "5")
1588 (set_attr "cc" "clobber")])
1590 (define_insn "muluqihi3"
1591 [(set (match_operand:HI 0 "register_operand" "=&r")
1592 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1593 (match_operand:HI 2 "register_operand" "r")))]
1600 [(set_attr "length" "5")
1601 (set_attr "cc" "clobber")])
1603 ;; one-extend operand 1
1605 (define_insn "muloqihi3"
1606 [(set (match_operand:HI 0 "register_operand" "=&r")
1607 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1608 (match_operand:HI 2 "register_operand" "r")))]
1616 [(set_attr "length" "6")
1617 (set_attr "cc" "clobber")])
1619 ;******************************************************************************
1621 (define_expand "mulhi3"
1622 [(set (match_operand:HI 0 "register_operand" "")
1623 (mult:HI (match_operand:HI 1 "register_operand" "")
1624 (match_operand:HI 2 "register_or_s9_operand" "")))]
1629 if (!register_operand (operands[2], HImode))
1630 operands[2] = force_reg (HImode, operands[2]);
1632 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1636 /* For small constants we can do better by extending them on the fly.
1637 The constant can be loaded in one instruction and the widening
1638 multiplication is shorter. First try the unsigned variant because it
1639 allows constraint "d" instead of "a" for the signed version. */
1641 if (s9_operand (operands[2], HImode))
1643 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1645 if (u8_operand (operands[2], HImode))
1647 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1649 else if (s8_operand (operands[2], HImode))
1651 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1655 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1661 if (!register_operand (operands[2], HImode))
1662 operands[2] = force_reg (HImode, operands[2]);
1665 (define_insn "*mulhi3_enh"
1666 [(set (match_operand:HI 0 "register_operand" "=&r")
1667 (mult:HI (match_operand:HI 1 "register_operand" "r")
1668 (match_operand:HI 2 "register_operand" "r")))]
1677 [(set_attr "length" "7")
1678 (set_attr "cc" "clobber")])
1680 (define_expand "mulhi3_call"
1681 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1682 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1683 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1684 (clobber (reg:HI 22))
1685 (clobber (reg:QI 21))])
1686 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1690 (define_insn "*mulhi3_call"
1691 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1692 (clobber (reg:HI 22))
1693 (clobber (reg:QI 21))]
1696 [(set_attr "type" "xcall")
1697 (set_attr "cc" "clobber")])
1699 ;; To support widening multiplicatioon with constant we postpone
1700 ;; expanding to the implicit library call until post combine and
1701 ;; prior to register allocation. Clobber all hard registers that
1702 ;; might be used by the (widening) multiply until it is split and
1703 ;; it's final register footprint is worked out.
1705 (define_expand "mulsi3"
1706 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1707 (mult:SI (match_operand:SI 1 "register_operand" "")
1708 (match_operand:SI 2 "nonmemory_operand" "")))
1709 (clobber (reg:HI 26))
1710 (clobber (reg:DI 18))])]
1713 if (u16_operand (operands[2], SImode))
1715 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1716 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1720 if (o16_operand (operands[2], SImode))
1722 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1723 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1728 (define_insn_and_split "*mulsi3"
1729 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1730 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
1731 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1732 (clobber (reg:HI 26))
1733 (clobber (reg:DI 18))]
1734 "AVR_HAVE_MUL && !reload_completed"
1735 { gcc_unreachable(); }
1741 (parallel [(set (reg:SI 22)
1742 (mult:SI (reg:SI 22)
1744 (clobber (reg:HI 26))])
1748 if (u16_operand (operands[2], SImode))
1750 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1751 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1755 if (o16_operand (operands[2], SImode))
1757 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1758 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1765 (define_insn_and_split "mulu<mode>si3"
1766 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1767 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1768 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1769 (clobber (reg:HI 26))
1770 (clobber (reg:DI 18))]
1771 "AVR_HAVE_MUL && !reload_completed"
1772 { gcc_unreachable(); }
1779 (mult:SI (zero_extend:SI (reg:HI 26))
1784 /* Do the QI -> HI extension explicitely before the multiplication. */
1785 /* Do the HI -> SI extension implicitely and after the multiplication. */
1787 if (QImode == <MODE>mode)
1788 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
1790 if (u16_operand (operands[2], SImode))
1792 operands[1] = force_reg (HImode, operands[1]);
1793 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1794 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
1801 (define_insn_and_split "muls<mode>si3"
1802 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1803 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1804 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1805 (clobber (reg:HI 26))
1806 (clobber (reg:DI 18))]
1807 "AVR_HAVE_MUL && !reload_completed"
1808 { gcc_unreachable(); }
1815 (mult:SI (sign_extend:SI (reg:HI 26))
1820 /* Do the QI -> HI extension explicitely before the multiplication. */
1821 /* Do the HI -> SI extension implicitely and after the multiplication. */
1823 if (QImode == <MODE>mode)
1824 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
1826 if (u16_operand (operands[2], SImode)
1827 || s16_operand (operands[2], SImode))
1829 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1831 operands[1] = force_reg (HImode, operands[1]);
1833 if (u16_operand (operands[2], SImode))
1834 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
1836 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
1842 ;; One-extend operand 1
1844 (define_insn_and_split "mulohisi3"
1845 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1846 (mult:SI (not:SI (zero_extend:SI
1847 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
1848 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1849 (clobber (reg:HI 26))
1850 (clobber (reg:DI 18))]
1851 "AVR_HAVE_MUL && !reload_completed"
1852 { gcc_unreachable(); }
1859 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1867 (define_expand "<extend_u>mulhisi3"
1868 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1869 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
1870 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
1871 (clobber (reg:HI 26))
1872 (clobber (reg:DI 18))])]
1876 (define_expand "usmulhisi3"
1877 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1878 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1879 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1880 (clobber (reg:HI 26))
1881 (clobber (reg:DI 18))])]
1885 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
1886 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
1887 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
1888 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
1889 (define_insn_and_split
1890 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
1891 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1892 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1893 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
1894 (clobber (reg:HI 26))
1895 (clobber (reg:DI 18))]
1896 "AVR_HAVE_MUL && !reload_completed"
1897 { gcc_unreachable(); }
1904 (mult:SI (match_dup 3)
1909 rtx xop1 = operands[1];
1910 rtx xop2 = operands[2];
1912 /* Do the QI -> HI extension explicitely before the multiplication. */
1913 /* Do the HI -> SI extension implicitely and after the multiplication. */
1915 if (QImode == <QIHI:MODE>mode)
1916 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
1918 if (QImode == <QIHI2:MODE>mode)
1919 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
1921 if (<any_extend:CODE> == <any_extend2:CODE>
1922 || <any_extend:CODE> == ZERO_EXTEND)
1926 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
1927 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
1931 /* <any_extend:CODE> = SIGN_EXTEND */
1932 /* <any_extend2:CODE> = ZERO_EXTEND */
1936 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
1937 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
1941 ;; "smulhi3_highpart"
1942 ;; "umulhi3_highpart"
1943 (define_expand "<extend_su>mulhi3_highpart"
1945 (match_operand:HI 1 "nonmemory_operand" ""))
1947 (match_operand:HI 2 "nonmemory_operand" ""))
1948 (parallel [(set (reg:HI 24)
1949 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1950 (any_extend:SI (reg:HI 26)))
1952 (clobber (reg:HI 22))])
1953 (set (match_operand:HI 0 "register_operand" "")
1959 (define_insn "*mulsi3_call"
1961 (mult:SI (reg:SI 22)
1963 (clobber (reg:HI 26))]
1966 [(set_attr "type" "xcall")
1967 (set_attr "cc" "clobber")])
1970 ;; "*umulhisi3_call"
1971 (define_insn "*<extend_u>mulhisi3_call"
1973 (mult:SI (any_extend:SI (reg:HI 18))
1974 (any_extend:SI (reg:HI 26))))]
1976 "%~call __<extend_u>mulhisi3"
1977 [(set_attr "type" "xcall")
1978 (set_attr "cc" "clobber")])
1980 ;; "*umulhi3_highpart_call"
1981 ;; "*smulhi3_highpart_call"
1982 (define_insn "*<extend_su>mulhi3_highpart_call"
1984 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1985 (any_extend:SI (reg:HI 26)))
1987 (clobber (reg:HI 22))]
1989 "%~call __<extend_u>mulhisi3"
1990 [(set_attr "type" "xcall")
1991 (set_attr "cc" "clobber")])
1993 (define_insn "*usmulhisi3_call"
1995 (mult:SI (zero_extend:SI (reg:HI 18))
1996 (sign_extend:SI (reg:HI 26))))]
1998 "%~call __usmulhisi3"
1999 [(set_attr "type" "xcall")
2000 (set_attr "cc" "clobber")])
2002 (define_insn "*mul<extend_su>hisi3_call"
2004 (mult:SI (any_extend:SI (reg:HI 26))
2007 "%~call __mul<extend_su>hisi3"
2008 [(set_attr "type" "xcall")
2009 (set_attr "cc" "clobber")])
2011 (define_insn "*mulohisi3_call"
2013 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2016 "%~call __mulohisi3"
2017 [(set_attr "type" "xcall")
2018 (set_attr "cc" "clobber")])
2020 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2023 ;; Generate libgcc.S calls ourselves, because:
2024 ;; - we know exactly which registers are clobbered (for QI and HI
2025 ;; modes, some of the call-used registers are preserved)
2026 ;; - we get both the quotient and the remainder at no extra cost
2027 ;; - we split the patterns only after the first CSE passes because
2028 ;; CSE has problems to operate on hard regs.
2030 (define_insn_and_split "divmodqi4"
2031 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2032 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2033 (match_operand:QI 2 "pseudo_register_operand" "")))
2034 (set (match_operand:QI 3 "pseudo_register_operand" "")
2035 (mod:QI (match_dup 1) (match_dup 2)))
2036 (clobber (reg:QI 22))
2037 (clobber (reg:QI 23))
2038 (clobber (reg:QI 24))
2039 (clobber (reg:QI 25))])]
2041 "this divmodqi4 pattern should have been splitted;"
2043 [(set (reg:QI 24) (match_dup 1))
2044 (set (reg:QI 22) (match_dup 2))
2045 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2046 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2047 (clobber (reg:QI 22))
2048 (clobber (reg:QI 23))])
2049 (set (match_dup 0) (reg:QI 24))
2050 (set (match_dup 3) (reg:QI 25))]
2053 (define_insn "*divmodqi4_call"
2054 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2055 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2056 (clobber (reg:QI 22))
2057 (clobber (reg:QI 23))]
2059 "%~call __divmodqi4"
2060 [(set_attr "type" "xcall")
2061 (set_attr "cc" "clobber")])
2063 (define_insn_and_split "udivmodqi4"
2064 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2065 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2066 (match_operand:QI 2 "pseudo_register_operand" "")))
2067 (set (match_operand:QI 3 "pseudo_register_operand" "")
2068 (umod:QI (match_dup 1) (match_dup 2)))
2069 (clobber (reg:QI 22))
2070 (clobber (reg:QI 23))
2071 (clobber (reg:QI 24))
2072 (clobber (reg:QI 25))])]
2074 "this udivmodqi4 pattern should have been splitted;"
2076 [(set (reg:QI 24) (match_dup 1))
2077 (set (reg:QI 22) (match_dup 2))
2078 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2079 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2080 (clobber (reg:QI 23))])
2081 (set (match_dup 0) (reg:QI 24))
2082 (set (match_dup 3) (reg:QI 25))]
2085 (define_insn "*udivmodqi4_call"
2086 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2087 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2088 (clobber (reg:QI 23))]
2090 "%~call __udivmodqi4"
2091 [(set_attr "type" "xcall")
2092 (set_attr "cc" "clobber")])
2094 (define_insn_and_split "divmodhi4"
2095 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2096 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2097 (match_operand:HI 2 "pseudo_register_operand" "")))
2098 (set (match_operand:HI 3 "pseudo_register_operand" "")
2099 (mod:HI (match_dup 1) (match_dup 2)))
2100 (clobber (reg:QI 21))
2101 (clobber (reg:HI 22))
2102 (clobber (reg:HI 24))
2103 (clobber (reg:HI 26))])]
2105 "this should have been splitted;"
2107 [(set (reg:HI 24) (match_dup 1))
2108 (set (reg:HI 22) (match_dup 2))
2109 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2110 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2111 (clobber (reg:HI 26))
2112 (clobber (reg:QI 21))])
2113 (set (match_dup 0) (reg:HI 22))
2114 (set (match_dup 3) (reg:HI 24))]
2117 (define_insn "*divmodhi4_call"
2118 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2119 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2120 (clobber (reg:HI 26))
2121 (clobber (reg:QI 21))]
2123 "%~call __divmodhi4"
2124 [(set_attr "type" "xcall")
2125 (set_attr "cc" "clobber")])
2127 (define_insn_and_split "udivmodhi4"
2128 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2129 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2130 (match_operand:HI 2 "pseudo_register_operand" "")))
2131 (set (match_operand:HI 3 "pseudo_register_operand" "")
2132 (umod:HI (match_dup 1) (match_dup 2)))
2133 (clobber (reg:QI 21))
2134 (clobber (reg:HI 22))
2135 (clobber (reg:HI 24))
2136 (clobber (reg:HI 26))])]
2138 "this udivmodhi4 pattern should have been splitted.;"
2140 [(set (reg:HI 24) (match_dup 1))
2141 (set (reg:HI 22) (match_dup 2))
2142 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2143 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2144 (clobber (reg:HI 26))
2145 (clobber (reg:QI 21))])
2146 (set (match_dup 0) (reg:HI 22))
2147 (set (match_dup 3) (reg:HI 24))]
2150 (define_insn "*udivmodhi4_call"
2151 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2152 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2153 (clobber (reg:HI 26))
2154 (clobber (reg:QI 21))]
2156 "%~call __udivmodhi4"
2157 [(set_attr "type" "xcall")
2158 (set_attr "cc" "clobber")])
2160 (define_insn_and_split "divmodsi4"
2161 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2162 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2163 (match_operand:SI 2 "pseudo_register_operand" "")))
2164 (set (match_operand:SI 3 "pseudo_register_operand" "")
2165 (mod:SI (match_dup 1) (match_dup 2)))
2166 (clobber (reg:SI 18))
2167 (clobber (reg:SI 22))
2168 (clobber (reg:HI 26))
2169 (clobber (reg:HI 30))])]
2171 "this divmodsi4 pattern should have been splitted;"
2173 [(set (reg:SI 22) (match_dup 1))
2174 (set (reg:SI 18) (match_dup 2))
2175 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2176 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2177 (clobber (reg:HI 26))
2178 (clobber (reg:HI 30))])
2179 (set (match_dup 0) (reg:SI 18))
2180 (set (match_dup 3) (reg:SI 22))]
2183 (define_insn "*divmodsi4_call"
2184 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2185 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2186 (clobber (reg:HI 26))
2187 (clobber (reg:HI 30))]
2189 "%~call __divmodsi4"
2190 [(set_attr "type" "xcall")
2191 (set_attr "cc" "clobber")])
2193 (define_insn_and_split "udivmodsi4"
2194 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2195 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2196 (match_operand:SI 2 "pseudo_register_operand" "")))
2197 (set (match_operand:SI 3 "pseudo_register_operand" "")
2198 (umod:SI (match_dup 1) (match_dup 2)))
2199 (clobber (reg:SI 18))
2200 (clobber (reg:SI 22))
2201 (clobber (reg:HI 26))
2202 (clobber (reg:HI 30))])]
2204 "this udivmodsi4 pattern should have been splitted;"
2206 [(set (reg:SI 22) (match_dup 1))
2207 (set (reg:SI 18) (match_dup 2))
2208 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2209 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2210 (clobber (reg:HI 26))
2211 (clobber (reg:HI 30))])
2212 (set (match_dup 0) (reg:SI 18))
2213 (set (match_dup 3) (reg:SI 22))]
2216 (define_insn "*udivmodsi4_call"
2217 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2218 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2219 (clobber (reg:HI 26))
2220 (clobber (reg:HI 30))]
2222 "%~call __udivmodsi4"
2223 [(set_attr "type" "xcall")
2224 (set_attr "cc" "clobber")])
2226 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2229 (define_insn "andqi3"
2230 [(set (match_operand:QI 0 "register_operand" "=r,d")
2231 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2232 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2237 [(set_attr "length" "1,1")
2238 (set_attr "cc" "set_zn,set_zn")])
2240 (define_insn "andhi3"
2241 [(set (match_operand:HI 0 "register_operand" "=r,d,r")
2242 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
2243 (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
2244 (clobber (match_scratch:QI 3 "=X,X,&d"))]
2247 if (which_alternative==0)
2248 return ("and %A0,%A2" CR_TAB
2250 else if (which_alternative==1)
2252 if (GET_CODE (operands[2]) == CONST_INT)
2254 int mask = INTVAL (operands[2]);
2255 if ((mask & 0xff) != 0xff)
2256 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
2257 if ((mask & 0xff00) != 0xff00)
2258 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
2261 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
2262 AS2 (andi,%B0,hi8(%2)));
2264 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
2268 [(set_attr "length" "2,2,3")
2269 (set_attr "cc" "set_n,clobber,set_n")])
2271 (define_insn "andsi3"
2272 [(set (match_operand:SI 0 "register_operand" "=r,d")
2273 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
2274 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
2277 if (which_alternative==0)
2278 return ("and %0,%2" CR_TAB
2279 "and %B0,%B2" CR_TAB
2280 "and %C0,%C2" CR_TAB
2282 else if (which_alternative==1)
2284 if (GET_CODE (operands[2]) == CONST_INT)
2286 HOST_WIDE_INT mask = INTVAL (operands[2]);
2287 if ((mask & 0xff) != 0xff)
2288 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
2289 if ((mask & 0xff00) != 0xff00)
2290 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
2291 if ((mask & 0xff0000L) != 0xff0000L)
2292 output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
2293 if ((mask & 0xff000000L) != 0xff000000L)
2294 output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
2297 return (AS2 (andi, %A0,lo8(%2)) CR_TAB
2298 AS2 (andi, %B0,hi8(%2)) CR_TAB
2299 AS2 (andi, %C0,hlo8(%2)) CR_TAB
2300 AS2 (andi, %D0,hhi8(%2)));
2304 [(set_attr "length" "4,4")
2305 (set_attr "cc" "set_n,clobber")])
2307 (define_peephole2 ; andi
2308 [(set (match_operand:QI 0 "d_register_operand" "")
2309 (and:QI (match_dup 0)
2310 (match_operand:QI 1 "const_int_operand" "")))
2312 (and:QI (match_dup 0)
2313 (match_operand:QI 2 "const_int_operand" "")))]
2315 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2317 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2320 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2323 (define_insn "iorqi3"
2324 [(set (match_operand:QI 0 "register_operand" "=r,d")
2325 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2326 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2331 [(set_attr "length" "1,1")
2332 (set_attr "cc" "set_zn,set_zn")])
2334 (define_insn "iorhi3"
2335 [(set (match_operand:HI 0 "register_operand" "=r,d")
2336 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2337 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
2340 if (which_alternative==0)
2341 return ("or %A0,%A2" CR_TAB
2343 if (GET_CODE (operands[2]) == CONST_INT)
2345 int mask = INTVAL (operands[2]);
2347 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2349 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2352 return (AS2 (ori,%0,lo8(%2)) CR_TAB
2353 AS2 (ori,%B0,hi8(%2)));
2355 [(set_attr "length" "2,2")
2356 (set_attr "cc" "set_n,clobber")])
2358 (define_insn "*iorhi3_clobber"
2359 [(set (match_operand:HI 0 "register_operand" "=r,r")
2360 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2361 (match_operand:HI 2 "immediate_operand" "M,i")))
2362 (clobber (match_scratch:QI 3 "=&d,&d"))]
2365 ldi %3,lo8(%2)\;or %A0,%3
2366 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
2367 [(set_attr "length" "2,4")
2368 (set_attr "cc" "clobber,set_n")])
2370 (define_insn "iorsi3"
2371 [(set (match_operand:SI 0 "register_operand" "=r,d")
2372 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2373 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
2376 if (which_alternative==0)
2377 return ("or %0,%2" CR_TAB
2381 if (GET_CODE (operands[2]) == CONST_INT)
2383 HOST_WIDE_INT mask = INTVAL (operands[2]);
2385 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2387 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2388 if (mask & 0xff0000L)
2389 output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
2390 if (mask & 0xff000000L)
2391 output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
2394 return (AS2 (ori, %A0,lo8(%2)) CR_TAB
2395 AS2 (ori, %B0,hi8(%2)) CR_TAB
2396 AS2 (ori, %C0,hlo8(%2)) CR_TAB
2397 AS2 (ori, %D0,hhi8(%2)));
2399 [(set_attr "length" "4,4")
2400 (set_attr "cc" "set_n,clobber")])
2402 (define_insn "*iorsi3_clobber"
2403 [(set (match_operand:SI 0 "register_operand" "=r,r")
2404 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2405 (match_operand:SI 2 "immediate_operand" "M,i")))
2406 (clobber (match_scratch:QI 3 "=&d,&d"))]
2409 ldi %3,lo8(%2)\;or %A0,%3
2410 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3"
2411 [(set_attr "length" "2,8")
2412 (set_attr "cc" "clobber,set_n")])
2414 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2417 (define_insn "xorqi3"
2418 [(set (match_operand:QI 0 "register_operand" "=r")
2419 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2420 (match_operand:QI 2 "register_operand" "r")))]
2423 [(set_attr "length" "1")
2424 (set_attr "cc" "set_zn")])
2426 (define_insn "xorhi3"
2427 [(set (match_operand:HI 0 "register_operand" "=r")
2428 (xor:HI (match_operand:HI 1 "register_operand" "%0")
2429 (match_operand:HI 2 "register_operand" "r")))]
2433 [(set_attr "length" "2")
2434 (set_attr "cc" "set_n")])
2436 (define_insn "xorsi3"
2437 [(set (match_operand:SI 0 "register_operand" "=r")
2438 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2439 (match_operand:SI 2 "register_operand" "r")))]
2445 [(set_attr "length" "4")
2446 (set_attr "cc" "set_n")])
2448 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
2451 (define_expand "rotlqi3"
2452 [(set (match_operand:QI 0 "register_operand" "")
2453 (rotate:QI (match_operand:QI 1 "register_operand" "")
2454 (match_operand:QI 2 "const_int_operand" "")))]
2458 if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
2462 (define_insn "rotlqi3_4"
2463 [(set (match_operand:QI 0 "register_operand" "=r")
2464 (rotate:QI (match_operand:QI 1 "register_operand" "0")
2468 [(set_attr "length" "1")
2469 (set_attr "cc" "none")])
2471 ;; Split all rotates of HI,SI and DImode registers where rotation is by
2472 ;; a whole number of bytes. The split creates the appropriate moves and
2473 ;; considers all overlap situations. DImode is split before reload.
2475 ;; HImode does not need scratch. Use attribute for this constraint.
2476 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
2478 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
2479 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
2481 (define_expand "rotl<mode>3"
2482 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
2483 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2484 (match_operand:VOID 2 "const_int_operand" "")))
2485 (clobber (match_dup 3))])]
2488 if (CONST_INT_P (operands[2])
2489 && 0 == INTVAL (operands[2]) % 8)
2491 if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
2492 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2494 operands[3] = gen_rtx_SCRATCH (QImode);
2501 ;; Overlapping non-HImode registers often (but not always) need a scratch.
2502 ;; The best we can do is use early clobber alternative "#&r" so that
2503 ;; completely non-overlapping operands dont get a scratch but # so register
2504 ;; allocation does not prefer non-overlapping.
2507 ; Split word aligned rotates using scratch that is mode dependent.
2508 (define_insn_and_split "*rotw<mode>"
2509 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2510 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2511 (match_operand 2 "const_int_operand" "n,n,n")))
2512 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2514 && CONST_INT_P (operands[2])
2515 && 0 == INTVAL (operands[2]) % 16"
2517 "&& (reload_completed || <MODE>mode == DImode)"
2520 avr_rotate_bytes (operands);
2525 ; Split byte aligned rotates using scratch that is always QI mode.
2526 (define_insn_and_split "*rotb<mode>"
2527 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2528 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2529 (match_operand 2 "const_int_operand" "n,n,n")))
2530 (clobber (match_scratch:QI 3 "=<rotx>"))]
2531 "CONST_INT_P (operands[2])
2532 && (8 == INTVAL (operands[2]) % 16
2534 && 0 == INTVAL (operands[2]) % 16))"
2536 "&& (reload_completed || <MODE>mode == DImode)"
2539 avr_rotate_bytes (operands);
2544 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2545 ;; arithmetic shift left
2547 (define_expand "ashlqi3"
2548 [(set (match_operand:QI 0 "register_operand" "")
2549 (ashift:QI (match_operand:QI 1 "register_operand" "")
2550 (match_operand:QI 2 "general_operand" "")))]
2554 (define_split ; ashlqi3_const4
2555 [(set (match_operand:QI 0 "d_register_operand" "")
2556 (ashift:QI (match_dup 0)
2559 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2560 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2563 (define_split ; ashlqi3_const5
2564 [(set (match_operand:QI 0 "d_register_operand" "")
2565 (ashift:QI (match_dup 0)
2568 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2569 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2570 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2573 (define_split ; ashlqi3_const6
2574 [(set (match_operand:QI 0 "d_register_operand" "")
2575 (ashift:QI (match_dup 0)
2578 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2579 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2580 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2583 (define_insn "*ashlqi3"
2584 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2585 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2586 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2588 "* return ashlqi3_out (insn, operands, NULL);"
2589 [(set_attr "length" "5,0,1,2,4,6,9")
2590 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2592 (define_insn "ashlhi3"
2593 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2594 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2595 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2597 "* return ashlhi3_out (insn, operands, NULL);"
2598 [(set_attr "length" "6,0,2,2,4,10,10")
2599 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2602 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
2603 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
2607 (define_insn_and_split "*ashl<extend_su>qihiqi3"
2608 [(set (match_operand:QI 0 "register_operand" "=r")
2609 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
2610 (match_operand:QI 2 "register_operand" "r"))
2616 (ashift:QI (match_dup 1)
2620 ;; ??? Combiner does not recognize that it could split the following insn;
2621 ;; presumably because he has no register handy?
2623 ;; "*ashluqihiqi3.mem"
2624 ;; "*ashlsqihiqi3.mem"
2625 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
2626 [(set (match_operand:QI 0 "memory_operand" "=m")
2627 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
2628 (match_operand:QI 2 "register_operand" "r"))
2631 { gcc_unreachable(); }
2634 (ashift:QI (match_dup 1)
2639 operands[3] = gen_reg_rtx (QImode);
2644 (define_insn_and_split "*ashlhiqi3"
2645 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
2646 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
2647 (match_operand:QI 2 "register_operand" "r")) 0))]
2649 { gcc_unreachable(); }
2652 (ashift:QI (match_dup 3)
2657 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
2658 operands[4] = gen_reg_rtx (QImode);
2661 ;; High part of 16-bit shift is unused after the instruction:
2662 ;; No need to compute it, map to 8-bit shift.
2665 [(set (match_operand:HI 0 "register_operand" "")
2666 (ashift:HI (match_dup 0)
2667 (match_operand:QI 1 "register_operand" "")))]
2670 (ashift:QI (match_dup 2)
2672 (clobber (match_dup 3))]
2674 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
2676 if (!peep2_reg_dead_p (1, operands[3]))
2679 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
2683 (define_insn "ashlsi3"
2684 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2685 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2686 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2688 "* return ashlsi3_out (insn, operands, NULL);"
2689 [(set_attr "length" "8,0,4,4,8,10,12")
2690 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2692 ;; Optimize if a scratch register from LD_REGS happens to be available.
2694 (define_peephole2 ; ashlqi3_l_const4
2695 [(set (match_operand:QI 0 "l_register_operand" "")
2696 (ashift:QI (match_dup 0)
2698 (match_scratch:QI 1 "d")]
2700 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2701 (set (match_dup 1) (const_int -16))
2702 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2705 (define_peephole2 ; ashlqi3_l_const5
2706 [(set (match_operand:QI 0 "l_register_operand" "")
2707 (ashift:QI (match_dup 0)
2709 (match_scratch:QI 1 "d")]
2711 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2712 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2713 (set (match_dup 1) (const_int -32))
2714 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2717 (define_peephole2 ; ashlqi3_l_const6
2718 [(set (match_operand:QI 0 "l_register_operand" "")
2719 (ashift:QI (match_dup 0)
2721 (match_scratch:QI 1 "d")]
2723 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2724 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2725 (set (match_dup 1) (const_int -64))
2726 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2730 [(match_scratch:QI 3 "d")
2731 (set (match_operand:HI 0 "register_operand" "")
2732 (ashift:HI (match_operand:HI 1 "register_operand" "")
2733 (match_operand:QI 2 "const_int_operand" "")))]
2735 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
2736 (clobber (match_dup 3))])]
2739 (define_insn "*ashlhi3_const"
2740 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2741 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2742 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2743 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2745 "* return ashlhi3_out (insn, operands, NULL);"
2746 [(set_attr "length" "0,2,2,4,10")
2747 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
2750 [(match_scratch:QI 3 "d")
2751 (set (match_operand:SI 0 "register_operand" "")
2752 (ashift:SI (match_operand:SI 1 "register_operand" "")
2753 (match_operand:QI 2 "const_int_operand" "")))]
2755 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2756 (clobber (match_dup 3))])]
2759 (define_insn "*ashlsi3_const"
2760 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2761 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2762 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2763 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2765 "* return ashlsi3_out (insn, operands, NULL);"
2766 [(set_attr "length" "0,4,4,10")
2767 (set_attr "cc" "none,set_n,clobber,clobber")])
2769 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2770 ;; arithmetic shift right
2772 (define_insn "ashrqi3"
2773 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
2774 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
2775 (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))]
2777 "* return ashrqi3_out (insn, operands, NULL);"
2778 [(set_attr "length" "5,0,1,2,5,9")
2779 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
2781 (define_insn "ashrhi3"
2782 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2783 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2784 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2786 "* return ashrhi3_out (insn, operands, NULL);"
2787 [(set_attr "length" "6,0,2,4,4,10,10")
2788 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2790 (define_insn "ashrsi3"
2791 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2792 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2793 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2795 "* return ashrsi3_out (insn, operands, NULL);"
2796 [(set_attr "length" "8,0,4,6,8,10,12")
2797 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2799 ;; Optimize if a scratch register from LD_REGS happens to be available.
2802 [(match_scratch:QI 3 "d")
2803 (set (match_operand:HI 0 "register_operand" "")
2804 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2805 (match_operand:QI 2 "const_int_operand" "")))]
2807 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
2808 (clobber (match_dup 3))])]
2811 (define_insn "*ashrhi3_const"
2812 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2813 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2814 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2815 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2817 "* return ashrhi3_out (insn, operands, NULL);"
2818 [(set_attr "length" "0,2,4,4,10")
2819 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
2822 [(match_scratch:QI 3 "d")
2823 (set (match_operand:SI 0 "register_operand" "")
2824 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2825 (match_operand:QI 2 "const_int_operand" "")))]
2827 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2828 (clobber (match_dup 3))])]
2831 (define_insn "*ashrsi3_const"
2832 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2833 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2834 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2835 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2837 "* return ashrsi3_out (insn, operands, NULL);"
2838 [(set_attr "length" "0,4,4,10")
2839 (set_attr "cc" "none,clobber,set_n,clobber")])
2841 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2842 ;; logical shift right
2844 (define_expand "lshrqi3"
2845 [(set (match_operand:QI 0 "register_operand" "")
2846 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2847 (match_operand:QI 2 "general_operand" "")))]
2851 (define_split ; lshrqi3_const4
2852 [(set (match_operand:QI 0 "d_register_operand" "")
2853 (lshiftrt:QI (match_dup 0)
2856 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2857 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
2860 (define_split ; lshrqi3_const5
2861 [(set (match_operand:QI 0 "d_register_operand" "")
2862 (lshiftrt:QI (match_dup 0)
2865 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2866 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2867 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
2870 (define_split ; lshrqi3_const6
2871 [(set (match_operand:QI 0 "d_register_operand" "")
2872 (lshiftrt:QI (match_dup 0)
2875 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2876 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2877 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
2880 (define_insn "*lshrqi3"
2881 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2882 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2883 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2885 "* return lshrqi3_out (insn, operands, NULL);"
2886 [(set_attr "length" "5,0,1,2,4,6,9")
2887 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2889 (define_insn "lshrhi3"
2890 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2891 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2892 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2894 "* return lshrhi3_out (insn, operands, NULL);"
2895 [(set_attr "length" "6,0,2,2,4,10,10")
2896 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2898 (define_insn "lshrsi3"
2899 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2900 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2901 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2903 "* return lshrsi3_out (insn, operands, NULL);"
2904 [(set_attr "length" "8,0,4,4,8,10,12")
2905 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2907 ;; Optimize if a scratch register from LD_REGS happens to be available.
2909 (define_peephole2 ; lshrqi3_l_const4
2910 [(set (match_operand:QI 0 "l_register_operand" "")
2911 (lshiftrt:QI (match_dup 0)
2913 (match_scratch:QI 1 "d")]
2915 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2916 (set (match_dup 1) (const_int 15))
2917 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2920 (define_peephole2 ; lshrqi3_l_const5
2921 [(set (match_operand:QI 0 "l_register_operand" "")
2922 (lshiftrt:QI (match_dup 0)
2924 (match_scratch:QI 1 "d")]
2926 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2927 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2928 (set (match_dup 1) (const_int 7))
2929 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2932 (define_peephole2 ; lshrqi3_l_const6
2933 [(set (match_operand:QI 0 "l_register_operand" "")
2934 (lshiftrt:QI (match_dup 0)
2936 (match_scratch:QI 1 "d")]
2938 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2939 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2940 (set (match_dup 1) (const_int 3))
2941 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2945 [(match_scratch:QI 3 "d")
2946 (set (match_operand:HI 0 "register_operand" "")
2947 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2948 (match_operand:QI 2 "const_int_operand" "")))]
2950 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
2951 (clobber (match_dup 3))])]
2954 (define_insn "*lshrhi3_const"
2955 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2956 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2957 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2958 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2960 "* return lshrhi3_out (insn, operands, NULL);"
2961 [(set_attr "length" "0,2,2,4,10")
2962 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
2965 [(match_scratch:QI 3 "d")
2966 (set (match_operand:SI 0 "register_operand" "")
2967 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2968 (match_operand:QI 2 "const_int_operand" "")))]
2970 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2971 (clobber (match_dup 3))])]
2974 (define_insn "*lshrsi3_const"
2975 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2976 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2977 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2978 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2980 "* return lshrsi3_out (insn, operands, NULL);"
2981 [(set_attr "length" "0,4,4,10")
2982 (set_attr "cc" "none,clobber,clobber,clobber")])
2984 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2987 (define_insn "absqi2"
2988 [(set (match_operand:QI 0 "register_operand" "=r")
2989 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2993 [(set_attr "length" "2")
2994 (set_attr "cc" "clobber")])
2997 (define_insn "abssf2"
2998 [(set (match_operand:SF 0 "register_operand" "=d,r")
2999 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3004 [(set_attr "length" "1,2")
3005 (set_attr "cc" "set_n,clobber")])
3007 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3010 (define_insn "negqi2"
3011 [(set (match_operand:QI 0 "register_operand" "=r")
3012 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3015 [(set_attr "length" "1")
3016 (set_attr "cc" "set_zn")])
3018 (define_insn "neghi2"
3019 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
3020 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
3023 com %B0\;neg %A0\;sbci %B0,lo8(-1)
3024 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
3025 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3026 [(set_attr "length" "3,4,4")
3027 (set_attr "cc" "set_czn,set_n,set_czn")])
3029 (define_insn "negsi2"
3030 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
3031 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
3034 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3035 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3036 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3037 [(set_attr_alternative "length"
3040 (if_then_else (eq_attr "mcu_have_movw" "yes")
3043 (set_attr "cc" "set_czn,set_n,set_czn")])
3045 (define_insn "negsf2"
3046 [(set (match_operand:SF 0 "register_operand" "=d,r")
3047 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3051 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3052 [(set_attr "length" "1,4")
3053 (set_attr "cc" "set_n,set_n")])
3055 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3058 (define_insn "one_cmplqi2"
3059 [(set (match_operand:QI 0 "register_operand" "=r")
3060 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3063 [(set_attr "length" "1")
3064 (set_attr "cc" "set_czn")])
3066 (define_insn "one_cmplhi2"
3067 [(set (match_operand:HI 0 "register_operand" "=r")
3068 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3072 [(set_attr "length" "2")
3073 (set_attr "cc" "set_n")])
3075 (define_insn "one_cmplsi2"
3076 [(set (match_operand:SI 0 "register_operand" "=r")
3077 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3083 [(set_attr "length" "4")
3084 (set_attr "cc" "set_n")])
3086 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3089 ;; We keep combiner from inserting hard registers into the input of sign- and
3090 ;; zero-extends. A hard register in the input operand is not wanted because
3091 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3092 ;; hard register that overlaps these clobbers won't be combined to a widening
3093 ;; multiplication. There is no need for combine to propagate hard registers,
3094 ;; register allocation can do it just as well.
3096 (define_insn "extendqihi2"
3097 [(set (match_operand:HI 0 "register_operand" "=r,r")
3098 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3101 clr %B0\;sbrc %0,7\;com %B0
3102 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3103 [(set_attr "length" "3,4")
3104 (set_attr "cc" "set_n,set_n")])
3106 (define_insn "extendqisi2"
3107 [(set (match_operand:SI 0 "register_operand" "=r,r")
3108 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3111 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3112 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3113 [(set_attr "length" "5,6")
3114 (set_attr "cc" "set_n,set_n")])
3116 (define_insn "extendhisi2"
3117 [(set (match_operand:SI 0 "register_operand" "=r,r")
3118 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
3121 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3122 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3123 [(set_attr_alternative "length"
3125 (if_then_else (eq_attr "mcu_have_movw" "yes")
3128 (set_attr "cc" "set_n,set_n")])
3130 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3133 (define_insn_and_split "zero_extendqihi2"
3134 [(set (match_operand:HI 0 "register_operand" "=r")
3135 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3139 [(set (match_dup 2) (match_dup 1))
3140 (set (match_dup 3) (const_int 0))]
3142 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
3143 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
3145 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
3146 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
3149 (define_insn_and_split "zero_extendqisi2"
3150 [(set (match_operand:SI 0 "register_operand" "=r")
3151 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3155 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
3156 (set (match_dup 3) (const_int 0))]
3158 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3159 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3161 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3162 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3165 (define_insn_and_split "zero_extendhisi2"
3166 [(set (match_operand:SI 0 "register_operand" "=r")
3167 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
3171 [(set (match_dup 2) (match_dup 1))
3172 (set (match_dup 3) (const_int 0))]
3174 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3175 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3177 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3178 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3181 (define_insn_and_split "zero_extendqidi2"
3182 [(set (match_operand:DI 0 "register_operand" "=r")
3183 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3187 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3188 (set (match_dup 3) (const_int 0))]
3190 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3191 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3193 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3194 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3197 (define_insn_and_split "zero_extendhidi2"
3198 [(set (match_operand:DI 0 "register_operand" "=r")
3199 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3203 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3204 (set (match_dup 3) (const_int 0))]
3206 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3207 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3209 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3210 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3213 (define_insn_and_split "zero_extendsidi2"
3214 [(set (match_operand:DI 0 "register_operand" "=r")
3215 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3219 [(set (match_dup 2) (match_dup 1))
3220 (set (match_dup 3) (const_int 0))]
3222 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3223 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3225 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3226 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3229 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
3232 ; Optimize negated tests into reverse compare if overflow is undefined.
3233 (define_insn "*negated_tstqi"
3235 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
3237 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3238 "cp __zero_reg__,%0"
3239 [(set_attr "cc" "compare")
3240 (set_attr "length" "1")])
3242 (define_insn "*reversed_tstqi"
3244 (compare (const_int 0)
3245 (match_operand:QI 0 "register_operand" "r")))]
3247 "cp __zero_reg__,%0"
3248 [(set_attr "cc" "compare")
3249 (set_attr "length" "2")])
3251 (define_insn "*negated_tsthi"
3253 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
3255 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3256 "cp __zero_reg__,%A0
3257 cpc __zero_reg__,%B0"
3258 [(set_attr "cc" "compare")
3259 (set_attr "length" "2")])
3261 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
3262 ;; though it is unused, because this pattern is synthesized by avr_reorg.
3263 (define_insn "*reversed_tsthi"
3265 (compare (const_int 0)
3266 (match_operand:HI 0 "register_operand" "r")))
3267 (clobber (match_scratch:QI 1 "=X"))]
3269 "cp __zero_reg__,%A0
3270 cpc __zero_reg__,%B0"
3271 [(set_attr "cc" "compare")
3272 (set_attr "length" "2")])
3274 (define_insn "*negated_tstsi"
3276 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
3278 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3279 "cp __zero_reg__,%A0
3280 cpc __zero_reg__,%B0
3281 cpc __zero_reg__,%C0
3282 cpc __zero_reg__,%D0"
3283 [(set_attr "cc" "compare")
3284 (set_attr "length" "4")])
3286 (define_insn "*reversed_tstsi"
3288 (compare (const_int 0)
3289 (match_operand:SI 0 "register_operand" "r")))
3290 (clobber (match_scratch:QI 1 "=X"))]
3292 "cp __zero_reg__,%A0
3293 cpc __zero_reg__,%B0
3294 cpc __zero_reg__,%C0
3295 cpc __zero_reg__,%D0"
3296 [(set_attr "cc" "compare")
3297 (set_attr "length" "4")])
3300 (define_insn "*cmpqi"
3302 (compare (match_operand:QI 0 "register_operand" "r,r,d")
3303 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
3309 [(set_attr "cc" "compare,compare,compare")
3310 (set_attr "length" "1,1,1")])
3312 (define_insn "*cmpqi_sign_extend"
3314 (compare (sign_extend:HI
3315 (match_operand:QI 0 "register_operand" "d"))
3316 (match_operand:HI 1 "const_int_operand" "n")))]
3317 "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
3319 [(set_attr "cc" "compare")
3320 (set_attr "length" "1")])
3322 (define_insn "*cmphi"
3324 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d,d,r,r")
3325 (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
3326 (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
3329 switch (which_alternative)
3332 return out_tsthi (insn, operands[0], NULL);
3335 return (AS2 (cp,%A0,%A1) CR_TAB
3338 if (reg_unused_after (insn, operands[0])
3339 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
3340 && test_hard_reg_class (ADDW_REGS, operands[0]))
3341 return AS2 (sbiw,%0,%1);
3343 return (AS2 (cpi,%0,%1) CR_TAB
3344 AS2 (cpc,%B0,__zero_reg__));
3346 if (reg_unused_after (insn, operands[0]))
3347 return (AS2 (subi,%0,lo8(%1)) CR_TAB
3348 AS2 (sbci,%B0,hi8(%1)));
3350 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
3351 AS2 (cpi, %A0,lo8(%1)) CR_TAB
3354 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3355 AS2 (cp, %A0,%2) CR_TAB
3356 AS2 (cpc, %B0,__zero_reg__));
3359 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3360 AS2 (cp, %A0,%2) CR_TAB
3361 AS2 (ldi, %2,hi8(%1)) CR_TAB
3366 [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
3367 (set_attr "length" "1,2,2,2,3,3,4")])
3370 (define_insn "*cmpsi"
3372 (compare (match_operand:SI 0 "register_operand" "r,r,d,d,r,r")
3373 (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
3374 (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
3377 switch (which_alternative)
3380 return out_tstsi (insn, operands[0], NULL);
3383 return (AS2 (cp,%A0,%A1) CR_TAB
3384 AS2 (cpc,%B0,%B1) CR_TAB
3385 AS2 (cpc,%C0,%C1) CR_TAB
3388 if (reg_unused_after (insn, operands[0])
3389 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
3390 && test_hard_reg_class (ADDW_REGS, operands[0]))
3391 return (AS2 (sbiw,%0,%1) CR_TAB
3392 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3393 AS2 (cpc,%D0,__zero_reg__));
3395 return (AS2 (cpi,%A0,lo8(%1)) CR_TAB
3396 AS2 (cpc,%B0,__zero_reg__) CR_TAB
3397 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3398 AS2 (cpc,%D0,__zero_reg__));
3400 if (reg_unused_after (insn, operands[0]))
3401 return (AS2 (subi,%A0,lo8(%1)) CR_TAB
3402 AS2 (sbci,%B0,hi8(%1)) CR_TAB
3403 AS2 (sbci,%C0,hlo8(%1)) CR_TAB
3404 AS2 (sbci,%D0,hhi8(%1)));
3406 return (AS2 (cpi, %A0,lo8(%1)) CR_TAB
3407 AS2 (ldi, %2,hi8(%1)) CR_TAB
3408 AS2 (cpc, %B0,%2) CR_TAB
3409 AS2 (ldi, %2,hlo8(%1)) CR_TAB
3410 AS2 (cpc, %C0,%2) CR_TAB
3411 AS2 (ldi, %2,hhi8(%1)) CR_TAB
3414 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
3415 AS2 (cp,%A0,%2) CR_TAB
3416 AS2 (cpc,%B0,__zero_reg__) CR_TAB
3417 AS2 (cpc,%C0,__zero_reg__) CR_TAB
3418 AS2 (cpc,%D0,__zero_reg__));
3420 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
3421 AS2 (cp, %A0,%2) CR_TAB
3422 AS2 (ldi, %2,hi8(%1)) CR_TAB
3423 AS2 (cpc, %B0,%2) CR_TAB
3424 AS2 (ldi, %2,hlo8(%1)) CR_TAB
3425 AS2 (cpc, %C0,%2) CR_TAB
3426 AS2 (ldi, %2,hhi8(%1)) CR_TAB
3431 [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
3432 (set_attr "length" "4,4,4,7,5,8")])
3435 ;; ----------------------------------------------------------------------
3436 ;; JUMP INSTRUCTIONS
3437 ;; ----------------------------------------------------------------------
3438 ;; Conditional jump instructions
3440 (define_expand "cbranchsi4"
3441 [(parallel [(set (cc0)
3442 (compare (match_operand:SI 1 "register_operand" "")
3443 (match_operand:SI 2 "nonmemory_operand" "")))
3444 (clobber (match_scratch:QI 4 ""))])
3447 (match_operator 0 "ordered_comparison_operator" [(cc0)
3449 (label_ref (match_operand 3 "" ""))
3453 (define_expand "cbranchhi4"
3454 [(parallel [(set (cc0)
3455 (compare (match_operand:HI 1 "register_operand" "")
3456 (match_operand:HI 2 "nonmemory_operand" "")))
3457 (clobber (match_scratch:QI 4 ""))])
3460 (match_operator 0 "ordered_comparison_operator" [(cc0)
3462 (label_ref (match_operand 3 "" ""))
3466 (define_expand "cbranchqi4"
3468 (compare (match_operand:QI 1 "register_operand" "")
3469 (match_operand:QI 2 "nonmemory_operand" "")))
3472 (match_operator 0 "ordered_comparison_operator" [(cc0)
3474 (label_ref (match_operand 3 "" ""))
3479 ;; Test a single bit in a QI/HI/SImode register.
3480 ;; Combine will create zero extract patterns for single bit tests.
3481 ;; permit any mode in source pattern by using VOIDmode.
3483 (define_insn "*sbrx_branch<mode>"
3486 (match_operator 0 "eqne_operator"
3488 (match_operand:VOID 1 "register_operand" "r")
3490 (match_operand 2 "const_int_operand" "n"))
3492 (label_ref (match_operand 3 "" ""))
3495 "* return avr_out_sbxx_branch (insn, operands);"
3496 [(set (attr "length")
3497 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3498 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3500 (if_then_else (eq_attr "mcu_mega" "no")
3503 (set_attr "cc" "clobber")])
3505 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
3506 ;; or for old peepholes.
3507 ;; Fixme - bitwise Mask will not work for DImode
3509 (define_insn "*sbrx_and_branch<mode>"
3512 (match_operator 0 "eqne_operator"
3514 (match_operand:QISI 1 "register_operand" "r")
3515 (match_operand:QISI 2 "single_one_operand" "n"))
3517 (label_ref (match_operand 3 "" ""))
3521 HOST_WIDE_INT bitnumber;
3522 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
3523 operands[2] = GEN_INT (bitnumber);
3524 return avr_out_sbxx_branch (insn, operands);
3526 [(set (attr "length")
3527 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3528 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3530 (if_then_else (eq_attr "mcu_mega" "no")
3533 (set_attr "cc" "clobber")])
3535 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
3537 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3539 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3540 (label_ref (match_operand 1 "" ""))
3543 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
3547 (label_ref (match_dup 1))
3552 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3554 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3555 (label_ref (match_operand 1 "" ""))
3558 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
3562 (label_ref (match_dup 1))
3567 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3569 (clobber (match_operand:HI 2 ""))])
3570 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3571 (label_ref (match_operand 1 "" ""))
3574 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
3576 (label_ref (match_dup 1))
3581 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3583 (clobber (match_operand:HI 2 ""))])
3584 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3585 (label_ref (match_operand 1 "" ""))
3588 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
3590 (label_ref (match_dup 1))
3595 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3597 (clobber (match_operand:SI 2 ""))])
3598 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3599 (label_ref (match_operand 1 "" ""))
3602 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
3604 (label_ref (match_dup 1))
3606 "operands[2] = GEN_INT (-2147483647 - 1);")
3609 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3611 (clobber (match_operand:SI 2 ""))])
3612 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3613 (label_ref (match_operand 1 "" ""))
3616 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
3618 (label_ref (match_dup 1))
3620 "operands[2] = GEN_INT (-2147483647 - 1);")
3622 ;; ************************************************************************
3623 ;; Implementation of conditional jumps here.
3624 ;; Compare with 0 (test) jumps
3625 ;; ************************************************************************
3627 (define_insn "branch"
3629 (if_then_else (match_operator 1 "simple_comparison_operator"
3632 (label_ref (match_operand 0 "" ""))
3636 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3638 [(set_attr "type" "branch")
3639 (set_attr "cc" "clobber")])
3642 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
3643 ;; or optimized in the remainder.
3645 (define_insn "branch_unspec"
3647 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
3650 (label_ref (match_operand 0 "" ""))
3652 ] UNSPEC_IDENTITY))]
3655 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3657 [(set_attr "type" "branch")
3658 (set_attr "cc" "none")])
3660 ;; ****************************************************************
3661 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
3662 ;; Convert them all to proper jumps.
3663 ;; ****************************************************************/
3665 (define_insn "difficult_branch"
3667 (if_then_else (match_operator 1 "difficult_comparison_operator"
3670 (label_ref (match_operand 0 "" ""))
3674 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3675 [(set_attr "type" "branch1")
3676 (set_attr "cc" "clobber")])
3680 (define_insn "rvbranch"
3682 (if_then_else (match_operator 1 "simple_comparison_operator"
3686 (label_ref (match_operand 0 "" ""))))]
3689 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3690 [(set_attr "type" "branch1")
3691 (set_attr "cc" "clobber")])
3693 (define_insn "difficult_rvbranch"
3695 (if_then_else (match_operator 1 "difficult_comparison_operator"
3699 (label_ref (match_operand 0 "" ""))))]
3702 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3703 [(set_attr "type" "branch")
3704 (set_attr "cc" "clobber")])
3706 ;; **************************************************************************
3707 ;; Unconditional and other jump instructions.
3711 (label_ref (match_operand 0 "" "")))]
3714 if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
3715 return AS1 (jmp,%x0);
3716 return AS1 (rjmp,%x0);
3718 [(set (attr "length")
3719 (if_then_else (match_operand 0 "symbol_ref_operand" "")
3720 (if_then_else (eq_attr "mcu_mega" "no")
3723 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
3724 (le (minus (pc) (match_dup 0)) (const_int 2047)))
3727 (set_attr "cc" "none")])
3731 (define_expand "call"
3732 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3733 (match_operand:HI 1 "general_operand" ""))
3734 (use (const_int 0))])]
3735 ;; Operand 1 not used on the AVR.
3736 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3740 (define_expand "sibcall"
3741 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3742 (match_operand:HI 1 "general_operand" ""))
3743 (use (const_int 1))])]
3744 ;; Operand 1 not used on the AVR.
3745 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3751 (define_expand "call_value"
3752 [(parallel[(set (match_operand 0 "register_operand" "")
3753 (call (match_operand:HI 1 "call_insn_operand" "")
3754 (match_operand:HI 2 "general_operand" "")))
3755 (use (const_int 0))])]
3756 ;; Operand 2 not used on the AVR.
3757 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3761 (define_expand "sibcall_value"
3762 [(parallel[(set (match_operand 0 "register_operand" "")
3763 (call (match_operand:HI 1 "call_insn_operand" "")
3764 (match_operand:HI 2 "general_operand" "")))
3765 (use (const_int 1))])]
3766 ;; Operand 2 not used on the AVR.
3767 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3771 (define_insn "*call_insn"
3772 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
3773 (match_operand:HI 1 "general_operand" "X,X,X,X"))
3774 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
3775 ;; Operand 1 not used on the AVR.
3776 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3783 [(set_attr "cc" "clobber")
3784 (set_attr_alternative "length"
3786 (if_then_else (eq_attr "mcu_mega" "yes")
3790 (if_then_else (eq_attr "mcu_mega" "yes")
3794 (define_insn "*call_value_insn"
3795 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
3796 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
3797 (match_operand:HI 2 "general_operand" "X,X,X,X")))
3798 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
3799 ;; Operand 2 not used on the AVR.
3800 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3807 [(set_attr "cc" "clobber")
3808 (set_attr_alternative "length"
3810 (if_then_else (eq_attr "mcu_mega" "yes")
3814 (if_then_else (eq_attr "mcu_mega" "yes")
3822 [(set_attr "cc" "none")
3823 (set_attr "length" "1")])
3827 (define_expand "indirect_jump"
3828 [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
3830 " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
3832 operands[0] = copy_to_mode_reg(HImode, operand0);
3837 (define_insn "*jcindirect_jump"
3838 [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
3841 [(set_attr "length" "2")
3842 (set_attr "cc" "none")])
3845 (define_insn "*njcindirect_jump"
3846 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
3847 "!AVR_HAVE_EIJMP_EICALL"
3850 push %A0\;push %B0\;ret"
3851 [(set_attr "length" "1,3")
3852 (set_attr "cc" "none,none")])
3854 (define_insn "*indirect_jump_avr6"
3855 [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
3856 "AVR_HAVE_EIJMP_EICALL"
3858 [(set_attr "length" "1")
3859 (set_attr "cc" "none")])
3863 ;; Table made from "rjmp" instructions for <=8K devices.
3864 (define_insn "*tablejump_rjmp"
3865 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
3867 (use (label_ref (match_operand 1 "" "")))
3868 (clobber (match_dup 0))]
3869 "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
3872 push %A0\;push %B0\;ret"
3873 [(set_attr "length" "1,3")
3874 (set_attr "cc" "none,none")])
3876 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
3877 (define_insn "*tablejump_lib"
3878 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3880 (use (label_ref (match_operand 1 "" "")))
3881 (clobber (match_dup 0))]
3882 "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
3883 "%~jmp __tablejump2__"
3884 [(set_attr "length" "2")
3885 (set_attr "cc" "clobber")])
3887 (define_insn "*tablejump_enh"
3888 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3890 (use (label_ref (match_operand 1 "" "")))
3891 (clobber (match_dup 0))]
3892 "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
3899 [(set_attr "length" "6")
3900 (set_attr "cc" "clobber")])
3902 (define_insn "*tablejump"
3903 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3905 (use (label_ref (match_operand 1 "" "")))
3906 (clobber (match_dup 0))]
3907 "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
3916 [(set_attr "length" "8")
3917 (set_attr "cc" "clobber")])
3919 (define_expand "casesi"
3921 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
3922 (match_operand:HI 1 "register_operand" "")))
3923 (parallel [(set (cc0)
3924 (compare (match_dup 6)
3925 (match_operand:HI 2 "register_operand" "")))
3926 (clobber (match_scratch:QI 9 ""))])
3929 (if_then_else (gtu (cc0)
3931 (label_ref (match_operand 4 "" ""))
3935 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
3937 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
3938 (use (label_ref (match_dup 3)))
3939 (clobber (match_dup 6))])]
3943 operands[6] = gen_reg_rtx (HImode);
3947 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3948 ;; This instruction sets Z flag
3951 [(set (cc0) (const_int 0))]
3954 [(set_attr "length" "1")
3955 (set_attr "cc" "compare")])
3957 ;; Clear/set/test a single bit in I/O address space.
3960 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3961 (and:QI (mem:QI (match_dup 0))
3962 (match_operand:QI 1 "single_zero_operand" "n")))]
3965 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
3966 return AS2 (cbi,%m0-0x20,%2);
3968 [(set_attr "length" "1")
3969 (set_attr "cc" "none")])
3972 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3973 (ior:QI (mem:QI (match_dup 0))
3974 (match_operand:QI 1 "single_one_operand" "n")))]
3977 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
3978 return AS2 (sbi,%m0-0x20,%2);
3980 [(set_attr "length" "1")
3981 (set_attr "cc" "none")])
3983 ;; Lower half of the I/O space - use sbic/sbis directly.
3984 (define_insn "*sbix_branch"
3987 (match_operator 0 "eqne_operator"
3989 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
3991 (match_operand 2 "const_int_operand" "n"))
3993 (label_ref (match_operand 3 "" ""))
3996 "* return avr_out_sbxx_branch (insn, operands);"
3997 [(set (attr "length")
3998 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3999 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4001 (if_then_else (eq_attr "mcu_mega" "no")
4004 (set_attr "cc" "clobber")])
4006 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4007 (define_insn "*sbix_branch_bit7"
4010 (match_operator 0 "gelt_operator"
4011 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
4013 (label_ref (match_operand 2 "" ""))
4017 operands[3] = operands[2];
4018 operands[2] = GEN_INT (7);
4019 return avr_out_sbxx_branch (insn, operands);
4021 [(set (attr "length")
4022 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4023 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4025 (if_then_else (eq_attr "mcu_mega" "no")
4028 (set_attr "cc" "clobber")])
4030 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4031 (define_insn "*sbix_branch_tmp"
4034 (match_operator 0 "eqne_operator"
4036 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
4038 (match_operand 2 "const_int_operand" "n"))
4040 (label_ref (match_operand 3 "" ""))
4043 "* return avr_out_sbxx_branch (insn, operands);"
4044 [(set (attr "length")
4045 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4046 (le (minus (pc) (match_dup 3)) (const_int 2045)))
4048 (if_then_else (eq_attr "mcu_mega" "no")
4051 (set_attr "cc" "clobber")])
4053 (define_insn "*sbix_branch_tmp_bit7"
4056 (match_operator 0 "gelt_operator"
4057 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
4059 (label_ref (match_operand 2 "" ""))
4063 operands[3] = operands[2];
4064 operands[2] = GEN_INT (7);
4065 return avr_out_sbxx_branch (insn, operands);
4067 [(set (attr "length")
4068 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4069 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4071 (if_then_else (eq_attr "mcu_mega" "no")
4074 (set_attr "cc" "clobber")])
4076 ;; ************************* Peepholes ********************************
4079 [(set (match_operand:SI 0 "d_register_operand" "")
4080 (plus:SI (match_dup 0)
4084 (compare (match_dup 0)
4086 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4088 (if_then_else (ne (cc0) (const_int 0))
4089 (label_ref (match_operand 2 "" ""))
4095 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4096 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
4097 AS2 (sbc,%C0,__zero_reg__) CR_TAB
4098 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
4100 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
4101 AS2 (sbc,%B0,__zero_reg__) CR_TAB
4102 AS2 (sbc,%C0,__zero_reg__) CR_TAB
4103 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
4104 switch (avr_jump_mode (operands[2],insn))
4107 return AS1 (brcc,%2);
4109 return (AS1 (brcs,.+2) CR_TAB
4112 return (AS1 (brcs,.+4) CR_TAB
4117 [(set (match_operand:HI 0 "d_register_operand" "")
4118 (plus:HI (match_dup 0)
4122 (compare (match_dup 0)
4124 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4126 (if_then_else (ne (cc0) (const_int 0))
4127 (label_ref (match_operand 2 "" ""))
4133 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4134 output_asm_insn (AS2 (sbiw,%0,1), operands);
4136 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
4137 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
4138 switch (avr_jump_mode (operands[2],insn))
4141 return AS1 (brcc,%2);
4143 return (AS1 (brcs,.+2) CR_TAB
4146 return (AS1 (brcs,.+4) CR_TAB
4151 [(set (match_operand:QI 0 "d_register_operand" "")
4152 (plus:QI (match_dup 0)
4155 (compare (match_dup 0)
4158 (if_then_else (ne (cc0) (const_int 0))
4159 (label_ref (match_operand 1 "" ""))
4165 cc_status.value1 = operands[0];
4166 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
4167 output_asm_insn (AS2 (subi,%A0,1), operands);
4168 switch (avr_jump_mode (operands[1],insn))
4171 return AS1 (brcc,%1);
4173 return (AS1 (brcs,.+2) CR_TAB
4176 return (AS1 (brcs,.+4) CR_TAB
4182 (compare (match_operand:QI 0 "register_operand" "")
4185 (if_then_else (eq (cc0) (const_int 0))
4186 (label_ref (match_operand 1 "" ""))
4188 "jump_over_one_insn_p (insn, operands[1])"
4189 "cpse %0,__zero_reg__")
4193 (compare (match_operand:QI 0 "register_operand" "")
4194 (match_operand:QI 1 "register_operand" "")))
4196 (if_then_else (eq (cc0) (const_int 0))
4197 (label_ref (match_operand 2 "" ""))
4199 "jump_over_one_insn_p (insn, operands[2])"
4202 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
4203 ;;prologue/epilogue support instructions
4205 (define_insn "popqi"
4206 [(set (match_operand:QI 0 "register_operand" "=r")
4207 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
4210 [(set_attr "cc" "none")
4211 (set_attr "length" "1")])
4213 ;; Enable Interrupts
4214 (define_insn "enable_interrupt"
4215 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
4218 [(set_attr "length" "1")
4219 (set_attr "cc" "none")])
4221 ;; Disable Interrupts
4222 (define_insn "disable_interrupt"
4223 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
4226 [(set_attr "length" "1")
4227 (set_attr "cc" "none")])
4229 ;; Library prologue saves
4230 (define_insn "call_prologue_saves"
4231 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
4232 (match_operand:HI 0 "immediate_operand" "")
4233 (set (reg:HI REG_SP) (minus:HI
4235 (match_operand:HI 1 "immediate_operand" "")))
4236 (use (reg:HI REG_X))
4237 (clobber (reg:HI REG_Z))]
4239 "ldi r30,lo8(gs(1f))
4241 %~jmp __prologue_saves__+((18 - %0) * 2)
4243 [(set_attr_alternative "length"
4244 [(if_then_else (eq_attr "mcu_mega" "yes")
4247 (set_attr "cc" "clobber")
4250 ; epilogue restores using library
4251 (define_insn "epilogue_restores"
4252 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
4253 (set (reg:HI REG_Y ) (plus:HI
4255 (match_operand:HI 0 "immediate_operand" "")))
4256 (set (reg:HI REG_SP) (reg:HI REG_Y))
4257 (clobber (reg:QI REG_Z))]
4260 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
4261 [(set_attr_alternative "length"
4262 [(if_then_else (eq_attr "mcu_mega" "yes")
4265 (set_attr "cc" "clobber")
4269 (define_insn "return"
4271 "reload_completed && avr_simple_epilogue ()"
4273 [(set_attr "cc" "none")
4274 (set_attr "length" "1")])
4276 (define_insn "return_from_epilogue"
4280 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
4281 && !cfun->machine->is_naked)"
4283 [(set_attr "cc" "none")
4284 (set_attr "length" "1")])
4286 (define_insn "return_from_interrupt_epilogue"
4290 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
4291 && !cfun->machine->is_naked)"
4293 [(set_attr "cc" "none")
4294 (set_attr "length" "1")])
4296 (define_insn "return_from_naked_epilogue"
4300 && cfun->machine->is_naked)"
4302 [(set_attr "cc" "none")
4303 (set_attr "length" "0")])
4305 (define_expand "prologue"
4314 (define_expand "epilogue"
4318 expand_epilogue (false /* sibcall_p */);
4322 (define_expand "sibcall_epilogue"
4326 expand_epilogue (true /* sibcall_p */);
4330 ;; Some instructions resp. instruction sequences available
4333 (define_insn "delay_cycles_1"
4334 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
4336 UNSPECV_DELAY_CYCLES)
4337 (clobber (match_scratch:QI 1 "=&d"))]
4342 [(set_attr "length" "3")
4343 (set_attr "cc" "clobber")])
4345 (define_insn "delay_cycles_2"
4346 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
4348 UNSPECV_DELAY_CYCLES)
4349 (clobber (match_scratch:HI 1 "=&w"))]
4355 [(set_attr "length" "4")
4356 (set_attr "cc" "clobber")])
4358 (define_insn "delay_cycles_3"
4359 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4361 UNSPECV_DELAY_CYCLES)
4362 (clobber (match_scratch:QI 1 "=&d"))
4363 (clobber (match_scratch:QI 2 "=&d"))
4364 (clobber (match_scratch:QI 3 "=&d"))]
4373 [(set_attr "length" "7")
4374 (set_attr "cc" "clobber")])
4376 (define_insn "delay_cycles_4"
4377 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4379 UNSPECV_DELAY_CYCLES)
4380 (clobber (match_scratch:QI 1 "=&d"))
4381 (clobber (match_scratch:QI 2 "=&d"))
4382 (clobber (match_scratch:QI 3 "=&d"))
4383 (clobber (match_scratch:QI 4 "=&d"))]
4394 [(set_attr "length" "9")
4395 (set_attr "cc" "clobber")])
4400 (define_expand "parityhi2"
4402 (match_operand:HI 1 "register_operand" ""))
4404 (parity:HI (reg:HI 24)))
4405 (set (match_operand:HI 0 "register_operand" "")
4410 (define_expand "paritysi2"
4412 (match_operand:SI 1 "register_operand" ""))
4414 (truncate:HI (parity:SI (reg:SI 22))))
4417 (set (match_operand:SI 0 "register_operand" "")
4418 (zero_extend:SI (match_dup 2)))]
4421 operands[2] = gen_reg_rtx (HImode);
4424 (define_insn "*parityhi2.libgcc"
4426 (parity:HI (reg:HI 24)))]
4428 "%~call __parityhi2"
4429 [(set_attr "type" "xcall")
4430 (set_attr "cc" "clobber")])
4432 (define_insn "*parityqihi2.libgcc"
4434 (zero_extend:HI (parity:QI (reg:QI 24))))]
4436 "%~call __parityqi2"
4437 [(set_attr "type" "xcall")
4438 (set_attr "cc" "clobber")])
4440 (define_insn "*paritysihi2.libgcc"
4442 (truncate:HI (parity:SI (reg:SI 22))))]
4444 "%~call __paritysi2"
4445 [(set_attr "type" "xcall")
4446 (set_attr "cc" "clobber")])
4451 (define_expand "popcounthi2"
4453 (match_operand:HI 1 "register_operand" ""))
4455 (popcount:HI (reg:HI 24)))
4456 (set (match_operand:HI 0 "register_operand" "")
4461 (define_expand "popcountsi2"
4463 (match_operand:SI 1 "register_operand" ""))
4465 (truncate:HI (popcount:SI (reg:SI 22))))
4468 (set (match_operand:SI 0 "register_operand" "")
4469 (zero_extend:SI (match_dup 2)))]
4472 operands[2] = gen_reg_rtx (HImode);
4475 (define_insn "*popcounthi2.libgcc"
4477 (popcount:HI (reg:HI 24)))]
4479 "%~call __popcounthi2"
4480 [(set_attr "type" "xcall")
4481 (set_attr "cc" "clobber")])
4483 (define_insn "*popcountsi2.libgcc"
4485 (truncate:HI (popcount:SI (reg:SI 22))))]
4487 "%~call __popcountsi2"
4488 [(set_attr "type" "xcall")
4489 (set_attr "cc" "clobber")])
4491 (define_insn "*popcountqi2.libgcc"
4493 (popcount:QI (reg:QI 24)))]
4495 "%~call __popcountqi2"
4496 [(set_attr "type" "xcall")
4497 (set_attr "cc" "clobber")])
4499 (define_insn_and_split "*popcountqihi2.libgcc"
4501 (zero_extend:HI (popcount:QI (reg:QI 24))))]
4506 (popcount:QI (reg:QI 24)))
4511 ;; Count Leading Zeros
4513 (define_expand "clzhi2"
4515 (match_operand:HI 1 "register_operand" ""))
4516 (parallel [(set (reg:HI 24)
4517 (clz:HI (reg:HI 24)))
4518 (clobber (reg:QI 26))])
4519 (set (match_operand:HI 0 "register_operand" "")
4524 (define_expand "clzsi2"
4526 (match_operand:SI 1 "register_operand" ""))
4527 (parallel [(set (reg:HI 24)
4528 (truncate:HI (clz:SI (reg:SI 22))))
4529 (clobber (reg:QI 26))])
4532 (set (match_operand:SI 0 "register_operand" "")
4533 (zero_extend:SI (match_dup 2)))]
4536 operands[2] = gen_reg_rtx (HImode);
4539 (define_insn "*clzhi2.libgcc"
4541 (clz:HI (reg:HI 24)))
4542 (clobber (reg:QI 26))]
4545 [(set_attr "type" "xcall")
4546 (set_attr "cc" "clobber")])
4548 (define_insn "*clzsihi2.libgcc"
4550 (truncate:HI (clz:SI (reg:SI 22))))
4551 (clobber (reg:QI 26))]
4554 [(set_attr "type" "xcall")
4555 (set_attr "cc" "clobber")])
4557 ;; Count Trailing Zeros
4559 (define_expand "ctzhi2"
4561 (match_operand:HI 1 "register_operand" ""))
4562 (parallel [(set (reg:HI 24)
4563 (ctz:HI (reg:HI 24)))
4564 (clobber (reg:QI 26))])
4565 (set (match_operand:HI 0 "register_operand" "")
4570 (define_expand "ctzsi2"
4572 (match_operand:SI 1 "register_operand" ""))
4573 (parallel [(set (reg:HI 24)
4574 (truncate:HI (ctz:SI (reg:SI 22))))
4575 (clobber (reg:QI 22))
4576 (clobber (reg:QI 26))])
4579 (set (match_operand:SI 0 "register_operand" "")
4580 (zero_extend:SI (match_dup 2)))]
4583 operands[2] = gen_reg_rtx (HImode);
4586 (define_insn "*ctzhi2.libgcc"
4588 (ctz:HI (reg:HI 24)))
4589 (clobber (reg:QI 26))]
4592 [(set_attr "type" "xcall")
4593 (set_attr "cc" "clobber")])
4595 (define_insn "*ctzsihi2.libgcc"
4597 (truncate:HI (ctz:SI (reg:SI 22))))
4598 (clobber (reg:QI 22))
4599 (clobber (reg:QI 26))]
4602 [(set_attr "type" "xcall")
4603 (set_attr "cc" "clobber")])
4607 (define_expand "ffshi2"
4609 (match_operand:HI 1 "register_operand" ""))
4610 (parallel [(set (reg:HI 24)
4611 (ffs:HI (reg:HI 24)))
4612 (clobber (reg:QI 26))])
4613 (set (match_operand:HI 0 "register_operand" "")
4618 (define_expand "ffssi2"
4620 (match_operand:SI 1 "register_operand" ""))
4621 (parallel [(set (reg:HI 24)
4622 (truncate:HI (ffs:SI (reg:SI 22))))
4623 (clobber (reg:QI 22))
4624 (clobber (reg:QI 26))])
4627 (set (match_operand:SI 0 "register_operand" "")
4628 (zero_extend:SI (match_dup 2)))]
4631 operands[2] = gen_reg_rtx (HImode);
4634 (define_insn "*ffshi2.libgcc"
4636 (ffs:HI (reg:HI 24)))
4637 (clobber (reg:QI 26))]
4640 [(set_attr "type" "xcall")
4641 (set_attr "cc" "clobber")])
4643 (define_insn "*ffssihi2.libgcc"
4645 (truncate:HI (ffs:SI (reg:SI 22))))
4646 (clobber (reg:QI 22))
4647 (clobber (reg:QI 26))]
4650 [(set_attr "type" "xcall")
4651 (set_attr "cc" "clobber")])
4655 (define_insn "copysignsf3"
4656 [(set (match_operand:SF 0 "register_operand" "=r")
4657 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
4658 (match_operand:SF 2 "register_operand" "r")]
4661 "bst %D2,7\;bld %D0,7"
4662 [(set_attr "length" "2")
4663 (set_attr "cc" "none")])
4665 ;; Swap Bytes (change byte-endianess)
4667 (define_expand "bswapsi2"
4669 (match_operand:SI 1 "register_operand" ""))
4671 (bswap:SI (reg:SI 22)))
4672 (set (match_operand:SI 0 "register_operand" "")
4677 (define_insn "*bswapsi2.libgcc"
4679 (bswap:SI (reg:SI 22)))]
4682 [(set_attr "type" "xcall")
4683 (set_attr "cc" "clobber")])
4688 ;; NOP taking 1 or 2 Ticks
4690 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
4696 [(set_attr "length" "1")
4697 (set_attr "cc" "none")])
4700 (define_insn "sleep"
4701 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
4704 [(set_attr "length" "1")
4705 (set_attr "cc" "none")])
4709 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
4712 [(set_attr "length" "1")
4713 (set_attr "cc" "none")])
4716 (define_expand "fmul"
4718 (match_operand:QI 1 "register_operand" ""))
4720 (match_operand:QI 2 "register_operand" ""))
4721 (parallel [(set (reg:HI 22)
4722 (unspec:HI [(reg:QI 24)
4723 (reg:QI 25)] UNSPEC_FMUL))
4724 (clobber (reg:HI 24))])
4725 (set (match_operand:HI 0 "register_operand" "")
4731 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
4736 (define_insn "fmul_insn"
4737 [(set (match_operand:HI 0 "register_operand" "=r")
4738 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4739 (match_operand:QI 2 "register_operand" "a")]
4745 [(set_attr "length" "3")
4746 (set_attr "cc" "clobber")])
4748 (define_insn "*fmul.call"
4750 (unspec:HI [(reg:QI 24)
4751 (reg:QI 25)] UNSPEC_FMUL))
4752 (clobber (reg:HI 24))]
4755 [(set_attr "type" "xcall")
4756 (set_attr "cc" "clobber")])
4759 (define_expand "fmuls"
4761 (match_operand:QI 1 "register_operand" ""))
4763 (match_operand:QI 2 "register_operand" ""))
4764 (parallel [(set (reg:HI 22)
4765 (unspec:HI [(reg:QI 24)
4766 (reg:QI 25)] UNSPEC_FMULS))
4767 (clobber (reg:HI 24))])
4768 (set (match_operand:HI 0 "register_operand" "")
4774 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
4779 (define_insn "fmuls_insn"
4780 [(set (match_operand:HI 0 "register_operand" "=r")
4781 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4782 (match_operand:QI 2 "register_operand" "a")]
4788 [(set_attr "length" "3")
4789 (set_attr "cc" "clobber")])
4791 (define_insn "*fmuls.call"
4793 (unspec:HI [(reg:QI 24)
4794 (reg:QI 25)] UNSPEC_FMULS))
4795 (clobber (reg:HI 24))]
4798 [(set_attr "type" "xcall")
4799 (set_attr "cc" "clobber")])
4802 (define_expand "fmulsu"
4804 (match_operand:QI 1 "register_operand" ""))
4806 (match_operand:QI 2 "register_operand" ""))
4807 (parallel [(set (reg:HI 22)
4808 (unspec:HI [(reg:QI 24)
4809 (reg:QI 25)] UNSPEC_FMULSU))
4810 (clobber (reg:HI 24))])
4811 (set (match_operand:HI 0 "register_operand" "")
4817 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
4822 (define_insn "fmulsu_insn"
4823 [(set (match_operand:HI 0 "register_operand" "=r")
4824 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4825 (match_operand:QI 2 "register_operand" "a")]
4831 [(set_attr "length" "3")
4832 (set_attr "cc" "clobber")])
4834 (define_insn "*fmulsu.call"
4836 (unspec:HI [(reg:QI 24)
4837 (reg:QI 25)] UNSPEC_FMULSU))
4838 (clobber (reg:HI 24))]
4841 [(set_attr "type" "xcall")
4842 (set_attr "cc" "clobber")])
4845 ;; Some combiner patterns dealing with bits.
4848 ;; Move bit $3.0 into bit $0.$4
4849 (define_insn "*movbitqi.1-6.a"
4850 [(set (match_operand:QI 0 "register_operand" "=r")
4851 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4852 (match_operand:QI 2 "single_zero_operand" "n"))
4853 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
4854 (match_operand:QI 4 "const_0_to_7_operand" "n"))
4855 (match_operand:QI 5 "single_one_operand" "n"))))]
4856 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
4857 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
4858 "bst %3,0\;bld %0,%4"
4859 [(set_attr "length" "2")
4860 (set_attr "cc" "none")])
4862 ;; Move bit $3.0 into bit $0.$4
4863 ;; Variation of above. Unfortunately, there is no canonicalized representation
4864 ;; of moving around bits. So what we see here depends on how user writes down
4865 ;; bit manipulations.
4866 (define_insn "*movbitqi.1-6.b"
4867 [(set (match_operand:QI 0 "register_operand" "=r")
4868 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4869 (match_operand:QI 2 "single_zero_operand" "n"))
4870 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
4872 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
4873 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4874 "bst %3,0\;bld %0,%4"
4875 [(set_attr "length" "2")
4876 (set_attr "cc" "none")])
4878 ;; Move bit $3.0 into bit $0.0.
4879 ;; For bit 0, combiner generates slightly different pattern.
4880 (define_insn "*movbitqi.0"
4881 [(set (match_operand:QI 0 "register_operand" "=r")
4882 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4883 (match_operand:QI 2 "single_zero_operand" "n"))
4884 (and:QI (match_operand:QI 3 "register_operand" "r")
4886 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4887 "bst %3,0\;bld %0,0"
4888 [(set_attr "length" "2")
4889 (set_attr "cc" "none")])
4891 ;; Move bit $2.0 into bit $0.7.
4892 ;; For bit 7, combiner generates slightly different pattern
4893 (define_insn "*movbitqi.7"
4894 [(set (match_operand:QI 0 "register_operand" "=r")
4895 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4897 (ashift:QI (match_operand:QI 2 "register_operand" "r")
4900 "bst %2,0\;bld %0,7"
4901 [(set_attr "length" "2")
4902 (set_attr "cc" "none")])
4904 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
4905 ;; and input/output match. We provide a special pattern for this, because
4906 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
4907 ;; operation on I/O is atomic.
4908 (define_insn "*insv.io"
4909 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
4911 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
4912 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
4917 sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
4918 [(set_attr "length" "1,1,4")
4919 (set_attr "cc" "none")])
4921 (define_insn "*insv.not.io"
4922 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4924 (match_operand:QI 1 "const_0_to_7_operand" "n"))
4925 (not:QI (match_operand:QI 2 "register_operand" "r")))]
4927 "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
4928 [(set_attr "length" "4")
4929 (set_attr "cc" "none")])
4931 ;; The insv expander.
4932 ;; We only support 1-bit inserts
4933 (define_expand "insv"
4934 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
4935 (match_operand:QI 1 "const1_operand" "") ; width
4936 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
4937 (match_operand:QI 3 "nonmemory_operand" ""))]
4941 ;; Insert bit $2.0 into $0.$1
4942 (define_insn "*insv.reg"
4943 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
4945 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
4946 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
4950 andi %0,lo8(~(1<<%1))
4954 [(set_attr "length" "2,1,1,2,2")
4955 (set_attr "cc" "none,set_zn,set_zn,none,none")])
4958 ;; Some combine patterns that try to fix bad code when a value is composed
4959 ;; from byte parts like in PR27663.
4960 ;; The patterns give some release but the code still is not optimal,
4961 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
4962 ;; That switch obfuscates things here and in many other places.
4964 (define_insn_and_split "*ior<mode>qi.byte0"
4965 [(set (match_operand:HISI 0 "register_operand" "=r")
4967 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4968 (match_operand:HISI 2 "register_operand" "0")))]
4973 (ior:QI (match_dup 3)
4976 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
4979 (define_insn_and_split "*ior<mode>qi.byte1-3"
4980 [(set (match_operand:HISI 0 "register_operand" "=r")
4982 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4983 (match_operand:QI 2 "const_8_16_24_operand" "n"))
4984 (match_operand:HISI 3 "register_operand" "0")))]
4985 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
4987 "&& reload_completed"
4989 (ior:QI (match_dup 4)
4992 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
4993 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
4996 (define_expand "extzv"
4997 [(set (match_operand:QI 0 "register_operand" "")
4998 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
4999 (match_operand:QI 2 "const1_operand" "")
5000 (match_operand:QI 3 "const_0_to_7_operand" "")))]
5004 (define_insn "*extzv"
5005 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
5006 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
5008 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
5012 mov %0,%1\;andi %0,1
5015 bst %1,%2\;clr %0\;bld %0,0"
5016 [(set_attr "length" "1,2,2,2,3")
5017 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
5019 (define_insn_and_split "*extzv.qihi1"
5020 [(set (match_operand:HI 0 "register_operand" "=r")
5021 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
5023 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
5028 (zero_extract:QI (match_dup 1)
5034 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5035 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5038 (define_insn_and_split "*extzv.qihi2"
5039 [(set (match_operand:HI 0 "register_operand" "=r")
5041 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
5043 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
5048 (zero_extract:QI (match_dup 1)
5054 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5055 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);