1 ;; -*- Mode: Scheme -*-
2 ;; Machine description for GNU compiler,
3 ;; for ATMEL AVR micro controllers.
4 ;; Copyright (C)
1998,
1999,
2000 Free Software Foundation, Inc.
5 ;; Contributed by Denis Chertykov (denisc@overta.ru)
7 ;; This file is part of GNU CC.
9 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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 ;; Condition code settings.
25 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
26 (const_string "none"))
28 (define_attr "type" "branch,branch1,arith"
29 (const_string "arith"))
31 ;; The size of instructions in bytes.
32 ;; XXX may depend from "cc"
34 (define_attr "length" ""
35 (cond [(eq_attr "type" "branch")
36 (if_then_else (and (ge (minus (pc) (match_dup
0))
38 (le (minus (pc) (match_dup
0))
41 (if_then_else (and (ge (minus (pc) (match_dup
0))
43 (le (minus (pc) (match_dup
0))
47 (eq_attr "type" "branch1")
48 (if_then_else (and (ge (minus (pc) (match_dup
0))
50 (le (minus (pc) (match_dup
0))
53 (if_then_else (and (ge (minus (pc) (match_dup
0))
55 (le (minus (pc) (match_dup
0))
62 [(set (reg:HI
32) (plus:HI (reg:HI
32) (const_int
1)))]
65 [(set_attr "length" "
1")])
68 [(set (reg:HI
32) (plus:HI (reg:HI
32) (const_int
2)))]
72 [(set_attr "length" "
2")])
75 [(set (reg:HI
32) (plus:HI (reg:HI
32) (const_int
3)))]
80 [(set_attr "length" "
3")])
83 [(set (reg:HI
32) (plus:HI (reg:HI
32) (const_int
4)))]
89 [(set_attr "length" "
4")])
92 [(set (reg:HI
32) (plus:HI (reg:HI
32) (const_int
5)))]
99 [(set_attr "length" "
5")])
101 (define_insn "*pushqi"
102 [(set (mem:QI (post_dec (reg:HI
32)))
103 (match_operand:QI
0 "nonmemory_operand" "r,L"))]
104 "(operands[
0] == const0_rtx || register_operand (operands[
0], QImode))"
108 [(set_attr "length" "
1,
1")])
111 (define_insn "*pushhi"
112 [(set (mem:HI (post_dec (reg:HI
32)))
113 (match_operand:HI
0 "nonmemory_operand" "r,L"))]
114 "(operands[
0] == const0_rtx || register_operand (operands[
0], HImode))"
117 push __zero_reg__\;push __zero_reg__"
118 [(set_attr "length" "
2,
2")])
120 (define_insn "*pushsi"
121 [(set (mem:SI (post_dec (reg:HI
32)))
122 (match_operand:SI
0 "nonmemory_operand" "r,L"))]
123 "(operands[
0] == const0_rtx || register_operand (operands[
0], SImode))"
125 push %D0\;push %C0\;push %B0\;push %A0
126 push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
127 [(set_attr "length" "
4,
4")])
129 (define_insn "*pushsf"
130 [(set (mem:SF (post_dec (reg:HI
32)))
131 (match_operand:SF
0 "register_operand" "r"))]
137 [(set_attr "length" "
4")])
139 ;;========================================================================
141 ;; The last alternative (any immediate constant to any register) is
142 ;; very expensive. It should be optimized by peephole2 if a scratch
143 ;; register is available, but then that register could just as well be
144 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
145 ;; are call-saved registers, and most of LD_REGS are call-used registers,
146 ;; so this may still be a win for registers live across function calls.
148 (define_expand "movqi"
149 [(set (match_operand:QI
0 "nonimmediate_operand" "")
150 (match_operand:QI
1 "general_operand" ""))]
152 "/* One of the ops has to be in a register */
153 if (!register_operand(operand0, QImode)
154 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
155 operands[
1] = copy_to_mode_reg(QImode, operand1);
158 (define_insn "*movqi"
159 [(set (match_operand:QI
0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
160 (match_operand:QI
1 "general_operand" "r,i,rL,Qm,r,q,i"))]
161 "(register_operand (operands[
0],QImode)
162 || register_operand (operands[
1], QImode) || const0_rtx == operands[
1])"
163 "* return output_movqi (insn, operands, NULL);"
164 [(set_attr "length" "
1,
1,
5,
5,
1,
1,
4")
165 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
167 ;; This is used in peephole2 to optimize loading immediate constants
168 ;; if a scratch register from LD_REGS happens to be available.
170 (define_insn "*reload_inqi"
171 [(set (match_operand:QI
0 "register_operand" "=l")
172 (match_operand:QI
1 "immediate_operand" "i"))
173 (clobber (match_operand:QI
2 "register_operand" "=&d"))]
177 [(set_attr "length" "
2")
178 (set_attr "cc" "none")])
180 ;;============================================================================
181 ;; move word (
16 bit)
183 (define_expand "movhi"
184 [(set (match_operand:HI
0 "nonimmediate_operand" "")
185 (match_operand:HI
1 "general_operand" ""))]
189 /* One of the ops has to be in a register */
190 if (!register_operand(operand0, HImode)
191 && !(register_operand(operand1, HImode) || const0_rtx == operands[
1]))
193 operands[
1] = copy_to_mode_reg(HImode, operand1);
199 [(match_scratch:QI
2 "d")
200 (set (match_operand:HI
0 "register_operand" "")
201 (match_operand:HI
1 "immediate_operand" ""))]
202 "(operands[
1] != const0_rtx
203 && test_hard_reg_class (NO_LD_REGS, operands[
0]))"
204 [(parallel [(set (match_dup
0) (match_dup
1))
205 (clobber (match_dup
2))])]
208 ;; '*' because it is not used in rtl generation, only in above peephole
209 (define_insn "*reload_inhi"
210 [(set (match_operand:HI
0 "register_operand" "=r")
211 (match_operand:HI
1 "immediate_operand" "i"))
212 (clobber (match_operand:QI
2 "register_operand" "=&d"))]
214 "* return output_reload_inhi (insn, operands, NULL);"
215 [(set_attr "length" "
4")
216 (set_attr "cc" "none")])
218 (define_insn "*movhi"
219 [(set (match_operand:HI
0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
220 (match_operand:HI
1 "general_operand" "r,m,rL,i,i,r,q"))]
221 "(register_operand (operands[
0],HImode)
222 || register_operand (operands[
1],HImode) || const0_rtx == operands[
1])"
223 "* return output_movhi (insn, operands, NULL);"
224 [(set_attr "length" "
2,
4,
4,
2,
6,
5,
2")
225 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
227 ;;==========================================================================
228 ;; move double word (
32 bit)
230 (define_expand "movsi"
231 [(set (match_operand:SI
0 "nonimmediate_operand" "")
232 (match_operand:SI
1 "general_operand" ""))]
236 /* One of the ops has to be in a register. */
237 if (!register_operand (operand0, SImode)
238 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
240 operands[
1] = copy_to_mode_reg (SImode, operand1);
247 [(match_scratch:QI
2 "d")
248 (set (match_operand:SI
0 "register_operand" "")
249 (match_operand:SI
1 "immediate_operand" ""))]
250 "(operands[
1] != const0_rtx
251 && test_hard_reg_class (NO_LD_REGS, operands[
0]))"
252 [(parallel [(set (match_dup
0) (match_dup
1))
253 (clobber (match_dup
2))])]
256 ;; '*' because it is not used in rtl generation.
257 (define_insn "*reload_insi"
258 [(set (match_operand:SI
0 "register_operand" "=r")
259 (match_operand:SI
1 "immediate_operand" "i"))
260 (clobber (match_operand:QI
2 "register_operand" "=&d"))]
262 "* return output_reload_insisf (insn, operands, NULL);"
263 [(set_attr "length" "
8")
264 (set_attr "cc" "none")])
267 (define_insn "*movsi"
268 [(set (match_operand:SI
0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
269 (match_operand:SI
1 "general_operand" "r,L,Qm,rL,i,i"))]
270 "(register_operand (operands[
0],SImode)
271 || register_operand (operands[
1],SImode) || const0_rtx == operands[
1])"
272 "* return output_movsisf (insn, operands, NULL);"
273 [(set_attr "length" "
4,
4,
8,
8,
4,
10")
274 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
276 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
277 ;; move floating point numbers (
32 bit)
279 (define_expand "movsf"
280 [(set (match_operand:SF
0 "nonimmediate_operand" "")
281 (match_operand:SF
1 "general_operand" ""))]
285 /* One of the ops has to be in a register. */
286 if (!register_operand (operand1, SFmode)
287 && !register_operand (operand0, SFmode))
289 operands[
1] = copy_to_mode_reg (SFmode, operand1);
293 (define_insn "*movsf"
294 [(set (match_operand:SF
0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
295 (match_operand:SF
1 "general_operand" "r,G,Qm,r,F,F"))]
296 "register_operand (operands[
0], SFmode)
297 || register_operand (operands[
1], SFmode)"
298 "* return output_movsisf (insn, operands, NULL);"
299 [(set_attr "length" "
4,
4,
8,
8,
4,
10")
300 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
302 ;;=========================================================================
303 ;; move string (like memcpy)
305 (define_expand "movstrhi"
306 [(parallel [(set (match_operand:BLK
0 "memory_operand" "")
307 (match_operand:BLK
1 "memory_operand" ""))
308 (use (match_operand:HI
2 "const_int_operand" ""))
309 (use (match_operand:HI
3 "const_int_operand" ""))
310 (clobber (match_dup
4))
311 (clobber (match_dup
5))
312 (clobber (match_dup
6))])]
318 if (GET_CODE (operands[
2]) != CONST_INT)
320 cnt8 = byte_immediate_operand (operands[
2], GET_MODE (operands[
2]));
321 operands[
2] = copy_to_mode_reg (cnt8 ? QImode : HImode, operands[
2]);
322 operands[
4] = operands[
2];
324 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
325 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
330 operands[
0] = gen_rtx (MEM, BLKmode, addr0);
331 operands[
1] = gen_rtx (MEM, BLKmode, addr1);
334 (define_insn "*movstrqi_insn"
335 [(set (mem:BLK (match_operand:HI
0 "register_operand" "e"))
336 (mem:BLK (match_operand:HI
1 "register_operand" "e")))
337 (use (match_operand:QI
2 "register_operand" "r"))
338 (use (match_operand:QI
3 "const_int_operand" "i"))
339 (clobber (match_dup
2))
340 (clobber (match_dup
0))
341 (clobber (match_dup
1))]
348 [(set_attr "length" "
4")
349 (set_attr "cc" "clobber")])
351 (define_insn "*movstrhi"
352 [(set (mem:BLK (match_operand:HI
0 "register_operand" "e,e"))
353 (mem:BLK (match_operand:HI
1 "register_operand" "e,e")))
354 (use (match_operand:HI
2 "register_operand" "!w,d"))
355 (use (match_operand:HI
3 "const_int_operand" ""))
356 (clobber (match_dup
2))
357 (clobber (match_dup
0))
358 (clobber (match_dup
1))]
361 if (which_alternative==
0)
362 return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
363 AS2 (st,%a0+,__tmp_reg__) CR_TAB
364 AS2 (sbiw,%A2,
1) CR_TAB
367 return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
368 AS2 (st,%a0+,__tmp_reg__) CR_TAB
369 AS2 (subi,%A2,
1) CR_TAB
370 AS2 (sbci,%B2,
0) CR_TAB
373 [(set_attr "length" "
4,
5")
374 (set_attr "cc" "clobber,clobber")])
376 ;; =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0 =
0
377 ;; memset (%
0,
0, %
1)
379 (define_expand "clrstrhi"
380 [(parallel [(set (match_operand:BLK
0 "memory_operand" "")
382 (use (match_operand:HI
1 "const_int_operand" ""))
383 (use (match_operand:HI
2 "const_int_operand" "n"))
384 (clobber (match_dup
3))
385 (clobber (match_dup
4))])]
391 if (GET_CODE (operands[
1]) != CONST_INT)
394 cnt8 = byte_immediate_operand (operands[
1], GET_MODE (operands[
1]));
395 operands[
1] = copy_to_mode_reg (cnt8 ? QImode : HImode, operands[
1]);
396 operands[
3] = operands[
1];
398 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
401 operands[
0] = gen_rtx (MEM, BLKmode, addr0);
404 (define_insn "*clrstrqi"
405 [(set (mem:BLK (match_operand:HI
0 "register_operand" "e"))
407 (use (match_operand:QI
1 "register_operand" "r"))
408 (use (match_operand:QI
2 "const_int_operand" "n"))
409 (clobber (match_dup
1))
410 (clobber (match_dup
0))]
416 [(set_attr "length" "
3")
417 (set_attr "cc" "clobber")])
419 (define_insn "*clrstrhi"
420 [(set (mem:BLK (match_operand:HI
0 "register_operand" "e,e"))
422 (use (match_operand:HI
1 "register_operand" "!w,d"))
423 (use (match_operand:HI
2 "const_int_operand" "n,n"))
424 (clobber (match_dup
1))
425 (clobber (match_dup
0))]
428 if (which_alternative==
0)
429 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
430 AS2 (sbiw,%A1,
1) CR_TAB
433 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
434 AS2 (subi,%A1,
1) CR_TAB
435 AS2 (sbci,%B1,
0) CR_TAB
438 [(set_attr "length" "
3,
4")
439 (set_attr "cc" "clobber,clobber")])
441 (define_expand "strlenhi"
444 (unspec:HI [(match_operand:BLK
1 "memory_operand" "")
445 (match_operand:QI
2 "const_int_operand" "")
446 (match_operand:HI
3 "immediate_operand" "")]
0))
447 (clobber (match_dup
6))])
448 (set (match_dup
4) (plus:HI (match_dup
4)
450 (set (match_operand:HI
0 "register_operand" "")
451 (minus:HI (match_dup
4)
455 if (! (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) ==
0))
457 operands[
6] = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
458 operands[
1] = gen_rtx (MEM, BLKmode, operands[
6]);
459 operands[
5] = operands[
6];
460 operands[
4] = gen_reg_rtx (HImode);
463 (define_insn "*strlenhi"
464 [(set (match_operand:HI
0 "register_operand" "=e")
465 (unspec:HI [(mem:BLK (match_operand:HI
1 "register_operand" "%
0"))
467 (match_operand:HI
2 "immediate_operand" "i")]
0))
468 (clobber (match_dup
1))]
473 [(set_attr "length" "
3")
474 (set_attr "cc" "clobber")])
476 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
479 (define_insn "addqi3"
480 [(set (match_operand:QI
0 "register_operand" "=r,d,r,r")
481 (plus:QI (match_operand:QI
1 "register_operand" "%
0,
0,
0,
0")
482 (match_operand:QI
2 "nonmemory_operand" "r,i,P,N")))]
489 [(set_attr "length" "
1,
1,
1,
1")
490 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
493 (define_expand "addhi3"
494 [(set (match_operand:HI
0 "register_operand" "")
495 (plus:HI (match_operand:HI
1 "register_operand" "")
496 (match_operand:HI
2 "nonmemory_operand" "")))]
500 if (GET_CODE (operands[
2]) == CONST_INT)
502 short tmp = INTVAL (operands[
2]);
503 operands[
2] = GEN_INT(tmp);
508 (define_insn "*addhi3_zero_extend"
509 [(set (match_operand:HI
0 "register_operand" "=r")
510 (plus:HI (zero_extend:HI
511 (match_operand:QI
1 "register_operand" "r"))
512 (match_operand:HI
2 "register_operand" "
0")))]
515 adc %B0,__zero_reg__"
516 [(set_attr "length" "
2")
517 (set_attr "cc" "set_n")])
519 (define_insn "*addhi3_zero_extend1"
520 [(set (match_operand:HI
0 "register_operand" "=r")
521 (plus:HI (match_operand:HI
1 "register_operand" "%
0")
523 (match_operand:QI
2 "register_operand" "r"))))]
526 adc %B0,__zero_reg__"
527 [(set_attr "length" "
2")
528 (set_attr "cc" "set_n")])
530 (define_insn "*addhi3_zero_extend2"
531 [(set (match_operand:HI
0 "register_operand" "=r")
533 (zero_extend:HI (match_operand:QI
1 "register_operand" "%
0"))
534 (zero_extend:HI (match_operand:QI
2 "register_operand" "r"))))]
538 adc %B0,__zero_reg__"
539 [(set_attr "length" "
3")
540 (set_attr "cc" "set_n")])
542 (define_insn "*addhi3"
543 [(set (match_operand:HI
0 "register_operand" "=r,!w,!w,d,r,r")
545 (match_operand:HI
1 "register_operand" "%
0,
0,
0,
0,
0,
0")
546 (match_operand:HI
2 "nonmemory_operand" "r,I,J,i,P,N")))]
549 add %A0,%A2\;adc %B0,%B2
552 subi %A0,lo8(-(%
2))\;sbci %B0,hi8(-(%
2))
553 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
554 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
555 [(set_attr "length" "
2,
1,
1,
2,
3,
3")
556 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
558 ;; TODO: use "movw" if available
559 (define_insn "addsi3"
560 [(set (match_operand:SI
0 "register_operand" "=r,!w,!w,d,r,r,&*!w,&*!w")
562 (match_operand:SI
1 "register_operand" "%
0,
0,
0,
0,
0,
0,r,r")
563 (match_operand:SI
2 "nonmemory_operand" "r,I,J,i,P,N,#I,#J")))]
566 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
567 adiw %
0,%
2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
568 sbiw %
0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
569 subi %
0,lo8(-(%
2))\;sbci %B0,hi8(-(%
2))\;sbci %C0,hlo8(-(%
2))\;sbci %D0,hhi8(-(%
2))
570 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
571 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
572 mov %A0,%A1\;mov %B0,%B1\;mov %C0,%C1\;mov %D0,%D1\;adiw %
0,%
2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
573 mov %A0,%A1\;mov %B0,%B1\;mov %C0,%C1\;mov %D0,%D1\;sbiw %
0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
574 [(set_attr "length" "
4,
3,
3,
4,
5,
5,
7,
7")
575 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n,set_n,set_czn")])
577 ;-----------------------------------------------------------------------------
579 (define_insn "subqi3"
580 [(set (match_operand:QI
0 "register_operand" "=r,d")
581 (minus:QI (match_operand:QI
1 "register_operand" "
0,
0")
582 (match_operand:QI
2 "nonmemory_operand" "r,i")))]
587 [(set_attr "length" "
1,
1")
588 (set_attr "cc" "set_czn,set_czn")])
590 (define_insn "subhi3"
591 [(set (match_operand:HI
0 "register_operand" "=r,d")
592 (minus:HI (match_operand:HI
1 "register_operand" "
0,
0")
593 (match_operand:HI
2 "nonmemory_operand" "r,i")))]
596 sub %A0,%A2\;sbc %B0,%B2
597 subi %A0,lo8(%
2)\;sbci %B0,hi8(%
2)"
598 [(set_attr "length" "
2,
2")
599 (set_attr "cc" "set_czn,set_czn")])
601 (define_insn "subsi3"
602 [(set (match_operand:SI
0 "register_operand" "=r,d")
603 (minus:SI (match_operand:SI
1 "register_operand" "
0,
0")
604 (match_operand:SI
2 "nonmemory_operand" "r,i")))]
607 sub %
0,%
2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
608 subi %A0,lo8(%
2)\;sbci %B0,hi8(%
2)\;sbci %C0,hlo8(%
2)\;sbci %D0,hhi8(%
2)"
609 [(set_attr "length" "
4,
4")
610 (set_attr "cc" "set_czn,set_czn")])
612 ;******************************************************************************
615 (define_insn "mulqi3"
616 [(set (match_operand:QI
0 "register_operand" "=r")
617 (mult:QI (match_operand:QI
1 "register_operand" "r")
618 (match_operand:QI
2 "register_operand" "r")))]
623 [(set_attr "length" "
3")
624 (set_attr "cc" "clobber")])
626 (define_insn "mulqihi3"
627 [(set (match_operand:HI
0 "register_operand" "=r")
628 (mult:HI (sign_extend:HI (match_operand:QI
1 "register_operand" "d"))
629 (sign_extend:HI (match_operand:QI
2 "register_operand" "d"))))]
634 [(set_attr "length" "
3")
635 (set_attr "cc" "clobber")])
637 (define_insn "umulqihi3"
638 [(set (match_operand:HI
0 "register_operand" "=r")
639 (mult:HI (zero_extend:HI (match_operand:QI
1 "register_operand" "r"))
640 (zero_extend:HI (match_operand:QI
2 "register_operand" "r"))))]
645 [(set_attr "length" "
3")
646 (set_attr "cc" "clobber")])
648 (define_insn "mulhi3"
649 [(set (match_operand:HI
0 "register_operand" "=&r")
650 (mult:HI (match_operand:HI
1 "register_operand" "r")
651 (match_operand:HI
2 "register_operand" "r")))]
660 [(set_attr "length" "
7")
661 (set_attr "cc" "clobber")])
663 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
666 (define_insn "andqi3"
667 [(set (match_operand:QI
0 "register_operand" "=r,d")
668 (and:QI (match_operand:QI
1 "register_operand" "%
0,
0")
669 (match_operand:QI
2 "nonmemory_operand" "r,i")))]
674 [(set_attr "length" "
1,
1")
675 (set_attr "cc" "set_zn,set_zn")])
677 (define_insn "andhi3"
678 [(set (match_operand:HI
0 "register_operand" "=r,d,r")
679 (and:HI (match_operand:HI
1 "register_operand" "%
0,
0,
0")
680 (match_operand:HI
2 "nonmemory_operand" "r,i,M")))
681 (clobber (match_scratch:QI
3 "=X,X,&d"))]
684 if (which_alternative==
0)
685 return (AS2 (and,%A0,%A2) CR_TAB
687 else if (which_alternative==
1)
689 if (GET_CODE (operands[
2]) == CONST_INT)
691 int mask = INTVAL (operands[
2]);
692 if ((mask &
0xff) !=
0xff)
693 output_asm_insn (AS2 (andi,%A0,lo8(%
2)), operands);
694 if ((mask &
0xff00) !=
0xff00)
695 output_asm_insn (AS2 (andi,%B0,hi8(%
2)), operands);
698 return (AS2 (andi,%A0,lo8(%
2)) CR_TAB
699 AS2 (andi,%B0,hi8(%
2)));
701 return (AS2 (ldi,%
3,lo8(%
2)) CR_TAB
702 AS2 (and,%A0,%
3) CR_TAB
705 [(set_attr "length" "
2,
2,
3")
706 (set_attr "cc" "set_n,clobber,clobber")])
708 (define_insn "andsi3"
709 [(set (match_operand:SI
0 "register_operand" "=r,d")
710 (and:SI (match_operand:SI
1 "register_operand" "%
0,
0")
711 (match_operand:SI
2 "nonmemory_operand" "r,i")))]
714 if (which_alternative==
0)
715 return (AS2 (and, %
0,%
2) CR_TAB
716 AS2 (and, %B0,%B2) CR_TAB
717 AS2 (and, %C0,%C2) CR_TAB
719 else if (which_alternative==
1)
721 if (GET_CODE (operands[
2]) == CONST_INT)
723 HOST_WIDE_INT mask = INTVAL (operands[
2]);
724 if ((mask &
0xff) !=
0xff)
725 output_asm_insn (AS2 (andi,%A0,lo8(%
2)), operands);
726 if ((mask &
0xff00) !=
0xff00)
727 output_asm_insn (AS2 (andi,%B0,hi8(%
2)), operands);
728 if ((mask &
0xff0000UL) !=
0xff0000UL)
729 output_asm_insn (AS2 (andi,%C0,hlo8(%
2)), operands);
730 if ((mask &
0xff000000UL) !=
0xff000000UL)
731 output_asm_insn (AS2 (andi,%D0,hhi8(%
2)), operands);
734 return (AS2 (andi, %A0,lo8(%
2)) CR_TAB
735 AS2 (andi, %B0,hi8(%
2)) CR_TAB
736 AS2 (andi, %C0,hlo8(%
2)) CR_TAB
737 AS2 (andi, %D0,hhi8(%
2)));
741 [(set_attr "length" "
4,
4")
742 (set_attr "cc" "set_n,set_n")])
744 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
747 (define_insn "iorqi3"
748 [(set (match_operand:QI
0 "register_operand" "=r,d")
749 (ior:QI (match_operand:QI
1 "register_operand" "%
0,
0")
750 (match_operand:QI
2 "nonmemory_operand" "r,i")))]
755 [(set_attr "length" "
1,
1")
756 (set_attr "cc" "set_zn,set_zn")])
758 (define_insn "iorhi3"
759 [(set (match_operand:HI
0 "register_operand" "=r,d")
760 (ior:HI (match_operand:HI
1 "register_operand" "%
0,
0")
761 (match_operand:HI
2 "nonmemory_operand" "r,i")))]
764 if (which_alternative==
0)
765 return (AS2 (or,%A0,%A2) CR_TAB
767 if (GET_CODE (operands[
2]) == CONST_INT)
769 int mask = INTVAL (operands[
2]);
771 output_asm_insn (AS2 (ori,%A0,lo8(%
2)), operands);
773 output_asm_insn (AS2 (ori,%B0,hi8(%
2)), operands);
776 return (AS2 (ori,%
0,lo8(%
2)) CR_TAB
777 AS2 (ori,%B0,hi8(%
2)));
779 [(set_attr "length" "
2,
2")
780 (set_attr "cc" "set_n,clobber")])
782 (define_insn "*iorhi3_clobber"
783 [(set (match_operand:HI
0 "register_operand" "=r,r")
784 (ior:HI (match_operand:HI
1 "register_operand" "%
0,
0")
785 (match_operand:HI
2 "immediate_operand" "M,i")))
786 (clobber (match_scratch:QI
3 "=&d,&d"))]
789 ldi %
3,lo8(%
2)\;or %A0,%
3
790 ldi %
3,lo8(%
2)\;or %A0,%
3\;ldi %
3,lo8(%
2)\;or %B0,%
3"
791 [(set_attr "length" "
2,
4")
792 (set_attr "cc" "clobber,set_n")])
794 (define_insn "iorsi3"
795 [(set (match_operand:SI
0 "register_operand" "=r,d")
796 (ior:SI (match_operand:SI
1 "register_operand" "%
0,
0")
797 (match_operand:SI
2 "nonmemory_operand" "r,i")))]
800 if (which_alternative==
0)
801 return (AS2 (or, %
0,%
2) CR_TAB
802 AS2 (or, %B0,%B2) CR_TAB
803 AS2 (or, %C0,%C2) CR_TAB
805 if (GET_CODE (operands[
2]) == CONST_INT)
807 HOST_WIDE_INT mask = INTVAL (operands[
2]);
809 output_asm_insn (AS2 (ori,%A0,lo8(%
2)), operands);
811 output_asm_insn (AS2 (ori,%B0,hi8(%
2)), operands);
812 if (mask &
0xff0000UL)
813 output_asm_insn (AS2 (ori,%C0,hlo8(%
2)), operands);
814 if (mask &
0xff000000UL)
815 output_asm_insn (AS2 (ori,%D0,hhi8(%
2)), operands);
818 return (AS2 (ori, %A0,lo8(%
2)) CR_TAB
819 AS2 (ori, %B0,hi8(%
2)) CR_TAB
820 AS2 (ori, %C0,hlo8(%
2)) CR_TAB
821 AS2 (ori, %D0,hhi8(%
2)));
823 [(set_attr "length" "
4,
4")
824 (set_attr "cc" "set_n,clobber")])
826 (define_insn "*iorsi3_clobber"
827 [(set (match_operand:SI
0 "register_operand" "=r,r")
828 (ior:SI (match_operand:SI
1 "register_operand" "%
0,
0")
829 (match_operand:SI
2 "immediate_operand" "M,i")))
830 (clobber (match_scratch:QI
3 "=&d,&d"))]
833 ldi %
3,lo8(%
2)\;or %A0,%
3
834 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"
835 [(set_attr "length" "
2,
8")
836 (set_attr "cc" "clobber,set_n")])
838 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
841 (define_insn "xorqi3"
842 [(set (match_operand:QI
0 "register_operand" "=r")
843 (xor:QI (match_operand:QI
1 "register_operand" "%
0")
844 (match_operand:QI
2 "register_operand" "r")))]
847 [(set_attr "length" "
1")
848 (set_attr "cc" "set_zn")])
850 (define_insn "xorhi3"
851 [(set (match_operand:HI
0 "register_operand" "=r")
852 (xor:HI (match_operand:HI
1 "register_operand" "%
0")
853 (match_operand:HI
2 "register_operand" "r")))]
855 "eor %
0,%
2\;eor %B0,%B2"
856 [(set_attr "length" "
2")
857 (set_attr "cc" "set_n")])
859 (define_insn "xorsi3"
860 [(set (match_operand:SI
0 "register_operand" "=r")
861 (xor:SI (match_operand:SI
1 "register_operand" "%
0")
862 (match_operand:SI
2 "register_operand" "r")))]
868 [(set_attr "length" "
4")
869 (set_attr "cc" "set_n")])
871 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
872 ;; arithmetic shift left
874 (define_insn "ashlqi3"
875 [(set (match_operand:QI
0 "register_operand" "=r,!d,r,r")
876 (ashift:QI (match_operand:QI
1 "register_operand" "
0,
0,
0,
0")
877 (match_operand:QI
2 "general_operand" "r,n,n,Qm")))]
879 "* return ashlqi3_out (insn, operands, NULL);"
880 [(set_attr "length" "
5,
4,
6,
7")
881 (set_attr "cc" "clobber,set_czn,set_czn,clobber")])
883 (define_insn "ashlhi3"
884 [(set (match_operand:HI
0 "register_operand" "=r,r,r,r,r,r")
885 (ashift:HI (match_operand:HI
1 "register_operand" "
0,
0,r,
0,
0,
0")
886 (match_operand:QI
2 "general_operand" "r,P,O,K,i,Qm")))
887 (clobber (match_scratch:QI
3 "=X,X,X,X,&d,X"))]
889 "* return ashlhi3_out (insn,operands, NULL);"
890 [(set_attr "length" "
7,
2,
4,
2,
5,
8")
891 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")])
893 (define_insn "ashlsi3"
894 [(set (match_operand:SI
0 "register_operand" "=r,r,r,r,r")
895 (ashift:SI (match_operand:SI
1 "register_operand" "
0,
0,r,
0,
0")
896 (match_operand:QI
2 "general_operand" "r,P,O,i,Qm")))
897 (clobber (match_scratch:QI
3 "=X,X,X,&d,X"))]
899 "* return ashlsi3_out (insn,operands, NULL);"
900 [(set_attr "length" "
9,
4,
4,
7,
10")
901 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")])
903 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
904 ;; arithmetic shift right
906 (define_insn "ashrqi3"
907 [(set (match_operand:QI
0 "register_operand" "=r,r,r,r,r")
908 (ashiftrt:QI (match_operand:QI
1 "register_operand" "
0,
0,
0,
0,
0")
909 (match_operand:QI
2 "general_operand" "r,P,K,n,Qm")))]
911 "* return ashrqi3_out (insn, operands, NULL);"
912 [(set_attr "length" "
5,
1,
2,
5,
7")
913 (set_attr "cc" "clobber,set_zn,set_zn,clobber,clobber")])
915 (define_insn "ashrhi3"
916 [(set (match_operand:HI
0 "register_operand" "=r,r,r,r,r,r")
917 (ashiftrt:HI (match_operand:HI
1 "register_operand" "
0,
0,
0,r,
0,
0")
918 (match_operand:QI
2 "general_operand" "r,P,K,O,i,Qm")))
919 (clobber (match_scratch:QI
3 "=X,X,X,X,&d,X"))]
921 "* return ashrhi3_out (insn,operands, NULL);"
922 [(set_attr "length" "
7,
2,
4,
2,
5,
8")
923 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")])
925 (define_insn "ashrsi3"
926 [(set (match_operand:SI
0 "register_operand" "=r,r,r,r,r")
927 (ashiftrt:SI (match_operand:SI
1 "register_operand" "
0,
0,r,
0,
0")
928 (match_operand:QI
2 "general_operand" "r,P,O,i,Qm")))
929 (clobber (match_scratch:QI
3 "=X,X,X,&d,X"))]
931 "* return ashrsi3_out (insn,operands, NULL);"
932 [(set_attr "length" "
9,
4,
6,
7,
10")
933 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")])
935 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
936 ;; logical shift right
938 (define_insn "lshrqi3"
939 [(set (match_operand:QI
0 "register_operand" "=r,d,r,r")
940 (lshiftrt:QI (match_operand:QI
1 "register_operand" "
0,
0,
0,
0")
941 (match_operand:QI
2 "general_operand" "r,n,n,Qm")))]
943 "* return lshrqi3_out (insn,operands, NULL);"
944 [(set_attr "length" "
6,
4,
6,
7")
945 (set_attr "cc" "clobber,set_czn,set_czn,clobber")])
947 (define_insn "lshrhi3"
948 [(set (match_operand:HI
0 "register_operand" "=r,r,r,r,r,r")
949 (lshiftrt:HI (match_operand:HI
1 "register_operand" "
0,
0,
0,r,
0,
0")
950 (match_operand:QI
2 "general_operand" "r,P,K,O,i,Qm")))
951 (clobber (match_scratch:QI
3 "=X,X,X,X,&d,X"))]
953 "* return lshrhi3_out (insn,operands, NULL);"
954 [(set_attr "length" "
7,
2,
4,
2,
5,
8")
955 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")])
957 (define_insn "lshrsi3"
958 [(set (match_operand:SI
0 "register_operand" "=r,r,r,r,r")
959 (lshiftrt:SI (match_operand:SI
1 "register_operand" "
0,
0,r,
0,
0")
960 (match_operand:QI
2 "general_operand" "r,P,O,i,Qm")))
961 (clobber (match_scratch:QI
3 "=X,X,X,&d,X"))]
963 "* return lshrsi3_out (insn,operands, NULL);"
964 [(set_attr "length" "
9,
4,
4,
7,
10")
965 (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")])
967 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
970 (define_insn "absqi2"
971 [(set (match_operand:QI
0 "register_operand" "=r")
972 (abs:QI (match_operand:QI
1 "register_operand" "
0")))]
975 [(set_attr "length" "
2")
976 (set_attr "cc" "clobber")])
979 (define_insn "abssf2"
980 [(set (match_operand:SF
0 "register_operand" "=d,r")
981 (abs:SF (match_operand:SF
1 "register_operand" "
0,
0")))]
986 [(set_attr "length" "
1,
2")
987 (set_attr "cc" "clobber,clobber")])
989 ;;
0 - x
0 - x
0 - x
0 - x
0 - x
0 - x
0 - x
0 - x
0 - x
0 - x
0 - x
992 (define_insn "negqi2"
993 [(set (match_operand:QI
0 "register_operand" "=r")
994 (neg:QI (match_operand:QI
1 "register_operand" "
0")))]
997 [(set_attr "length" "
1")
998 (set_attr "cc" "set_zn")])
1000 (define_insn "neghi2"
1001 [(set (match_operand:HI
0 "register_operand" "=!d,r")
1002 (neg:HI (match_operand:HI
1 "register_operand" "
0,
0")))]
1005 com %B0\;neg %A0\;sbci %B0,lo8(-
1)
1006 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0"
1007 [(set_attr "length" "
3,
4")
1008 (set_attr "cc" "set_czn,set_n")])
1010 (define_insn "*negsi2"
1011 [(set (match_operand:SI
0 "register_operand" "=!d,r,&r")
1012 (neg:SI (match_operand:SI
1 "register_operand" "
0,
0,r")))]
1015 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-
1)\;sbci %C0,lo8(-
1)\;sbci %D0,lo8(-
1)
1016 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1017 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1018 [(set_attr "length" "
7,
8,
8")
1019 (set_attr "cc" "set_czn,set_n,set_czn")])
1021 (define_insn "negsf2"
1022 [(set (match_operand:SF
0 "register_operand" "=d,r")
1023 (neg:SF (match_operand:SF
1 "register_operand" "
0,
0")))]
1027 bst %D0,
7\;com %D0\;bld %D0,
7\;com %D0"
1028 [(set_attr "length" "
1,
4")
1029 (set_attr "cc" "set_n,set_n")])
1031 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1034 (define_insn "one_cmplqi2"
1035 [(set (match_operand:QI
0 "register_operand" "=r")
1036 (not:QI (match_operand:QI
1 "register_operand" "
0")))]
1039 [(set_attr "length" "
1")
1040 (set_attr "cc" "set_czn")])
1042 (define_insn "one_cmplhi2"
1043 [(set (match_operand:HI
0 "register_operand" "=r")
1044 (not:HI (match_operand:HI
1 "register_operand" "
0")))]
1047 [(set_attr "length" "
2")
1048 (set_attr "cc" "set_n")])
1050 (define_insn "one_cmplsi2"
1051 [(set (match_operand:SI
0 "register_operand" "=r")
1052 (not:SI (match_operand:SI
1 "register_operand" "
0")))]
1054 "com %
0\;com %B0\;com %C0\;com %D0"
1055 [(set_attr "length" "
4")
1056 (set_attr "cc" "set_n")])
1058 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1061 (define_insn "extendqihi2"
1062 [(set (match_operand:HI
0 "register_operand" "=r,r")
1063 (sign_extend:HI (match_operand:QI
1 "register_operand" "
0,*r")))]
1066 clr %B0\;sbrc %
0,
7\;com %B0
1067 mov %A0,%A1\;clr %B0\;sbrc %A0,
7\;com %B0"
1068 [(set_attr "length" "
3,
4")
1069 (set_attr "cc" "set_n,set_n")])
1071 (define_insn "extendqisi2"
1072 [(set (match_operand:SI
0 "register_operand" "=r,r")
1073 (sign_extend:SI (match_operand:QI
1 "register_operand" "
0,*r")))]
1076 clr %B0\;sbrc %A0,
7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
1077 mov %A0,%A1\;clr %B0\;sbrc %A0,
7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
1078 [(set_attr "length" "
5,
6")
1079 (set_attr "cc" "clobber,clobber")])
1081 ;; TODO: use "movw" if available
1082 (define_insn "extendhisi2"
1083 [(set (match_operand:SI
0 "register_operand" "=r,&r")
1084 (sign_extend:SI (match_operand:HI
1 "register_operand" "
0,*r")))]
1087 clr %C0\;sbrc %B0,
7\;com %C0\;mov %D0,%C0
1088 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,
7\;com %C0\;mov %D0,%C0"
1089 [(set_attr "length" "
4,
6")
1090 (set_attr "cc" "clobber,clobber")])
1092 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1095 (define_insn "zero_extendqihi2"
1096 [(set (match_operand:HI
0 "register_operand" "=r,r")
1097 (zero_extend:HI (match_operand:QI
1 "register_operand" "
0,*r")))]
1101 mov %A0,%A1\;clr %B0"
1102 [(set_attr "length" "
1,
2")
1103 (set_attr "cc" "set_n,set_n")])
1105 (define_insn "zero_extendqisi2"
1106 [(set (match_operand:SI
0 "register_operand" "=r,r")
1107 (zero_extend:SI (match_operand:QI
1 "register_operand" "
0,*r")))]
1110 clr %B0\;clr %C0\;clr %D0
1111 mov %A0,%A1\;clr %B0\;clr %C0\;clr %D0"
1112 [(set_attr "length" "
3,
4")
1113 (set_attr "cc" "set_n,set_n")])
1115 ;; TODO: use "movw" if available
1116 (define_insn "zero_extendhisi2"
1117 [(set (match_operand:SI
0 "register_operand" "=r,&r")
1118 (zero_extend:SI (match_operand:HI
1 "register_operand" "
0,*r")))]
1122 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;clr %D0"
1123 [(set_attr "length" "
2,
4")
1124 (set_attr "cc" "set_n,set_n")])
1126 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
1129 (define_insn "tstqi"
1131 (match_operand:QI
0 "register_operand" "r"))]
1134 [(set_attr "cc" "compare")
1135 (set_attr "length" "
1")])
1137 (define_insn "*negated_tstqi"
1139 (neg:QI (match_operand:QI
0 "register_operand" "r")))]
1141 "cp __zero_reg__,%
0"
1142 [(set_attr "cc" "compare")
1143 (set_attr "length" "
1")])
1145 (define_insn "tsthi"
1147 (match_operand:HI
0 "register_operand" "!w,r"))]
1149 "* return out_tsthi (insn,NULL);"
1150 [(set_attr "cc" "compare,compare")
1151 (set_attr "length" "
1,
2")])
1153 (define_insn "*negated_tsthi"
1155 (neg:HI (match_operand:HI
0 "register_operand" "r")))]
1157 "cp __zero_reg__,%A0
1158 cpc __zero_reg__,%B0"
1159 [(set_attr "cc" "compare")
1160 (set_attr "length" "
2")])
1162 (define_insn "tstsi"
1164 (match_operand:SI
0 "register_operand" "r"))]
1166 "* return out_tstsi (insn,NULL);"
1167 [(set_attr "cc" "compare")
1168 (set_attr "length" "
4")])
1170 (define_insn "*negated_tstsi"
1172 (neg:SI (match_operand:SI
0 "register_operand" "r")))]
1174 "cp __zero_reg__,%A0
1175 cpc __zero_reg__,%B0
1176 cpc __zero_reg__,%C0
1177 cpc __zero_reg__,%D0"
1178 [(set_attr "cc" "compare")
1179 (set_attr "length" "
4")])
1182 (define_insn "cmpqi"
1184 (compare (match_operand:QI
0 "register_operand" "r,d")
1185 (match_operand:QI
1 "nonmemory_operand" "r,i")))]
1190 [(set_attr "cc" "compare,compare")
1191 (set_attr "length" "
1,
1")])
1193 (define_insn "*cmpqi_sign_extend"
1195 (compare (sign_extend:HI
1196 (match_operand:QI
0 "register_operand" "d"))
1197 (match_operand:HI
1 "immediate_operand" "M")))]
1200 [(set_attr "cc" "compare")
1201 (set_attr "length" "
1")])
1203 (define_insn "cmphi"
1205 (compare (match_operand:HI
0 "register_operand" "r,d,d,r,r")
1206 (match_operand:HI
1 "nonmemory_operand" "r,M,i,M,i")))
1207 (clobber (match_scratch:QI
2 "=X,X,&d,&d,&d"))]
1210 switch (which_alternative)
1213 return (AS2 (cp,%A0,%A1) CR_TAB
1216 if (reg_unused_after (insn, operands[
0])
1217 && INTVAL (operands[
1]) >=
0 && INTVAL (operands[
1]) <=
63
1218 && test_hard_reg_class (ADDW_REGS, operands[
0]))
1219 return AS2 (sbiw,%
0,%
1);
1221 return (AS2 (cpi,%
0,%
1) CR_TAB
1222 AS2 (cpc,%B0,__zero_reg__));
1224 if (reg_unused_after (insn, operands[
0]))
1225 return (AS2 (subi,%
0,lo8(%
1)) CR_TAB
1226 AS2 (sbci,%B0,hi8(%
1)));
1228 return (AS2 (ldi, %
2,hi8(%
1)) CR_TAB
1229 AS2 (cpi, %A0,lo8(%
1)) CR_TAB
1232 return (AS2 (ldi, %
2,lo8(%
1)) CR_TAB
1233 AS2 (cp, %A0,%
2) CR_TAB
1234 AS2 (cpc, %B0,__zero_reg__));
1237 return (AS2 (ldi, %
2,lo8(%
1)) CR_TAB
1238 AS2 (cp, %A0,%
2) CR_TAB
1239 AS2 (ldi, %
2,hi8(%
1)) CR_TAB
1244 [(set_attr "cc" "compare,compare,compare,compare,compare")
1245 (set_attr "length" "
2,
2,
3,
3,
4")])
1248 (define_insn "cmpsi"
1250 (compare (match_operand:SI
0 "register_operand" "r,d,d,r,r")
1251 (match_operand:SI
1 "nonmemory_operand" "r,M,i,M,i")))
1252 (clobber (match_scratch:QI
2 "=X,X,&d,&d,&d"))]
1255 switch (which_alternative)
1258 return (AS2 (cp,%A0,%A1) CR_TAB
1259 AS2 (cpc,%B0,%B1) CR_TAB
1260 AS2 (cpc,%C0,%C1) CR_TAB
1263 if (reg_unused_after (insn, operands[
0])
1264 && INTVAL (operands[
1]) >=
0 && INTVAL (operands[
1]) <=
63
1265 && test_hard_reg_class (ADDW_REGS, operands[
0]))
1266 return (AS2 (sbiw,%
0,%
1) CR_TAB
1267 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1268 AS2 (cpc,%D0,__zero_reg__));
1270 return (AS2 (cpi,%A0,lo8(%
1)) CR_TAB
1271 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1272 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1273 AS2 (cpc,%D0,__zero_reg__));
1275 if (reg_unused_after (insn, operands[
0]))
1276 return (AS2 (subi,%A0,lo8(%
1)) CR_TAB
1277 AS2 (sbci,%B0,hi8(%
1)) CR_TAB
1278 AS2 (sbci,%C0,hlo8(%
1)) CR_TAB
1279 AS2 (sbci,%D0,hhi8(%
1)));
1281 return (AS2 (cpi, %A0,lo8(%
1)) CR_TAB
1282 AS2 (ldi, %
2,hi8(%
1)) CR_TAB
1283 AS2 (cpc, %B0,%
2) CR_TAB
1284 AS2 (ldi, %
2,hlo8(%
1)) CR_TAB
1285 AS2 (cpc, %C0,%
2) CR_TAB
1286 AS2 (ldi, %
2,hhi8(%
1)) CR_TAB
1289 return (AS2 (ldi,%
2,lo8(%
1)) CR_TAB
1290 AS2 (cp,%A0,%
2) CR_TAB
1291 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1292 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1293 AS2 (cpc,%D0,__zero_reg__));
1295 return (AS2 (ldi, %
2,lo8(%
1)) CR_TAB
1296 AS2 (cp, %A0,%
2) CR_TAB
1297 AS2 (ldi, %
2,hi8(%
1)) CR_TAB
1298 AS2 (cpc, %B0,%
2) CR_TAB
1299 AS2 (ldi, %
2,hlo8(%
1)) CR_TAB
1300 AS2 (cpc, %C0,%
2) CR_TAB
1301 AS2 (ldi, %
2,hhi8(%
1)) CR_TAB
1306 [(set_attr "cc" "compare,compare,compare,compare,compare")
1307 (set_attr "length" "
4,
4,
7,
5,
8")])
1309 ;; ----------------------------------------------------------------------
1310 ;; JUMP INSTRUCTIONS
1311 ;; ----------------------------------------------------------------------
1312 ;; Conditional jump instructions
1314 (define_expand "beq"
1316 (if_then_else (eq (cc0) (const_int
0))
1317 (label_ref (match_operand
0 "" ""))
1322 (define_expand "bne"
1324 (if_then_else (ne (cc0) (const_int
0))
1325 (label_ref (match_operand
0 "" ""))
1330 (define_expand "bge"
1332 (if_then_else (ge (cc0) (const_int
0))
1333 (label_ref (match_operand
0 "" ""))
1338 (define_expand "bgeu"
1340 (if_then_else (geu (cc0) (const_int
0))
1341 (label_ref (match_operand
0 "" ""))
1346 (define_expand "blt"
1348 (if_then_else (lt (cc0) (const_int
0))
1349 (label_ref (match_operand
0 "" ""))
1354 (define_expand "bltu"
1356 (if_then_else (ltu (cc0) (const_int
0))
1357 (label_ref (match_operand
0 "" ""))
1364 /****************************************************************
1365 AVR not have following conditional jumps: LE,LEU,GT,GTU.
1366 Convert them all to proper jumps.
1367 *****************************************************************/
1369 (define_expand "ble"
1371 (if_then_else (le (cc0) (const_int
0))
1372 (label_ref (match_operand
0 "" ""))
1377 (define_expand "bleu"
1379 (if_then_else (leu (cc0) (const_int
0))
1380 (label_ref (match_operand
0 "" ""))
1385 (define_expand "bgt"
1387 (if_then_else (gt (cc0) (const_int
0))
1388 (label_ref (match_operand
0 "" ""))
1393 (define_expand "bgtu"
1395 (if_then_else (gtu (cc0) (const_int
0))
1396 (label_ref (match_operand
0 "" ""))
1401 (define_insn "*sbrx_branch"
1404 (match_operator
0 "comparison_operator"
1406 (match_operand:QI
1 "register_operand" "r")
1408 (match_operand
2 "immediate_operand" "n"))
1410 (label_ref (match_operand
3 "" ""))
1412 "(GET_CODE (operands[
0]) == EQ || GET_CODE (operands[
0]) == NE)"
1414 int comp = ((get_attr_length (insn) ==
4)
1415 ? reverse_condition (GET_CODE (operands[
0]))
1416 : GET_CODE (operands[
0]));
1418 output_asm_insn (AS2 (sbrs,%
1,%
2), operands);
1420 output_asm_insn (AS2 (sbrc,%
1,%
2), operands);
1421 if (get_attr_length (insn) !=
4)
1422 return AS1 (rjmp,%
3);
1423 return (AS1 (rjmp,_PC_+
4) CR_TAB
1426 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup
3))
1428 (le (minus (pc) (match_dup
3))
1431 (if_then_else (eq (symbol_ref "AVR_MEGA")
1435 (set_attr "cc" "clobber")])
1437 (define_insn "*sbrx_and_branchsi"
1440 (match_operator
0 "comparison_operator"
1442 (match_operand:SI
1 "register_operand" "r")
1443 (match_operand:SI
2 "immediate_operand" "n"))
1445 (label_ref (match_operand
3 "" ""))
1447 "(GET_CODE (operands[
0]) == EQ || GET_CODE (operands[
0]) == NE)
1448 && mask_one_bit_p(INTVAL (operands[
2]))"
1450 int comp = ((get_attr_length (insn) ==
4)
1451 ? reverse_condition (GET_CODE (operands[
0]))
1452 : GET_CODE (operands[
0]));
1453 int bit = mask_one_bit_p(INTVAL (operands[
2])) -
1;
1454 static char buf[] =
\"sbrc %A1,
0\";
1455 buf[
3] = (comp == EQ ? 's' : 'c');
1456 buf[
6] = bit /
8 + 'A';
1457 buf[
9] = bit %
8 + '
0';
1458 output_asm_insn (buf, operands);
1460 if (get_attr_length (insn) !=
4)
1461 return AS1 (rjmp,%
3);
1462 return (AS1 (rjmp,_PC_+
4) CR_TAB
1465 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup
3))
1467 (le (minus (pc) (match_dup
3))
1470 (if_then_else (eq (symbol_ref "AVR_MEGA")
1474 (set_attr "cc" "clobber")])
1476 (define_insn "*sbrx_and_branchhi"
1479 (match_operator
0 "comparison_operator"
1481 (match_operand:HI
1 "register_operand" "r")
1482 (match_operand:HI
2 "immediate_operand" "n"))
1484 (label_ref (match_operand
3 "" ""))
1486 "(GET_CODE (operands[
0]) == EQ || GET_CODE (operands[
0]) == NE)
1487 && mask_one_bit_p(INTVAL (operands[
2]))"
1489 int comp = ((get_attr_length (insn) ==
4)
1490 ? reverse_condition (GET_CODE (operands[
0]))
1491 : GET_CODE (operands[
0]));
1492 int bit = mask_one_bit_p(INTVAL (operands[
2])) -
1;
1493 static char buf[] =
\"sbrc %A1,
0\";
1494 buf[
3] = (comp == EQ ? 's' : 'c');
1495 buf[
6] = bit /
8 + 'A';
1496 buf[
9] = bit %
8 + '
0';
1497 output_asm_insn (buf, operands);
1499 if (get_attr_length (insn) !=
4)
1500 return AS1 (rjmp,%
3);
1501 return (AS1 (rjmp,_PC_+
4) CR_TAB
1504 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup
3))
1506 (le (minus (pc) (match_dup
3))
1509 (if_then_else (eq (symbol_ref "AVR_MEGA")
1513 (set_attr "cc" "clobber")])
1515 ;; ************************************************************************
1516 ;; Implementation of conditional jumps here.
1517 ;; Compare with
0 (test) jumps
1518 ;; ************************************************************************
1520 (define_insn "branch"
1522 (if_then_else (match_operator
1 "comparison_operator"
1525 (label_ref (match_operand
0 "" ""))
1527 "! (GET_CODE (operands[
1]) == GT || GET_CODE (operands[
1]) == GTU
1528 || GET_CODE (operands[
1]) == LE || GET_CODE (operands[
1]) == LEU)"
1530 return ret_cond_branch (GET_CODE (operands[
1]),
1531 avr_jump_mode (operands[
0],insn));"
1532 [(set_attr "type" "branch")
1533 (set_attr "cc" "clobber")])
1535 (define_insn "difficult_branch"
1537 (if_then_else (match_operator
1 "comparison_operator"
1540 (label_ref (match_operand
0 "" ""))
1542 "(GET_CODE (operands[
1]) == GT || GET_CODE (operands[
1]) == GTU
1543 || GET_CODE (operands[
1]) == LE || GET_CODE (operands[
1]) == LEU)"
1545 return ret_cond_branch (GET_CODE (operands[
1]),
1546 avr_jump_mode (operands[
0],insn));"
1547 [(set_attr "type" "branch1")
1548 (set_attr "cc" "clobber")])
1552 (define_insn "rvbranch"
1554 (if_then_else (match_operator
1 "comparison_operator" [(cc0)
1557 (label_ref (match_operand
0 "" ""))))]
1558 "! (GET_CODE (operands[
1]) == GT || GET_CODE (operands[
1]) == GTU
1559 || GET_CODE (operands[
1]) == LE || GET_CODE (operands[
1]) == LEU)"
1561 return ret_cond_branch (reverse_condition (GET_CODE (operands[
1])),
1562 avr_jump_mode (operands[
0],insn));"
1563 [(set_attr "type" "branch1")
1564 (set_attr "cc" "clobber")])
1566 (define_insn "difficult_rvbranch"
1568 (if_then_else (match_operator
1 "comparison_operator" [(cc0)
1571 (label_ref (match_operand
0 "" ""))))]
1572 "(GET_CODE (operands[
1]) == GT || GET_CODE (operands[
1]) == GTU
1573 || GET_CODE (operands[
1]) == LE || GET_CODE (operands[
1]) == LEU)"
1575 return ret_cond_branch (reverse_condition (GET_CODE (operands[
1])),
1576 avr_jump_mode (operands[
0],insn));"
1577 [(set_attr "type" "branch")
1578 (set_attr "cc" "clobber")])
1580 ;; **************************************************************************
1581 ;; Unconditional and other jump instructions.
1585 (label_ref (match_operand
0 "" "")))]
1588 if (AVR_MEGA && get_attr_length (insn) !=
1)
1592 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup
0))
1594 (le (minus (pc) (match_dup
0))
1598 (set_attr "cc" "none")])
1602 (define_expand "call"
1603 [(call (match_operand:HI
0 "call_insn_operand" "")
1604 (match_operand:HI
1 "general_operand" ""))]
1605 ;; Operand
1 not used on the AVR.
1611 (define_expand "call_value"
1612 [(set (match_operand
0 "register_operand" "")
1613 (call (match_operand:HI
1 "call_insn_operand" "")
1614 (match_operand:HI
2 "general_operand" "")))]
1615 ;; Operand
2 not used on the AVR.
1619 ;; TODO: insn length for AVR_ENHANCED
1620 (define_insn "call_insn"
1621 [(call (mem:HI (match_operand:HI
0 "nonmemory_operand" "!z,*r,i"))
1622 (match_operand:HI
1 "general_operand" "X,X,X"))]
1623 ;; We don't need in saving Z register because r30,r31 is a call used registers
1624 ;; Operand
1 not used on the AVR.
1625 "(register_operand (operands[
0], HImode) || CONSTANT_P (operands[
0]))"
1628 if (which_alternative==
0)
1630 else if (which_alternative==
1)
1633 return (AS2 (movw, r30, %
0) CR_TAB
1636 return (AS2 (mov, r30, %A0) CR_TAB
1637 AS2 (mov, r31, %B0) CR_TAB
1641 return AS1(rcall,%c0);
1642 return AS1(call,%c0);
1644 [(set_attr "cc" "clobber,clobber,clobber")
1645 (set (attr "length")
1646 (cond [(eq (symbol_ref "which_alternative") (const_int
0))
1648 (eq (symbol_ref "which_alternative") (const_int
1))
1650 (eq (symbol_ref "!AVR_MEGA")
1655 ;; TODO: insn length for AVR_ENHANCED
1656 (define_insn "call_value_insn"
1657 [(set (match_operand
0 "register_operand" "=r,r,r")
1658 (call (mem:HI (match_operand:HI
1 "nonmemory_operand" "!z,*r,i"))
1659 ;; We don't need in saving Z register because r30,r31 is a call used registers
1660 (match_operand:HI
2 "general_operand" "X,X,X")))]
1661 ;; Operand
2 not used on the AVR.
1662 "(register_operand (operands[
0], VOIDmode) || CONSTANT_P (operands[
0]))"
1665 if (which_alternative==
0)
1667 else if (which_alternative==
1)
1670 return (AS2 (movw, r30, %
1) CR_TAB
1673 return (AS2 (mov, r30, %A1) CR_TAB
1674 AS2 (mov, r31, %B1) CR_TAB
1678 return AS1(rcall,%c1);
1679 return AS1(call,%c1);
1681 [(set_attr "cc" "clobber,clobber,clobber")
1682 (set (attr "length")
1683 (cond [(eq (symbol_ref "which_alternative") (const_int
0))
1685 (eq (symbol_ref "which_alternative") (const_int
1))
1687 (eq (symbol_ref "!AVR_MEGA")
1696 [(set_attr "cc" "none")
1697 (set_attr "length" "
1")])
1700 (define_insn "indirect_jump"
1701 [(set (pc) (match_operand:HI
0 "register_operand" "!z,*r"))]
1705 push %A0\;push %B0\;ret"
1706 [(set_attr "length" "
1,
3")
1707 (set_attr "cc" "none,none")])
1710 (define_expand "tablejump"
1711 [(parallel [(set (pc) (match_operand:HI
0 "register_operand" ""))
1712 (use (label_ref (match_operand
1 "" "")))])]
1716 ;; TODO: jump to __tabjejump__ in libgcc
1718 (define_insn "*tablejump_enh"
1720 (plus:HI (match_operand:HI
0 "register_operand" "=&z")
1721 (label_ref (match_operand
2 "" "")))))
1722 (use (label_ref (match_operand
1 "" "")))]
1724 "subi r30,lo8(-(%
2))
1730 [(set_attr "length" "
6")
1731 (set_attr "cc" "clobber")])
1733 (define_insn "*tablejump"
1735 (plus:HI (match_operand:HI
0 "register_operand" "=&z")
1736 (label_ref (match_operand
2 "" "")))))
1737 (use (label_ref (match_operand
1 "" "")))]
1739 "subi r30,lo8(-(%
2))
1747 [(set_attr "length" "
8")
1748 (set_attr "cc" "clobber")])
1750 (define_expand "casesi"
1752 (minus:HI (subreg:HI (match_operand:SI
0 "register_operand" "")
0)
1753 (match_operand:HI
1 "register_operand" "")))
1754 (parallel [(set (cc0)
1755 (compare (match_dup
6)
1756 (match_operand:HI
2 "register_operand" "")))
1757 (clobber (match_scratch:QI
9 ""))])
1760 (if_then_else (gtu (cc0)
1762 (label_ref (match_operand
4 "" ""))
1765 (plus:HI (match_dup
6)
1767 ;; (set (match_dup
6)
1768 ;; (plus:HI (match_dup
6) (label_ref (match_operand:HI
3 "" ""))))
1770 (parallel [(set (pc) (mem:HI
1771 (plus:HI (match_dup
6)
1772 (label_ref (match_operand:HI
3 "" "")))))
1773 (use (label_ref (match_dup
3)))])]
1777 operands[
6] = gen_reg_rtx (HImode);
1781 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1782 ;; This instructin sets Z flag
1785 [(set (cc0) (const_int
0))]
1788 [(set_attr "length" "
1")
1789 (set_attr "cc" "compare")])
1792 ;; ************************* Peepholes ********************************
1795 [(set (match_operand:SI
0 "register_operand" "")
1796 (plus:SI (match_dup
0)
1800 (compare (match_dup
0)
1802 (clobber (match_operand:QI
1 "register_operand" ""))])
1804 (if_then_else (ne (cc0) (const_int
0))
1805 (label_ref (match_operand
2 "" ""))
1807 "(test_hard_reg_class (LD_REGS, operands[
0])
1808 && test_hard_reg_class (LD_REGS, operands[
1]))"
1811 if (test_hard_reg_class (ADDW_REGS, operands[
0]))
1812 output_asm_insn (AS2 (sbiw,%
0,
1) CR_TAB
1813 AS2 (sbc,%C0,__zero_reg__) CR_TAB
1814 AS2 (sbc,%D0,__zero_reg__)
\"\\n
\", operands);
1816 output_asm_insn (AS2 (subi,%A0,
1) CR_TAB
1817 AS2 (sbc,%B0,__zero_reg__) CR_TAB
1818 AS2 (sbc,%C0,__zero_reg__) CR_TAB
1819 AS2 (sbc,%D0,__zero_reg__)
\"\\n
\", operands);
1820 switch (avr_jump_mode (operands[
2],insn))
1823 return AS1 (brcc,%
2);
1825 return (AS1 (brcs,_PC_+
2) CR_TAB
1828 return (AS1 (brcs,_PC_+
4) CR_TAB
1833 [(set (match_operand:HI
0 "register_operand" "")
1834 (plus:HI (match_dup
0)
1838 (compare (match_dup
0)
1840 (clobber (match_operand:QI
1 "register_operand" ""))])
1842 (if_then_else (ne (cc0) (const_int
0))
1843 (label_ref (match_operand
2 "" ""))
1845 "(test_hard_reg_class (LD_REGS, operands[
0])
1846 && test_hard_reg_class (LD_REGS, operands[
1]))"
1849 if (test_hard_reg_class (ADDW_REGS, operands[
0]))
1850 output_asm_insn (AS2 (sbiw,%
0,
1), operands);
1852 output_asm_insn (AS2 (subi,%A0,
1) CR_TAB
1853 AS2 (sbc,%B0,__zero_reg__)
\"\\n
\", operands);
1854 switch (avr_jump_mode (operands[
2],insn))
1857 return AS1 (brcc,%
2);
1859 return (AS1 (brcs,_PC_+
2) CR_TAB
1862 return (AS1 (brcs,_PC_+
4) CR_TAB
1867 [(set (match_operand:QI
0 "register_operand" "")
1868 (plus:QI (match_dup
0)
1871 (compare (match_dup
0)
1874 (if_then_else (ne (cc0) (const_int
0))
1875 (label_ref (match_operand
1 "" ""))
1877 "test_hard_reg_class (LD_REGS, operands[
0])"
1880 output_asm_insn (AS2 (subi,%A0,
1), operands);
1881 switch (avr_jump_mode (operands[
1],insn))
1884 return AS1 (brcc,%
1);
1886 return (AS1 (brcs,_PC_+
2) CR_TAB
1889 return (AS1 (brcs,_PC_+
4) CR_TAB
1894 [(set (cc0) (match_operand:QI
0 "register_operand" ""))
1896 (if_then_else (lt (cc0) (const_int
0))
1897 (label_ref (match_operand
1 "" ""))
1899 "jump_over_one_insn_p (insn, operands[
1])"
1903 [(set (cc0) (match_operand:QI
0 "register_operand" ""))
1905 (if_then_else (ge (cc0) (const_int
0))
1906 (label_ref (match_operand
1 "" ""))
1908 "jump_over_one_insn_p (insn, operands[
1])"
1912 [(set (cc0) (match_operand:HI
0 "register_operand" ""))
1914 (if_then_else (lt (cc0) (const_int
0))
1915 (label_ref (match_operand
1 "" ""))
1917 "jump_over_one_insn_p (insn, operands[
1])"
1921 [(set (cc0) (match_operand:HI
0 "register_operand" ""))
1923 (if_then_else (ge (cc0) (const_int
0))
1924 (label_ref (match_operand
1 "" ""))
1926 "jump_over_one_insn_p (insn, operands[
1])"
1930 [(set (cc0) (match_operand:SI
0 "register_operand" ""))
1932 (if_then_else (lt (cc0) (const_int
0))
1933 (label_ref (match_operand
1 "" ""))
1935 "jump_over_one_insn_p (insn, operands[
1])"
1939 [(set (cc0) (match_operand:SI
0 "register_operand" ""))
1941 (if_then_else (ge (cc0) (const_int
0))
1942 (label_ref (match_operand
1 "" ""))
1944 "jump_over_one_insn_p (insn, operands[
1])"
1948 [(set (cc0) (match_operand:QI
0 "register_operand" ""))
1950 (if_then_else (eq (cc0) (const_int
0))
1951 (label_ref (match_operand
1 "" ""))
1953 "jump_over_one_insn_p (insn, operands[
1])"
1954 "cpse %
0,__zero_reg__")
1958 (compare (match_operand:QI
0 "register_operand" "")
1959 (match_operand:QI
1 "register_operand" "")))
1961 (if_then_else (eq (cc0) (const_int
0))
1962 (label_ref (match_operand
2 "" ""))
1964 "jump_over_one_insn_p (insn, operands[
2])"