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,
82 (const_string "none"))
84 (define_attr "type" "branch,branch1,arith,xcall"
85 (const_string "arith"))
87 (define_attr "mcu_have_movw" "yes,no"
88 (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
90 (const_string "no"))))
92 (define_attr "mcu_mega" "yes,no"
93 (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
95 (const_string "no"))))
98 ;; The size of instructions in bytes.
99 ;; XXX may depend from "cc"
101 (define_attr "length" ""
102 (cond [(eq_attr "type" "branch")
103 (if_then_else (and (ge (minus (pc) (match_dup 0))
105 (le (minus (pc) (match_dup 0))
108 (if_then_else (and (ge (minus (pc) (match_dup 0))
110 (le (minus (pc) (match_dup 0))
114 (eq_attr "type" "branch1")
115 (if_then_else (and (ge (minus (pc) (match_dup 0))
117 (le (minus (pc) (match_dup 0))
120 (if_then_else (and (ge (minus (pc) (match_dup 0))
122 (le (minus (pc) (match_dup 0))
126 (eq_attr "type" "xcall")
127 (if_then_else (eq_attr "mcu_mega" "no")
132 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
133 ;; Following insn attribute tells if and how the adjustment has to be
135 ;; no No adjustment needed; attribute "length" is fine.
136 ;; yes Analyse pattern in adjust_insn_length by hand.
137 ;; Otherwise do special processing depending on the attribute.
139 (define_attr "adjust_len"
140 "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare,
141 mov8, mov16, mov32, reload_in16, reload_in32,
142 ashlqi, ashrqi, lshrqi,
143 ashlhi, ashrhi, lshrhi,
144 ashlsi, ashrsi, lshrsi,
148 ;; Define mode iterators
149 (define_mode_iterator QIHI [(QI "") (HI "")])
150 (define_mode_iterator QIHI2 [(QI "") (HI "")])
151 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
152 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
153 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
154 (define_mode_iterator HISI [(HI "") (SI "")])
156 ;; Define code iterators
157 ;; Define two incarnations so that we can build the cross product.
158 (define_code_iterator any_extend [sign_extend zero_extend])
159 (define_code_iterator any_extend2 [sign_extend zero_extend])
161 ;; Define code attributes
162 (define_code_attr extend_su
166 (define_code_attr extend_u
170 (define_code_attr extend_s
174 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
175 (define_code_attr mul_r_d
180 ;;========================================================================
181 ;; The following is used by nonlocal_goto and setjmp.
182 ;; The receiver pattern will create no instructions since internally
183 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
184 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
185 ;; The 'null' receiver also avoids problems with optimisation
186 ;; not recognising incoming jmp and removing code that resets frame_pointer.
187 ;; The code derived from builtins.c.
189 (define_expand "nonlocal_goto_receiver"
191 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
194 emit_move_insn (virtual_stack_vars_rtx,
195 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
196 gen_int_mode (STARTING_FRAME_OFFSET,
198 /* This might change the hard frame pointer in ways that aren't
199 apparent to early optimization passes, so force a clobber. */
200 emit_clobber (hard_frame_pointer_rtx);
205 ;; Defining nonlocal_goto_receiver means we must also define this.
206 ;; even though its function is identical to that in builtins.c
208 (define_expand "nonlocal_goto"
210 (use (match_operand 0 "general_operand"))
211 (use (match_operand 1 "general_operand"))
212 (use (match_operand 2 "general_operand"))
213 (use (match_operand 3 "general_operand"))
217 rtx r_label = copy_to_reg (operands[1]);
218 rtx r_fp = operands[3];
219 rtx r_sp = operands[2];
221 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
223 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
225 emit_move_insn (hard_frame_pointer_rtx, r_fp);
226 emit_stack_restore (SAVE_NONLOCAL, r_sp);
228 emit_use (hard_frame_pointer_rtx);
229 emit_use (stack_pointer_rtx);
231 emit_indirect_jump (r_label);
236 (define_insn "pushqi1"
237 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
238 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
243 [(set_attr "length" "1,1")])
245 ;; All modes for a multi-byte push. We must include complex modes here too,
246 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
247 (define_mode_iterator MPUSH
254 (define_expand "push<mode>1"
255 [(match_operand:MPUSH 0 "" "")]
259 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
261 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
262 if (part != const0_rtx)
263 part = force_reg (QImode, part);
264 emit_insn (gen_pushqi1 (part));
269 ;; Notice a special-case when adding N to SP where N results in a
270 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
272 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
274 && frame_pointer_needed
275 && !cfun->calls_alloca
276 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
277 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
280 ;;========================================================================
282 ;; The last alternative (any immediate constant to any register) is
283 ;; very expensive. It should be optimized by peephole2 if a scratch
284 ;; register is available, but then that register could just as well be
285 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
286 ;; are call-saved registers, and most of LD_REGS are call-used registers,
287 ;; so this may still be a win for registers live across function calls.
289 (define_expand "movqi"
290 [(set (match_operand:QI 0 "nonimmediate_operand" "")
291 (match_operand:QI 1 "general_operand" ""))]
293 "/* One of the ops has to be in a register. */
294 if (!register_operand(operand0, QImode)
295 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
296 operands[1] = copy_to_mode_reg(QImode, operand1);
299 (define_insn "movqi_insn"
300 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
301 (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))]
302 "(register_operand (operands[0],QImode)
303 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
304 "* return output_movqi (insn, operands, NULL);"
305 [(set_attr "length" "1,1,5,5,1,1,4")
306 (set_attr "adjust_len" "mov8")
307 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
309 ;; This is used in peephole2 to optimize loading immediate constants
310 ;; if a scratch register from LD_REGS happens to be available.
312 (define_insn "*reload_inqi"
313 [(set (match_operand:QI 0 "register_operand" "=l")
314 (match_operand:QI 1 "immediate_operand" "i"))
315 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
319 [(set_attr "length" "2")
320 (set_attr "cc" "none")])
323 [(match_scratch:QI 2 "d")
324 (set (match_operand:QI 0 "l_register_operand" "")
325 (match_operand:QI 1 "immediate_operand" ""))]
326 "(operands[1] != const0_rtx
327 && operands[1] != const1_rtx
328 && operands[1] != constm1_rtx)"
329 [(parallel [(set (match_dup 0) (match_dup 1))
330 (clobber (match_dup 2))])]
333 ;;============================================================================
334 ;; move word (16 bit)
336 (define_expand "movhi"
337 [(set (match_operand:HI 0 "nonimmediate_operand" "")
338 (match_operand:HI 1 "general_operand" ""))]
342 /* One of the ops has to be in a register. */
343 if (!register_operand(operand0, HImode)
344 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
346 operands[1] = copy_to_mode_reg(HImode, operand1);
350 (define_insn "movhi_sp_r_irq_off"
351 [(set (match_operand:HI 0 "stack_register_operand" "=q")
352 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
353 UNSPECV_WRITE_SP_IRQ_OFF))]
357 [(set_attr "length" "2")
358 (set_attr "cc" "none")])
360 (define_insn "movhi_sp_r_irq_on"
361 [(set (match_operand:HI 0 "stack_register_operand" "=q")
362 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
363 UNSPECV_WRITE_SP_IRQ_ON))]
369 [(set_attr "length" "4")
370 (set_attr "cc" "none")])
373 [(match_scratch:QI 2 "d")
374 (set (match_operand:HI 0 "l_register_operand" "")
375 (match_operand:HI 1 "immediate_operand" ""))]
376 "(operands[1] != const0_rtx
377 && operands[1] != constm1_rtx)"
378 [(parallel [(set (match_dup 0) (match_dup 1))
379 (clobber (match_dup 2))])]
382 ;; '*' because it is not used in rtl generation, only in above peephole
383 (define_insn "*reload_inhi"
384 [(set (match_operand:HI 0 "register_operand" "=r")
385 (match_operand:HI 1 "immediate_operand" "i"))
386 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
389 return output_reload_inhi (operands, operands[2], NULL);
391 [(set_attr "length" "4")
392 (set_attr "adjust_len" "reload_in16")
393 (set_attr "cc" "none")])
395 (define_insn "*movhi"
396 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,d,*r,q,r")
397 (match_operand:HI 1 "general_operand" "r,L,m,rL,i,i,r,q"))]
398 "(register_operand (operands[0],HImode)
399 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
400 "* return output_movhi (insn, operands, NULL);"
401 [(set_attr "length" "2,2,6,7,2,6,5,2")
402 (set_attr "adjust_len" "mov16")
403 (set_attr "cc" "none,clobber,clobber,clobber,none,clobber,none,none")])
405 (define_peephole2 ; movw
406 [(set (match_operand:QI 0 "even_register_operand" "")
407 (match_operand:QI 1 "even_register_operand" ""))
408 (set (match_operand:QI 2 "odd_register_operand" "")
409 (match_operand:QI 3 "odd_register_operand" ""))]
411 && REGNO (operands[0]) == REGNO (operands[2]) - 1
412 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
413 [(set (match_dup 4) (match_dup 5))]
415 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
416 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
419 (define_peephole2 ; movw_r
420 [(set (match_operand:QI 0 "odd_register_operand" "")
421 (match_operand:QI 1 "odd_register_operand" ""))
422 (set (match_operand:QI 2 "even_register_operand" "")
423 (match_operand:QI 3 "even_register_operand" ""))]
425 && REGNO (operands[2]) == REGNO (operands[0]) - 1
426 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
427 [(set (match_dup 4) (match_dup 5))]
429 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
430 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
433 ;;==========================================================================
434 ;; move double word (32 bit)
436 (define_expand "movsi"
437 [(set (match_operand:SI 0 "nonimmediate_operand" "")
438 (match_operand:SI 1 "general_operand" ""))]
442 /* One of the ops has to be in a register. */
443 if (!register_operand (operand0, SImode)
444 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
446 operands[1] = copy_to_mode_reg (SImode, operand1);
452 (define_peephole2 ; *reload_insi
453 [(match_scratch:QI 2 "d")
454 (set (match_operand:SI 0 "l_register_operand" "")
455 (match_operand:SI 1 "const_int_operand" ""))
457 "(operands[1] != const0_rtx
458 && operands[1] != constm1_rtx)"
459 [(parallel [(set (match_dup 0) (match_dup 1))
460 (clobber (match_dup 2))])]
463 ;; '*' because it is not used in rtl generation.
464 (define_insn "*reload_insi"
465 [(set (match_operand:SI 0 "register_operand" "=r")
466 (match_operand:SI 1 "const_int_operand" "n"))
467 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
470 return output_reload_insisf (operands, operands[2], NULL);
472 [(set_attr "length" "8")
473 (set_attr "adjust_len" "reload_in32")
474 (set_attr "cc" "clobber")])
477 (define_insn "*movsi"
478 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
479 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
480 "(register_operand (operands[0],SImode)
481 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
483 return output_movsisf (insn, operands, NULL);
485 [(set_attr "length" "4,4,8,9,4,10")
486 (set_attr "adjust_len" "mov32")
487 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
489 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
490 ;; move floating point numbers (32 bit)
492 (define_expand "movsf"
493 [(set (match_operand:SF 0 "nonimmediate_operand" "")
494 (match_operand:SF 1 "general_operand" ""))]
498 /* One of the ops has to be in a register. */
499 if (!register_operand (operand1, SFmode)
500 && !register_operand (operand0, SFmode))
502 operands[1] = copy_to_mode_reg (SFmode, operand1);
506 (define_insn "*movsf"
507 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
508 (match_operand:SF 1 "general_operand" "r,G,Qm,rG,F,F"))]
509 "register_operand (operands[0], SFmode)
510 || register_operand (operands[1], SFmode)
511 || operands[1] == CONST0_RTX (SFmode)"
513 return output_movsisf (insn, operands, NULL);
515 [(set_attr "length" "4,4,8,9,4,10")
516 (set_attr "adjust_len" "mov32")
517 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
519 (define_peephole2 ; *reload_insf
520 [(match_scratch:QI 2 "d")
521 (set (match_operand:SF 0 "l_register_operand" "")
522 (match_operand:SF 1 "const_double_operand" ""))
524 "operands[1] != CONST0_RTX (SFmode)"
525 [(parallel [(set (match_dup 0)
527 (clobber (match_dup 2))])]
530 ;; '*' because it is not used in rtl generation.
531 (define_insn "*reload_insf"
532 [(set (match_operand:SF 0 "register_operand" "=r")
533 (match_operand:SF 1 "const_double_operand" "F"))
534 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
537 return output_reload_insisf (operands, operands[2], NULL);
539 [(set_attr "length" "8")
540 (set_attr "adjust_len" "reload_in32")
541 (set_attr "cc" "clobber")])
543 ;;=========================================================================
544 ;; move string (like memcpy)
545 ;; implement as RTL loop
547 (define_expand "movmemhi"
548 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
549 (match_operand:BLK 1 "memory_operand" ""))
550 (use (match_operand:HI 2 "const_int_operand" ""))
551 (use (match_operand:HI 3 "const_int_operand" ""))])]
556 enum machine_mode mode;
557 rtx label = gen_label_rtx ();
561 /* Copy pointers into new psuedos - they will be changed. */
562 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
563 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
565 /* Create rtx for tmp register - we use this as scratch. */
566 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
568 if (GET_CODE (operands[2]) != CONST_INT)
571 count = INTVAL (operands[2]);
575 /* Work out branch probability for latter use. */
576 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
578 /* See if constant fit 8 bits. */
579 mode = (count < 0x100) ? QImode : HImode;
580 /* Create loop counter register. */
581 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
583 /* Now create RTL code for move loop. */
584 /* Label at top of loop. */
587 /* Move one byte into scratch and inc pointer. */
588 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
589 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
591 /* Move to mem and inc pointer. */
592 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
593 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
595 /* Decrement count. */
596 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
598 /* Compare with zero and jump if not equal. */
599 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
601 /* Set jump probability based on loop count. */
602 jump = get_last_insn ();
603 add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
607 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
608 ;; memset (%0, %2, %1)
610 (define_expand "setmemhi"
611 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
612 (match_operand 2 "const_int_operand" ""))
613 (use (match_operand:HI 1 "const_int_operand" ""))
614 (use (match_operand:HI 3 "const_int_operand" "n"))
615 (clobber (match_scratch:HI 4 ""))
616 (clobber (match_dup 5))])]
620 enum machine_mode mode;
622 /* If value to set is not zero, use the library routine. */
623 if (operands[2] != const0_rtx)
626 if (!CONST_INT_P (operands[1]))
629 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
630 operands[5] = gen_rtx_SCRATCH (mode);
631 operands[1] = copy_to_mode_reg (mode,
632 gen_int_mode (INTVAL (operands[1]), mode));
633 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
634 operands[0] = gen_rtx_MEM (BLKmode, addr0);
637 (define_insn "*clrmemqi"
638 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
640 (use (match_operand:QI 1 "register_operand" "r"))
641 (use (match_operand:QI 2 "const_int_operand" "n"))
642 (clobber (match_scratch:HI 3 "=0"))
643 (clobber (match_scratch:QI 4 "=&1"))]
645 "st %a0+,__zero_reg__
648 [(set_attr "length" "3")
649 (set_attr "cc" "clobber")])
651 (define_insn "*clrmemhi"
652 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
654 (use (match_operand:HI 1 "register_operand" "!w,d"))
655 (use (match_operand:HI 2 "const_int_operand" "n,n"))
656 (clobber (match_scratch:HI 3 "=0,0"))
657 (clobber (match_scratch:HI 4 "=&1,&1"))]
660 if (which_alternative==0)
661 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
662 AS2 (sbiw,%A1,1) CR_TAB
665 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
666 AS2 (subi,%A1,1) CR_TAB
667 AS2 (sbci,%B1,0) CR_TAB
670 [(set_attr "length" "3,4")
671 (set_attr "cc" "clobber,clobber")])
673 (define_expand "strlenhi"
675 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
676 (match_operand:QI 2 "const_int_operand" "")
677 (match_operand:HI 3 "immediate_operand" "")]
679 (set (match_dup 4) (plus:HI (match_dup 4)
681 (set (match_operand:HI 0 "register_operand" "")
682 (minus:HI (match_dup 4)
687 if (operands[2] != const0_rtx)
689 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
690 operands[1] = gen_rtx_MEM (BLKmode, addr);
692 operands[4] = gen_reg_rtx (HImode);
695 (define_insn "*strlenhi"
696 [(set (match_operand:HI 0 "register_operand" "=e")
697 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
699 (match_operand:HI 2 "immediate_operand" "i")]
705 [(set_attr "length" "3")
706 (set_attr "cc" "clobber")])
708 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
711 (define_insn "addqi3"
712 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
713 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
714 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
721 [(set_attr "length" "1,1,1,1")
722 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
725 (define_expand "addhi3"
726 [(set (match_operand:HI 0 "register_operand" "")
727 (plus:HI (match_operand:HI 1 "register_operand" "")
728 (match_operand:HI 2 "nonmemory_operand" "")))]
732 if (GET_CODE (operands[2]) == CONST_INT)
734 short tmp = INTVAL (operands[2]);
735 operands[2] = GEN_INT(tmp);
740 (define_insn "*addhi3_zero_extend"
741 [(set (match_operand:HI 0 "register_operand" "=r")
742 (plus:HI (zero_extend:HI
743 (match_operand:QI 1 "register_operand" "r"))
744 (match_operand:HI 2 "register_operand" "0")))]
747 adc %B0,__zero_reg__"
748 [(set_attr "length" "2")
749 (set_attr "cc" "set_n")])
751 (define_insn "*addhi3_zero_extend1"
752 [(set (match_operand:HI 0 "register_operand" "=r")
753 (plus:HI (match_operand:HI 1 "register_operand" "%0")
755 (match_operand:QI 2 "register_operand" "r"))))]
758 adc %B0,__zero_reg__"
759 [(set_attr "length" "2")
760 (set_attr "cc" "set_n")])
762 (define_insn "*addhi3_sp_R"
763 [(set (match_operand:HI 1 "stack_register_operand" "=q")
764 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
765 (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
768 return avr_out_addto_sp (operands, NULL);
770 [(set_attr "length" "5")
771 (set_attr "adjust_len" "addto_sp")])
773 (define_insn "*addhi3"
774 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
776 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
777 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
780 add %A0,%A2\;adc %B0,%B2
783 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
784 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
785 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
786 [(set_attr "length" "2,1,1,2,3,3")
787 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
789 (define_insn "addsi3"
790 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
791 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
792 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
793 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
796 static const char * const asm_code[] =
798 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
799 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
804 if (*asm_code[which_alternative])
805 return asm_code [which_alternative];
807 return avr_out_plus (operands, NULL, NULL);
809 [(set_attr "length" "4,4,4,8")
810 (set_attr "adjust_len" "*,*,out_plus,out_plus")
811 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
813 (define_insn "*addsi3_zero_extend"
814 [(set (match_operand:SI 0 "register_operand" "=r")
815 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
816 (match_operand:SI 2 "register_operand" "0")))]
818 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
819 [(set_attr "length" "4")
820 (set_attr "cc" "set_n")])
822 (define_insn "*addsi3_zero_extend.hi"
823 [(set (match_operand:SI 0 "register_operand" "=r")
824 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
825 (match_operand:SI 2 "register_operand" "0")))]
827 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
828 [(set_attr "length" "4")
829 (set_attr "cc" "set_n")])
831 ;-----------------------------------------------------------------------------
833 (define_insn "subqi3"
834 [(set (match_operand:QI 0 "register_operand" "=r,d")
835 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
836 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
841 [(set_attr "length" "1,1")
842 (set_attr "cc" "set_czn,set_czn")])
844 (define_insn "subhi3"
845 [(set (match_operand:HI 0 "register_operand" "=r,d")
846 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
847 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
850 sub %A0,%A2\;sbc %B0,%B2
851 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
852 [(set_attr "length" "2,2")
853 (set_attr "cc" "set_czn,set_czn")])
855 (define_insn "*subhi3_zero_extend1"
856 [(set (match_operand:HI 0 "register_operand" "=r")
857 (minus:HI (match_operand:HI 1 "register_operand" "0")
858 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
860 "sub %A0,%2\;sbc %B0,__zero_reg__"
861 [(set_attr "length" "2")
862 (set_attr "cc" "set_czn")])
864 (define_insn "subsi3"
865 [(set (match_operand:SI 0 "register_operand" "=r")
866 (minus:SI (match_operand:SI 1 "register_operand" "0")
867 (match_operand:SI 2 "register_operand" "r")))]
869 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
870 [(set_attr "length" "4")
871 (set_attr "cc" "set_czn")])
873 (define_insn "*subsi3_zero_extend"
874 [(set (match_operand:SI 0 "register_operand" "=r")
875 (minus:SI (match_operand:SI 1 "register_operand" "0")
876 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
878 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
879 [(set_attr "length" "4")
880 (set_attr "cc" "set_czn")])
882 (define_insn "*subsi3_zero_extend.hi"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (minus:SI (match_operand:SI 1 "register_operand" "0")
885 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
887 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
888 [(set_attr "length" "4")
889 (set_attr "cc" "set_czn")])
891 ;******************************************************************************
894 (define_expand "mulqi3"
895 [(set (match_operand:QI 0 "register_operand" "")
896 (mult:QI (match_operand:QI 1 "register_operand" "")
897 (match_operand:QI 2 "register_operand" "")))]
902 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
907 (define_insn "*mulqi3_enh"
908 [(set (match_operand:QI 0 "register_operand" "=r")
909 (mult:QI (match_operand:QI 1 "register_operand" "r")
910 (match_operand:QI 2 "register_operand" "r")))]
915 [(set_attr "length" "3")
916 (set_attr "cc" "clobber")])
918 (define_expand "mulqi3_call"
919 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
920 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
921 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
922 (clobber (reg:QI 22))])
923 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
927 (define_insn "*mulqi3_call"
928 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
929 (clobber (reg:QI 22))]
932 [(set_attr "type" "xcall")
933 (set_attr "cc" "clobber")])
935 ;; "umulqi3_highpart"
936 ;; "smulqi3_highpart"
937 (define_insn "<extend_su>mulqi3_highpart"
938 [(set (match_operand:QI 0 "register_operand" "=r")
940 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
941 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
947 [(set_attr "length" "3")
948 (set_attr "cc" "clobber")])
951 ;; Used when expanding div or mod inline for some special values
952 (define_insn "*subqi3.ashiftrt7"
953 [(set (match_operand:QI 0 "register_operand" "=r")
954 (minus:QI (match_operand:QI 1 "register_operand" "0")
955 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
959 [(set_attr "length" "2")
960 (set_attr "cc" "clobber")])
964 (define_insn "<extend_u>mulqihi3"
965 [(set (match_operand:HI 0 "register_operand" "=r")
966 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
967 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
972 [(set_attr "length" "3")
973 (set_attr "cc" "clobber")])
975 (define_insn "usmulqihi3"
976 [(set (match_operand:HI 0 "register_operand" "=r")
977 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
978 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
983 [(set_attr "length" "3")
984 (set_attr "cc" "clobber")])
986 ;; Above insn is not canonicalized by insn combine, so here is a version with
989 (define_insn "*sumulqihi3"
990 [(set (match_operand:HI 0 "register_operand" "=r")
991 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
992 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
997 [(set_attr "length" "3")
998 (set_attr "cc" "clobber")])
1000 ;; One-extend operand 1
1002 (define_insn "*osmulqihi3"
1003 [(set (match_operand:HI 0 "register_operand" "=&r")
1004 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1005 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1011 [(set_attr "length" "4")
1012 (set_attr "cc" "clobber")])
1014 (define_insn "*oumulqihi3"
1015 [(set (match_operand:HI 0 "register_operand" "=&r")
1016 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1017 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1023 [(set_attr "length" "4")
1024 (set_attr "cc" "clobber")])
1026 ;******************************************************************************
1027 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1028 ;******************************************************************************
1030 (define_insn "*maddqi4"
1031 [(set (match_operand:QI 0 "register_operand" "=r")
1032 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1033 (match_operand:QI 2 "register_operand" "r"))
1034 (match_operand:QI 3 "register_operand" "0")))]
1040 [(set_attr "length" "4")
1041 (set_attr "cc" "clobber")])
1043 (define_insn "*msubqi4"
1044 [(set (match_operand:QI 0 "register_operand" "=r")
1045 (minus:QI (match_operand:QI 3 "register_operand" "0")
1046 (mult:QI (match_operand:QI 1 "register_operand" "r")
1047 (match_operand:QI 2 "register_operand" "r"))))]
1052 [(set_attr "length" "4")
1053 (set_attr "cc" "clobber")])
1055 (define_insn_and_split "*maddqi4.const"
1056 [(set (match_operand:QI 0 "register_operand" "=r")
1057 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1058 (match_operand:QI 2 "const_int_operand" "n"))
1059 (match_operand:QI 3 "register_operand" "0")))
1060 (clobber (match_scratch:QI 4 "=&d"))]
1063 "&& reload_completed"
1068 (plus:QI (mult:QI (match_dup 1)
1073 (define_insn_and_split "*msubqi4.const"
1074 [(set (match_operand:QI 0 "register_operand" "=r")
1075 (minus:QI (match_operand:QI 3 "register_operand" "0")
1076 (mult:QI (match_operand:QI 1 "register_operand" "r")
1077 (match_operand:QI 2 "const_int_operand" "n"))))
1078 (clobber (match_scratch:QI 4 "=&d"))]
1081 "&& reload_completed"
1086 (minus:QI (match_dup 3)
1087 (mult:QI (match_dup 1)
1092 ;******************************************************************************
1093 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1094 ;******************************************************************************
1096 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1099 ;; int foo (unsigned char z)
1101 ;; extern int aInt[];
1102 ;; return aInt[3*z+2];
1105 ;; because the constant +4 then is added explicitely instead of consuming it
1106 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1107 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1108 ;; The implementational effort is the same so we are fine with that approach.
1113 (define_insn "*<extend_u>maddqihi4"
1114 [(set (match_operand:HI 0 "register_operand" "=r")
1115 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1116 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1117 (match_operand:HI 3 "register_operand" "0")))]
1120 "mul<extend_s> %1,%2
1124 [(set_attr "length" "4")
1125 (set_attr "cc" "clobber")])
1129 (define_insn "*<extend_u>msubqihi4"
1130 [(set (match_operand:HI 0 "register_operand" "=r")
1131 (minus:HI (match_operand:HI 3 "register_operand" "0")
1132 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1133 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1135 "mul<extend_s> %1,%2
1139 [(set_attr "length" "4")
1140 (set_attr "cc" "clobber")])
1144 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1145 [(set (match_operand:HI 0 "register_operand" "=r")
1146 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1147 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1148 (match_operand:HI 3 "register_operand" "0")))]
1151 && <any_extend:CODE> != <any_extend2:CODE>"
1153 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1154 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1156 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1158 [(set_attr "length" "4")
1159 (set_attr "cc" "clobber")])
1163 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1164 [(set (match_operand:HI 0 "register_operand" "=r")
1165 (minus:HI (match_operand:HI 3 "register_operand" "0")
1166 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1167 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1170 && <any_extend:CODE> != <any_extend2:CODE>"
1172 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1173 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1175 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1177 [(set_attr "length" "4")
1178 (set_attr "cc" "clobber")])
1180 ;; Handle small constants
1182 ;; "umaddqihi4.uconst"
1183 ;; "maddqihi4.sconst"
1184 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1185 [(set (match_operand:HI 0 "register_operand" "=r")
1186 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1187 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1188 (match_operand:HI 3 "register_operand" "0")))
1189 (clobber (match_scratch:QI 4 "=&d"))]
1192 "&& reload_completed"
1195 ; *umaddqihi4 resp. *maddqihi4
1197 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1198 (any_extend:HI (match_dup 4)))
1201 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1204 ;; "*umsubqihi4.uconst"
1205 ;; "*msubqihi4.sconst"
1206 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1207 [(set (match_operand:HI 0 "register_operand" "=r")
1208 (minus:HI (match_operand:HI 3 "register_operand" "0")
1209 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1210 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1211 (clobber (match_scratch:QI 4 "=&d"))]
1214 "&& reload_completed"
1217 ; *umsubqihi4 resp. *msubqihi4
1219 (minus:HI (match_dup 3)
1220 (mult:HI (any_extend:HI (match_dup 1))
1221 (any_extend:HI (match_dup 4)))))]
1223 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1226 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1227 ;; for MULT with power of 2 and skips trying MULT insn above.
1229 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1230 [(set (match_operand:HI 0 "register_operand" "=r")
1231 (minus:HI (match_operand:HI 3 "register_operand" "0")
1232 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1233 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1234 (clobber (match_scratch:QI 4 "=&d"))]
1237 "&& reload_completed"
1242 (minus:HI (match_dup 3)
1243 (mult:HI (zero_extend:HI (match_dup 1))
1244 (zero_extend:HI (match_dup 4)))))]
1246 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1249 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1250 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1251 ;; because this would require an extra pattern for just one value.
1253 (define_insn_and_split "*msubqihi4.sconst.ashift"
1254 [(set (match_operand:HI 0 "register_operand" "=r")
1255 (minus:HI (match_operand:HI 3 "register_operand" "0")
1256 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1257 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1258 (clobber (match_scratch:QI 4 "=&d"))]
1261 "&& reload_completed"
1266 (minus:HI (match_dup 3)
1267 (mult:HI (sign_extend:HI (match_dup 1))
1268 (sign_extend:HI (match_dup 4)))))]
1270 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1273 ;; For signed/unsigned combinations that require narrow constraint "a"
1274 ;; just provide a pattern if signed/unsigned combination is actually needed.
1276 (define_insn_and_split "*sumaddqihi4.uconst"
1277 [(set (match_operand:HI 0 "register_operand" "=r")
1278 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1279 (match_operand:HI 2 "u8_operand" "M"))
1280 (match_operand:HI 3 "register_operand" "0")))
1281 (clobber (match_scratch:QI 4 "=&a"))]
1283 && !s8_operand (operands[2], VOIDmode)"
1285 "&& reload_completed"
1290 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1291 (zero_extend:HI (match_dup 4)))
1294 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1297 (define_insn_and_split "*sumsubqihi4.uconst"
1298 [(set (match_operand:HI 0 "register_operand" "=r")
1299 (minus:HI (match_operand:HI 3 "register_operand" "0")
1300 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1301 (match_operand:HI 2 "u8_operand" "M"))))
1302 (clobber (match_scratch:QI 4 "=&a"))]
1304 && !s8_operand (operands[2], VOIDmode)"
1306 "&& reload_completed"
1311 (minus:HI (match_dup 3)
1312 (mult:HI (sign_extend:HI (match_dup 1))
1313 (zero_extend:HI (match_dup 4)))))]
1315 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1318 ;******************************************************************************
1319 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1320 ;******************************************************************************
1322 ;; "*muluqihi3.uconst"
1323 ;; "*mulsqihi3.sconst"
1324 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1325 [(set (match_operand:HI 0 "register_operand" "=r")
1326 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1327 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1328 (clobber (match_scratch:QI 3 "=&d"))]
1331 "&& reload_completed"
1334 ; umulqihi3 resp. mulqihi3
1336 (mult:HI (any_extend:HI (match_dup 1))
1337 (any_extend:HI (match_dup 3))))]
1339 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1342 (define_insn_and_split "*muluqihi3.sconst"
1343 [(set (match_operand:HI 0 "register_operand" "=r")
1344 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1345 (match_operand:HI 2 "s8_operand" "n")))
1346 (clobber (match_scratch:QI 3 "=&a"))]
1349 "&& reload_completed"
1354 (mult:HI (zero_extend:HI (match_dup 1))
1355 (sign_extend:HI (match_dup 3))))]
1357 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1360 (define_insn_and_split "*mulsqihi3.uconst"
1361 [(set (match_operand:HI 0 "register_operand" "=r")
1362 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1363 (match_operand:HI 2 "u8_operand" "M")))
1364 (clobber (match_scratch:QI 3 "=&a"))]
1367 "&& reload_completed"
1372 (mult:HI (zero_extend:HI (match_dup 3))
1373 (sign_extend:HI (match_dup 1))))]
1375 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1378 (define_insn_and_split "*mulsqihi3.oconst"
1379 [(set (match_operand:HI 0 "register_operand" "=&r")
1380 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1381 (match_operand:HI 2 "o8_operand" "n")))
1382 (clobber (match_scratch:QI 3 "=&a"))]
1385 "&& reload_completed"
1390 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1391 (sign_extend:HI (match_dup 1))))]
1393 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1396 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1397 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1398 ;; at that time. Fix that.
1400 (define_insn "*ashiftqihi2.signx.1"
1401 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1402 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1406 lsl %A0\;sbc %B0,%B0
1407 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1408 [(set_attr "length" "2,3")
1409 (set_attr "cc" "clobber")])
1411 (define_insn_and_split "*ashifthi3.signx.const"
1412 [(set (match_operand:HI 0 "register_operand" "=r")
1413 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1414 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1415 (clobber (match_scratch:QI 3 "=&d"))]
1418 "&& reload_completed"
1423 (mult:HI (sign_extend:HI (match_dup 1))
1424 (sign_extend:HI (match_dup 3))))]
1426 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1429 (define_insn_and_split "*ashifthi3.signx.const7"
1430 [(set (match_operand:HI 0 "register_operand" "=r")
1431 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1433 (clobber (match_scratch:QI 2 "=&a"))]
1436 "&& reload_completed"
1441 (mult:HI (zero_extend:HI (match_dup 2))
1442 (sign_extend:HI (match_dup 1))))]
1444 operands[3] = gen_int_mode (1 << 7, QImode);
1447 (define_insn_and_split "*ashifthi3.zerox.const"
1448 [(set (match_operand:HI 0 "register_operand" "=r")
1449 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1450 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1451 (clobber (match_scratch:QI 3 "=&d"))]
1454 "&& reload_completed"
1459 (mult:HI (zero_extend:HI (match_dup 1))
1460 (zero_extend:HI (match_dup 3))))]
1462 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1465 ;******************************************************************************
1466 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1467 ;******************************************************************************
1469 (define_insn "mulsqihi3"
1470 [(set (match_operand:HI 0 "register_operand" "=&r")
1471 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1472 (match_operand:HI 2 "register_operand" "a")))]
1479 [(set_attr "length" "5")
1480 (set_attr "cc" "clobber")])
1482 (define_insn "muluqihi3"
1483 [(set (match_operand:HI 0 "register_operand" "=&r")
1484 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1485 (match_operand:HI 2 "register_operand" "r")))]
1492 [(set_attr "length" "5")
1493 (set_attr "cc" "clobber")])
1495 ;; one-extend operand 1
1497 (define_insn "muloqihi3"
1498 [(set (match_operand:HI 0 "register_operand" "=&r")
1499 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1500 (match_operand:HI 2 "register_operand" "r")))]
1508 [(set_attr "length" "6")
1509 (set_attr "cc" "clobber")])
1511 ;******************************************************************************
1513 (define_expand "mulhi3"
1514 [(set (match_operand:HI 0 "register_operand" "")
1515 (mult:HI (match_operand:HI 1 "register_operand" "")
1516 (match_operand:HI 2 "register_or_s9_operand" "")))]
1521 if (!register_operand (operands[2], HImode))
1522 operands[2] = force_reg (HImode, operands[2]);
1524 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1528 /* For small constants we can do better by extending them on the fly.
1529 The constant can be loaded in one instruction and the widening
1530 multiplication is shorter. First try the unsigned variant because it
1531 allows constraint "d" instead of "a" for the signed version. */
1533 if (s9_operand (operands[2], HImode))
1535 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1537 if (u8_operand (operands[2], HImode))
1539 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1541 else if (s8_operand (operands[2], HImode))
1543 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1547 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1553 if (!register_operand (operands[2], HImode))
1554 operands[2] = force_reg (HImode, operands[2]);
1557 (define_insn "*mulhi3_enh"
1558 [(set (match_operand:HI 0 "register_operand" "=&r")
1559 (mult:HI (match_operand:HI 1 "register_operand" "r")
1560 (match_operand:HI 2 "register_operand" "r")))]
1563 return REGNO (operands[1]) == REGNO (operands[2])
1564 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
1565 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
1567 [(set_attr "length" "7")
1568 (set_attr "cc" "clobber")])
1570 (define_expand "mulhi3_call"
1571 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1572 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1573 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1574 (clobber (reg:HI 22))
1575 (clobber (reg:QI 21))])
1576 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1580 (define_insn "*mulhi3_call"
1581 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1582 (clobber (reg:HI 22))
1583 (clobber (reg:QI 21))]
1586 [(set_attr "type" "xcall")
1587 (set_attr "cc" "clobber")])
1589 ;; To support widening multiplicatioon with constant we postpone
1590 ;; expanding to the implicit library call until post combine and
1591 ;; prior to register allocation. Clobber all hard registers that
1592 ;; might be used by the (widening) multiply until it is split and
1593 ;; it's final register footprint is worked out.
1595 (define_expand "mulsi3"
1596 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1597 (mult:SI (match_operand:SI 1 "register_operand" "")
1598 (match_operand:SI 2 "nonmemory_operand" "")))
1599 (clobber (reg:HI 26))
1600 (clobber (reg:DI 18))])]
1603 if (u16_operand (operands[2], SImode))
1605 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1606 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1610 if (o16_operand (operands[2], SImode))
1612 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1613 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1618 (define_insn_and_split "*mulsi3"
1619 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1620 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
1621 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1622 (clobber (reg:HI 26))
1623 (clobber (reg:DI 18))]
1624 "AVR_HAVE_MUL && !reload_completed"
1625 { gcc_unreachable(); }
1631 (parallel [(set (reg:SI 22)
1632 (mult:SI (reg:SI 22)
1634 (clobber (reg:HI 26))])
1638 if (u16_operand (operands[2], SImode))
1640 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1641 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1645 if (o16_operand (operands[2], SImode))
1647 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1648 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1655 (define_insn_and_split "mulu<mode>si3"
1656 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1657 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1658 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1659 (clobber (reg:HI 26))
1660 (clobber (reg:DI 18))]
1661 "AVR_HAVE_MUL && !reload_completed"
1662 { gcc_unreachable(); }
1669 (mult:SI (zero_extend:SI (reg:HI 26))
1674 /* Do the QI -> HI extension explicitely before the multiplication. */
1675 /* Do the HI -> SI extension implicitely and after the multiplication. */
1677 if (QImode == <MODE>mode)
1678 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
1680 if (u16_operand (operands[2], SImode))
1682 operands[1] = force_reg (HImode, operands[1]);
1683 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1684 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
1691 (define_insn_and_split "muls<mode>si3"
1692 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1693 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1694 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1695 (clobber (reg:HI 26))
1696 (clobber (reg:DI 18))]
1697 "AVR_HAVE_MUL && !reload_completed"
1698 { gcc_unreachable(); }
1705 (mult:SI (sign_extend:SI (reg:HI 26))
1710 /* Do the QI -> HI extension explicitely before the multiplication. */
1711 /* Do the HI -> SI extension implicitely and after the multiplication. */
1713 if (QImode == <MODE>mode)
1714 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
1716 if (u16_operand (operands[2], SImode)
1717 || s16_operand (operands[2], SImode))
1719 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1721 operands[1] = force_reg (HImode, operands[1]);
1723 if (u16_operand (operands[2], SImode))
1724 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
1726 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
1732 ;; One-extend operand 1
1734 (define_insn_and_split "mulohisi3"
1735 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1736 (mult:SI (not:SI (zero_extend:SI
1737 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
1738 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1739 (clobber (reg:HI 26))
1740 (clobber (reg:DI 18))]
1741 "AVR_HAVE_MUL && !reload_completed"
1742 { gcc_unreachable(); }
1749 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1757 (define_expand "<extend_u>mulhisi3"
1758 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1759 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
1760 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
1761 (clobber (reg:HI 26))
1762 (clobber (reg:DI 18))])]
1766 (define_expand "usmulhisi3"
1767 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1768 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1769 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1770 (clobber (reg:HI 26))
1771 (clobber (reg:DI 18))])]
1775 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
1776 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
1777 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
1778 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
1779 (define_insn_and_split
1780 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
1781 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1782 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1783 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
1784 (clobber (reg:HI 26))
1785 (clobber (reg:DI 18))]
1786 "AVR_HAVE_MUL && !reload_completed"
1787 { gcc_unreachable(); }
1794 (mult:SI (match_dup 3)
1799 rtx xop1 = operands[1];
1800 rtx xop2 = operands[2];
1802 /* Do the QI -> HI extension explicitely before the multiplication. */
1803 /* Do the HI -> SI extension implicitely and after the multiplication. */
1805 if (QImode == <QIHI:MODE>mode)
1806 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
1808 if (QImode == <QIHI2:MODE>mode)
1809 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
1811 if (<any_extend:CODE> == <any_extend2:CODE>
1812 || <any_extend:CODE> == ZERO_EXTEND)
1816 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
1817 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
1821 /* <any_extend:CODE> = SIGN_EXTEND */
1822 /* <any_extend2:CODE> = ZERO_EXTEND */
1826 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
1827 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
1831 ;; "smulhi3_highpart"
1832 ;; "umulhi3_highpart"
1833 (define_expand "<extend_su>mulhi3_highpart"
1835 (match_operand:HI 1 "nonmemory_operand" ""))
1837 (match_operand:HI 2 "nonmemory_operand" ""))
1838 (parallel [(set (reg:HI 24)
1839 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1840 (any_extend:SI (reg:HI 26)))
1842 (clobber (reg:HI 22))])
1843 (set (match_operand:HI 0 "register_operand" "")
1849 (define_insn "*mulsi3_call"
1851 (mult:SI (reg:SI 22)
1853 (clobber (reg:HI 26))]
1856 [(set_attr "type" "xcall")
1857 (set_attr "cc" "clobber")])
1860 ;; "*umulhisi3_call"
1861 (define_insn "*<extend_u>mulhisi3_call"
1863 (mult:SI (any_extend:SI (reg:HI 18))
1864 (any_extend:SI (reg:HI 26))))]
1866 "%~call __<extend_u>mulhisi3"
1867 [(set_attr "type" "xcall")
1868 (set_attr "cc" "clobber")])
1870 ;; "*umulhi3_highpart_call"
1871 ;; "*smulhi3_highpart_call"
1872 (define_insn "*<extend_su>mulhi3_highpart_call"
1874 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
1875 (any_extend:SI (reg:HI 26)))
1877 (clobber (reg:HI 22))]
1879 "%~call __<extend_u>mulhisi3"
1880 [(set_attr "type" "xcall")
1881 (set_attr "cc" "clobber")])
1883 (define_insn "*usmulhisi3_call"
1885 (mult:SI (zero_extend:SI (reg:HI 18))
1886 (sign_extend:SI (reg:HI 26))))]
1888 "%~call __usmulhisi3"
1889 [(set_attr "type" "xcall")
1890 (set_attr "cc" "clobber")])
1892 (define_insn "*mul<extend_su>hisi3_call"
1894 (mult:SI (any_extend:SI (reg:HI 26))
1897 "%~call __mul<extend_su>hisi3"
1898 [(set_attr "type" "xcall")
1899 (set_attr "cc" "clobber")])
1901 (define_insn "*mulohisi3_call"
1903 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1906 "%~call __mulohisi3"
1907 [(set_attr "type" "xcall")
1908 (set_attr "cc" "clobber")])
1910 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1913 ;; Generate libgcc.S calls ourselves, because:
1914 ;; - we know exactly which registers are clobbered (for QI and HI
1915 ;; modes, some of the call-used registers are preserved)
1916 ;; - we get both the quotient and the remainder at no extra cost
1917 ;; - we split the patterns only after the first CSE passes because
1918 ;; CSE has problems to operate on hard regs.
1920 (define_insn_and_split "divmodqi4"
1921 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1922 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
1923 (match_operand:QI 2 "pseudo_register_operand" "")))
1924 (set (match_operand:QI 3 "pseudo_register_operand" "")
1925 (mod:QI (match_dup 1) (match_dup 2)))
1926 (clobber (reg:QI 22))
1927 (clobber (reg:QI 23))
1928 (clobber (reg:QI 24))
1929 (clobber (reg:QI 25))])]
1931 "this divmodqi4 pattern should have been splitted;"
1933 [(set (reg:QI 24) (match_dup 1))
1934 (set (reg:QI 22) (match_dup 2))
1935 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1936 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1937 (clobber (reg:QI 22))
1938 (clobber (reg:QI 23))])
1939 (set (match_dup 0) (reg:QI 24))
1940 (set (match_dup 3) (reg:QI 25))]
1943 (define_insn "*divmodqi4_call"
1944 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1945 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1946 (clobber (reg:QI 22))
1947 (clobber (reg:QI 23))]
1949 "%~call __divmodqi4"
1950 [(set_attr "type" "xcall")
1951 (set_attr "cc" "clobber")])
1953 (define_insn_and_split "udivmodqi4"
1954 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1955 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
1956 (match_operand:QI 2 "pseudo_register_operand" "")))
1957 (set (match_operand:QI 3 "pseudo_register_operand" "")
1958 (umod:QI (match_dup 1) (match_dup 2)))
1959 (clobber (reg:QI 22))
1960 (clobber (reg:QI 23))
1961 (clobber (reg:QI 24))
1962 (clobber (reg:QI 25))])]
1964 "this udivmodqi4 pattern should have been splitted;"
1966 [(set (reg:QI 24) (match_dup 1))
1967 (set (reg:QI 22) (match_dup 2))
1968 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1969 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1970 (clobber (reg:QI 23))])
1971 (set (match_dup 0) (reg:QI 24))
1972 (set (match_dup 3) (reg:QI 25))]
1975 (define_insn "*udivmodqi4_call"
1976 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1977 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1978 (clobber (reg:QI 23))]
1980 "%~call __udivmodqi4"
1981 [(set_attr "type" "xcall")
1982 (set_attr "cc" "clobber")])
1984 (define_insn_and_split "divmodhi4"
1985 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1986 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
1987 (match_operand:HI 2 "pseudo_register_operand" "")))
1988 (set (match_operand:HI 3 "pseudo_register_operand" "")
1989 (mod:HI (match_dup 1) (match_dup 2)))
1990 (clobber (reg:QI 21))
1991 (clobber (reg:HI 22))
1992 (clobber (reg:HI 24))
1993 (clobber (reg:HI 26))])]
1995 "this should have been splitted;"
1997 [(set (reg:HI 24) (match_dup 1))
1998 (set (reg:HI 22) (match_dup 2))
1999 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2000 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2001 (clobber (reg:HI 26))
2002 (clobber (reg:QI 21))])
2003 (set (match_dup 0) (reg:HI 22))
2004 (set (match_dup 3) (reg:HI 24))]
2007 (define_insn "*divmodhi4_call"
2008 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2009 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2010 (clobber (reg:HI 26))
2011 (clobber (reg:QI 21))]
2013 "%~call __divmodhi4"
2014 [(set_attr "type" "xcall")
2015 (set_attr "cc" "clobber")])
2017 (define_insn_and_split "udivmodhi4"
2018 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2019 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2020 (match_operand:HI 2 "pseudo_register_operand" "")))
2021 (set (match_operand:HI 3 "pseudo_register_operand" "")
2022 (umod:HI (match_dup 1) (match_dup 2)))
2023 (clobber (reg:QI 21))
2024 (clobber (reg:HI 22))
2025 (clobber (reg:HI 24))
2026 (clobber (reg:HI 26))])]
2028 "this udivmodhi4 pattern should have been splitted.;"
2030 [(set (reg:HI 24) (match_dup 1))
2031 (set (reg:HI 22) (match_dup 2))
2032 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2033 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2034 (clobber (reg:HI 26))
2035 (clobber (reg:QI 21))])
2036 (set (match_dup 0) (reg:HI 22))
2037 (set (match_dup 3) (reg:HI 24))]
2040 (define_insn "*udivmodhi4_call"
2041 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2042 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2043 (clobber (reg:HI 26))
2044 (clobber (reg:QI 21))]
2046 "%~call __udivmodhi4"
2047 [(set_attr "type" "xcall")
2048 (set_attr "cc" "clobber")])
2050 (define_insn_and_split "divmodsi4"
2051 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2052 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2053 (match_operand:SI 2 "pseudo_register_operand" "")))
2054 (set (match_operand:SI 3 "pseudo_register_operand" "")
2055 (mod:SI (match_dup 1) (match_dup 2)))
2056 (clobber (reg:SI 18))
2057 (clobber (reg:SI 22))
2058 (clobber (reg:HI 26))
2059 (clobber (reg:HI 30))])]
2061 "this divmodsi4 pattern should have been splitted;"
2063 [(set (reg:SI 22) (match_dup 1))
2064 (set (reg:SI 18) (match_dup 2))
2065 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2066 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2067 (clobber (reg:HI 26))
2068 (clobber (reg:HI 30))])
2069 (set (match_dup 0) (reg:SI 18))
2070 (set (match_dup 3) (reg:SI 22))]
2073 (define_insn "*divmodsi4_call"
2074 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2075 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2076 (clobber (reg:HI 26))
2077 (clobber (reg:HI 30))]
2079 "%~call __divmodsi4"
2080 [(set_attr "type" "xcall")
2081 (set_attr "cc" "clobber")])
2083 (define_insn_and_split "udivmodsi4"
2084 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2085 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2086 (match_operand:SI 2 "pseudo_register_operand" "")))
2087 (set (match_operand:SI 3 "pseudo_register_operand" "")
2088 (umod:SI (match_dup 1) (match_dup 2)))
2089 (clobber (reg:SI 18))
2090 (clobber (reg:SI 22))
2091 (clobber (reg:HI 26))
2092 (clobber (reg:HI 30))])]
2094 "this udivmodsi4 pattern should have been splitted;"
2096 [(set (reg:SI 22) (match_dup 1))
2097 (set (reg:SI 18) (match_dup 2))
2098 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2099 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2100 (clobber (reg:HI 26))
2101 (clobber (reg:HI 30))])
2102 (set (match_dup 0) (reg:SI 18))
2103 (set (match_dup 3) (reg:SI 22))]
2106 (define_insn "*udivmodsi4_call"
2107 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2108 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2109 (clobber (reg:HI 26))
2110 (clobber (reg:HI 30))]
2112 "%~call __udivmodsi4"
2113 [(set_attr "type" "xcall")
2114 (set_attr "cc" "clobber")])
2116 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2119 (define_insn "andqi3"
2120 [(set (match_operand:QI 0 "register_operand" "=r,d")
2121 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2122 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2127 [(set_attr "length" "1,1")
2128 (set_attr "cc" "set_zn,set_zn")])
2130 (define_insn "andhi3"
2131 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2132 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2133 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2134 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2137 if (which_alternative == 0)
2138 return "and %A0,%A2\;and %B0,%B2";
2139 else if (which_alternative == 1)
2140 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2142 return avr_out_bitop (insn, operands, NULL);
2144 [(set_attr "length" "2,2,2,4,4")
2145 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2146 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2148 (define_insn "andsi3"
2149 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2150 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2151 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2152 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2155 if (which_alternative == 0)
2156 return "and %0,%2" CR_TAB
2157 "and %B0,%B2" CR_TAB
2158 "and %C0,%C2" CR_TAB
2161 return avr_out_bitop (insn, operands, NULL);
2163 [(set_attr "length" "4,4,8,8")
2164 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2165 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2167 (define_peephole2 ; andi
2168 [(set (match_operand:QI 0 "d_register_operand" "")
2169 (and:QI (match_dup 0)
2170 (match_operand:QI 1 "const_int_operand" "")))
2172 (and:QI (match_dup 0)
2173 (match_operand:QI 2 "const_int_operand" "")))]
2175 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2177 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2180 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2183 (define_insn "iorqi3"
2184 [(set (match_operand:QI 0 "register_operand" "=r,d")
2185 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2186 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2191 [(set_attr "length" "1,1")
2192 (set_attr "cc" "set_zn,set_zn")])
2194 (define_insn "iorhi3"
2195 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2196 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2197 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2198 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2201 if (which_alternative == 0)
2202 return "or %A0,%A2\;or %B0,%B2";
2203 else if (which_alternative == 1)
2204 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
2206 return avr_out_bitop (insn, operands, NULL);
2208 [(set_attr "length" "2,2,2,4,4")
2209 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2210 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2212 (define_insn "iorsi3"
2213 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2214 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2215 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2216 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2219 if (which_alternative == 0)
2220 return "or %0,%2" CR_TAB
2225 return avr_out_bitop (insn, operands, NULL);
2227 [(set_attr "length" "4,4,8,8")
2228 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2229 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2231 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2234 (define_insn "xorqi3"
2235 [(set (match_operand:QI 0 "register_operand" "=r")
2236 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2237 (match_operand:QI 2 "register_operand" "r")))]
2240 [(set_attr "length" "1")
2241 (set_attr "cc" "set_zn")])
2243 (define_insn "xorhi3"
2244 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
2245 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
2246 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
2247 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2250 if (which_alternative == 0)
2251 return "eor %A0,%A2\;eor %B0,%B2";
2253 return avr_out_bitop (insn, operands, NULL);
2255 [(set_attr "length" "2,2,4")
2256 (set_attr "adjust_len" "*,out_bitop,out_bitop")
2257 (set_attr "cc" "set_n,clobber,clobber")])
2259 (define_insn "xorsi3"
2260 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
2261 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
2262 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
2263 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2266 if (which_alternative == 0)
2267 return "eor %0,%2" CR_TAB
2268 "eor %B0,%B2" CR_TAB
2269 "eor %C0,%C2" CR_TAB
2272 return avr_out_bitop (insn, operands, NULL);
2274 [(set_attr "length" "4,8,8")
2275 (set_attr "adjust_len" "*,out_bitop,out_bitop")
2276 (set_attr "cc" "set_n,clobber,clobber")])
2278 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
2281 (define_expand "rotlqi3"
2282 [(set (match_operand:QI 0 "register_operand" "")
2283 (rotate:QI (match_operand:QI 1 "register_operand" "")
2284 (match_operand:QI 2 "const_0_to_7_operand" "")))]
2287 if (!CONST_INT_P (operands[2]))
2290 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
2293 ;; Expander used by __builtin_avr_swap
2294 (define_expand "rotlqi3_4"
2295 [(set (match_operand:QI 0 "register_operand" "")
2296 (rotate:QI (match_operand:QI 1 "register_operand" "")
2299 (define_insn "*rotlqi3"
2300 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
2301 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
2302 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
2305 lsl %0\;adc %0,__zero_reg__
2306 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
2307 swap %0\;bst %0,0\;ror %0\;bld %0,7
2309 swap %0\;lsl %0\;adc %0,__zero_reg__
2310 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
2311 bst %0,0\;ror %0\;bld %0,7
2313 [(set_attr "length" "2,4,4,1,3,5,3,0")
2314 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
2316 ;; Split all rotates of HI,SI and DImode registers where rotation is by
2317 ;; a whole number of bytes. The split creates the appropriate moves and
2318 ;; considers all overlap situations. DImode is split before reload.
2320 ;; HImode does not need scratch. Use attribute for this constraint.
2321 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
2323 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
2324 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
2329 (define_expand "rotl<mode>3"
2330 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
2331 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2332 (match_operand:VOID 2 "const_int_operand" "")))
2333 (clobber (match_dup 3))])]
2338 if (!CONST_INT_P (operands[2]))
2341 offset = INTVAL (operands[2]);
2343 if (0 == offset % 8)
2345 if (AVR_HAVE_MOVW && 0 == offset % 16)
2346 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2348 operands[3] = gen_rtx_SCRATCH (QImode);
2350 else if (<MODE>mode != DImode
2352 || offset == GET_MODE_BITSIZE (<MODE>mode) -1))
2354 /*; Support rotate left/right by 1 */
2356 emit_move_insn (operands[0],
2357 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
2364 (define_insn "*rotlhi2.1"
2365 [(set (match_operand:HI 0 "register_operand" "=r")
2366 (rotate:HI (match_operand:HI 1 "register_operand" "0")
2369 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
2370 [(set_attr "length" "3")
2371 (set_attr "cc" "clobber")])
2373 (define_insn "*rotlhi2.15"
2374 [(set (match_operand:HI 0 "register_operand" "=r")
2375 (rotate:HI (match_operand:HI 1 "register_operand" "0")
2378 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
2379 [(set_attr "length" "3")
2380 (set_attr "cc" "clobber")])
2382 (define_insn "*rotlsi2.1"
2383 [(set (match_operand:SI 0 "register_operand" "=r")
2384 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2387 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
2388 [(set_attr "length" "5")
2389 (set_attr "cc" "clobber")])
2391 (define_insn "*rotlsi2.31"
2392 [(set (match_operand:SI 0 "register_operand" "=r")
2393 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2396 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
2397 [(set_attr "length" "6")
2398 (set_attr "cc" "clobber")])
2400 ;; Overlapping non-HImode registers often (but not always) need a scratch.
2401 ;; The best we can do is use early clobber alternative "#&r" so that
2402 ;; completely non-overlapping operands dont get a scratch but # so register
2403 ;; allocation does not prefer non-overlapping.
2406 ;; Split word aligned rotates using scratch that is mode dependent.
2411 (define_insn_and_split "*rotw<mode>"
2412 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2413 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2414 (match_operand 2 "const_int_operand" "n,n,n")))
2415 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2417 && CONST_INT_P (operands[2])
2418 && 0 == INTVAL (operands[2]) % 16"
2420 "&& (reload_completed || <MODE>mode == DImode)"
2423 avr_rotate_bytes (operands);
2428 ;; Split byte aligned rotates using scratch that is always QI mode.
2433 (define_insn_and_split "*rotb<mode>"
2434 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2435 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2436 (match_operand 2 "const_int_operand" "n,n,n")))
2437 (clobber (match_scratch:QI 3 "=<rotx>"))]
2438 "CONST_INT_P (operands[2])
2439 && (8 == INTVAL (operands[2]) % 16
2441 && 0 == INTVAL (operands[2]) % 16))"
2443 "&& (reload_completed || <MODE>mode == DImode)"
2446 avr_rotate_bytes (operands);
2451 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2452 ;; arithmetic shift left
2454 (define_expand "ashlqi3"
2455 [(set (match_operand:QI 0 "register_operand" "")
2456 (ashift:QI (match_operand:QI 1 "register_operand" "")
2457 (match_operand:QI 2 "general_operand" "")))]
2461 (define_split ; ashlqi3_const4
2462 [(set (match_operand:QI 0 "d_register_operand" "")
2463 (ashift:QI (match_dup 0)
2466 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2467 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2470 (define_split ; ashlqi3_const5
2471 [(set (match_operand:QI 0 "d_register_operand" "")
2472 (ashift:QI (match_dup 0)
2475 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2476 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2477 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2480 (define_split ; ashlqi3_const6
2481 [(set (match_operand:QI 0 "d_register_operand" "")
2482 (ashift:QI (match_dup 0)
2485 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2486 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2487 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2490 (define_insn "*ashlqi3"
2491 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2492 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2493 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2495 "* return ashlqi3_out (insn, operands, NULL);"
2496 [(set_attr "length" "5,0,1,2,4,6,9")
2497 (set_attr "adjust_len" "ashlqi")
2498 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2500 (define_insn "ashlhi3"
2501 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2502 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2503 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2505 "* return ashlhi3_out (insn, operands, NULL);"
2506 [(set_attr "length" "6,0,2,2,4,10,10")
2507 (set_attr "adjust_len" "ashlhi")
2508 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2511 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
2512 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
2516 (define_insn_and_split "*ashl<extend_su>qihiqi3"
2517 [(set (match_operand:QI 0 "register_operand" "=r")
2518 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
2519 (match_operand:QI 2 "register_operand" "r"))
2525 (ashift:QI (match_dup 1)
2529 ;; ??? Combiner does not recognize that it could split the following insn;
2530 ;; presumably because he has no register handy?
2532 ;; "*ashluqihiqi3.mem"
2533 ;; "*ashlsqihiqi3.mem"
2534 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
2535 [(set (match_operand:QI 0 "memory_operand" "=m")
2536 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
2537 (match_operand:QI 2 "register_operand" "r"))
2540 { gcc_unreachable(); }
2543 (ashift:QI (match_dup 1)
2548 operands[3] = gen_reg_rtx (QImode);
2553 (define_insn_and_split "*ashlhiqi3"
2554 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
2555 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
2556 (match_operand:QI 2 "register_operand" "r")) 0))]
2558 { gcc_unreachable(); }
2561 (ashift:QI (match_dup 3)
2566 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
2567 operands[4] = gen_reg_rtx (QImode);
2570 ;; High part of 16-bit shift is unused after the instruction:
2571 ;; No need to compute it, map to 8-bit shift.
2574 [(set (match_operand:HI 0 "register_operand" "")
2575 (ashift:HI (match_dup 0)
2576 (match_operand:QI 1 "register_operand" "")))]
2579 (ashift:QI (match_dup 2)
2581 (clobber (match_dup 3))]
2583 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
2585 if (!peep2_reg_dead_p (1, operands[3]))
2588 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
2592 (define_insn "ashlsi3"
2593 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2594 (ashift:SI (match_operand:SI 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 ashlsi3_out (insn, operands, NULL);"
2598 [(set_attr "length" "8,0,4,4,8,10,12")
2599 (set_attr "adjust_len" "ashlsi")
2600 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2602 ;; Optimize if a scratch register from LD_REGS happens to be available.
2604 (define_peephole2 ; ashlqi3_l_const4
2605 [(set (match_operand:QI 0 "l_register_operand" "")
2606 (ashift:QI (match_dup 0)
2608 (match_scratch:QI 1 "d")]
2610 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2611 (set (match_dup 1) (const_int -16))
2612 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2615 (define_peephole2 ; ashlqi3_l_const5
2616 [(set (match_operand:QI 0 "l_register_operand" "")
2617 (ashift:QI (match_dup 0)
2619 (match_scratch:QI 1 "d")]
2621 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2622 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2623 (set (match_dup 1) (const_int -32))
2624 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2627 (define_peephole2 ; ashlqi3_l_const6
2628 [(set (match_operand:QI 0 "l_register_operand" "")
2629 (ashift:QI (match_dup 0)
2631 (match_scratch:QI 1 "d")]
2633 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2634 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2635 (set (match_dup 1) (const_int -64))
2636 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2640 [(match_scratch:QI 3 "d")
2641 (set (match_operand:HI 0 "register_operand" "")
2642 (ashift:HI (match_operand:HI 1 "register_operand" "")
2643 (match_operand:QI 2 "const_int_operand" "")))]
2645 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
2646 (clobber (match_dup 3))])]
2649 (define_insn "*ashlhi3_const"
2650 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2651 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2652 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2653 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2655 "* return ashlhi3_out (insn, operands, NULL);"
2656 [(set_attr "length" "0,2,2,4,10")
2657 (set_attr "adjust_len" "ashlhi")
2658 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
2661 [(match_scratch:QI 3 "d")
2662 (set (match_operand:SI 0 "register_operand" "")
2663 (ashift:SI (match_operand:SI 1 "register_operand" "")
2664 (match_operand:QI 2 "const_int_operand" "")))]
2666 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2667 (clobber (match_dup 3))])]
2670 (define_insn "*ashlsi3_const"
2671 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2672 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2673 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2674 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2676 "* return ashlsi3_out (insn, operands, NULL);"
2677 [(set_attr "length" "0,4,4,10")
2678 (set_attr "adjust_len" "ashlsi")
2679 (set_attr "cc" "none,set_n,clobber,clobber")])
2681 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2682 ;; arithmetic shift right
2684 (define_insn "ashrqi3"
2685 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
2686 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
2687 (match_operand:QI 2 "general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
2689 "* return ashrqi3_out (insn, operands, NULL);"
2690 [(set_attr "length" "5,0,1,2,5,4,9")
2691 (set_attr "adjust_len" "ashrqi")
2692 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
2694 (define_insn "ashrhi3"
2695 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2696 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2697 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2699 "* return ashrhi3_out (insn, operands, NULL);"
2700 [(set_attr "length" "6,0,2,4,4,10,10")
2701 (set_attr "adjust_len" "ashrhi")
2702 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2704 (define_insn "ashrsi3"
2705 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2706 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2707 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2709 "* return ashrsi3_out (insn, operands, NULL);"
2710 [(set_attr "length" "8,0,4,6,8,10,12")
2711 (set_attr "adjust_len" "ashrsi")
2712 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2714 ;; Optimize if a scratch register from LD_REGS happens to be available.
2717 [(match_scratch:QI 3 "d")
2718 (set (match_operand:HI 0 "register_operand" "")
2719 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2720 (match_operand:QI 2 "const_int_operand" "")))]
2722 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
2723 (clobber (match_dup 3))])]
2726 (define_insn "*ashrhi3_const"
2727 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2728 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2729 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2730 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2732 "* return ashrhi3_out (insn, operands, NULL);"
2733 [(set_attr "length" "0,2,4,4,10")
2734 (set_attr "adjust_len" "ashrhi")
2735 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
2738 [(match_scratch:QI 3 "d")
2739 (set (match_operand:SI 0 "register_operand" "")
2740 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2741 (match_operand:QI 2 "const_int_operand" "")))]
2743 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2744 (clobber (match_dup 3))])]
2747 (define_insn "*ashrsi3_const"
2748 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2749 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2750 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2751 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2753 "* return ashrsi3_out (insn, operands, NULL);"
2754 [(set_attr "length" "0,4,4,10")
2755 (set_attr "adjust_len" "ashrsi")
2756 (set_attr "cc" "none,clobber,set_n,clobber")])
2758 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2759 ;; logical shift right
2761 (define_expand "lshrqi3"
2762 [(set (match_operand:QI 0 "register_operand" "")
2763 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2764 (match_operand:QI 2 "general_operand" "")))]
2768 (define_split ; lshrqi3_const4
2769 [(set (match_operand:QI 0 "d_register_operand" "")
2770 (lshiftrt:QI (match_dup 0)
2773 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2774 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
2777 (define_split ; lshrqi3_const5
2778 [(set (match_operand:QI 0 "d_register_operand" "")
2779 (lshiftrt:QI (match_dup 0)
2782 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2783 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2784 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
2787 (define_split ; lshrqi3_const6
2788 [(set (match_operand:QI 0 "d_register_operand" "")
2789 (lshiftrt:QI (match_dup 0)
2792 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2793 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2794 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
2797 (define_insn "*lshrqi3"
2798 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2799 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2800 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
2802 "* return lshrqi3_out (insn, operands, NULL);"
2803 [(set_attr "length" "5,0,1,2,4,6,9")
2804 (set_attr "adjust_len" "lshrqi")
2805 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2807 (define_insn "lshrhi3"
2808 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2809 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2810 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2812 "* return lshrhi3_out (insn, operands, NULL);"
2813 [(set_attr "length" "6,0,2,2,4,10,10")
2814 (set_attr "adjust_len" "lshrhi")
2815 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2817 (define_insn "lshrsi3"
2818 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
2819 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2820 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
2822 "* return lshrsi3_out (insn, operands, NULL);"
2823 [(set_attr "length" "8,0,4,4,8,10,12")
2824 (set_attr "adjust_len" "lshrsi")
2825 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2827 ;; Optimize if a scratch register from LD_REGS happens to be available.
2829 (define_peephole2 ; lshrqi3_l_const4
2830 [(set (match_operand:QI 0 "l_register_operand" "")
2831 (lshiftrt:QI (match_dup 0)
2833 (match_scratch:QI 1 "d")]
2835 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2836 (set (match_dup 1) (const_int 15))
2837 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2840 (define_peephole2 ; lshrqi3_l_const5
2841 [(set (match_operand:QI 0 "l_register_operand" "")
2842 (lshiftrt:QI (match_dup 0)
2844 (match_scratch:QI 1 "d")]
2846 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2847 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2848 (set (match_dup 1) (const_int 7))
2849 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2852 (define_peephole2 ; lshrqi3_l_const6
2853 [(set (match_operand:QI 0 "l_register_operand" "")
2854 (lshiftrt:QI (match_dup 0)
2856 (match_scratch:QI 1 "d")]
2858 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2859 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2860 (set (match_dup 1) (const_int 3))
2861 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2865 [(match_scratch:QI 3 "d")
2866 (set (match_operand:HI 0 "register_operand" "")
2867 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2868 (match_operand:QI 2 "const_int_operand" "")))]
2870 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
2871 (clobber (match_dup 3))])]
2874 (define_insn "*lshrhi3_const"
2875 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
2876 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
2877 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2878 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2880 "* return lshrhi3_out (insn, operands, NULL);"
2881 [(set_attr "length" "0,2,2,4,10")
2882 (set_attr "adjust_len" "lshrhi")
2883 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
2886 [(match_scratch:QI 3 "d")
2887 (set (match_operand:SI 0 "register_operand" "")
2888 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2889 (match_operand:QI 2 "const_int_operand" "")))]
2891 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2892 (clobber (match_dup 3))])]
2895 (define_insn "*lshrsi3_const"
2896 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2897 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
2898 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2899 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2901 "* return lshrsi3_out (insn, operands, NULL);"
2902 [(set_attr "length" "0,4,4,10")
2903 (set_attr "adjust_len" "lshrsi")
2904 (set_attr "cc" "none,clobber,clobber,clobber")])
2906 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2909 (define_insn "absqi2"
2910 [(set (match_operand:QI 0 "register_operand" "=r")
2911 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2915 [(set_attr "length" "2")
2916 (set_attr "cc" "clobber")])
2919 (define_insn "abssf2"
2920 [(set (match_operand:SF 0 "register_operand" "=d,r")
2921 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
2926 [(set_attr "length" "1,2")
2927 (set_attr "cc" "set_n,clobber")])
2929 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
2932 (define_insn "negqi2"
2933 [(set (match_operand:QI 0 "register_operand" "=r")
2934 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
2937 [(set_attr "length" "1")
2938 (set_attr "cc" "set_zn")])
2940 (define_insn "neghi2"
2941 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
2942 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
2945 com %B0\;neg %A0\;sbci %B0,lo8(-1)
2946 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
2947 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
2948 [(set_attr "length" "3,4,4")
2949 (set_attr "cc" "set_czn,set_n,set_czn")])
2951 (define_insn "negsi2"
2952 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
2953 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
2956 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
2957 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
2958 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
2959 [(set_attr_alternative "length"
2962 (if_then_else (eq_attr "mcu_have_movw" "yes")
2965 (set_attr "cc" "set_czn,set_n,set_czn")])
2967 (define_insn "negsf2"
2968 [(set (match_operand:SF 0 "register_operand" "=d,r")
2969 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
2973 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
2974 [(set_attr "length" "1,4")
2975 (set_attr "cc" "set_n,set_n")])
2977 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2980 (define_insn "one_cmplqi2"
2981 [(set (match_operand:QI 0 "register_operand" "=r")
2982 (not:QI (match_operand:QI 1 "register_operand" "0")))]
2985 [(set_attr "length" "1")
2986 (set_attr "cc" "set_czn")])
2988 (define_insn "one_cmplhi2"
2989 [(set (match_operand:HI 0 "register_operand" "=r")
2990 (not:HI (match_operand:HI 1 "register_operand" "0")))]
2994 [(set_attr "length" "2")
2995 (set_attr "cc" "set_n")])
2997 (define_insn "one_cmplsi2"
2998 [(set (match_operand:SI 0 "register_operand" "=r")
2999 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3005 [(set_attr "length" "4")
3006 (set_attr "cc" "set_n")])
3008 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3011 ;; We keep combiner from inserting hard registers into the input of sign- and
3012 ;; zero-extends. A hard register in the input operand is not wanted because
3013 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3014 ;; hard register that overlaps these clobbers won't be combined to a widening
3015 ;; multiplication. There is no need for combine to propagate hard registers,
3016 ;; register allocation can do it just as well.
3018 (define_insn "extendqihi2"
3019 [(set (match_operand:HI 0 "register_operand" "=r,r")
3020 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3023 clr %B0\;sbrc %0,7\;com %B0
3024 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3025 [(set_attr "length" "3,4")
3026 (set_attr "cc" "set_n,set_n")])
3028 (define_insn "extendqisi2"
3029 [(set (match_operand:SI 0 "register_operand" "=r,r")
3030 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3033 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3034 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3035 [(set_attr "length" "5,6")
3036 (set_attr "cc" "set_n,set_n")])
3038 (define_insn "extendhisi2"
3039 [(set (match_operand:SI 0 "register_operand" "=r,r")
3040 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
3043 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3044 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3045 [(set_attr_alternative "length"
3047 (if_then_else (eq_attr "mcu_have_movw" "yes")
3050 (set_attr "cc" "set_n,set_n")])
3052 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3055 (define_insn_and_split "zero_extendqihi2"
3056 [(set (match_operand:HI 0 "register_operand" "=r")
3057 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3061 [(set (match_dup 2) (match_dup 1))
3062 (set (match_dup 3) (const_int 0))]
3064 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
3065 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
3067 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
3068 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
3071 (define_insn_and_split "zero_extendqisi2"
3072 [(set (match_operand:SI 0 "register_operand" "=r")
3073 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3077 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
3078 (set (match_dup 3) (const_int 0))]
3080 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3081 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3083 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3084 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3087 (define_insn_and_split "zero_extendhisi2"
3088 [(set (match_operand:SI 0 "register_operand" "=r")
3089 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
3093 [(set (match_dup 2) (match_dup 1))
3094 (set (match_dup 3) (const_int 0))]
3096 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3097 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3099 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3100 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3103 (define_insn_and_split "zero_extendqidi2"
3104 [(set (match_operand:DI 0 "register_operand" "=r")
3105 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3109 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3110 (set (match_dup 3) (const_int 0))]
3112 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3113 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3115 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3116 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3119 (define_insn_and_split "zero_extendhidi2"
3120 [(set (match_operand:DI 0 "register_operand" "=r")
3121 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3125 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3126 (set (match_dup 3) (const_int 0))]
3128 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3129 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3131 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3132 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3135 (define_insn_and_split "zero_extendsidi2"
3136 [(set (match_operand:DI 0 "register_operand" "=r")
3137 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3141 [(set (match_dup 2) (match_dup 1))
3142 (set (match_dup 3) (const_int 0))]
3144 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3145 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3147 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3148 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3151 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
3154 ; Optimize negated tests into reverse compare if overflow is undefined.
3155 (define_insn "*negated_tstqi"
3157 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
3159 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3160 "cp __zero_reg__,%0"
3161 [(set_attr "cc" "compare")
3162 (set_attr "length" "1")])
3164 (define_insn "*reversed_tstqi"
3166 (compare (const_int 0)
3167 (match_operand:QI 0 "register_operand" "r")))]
3169 "cp __zero_reg__,%0"
3170 [(set_attr "cc" "compare")
3171 (set_attr "length" "2")])
3173 (define_insn "*negated_tsthi"
3175 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
3177 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3178 "cp __zero_reg__,%A0
3179 cpc __zero_reg__,%B0"
3180 [(set_attr "cc" "compare")
3181 (set_attr "length" "2")])
3183 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
3184 ;; though it is unused, because this pattern is synthesized by avr_reorg.
3185 (define_insn "*reversed_tsthi"
3187 (compare (const_int 0)
3188 (match_operand:HI 0 "register_operand" "r")))
3189 (clobber (match_scratch:QI 1 "=X"))]
3191 "cp __zero_reg__,%A0
3192 cpc __zero_reg__,%B0"
3193 [(set_attr "cc" "compare")
3194 (set_attr "length" "2")])
3196 (define_insn "*negated_tstsi"
3198 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
3200 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3201 "cp __zero_reg__,%A0
3202 cpc __zero_reg__,%B0
3203 cpc __zero_reg__,%C0
3204 cpc __zero_reg__,%D0"
3205 [(set_attr "cc" "compare")
3206 (set_attr "length" "4")])
3208 (define_insn "*reversed_tstsi"
3210 (compare (const_int 0)
3211 (match_operand:SI 0 "register_operand" "r")))
3212 (clobber (match_scratch:QI 1 "=X"))]
3214 "cp __zero_reg__,%A0
3215 cpc __zero_reg__,%B0
3216 cpc __zero_reg__,%C0
3217 cpc __zero_reg__,%D0"
3218 [(set_attr "cc" "compare")
3219 (set_attr "length" "4")])
3222 (define_insn "*cmpqi"
3224 (compare (match_operand:QI 0 "register_operand" "r,r,d")
3225 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
3231 [(set_attr "cc" "compare,compare,compare")
3232 (set_attr "length" "1,1,1")])
3234 (define_insn "*cmpqi_sign_extend"
3236 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
3237 (match_operand:HI 1 "s8_operand" "n")))]
3240 [(set_attr "cc" "compare")
3241 (set_attr "length" "1")])
3243 (define_insn "*cmphi"
3245 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
3246 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
3247 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
3250 switch (which_alternative)
3254 return avr_out_tsthi (insn, operands, NULL);
3257 return "cp %A0,%A1\;cpc %B0,%B1";
3260 return reg_unused_after (insn, operands[0])
3261 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
3262 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
3265 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
3268 return avr_out_compare (insn, operands, NULL);
3270 [(set_attr "cc" "compare")
3271 (set_attr "length" "1,2,2,3,4,2,4")
3272 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
3275 (define_insn "*cmpsi"
3277 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
3278 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
3279 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
3282 if (0 == which_alternative)
3283 return avr_out_tstsi (insn, operands, NULL);
3284 else if (1 == which_alternative)
3285 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
3287 return avr_out_compare (insn, operands, NULL);
3289 [(set_attr "cc" "compare")
3290 (set_attr "length" "4,4,4,5,8")
3291 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
3294 ;; ----------------------------------------------------------------------
3295 ;; JUMP INSTRUCTIONS
3296 ;; ----------------------------------------------------------------------
3297 ;; Conditional jump instructions
3299 (define_expand "cbranchsi4"
3300 [(parallel [(set (cc0)
3301 (compare (match_operand:SI 1 "register_operand" "")
3302 (match_operand:SI 2 "nonmemory_operand" "")))
3303 (clobber (match_scratch:QI 4 ""))])
3306 (match_operator 0 "ordered_comparison_operator" [(cc0)
3308 (label_ref (match_operand 3 "" ""))
3312 (define_expand "cbranchhi4"
3313 [(parallel [(set (cc0)
3314 (compare (match_operand:HI 1 "register_operand" "")
3315 (match_operand:HI 2 "nonmemory_operand" "")))
3316 (clobber (match_scratch:QI 4 ""))])
3319 (match_operator 0 "ordered_comparison_operator" [(cc0)
3321 (label_ref (match_operand 3 "" ""))
3325 (define_expand "cbranchqi4"
3327 (compare (match_operand:QI 1 "register_operand" "")
3328 (match_operand:QI 2 "nonmemory_operand" "")))
3331 (match_operator 0 "ordered_comparison_operator" [(cc0)
3333 (label_ref (match_operand 3 "" ""))
3338 ;; Test a single bit in a QI/HI/SImode register.
3339 ;; Combine will create zero extract patterns for single bit tests.
3340 ;; permit any mode in source pattern by using VOIDmode.
3342 (define_insn "*sbrx_branch<mode>"
3345 (match_operator 0 "eqne_operator"
3347 (match_operand:VOID 1 "register_operand" "r")
3349 (match_operand 2 "const_int_operand" "n"))
3351 (label_ref (match_operand 3 "" ""))
3354 "* return avr_out_sbxx_branch (insn, operands);"
3355 [(set (attr "length")
3356 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3357 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3359 (if_then_else (eq_attr "mcu_mega" "no")
3362 (set_attr "cc" "clobber")])
3364 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
3365 ;; or for old peepholes.
3366 ;; Fixme - bitwise Mask will not work for DImode
3368 (define_insn "*sbrx_and_branch<mode>"
3371 (match_operator 0 "eqne_operator"
3373 (match_operand:QISI 1 "register_operand" "r")
3374 (match_operand:QISI 2 "single_one_operand" "n"))
3376 (label_ref (match_operand 3 "" ""))
3380 HOST_WIDE_INT bitnumber;
3381 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
3382 operands[2] = GEN_INT (bitnumber);
3383 return avr_out_sbxx_branch (insn, operands);
3385 [(set (attr "length")
3386 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3387 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3389 (if_then_else (eq_attr "mcu_mega" "no")
3392 (set_attr "cc" "clobber")])
3394 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
3396 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3398 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3399 (label_ref (match_operand 1 "" ""))
3402 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
3406 (label_ref (match_dup 1))
3411 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3413 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3414 (label_ref (match_operand 1 "" ""))
3417 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
3421 (label_ref (match_dup 1))
3426 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3428 (clobber (match_operand:HI 2 ""))])
3429 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3430 (label_ref (match_operand 1 "" ""))
3433 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
3435 (label_ref (match_dup 1))
3440 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3442 (clobber (match_operand:HI 2 ""))])
3443 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3444 (label_ref (match_operand 1 "" ""))
3447 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
3449 (label_ref (match_dup 1))
3454 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3456 (clobber (match_operand:SI 2 ""))])
3457 (set (pc) (if_then_else (ge (cc0) (const_int 0))
3458 (label_ref (match_operand 1 "" ""))
3461 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
3463 (label_ref (match_dup 1))
3465 "operands[2] = GEN_INT (-2147483647 - 1);")
3468 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3470 (clobber (match_operand:SI 2 ""))])
3471 (set (pc) (if_then_else (lt (cc0) (const_int 0))
3472 (label_ref (match_operand 1 "" ""))
3475 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
3477 (label_ref (match_dup 1))
3479 "operands[2] = GEN_INT (-2147483647 - 1);")
3481 ;; ************************************************************************
3482 ;; Implementation of conditional jumps here.
3483 ;; Compare with 0 (test) jumps
3484 ;; ************************************************************************
3486 (define_insn "branch"
3488 (if_then_else (match_operator 1 "simple_comparison_operator"
3491 (label_ref (match_operand 0 "" ""))
3495 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3497 [(set_attr "type" "branch")
3498 (set_attr "cc" "clobber")])
3501 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
3502 ;; or optimized in the remainder.
3504 (define_insn "branch_unspec"
3506 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
3509 (label_ref (match_operand 0 "" ""))
3511 ] UNSPEC_IDENTITY))]
3514 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
3516 [(set_attr "type" "branch")
3517 (set_attr "cc" "none")])
3519 ;; ****************************************************************
3520 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
3521 ;; Convert them all to proper jumps.
3522 ;; ****************************************************************/
3524 (define_insn "difficult_branch"
3526 (if_then_else (match_operator 1 "difficult_comparison_operator"
3529 (label_ref (match_operand 0 "" ""))
3533 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3534 [(set_attr "type" "branch1")
3535 (set_attr "cc" "clobber")])
3539 (define_insn "rvbranch"
3541 (if_then_else (match_operator 1 "simple_comparison_operator"
3545 (label_ref (match_operand 0 "" ""))))]
3548 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3549 [(set_attr "type" "branch1")
3550 (set_attr "cc" "clobber")])
3552 (define_insn "difficult_rvbranch"
3554 (if_then_else (match_operator 1 "difficult_comparison_operator"
3558 (label_ref (match_operand 0 "" ""))))]
3561 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3562 [(set_attr "type" "branch")
3563 (set_attr "cc" "clobber")])
3565 ;; **************************************************************************
3566 ;; Unconditional and other jump instructions.
3570 (label_ref (match_operand 0 "" "")))]
3573 if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
3574 return AS1 (jmp,%x0);
3575 return AS1 (rjmp,%x0);
3577 [(set (attr "length")
3578 (if_then_else (match_operand 0 "symbol_ref_operand" "")
3579 (if_then_else (eq_attr "mcu_mega" "no")
3582 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
3583 (le (minus (pc) (match_dup 0)) (const_int 2047)))
3586 (set_attr "cc" "none")])
3590 (define_expand "call"
3591 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3592 (match_operand:HI 1 "general_operand" ""))
3593 (use (const_int 0))])]
3594 ;; Operand 1 not used on the AVR.
3595 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3599 (define_expand "sibcall"
3600 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3601 (match_operand:HI 1 "general_operand" ""))
3602 (use (const_int 1))])]
3603 ;; Operand 1 not used on the AVR.
3604 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3610 (define_expand "call_value"
3611 [(parallel[(set (match_operand 0 "register_operand" "")
3612 (call (match_operand:HI 1 "call_insn_operand" "")
3613 (match_operand:HI 2 "general_operand" "")))
3614 (use (const_int 0))])]
3615 ;; Operand 2 not used on the AVR.
3616 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3620 (define_expand "sibcall_value"
3621 [(parallel[(set (match_operand 0 "register_operand" "")
3622 (call (match_operand:HI 1 "call_insn_operand" "")
3623 (match_operand:HI 2 "general_operand" "")))
3624 (use (const_int 1))])]
3625 ;; Operand 2 not used on the AVR.
3626 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3630 (define_insn "call_insn"
3631 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
3632 (match_operand:HI 1 "general_operand" "X,X,X,X"))
3633 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
3634 ;; Operand 1 not used on the AVR.
3635 ;; Operand 2 is 1 for tail-call, 0 otherwise.
3642 [(set_attr "cc" "clobber")
3643 (set_attr_alternative "length"
3645 (if_then_else (eq_attr "mcu_mega" "yes")
3649 (if_then_else (eq_attr "mcu_mega" "yes")
3653 (define_insn "call_value_insn"
3654 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
3655 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
3656 (match_operand:HI 2 "general_operand" "X,X,X,X")))
3657 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
3658 ;; Operand 2 not used on the AVR.
3659 ;; Operand 3 is 1 for tail-call, 0 otherwise.
3666 [(set_attr "cc" "clobber")
3667 (set_attr_alternative "length"
3669 (if_then_else (eq_attr "mcu_mega" "yes")
3673 (if_then_else (eq_attr "mcu_mega" "yes")
3681 [(set_attr "cc" "none")
3682 (set_attr "length" "1")])
3686 (define_expand "indirect_jump"
3687 [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
3689 " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
3691 operands[0] = copy_to_mode_reg(HImode, operand0);
3696 (define_insn "*jcindirect_jump"
3697 [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
3700 [(set_attr "length" "2")
3701 (set_attr "cc" "none")])
3704 (define_insn "*njcindirect_jump"
3705 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
3706 "!AVR_HAVE_EIJMP_EICALL"
3709 push %A0\;push %B0\;ret"
3710 [(set_attr "length" "1,3")
3711 (set_attr "cc" "none,none")])
3713 (define_insn "*indirect_jump_avr6"
3714 [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
3715 "AVR_HAVE_EIJMP_EICALL"
3717 [(set_attr "length" "1")
3718 (set_attr "cc" "none")])
3721 ;; For entries in jump table see avr_output_addr_vec_elt.
3723 ;; Table made from "rjmp .L<n>" instructions for <= 8K devices.
3724 (define_insn "*tablejump_rjmp"
3726 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
3728 (use (label_ref (match_operand 1 "" "")))
3729 (clobber (match_dup 0))]
3730 "!AVR_HAVE_JMP_CALL"
3733 push %A0\;push %B0\;ret"
3734 [(set_attr "length" "1,3")
3735 (set_attr "cc" "none,none")])
3737 ;; Move the common piece of code to libgcc.
3738 ;; Table made from ".word gs(.L<n>)" addresses for > 8K devices.
3739 ;; Read jump address from table and perform indirect jump.
3740 (define_insn "*tablejump_lib"
3742 (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3744 (use (label_ref (match_operand 1 "" "")))
3745 (clobber (match_dup 0))]
3747 "jmp __tablejump2__"
3748 [(set_attr "length" "2")
3749 (set_attr "cc" "clobber")])
3752 (define_expand "casesi"
3754 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
3755 (match_operand:HI 1 "register_operand" "")))
3756 (parallel [(set (cc0)
3757 (compare (match_dup 6)
3758 (match_operand:HI 2 "register_operand" "")))
3759 (clobber (match_scratch:QI 9 ""))])
3762 (if_then_else (gtu (cc0)
3764 (label_ref (match_operand 4 "" ""))
3768 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
3770 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
3771 (use (label_ref (match_dup 3)))
3772 (clobber (match_dup 6))])]
3776 operands[6] = gen_reg_rtx (HImode);
3780 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3781 ;; This instruction sets Z flag
3784 [(set (cc0) (const_int 0))]
3787 [(set_attr "length" "1")
3788 (set_attr "cc" "compare")])
3790 ;; Clear/set/test a single bit in I/O address space.
3793 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3794 (and:QI (mem:QI (match_dup 0))
3795 (match_operand:QI 1 "single_zero_operand" "n")))]
3798 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
3799 return AS2 (cbi,%m0-0x20,%2);
3801 [(set_attr "length" "1")
3802 (set_attr "cc" "none")])
3805 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3806 (ior:QI (mem:QI (match_dup 0))
3807 (match_operand:QI 1 "single_one_operand" "n")))]
3810 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
3811 return AS2 (sbi,%m0-0x20,%2);
3813 [(set_attr "length" "1")
3814 (set_attr "cc" "none")])
3816 ;; Lower half of the I/O space - use sbic/sbis directly.
3817 (define_insn "*sbix_branch"
3820 (match_operator 0 "eqne_operator"
3822 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
3824 (match_operand 2 "const_int_operand" "n"))
3826 (label_ref (match_operand 3 "" ""))
3829 "* return avr_out_sbxx_branch (insn, operands);"
3830 [(set (attr "length")
3831 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3832 (le (minus (pc) (match_dup 3)) (const_int 2046)))
3834 (if_then_else (eq_attr "mcu_mega" "no")
3837 (set_attr "cc" "clobber")])
3839 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
3840 (define_insn "*sbix_branch_bit7"
3843 (match_operator 0 "gelt_operator"
3844 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
3846 (label_ref (match_operand 2 "" ""))
3850 operands[3] = operands[2];
3851 operands[2] = GEN_INT (7);
3852 return avr_out_sbxx_branch (insn, operands);
3854 [(set (attr "length")
3855 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3856 (le (minus (pc) (match_dup 2)) (const_int 2046)))
3858 (if_then_else (eq_attr "mcu_mega" "no")
3861 (set_attr "cc" "clobber")])
3863 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
3864 (define_insn "*sbix_branch_tmp"
3867 (match_operator 0 "eqne_operator"
3869 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
3871 (match_operand 2 "const_int_operand" "n"))
3873 (label_ref (match_operand 3 "" ""))
3876 "* return avr_out_sbxx_branch (insn, operands);"
3877 [(set (attr "length")
3878 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3879 (le (minus (pc) (match_dup 3)) (const_int 2045)))
3881 (if_then_else (eq_attr "mcu_mega" "no")
3884 (set_attr "cc" "clobber")])
3886 (define_insn "*sbix_branch_tmp_bit7"
3889 (match_operator 0 "gelt_operator"
3890 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
3892 (label_ref (match_operand 2 "" ""))
3896 operands[3] = operands[2];
3897 operands[2] = GEN_INT (7);
3898 return avr_out_sbxx_branch (insn, operands);
3900 [(set (attr "length")
3901 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3902 (le (minus (pc) (match_dup 2)) (const_int 2045)))
3904 (if_then_else (eq_attr "mcu_mega" "no")
3907 (set_attr "cc" "clobber")])
3909 ;; ************************* Peepholes ********************************
3912 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
3913 (plus:SI (match_dup 0)
3915 (clobber (scratch:QI))])
3916 (parallel [(set (cc0)
3917 (compare (match_dup 0)
3919 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3921 (if_then_else (ne (cc0)
3923 (label_ref (match_operand 2 "" ""))
3928 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3929 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3930 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3931 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
3933 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3934 AS2 (sbc,%B0,__zero_reg__) CR_TAB
3935 AS2 (sbc,%C0,__zero_reg__) CR_TAB
3936 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
3938 switch (avr_jump_mode (operands[2], insn))
3941 return AS1 (brcc,%2);
3943 return (AS1 (brcs,.+2) CR_TAB
3947 return (AS1 (brcs,.+4) CR_TAB
3952 [(set (match_operand:HI 0 "d_register_operand" "")
3953 (plus:HI (match_dup 0)
3957 (compare (match_dup 0)
3959 (clobber (match_operand:QI 1 "d_register_operand" ""))])
3961 (if_then_else (ne (cc0) (const_int 0))
3962 (label_ref (match_operand 2 "" ""))
3968 if (test_hard_reg_class (ADDW_REGS, operands[0]))
3969 output_asm_insn (AS2 (sbiw,%0,1), operands);
3971 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3972 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3973 switch (avr_jump_mode (operands[2],insn))
3976 return AS1 (brcc,%2);
3978 return (AS1 (brcs,.+2) CR_TAB
3981 return (AS1 (brcs,.+4) CR_TAB
3986 [(set (match_operand:QI 0 "d_register_operand" "")
3987 (plus:QI (match_dup 0)
3990 (compare (match_dup 0)
3993 (if_then_else (ne (cc0) (const_int 0))
3994 (label_ref (match_operand 1 "" ""))
4000 cc_status.value1 = operands[0];
4001 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
4002 output_asm_insn (AS2 (subi,%A0,1), operands);
4003 switch (avr_jump_mode (operands[1],insn))
4006 return AS1 (brcc,%1);
4008 return (AS1 (brcs,.+2) CR_TAB
4011 return (AS1 (brcs,.+4) CR_TAB
4017 (compare (match_operand:QI 0 "register_operand" "")
4020 (if_then_else (eq (cc0) (const_int 0))
4021 (label_ref (match_operand 1 "" ""))
4023 "jump_over_one_insn_p (insn, operands[1])"
4024 "cpse %0,__zero_reg__")
4028 (compare (match_operand:QI 0 "register_operand" "")
4029 (match_operand:QI 1 "register_operand" "")))
4031 (if_then_else (eq (cc0) (const_int 0))
4032 (label_ref (match_operand 2 "" ""))
4034 "jump_over_one_insn_p (insn, operands[2])"
4037 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
4038 ;;prologue/epilogue support instructions
4040 (define_insn "popqi"
4041 [(set (match_operand:QI 0 "register_operand" "=r")
4042 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
4045 [(set_attr "cc" "none")
4046 (set_attr "length" "1")])
4048 ;; Enable Interrupts
4049 (define_insn "enable_interrupt"
4050 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
4053 [(set_attr "length" "1")
4054 (set_attr "cc" "none")])
4056 ;; Disable Interrupts
4057 (define_insn "disable_interrupt"
4058 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
4061 [(set_attr "length" "1")
4062 (set_attr "cc" "none")])
4064 ;; Library prologue saves
4065 (define_insn "call_prologue_saves"
4066 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
4067 (match_operand:HI 0 "immediate_operand" "")
4068 (set (reg:HI REG_SP) (minus:HI
4070 (match_operand:HI 1 "immediate_operand" "")))
4071 (use (reg:HI REG_X))
4072 (clobber (reg:HI REG_Z))]
4074 "ldi r30,lo8(gs(1f))
4076 %~jmp __prologue_saves__+((18 - %0) * 2)
4078 [(set_attr_alternative "length"
4079 [(if_then_else (eq_attr "mcu_mega" "yes")
4082 (set_attr "cc" "clobber")
4085 ; epilogue restores using library
4086 (define_insn "epilogue_restores"
4087 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
4088 (set (reg:HI REG_Y ) (plus:HI
4090 (match_operand:HI 0 "immediate_operand" "")))
4091 (set (reg:HI REG_SP) (reg:HI REG_Y))
4092 (clobber (reg:QI REG_Z))]
4095 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
4096 [(set_attr_alternative "length"
4097 [(if_then_else (eq_attr "mcu_mega" "yes")
4100 (set_attr "cc" "clobber")
4104 (define_insn "return"
4106 "reload_completed && avr_simple_epilogue ()"
4108 [(set_attr "cc" "none")
4109 (set_attr "length" "1")])
4111 (define_insn "return_from_epilogue"
4115 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
4116 && !cfun->machine->is_naked)"
4118 [(set_attr "cc" "none")
4119 (set_attr "length" "1")])
4121 (define_insn "return_from_interrupt_epilogue"
4125 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
4126 && !cfun->machine->is_naked)"
4128 [(set_attr "cc" "none")
4129 (set_attr "length" "1")])
4131 (define_insn "return_from_naked_epilogue"
4135 && cfun->machine->is_naked)"
4137 [(set_attr "cc" "none")
4138 (set_attr "length" "0")])
4140 (define_expand "prologue"
4149 (define_expand "epilogue"
4153 expand_epilogue (false /* sibcall_p */);
4157 (define_expand "sibcall_epilogue"
4161 expand_epilogue (true /* sibcall_p */);
4165 ;; Some instructions resp. instruction sequences available
4168 (define_insn "delay_cycles_1"
4169 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
4171 UNSPECV_DELAY_CYCLES)
4172 (clobber (match_scratch:QI 1 "=&d"))]
4177 [(set_attr "length" "3")
4178 (set_attr "cc" "clobber")])
4180 (define_insn "delay_cycles_2"
4181 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
4183 UNSPECV_DELAY_CYCLES)
4184 (clobber (match_scratch:HI 1 "=&w"))]
4190 [(set_attr "length" "4")
4191 (set_attr "cc" "clobber")])
4193 (define_insn "delay_cycles_3"
4194 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4196 UNSPECV_DELAY_CYCLES)
4197 (clobber (match_scratch:QI 1 "=&d"))
4198 (clobber (match_scratch:QI 2 "=&d"))
4199 (clobber (match_scratch:QI 3 "=&d"))]
4208 [(set_attr "length" "7")
4209 (set_attr "cc" "clobber")])
4211 (define_insn "delay_cycles_4"
4212 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4214 UNSPECV_DELAY_CYCLES)
4215 (clobber (match_scratch:QI 1 "=&d"))
4216 (clobber (match_scratch:QI 2 "=&d"))
4217 (clobber (match_scratch:QI 3 "=&d"))
4218 (clobber (match_scratch:QI 4 "=&d"))]
4229 [(set_attr "length" "9")
4230 (set_attr "cc" "clobber")])
4235 (define_expand "parityhi2"
4237 (match_operand:HI 1 "register_operand" ""))
4239 (parity:HI (reg:HI 24)))
4240 (set (match_operand:HI 0 "register_operand" "")
4245 (define_expand "paritysi2"
4247 (match_operand:SI 1 "register_operand" ""))
4249 (truncate:HI (parity:SI (reg:SI 22))))
4252 (set (match_operand:SI 0 "register_operand" "")
4253 (zero_extend:SI (match_dup 2)))]
4256 operands[2] = gen_reg_rtx (HImode);
4259 (define_insn "*parityhi2.libgcc"
4261 (parity:HI (reg:HI 24)))]
4263 "%~call __parityhi2"
4264 [(set_attr "type" "xcall")
4265 (set_attr "cc" "clobber")])
4267 (define_insn "*parityqihi2.libgcc"
4269 (zero_extend:HI (parity:QI (reg:QI 24))))]
4271 "%~call __parityqi2"
4272 [(set_attr "type" "xcall")
4273 (set_attr "cc" "clobber")])
4275 (define_insn "*paritysihi2.libgcc"
4277 (truncate:HI (parity:SI (reg:SI 22))))]
4279 "%~call __paritysi2"
4280 [(set_attr "type" "xcall")
4281 (set_attr "cc" "clobber")])
4286 (define_expand "popcounthi2"
4288 (match_operand:HI 1 "register_operand" ""))
4290 (popcount:HI (reg:HI 24)))
4291 (set (match_operand:HI 0 "register_operand" "")
4296 (define_expand "popcountsi2"
4298 (match_operand:SI 1 "register_operand" ""))
4300 (truncate:HI (popcount:SI (reg:SI 22))))
4303 (set (match_operand:SI 0 "register_operand" "")
4304 (zero_extend:SI (match_dup 2)))]
4307 operands[2] = gen_reg_rtx (HImode);
4310 (define_insn "*popcounthi2.libgcc"
4312 (popcount:HI (reg:HI 24)))]
4314 "%~call __popcounthi2"
4315 [(set_attr "type" "xcall")
4316 (set_attr "cc" "clobber")])
4318 (define_insn "*popcountsi2.libgcc"
4320 (truncate:HI (popcount:SI (reg:SI 22))))]
4322 "%~call __popcountsi2"
4323 [(set_attr "type" "xcall")
4324 (set_attr "cc" "clobber")])
4326 (define_insn "*popcountqi2.libgcc"
4328 (popcount:QI (reg:QI 24)))]
4330 "%~call __popcountqi2"
4331 [(set_attr "type" "xcall")
4332 (set_attr "cc" "clobber")])
4334 (define_insn_and_split "*popcountqihi2.libgcc"
4336 (zero_extend:HI (popcount:QI (reg:QI 24))))]
4341 (popcount:QI (reg:QI 24)))
4346 ;; Count Leading Zeros
4348 (define_expand "clzhi2"
4350 (match_operand:HI 1 "register_operand" ""))
4351 (parallel [(set (reg:HI 24)
4352 (clz:HI (reg:HI 24)))
4353 (clobber (reg:QI 26))])
4354 (set (match_operand:HI 0 "register_operand" "")
4359 (define_expand "clzsi2"
4361 (match_operand:SI 1 "register_operand" ""))
4362 (parallel [(set (reg:HI 24)
4363 (truncate:HI (clz:SI (reg:SI 22))))
4364 (clobber (reg:QI 26))])
4367 (set (match_operand:SI 0 "register_operand" "")
4368 (zero_extend:SI (match_dup 2)))]
4371 operands[2] = gen_reg_rtx (HImode);
4374 (define_insn "*clzhi2.libgcc"
4376 (clz:HI (reg:HI 24)))
4377 (clobber (reg:QI 26))]
4380 [(set_attr "type" "xcall")
4381 (set_attr "cc" "clobber")])
4383 (define_insn "*clzsihi2.libgcc"
4385 (truncate:HI (clz:SI (reg:SI 22))))
4386 (clobber (reg:QI 26))]
4389 [(set_attr "type" "xcall")
4390 (set_attr "cc" "clobber")])
4392 ;; Count Trailing Zeros
4394 (define_expand "ctzhi2"
4396 (match_operand:HI 1 "register_operand" ""))
4397 (parallel [(set (reg:HI 24)
4398 (ctz:HI (reg:HI 24)))
4399 (clobber (reg:QI 26))])
4400 (set (match_operand:HI 0 "register_operand" "")
4405 (define_expand "ctzsi2"
4407 (match_operand:SI 1 "register_operand" ""))
4408 (parallel [(set (reg:HI 24)
4409 (truncate:HI (ctz:SI (reg:SI 22))))
4410 (clobber (reg:QI 22))
4411 (clobber (reg:QI 26))])
4414 (set (match_operand:SI 0 "register_operand" "")
4415 (zero_extend:SI (match_dup 2)))]
4418 operands[2] = gen_reg_rtx (HImode);
4421 (define_insn "*ctzhi2.libgcc"
4423 (ctz:HI (reg:HI 24)))
4424 (clobber (reg:QI 26))]
4427 [(set_attr "type" "xcall")
4428 (set_attr "cc" "clobber")])
4430 (define_insn "*ctzsihi2.libgcc"
4432 (truncate:HI (ctz:SI (reg:SI 22))))
4433 (clobber (reg:QI 22))
4434 (clobber (reg:QI 26))]
4437 [(set_attr "type" "xcall")
4438 (set_attr "cc" "clobber")])
4442 (define_expand "ffshi2"
4444 (match_operand:HI 1 "register_operand" ""))
4445 (parallel [(set (reg:HI 24)
4446 (ffs:HI (reg:HI 24)))
4447 (clobber (reg:QI 26))])
4448 (set (match_operand:HI 0 "register_operand" "")
4453 (define_expand "ffssi2"
4455 (match_operand:SI 1 "register_operand" ""))
4456 (parallel [(set (reg:HI 24)
4457 (truncate:HI (ffs:SI (reg:SI 22))))
4458 (clobber (reg:QI 22))
4459 (clobber (reg:QI 26))])
4462 (set (match_operand:SI 0 "register_operand" "")
4463 (zero_extend:SI (match_dup 2)))]
4466 operands[2] = gen_reg_rtx (HImode);
4469 (define_insn "*ffshi2.libgcc"
4471 (ffs:HI (reg:HI 24)))
4472 (clobber (reg:QI 26))]
4475 [(set_attr "type" "xcall")
4476 (set_attr "cc" "clobber")])
4478 (define_insn "*ffssihi2.libgcc"
4480 (truncate:HI (ffs:SI (reg:SI 22))))
4481 (clobber (reg:QI 22))
4482 (clobber (reg:QI 26))]
4485 [(set_attr "type" "xcall")
4486 (set_attr "cc" "clobber")])
4490 (define_insn "copysignsf3"
4491 [(set (match_operand:SF 0 "register_operand" "=r")
4492 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
4493 (match_operand:SF 2 "register_operand" "r")]
4496 "bst %D2,7\;bld %D0,7"
4497 [(set_attr "length" "2")
4498 (set_attr "cc" "none")])
4500 ;; Swap Bytes (change byte-endianess)
4502 (define_expand "bswapsi2"
4504 (match_operand:SI 1 "register_operand" ""))
4506 (bswap:SI (reg:SI 22)))
4507 (set (match_operand:SI 0 "register_operand" "")
4512 (define_insn "*bswapsi2.libgcc"
4514 (bswap:SI (reg:SI 22)))]
4517 [(set_attr "type" "xcall")
4518 (set_attr "cc" "clobber")])
4523 ;; NOP taking 1 or 2 Ticks
4525 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
4531 [(set_attr "length" "1")
4532 (set_attr "cc" "none")])
4535 (define_insn "sleep"
4536 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
4539 [(set_attr "length" "1")
4540 (set_attr "cc" "none")])
4544 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
4547 [(set_attr "length" "1")
4548 (set_attr "cc" "none")])
4551 (define_expand "fmul"
4553 (match_operand:QI 1 "register_operand" ""))
4555 (match_operand:QI 2 "register_operand" ""))
4556 (parallel [(set (reg:HI 22)
4557 (unspec:HI [(reg:QI 24)
4558 (reg:QI 25)] UNSPEC_FMUL))
4559 (clobber (reg:HI 24))])
4560 (set (match_operand:HI 0 "register_operand" "")
4566 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
4571 (define_insn "fmul_insn"
4572 [(set (match_operand:HI 0 "register_operand" "=r")
4573 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4574 (match_operand:QI 2 "register_operand" "a")]
4580 [(set_attr "length" "3")
4581 (set_attr "cc" "clobber")])
4583 (define_insn "*fmul.call"
4585 (unspec:HI [(reg:QI 24)
4586 (reg:QI 25)] UNSPEC_FMUL))
4587 (clobber (reg:HI 24))]
4590 [(set_attr "type" "xcall")
4591 (set_attr "cc" "clobber")])
4594 (define_expand "fmuls"
4596 (match_operand:QI 1 "register_operand" ""))
4598 (match_operand:QI 2 "register_operand" ""))
4599 (parallel [(set (reg:HI 22)
4600 (unspec:HI [(reg:QI 24)
4601 (reg:QI 25)] UNSPEC_FMULS))
4602 (clobber (reg:HI 24))])
4603 (set (match_operand:HI 0 "register_operand" "")
4609 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
4614 (define_insn "fmuls_insn"
4615 [(set (match_operand:HI 0 "register_operand" "=r")
4616 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4617 (match_operand:QI 2 "register_operand" "a")]
4623 [(set_attr "length" "3")
4624 (set_attr "cc" "clobber")])
4626 (define_insn "*fmuls.call"
4628 (unspec:HI [(reg:QI 24)
4629 (reg:QI 25)] UNSPEC_FMULS))
4630 (clobber (reg:HI 24))]
4633 [(set_attr "type" "xcall")
4634 (set_attr "cc" "clobber")])
4637 (define_expand "fmulsu"
4639 (match_operand:QI 1 "register_operand" ""))
4641 (match_operand:QI 2 "register_operand" ""))
4642 (parallel [(set (reg:HI 22)
4643 (unspec:HI [(reg:QI 24)
4644 (reg:QI 25)] UNSPEC_FMULSU))
4645 (clobber (reg:HI 24))])
4646 (set (match_operand:HI 0 "register_operand" "")
4652 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
4657 (define_insn "fmulsu_insn"
4658 [(set (match_operand:HI 0 "register_operand" "=r")
4659 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4660 (match_operand:QI 2 "register_operand" "a")]
4666 [(set_attr "length" "3")
4667 (set_attr "cc" "clobber")])
4669 (define_insn "*fmulsu.call"
4671 (unspec:HI [(reg:QI 24)
4672 (reg:QI 25)] UNSPEC_FMULSU))
4673 (clobber (reg:HI 24))]
4676 [(set_attr "type" "xcall")
4677 (set_attr "cc" "clobber")])
4680 ;; Some combiner patterns dealing with bits.
4683 ;; Move bit $3.0 into bit $0.$4
4684 (define_insn "*movbitqi.1-6.a"
4685 [(set (match_operand:QI 0 "register_operand" "=r")
4686 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4687 (match_operand:QI 2 "single_zero_operand" "n"))
4688 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
4689 (match_operand:QI 4 "const_0_to_7_operand" "n"))
4690 (match_operand:QI 5 "single_one_operand" "n"))))]
4691 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
4692 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
4693 "bst %3,0\;bld %0,%4"
4694 [(set_attr "length" "2")
4695 (set_attr "cc" "none")])
4697 ;; Move bit $3.0 into bit $0.$4
4698 ;; Variation of above. Unfortunately, there is no canonicalized representation
4699 ;; of moving around bits. So what we see here depends on how user writes down
4700 ;; bit manipulations.
4701 (define_insn "*movbitqi.1-6.b"
4702 [(set (match_operand:QI 0 "register_operand" "=r")
4703 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4704 (match_operand:QI 2 "single_zero_operand" "n"))
4705 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
4707 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
4708 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4709 "bst %3,0\;bld %0,%4"
4710 [(set_attr "length" "2")
4711 (set_attr "cc" "none")])
4713 ;; Move bit $3.0 into bit $0.0.
4714 ;; For bit 0, combiner generates slightly different pattern.
4715 (define_insn "*movbitqi.0"
4716 [(set (match_operand:QI 0 "register_operand" "=r")
4717 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4718 (match_operand:QI 2 "single_zero_operand" "n"))
4719 (and:QI (match_operand:QI 3 "register_operand" "r")
4721 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4722 "bst %3,0\;bld %0,0"
4723 [(set_attr "length" "2")
4724 (set_attr "cc" "none")])
4726 ;; Move bit $2.0 into bit $0.7.
4727 ;; For bit 7, combiner generates slightly different pattern
4728 (define_insn "*movbitqi.7"
4729 [(set (match_operand:QI 0 "register_operand" "=r")
4730 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
4732 (ashift:QI (match_operand:QI 2 "register_operand" "r")
4735 "bst %2,0\;bld %0,7"
4736 [(set_attr "length" "2")
4737 (set_attr "cc" "none")])
4739 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
4740 ;; and input/output match. We provide a special pattern for this, because
4741 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
4742 ;; operation on I/O is atomic.
4743 (define_insn "*insv.io"
4744 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
4746 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
4747 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
4752 sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
4753 [(set_attr "length" "1,1,4")
4754 (set_attr "cc" "none")])
4756 (define_insn "*insv.not.io"
4757 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4759 (match_operand:QI 1 "const_0_to_7_operand" "n"))
4760 (not:QI (match_operand:QI 2 "register_operand" "r")))]
4762 "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
4763 [(set_attr "length" "4")
4764 (set_attr "cc" "none")])
4766 ;; The insv expander.
4767 ;; We only support 1-bit inserts
4768 (define_expand "insv"
4769 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
4770 (match_operand:QI 1 "const1_operand" "") ; width
4771 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
4772 (match_operand:QI 3 "nonmemory_operand" ""))]
4776 ;; Insert bit $2.0 into $0.$1
4777 (define_insn "*insv.reg"
4778 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
4780 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
4781 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
4785 andi %0,lo8(~(1<<%1))
4789 [(set_attr "length" "2,1,1,2,2")
4790 (set_attr "cc" "none,set_zn,set_zn,none,none")])
4793 ;; Some combine patterns that try to fix bad code when a value is composed
4794 ;; from byte parts like in PR27663.
4795 ;; The patterns give some release but the code still is not optimal,
4796 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
4797 ;; That switch obfuscates things here and in many other places.
4799 (define_insn_and_split "*ior<mode>qi.byte0"
4800 [(set (match_operand:HISI 0 "register_operand" "=r")
4802 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4803 (match_operand:HISI 2 "register_operand" "0")))]
4808 (ior:QI (match_dup 3)
4811 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
4814 (define_insn_and_split "*ior<mode>qi.byte1-3"
4815 [(set (match_operand:HISI 0 "register_operand" "=r")
4817 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4818 (match_operand:QI 2 "const_8_16_24_operand" "n"))
4819 (match_operand:HISI 3 "register_operand" "0")))]
4820 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
4822 "&& reload_completed"
4824 (ior:QI (match_dup 4)
4827 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
4828 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
4831 (define_expand "extzv"
4832 [(set (match_operand:QI 0 "register_operand" "")
4833 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
4834 (match_operand:QI 2 "const1_operand" "")
4835 (match_operand:QI 3 "const_0_to_7_operand" "")))]
4839 (define_insn "*extzv"
4840 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
4841 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
4843 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
4847 mov %0,%1\;andi %0,1
4850 bst %1,%2\;clr %0\;bld %0,0"
4851 [(set_attr "length" "1,2,2,2,3")
4852 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
4854 (define_insn_and_split "*extzv.qihi1"
4855 [(set (match_operand:HI 0 "register_operand" "=r")
4856 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
4858 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
4863 (zero_extract:QI (match_dup 1)
4869 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4870 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4873 (define_insn_and_split "*extzv.qihi2"
4874 [(set (match_operand:HI 0 "register_operand" "=r")
4876 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
4878 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
4883 (zero_extract:QI (match_dup 1)
4889 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4890 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);