1 ;; -*- Mode: Scheme -*-
2 ;; Machine description for GNU compiler,
3 ;; for ATMEL AVR micro controllers.
4 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
5 ;; Contributed by Denis Chertykov (denisc@overta.ru)
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 2, 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 COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;; Special characters after '%':
25 ;; A No effect (add 0).
26 ;; B Add 1 to REG number, MEM address or CONST_INT.
29 ;; j Branch condition.
30 ;; k Reverse branch condition.
31 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
32 ;; ~ Output 'r' if not AVR_MEGA.
35 ;; 0 Length of a string, see "strlenhi".
36 ;; 1 Read from a word address in program memory, see "casesi".
38 ;; Condition code settings.
39 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
40 (const_string "none"))
42 (define_attr "type" "branch,branch1,arith,xcall"
43 (const_string "arith"))
45 (define_attr "mcu_enhanced" "yes,no"
46 (const (if_then_else (symbol_ref "AVR_ENHANCED")
48 (const_string "no"))))
50 (define_attr "mcu_mega" "yes,no"
51 (const (if_then_else (symbol_ref "AVR_MEGA")
53 (const_string "no"))))
56 ;; The size of instructions in bytes.
57 ;; XXX may depend from "cc"
59 (define_attr "length" ""
60 (cond [(eq_attr "type" "branch")
61 (if_then_else (and (ge (minus (pc) (match_dup 0))
63 (le (minus (pc) (match_dup 0))
66 (if_then_else (and (ge (minus (pc) (match_dup 0))
68 (le (minus (pc) (match_dup 0))
72 (eq_attr "type" "branch1")
73 (if_then_else (and (ge (minus (pc) (match_dup 0))
75 (le (minus (pc) (match_dup 0))
78 (if_then_else (and (ge (minus (pc) (match_dup 0))
80 (le (minus (pc) (match_dup 0))
84 (eq_attr "type" "xcall")
85 (if_then_else (eq_attr "mcu_mega" "no")
91 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 1)))]
94 [(set_attr "length" "1")])
97 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 2)))]
101 [(set_attr "length" "2")])
104 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 3)))]
109 [(set_attr "length" "3")])
112 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 4)))]
118 [(set_attr "length" "4")])
121 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 5)))]
128 [(set_attr "length" "5")])
130 (define_insn "*pushqi"
131 [(set (mem:QI (post_dec (reg:HI 32)))
132 (match_operand:QI 0 "nonmemory_operand" "r,L"))]
133 "(operands[0] == const0_rtx || register_operand (operands[0], QImode))"
137 [(set_attr "length" "1,1")])
140 (define_insn "*pushhi"
141 [(set (mem:HI (post_dec (reg:HI 32)))
142 (match_operand:HI 0 "nonmemory_operand" "r,L"))]
143 "(operands[0] == const0_rtx || register_operand (operands[0], HImode))"
146 push __zero_reg__\;push __zero_reg__"
147 [(set_attr "length" "2,2")])
149 (define_insn "*pushsi"
150 [(set (mem:SI (post_dec (reg:HI 32)))
151 (match_operand:SI 0 "nonmemory_operand" "r,L"))]
152 "(operands[0] == const0_rtx || register_operand (operands[0], SImode))"
154 push %D0\;push %C0\;push %B0\;push %A0
155 push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
156 [(set_attr "length" "4,4")])
158 (define_insn "*pushsf"
159 [(set (mem:SF (post_dec (reg:HI 32)))
160 (match_operand:SF 0 "register_operand" "r"))]
166 [(set_attr "length" "4")])
168 ;;========================================================================
170 ;; The last alternative (any immediate constant to any register) is
171 ;; very expensive. It should be optimized by peephole2 if a scratch
172 ;; register is available, but then that register could just as well be
173 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
174 ;; are call-saved registers, and most of LD_REGS are call-used registers,
175 ;; so this may still be a win for registers live across function calls.
177 (define_expand "movqi"
178 [(set (match_operand:QI 0 "nonimmediate_operand" "")
179 (match_operand:QI 1 "general_operand" ""))]
181 "/* One of the ops has to be in a register. */
182 if (!register_operand(operand0, QImode)
183 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
184 operands[1] = copy_to_mode_reg(QImode, operand1);
187 (define_insn "*movqi"
188 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
189 (match_operand:QI 1 "general_operand" "r,i,rL,Qm,r,q,i"))]
190 "(register_operand (operands[0],QImode)
191 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
192 "* return output_movqi (insn, operands, NULL);"
193 [(set_attr "length" "1,1,5,5,1,1,4")
194 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
196 ;; This is used in peephole2 to optimize loading immediate constants
197 ;; if a scratch register from LD_REGS happens to be available.
199 (define_insn "*reload_inqi"
200 [(set (match_operand:QI 0 "register_operand" "=l")
201 (match_operand:QI 1 "immediate_operand" "i"))
202 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
206 [(set_attr "length" "2")
207 (set_attr "cc" "none")])
210 [(match_scratch:QI 2 "d")
211 (set (match_operand:QI 0 "register_operand" "")
212 (match_operand:QI 1 "immediate_operand" ""))]
213 "(operands[1] != const0_rtx
214 && test_hard_reg_class (NO_LD_REGS, operands[0]))"
215 [(parallel [(set (match_dup 0) (match_dup 1))
216 (clobber (match_dup 2))])]
217 "if (!avr_peep2_scratch_safe (operands[2]))
220 ;;============================================================================
221 ;; move word (16 bit)
223 (define_expand "movhi"
224 [(set (match_operand:HI 0 "nonimmediate_operand" "")
225 (match_operand:HI 1 "general_operand" ""))]
229 /* One of the ops has to be in a register. */
230 if (!register_operand(operand0, HImode)
231 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
233 operands[1] = copy_to_mode_reg(HImode, operand1);
239 [(match_scratch:QI 2 "d")
240 (set (match_operand:HI 0 "register_operand" "")
241 (match_operand:HI 1 "immediate_operand" ""))]
242 "(operands[1] != const0_rtx
243 && test_hard_reg_class (NO_LD_REGS, operands[0]))"
244 [(parallel [(set (match_dup 0) (match_dup 1))
245 (clobber (match_dup 2))])]
246 "if (!avr_peep2_scratch_safe (operands[2]))
249 ;; '*' because it is not used in rtl generation, only in above peephole
250 (define_insn "*reload_inhi"
251 [(set (match_operand:HI 0 "register_operand" "=r")
252 (match_operand:HI 1 "immediate_operand" "i"))
253 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
255 "* return output_reload_inhi (insn, operands, NULL);"
256 [(set_attr "length" "4")
257 (set_attr "cc" "none")])
259 (define_insn "*movhi"
260 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
261 (match_operand:HI 1 "general_operand" "r,m,rL,i,i,r,q"))]
262 "(register_operand (operands[0],HImode)
263 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
264 "* return output_movhi (insn, operands, NULL);"
265 [(set_attr "length" "2,6,7,2,6,5,2")
266 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
268 ;;==========================================================================
269 ;; move double word (32 bit)
271 (define_expand "movsi"
272 [(set (match_operand:SI 0 "nonimmediate_operand" "")
273 (match_operand:SI 1 "general_operand" ""))]
277 /* One of the ops has to be in a register. */
278 if (!register_operand (operand0, SImode)
279 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
281 operands[1] = copy_to_mode_reg (SImode, operand1);
288 [(match_scratch:QI 2 "d")
289 (set (match_operand:SI 0 "register_operand" "")
290 (match_operand:SI 1 "immediate_operand" ""))]
291 "(operands[1] != const0_rtx
292 && test_hard_reg_class (NO_LD_REGS, operands[0]))"
293 [(parallel [(set (match_dup 0) (match_dup 1))
294 (clobber (match_dup 2))])]
295 "if (!avr_peep2_scratch_safe (operands[2]))
298 ;; '*' because it is not used in rtl generation.
299 (define_insn "*reload_insi"
300 [(set (match_operand:SI 0 "register_operand" "=r")
301 (match_operand:SI 1 "immediate_operand" "i"))
302 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
304 "* return output_reload_insisf (insn, operands, NULL);"
305 [(set_attr "length" "8")
306 (set_attr "cc" "none")])
309 (define_insn "*movsi"
310 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
311 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
312 "(register_operand (operands[0],SImode)
313 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
314 "* return output_movsisf (insn, operands, NULL);"
315 [(set_attr "length" "4,4,8,9,4,10")
316 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
318 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
319 ;; move floating point numbers (32 bit)
321 (define_expand "movsf"
322 [(set (match_operand:SF 0 "nonimmediate_operand" "")
323 (match_operand:SF 1 "general_operand" ""))]
327 /* One of the ops has to be in a register. */
328 if (!register_operand (operand1, SFmode)
329 && !register_operand (operand0, SFmode))
331 operands[1] = copy_to_mode_reg (SFmode, operand1);
335 (define_insn "*movsf"
336 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
337 (match_operand:SF 1 "general_operand" "r,G,Qm,r,F,F"))]
338 "register_operand (operands[0], SFmode)
339 || register_operand (operands[1], SFmode)"
340 "* return output_movsisf (insn, operands, NULL);"
341 [(set_attr "length" "4,4,8,9,4,10")
342 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
344 ;;=========================================================================
345 ;; move string (like memcpy)
347 (define_expand "movstrhi"
348 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
349 (match_operand:BLK 1 "memory_operand" ""))
350 (use (match_operand:HI 2 "const_int_operand" ""))
351 (use (match_operand:HI 3 "const_int_operand" ""))
352 (clobber (match_dup 4))
353 (clobber (match_dup 5))
354 (clobber (match_dup 6))])]
359 enum machine_mode mode;
361 if (GET_CODE (operands[2]) != CONST_INT)
363 cnt8 = byte_immediate_operand (operands[2], GET_MODE (operands[2]));
364 mode = cnt8 ? QImode : HImode;
365 operands[2] = copy_to_mode_reg (mode,
366 gen_int_mode (INTVAL (operands[2]), mode));
367 operands[4] = operands[2];
368 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
369 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
374 operands[0] = gen_rtx_MEM (BLKmode, addr0);
375 operands[1] = gen_rtx_MEM (BLKmode, addr1);
378 (define_insn "*movstrqi_insn"
379 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
380 (mem:BLK (match_operand:HI 1 "register_operand" "e")))
381 (use (match_operand:QI 2 "register_operand" "r"))
382 (use (match_operand:QI 3 "const_int_operand" "i"))
383 (clobber (match_dup 2))
384 (clobber (match_dup 0))
385 (clobber (match_dup 1))]
391 [(set_attr "length" "4")
392 (set_attr "cc" "clobber")])
394 (define_insn "*movstrhi"
395 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
396 (mem:BLK (match_operand:HI 1 "register_operand" "e,e")))
397 (use (match_operand:HI 2 "register_operand" "!w,d"))
398 (use (match_operand:HI 3 "const_int_operand" ""))
399 (clobber (match_dup 2))
400 (clobber (match_dup 0))
401 (clobber (match_dup 1))]
404 if (which_alternative==0)
405 return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
406 AS2 (st,%a0+,__tmp_reg__) CR_TAB
407 AS2 (sbiw,%A2,1) CR_TAB
410 return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
411 AS2 (st,%a0+,__tmp_reg__) CR_TAB
412 AS2 (subi,%A2,1) CR_TAB
413 AS2 (sbci,%B2,0) CR_TAB
416 [(set_attr "length" "4,5")
417 (set_attr "cc" "clobber,clobber")])
419 ;; =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0
420 ;; memset (%0, 0, %1)
422 (define_expand "clrstrhi"
423 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
425 (use (match_operand:HI 1 "const_int_operand" ""))
426 (use (match_operand:HI 2 "const_int_operand" "n"))
427 (clobber (match_dup 3))
428 (clobber (match_dup 4))])]
433 enum machine_mode mode;
435 if (GET_CODE (operands[1]) != CONST_INT)
438 cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
439 mode = cnt8 ? QImode : HImode;
440 operands[1] = copy_to_mode_reg (mode,
441 gen_int_mode (INTVAL (operands[1]), mode));
442 operands[3] = operands[1];
444 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
447 operands[0] = gen_rtx_MEM (BLKmode, addr0);
450 (define_insn "*clrstrqi"
451 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
453 (use (match_operand:QI 1 "register_operand" "r"))
454 (use (match_operand:QI 2 "const_int_operand" "n"))
455 (clobber (match_dup 1))
456 (clobber (match_dup 0))]
458 "st %a0+,__zero_reg__
461 [(set_attr "length" "3")
462 (set_attr "cc" "clobber")])
464 (define_insn "*clrstrhi"
465 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
467 (use (match_operand:HI 1 "register_operand" "!w,d"))
468 (use (match_operand:HI 2 "const_int_operand" "n,n"))
469 (clobber (match_dup 1))
470 (clobber (match_dup 0))]
473 if (which_alternative==0)
474 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
475 AS2 (sbiw,%A1,1) CR_TAB
478 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
479 AS2 (subi,%A1,1) CR_TAB
480 AS2 (sbci,%B1,0) CR_TAB
483 [(set_attr "length" "3,4")
484 (set_attr "cc" "clobber,clobber")])
486 (define_expand "strlenhi"
488 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
489 (match_operand:QI 2 "const_int_operand" "")
490 (match_operand:HI 3 "immediate_operand" "")] 0))
491 (set (match_dup 4) (plus:HI (match_dup 4)
493 (set (match_operand:HI 0 "register_operand" "")
494 (minus:HI (match_dup 4)
499 if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
501 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
502 operands[1] = gen_rtx_MEM (BLKmode, addr);
504 operands[4] = gen_reg_rtx (HImode);
507 (define_insn "*strlenhi"
508 [(set (match_operand:HI 0 "register_operand" "=e")
509 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
511 (match_operand:HI 2 "immediate_operand" "i")] 0))]
516 [(set_attr "length" "3")
517 (set_attr "cc" "clobber")])
519 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
522 (define_insn "addqi3"
523 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
524 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
525 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
532 [(set_attr "length" "1,1,1,1")
533 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
536 (define_expand "addhi3"
537 [(set (match_operand:HI 0 "register_operand" "")
538 (plus:HI (match_operand:HI 1 "register_operand" "")
539 (match_operand:HI 2 "nonmemory_operand" "")))]
543 if (GET_CODE (operands[2]) == CONST_INT)
545 short tmp = INTVAL (operands[2]);
546 operands[2] = GEN_INT(tmp);
551 (define_insn "*addhi3_zero_extend"
552 [(set (match_operand:HI 0 "register_operand" "=r")
553 (plus:HI (zero_extend:HI
554 (match_operand:QI 1 "register_operand" "r"))
555 (match_operand:HI 2 "register_operand" "0")))]
558 adc %B0,__zero_reg__"
559 [(set_attr "length" "2")
560 (set_attr "cc" "set_n")])
562 (define_insn "*addhi3_zero_extend1"
563 [(set (match_operand:HI 0 "register_operand" "=r")
564 (plus:HI (match_operand:HI 1 "register_operand" "%0")
566 (match_operand:QI 2 "register_operand" "r"))))]
569 adc %B0,__zero_reg__"
570 [(set_attr "length" "2")
571 (set_attr "cc" "set_n")])
573 (define_insn "*addhi3_zero_extend2"
574 [(set (match_operand:HI 0 "register_operand" "=r")
576 (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
577 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
581 adc %B0,__zero_reg__"
582 [(set_attr "length" "3")
583 (set_attr "cc" "set_n")])
585 (define_insn "*addhi3"
586 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
588 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
589 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
592 add %A0,%A2\;adc %B0,%B2
595 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
596 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
597 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
598 [(set_attr "length" "2,1,1,2,3,3")
599 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
601 (define_insn "addsi3"
602 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
604 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
605 (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
608 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
609 adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
610 sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
611 subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
612 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
613 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
614 [(set_attr "length" "4,3,3,4,5,5")
615 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
617 (define_insn "*addsi3_zero_extend"
618 [(set (match_operand:SI 0 "register_operand" "=r")
619 (plus:SI (zero_extend:SI
620 (match_operand:QI 1 "register_operand" "r"))
621 (match_operand:SI 2 "register_operand" "0")))]
626 adc %D0,__zero_reg__"
627 [(set_attr "length" "4")
628 (set_attr "cc" "set_n")])
630 ;-----------------------------------------------------------------------------
632 (define_insn "subqi3"
633 [(set (match_operand:QI 0 "register_operand" "=r,d")
634 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
635 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
640 [(set_attr "length" "1,1")
641 (set_attr "cc" "set_czn,set_czn")])
643 (define_insn "subhi3"
644 [(set (match_operand:HI 0 "register_operand" "=r,d")
645 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
646 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
649 sub %A0,%A2\;sbc %B0,%B2
650 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
651 [(set_attr "length" "2,2")
652 (set_attr "cc" "set_czn,set_czn")])
654 (define_insn "*subhi3_zero_extend1"
655 [(set (match_operand:HI 0 "register_operand" "=r")
656 (minus:HI (match_operand:HI 1 "register_operand" "0")
658 (match_operand:QI 2 "register_operand" "r"))))]
661 sbc %B0,__zero_reg__"
662 [(set_attr "length" "2")
663 (set_attr "cc" "set_n")])
665 (define_insn "subsi3"
666 [(set (match_operand:SI 0 "register_operand" "=r,d")
667 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
668 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
671 sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
672 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
673 [(set_attr "length" "4,4")
674 (set_attr "cc" "set_czn,set_czn")])
676 (define_insn "*subsi3_zero_extend"
677 [(set (match_operand:SI 0 "register_operand" "=r")
678 (minus:SI (match_operand:SI 1 "register_operand" "0")
680 (match_operand:QI 2 "register_operand" "r"))))]
685 sbc %D0,__zero_reg__"
686 [(set_attr "length" "4")
687 (set_attr "cc" "set_n")])
689 ;******************************************************************************
692 (define_expand "mulqi3"
693 [(set (match_operand:QI 0 "register_operand" "")
694 (mult:QI (match_operand:QI 1 "register_operand" "")
695 (match_operand:QI 2 "register_operand" "")))]
700 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
705 (define_insn "*mulqi3_enh"
706 [(set (match_operand:QI 0 "register_operand" "=r")
707 (mult:QI (match_operand:QI 1 "register_operand" "r")
708 (match_operand:QI 2 "register_operand" "r")))]
713 [(set_attr "length" "3")
714 (set_attr "cc" "clobber")])
716 (define_expand "mulqi3_call"
717 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
718 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
719 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
720 (clobber (reg:QI 22))])
721 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
725 (define_insn "*mulqi3_call"
726 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
727 (clobber (reg:QI 22))]
730 [(set_attr "type" "xcall")
731 (set_attr "cc" "clobber")])
733 (define_insn "mulqihi3"
734 [(set (match_operand:HI 0 "register_operand" "=r")
735 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
736 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
741 [(set_attr "length" "3")
742 (set_attr "cc" "clobber")])
744 (define_insn "umulqihi3"
745 [(set (match_operand:HI 0 "register_operand" "=r")
746 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
747 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
752 [(set_attr "length" "3")
753 (set_attr "cc" "clobber")])
755 (define_expand "mulhi3"
756 [(set (match_operand:HI 0 "register_operand" "")
757 (mult:HI (match_operand:HI 1 "register_operand" "")
758 (match_operand:HI 2 "register_operand" "")))]
764 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
769 (define_insn "*mulhi3_enh"
770 [(set (match_operand:HI 0 "register_operand" "=&r")
771 (mult:HI (match_operand:HI 1 "register_operand" "r")
772 (match_operand:HI 2 "register_operand" "r")))]
781 [(set_attr "length" "7")
782 (set_attr "cc" "clobber")])
784 (define_expand "mulhi3_call"
785 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
786 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
787 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
788 (clobber (reg:HI 22))
789 (clobber (reg:QI 21))])
790 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
794 (define_insn "*mulhi3_call"
795 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
796 (clobber (reg:HI 22))
797 (clobber (reg:QI 21))]
800 [(set_attr "type" "xcall")
801 (set_attr "cc" "clobber")])
803 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
804 ;; All call-used registers clobbered otherwise - normal library call.
805 (define_expand "mulsi3"
806 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
807 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
808 (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
809 (clobber (reg:HI 26))
810 (clobber (reg:HI 30))])
811 (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
815 (define_insn "*mulsi3_call"
816 [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
817 (clobber (reg:HI 26))
818 (clobber (reg:HI 30))]
821 [(set_attr "type" "xcall")
822 (set_attr "cc" "clobber")])
824 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
827 ;; Generate libgcc.S calls ourselves, because:
828 ;; - we know exactly which registers are clobbered (for QI and HI
829 ;; modes, some of the call-used registers are preserved)
830 ;; - we get both the quotient and the remainder at no extra cost
832 (define_expand "divmodqi4"
833 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
834 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
835 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
836 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
837 (clobber (reg:QI 22))
838 (clobber (reg:QI 23))])
839 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
840 (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
844 (define_insn "*divmodqi4_call"
845 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
846 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
847 (clobber (reg:QI 22))
848 (clobber (reg:QI 23))]
851 [(set_attr "type" "xcall")
852 (set_attr "cc" "clobber")])
854 (define_expand "udivmodqi4"
855 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
856 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
857 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
858 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
859 (clobber (reg:QI 23))])
860 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
861 (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
865 (define_insn "*udivmodqi4_call"
866 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
867 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
868 (clobber (reg:QI 23))]
870 "%~call __udivmodqi4"
871 [(set_attr "type" "xcall")
872 (set_attr "cc" "clobber")])
874 (define_expand "divmodhi4"
875 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
876 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
877 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
878 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
879 (clobber (reg:HI 26))
880 (clobber (reg:QI 21))])
881 (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
882 (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
886 (define_insn "*divmodhi4_call"
887 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
888 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
889 (clobber (reg:HI 26))
890 (clobber (reg:QI 21))]
893 [(set_attr "type" "xcall")
894 (set_attr "cc" "clobber")])
896 (define_expand "udivmodhi4"
897 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
898 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
899 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
900 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
901 (clobber (reg:HI 26))
902 (clobber (reg:QI 21))])
903 (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
904 (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
908 (define_insn "*udivmodhi4_call"
909 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
910 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
911 (clobber (reg:HI 26))
912 (clobber (reg:QI 21))]
914 "%~call __udivmodhi4"
915 [(set_attr "type" "xcall")
916 (set_attr "cc" "clobber")])
918 (define_expand "divmodsi4"
919 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
920 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
921 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
922 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
923 (clobber (reg:HI 26))
924 (clobber (reg:HI 30))])
925 (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
926 (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
930 (define_insn "*divmodsi4_call"
931 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
932 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
933 (clobber (reg:HI 26))
934 (clobber (reg:HI 30))]
937 [(set_attr "type" "xcall")
938 (set_attr "cc" "clobber")])
940 (define_expand "udivmodsi4"
941 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
942 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
943 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
944 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
945 (clobber (reg:HI 26))
946 (clobber (reg:HI 30))])
947 (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
948 (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
952 (define_insn "*udivmodsi4_call"
953 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
954 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
955 (clobber (reg:HI 26))
956 (clobber (reg:HI 30))]
958 "%~call __udivmodsi4"
959 [(set_attr "type" "xcall")
960 (set_attr "cc" "clobber")])
962 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
965 (define_insn "andqi3"
966 [(set (match_operand:QI 0 "register_operand" "=r,d")
967 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
968 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
973 [(set_attr "length" "1,1")
974 (set_attr "cc" "set_zn,set_zn")])
976 (define_insn "andhi3"
977 [(set (match_operand:HI 0 "register_operand" "=r,d,r")
978 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
979 (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
980 (clobber (match_scratch:QI 3 "=X,X,&d"))]
983 if (which_alternative==0)
984 return (AS2 (and,%A0,%A2) CR_TAB
986 else if (which_alternative==1)
988 if (GET_CODE (operands[2]) == CONST_INT)
990 int mask = INTVAL (operands[2]);
991 if ((mask & 0xff) != 0xff)
992 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
993 if ((mask & 0xff00) != 0xff00)
994 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
997 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
998 AS2 (andi,%B0,hi8(%2)));
1000 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1001 AS2 (and,%A0,%3) CR_TAB
1004 [(set_attr "length" "2,2,3")
1005 (set_attr "cc" "set_n,clobber,set_n")])
1007 (define_insn "andsi3"
1008 [(set (match_operand:SI 0 "register_operand" "=r,d")
1009 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1010 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1013 if (which_alternative==0)
1014 return (AS2 (and, %0,%2) CR_TAB
1015 AS2 (and, %B0,%B2) CR_TAB
1016 AS2 (and, %C0,%C2) CR_TAB
1017 AS2 (and, %D0,%D2));
1018 else if (which_alternative==1)
1020 if (GET_CODE (operands[2]) == CONST_INT)
1022 HOST_WIDE_INT mask = INTVAL (operands[2]);
1023 if ((mask & 0xff) != 0xff)
1024 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1025 if ((mask & 0xff00) != 0xff00)
1026 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1027 if ((mask & 0xff0000L) != 0xff0000L)
1028 output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1029 if ((mask & 0xff000000L) != 0xff000000L)
1030 output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1033 return (AS2 (andi, %A0,lo8(%2)) CR_TAB
1034 AS2 (andi, %B0,hi8(%2)) CR_TAB
1035 AS2 (andi, %C0,hlo8(%2)) CR_TAB
1036 AS2 (andi, %D0,hhi8(%2)));
1040 [(set_attr "length" "4,4")
1041 (set_attr "cc" "set_n,set_n")])
1043 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1046 (define_insn "iorqi3"
1047 [(set (match_operand:QI 0 "register_operand" "=r,d")
1048 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1049 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1054 [(set_attr "length" "1,1")
1055 (set_attr "cc" "set_zn,set_zn")])
1057 (define_insn "iorhi3"
1058 [(set (match_operand:HI 0 "register_operand" "=r,d")
1059 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1060 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1063 if (which_alternative==0)
1064 return (AS2 (or,%A0,%A2) CR_TAB
1066 if (GET_CODE (operands[2]) == CONST_INT)
1068 int mask = INTVAL (operands[2]);
1070 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1072 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1075 return (AS2 (ori,%0,lo8(%2)) CR_TAB
1076 AS2 (ori,%B0,hi8(%2)));
1078 [(set_attr "length" "2,2")
1079 (set_attr "cc" "set_n,clobber")])
1081 (define_insn "*iorhi3_clobber"
1082 [(set (match_operand:HI 0 "register_operand" "=r,r")
1083 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1084 (match_operand:HI 2 "immediate_operand" "M,i")))
1085 (clobber (match_scratch:QI 3 "=&d,&d"))]
1088 ldi %3,lo8(%2)\;or %A0,%3
1089 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1090 [(set_attr "length" "2,4")
1091 (set_attr "cc" "clobber,set_n")])
1093 (define_insn "iorsi3"
1094 [(set (match_operand:SI 0 "register_operand" "=r,d")
1095 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1096 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1099 if (which_alternative==0)
1100 return (AS2 (or, %0,%2) CR_TAB
1101 AS2 (or, %B0,%B2) CR_TAB
1102 AS2 (or, %C0,%C2) CR_TAB
1104 if (GET_CODE (operands[2]) == CONST_INT)
1106 HOST_WIDE_INT mask = INTVAL (operands[2]);
1108 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1110 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1111 if (mask & 0xff0000L)
1112 output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1113 if (mask & 0xff000000L)
1114 output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1117 return (AS2 (ori, %A0,lo8(%2)) CR_TAB
1118 AS2 (ori, %B0,hi8(%2)) CR_TAB
1119 AS2 (ori, %C0,hlo8(%2)) CR_TAB
1120 AS2 (ori, %D0,hhi8(%2)));
1122 [(set_attr "length" "4,4")
1123 (set_attr "cc" "set_n,clobber")])
1125 (define_insn "*iorsi3_clobber"
1126 [(set (match_operand:SI 0 "register_operand" "=r,r")
1127 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1128 (match_operand:SI 2 "immediate_operand" "M,i")))
1129 (clobber (match_scratch:QI 3 "=&d,&d"))]
1132 ldi %3,lo8(%2)\;or %A0,%3
1133 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"
1134 [(set_attr "length" "2,8")
1135 (set_attr "cc" "clobber,set_n")])
1137 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1140 (define_insn "xorqi3"
1141 [(set (match_operand:QI 0 "register_operand" "=r")
1142 (xor:QI (match_operand:QI 1 "register_operand" "%0")
1143 (match_operand:QI 2 "register_operand" "r")))]
1146 [(set_attr "length" "1")
1147 (set_attr "cc" "set_zn")])
1149 (define_insn "xorhi3"
1150 [(set (match_operand:HI 0 "register_operand" "=r")
1151 (xor:HI (match_operand:HI 1 "register_operand" "%0")
1152 (match_operand:HI 2 "register_operand" "r")))]
1156 [(set_attr "length" "2")
1157 (set_attr "cc" "set_n")])
1159 (define_insn "xorsi3"
1160 [(set (match_operand:SI 0 "register_operand" "=r")
1161 (xor:SI (match_operand:SI 1 "register_operand" "%0")
1162 (match_operand:SI 2 "register_operand" "r")))]
1168 [(set_attr "length" "4")
1169 (set_attr "cc" "set_n")])
1171 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1172 ;; arithmetic shift left
1174 (define_insn "ashlqi3"
1175 [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r")
1176 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1177 (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))]
1179 "* return ashlqi3_out (insn, operands, NULL);"
1180 [(set_attr "length" "5,1,2,4,6,9")
1181 (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")])
1183 (define_insn "ashlhi3"
1184 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
1185 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0")
1186 (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
1188 "* return ashlhi3_out (insn, operands, NULL);"
1189 [(set_attr "length" "6,2,2,4,10,10")
1190 (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")])
1192 (define_insn "ashlsi3"
1193 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1194 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0")
1195 (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
1197 "* return ashlsi3_out (insn, operands, NULL);"
1198 [(set_attr "length" "8,4,4,8,10,12")
1199 (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")])
1201 ;; Optimize if a scratch register from LD_REGS happens to be available.
1204 [(match_scratch:QI 3 "d")
1205 (set (match_operand:HI 0 "register_operand" "")
1206 (ashift:HI (match_operand:HI 1 "register_operand" "")
1207 (match_operand:QI 2 "const_int_operand" "")))]
1209 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1210 (clobber (match_dup 3))])]
1211 "if (!avr_peep2_scratch_safe (operands[3]))
1214 (define_insn "*ashlhi3_const"
1215 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1216 (ashift:HI (match_operand:HI 1 "register_operand" "0,r,0,0")
1217 (match_operand:QI 2 "const_int_operand" "P,O,K,n")))
1218 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1220 "* return ashlhi3_out (insn, operands, NULL);"
1221 [(set_attr "length" "2,2,4,10")
1222 (set_attr "cc" "set_n,clobber,set_n,clobber")])
1225 [(match_scratch:QI 3 "d")
1226 (set (match_operand:SI 0 "register_operand" "")
1227 (ashift:SI (match_operand:SI 1 "register_operand" "")
1228 (match_operand:QI 2 "const_int_operand" "")))]
1230 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1231 (clobber (match_dup 3))])]
1232 "if (!avr_peep2_scratch_safe (operands[3]))
1235 (define_insn "*ashlsi3_const"
1236 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1237 (ashift:SI (match_operand:SI 1 "register_operand" "0,r,0")
1238 (match_operand:QI 2 "const_int_operand" "P,O,n")))
1239 (clobber (match_scratch:QI 3 "=X,X,&d"))]
1241 "* return ashlsi3_out (insn, operands, NULL);"
1242 [(set_attr "length" "4,4,10")
1243 (set_attr "cc" "set_n,clobber,clobber")])
1245 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1246 ;; arithmetic shift right
1248 (define_insn "ashrqi3"
1249 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
1250 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0")
1251 (match_operand:QI 2 "general_operand" "r,P,K,n,Qm")))]
1253 "* return ashrqi3_out (insn, operands, NULL);"
1254 [(set_attr "length" "5,1,2,5,9")
1255 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")])
1257 (define_insn "ashrhi3"
1258 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
1259 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0")
1260 (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
1262 "* return ashrhi3_out (insn, operands, NULL);"
1263 [(set_attr "length" "6,2,4,4,10,10")
1264 (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")])
1266 (define_insn "ashrsi3"
1267 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1268 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0")
1269 (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
1271 "* return ashrsi3_out (insn, operands, NULL);"
1272 [(set_attr "length" "8,4,6,8,10,12")
1273 (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")])
1275 ;; Optimize if a scratch register from LD_REGS happens to be available.
1278 [(match_scratch:QI 3 "d")
1279 (set (match_operand:HI 0 "register_operand" "")
1280 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1281 (match_operand:QI 2 "const_int_operand" "")))]
1283 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1284 (clobber (match_dup 3))])]
1285 "if (!avr_peep2_scratch_safe (operands[3]))
1288 (define_insn "*ashrhi3_const"
1289 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1290 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0")
1291 (match_operand:QI 2 "const_int_operand" "P,O,K,n")))
1292 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1294 "* return ashrhi3_out (insn, operands, NULL);"
1295 [(set_attr "length" "2,4,4,10")
1296 (set_attr "cc" "clobber,set_n,clobber,clobber")])
1299 [(match_scratch:QI 3 "d")
1300 (set (match_operand:SI 0 "register_operand" "")
1301 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1302 (match_operand:QI 2 "const_int_operand" "")))]
1304 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1305 (clobber (match_dup 3))])]
1306 "if (!avr_peep2_scratch_safe (operands[3]))
1309 (define_insn "*ashrsi3_const"
1310 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1311 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0")
1312 (match_operand:QI 2 "const_int_operand" "P,O,n")))
1313 (clobber (match_scratch:QI 3 "=X,X,&d"))]
1315 "* return ashrsi3_out (insn, operands, NULL);"
1316 [(set_attr "length" "4,4,10")
1317 (set_attr "cc" "clobber,set_n,clobber")])
1319 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1320 ;; logical shift right
1322 (define_insn "lshrqi3"
1323 [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r")
1324 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1325 (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))]
1327 "* return lshrqi3_out (insn, operands, NULL);"
1328 [(set_attr "length" "5,1,2,4,6,9")
1329 (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")])
1331 (define_insn "lshrhi3"
1332 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
1333 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0")
1334 (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
1336 "* return lshrhi3_out (insn, operands, NULL);"
1337 [(set_attr "length" "6,2,2,4,10,10")
1338 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")])
1340 (define_insn "lshrsi3"
1341 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1342 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0")
1343 (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))]
1345 "* return lshrsi3_out (insn, operands, NULL);"
1346 [(set_attr "length" "8,4,4,8,10,12")
1347 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")])
1349 ;; Optimize if a scratch register from LD_REGS happens to be available.
1352 [(match_scratch:QI 3 "d")
1353 (set (match_operand:HI 0 "register_operand" "")
1354 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1355 (match_operand:QI 2 "const_int_operand" "")))]
1357 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1358 (clobber (match_dup 3))])]
1359 "if (!avr_peep2_scratch_safe (operands[3]))
1362 (define_insn "*lshrhi3_const"
1363 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1364 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0")
1365 (match_operand:QI 2 "const_int_operand" "P,O,K,n")))
1366 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1368 "* return lshrhi3_out (insn, operands, NULL);"
1369 [(set_attr "length" "2,2,4,10")
1370 (set_attr "cc" "clobber,clobber,clobber,clobber")])
1373 [(match_scratch:QI 3 "d")
1374 (set (match_operand:SI 0 "register_operand" "")
1375 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1376 (match_operand:QI 2 "const_int_operand" "")))]
1378 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1379 (clobber (match_dup 3))])]
1380 "if (!avr_peep2_scratch_safe (operands[3]))
1383 (define_insn "*lshrsi3_const"
1384 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1385 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0")
1386 (match_operand:QI 2 "const_int_operand" "P,O,n")))
1387 (clobber (match_scratch:QI 3 "=X,X,&d"))]
1389 "* return lshrsi3_out (insn, operands, NULL);"
1390 [(set_attr "length" "4,4,10")
1391 (set_attr "cc" "clobber,clobber,clobber")])
1393 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
1396 (define_insn "absqi2"
1397 [(set (match_operand:QI 0 "register_operand" "=r")
1398 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
1402 [(set_attr "length" "2")
1403 (set_attr "cc" "clobber")])
1406 (define_insn "abssf2"
1407 [(set (match_operand:SF 0 "register_operand" "=d,r")
1408 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
1413 [(set_attr "length" "1,2")
1414 (set_attr "cc" "set_n,clobber")])
1416 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
1419 (define_insn "negqi2"
1420 [(set (match_operand:QI 0 "register_operand" "=r")
1421 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1424 [(set_attr "length" "1")
1425 (set_attr "cc" "set_zn")])
1427 (define_insn "neghi2"
1428 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
1429 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
1432 com %B0\;neg %A0\;sbci %B0,lo8(-1)
1433 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
1434 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
1435 [(set_attr "length" "3,4,4")
1436 (set_attr "cc" "set_czn,set_n,set_czn")])
1438 (define_insn "negsi2"
1439 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
1440 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
1443 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
1444 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1445 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1446 [(set_attr_alternative "length"
1449 (if_then_else (eq_attr "mcu_enhanced" "yes")
1452 (set_attr "cc" "set_czn,set_n,set_czn")])
1454 (define_insn "negsf2"
1455 [(set (match_operand:SF 0 "register_operand" "=d,r")
1456 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
1460 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
1461 [(set_attr "length" "1,4")
1462 (set_attr "cc" "set_n,set_n")])
1464 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1467 (define_insn "one_cmplqi2"
1468 [(set (match_operand:QI 0 "register_operand" "=r")
1469 (not:QI (match_operand:QI 1 "register_operand" "0")))]
1472 [(set_attr "length" "1")
1473 (set_attr "cc" "set_czn")])
1475 (define_insn "one_cmplhi2"
1476 [(set (match_operand:HI 0 "register_operand" "=r")
1477 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1481 [(set_attr "length" "2")
1482 (set_attr "cc" "set_n")])
1484 (define_insn "one_cmplsi2"
1485 [(set (match_operand:SI 0 "register_operand" "=r")
1486 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1492 [(set_attr "length" "4")
1493 (set_attr "cc" "set_n")])
1495 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1498 (define_insn "extendqihi2"
1499 [(set (match_operand:HI 0 "register_operand" "=r,r")
1500 (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1503 clr %B0\;sbrc %0,7\;com %B0
1504 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
1505 [(set_attr "length" "3,4")
1506 (set_attr "cc" "set_n,set_n")])
1508 (define_insn "extendqisi2"
1509 [(set (match_operand:SI 0 "register_operand" "=r,r")
1510 (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1513 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
1514 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
1515 [(set_attr "length" "5,6")
1516 (set_attr "cc" "set_n,set_n")])
1518 (define_insn "extendhisi2"
1519 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1520 (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1523 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
1524 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
1525 [(set_attr_alternative "length"
1527 (if_then_else (eq_attr "mcu_enhanced" "yes")
1530 (set_attr "cc" "set_n,set_n")])
1532 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1535 (define_insn "zero_extendqihi2"
1536 [(set (match_operand:HI 0 "register_operand" "=r,r")
1537 (zero_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1541 mov %A0,%A1\;clr %B0"
1542 [(set_attr "length" "1,2")
1543 (set_attr "cc" "set_n,set_n")])
1545 (define_insn "zero_extendqisi2"
1546 [(set (match_operand:SI 0 "register_operand" "=r,r")
1547 (zero_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1550 clr %B0\;clr %C0\;clr %D0
1551 mov %A0,%A1\;clr %B0\;clr %C0\;clr %D0"
1552 [(set_attr "length" "3,4")
1553 (set_attr "cc" "set_n,set_n")])
1555 (define_insn "zero_extendhisi2"
1556 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1557 (zero_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1561 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;clr %D0"
1562 [(set_attr_alternative "length"
1564 (if_then_else (eq_attr "mcu_enhanced" "yes")
1567 (set_attr "cc" "set_n,set_n")])
1569 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
1572 (define_insn "tstqi"
1574 (match_operand:QI 0 "register_operand" "r"))]
1577 [(set_attr "cc" "compare")
1578 (set_attr "length" "1")])
1580 (define_insn "*negated_tstqi"
1582 (neg:QI (match_operand:QI 0 "register_operand" "r")))]
1584 "cp __zero_reg__,%0"
1585 [(set_attr "cc" "compare")
1586 (set_attr "length" "1")])
1588 (define_insn "tsthi"
1590 (match_operand:HI 0 "register_operand" "!w,r"))]
1592 "* return out_tsthi (insn,NULL);"
1593 [(set_attr "cc" "compare,compare")
1594 (set_attr "length" "1,2")])
1596 (define_insn "*negated_tsthi"
1598 (neg:HI (match_operand:HI 0 "register_operand" "r")))]
1600 "cp __zero_reg__,%A0
1601 cpc __zero_reg__,%B0"
1602 [(set_attr "cc" "compare")
1603 (set_attr "length" "2")])
1605 (define_insn "tstsi"
1607 (match_operand:SI 0 "register_operand" "r"))]
1609 "* return out_tstsi (insn,NULL);"
1610 [(set_attr "cc" "compare")
1611 (set_attr "length" "4")])
1613 (define_insn "*negated_tstsi"
1615 (neg:SI (match_operand:SI 0 "register_operand" "r")))]
1617 "cp __zero_reg__,%A0
1618 cpc __zero_reg__,%B0
1619 cpc __zero_reg__,%C0
1620 cpc __zero_reg__,%D0"
1621 [(set_attr "cc" "compare")
1622 (set_attr "length" "4")])
1625 (define_insn "cmpqi"
1627 (compare (match_operand:QI 0 "register_operand" "r,d")
1628 (match_operand:QI 1 "nonmemory_operand" "r,i")))]
1633 [(set_attr "cc" "compare,compare")
1634 (set_attr "length" "1,1")])
1636 (define_insn "*cmpqi_sign_extend"
1638 (compare (sign_extend:HI
1639 (match_operand:QI 0 "register_operand" "d"))
1640 (match_operand:HI 1 "const_int_operand" "n")))]
1641 "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
1643 [(set_attr "cc" "compare")
1644 (set_attr "length" "1")])
1646 (define_insn "cmphi"
1648 (compare (match_operand:HI 0 "register_operand" "r,d,d,r,r")
1649 (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
1650 (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1653 switch (which_alternative)
1656 return (AS2 (cp,%A0,%A1) CR_TAB
1659 if (reg_unused_after (insn, operands[0])
1660 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1661 && test_hard_reg_class (ADDW_REGS, operands[0]))
1662 return AS2 (sbiw,%0,%1);
1664 return (AS2 (cpi,%0,%1) CR_TAB
1665 AS2 (cpc,%B0,__zero_reg__));
1667 if (reg_unused_after (insn, operands[0]))
1668 return (AS2 (subi,%0,lo8(%1)) CR_TAB
1669 AS2 (sbci,%B0,hi8(%1)));
1671 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
1672 AS2 (cpi, %A0,lo8(%1)) CR_TAB
1675 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1676 AS2 (cp, %A0,%2) CR_TAB
1677 AS2 (cpc, %B0,__zero_reg__));
1680 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1681 AS2 (cp, %A0,%2) CR_TAB
1682 AS2 (ldi, %2,hi8(%1)) CR_TAB
1687 [(set_attr "cc" "compare,compare,compare,compare,compare")
1688 (set_attr "length" "2,2,3,3,4")])
1691 (define_insn "cmpsi"
1693 (compare (match_operand:SI 0 "register_operand" "r,d,d,r,r")
1694 (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
1695 (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1698 switch (which_alternative)
1701 return (AS2 (cp,%A0,%A1) CR_TAB
1702 AS2 (cpc,%B0,%B1) CR_TAB
1703 AS2 (cpc,%C0,%C1) CR_TAB
1706 if (reg_unused_after (insn, operands[0])
1707 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1708 && test_hard_reg_class (ADDW_REGS, operands[0]))
1709 return (AS2 (sbiw,%0,%1) CR_TAB
1710 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1711 AS2 (cpc,%D0,__zero_reg__));
1713 return (AS2 (cpi,%A0,lo8(%1)) CR_TAB
1714 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1715 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1716 AS2 (cpc,%D0,__zero_reg__));
1718 if (reg_unused_after (insn, operands[0]))
1719 return (AS2 (subi,%A0,lo8(%1)) CR_TAB
1720 AS2 (sbci,%B0,hi8(%1)) CR_TAB
1721 AS2 (sbci,%C0,hlo8(%1)) CR_TAB
1722 AS2 (sbci,%D0,hhi8(%1)));
1724 return (AS2 (cpi, %A0,lo8(%1)) CR_TAB
1725 AS2 (ldi, %2,hi8(%1)) CR_TAB
1726 AS2 (cpc, %B0,%2) CR_TAB
1727 AS2 (ldi, %2,hlo8(%1)) CR_TAB
1728 AS2 (cpc, %C0,%2) CR_TAB
1729 AS2 (ldi, %2,hhi8(%1)) CR_TAB
1732 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
1733 AS2 (cp,%A0,%2) CR_TAB
1734 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1735 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1736 AS2 (cpc,%D0,__zero_reg__));
1738 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1739 AS2 (cp, %A0,%2) CR_TAB
1740 AS2 (ldi, %2,hi8(%1)) CR_TAB
1741 AS2 (cpc, %B0,%2) CR_TAB
1742 AS2 (ldi, %2,hlo8(%1)) CR_TAB
1743 AS2 (cpc, %C0,%2) CR_TAB
1744 AS2 (ldi, %2,hhi8(%1)) CR_TAB
1749 [(set_attr "cc" "compare,compare,compare,compare,compare")
1750 (set_attr "length" "4,4,7,5,8")])
1752 ;; ----------------------------------------------------------------------
1753 ;; JUMP INSTRUCTIONS
1754 ;; ----------------------------------------------------------------------
1755 ;; Conditional jump instructions
1757 (define_expand "beq"
1759 (if_then_else (eq (cc0) (const_int 0))
1760 (label_ref (match_operand 0 "" ""))
1765 (define_expand "bne"
1767 (if_then_else (ne (cc0) (const_int 0))
1768 (label_ref (match_operand 0 "" ""))
1773 (define_expand "bge"
1775 (if_then_else (ge (cc0) (const_int 0))
1776 (label_ref (match_operand 0 "" ""))
1781 (define_expand "bgeu"
1783 (if_then_else (geu (cc0) (const_int 0))
1784 (label_ref (match_operand 0 "" ""))
1789 (define_expand "blt"
1791 (if_then_else (lt (cc0) (const_int 0))
1792 (label_ref (match_operand 0 "" ""))
1797 (define_expand "bltu"
1799 (if_then_else (ltu (cc0) (const_int 0))
1800 (label_ref (match_operand 0 "" ""))
1807 /****************************************************************
1808 AVR not have following conditional jumps: LE,LEU,GT,GTU.
1809 Convert them all to proper jumps.
1810 *****************************************************************/
1812 (define_expand "ble"
1814 (if_then_else (le (cc0) (const_int 0))
1815 (label_ref (match_operand 0 "" ""))
1820 (define_expand "bleu"
1822 (if_then_else (leu (cc0) (const_int 0))
1823 (label_ref (match_operand 0 "" ""))
1828 (define_expand "bgt"
1830 (if_then_else (gt (cc0) (const_int 0))
1831 (label_ref (match_operand 0 "" ""))
1836 (define_expand "bgtu"
1838 (if_then_else (gtu (cc0) (const_int 0))
1839 (label_ref (match_operand 0 "" ""))
1844 ;; Test a single bit in a QI/HI/SImode register.
1845 (define_insn "*sbrx_branch"
1848 (match_operator 0 "comparison_operator"
1850 (match_operand:QI 1 "register_operand" "r")
1852 (match_operand 2 "const_int_operand" "n"))
1854 (label_ref (match_operand 3 "" ""))
1856 "GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE"
1857 "* return avr_out_sbxx_branch (insn, operands);"
1858 [(set (attr "length")
1859 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1860 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1862 (if_then_else (eq_attr "mcu_mega" "no")
1865 (set_attr "cc" "clobber")])
1867 (define_insn "*sbrx_and_branchhi"
1870 (match_operator 0 "comparison_operator"
1872 (match_operand:HI 1 "register_operand" "r")
1873 (match_operand:HI 2 "const_int_operand" "n"))
1875 (label_ref (match_operand 3 "" ""))
1877 "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
1878 && exact_log2 (INTVAL (operands[2]) & 0xffff) >= 0"
1879 "* return avr_out_sbxx_branch (insn, operands);"
1880 [(set (attr "length")
1881 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1882 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1884 (if_then_else (eq_attr "mcu_mega" "no")
1887 (set_attr "cc" "clobber")])
1889 (define_insn "*sbrx_and_branchsi"
1892 (match_operator 0 "comparison_operator"
1894 (match_operand:SI 1 "register_operand" "r")
1895 (match_operand:SI 2 "const_int_operand" "n"))
1897 (label_ref (match_operand 3 "" ""))
1899 "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
1900 && exact_log2 (INTVAL (operands[2]) & 0xffffffff) >= 0"
1901 "* return avr_out_sbxx_branch (insn, operands);"
1902 [(set (attr "length")
1903 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1904 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1906 (if_then_else (eq_attr "mcu_mega" "no")
1909 (set_attr "cc" "clobber")])
1911 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
1913 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1914 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1915 (label_ref (match_operand 1 "" ""))
1918 [(set (pc) (if_then_else (eq (zero_extract (match_dup 0)
1922 (label_ref (match_dup 1))
1927 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1928 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1929 (label_ref (match_operand 1 "" ""))
1932 [(set (pc) (if_then_else (ne (zero_extract (match_dup 0)
1936 (label_ref (match_dup 1))
1941 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1942 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1943 (label_ref (match_operand 1 "" ""))
1946 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
1948 (label_ref (match_dup 1))
1953 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1954 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1955 (label_ref (match_operand 1 "" ""))
1958 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
1960 (label_ref (match_dup 1))
1965 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1966 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1967 (label_ref (match_operand 1 "" ""))
1970 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
1972 (label_ref (match_dup 1))
1974 "operands[2] = GEN_INT (-2147483647 - 1);")
1977 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1978 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1979 (label_ref (match_operand 1 "" ""))
1982 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
1984 (label_ref (match_dup 1))
1986 "operands[2] = GEN_INT (-2147483647 - 1);")
1988 ;; ************************************************************************
1989 ;; Implementation of conditional jumps here.
1990 ;; Compare with 0 (test) jumps
1991 ;; ************************************************************************
1993 (define_insn "branch"
1995 (if_then_else (match_operator 1 "comparison_operator"
1998 (label_ref (match_operand 0 "" ""))
2000 "! (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GTU
2001 || GET_CODE (operands[1]) == LE || GET_CODE (operands[1]) == LEU)"
2003 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2004 [(set_attr "type" "branch")
2005 (set_attr "cc" "clobber")])
2007 (define_insn "difficult_branch"
2009 (if_then_else (match_operator 1 "comparison_operator"
2012 (label_ref (match_operand 0 "" ""))
2014 "(GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GTU
2015 || GET_CODE (operands[1]) == LE || GET_CODE (operands[1]) == LEU)"
2017 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2018 [(set_attr "type" "branch1")
2019 (set_attr "cc" "clobber")])
2023 (define_insn "rvbranch"
2025 (if_then_else (match_operator 1 "comparison_operator" [(cc0)
2028 (label_ref (match_operand 0 "" ""))))]
2029 "! (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GTU
2030 || GET_CODE (operands[1]) == LE || GET_CODE (operands[1]) == LEU)"
2032 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2033 [(set_attr "type" "branch1")
2034 (set_attr "cc" "clobber")])
2036 (define_insn "difficult_rvbranch"
2038 (if_then_else (match_operator 1 "comparison_operator" [(cc0)
2041 (label_ref (match_operand 0 "" ""))))]
2042 "(GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GTU
2043 || GET_CODE (operands[1]) == LE || GET_CODE (operands[1]) == LEU)"
2045 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2046 [(set_attr "type" "branch")
2047 (set_attr "cc" "clobber")])
2049 ;; **************************************************************************
2050 ;; Unconditional and other jump instructions.
2054 (label_ref (match_operand 0 "" "")))]
2057 if (AVR_MEGA && get_attr_length (insn) != 1)
2058 return AS1 (jmp,%0);
2059 return AS1 (rjmp,%0);
2061 [(set (attr "length")
2062 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2063 (le (minus (pc) (match_dup 0)) (const_int 2047)))
2066 (set_attr "cc" "none")])
2070 (define_expand "call"
2071 [(call (match_operand:HI 0 "call_insn_operand" "")
2072 (match_operand:HI 1 "general_operand" ""))]
2073 ;; Operand 1 not used on the AVR.
2079 (define_expand "call_value"
2080 [(set (match_operand 0 "register_operand" "")
2081 (call (match_operand:HI 1 "call_insn_operand" "")
2082 (match_operand:HI 2 "general_operand" "")))]
2083 ;; Operand 2 not used on the AVR.
2087 (define_insn "call_insn"
2088 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,i"))
2089 (match_operand:HI 1 "general_operand" "X,X,X"))]
2090 ;; We don't need in saving Z register because r30,r31 is a call used registers
2091 ;; Operand 1 not used on the AVR.
2092 "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
2094 if (which_alternative==0)
2096 else if (which_alternative==1)
2099 return (AS2 (movw, r30, %0) CR_TAB
2102 return (AS2 (mov, r30, %A0) CR_TAB
2103 AS2 (mov, r31, %B0) CR_TAB
2106 return AS1(%~call,%c0);
2108 [(set_attr "cc" "clobber,clobber,clobber")
2109 (set_attr_alternative "length"
2111 (if_then_else (eq_attr "mcu_enhanced" "yes")
2114 (if_then_else (eq_attr "mcu_mega" "yes")
2118 (define_insn "call_value_insn"
2119 [(set (match_operand 0 "register_operand" "=r,r,r")
2120 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,i"))
2121 ;; We don't need in saving Z register because r30,r31 is a call used registers
2122 (match_operand:HI 2 "general_operand" "X,X,X")))]
2123 ;; Operand 2 not used on the AVR.
2124 "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
2127 if (which_alternative==0)
2129 else if (which_alternative==1)
2132 return (AS2 (movw, r30, %1) CR_TAB
2135 return (AS2 (mov, r30, %A1) CR_TAB
2136 AS2 (mov, r31, %B1) CR_TAB
2139 return AS1(%~call,%c1);
2141 [(set_attr "cc" "clobber,clobber,clobber")
2142 (set_attr_alternative "length"
2144 (if_then_else (eq_attr "mcu_enhanced" "yes")
2147 (if_then_else (eq_attr "mcu_mega" "yes")
2151 (define_insn "return"
2153 "reload_completed && avr_simple_epilogue ()"
2155 [(set_attr "cc" "none")
2156 (set_attr "length" "1")])
2162 [(set_attr "cc" "none")
2163 (set_attr "length" "1")])
2166 (define_insn "indirect_jump"
2167 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2171 push %A0\;push %B0\;ret"
2172 [(set_attr "length" "1,3")
2173 (set_attr "cc" "none,none")])
2177 ;; Table made from "rjmp" instructions for <=8K devices.
2178 (define_insn "*tablejump_rjmp"
2179 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] 1))
2180 (use (label_ref (match_operand 1 "" "")))
2181 (clobber (match_dup 0))]
2185 push %A0\;push %B0\;ret"
2186 [(set_attr "length" "1,3")
2187 (set_attr "cc" "none,none")])
2189 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2190 (define_insn "*tablejump_lib"
2191 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
2192 (use (label_ref (match_operand 1 "" "")))
2193 (clobber (match_dup 0))]
2194 "AVR_MEGA && TARGET_CALL_PROLOGUES"
2195 "jmp __tablejump2__"
2196 [(set_attr "length" "2")
2197 (set_attr "cc" "clobber")])
2199 (define_insn "*tablejump_enh"
2200 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
2201 (use (label_ref (match_operand 1 "" "")))
2202 (clobber (match_dup 0))]
2203 "AVR_MEGA && AVR_ENHANCED"
2210 [(set_attr "length" "6")
2211 (set_attr "cc" "clobber")])
2213 (define_insn "*tablejump"
2214 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
2215 (use (label_ref (match_operand 1 "" "")))
2216 (clobber (match_dup 0))]
2226 [(set_attr "length" "8")
2227 (set_attr "cc" "clobber")])
2229 (define_expand "casesi"
2231 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2232 (match_operand:HI 1 "register_operand" "")))
2233 (parallel [(set (cc0)
2234 (compare (match_dup 6)
2235 (match_operand:HI 2 "register_operand" "")))
2236 (clobber (match_scratch:QI 9 ""))])
2239 (if_then_else (gtu (cc0)
2241 (label_ref (match_operand 4 "" ""))
2245 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2247 (parallel [(set (pc) (unspec:HI [(match_dup 6)] 1))
2248 (use (label_ref (match_dup 3)))
2249 (clobber (match_dup 6))])]
2253 operands[6] = gen_reg_rtx (HImode);
2257 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2258 ;; This instruction sets Z flag
2261 [(set (cc0) (const_int 0))]
2264 [(set_attr "length" "1")
2265 (set_attr "cc" "compare")])
2267 ;; Clear/set/test a single bit in I/O address space.
2270 [(set (mem:QI (match_operand 0 "const_int_operand" "n"))
2271 (and:QI (mem:QI (match_dup 0))
2272 (match_operand 1 "const_int_operand" "n")))]
2273 "avr_io_address_p (operands[0], 1 + 0x20)
2274 && exact_log2 (~INTVAL (operands[1]) & 0xff) >= 0"
2276 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2277 return AS2 (cbi,%0-0x20,%2);
2279 [(set_attr "length" "1")
2280 (set_attr "cc" "none")])
2283 [(set (mem:QI (match_operand 0 "const_int_operand" "n"))
2284 (ior:QI (mem:QI (match_dup 0))
2285 (match_operand 1 "const_int_operand" "n")))]
2286 "avr_io_address_p (operands[0], 1 + 0x20)
2287 && exact_log2 (INTVAL (operands[1]) & 0xff) >= 0"
2289 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2290 return AS2 (sbi,%0-0x20,%2);
2292 [(set_attr "length" "1")
2293 (set_attr "cc" "none")])
2295 ;; Lower half of the I/O space - use sbic/sbis directly.
2296 (define_insn "*sbix_branch"
2299 (match_operator 0 "comparison_operator"
2301 (mem:QI (match_operand 1 "const_int_operand" "n"))
2303 (match_operand 2 "const_int_operand" "n"))
2305 (label_ref (match_operand 3 "" ""))
2307 "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
2308 && avr_io_address_p (operands[1], 1 + 0x20)"
2309 "* return avr_out_sbxx_branch (insn, operands);"
2310 [(set (attr "length")
2311 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2312 (le (minus (pc) (match_dup 3)) (const_int 2046)))
2314 (if_then_else (eq_attr "mcu_mega" "no")
2317 (set_attr "cc" "clobber")])
2319 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
2320 (define_insn "*sbix_branch_bit7"
2323 (match_operator 0 "comparison_operator"
2324 [(mem:QI (match_operand 1 "const_int_operand" "n"))
2326 (label_ref (match_operand 2 "" ""))
2328 "(GET_CODE (operands[0]) == GE || GET_CODE (operands[0]) == LT)
2329 && avr_io_address_p (operands[1], 1 + 0x20)"
2331 operands[3] = operands[2];
2332 operands[2] = GEN_INT (7);
2333 return avr_out_sbxx_branch (insn, operands);
2335 [(set (attr "length")
2336 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2337 (le (minus (pc) (match_dup 2)) (const_int 2046)))
2339 (if_then_else (eq_attr "mcu_mega" "no")
2342 (set_attr "cc" "clobber")])
2344 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
2345 (define_insn "*sbix_branch_tmp"
2348 (match_operator 0 "comparison_operator"
2350 (mem:QI (match_operand 1 "const_int_operand" "n"))
2352 (match_operand 2 "const_int_operand" "n"))
2354 (label_ref (match_operand 3 "" ""))
2356 "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
2357 && avr_io_address_p (operands[1], 1) && INTVAL (operands[1]) >= 0x40"
2358 "* return avr_out_sbxx_branch (insn, operands);"
2359 [(set (attr "length")
2360 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2361 (le (minus (pc) (match_dup 3)) (const_int 2045)))
2363 (if_then_else (eq_attr "mcu_mega" "no")
2366 (set_attr "cc" "clobber")])
2368 (define_insn "*sbix_branch_tmp_bit7"
2371 (match_operator 0 "comparison_operator"
2372 [(mem:QI (match_operand 1 "const_int_operand" "n"))
2374 (label_ref (match_operand 2 "" ""))
2376 "(GET_CODE (operands[0]) == GE || GET_CODE (operands[0]) == LT)
2377 && avr_io_address_p (operands[1], 1) && INTVAL (operands[1]) >= 0x40"
2379 operands[3] = operands[2];
2380 operands[2] = GEN_INT (7);
2381 return avr_out_sbxx_branch (insn, operands);
2383 [(set (attr "length")
2384 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2385 (le (minus (pc) (match_dup 2)) (const_int 2045)))
2387 (if_then_else (eq_attr "mcu_mega" "no")
2390 (set_attr "cc" "clobber")])
2392 ;; ************************* Peepholes ********************************
2395 [(set (match_operand:SI 0 "register_operand" "")
2396 (plus:SI (match_dup 0)
2400 (compare (match_dup 0)
2402 (clobber (match_operand:QI 1 "register_operand" ""))])
2404 (if_then_else (ne (cc0) (const_int 0))
2405 (label_ref (match_operand 2 "" ""))
2407 "(test_hard_reg_class (LD_REGS, operands[0])
2408 && test_hard_reg_class (LD_REGS, operands[1]))"
2412 if (test_hard_reg_class (ADDW_REGS, operands[0]))
2413 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
2414 AS2 (sbc,%C0,__zero_reg__) CR_TAB
2415 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2417 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2418 AS2 (sbc,%B0,__zero_reg__) CR_TAB
2419 AS2 (sbc,%C0,__zero_reg__) CR_TAB
2420 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2421 switch (avr_jump_mode (operands[2],insn))
2424 return AS1 (brcc,%2);
2426 return (AS1 (brcs,.+2) CR_TAB
2429 return (AS1 (brcs,.+4) CR_TAB
2434 [(set (match_operand:HI 0 "register_operand" "")
2435 (plus:HI (match_dup 0)
2439 (compare (match_dup 0)
2441 (clobber (match_operand:QI 1 "register_operand" ""))])
2443 (if_then_else (ne (cc0) (const_int 0))
2444 (label_ref (match_operand 2 "" ""))
2446 "(test_hard_reg_class (LD_REGS, operands[0])
2447 && test_hard_reg_class (LD_REGS, operands[1]))"
2451 if (test_hard_reg_class (ADDW_REGS, operands[0]))
2452 output_asm_insn (AS2 (sbiw,%0,1), operands);
2454 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2455 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
2456 switch (avr_jump_mode (operands[2],insn))
2459 return AS1 (brcc,%2);
2461 return (AS1 (brcs,.+2) CR_TAB
2464 return (AS1 (brcs,.+4) CR_TAB
2469 [(set (match_operand:QI 0 "register_operand" "")
2470 (plus:QI (match_dup 0)
2473 (compare (match_dup 0)
2476 (if_then_else (ne (cc0) (const_int 0))
2477 (label_ref (match_operand 1 "" ""))
2479 "test_hard_reg_class (LD_REGS, operands[0])"
2483 cc_status.value1 = operands[0];
2484 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2485 output_asm_insn (AS2 (subi,%A0,1), operands);
2486 switch (avr_jump_mode (operands[1],insn))
2489 return AS1 (brcc,%1);
2491 return (AS1 (brcs,.+2) CR_TAB
2494 return (AS1 (brcs,.+4) CR_TAB
2499 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
2501 (if_then_else (eq (cc0) (const_int 0))
2502 (label_ref (match_operand 1 "" ""))
2504 "jump_over_one_insn_p (insn, operands[1])"
2505 "cpse %0,__zero_reg__")
2509 (compare (match_operand:QI 0 "register_operand" "")
2510 (match_operand:QI 1 "register_operand" "")))
2512 (if_then_else (eq (cc0) (const_int 0))
2513 (label_ref (match_operand 2 "" ""))
2515 "jump_over_one_insn_p (insn, operands[2])"