1 ;; -*- Mode: Scheme -*-
2 ;; Machine description for GNU compiler,
3 ;; for ATMEL AVR micro controllers.
4 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
5 ;; Free Software Foundation, Inc.
6 ;; Contributed by Denis Chertykov (denisc@overta.ru)
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;; Special characters after '%':
26 ;; A No effect (add 0).
27 ;; B Add 1 to REG number, MEM address or CONST_INT.
30 ;; j Branch condition.
31 ;; k Reverse branch condition.
32 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
33 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
34 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
35 ;; ~ Output 'r' if not AVR_MEGA.
38 ;; 0 Length of a string, see "strlenhi".
39 ;; 1 Jump by register pair Z or by table addressed by Z, see "casesi".
47 (TMP_REGNO 0) ; temporary register r0
48 (ZERO_REGNO 1) ; zero register r1
50 (UNSPEC_INDEX_JMP 1)])
52 (include "predicates.md")
53 (include "constraints.md")
55 ;; Condition code settings.
56 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
57 (const_string "none"))
59 (define_attr "type" "branch,branch1,arith,xcall"
60 (const_string "arith"))
62 (define_attr "mcu_have_movw" "yes,no"
63 (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
65 (const_string "no"))))
67 (define_attr "mcu_mega" "yes,no"
68 (const (if_then_else (symbol_ref "AVR_MEGA")
70 (const_string "no"))))
73 ;; The size of instructions in bytes.
74 ;; XXX may depend from "cc"
76 (define_attr "length" ""
77 (cond [(eq_attr "type" "branch")
78 (if_then_else (and (ge (minus (pc) (match_dup 0))
80 (le (minus (pc) (match_dup 0))
83 (if_then_else (and (ge (minus (pc) (match_dup 0))
85 (le (minus (pc) (match_dup 0))
89 (eq_attr "type" "branch1")
90 (if_then_else (and (ge (minus (pc) (match_dup 0))
92 (le (minus (pc) (match_dup 0))
95 (if_then_else (and (ge (minus (pc) (match_dup 0))
97 (le (minus (pc) (match_dup 0))
101 (eq_attr "type" "xcall")
102 (if_then_else (eq_attr "mcu_mega" "no")
108 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 1)))]
111 [(set_attr "length" "1")])
114 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 2)))]
118 [(set_attr "length" "2")])
121 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 3)))]
126 [(set_attr "length" "3")])
129 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 4)))]
135 [(set_attr "length" "4")])
138 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 5)))]
145 [(set_attr "length" "5")])
147 (define_insn "*pushqi"
148 [(set (mem:QI (post_dec (reg:HI REG_SP)))
149 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
154 [(set_attr "length" "1,1")])
157 (define_insn "*pushhi"
158 [(set (mem:HI (post_dec (reg:HI REG_SP)))
159 (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
163 push __zero_reg__\;push __zero_reg__"
164 [(set_attr "length" "2,2")])
166 (define_insn "*pushsi"
167 [(set (mem:SI (post_dec (reg:HI REG_SP)))
168 (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
171 push %D0\;push %C0\;push %B0\;push %A0
172 push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
173 [(set_attr "length" "4,4")])
175 (define_insn "*pushsf"
176 [(set (mem:SF (post_dec (reg:HI REG_SP)))
177 (match_operand:SF 0 "register_operand" "r"))]
183 [(set_attr "length" "4")])
185 ;;========================================================================
187 ;; The last alternative (any immediate constant to any register) is
188 ;; very expensive. It should be optimized by peephole2 if a scratch
189 ;; register is available, but then that register could just as well be
190 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
191 ;; are call-saved registers, and most of LD_REGS are call-used registers,
192 ;; so this may still be a win for registers live across function calls.
194 (define_expand "movqi"
195 [(set (match_operand:QI 0 "nonimmediate_operand" "")
196 (match_operand:QI 1 "general_operand" ""))]
198 "/* One of the ops has to be in a register. */
199 if (!register_operand(operand0, QImode)
200 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
201 operands[1] = copy_to_mode_reg(QImode, operand1);
204 (define_insn "*movqi"
205 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
206 (match_operand:QI 1 "general_operand" "r,i,rL,Qm,r,q,i"))]
207 "(register_operand (operands[0],QImode)
208 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
209 "* return output_movqi (insn, operands, NULL);"
210 [(set_attr "length" "1,1,5,5,1,1,4")
211 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
213 ;; This is used in peephole2 to optimize loading immediate constants
214 ;; if a scratch register from LD_REGS happens to be available.
216 (define_insn "*reload_inqi"
217 [(set (match_operand:QI 0 "register_operand" "=l")
218 (match_operand:QI 1 "immediate_operand" "i"))
219 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
223 [(set_attr "length" "2")
224 (set_attr "cc" "none")])
227 [(match_scratch:QI 2 "d")
228 (set (match_operand:QI 0 "l_register_operand" "")
229 (match_operand:QI 1 "immediate_operand" ""))]
230 "(operands[1] != const0_rtx
231 && operands[1] != const1_rtx
232 && operands[1] != constm1_rtx)"
233 [(parallel [(set (match_dup 0) (match_dup 1))
234 (clobber (match_dup 2))])]
235 "if (!avr_peep2_scratch_safe (operands[2]))
238 ;;============================================================================
239 ;; move word (16 bit)
241 (define_expand "movhi"
242 [(set (match_operand:HI 0 "nonimmediate_operand" "")
243 (match_operand:HI 1 "general_operand" ""))]
247 /* One of the ops has to be in a register. */
248 if (!register_operand(operand0, HImode)
249 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
251 operands[1] = copy_to_mode_reg(HImode, operand1);
257 [(match_scratch:QI 2 "d")
258 (set (match_operand:HI 0 "l_register_operand" "")
259 (match_operand:HI 1 "immediate_operand" ""))]
260 "(operands[1] != const0_rtx
261 && operands[1] != constm1_rtx)"
262 [(parallel [(set (match_dup 0) (match_dup 1))
263 (clobber (match_dup 2))])]
264 "if (!avr_peep2_scratch_safe (operands[2]))
267 ;; '*' because it is not used in rtl generation, only in above peephole
268 (define_insn "*reload_inhi"
269 [(set (match_operand:HI 0 "register_operand" "=r")
270 (match_operand:HI 1 "immediate_operand" "i"))
271 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
273 "* return output_reload_inhi (insn, operands, NULL);"
274 [(set_attr "length" "4")
275 (set_attr "cc" "none")])
277 (define_insn "*movhi"
278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
279 (match_operand:HI 1 "general_operand" "r,m,rL,i,i,r,q"))]
280 "(register_operand (operands[0],HImode)
281 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
282 "* return output_movhi (insn, operands, NULL);"
283 [(set_attr "length" "2,6,7,2,6,5,2")
284 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
286 ;;==========================================================================
287 ;; move double word (32 bit)
289 (define_expand "movsi"
290 [(set (match_operand:SI 0 "nonimmediate_operand" "")
291 (match_operand:SI 1 "general_operand" ""))]
295 /* One of the ops has to be in a register. */
296 if (!register_operand (operand0, SImode)
297 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
299 operands[1] = copy_to_mode_reg (SImode, operand1);
306 [(match_scratch:QI 2 "d")
307 (set (match_operand:SI 0 "l_register_operand" "")
308 (match_operand:SI 1 "immediate_operand" ""))]
309 "(operands[1] != const0_rtx
310 && operands[1] != constm1_rtx)"
311 [(parallel [(set (match_dup 0) (match_dup 1))
312 (clobber (match_dup 2))])]
313 "if (!avr_peep2_scratch_safe (operands[2]))
316 ;; '*' because it is not used in rtl generation.
317 (define_insn "*reload_insi"
318 [(set (match_operand:SI 0 "register_operand" "=r")
319 (match_operand:SI 1 "immediate_operand" "i"))
320 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
322 "* return output_reload_insisf (insn, operands, NULL);"
323 [(set_attr "length" "8")
324 (set_attr "cc" "none")])
327 (define_insn "*movsi"
328 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
329 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
330 "(register_operand (operands[0],SImode)
331 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
332 "* return output_movsisf (insn, operands, NULL);"
333 [(set_attr "length" "4,4,8,9,4,10")
334 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
336 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
337 ;; move floating point numbers (32 bit)
339 (define_expand "movsf"
340 [(set (match_operand:SF 0 "nonimmediate_operand" "")
341 (match_operand:SF 1 "general_operand" ""))]
345 /* One of the ops has to be in a register. */
346 if (!register_operand (operand1, SFmode)
347 && !register_operand (operand0, SFmode))
349 operands[1] = copy_to_mode_reg (SFmode, operand1);
353 (define_insn "*movsf"
354 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
355 (match_operand:SF 1 "general_operand" "r,G,Qm,r,F,F"))]
356 "register_operand (operands[0], SFmode)
357 || register_operand (operands[1], SFmode)"
358 "* return output_movsisf (insn, operands, NULL);"
359 [(set_attr "length" "4,4,8,9,4,10")
360 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
362 ;;=========================================================================
363 ;; move string (like memcpy)
364 ;; implement as RTL loop
366 (define_expand "movmemhi"
367 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
368 (match_operand:BLK 1 "memory_operand" ""))
369 (use (match_operand:HI 2 "const_int_operand" ""))
370 (use (match_operand:HI 3 "const_int_operand" ""))])]
375 enum machine_mode mode;
376 rtx label = gen_label_rtx ();
380 /* Copy pointers into new psuedos - they will be changed. */
381 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
382 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
384 /* Create rtx for tmp register - we use this as scratch. */
385 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
387 if (GET_CODE (operands[2]) != CONST_INT)
390 count = INTVAL (operands[2]);
394 /* Work out branch probability for latter use. */
395 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
397 /* See if constant fit 8 bits. */
398 mode = (count < 0x100) ? QImode : HImode;
399 /* Create loop counter register. */
400 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
402 /* Now create RTL code for move loop. */
403 /* Label at top of loop. */
406 /* Move one byte into scratch and inc pointer. */
407 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
408 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
410 /* Move to mem and inc pointer. */
411 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
412 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
414 /* Decrement count. */
415 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
417 /* Compare with zero and jump if not equal. */
418 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
420 /* Set jump probability based on loop count. */
421 jump = get_last_insn ();
422 REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB,
428 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
429 ;; memset (%0, %2, %1)
431 (define_expand "setmemhi"
432 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
433 (match_operand 2 "const_int_operand" ""))
434 (use (match_operand:HI 1 "const_int_operand" ""))
435 (use (match_operand:HI 3 "const_int_operand" "n"))
436 (clobber (match_scratch:HI 4 ""))
437 (clobber (match_dup 5))])]
442 enum machine_mode mode;
444 /* If value to set is not zero, use the library routine. */
445 if (operands[2] != const0_rtx)
448 if (GET_CODE (operands[1]) != CONST_INT)
451 cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
452 mode = cnt8 ? QImode : HImode;
453 operands[5] = gen_rtx_SCRATCH (mode);
454 operands[1] = copy_to_mode_reg (mode,
455 gen_int_mode (INTVAL (operands[1]), mode));
456 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
457 operands[0] = gen_rtx_MEM (BLKmode, addr0);
460 (define_insn "*clrmemqi"
461 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
463 (use (match_operand:QI 1 "register_operand" "r"))
464 (use (match_operand:QI 2 "const_int_operand" "n"))
465 (clobber (match_scratch:HI 3 "=0"))
466 (clobber (match_scratch:QI 4 "=1"))]
468 "st %a0+,__zero_reg__
471 [(set_attr "length" "3")
472 (set_attr "cc" "clobber")])
474 (define_insn "*clrmemhi"
475 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
477 (use (match_operand:HI 1 "register_operand" "!w,d"))
478 (use (match_operand:HI 2 "const_int_operand" "n,n"))
479 (clobber (match_scratch:HI 3 "=0,0"))
480 (clobber (match_scratch:HI 4 "=1,1"))]
483 if (which_alternative==0)
484 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
485 AS2 (sbiw,%A1,1) CR_TAB
488 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
489 AS2 (subi,%A1,1) CR_TAB
490 AS2 (sbci,%B1,0) CR_TAB
493 [(set_attr "length" "3,4")
494 (set_attr "cc" "clobber,clobber")])
496 (define_expand "strlenhi"
498 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
499 (match_operand:QI 2 "const_int_operand" "")
500 (match_operand:HI 3 "immediate_operand" "")]
502 (set (match_dup 4) (plus:HI (match_dup 4)
504 (set (match_operand:HI 0 "register_operand" "")
505 (minus:HI (match_dup 4)
510 if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
512 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
513 operands[1] = gen_rtx_MEM (BLKmode, addr);
515 operands[4] = gen_reg_rtx (HImode);
518 (define_insn "*strlenhi"
519 [(set (match_operand:HI 0 "register_operand" "=e")
520 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
522 (match_operand:HI 2 "immediate_operand" "i")]
528 [(set_attr "length" "3")
529 (set_attr "cc" "clobber")])
531 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
534 (define_insn "addqi3"
535 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
536 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
537 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
544 [(set_attr "length" "1,1,1,1")
545 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
548 (define_expand "addhi3"
549 [(set (match_operand:HI 0 "register_operand" "")
550 (plus:HI (match_operand:HI 1 "register_operand" "")
551 (match_operand:HI 2 "nonmemory_operand" "")))]
555 if (GET_CODE (operands[2]) == CONST_INT)
557 short tmp = INTVAL (operands[2]);
558 operands[2] = GEN_INT(tmp);
563 (define_insn "*addhi3_zero_extend"
564 [(set (match_operand:HI 0 "register_operand" "=r")
565 (plus:HI (zero_extend:HI
566 (match_operand:QI 1 "register_operand" "r"))
567 (match_operand:HI 2 "register_operand" "0")))]
570 adc %B0,__zero_reg__"
571 [(set_attr "length" "2")
572 (set_attr "cc" "set_n")])
574 (define_insn "*addhi3_zero_extend1"
575 [(set (match_operand:HI 0 "register_operand" "=r")
576 (plus:HI (match_operand:HI 1 "register_operand" "%0")
578 (match_operand:QI 2 "register_operand" "r"))))]
581 adc %B0,__zero_reg__"
582 [(set_attr "length" "2")
583 (set_attr "cc" "set_n")])
585 (define_insn "*addhi3_zero_extend2"
586 [(set (match_operand:HI 0 "register_operand" "=r")
588 (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
589 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
593 adc %B0,__zero_reg__"
594 [(set_attr "length" "3")
595 (set_attr "cc" "set_n")])
597 (define_insn "*addhi3"
598 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
600 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
601 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
604 add %A0,%A2\;adc %B0,%B2
607 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
608 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
609 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
610 [(set_attr "length" "2,1,1,2,3,3")
611 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
613 (define_insn "addsi3"
614 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
616 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
617 (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
620 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
621 adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
622 sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
623 subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
624 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
625 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
626 [(set_attr "length" "4,3,3,4,5,5")
627 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
629 (define_insn "*addsi3_zero_extend"
630 [(set (match_operand:SI 0 "register_operand" "=r")
631 (plus:SI (zero_extend:SI
632 (match_operand:QI 1 "register_operand" "r"))
633 (match_operand:SI 2 "register_operand" "0")))]
638 adc %D0,__zero_reg__"
639 [(set_attr "length" "4")
640 (set_attr "cc" "set_n")])
642 ;-----------------------------------------------------------------------------
644 (define_insn "subqi3"
645 [(set (match_operand:QI 0 "register_operand" "=r,d")
646 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
647 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
652 [(set_attr "length" "1,1")
653 (set_attr "cc" "set_czn,set_czn")])
655 (define_insn "subhi3"
656 [(set (match_operand:HI 0 "register_operand" "=r,d")
657 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
658 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
661 sub %A0,%A2\;sbc %B0,%B2
662 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
663 [(set_attr "length" "2,2")
664 (set_attr "cc" "set_czn,set_czn")])
666 (define_insn "*subhi3_zero_extend1"
667 [(set (match_operand:HI 0 "register_operand" "=r")
668 (minus:HI (match_operand:HI 1 "register_operand" "0")
670 (match_operand:QI 2 "register_operand" "r"))))]
673 sbc %B0,__zero_reg__"
674 [(set_attr "length" "2")
675 (set_attr "cc" "set_n")])
677 (define_insn "subsi3"
678 [(set (match_operand:SI 0 "register_operand" "=r,d")
679 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
680 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
683 sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
684 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
685 [(set_attr "length" "4,4")
686 (set_attr "cc" "set_czn,set_czn")])
688 (define_insn "*subsi3_zero_extend"
689 [(set (match_operand:SI 0 "register_operand" "=r")
690 (minus:SI (match_operand:SI 1 "register_operand" "0")
692 (match_operand:QI 2 "register_operand" "r"))))]
697 sbc %D0,__zero_reg__"
698 [(set_attr "length" "4")
699 (set_attr "cc" "set_n")])
701 ;******************************************************************************
704 (define_expand "mulqi3"
705 [(set (match_operand:QI 0 "register_operand" "")
706 (mult:QI (match_operand:QI 1 "register_operand" "")
707 (match_operand:QI 2 "register_operand" "")))]
712 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
717 (define_insn "*mulqi3_enh"
718 [(set (match_operand:QI 0 "register_operand" "=r")
719 (mult:QI (match_operand:QI 1 "register_operand" "r")
720 (match_operand:QI 2 "register_operand" "r")))]
725 [(set_attr "length" "3")
726 (set_attr "cc" "clobber")])
728 (define_expand "mulqi3_call"
729 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
730 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
731 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
732 (clobber (reg:QI 22))])
733 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
737 (define_insn "*mulqi3_call"
738 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
739 (clobber (reg:QI 22))]
742 [(set_attr "type" "xcall")
743 (set_attr "cc" "clobber")])
745 (define_insn "mulqihi3"
746 [(set (match_operand:HI 0 "register_operand" "=r")
747 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
748 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
753 [(set_attr "length" "3")
754 (set_attr "cc" "clobber")])
756 (define_insn "umulqihi3"
757 [(set (match_operand:HI 0 "register_operand" "=r")
758 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
759 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
764 [(set_attr "length" "3")
765 (set_attr "cc" "clobber")])
767 (define_expand "mulhi3"
768 [(set (match_operand:HI 0 "register_operand" "")
769 (mult:HI (match_operand:HI 1 "register_operand" "")
770 (match_operand:HI 2 "register_operand" "")))]
776 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
781 (define_insn "*mulhi3_enh"
782 [(set (match_operand:HI 0 "register_operand" "=&r")
783 (mult:HI (match_operand:HI 1 "register_operand" "r")
784 (match_operand:HI 2 "register_operand" "r")))]
793 [(set_attr "length" "7")
794 (set_attr "cc" "clobber")])
796 (define_expand "mulhi3_call"
797 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
798 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
799 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
800 (clobber (reg:HI 22))
801 (clobber (reg:QI 21))])
802 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
806 (define_insn "*mulhi3_call"
807 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
808 (clobber (reg:HI 22))
809 (clobber (reg:QI 21))]
812 [(set_attr "type" "xcall")
813 (set_attr "cc" "clobber")])
815 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
816 ;; All call-used registers clobbered otherwise - normal library call.
817 (define_expand "mulsi3"
818 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
819 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
820 (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
821 (clobber (reg:HI 26))
822 (clobber (reg:HI 30))])
823 (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
827 (define_insn "*mulsi3_call"
828 [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
829 (clobber (reg:HI 26))
830 (clobber (reg:HI 30))]
833 [(set_attr "type" "xcall")
834 (set_attr "cc" "clobber")])
836 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
839 ;; Generate libgcc.S calls ourselves, because:
840 ;; - we know exactly which registers are clobbered (for QI and HI
841 ;; modes, some of the call-used registers are preserved)
842 ;; - we get both the quotient and the remainder at no extra cost
844 (define_expand "divmodqi4"
845 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
846 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
847 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
848 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
849 (clobber (reg:QI 22))
850 (clobber (reg:QI 23))])
851 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
852 (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
856 (define_insn "*divmodqi4_call"
857 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
858 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
859 (clobber (reg:QI 22))
860 (clobber (reg:QI 23))]
863 [(set_attr "type" "xcall")
864 (set_attr "cc" "clobber")])
866 (define_expand "udivmodqi4"
867 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
868 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
869 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
870 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
871 (clobber (reg:QI 23))])
872 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
873 (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
877 (define_insn "*udivmodqi4_call"
878 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
879 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
880 (clobber (reg:QI 23))]
882 "%~call __udivmodqi4"
883 [(set_attr "type" "xcall")
884 (set_attr "cc" "clobber")])
886 (define_expand "divmodhi4"
887 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
888 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
889 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
890 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
891 (clobber (reg:HI 26))
892 (clobber (reg:QI 21))])
893 (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
894 (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
898 (define_insn "*divmodhi4_call"
899 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
900 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
901 (clobber (reg:HI 26))
902 (clobber (reg:QI 21))]
905 [(set_attr "type" "xcall")
906 (set_attr "cc" "clobber")])
908 (define_expand "udivmodhi4"
909 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
910 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
911 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
912 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
913 (clobber (reg:HI 26))
914 (clobber (reg:QI 21))])
915 (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
916 (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
920 (define_insn "*udivmodhi4_call"
921 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
922 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
923 (clobber (reg:HI 26))
924 (clobber (reg:QI 21))]
926 "%~call __udivmodhi4"
927 [(set_attr "type" "xcall")
928 (set_attr "cc" "clobber")])
930 (define_expand "divmodsi4"
931 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
932 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
933 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
934 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
935 (clobber (reg:HI 26))
936 (clobber (reg:HI 30))])
937 (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
938 (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
942 (define_insn "*divmodsi4_call"
943 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
944 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
945 (clobber (reg:HI 26))
946 (clobber (reg:HI 30))]
949 [(set_attr "type" "xcall")
950 (set_attr "cc" "clobber")])
952 (define_expand "udivmodsi4"
953 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
954 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
955 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
956 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
957 (clobber (reg:HI 26))
958 (clobber (reg:HI 30))])
959 (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
960 (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
964 (define_insn "*udivmodsi4_call"
965 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
966 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
967 (clobber (reg:HI 26))
968 (clobber (reg:HI 30))]
970 "%~call __udivmodsi4"
971 [(set_attr "type" "xcall")
972 (set_attr "cc" "clobber")])
974 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
977 (define_insn "andqi3"
978 [(set (match_operand:QI 0 "register_operand" "=r,d")
979 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
980 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
985 [(set_attr "length" "1,1")
986 (set_attr "cc" "set_zn,set_zn")])
988 (define_insn "andhi3"
989 [(set (match_operand:HI 0 "register_operand" "=r,d,r")
990 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
991 (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
992 (clobber (match_scratch:QI 3 "=X,X,&d"))]
995 if (which_alternative==0)
996 return (AS2 (and,%A0,%A2) CR_TAB
998 else if (which_alternative==1)
1000 if (GET_CODE (operands[2]) == CONST_INT)
1002 int mask = INTVAL (operands[2]);
1003 if ((mask & 0xff) != 0xff)
1004 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1005 if ((mask & 0xff00) != 0xff00)
1006 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1009 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1010 AS2 (andi,%B0,hi8(%2)));
1012 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1013 AS2 (and,%A0,%3) CR_TAB
1016 [(set_attr "length" "2,2,3")
1017 (set_attr "cc" "set_n,clobber,set_n")])
1019 (define_insn "andsi3"
1020 [(set (match_operand:SI 0 "register_operand" "=r,d")
1021 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1022 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1025 if (which_alternative==0)
1026 return (AS2 (and, %0,%2) CR_TAB
1027 AS2 (and, %B0,%B2) CR_TAB
1028 AS2 (and, %C0,%C2) CR_TAB
1029 AS2 (and, %D0,%D2));
1030 else if (which_alternative==1)
1032 if (GET_CODE (operands[2]) == CONST_INT)
1034 HOST_WIDE_INT mask = INTVAL (operands[2]);
1035 if ((mask & 0xff) != 0xff)
1036 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1037 if ((mask & 0xff00) != 0xff00)
1038 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1039 if ((mask & 0xff0000L) != 0xff0000L)
1040 output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1041 if ((mask & 0xff000000L) != 0xff000000L)
1042 output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1045 return (AS2 (andi, %A0,lo8(%2)) CR_TAB
1046 AS2 (andi, %B0,hi8(%2)) CR_TAB
1047 AS2 (andi, %C0,hlo8(%2)) CR_TAB
1048 AS2 (andi, %D0,hhi8(%2)));
1052 [(set_attr "length" "4,4")
1053 (set_attr "cc" "set_n,set_n")])
1055 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1058 (define_insn "iorqi3"
1059 [(set (match_operand:QI 0 "register_operand" "=r,d")
1060 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1061 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1066 [(set_attr "length" "1,1")
1067 (set_attr "cc" "set_zn,set_zn")])
1069 (define_insn "iorhi3"
1070 [(set (match_operand:HI 0 "register_operand" "=r,d")
1071 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1072 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1075 if (which_alternative==0)
1076 return (AS2 (or,%A0,%A2) CR_TAB
1078 if (GET_CODE (operands[2]) == CONST_INT)
1080 int mask = INTVAL (operands[2]);
1082 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1084 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1087 return (AS2 (ori,%0,lo8(%2)) CR_TAB
1088 AS2 (ori,%B0,hi8(%2)));
1090 [(set_attr "length" "2,2")
1091 (set_attr "cc" "set_n,clobber")])
1093 (define_insn "*iorhi3_clobber"
1094 [(set (match_operand:HI 0 "register_operand" "=r,r")
1095 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1096 (match_operand:HI 2 "immediate_operand" "M,i")))
1097 (clobber (match_scratch:QI 3 "=&d,&d"))]
1100 ldi %3,lo8(%2)\;or %A0,%3
1101 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1102 [(set_attr "length" "2,4")
1103 (set_attr "cc" "clobber,set_n")])
1105 (define_insn "iorsi3"
1106 [(set (match_operand:SI 0 "register_operand" "=r,d")
1107 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1108 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1111 if (which_alternative==0)
1112 return (AS2 (or, %0,%2) CR_TAB
1113 AS2 (or, %B0,%B2) CR_TAB
1114 AS2 (or, %C0,%C2) CR_TAB
1116 if (GET_CODE (operands[2]) == CONST_INT)
1118 HOST_WIDE_INT mask = INTVAL (operands[2]);
1120 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1122 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1123 if (mask & 0xff0000L)
1124 output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1125 if (mask & 0xff000000L)
1126 output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1129 return (AS2 (ori, %A0,lo8(%2)) CR_TAB
1130 AS2 (ori, %B0,hi8(%2)) CR_TAB
1131 AS2 (ori, %C0,hlo8(%2)) CR_TAB
1132 AS2 (ori, %D0,hhi8(%2)));
1134 [(set_attr "length" "4,4")
1135 (set_attr "cc" "set_n,clobber")])
1137 (define_insn "*iorsi3_clobber"
1138 [(set (match_operand:SI 0 "register_operand" "=r,r")
1139 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1140 (match_operand:SI 2 "immediate_operand" "M,i")))
1141 (clobber (match_scratch:QI 3 "=&d,&d"))]
1144 ldi %3,lo8(%2)\;or %A0,%3
1145 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3"
1146 [(set_attr "length" "2,8")
1147 (set_attr "cc" "clobber,set_n")])
1149 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1152 (define_insn "xorqi3"
1153 [(set (match_operand:QI 0 "register_operand" "=r")
1154 (xor:QI (match_operand:QI 1 "register_operand" "%0")
1155 (match_operand:QI 2 "register_operand" "r")))]
1158 [(set_attr "length" "1")
1159 (set_attr "cc" "set_zn")])
1161 (define_insn "xorhi3"
1162 [(set (match_operand:HI 0 "register_operand" "=r")
1163 (xor:HI (match_operand:HI 1 "register_operand" "%0")
1164 (match_operand:HI 2 "register_operand" "r")))]
1168 [(set_attr "length" "2")
1169 (set_attr "cc" "set_n")])
1171 (define_insn "xorsi3"
1172 [(set (match_operand:SI 0 "register_operand" "=r")
1173 (xor:SI (match_operand:SI 1 "register_operand" "%0")
1174 (match_operand:SI 2 "register_operand" "r")))]
1180 [(set_attr "length" "4")
1181 (set_attr "cc" "set_n")])
1183 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1184 ;; arithmetic shift left
1186 (define_insn "ashlqi3"
1187 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
1188 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1189 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
1191 "* return ashlqi3_out (insn, operands, NULL);"
1192 [(set_attr "length" "5,0,1,2,4,6,9")
1193 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1195 (define_insn "ashlhi3"
1196 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
1197 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1198 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1200 "* return ashlhi3_out (insn, operands, NULL);"
1201 [(set_attr "length" "6,0,2,2,4,10,10")
1202 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1204 (define_insn "ashlsi3"
1205 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
1206 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1207 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1209 "* return ashlsi3_out (insn, operands, NULL);"
1210 [(set_attr "length" "8,0,4,4,8,10,12")
1211 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1213 ;; Optimize if a scratch register from LD_REGS happens to be available.
1216 [(match_scratch:QI 3 "d")
1217 (set (match_operand:HI 0 "register_operand" "")
1218 (ashift:HI (match_operand:HI 1 "register_operand" "")
1219 (match_operand:QI 2 "const_int_operand" "")))]
1221 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1222 (clobber (match_dup 3))])]
1223 "if (!avr_peep2_scratch_safe (operands[3]))
1226 (define_insn "*ashlhi3_const"
1227 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1228 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
1229 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1230 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1232 "* return ashlhi3_out (insn, operands, NULL);"
1233 [(set_attr "length" "0,2,2,4,10")
1234 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
1237 [(match_scratch:QI 3 "d")
1238 (set (match_operand:SI 0 "register_operand" "")
1239 (ashift:SI (match_operand:SI 1 "register_operand" "")
1240 (match_operand:QI 2 "const_int_operand" "")))]
1242 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1243 (clobber (match_dup 3))])]
1244 "if (!avr_peep2_scratch_safe (operands[3]))
1247 (define_insn "*ashlsi3_const"
1248 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1249 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
1250 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1251 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1253 "* return ashlsi3_out (insn, operands, NULL);"
1254 [(set_attr "length" "0,4,4,10")
1255 (set_attr "cc" "none,set_n,clobber,clobber")])
1257 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1258 ;; arithmetic shift right
1260 (define_insn "ashrqi3"
1261 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1262 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1263 (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))]
1265 "* return ashrqi3_out (insn, operands, NULL);"
1266 [(set_attr "length" "5,0,1,2,5,9")
1267 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
1269 (define_insn "ashrhi3"
1270 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
1271 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1272 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1274 "* return ashrhi3_out (insn, operands, NULL);"
1275 [(set_attr "length" "6,0,2,4,4,10,10")
1276 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1278 (define_insn "ashrsi3"
1279 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
1280 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1281 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1283 "* return ashrsi3_out (insn, operands, NULL);"
1284 [(set_attr "length" "8,0,4,6,8,10,12")
1285 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1287 ;; Optimize if a scratch register from LD_REGS happens to be available.
1290 [(match_scratch:QI 3 "d")
1291 (set (match_operand:HI 0 "register_operand" "")
1292 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1293 (match_operand:QI 2 "const_int_operand" "")))]
1295 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1296 (clobber (match_dup 3))])]
1297 "if (!avr_peep2_scratch_safe (operands[3]))
1300 (define_insn "*ashrhi3_const"
1301 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1302 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
1303 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1304 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1306 "* return ashrhi3_out (insn, operands, NULL);"
1307 [(set_attr "length" "0,2,4,4,10")
1308 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
1311 [(match_scratch:QI 3 "d")
1312 (set (match_operand:SI 0 "register_operand" "")
1313 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1314 (match_operand:QI 2 "const_int_operand" "")))]
1316 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1317 (clobber (match_dup 3))])]
1318 "if (!avr_peep2_scratch_safe (operands[3]))
1321 (define_insn "*ashrsi3_const"
1322 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1323 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
1324 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1325 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1327 "* return ashrsi3_out (insn, operands, NULL);"
1328 [(set_attr "length" "0,4,4,10")
1329 (set_attr "cc" "none,clobber,set_n,clobber")])
1331 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1332 ;; logical shift right
1334 (define_insn "lshrqi3"
1335 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
1336 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1337 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
1339 "* return lshrqi3_out (insn, operands, NULL);"
1340 [(set_attr "length" "5,0,1,2,4,6,9")
1341 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1343 (define_insn "lshrhi3"
1344 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
1345 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1346 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1348 "* return lshrhi3_out (insn, operands, NULL);"
1349 [(set_attr "length" "6,0,2,2,4,10,10")
1350 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1352 (define_insn "lshrsi3"
1353 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
1354 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1355 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1357 "* return lshrsi3_out (insn, operands, NULL);"
1358 [(set_attr "length" "8,0,4,4,8,10,12")
1359 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1361 ;; Optimize if a scratch register from LD_REGS happens to be available.
1364 [(match_scratch:QI 3 "d")
1365 (set (match_operand:HI 0 "register_operand" "")
1366 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1367 (match_operand:QI 2 "const_int_operand" "")))]
1369 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1370 (clobber (match_dup 3))])]
1371 "if (!avr_peep2_scratch_safe (operands[3]))
1374 (define_insn "*lshrhi3_const"
1375 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1376 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
1377 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1378 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1380 "* return lshrhi3_out (insn, operands, NULL);"
1381 [(set_attr "length" "0,2,2,4,10")
1382 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
1385 [(match_scratch:QI 3 "d")
1386 (set (match_operand:SI 0 "register_operand" "")
1387 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1388 (match_operand:QI 2 "const_int_operand" "")))]
1390 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1391 (clobber (match_dup 3))])]
1392 "if (!avr_peep2_scratch_safe (operands[3]))
1395 (define_insn "*lshrsi3_const"
1396 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1397 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
1398 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1399 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1401 "* return lshrsi3_out (insn, operands, NULL);"
1402 [(set_attr "length" "0,4,4,10")
1403 (set_attr "cc" "none,clobber,clobber,clobber")])
1405 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
1408 (define_insn "absqi2"
1409 [(set (match_operand:QI 0 "register_operand" "=r")
1410 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
1414 [(set_attr "length" "2")
1415 (set_attr "cc" "clobber")])
1418 (define_insn "abssf2"
1419 [(set (match_operand:SF 0 "register_operand" "=d,r")
1420 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
1425 [(set_attr "length" "1,2")
1426 (set_attr "cc" "set_n,clobber")])
1428 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
1431 (define_insn "negqi2"
1432 [(set (match_operand:QI 0 "register_operand" "=r")
1433 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1436 [(set_attr "length" "1")
1437 (set_attr "cc" "set_zn")])
1439 (define_insn "neghi2"
1440 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
1441 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
1444 com %B0\;neg %A0\;sbci %B0,lo8(-1)
1445 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
1446 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
1447 [(set_attr "length" "3,4,4")
1448 (set_attr "cc" "set_czn,set_n,set_czn")])
1450 (define_insn "negsi2"
1451 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
1452 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
1455 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
1456 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1457 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1458 [(set_attr_alternative "length"
1461 (if_then_else (eq_attr "mcu_have_movw" "yes")
1464 (set_attr "cc" "set_czn,set_n,set_czn")])
1466 (define_insn "negsf2"
1467 [(set (match_operand:SF 0 "register_operand" "=d,r")
1468 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
1472 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
1473 [(set_attr "length" "1,4")
1474 (set_attr "cc" "set_n,set_n")])
1476 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1479 (define_insn "one_cmplqi2"
1480 [(set (match_operand:QI 0 "register_operand" "=r")
1481 (not:QI (match_operand:QI 1 "register_operand" "0")))]
1484 [(set_attr "length" "1")
1485 (set_attr "cc" "set_czn")])
1487 (define_insn "one_cmplhi2"
1488 [(set (match_operand:HI 0 "register_operand" "=r")
1489 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1493 [(set_attr "length" "2")
1494 (set_attr "cc" "set_n")])
1496 (define_insn "one_cmplsi2"
1497 [(set (match_operand:SI 0 "register_operand" "=r")
1498 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1504 [(set_attr "length" "4")
1505 (set_attr "cc" "set_n")])
1507 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1510 (define_insn "extendqihi2"
1511 [(set (match_operand:HI 0 "register_operand" "=r,r")
1512 (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1515 clr %B0\;sbrc %0,7\;com %B0
1516 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
1517 [(set_attr "length" "3,4")
1518 (set_attr "cc" "set_n,set_n")])
1520 (define_insn "extendqisi2"
1521 [(set (match_operand:SI 0 "register_operand" "=r,r")
1522 (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1525 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
1526 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
1527 [(set_attr "length" "5,6")
1528 (set_attr "cc" "set_n,set_n")])
1530 (define_insn "extendhisi2"
1531 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1532 (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1535 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
1536 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
1537 [(set_attr_alternative "length"
1539 (if_then_else (eq_attr "mcu_have_movw" "yes")
1542 (set_attr "cc" "set_n,set_n")])
1544 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1547 (define_insn "zero_extendqihi2"
1548 [(set (match_operand:HI 0 "register_operand" "=r,r")
1549 (zero_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1553 mov %A0,%A1\;clr %B0"
1554 [(set_attr "length" "1,2")
1555 (set_attr "cc" "set_n,set_n")])
1557 (define_insn "zero_extendqisi2"
1558 [(set (match_operand:SI 0 "register_operand" "=r,r")
1559 (zero_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1562 clr %B0\;clr %C0\;clr %D0
1563 mov %A0,%A1\;clr %B0\;clr %C0\;clr %D0"
1564 [(set_attr "length" "3,4")
1565 (set_attr "cc" "set_n,set_n")])
1567 (define_insn "zero_extendhisi2"
1568 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1569 (zero_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1573 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;clr %D0"
1574 [(set_attr_alternative "length"
1576 (if_then_else (eq_attr "mcu_have_movw" "yes")
1579 (set_attr "cc" "set_n,set_n")])
1581 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
1584 (define_insn "tstqi"
1586 (match_operand:QI 0 "register_operand" "r"))]
1589 [(set_attr "cc" "compare")
1590 (set_attr "length" "1")])
1592 (define_insn "*negated_tstqi"
1594 (neg:QI (match_operand:QI 0 "register_operand" "r")))]
1596 "cp __zero_reg__,%0"
1597 [(set_attr "cc" "compare")
1598 (set_attr "length" "1")])
1600 (define_insn "tsthi"
1602 (match_operand:HI 0 "register_operand" "!w,r"))]
1604 "* return out_tsthi (insn,NULL);"
1605 [(set_attr "cc" "compare,compare")
1606 (set_attr "length" "1,2")])
1608 (define_insn "*negated_tsthi"
1610 (neg:HI (match_operand:HI 0 "register_operand" "r")))]
1612 "cp __zero_reg__,%A0
1613 cpc __zero_reg__,%B0"
1614 [(set_attr "cc" "compare")
1615 (set_attr "length" "2")])
1617 (define_insn "tstsi"
1619 (match_operand:SI 0 "register_operand" "r"))]
1621 "* return out_tstsi (insn,NULL);"
1622 [(set_attr "cc" "compare")
1623 (set_attr "length" "4")])
1625 (define_insn "*negated_tstsi"
1627 (neg:SI (match_operand:SI 0 "register_operand" "r")))]
1629 "cp __zero_reg__,%A0
1630 cpc __zero_reg__,%B0
1631 cpc __zero_reg__,%C0
1632 cpc __zero_reg__,%D0"
1633 [(set_attr "cc" "compare")
1634 (set_attr "length" "4")])
1637 (define_insn "cmpqi"
1639 (compare (match_operand:QI 0 "register_operand" "r,d")
1640 (match_operand:QI 1 "nonmemory_operand" "r,i")))]
1645 [(set_attr "cc" "compare,compare")
1646 (set_attr "length" "1,1")])
1648 (define_insn "*cmpqi_sign_extend"
1650 (compare (sign_extend:HI
1651 (match_operand:QI 0 "register_operand" "d"))
1652 (match_operand:HI 1 "const_int_operand" "n")))]
1653 "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
1655 [(set_attr "cc" "compare")
1656 (set_attr "length" "1")])
1658 (define_insn "cmphi"
1660 (compare (match_operand:HI 0 "register_operand" "r,d,d,r,r")
1661 (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
1662 (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1665 switch (which_alternative)
1668 return (AS2 (cp,%A0,%A1) CR_TAB
1671 if (reg_unused_after (insn, operands[0])
1672 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1673 && test_hard_reg_class (ADDW_REGS, operands[0]))
1674 return AS2 (sbiw,%0,%1);
1676 return (AS2 (cpi,%0,%1) CR_TAB
1677 AS2 (cpc,%B0,__zero_reg__));
1679 if (reg_unused_after (insn, operands[0]))
1680 return (AS2 (subi,%0,lo8(%1)) CR_TAB
1681 AS2 (sbci,%B0,hi8(%1)));
1683 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
1684 AS2 (cpi, %A0,lo8(%1)) CR_TAB
1687 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1688 AS2 (cp, %A0,%2) CR_TAB
1689 AS2 (cpc, %B0,__zero_reg__));
1692 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1693 AS2 (cp, %A0,%2) CR_TAB
1694 AS2 (ldi, %2,hi8(%1)) CR_TAB
1699 [(set_attr "cc" "compare,compare,compare,compare,compare")
1700 (set_attr "length" "2,2,3,3,4")])
1703 (define_insn "cmpsi"
1705 (compare (match_operand:SI 0 "register_operand" "r,d,d,r,r")
1706 (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
1707 (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1710 switch (which_alternative)
1713 return (AS2 (cp,%A0,%A1) CR_TAB
1714 AS2 (cpc,%B0,%B1) CR_TAB
1715 AS2 (cpc,%C0,%C1) CR_TAB
1718 if (reg_unused_after (insn, operands[0])
1719 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1720 && test_hard_reg_class (ADDW_REGS, operands[0]))
1721 return (AS2 (sbiw,%0,%1) CR_TAB
1722 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1723 AS2 (cpc,%D0,__zero_reg__));
1725 return (AS2 (cpi,%A0,lo8(%1)) CR_TAB
1726 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1727 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1728 AS2 (cpc,%D0,__zero_reg__));
1730 if (reg_unused_after (insn, operands[0]))
1731 return (AS2 (subi,%A0,lo8(%1)) CR_TAB
1732 AS2 (sbci,%B0,hi8(%1)) CR_TAB
1733 AS2 (sbci,%C0,hlo8(%1)) CR_TAB
1734 AS2 (sbci,%D0,hhi8(%1)));
1736 return (AS2 (cpi, %A0,lo8(%1)) CR_TAB
1737 AS2 (ldi, %2,hi8(%1)) CR_TAB
1738 AS2 (cpc, %B0,%2) CR_TAB
1739 AS2 (ldi, %2,hlo8(%1)) CR_TAB
1740 AS2 (cpc, %C0,%2) CR_TAB
1741 AS2 (ldi, %2,hhi8(%1)) CR_TAB
1744 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
1745 AS2 (cp,%A0,%2) CR_TAB
1746 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1747 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1748 AS2 (cpc,%D0,__zero_reg__));
1750 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1751 AS2 (cp, %A0,%2) CR_TAB
1752 AS2 (ldi, %2,hi8(%1)) CR_TAB
1753 AS2 (cpc, %B0,%2) CR_TAB
1754 AS2 (ldi, %2,hlo8(%1)) CR_TAB
1755 AS2 (cpc, %C0,%2) CR_TAB
1756 AS2 (ldi, %2,hhi8(%1)) CR_TAB
1761 [(set_attr "cc" "compare,compare,compare,compare,compare")
1762 (set_attr "length" "4,4,7,5,8")])
1764 ;; ----------------------------------------------------------------------
1765 ;; JUMP INSTRUCTIONS
1766 ;; ----------------------------------------------------------------------
1767 ;; Conditional jump instructions
1769 (define_expand "beq"
1771 (if_then_else (eq (cc0) (const_int 0))
1772 (label_ref (match_operand 0 "" ""))
1777 (define_expand "bne"
1779 (if_then_else (ne (cc0) (const_int 0))
1780 (label_ref (match_operand 0 "" ""))
1785 (define_expand "bge"
1787 (if_then_else (ge (cc0) (const_int 0))
1788 (label_ref (match_operand 0 "" ""))
1793 (define_expand "bgeu"
1795 (if_then_else (geu (cc0) (const_int 0))
1796 (label_ref (match_operand 0 "" ""))
1801 (define_expand "blt"
1803 (if_then_else (lt (cc0) (const_int 0))
1804 (label_ref (match_operand 0 "" ""))
1809 (define_expand "bltu"
1811 (if_then_else (ltu (cc0) (const_int 0))
1812 (label_ref (match_operand 0 "" ""))
1819 /****************************************************************
1820 AVR not have following conditional jumps: LE,LEU,GT,GTU.
1821 Convert them all to proper jumps.
1822 *****************************************************************/
1824 (define_expand "ble"
1826 (if_then_else (le (cc0) (const_int 0))
1827 (label_ref (match_operand 0 "" ""))
1832 (define_expand "bleu"
1834 (if_then_else (leu (cc0) (const_int 0))
1835 (label_ref (match_operand 0 "" ""))
1840 (define_expand "bgt"
1842 (if_then_else (gt (cc0) (const_int 0))
1843 (label_ref (match_operand 0 "" ""))
1848 (define_expand "bgtu"
1850 (if_then_else (gtu (cc0) (const_int 0))
1851 (label_ref (match_operand 0 "" ""))
1856 ;; Test a single bit in a QI/HI/SImode register.
1857 (define_insn "*sbrx_branch"
1860 (match_operator 0 "eqne_operator"
1862 (match_operand:QI 1 "register_operand" "r")
1864 (match_operand 2 "const_int_operand" "n"))
1866 (label_ref (match_operand 3 "" ""))
1869 "* return avr_out_sbxx_branch (insn, operands);"
1870 [(set (attr "length")
1871 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1872 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1874 (if_then_else (eq_attr "mcu_mega" "no")
1877 (set_attr "cc" "clobber")])
1879 (define_insn "*sbrx_and_branchhi"
1882 (match_operator 0 "eqne_operator"
1884 (match_operand:HI 1 "register_operand" "r")
1885 (match_operand:HI 2 "single_one_operand" "n"))
1887 (label_ref (match_operand 3 "" ""))
1890 "* return avr_out_sbxx_branch (insn, operands);"
1891 [(set (attr "length")
1892 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1893 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1895 (if_then_else (eq_attr "mcu_mega" "no")
1898 (set_attr "cc" "clobber")])
1900 (define_insn "*sbrx_and_branchsi"
1903 (match_operator 0 "eqne_operator"
1905 (match_operand:SI 1 "register_operand" "r")
1906 (match_operand:SI 2 "single_one_operand" "n"))
1908 (label_ref (match_operand 3 "" ""))
1911 "* return avr_out_sbxx_branch (insn, operands);"
1912 [(set (attr "length")
1913 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1914 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1916 (if_then_else (eq_attr "mcu_mega" "no")
1919 (set_attr "cc" "clobber")])
1921 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
1923 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1924 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1925 (label_ref (match_operand 1 "" ""))
1928 [(set (pc) (if_then_else (eq (zero_extract (match_dup 0)
1932 (label_ref (match_dup 1))
1937 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1938 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1939 (label_ref (match_operand 1 "" ""))
1942 [(set (pc) (if_then_else (ne (zero_extract (match_dup 0)
1946 (label_ref (match_dup 1))
1951 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1952 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1953 (label_ref (match_operand 1 "" ""))
1956 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
1958 (label_ref (match_dup 1))
1963 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1964 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1965 (label_ref (match_operand 1 "" ""))
1968 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
1970 (label_ref (match_dup 1))
1975 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1976 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1977 (label_ref (match_operand 1 "" ""))
1980 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
1982 (label_ref (match_dup 1))
1984 "operands[2] = GEN_INT (-2147483647 - 1);")
1987 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1988 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1989 (label_ref (match_operand 1 "" ""))
1992 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
1994 (label_ref (match_dup 1))
1996 "operands[2] = GEN_INT (-2147483647 - 1);")
1998 ;; ************************************************************************
1999 ;; Implementation of conditional jumps here.
2000 ;; Compare with 0 (test) jumps
2001 ;; ************************************************************************
2003 (define_insn "branch"
2005 (if_then_else (match_operator 1 "simple_comparison_operator"
2008 (label_ref (match_operand 0 "" ""))
2012 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2013 [(set_attr "type" "branch")
2014 (set_attr "cc" "clobber")])
2016 (define_insn "difficult_branch"
2018 (if_then_else (match_operator 1 "difficult_comparison_operator"
2021 (label_ref (match_operand 0 "" ""))
2025 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2026 [(set_attr "type" "branch1")
2027 (set_attr "cc" "clobber")])
2031 (define_insn "rvbranch"
2033 (if_then_else (match_operator 1 "simple_comparison_operator"
2037 (label_ref (match_operand 0 "" ""))))]
2040 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2041 [(set_attr "type" "branch1")
2042 (set_attr "cc" "clobber")])
2044 (define_insn "difficult_rvbranch"
2046 (if_then_else (match_operator 1 "difficult_comparison_operator"
2050 (label_ref (match_operand 0 "" ""))))]
2053 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2054 [(set_attr "type" "branch")
2055 (set_attr "cc" "clobber")])
2057 ;; **************************************************************************
2058 ;; Unconditional and other jump instructions.
2062 (label_ref (match_operand 0 "" "")))]
2065 if (AVR_MEGA && get_attr_length (insn) != 1)
2066 return AS1 (jmp,%0);
2067 return AS1 (rjmp,%0);
2069 [(set (attr "length")
2070 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2071 (le (minus (pc) (match_dup 0)) (const_int 2047)))
2074 (set_attr "cc" "none")])
2078 (define_expand "call"
2079 [(call (match_operand:HI 0 "call_insn_operand" "")
2080 (match_operand:HI 1 "general_operand" ""))]
2081 ;; Operand 1 not used on the AVR.
2087 (define_expand "call_value"
2088 [(set (match_operand 0 "register_operand" "")
2089 (call (match_operand:HI 1 "call_insn_operand" "")
2090 (match_operand:HI 2 "general_operand" "")))]
2091 ;; Operand 2 not used on the AVR.
2095 (define_insn "call_insn"
2096 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,s,n"))
2097 (match_operand:HI 1 "general_operand" "X,X,X,X"))]
2098 ;; We don't need in saving Z register because r30,r31 is a call used registers
2099 ;; Operand 1 not used on the AVR.
2100 "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
2102 if (which_alternative==0)
2104 else if (which_alternative==1)
2107 return (AS2 (movw, r30, %0) CR_TAB
2110 return (AS2 (mov, r30, %A0) CR_TAB
2111 AS2 (mov, r31, %B0) CR_TAB
2114 else if (which_alternative==2)
2115 return AS1(%~call,%c0);
2116 return (AS2 (ldi,r30,lo8(%0)) CR_TAB
2117 AS2 (ldi,r31,hi8(%0)) CR_TAB
2120 [(set_attr "cc" "clobber,clobber,clobber,clobber")
2121 (set_attr_alternative "length"
2123 (if_then_else (eq_attr "mcu_have_movw" "yes")
2126 (if_then_else (eq_attr "mcu_mega" "yes")
2131 (define_insn "call_value_insn"
2132 [(set (match_operand 0 "register_operand" "=r,r,r,r")
2133 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,s,n"))
2134 ;; We don't need in saving Z register because r30,r31 is a call used registers
2135 (match_operand:HI 2 "general_operand" "X,X,X,X")))]
2136 ;; Operand 2 not used on the AVR.
2137 "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
2139 if (which_alternative==0)
2141 else if (which_alternative==1)
2144 return (AS2 (movw, r30, %1) CR_TAB
2147 return (AS2 (mov, r30, %A1) CR_TAB
2148 AS2 (mov, r31, %B1) CR_TAB
2151 else if (which_alternative==2)
2152 return AS1(%~call,%c1);
2153 return (AS2 (ldi, r30, lo8(%1)) CR_TAB
2154 AS2 (ldi, r31, hi8(%1)) CR_TAB
2157 [(set_attr "cc" "clobber,clobber,clobber,clobber")
2158 (set_attr_alternative "length"
2160 (if_then_else (eq_attr "mcu_have_movw" "yes")
2163 (if_then_else (eq_attr "mcu_mega" "yes")
2168 (define_insn "return"
2170 "reload_completed && avr_simple_epilogue ()"
2172 [(set_attr "cc" "none")
2173 (set_attr "length" "1")])
2179 [(set_attr "cc" "none")
2180 (set_attr "length" "1")])
2183 (define_insn "indirect_jump"
2184 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2188 push %A0\;push %B0\;ret"
2189 [(set_attr "length" "1,3")
2190 (set_attr "cc" "none,none")])
2194 ;; Table made from "rjmp" instructions for <=8K devices.
2195 (define_insn "*tablejump_rjmp"
2196 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
2198 (use (label_ref (match_operand 1 "" "")))
2199 (clobber (match_dup 0))]
2203 push %A0\;push %B0\;ret"
2204 [(set_attr "length" "1,3")
2205 (set_attr "cc" "none,none")])
2207 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2208 (define_insn "*tablejump_lib"
2209 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2211 (use (label_ref (match_operand 1 "" "")))
2212 (clobber (match_dup 0))]
2213 "AVR_MEGA && TARGET_CALL_PROLOGUES"
2214 "jmp __tablejump2__"
2215 [(set_attr "length" "2")
2216 (set_attr "cc" "clobber")])
2218 (define_insn "*tablejump_enh"
2219 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2221 (use (label_ref (match_operand 1 "" "")))
2222 (clobber (match_dup 0))]
2223 "AVR_MEGA && AVR_ENHANCED"
2230 [(set_attr "length" "6")
2231 (set_attr "cc" "clobber")])
2233 (define_insn "*tablejump"
2234 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2236 (use (label_ref (match_operand 1 "" "")))
2237 (clobber (match_dup 0))]
2247 [(set_attr "length" "8")
2248 (set_attr "cc" "clobber")])
2250 (define_expand "casesi"
2252 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2253 (match_operand:HI 1 "register_operand" "")))
2254 (parallel [(set (cc0)
2255 (compare (match_dup 6)
2256 (match_operand:HI 2 "register_operand" "")))
2257 (clobber (match_scratch:QI 9 ""))])
2260 (if_then_else (gtu (cc0)
2262 (label_ref (match_operand 4 "" ""))
2266 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2268 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
2269 (use (label_ref (match_dup 3)))
2270 (clobber (match_dup 6))])]
2274 operands[6] = gen_reg_rtx (HImode);
2278 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2279 ;; This instruction sets Z flag
2282 [(set (cc0) (const_int 0))]
2285 [(set_attr "length" "1")
2286 (set_attr "cc" "compare")])
2288 ;; Clear/set/test a single bit in I/O address space.
2291 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2292 (and:QI (mem:QI (match_dup 0))
2293 (match_operand:QI 1 "single_zero_operand" "n")))]
2296 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2297 return AS2 (cbi,%0-0x20,%2);
2299 [(set_attr "length" "1")
2300 (set_attr "cc" "none")])
2303 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2304 (ior:QI (mem:QI (match_dup 0))
2305 (match_operand:QI 1 "single_one_operand" "n")))]
2308 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2309 return AS2 (sbi,%0-0x20,%2);
2311 [(set_attr "length" "1")
2312 (set_attr "cc" "none")])
2314 ;; Lower half of the I/O space - use sbic/sbis directly.
2315 (define_insn "*sbix_branch"
2318 (match_operator 0 "eqne_operator"
2320 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
2322 (match_operand 2 "const_int_operand" "n"))
2324 (label_ref (match_operand 3 "" ""))
2327 "* return avr_out_sbxx_branch (insn, operands);"
2328 [(set (attr "length")
2329 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2330 (le (minus (pc) (match_dup 3)) (const_int 2046)))
2332 (if_then_else (eq_attr "mcu_mega" "no")
2335 (set_attr "cc" "clobber")])
2337 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
2338 (define_insn "*sbix_branch_bit7"
2341 (match_operator 0 "gelt_operator"
2342 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
2344 (label_ref (match_operand 2 "" ""))
2348 operands[3] = operands[2];
2349 operands[2] = GEN_INT (7);
2350 return avr_out_sbxx_branch (insn, operands);
2352 [(set (attr "length")
2353 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2354 (le (minus (pc) (match_dup 2)) (const_int 2046)))
2356 (if_then_else (eq_attr "mcu_mega" "no")
2359 (set_attr "cc" "clobber")])
2361 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
2362 (define_insn "*sbix_branch_tmp"
2365 (match_operator 0 "eqne_operator"
2367 (mem:QI (match_operand 1 "higth_io_address_operand" "n"))
2369 (match_operand 2 "const_int_operand" "n"))
2371 (label_ref (match_operand 3 "" ""))
2374 "* return avr_out_sbxx_branch (insn, operands);"
2375 [(set (attr "length")
2376 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2377 (le (minus (pc) (match_dup 3)) (const_int 2045)))
2379 (if_then_else (eq_attr "mcu_mega" "no")
2382 (set_attr "cc" "clobber")])
2384 (define_insn "*sbix_branch_tmp_bit7"
2387 (match_operator 0 "gelt_operator"
2388 [(mem:QI (match_operand 1 "higth_io_address_operand" "n"))
2390 (label_ref (match_operand 2 "" ""))
2394 operands[3] = operands[2];
2395 operands[2] = GEN_INT (7);
2396 return avr_out_sbxx_branch (insn, operands);
2398 [(set (attr "length")
2399 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2400 (le (minus (pc) (match_dup 2)) (const_int 2045)))
2402 (if_then_else (eq_attr "mcu_mega" "no")
2405 (set_attr "cc" "clobber")])
2407 ;; ************************* Peepholes ********************************
2410 [(set (match_operand:SI 0 "d_register_operand" "")
2411 (plus:SI (match_dup 0)
2415 (compare (match_dup 0)
2417 (clobber (match_operand:QI 1 "d_register_operand" ""))])
2419 (if_then_else (ne (cc0) (const_int 0))
2420 (label_ref (match_operand 2 "" ""))
2426 if (test_hard_reg_class (ADDW_REGS, operands[0]))
2427 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
2428 AS2 (sbc,%C0,__zero_reg__) CR_TAB
2429 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2431 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2432 AS2 (sbc,%B0,__zero_reg__) CR_TAB
2433 AS2 (sbc,%C0,__zero_reg__) CR_TAB
2434 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2435 switch (avr_jump_mode (operands[2],insn))
2438 return AS1 (brcc,%2);
2440 return (AS1 (brcs,.+2) CR_TAB
2443 return (AS1 (brcs,.+4) CR_TAB
2448 [(set (match_operand:HI 0 "d_register_operand" "")
2449 (plus:HI (match_dup 0)
2453 (compare (match_dup 0)
2455 (clobber (match_operand:QI 1 "d_register_operand" ""))])
2457 (if_then_else (ne (cc0) (const_int 0))
2458 (label_ref (match_operand 2 "" ""))
2464 if (test_hard_reg_class (ADDW_REGS, operands[0]))
2465 output_asm_insn (AS2 (sbiw,%0,1), operands);
2467 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2468 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
2469 switch (avr_jump_mode (operands[2],insn))
2472 return AS1 (brcc,%2);
2474 return (AS1 (brcs,.+2) CR_TAB
2477 return (AS1 (brcs,.+4) CR_TAB
2482 [(set (match_operand:QI 0 "d_register_operand" "")
2483 (plus:QI (match_dup 0)
2486 (compare (match_dup 0)
2489 (if_then_else (ne (cc0) (const_int 0))
2490 (label_ref (match_operand 1 "" ""))
2496 cc_status.value1 = operands[0];
2497 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2498 output_asm_insn (AS2 (subi,%A0,1), operands);
2499 switch (avr_jump_mode (operands[1],insn))
2502 return AS1 (brcc,%1);
2504 return (AS1 (brcs,.+2) CR_TAB
2507 return (AS1 (brcs,.+4) CR_TAB
2512 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
2514 (if_then_else (eq (cc0) (const_int 0))
2515 (label_ref (match_operand 1 "" ""))
2517 "jump_over_one_insn_p (insn, operands[1])"
2518 "cpse %0,__zero_reg__")
2522 (compare (match_operand:QI 0 "register_operand" "")
2523 (match_operand:QI 1 "register_operand" "")))
2525 (if_then_else (eq (cc0) (const_int 0))
2526 (label_ref (match_operand 2 "" ""))
2528 "jump_over_one_insn_p (insn, operands[2])"