]> gcc.gnu.org Git - gcc.git/blob - gcc/config/avr/avr.md
avr-protos.h, avr.c (unique_section, [...]): Add "const" as needed to remove warnings.
[gcc.git] / gcc / config / avr / avr.md
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)
6
7 ;; This file is part of GNU CC.
8
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)
12 ;; any later version.
13
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.
18
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.
23
24 ;; Condition code settings.
25 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
26 (const_string "none"))
27
28 (define_attr "type" "branch,branch1,arith"
29 (const_string "arith"))
30
31 ;; The size of instructions in bytes.
32 ;; XXX may depend from "cc"
33
34 (define_attr "length" ""
35 (cond [(eq_attr "type" "branch")
36 (if_then_else (and (ge (minus (pc) (match_dup 0))
37 (const_int -63))
38 (le (minus (pc) (match_dup 0))
39 (const_int 62)))
40 (const_int 1)
41 (if_then_else (and (ge (minus (pc) (match_dup 0))
42 (const_int -2045))
43 (le (minus (pc) (match_dup 0))
44 (const_int 2045)))
45 (const_int 2)
46 (const_int 2)))
47 (eq_attr "type" "branch1")
48 (if_then_else (and (ge (minus (pc) (match_dup 0))
49 (const_int -62))
50 (le (minus (pc) (match_dup 0))
51 (const_int 61)))
52 (const_int 2)
53 (if_then_else (and (ge (minus (pc) (match_dup 0))
54 (const_int -2044))
55 (le (minus (pc) (match_dup 0))
56 (const_int 2043)))
57 (const_int 3)
58 (const_int 3)))]
59 (const_int 2)))
60
61 (define_insn "*pop1"
62 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 1)))]
63 ""
64 "pop __tmp_reg__"
65 [(set_attr "length" "1")])
66
67 (define_insn "*pop2"
68 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 2)))]
69 ""
70 "pop __tmp_reg__
71 pop __tmp_reg__"
72 [(set_attr "length" "2")])
73
74 (define_insn "*pop3"
75 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 3)))]
76 ""
77 "pop __tmp_reg__
78 pop __tmp_reg__
79 pop __tmp_reg__"
80 [(set_attr "length" "3")])
81
82 (define_insn "*pop4"
83 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 4)))]
84 ""
85 "pop __tmp_reg__
86 pop __tmp_reg__
87 pop __tmp_reg__
88 pop __tmp_reg__"
89 [(set_attr "length" "4")])
90
91 (define_insn "*pop5"
92 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 5)))]
93 ""
94 "pop __tmp_reg__
95 pop __tmp_reg__
96 pop __tmp_reg__
97 pop __tmp_reg__
98 pop __tmp_reg__"
99 [(set_attr "length" "5")])
100
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))"
105 "@
106 push %0
107 push __zero_reg__"
108 [(set_attr "length" "1,1")])
109
110
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))"
115 "@
116 push %B0\;push %A0
117 push __zero_reg__\;push __zero_reg__"
118 [(set_attr "length" "2,2")])
119
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))"
124 "@
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")])
128
129 (define_insn "*pushsf"
130 [(set (mem:SF (post_dec (reg:HI 32)))
131 (match_operand:SF 0 "register_operand" "r"))]
132 ""
133 "push %D0
134 push %C0
135 push %B0
136 push %A0"
137 [(set_attr "length" "4")])
138
139 ;;========================================================================
140 ;; move byte
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.
147
148 (define_expand "movqi"
149 [(set (match_operand:QI 0 "nonimmediate_operand" "")
150 (match_operand:QI 1 "general_operand" ""))]
151 ""
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);
156 ")
157
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")])
166
167 ;; This is used in peephole2 to optimize loading immediate constants
168 ;; if a scratch register from LD_REGS happens to be available.
169
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"))]
174 ""
175 "ldi %2,lo8(%1)
176 mov %0,%2"
177 [(set_attr "length" "2")
178 (set_attr "cc" "none")])
179
180 ;;============================================================================
181 ;; move word (16 bit)
182
183 (define_expand "movhi"
184 [(set (match_operand:HI 0 "nonimmediate_operand" "")
185 (match_operand:HI 1 "general_operand" ""))]
186 ""
187 "
188 {
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]))
192 {
193 operands[1] = copy_to_mode_reg(HImode, operand1);
194 }
195 }")
196
197
198 (define_peephole2
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))])]
206 "")
207
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"))]
213 ""
214 "* return output_reload_inhi (insn, operands, NULL);"
215 [(set_attr "length" "4")
216 (set_attr "cc" "none")])
217
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")])
226
227 ;;==========================================================================
228 ;; move double word (32 bit)
229
230 (define_expand "movsi"
231 [(set (match_operand:SI 0 "nonimmediate_operand" "")
232 (match_operand:SI 1 "general_operand" ""))]
233 ""
234 "
235 {
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))
239 {
240 operands[1] = copy_to_mode_reg (SImode, operand1);
241 }
242 }")
243
244
245
246 (define_peephole2
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))])]
254 "")
255
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"))]
261 ""
262 "* return output_reload_insisf (insn, operands, NULL);"
263 [(set_attr "length" "8")
264 (set_attr "cc" "none")])
265
266
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")])
275
276 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
277 ;; move floating point numbers (32 bit)
278
279 (define_expand "movsf"
280 [(set (match_operand:SF 0 "nonimmediate_operand" "")
281 (match_operand:SF 1 "general_operand" ""))]
282 ""
283 "
284 {
285 /* One of the ops has to be in a register. */
286 if (!register_operand (operand1, SFmode)
287 && !register_operand (operand0, SFmode))
288 {
289 operands[1] = copy_to_mode_reg (SFmode, operand1);
290 }
291 }")
292
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")])
301
302 ;;=========================================================================
303 ;; move string (like memcpy)
304
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))])]
313 ""
314 "{
315 rtx addr0, addr1;
316 int cnt8;
317
318 if (GET_CODE (operands[2]) != CONST_INT)
319 FAIL;
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];
323
324 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
325 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
326
327 operands[5] = addr0;
328 operands[6] = addr1;
329
330 operands[0] = gen_rtx (MEM, BLKmode, addr0);
331 operands[1] = gen_rtx (MEM, BLKmode, addr1);
332 }")
333
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))]
342 ""
343 "
344 ld __tmp_reg__,%a1+
345 st %a0+,__tmp_reg__
346 dec %2
347 brne _PC_-8"
348 [(set_attr "length" "4")
349 (set_attr "cc" "clobber")])
350
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))]
359 ""
360 "*{
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
365 AS1 (brne,_PC_-8));
366 else
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
371 AS1 (brne,_PC_-10));
372 }"
373 [(set_attr "length" "4,5")
374 (set_attr "cc" "clobber,clobber")])
375
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)
378
379 (define_expand "clrstrhi"
380 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
381 (const_int 0))
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))])]
386 ""
387 "{
388 rtx addr0;
389 int cnt8;
390
391 if (GET_CODE (operands[1]) != CONST_INT)
392 FAIL;
393
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];
397
398 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
399 operands[4] = addr0;
400
401 operands[0] = gen_rtx (MEM, BLKmode, addr0);
402 }")
403
404 (define_insn "*clrstrqi"
405 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
406 (const_int 0))
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))]
411 ""
412 "
413 st %a0+,__zero_reg__
414 dec %1
415 brne _PC_-6"
416 [(set_attr "length" "3")
417 (set_attr "cc" "clobber")])
418
419 (define_insn "*clrstrhi"
420 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
421 (const_int 0))
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))]
426 ""
427 "*{
428 if (which_alternative==0)
429 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
430 AS2 (sbiw,%A1,1) CR_TAB
431 AS1 (brne,_PC_-6));
432 else
433 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
434 AS2 (subi,%A1,1) CR_TAB
435 AS2 (sbci,%B1,0) CR_TAB
436 AS1 (brne,_PC_-8));
437 }"
438 [(set_attr "length" "3,4")
439 (set_attr "cc" "clobber,clobber")])
440
441 (define_expand "strlenhi"
442 [(parallel
443 [(set (match_dup 4)
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)
449 (const_int -1)))
450 (set (match_operand:HI 0 "register_operand" "")
451 (minus:HI (match_dup 4)
452 (match_dup 5)))]
453 ""
454 "{
455 if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
456 FAIL;
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);
461 }")
462
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"))
466 (const_int 0)
467 (match_operand:HI 2 "immediate_operand" "i")] 0))
468 (clobber (match_dup 1))]
469 ""
470 "ld __tmp_reg__,%a0+
471 tst __tmp_reg__
472 brne _PC_-6"
473 [(set_attr "length" "3")
474 (set_attr "cc" "clobber")])
475
476 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
477 ; add bytes
478
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")))]
483 ""
484 "@
485 add %0,%2
486 subi %0,lo8(-(%2))
487 inc %0
488 dec %0"
489 [(set_attr "length" "1,1,1,1")
490 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
491
492
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" "")))]
497 ""
498 "
499 {
500 if (GET_CODE (operands[2]) == CONST_INT)
501 {
502 short tmp = INTVAL (operands[2]);
503 operands[2] = GEN_INT(tmp);
504 }
505 }")
506
507
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")))]
513 ""
514 "add %A0,%1
515 adc %B0,__zero_reg__"
516 [(set_attr "length" "2")
517 (set_attr "cc" "set_n")])
518
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")
522 (zero_extend:HI
523 (match_operand:QI 2 "register_operand" "r"))))]
524 ""
525 "add %A0,%2
526 adc %B0,__zero_reg__"
527 [(set_attr "length" "2")
528 (set_attr "cc" "set_n")])
529
530 (define_insn "*addhi3_zero_extend2"
531 [(set (match_operand:HI 0 "register_operand" "=r")
532 (plus:HI
533 (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
534 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
535 ""
536 "add %0,%2
537 mov %B0,__zero_reg__
538 adc %B0,__zero_reg__"
539 [(set_attr "length" "3")
540 (set_attr "cc" "set_n")])
541
542 (define_insn "*addhi3"
543 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
544 (plus:HI
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")))]
547 ""
548 "@
549 add %A0,%A2\;adc %B0,%B2
550 adiw %A0,%2
551 sbiw %A0,%n2
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")])
557
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")
561 (plus:SI
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")))]
564 ""
565 "@
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")])
576
577 ;-----------------------------------------------------------------------------
578 ; sub bytes
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")))]
583 ""
584 "@
585 sub %0,%2
586 subi %0,lo8(%2)"
587 [(set_attr "length" "1,1")
588 (set_attr "cc" "set_czn,set_czn")])
589
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")))]
594 ""
595 "@
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")])
600
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")))]
605 ""
606 "@
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")])
611
612 ;******************************************************************************
613 ; mul
614
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")))]
619 "AVR_ENHANCED"
620 "mul %1,%2
621 mov %0,r0
622 clr r1"
623 [(set_attr "length" "3")
624 (set_attr "cc" "clobber")])
625
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"))))]
630 "AVR_ENHANCED"
631 "muls %1,%2
632 movw %0,r0
633 clr r1"
634 [(set_attr "length" "3")
635 (set_attr "cc" "clobber")])
636
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"))))]
641 "AVR_ENHANCED"
642 "mul %1,%2
643 movw %0,r0
644 clr r1"
645 [(set_attr "length" "3")
646 (set_attr "cc" "clobber")])
647
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")))]
652 "AVR_ENHANCED"
653 "mul %A1,%A2
654 movw %0,r0
655 mul %A1,%B2
656 add %B0,r0
657 mul %B1,%A2
658 add %B0,r0
659 clr r1"
660 [(set_attr "length" "7")
661 (set_attr "cc" "clobber")])
662
663 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
664 ; and
665
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")))]
670 ""
671 "@
672 and %0,%2
673 andi %0,lo8(%2)"
674 [(set_attr "length" "1,1")
675 (set_attr "cc" "set_zn,set_zn")])
676
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"))]
682 ""
683 "*{
684 if (which_alternative==0)
685 return (AS2 (and,%A0,%A2) CR_TAB
686 AS2 (and,%B0,%B2));
687 else if (which_alternative==1)
688 {
689 if (GET_CODE (operands[2]) == CONST_INT)
690 {
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);
696 return \"\";
697 }
698 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
699 AS2 (andi,%B0,hi8(%2)));
700 }
701 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
702 AS2 (and,%A0,%3) CR_TAB
703 AS1 (clr,%B0));
704 }"
705 [(set_attr "length" "2,2,3")
706 (set_attr "cc" "set_n,clobber,clobber")])
707
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")))]
712 ""
713 "*{
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
718 AS2 (and, %D0,%D2));
719 else if (which_alternative==1)
720 {
721 if (GET_CODE (operands[2]) == CONST_INT)
722 {
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);
732 return \"\";
733 }
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)));
738 }
739 return \"bug\";
740 }"
741 [(set_attr "length" "4,4")
742 (set_attr "cc" "set_n,set_n")])
743
744 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
745 ;; ior
746
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")))]
751 ""
752 "@
753 or %0,%2
754 ori %0,lo8(%2)"
755 [(set_attr "length" "1,1")
756 (set_attr "cc" "set_zn,set_zn")])
757
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")))]
762 ""
763 "*{
764 if (which_alternative==0)
765 return (AS2 (or,%A0,%A2) CR_TAB
766 AS2 (or,%B0,%B2));
767 if (GET_CODE (operands[2]) == CONST_INT)
768 {
769 int mask = INTVAL (operands[2]);
770 if (mask & 0xff)
771 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
772 if (mask & 0xff00)
773 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
774 return \"\";
775 }
776 return (AS2 (ori,%0,lo8(%2)) CR_TAB
777 AS2 (ori,%B0,hi8(%2)));
778 }"
779 [(set_attr "length" "2,2")
780 (set_attr "cc" "set_n,clobber")])
781
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"))]
787 ""
788 "@
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")])
793
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")))]
798 ""
799 "*{
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
804 AS2 (or, %D0,%D2));
805 if (GET_CODE (operands[2]) == CONST_INT)
806 {
807 HOST_WIDE_INT mask = INTVAL (operands[2]);
808 if (mask & 0xff)
809 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
810 if (mask & 0xff00)
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);
816 return \"\";
817 }
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)));
822 }"
823 [(set_attr "length" "4,4")
824 (set_attr "cc" "set_n,clobber")])
825
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"))]
831 ""
832 "@
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")])
837
838 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
839 ;; xor
840
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")))]
845 ""
846 "eor %0,%2"
847 [(set_attr "length" "1")
848 (set_attr "cc" "set_zn")])
849
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")))]
854 ""
855 "eor %0,%2\;eor %B0,%B2"
856 [(set_attr "length" "2")
857 (set_attr "cc" "set_n")])
858
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")))]
863 ""
864 "eor %0,%2
865 eor %B0,%B2
866 eor %C0,%C2
867 eor %D0,%D2"
868 [(set_attr "length" "4")
869 (set_attr "cc" "set_n")])
870
871 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
872 ;; arithmetic shift left
873
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")))]
878 ""
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")])
882
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"))]
888 ""
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")])
892
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"))]
898 ""
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")])
902
903 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
904 ;; arithmetic shift right
905
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")))]
910 ""
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")])
914
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"))]
920 ""
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")])
924
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"))]
930 ""
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")])
934
935 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
936 ;; logical shift right
937
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")))]
942 ""
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")])
946
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"))]
952 ""
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")])
956
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"))]
962 ""
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")])
966
967 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
968 ;; abs
969
970 (define_insn "absqi2"
971 [(set (match_operand:QI 0 "register_operand" "=r")
972 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
973 ""
974 "sbrc %0,7\;neg %0"
975 [(set_attr "length" "2")
976 (set_attr "cc" "clobber")])
977
978
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")))]
982 ""
983 "@
984 andi %D0,0x7f
985 clt\;bld %D0,7"
986 [(set_attr "length" "1,2")
987 (set_attr "cc" "clobber,clobber")])
988
989 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
990 ;; neg
991
992 (define_insn "negqi2"
993 [(set (match_operand:QI 0 "register_operand" "=r")
994 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
995 ""
996 "neg %0"
997 [(set_attr "length" "1")
998 (set_attr "cc" "set_zn")])
999
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")))]
1003 ""
1004 "@
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")])
1009
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")))]
1013 ""
1014 "@
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")])
1020
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")))]
1024 ""
1025 "@
1026 subi %D0,0x80
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")])
1030
1031 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1032 ;; not
1033
1034 (define_insn "one_cmplqi2"
1035 [(set (match_operand:QI 0 "register_operand" "=r")
1036 (not:QI (match_operand:QI 1 "register_operand" "0")))]
1037 ""
1038 "com %0"
1039 [(set_attr "length" "1")
1040 (set_attr "cc" "set_czn")])
1041
1042 (define_insn "one_cmplhi2"
1043 [(set (match_operand:HI 0 "register_operand" "=r")
1044 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1045 ""
1046 "com %0\;com %B0"
1047 [(set_attr "length" "2")
1048 (set_attr "cc" "set_n")])
1049
1050 (define_insn "one_cmplsi2"
1051 [(set (match_operand:SI 0 "register_operand" "=r")
1052 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1053 ""
1054 "com %0\;com %B0\;com %C0\;com %D0"
1055 [(set_attr "length" "4")
1056 (set_attr "cc" "set_n")])
1057
1058 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1059 ;; sign extend
1060
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")))]
1064 ""
1065 "@
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")])
1070
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")))]
1074 ""
1075 "@
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")])
1080
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")))]
1085 ""
1086 "@
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")])
1091
1092 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1093 ;; zero extend
1094
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")))]
1098 ""
1099 "@
1100 clr %B0
1101 mov %A0,%A1\;clr %B0"
1102 [(set_attr "length" "1,2")
1103 (set_attr "cc" "set_n,set_n")])
1104
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")))]
1108 ""
1109 "@
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")])
1114
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")))]
1119 ""
1120 "@
1121 clr %C0\;clr %D0
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")])
1125
1126 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
1127 ;; compare
1128
1129 (define_insn "tstqi"
1130 [(set (cc0)
1131 (match_operand:QI 0 "register_operand" "r"))]
1132 ""
1133 "tst %0"
1134 [(set_attr "cc" "compare")
1135 (set_attr "length" "1")])
1136
1137 (define_insn "*negated_tstqi"
1138 [(set (cc0)
1139 (neg:QI (match_operand:QI 0 "register_operand" "r")))]
1140 ""
1141 "cp __zero_reg__,%0"
1142 [(set_attr "cc" "compare")
1143 (set_attr "length" "1")])
1144
1145 (define_insn "tsthi"
1146 [(set (cc0)
1147 (match_operand:HI 0 "register_operand" "!w,r"))]
1148 ""
1149 "* return out_tsthi (insn,NULL);"
1150 [(set_attr "cc" "compare,compare")
1151 (set_attr "length" "1,2")])
1152
1153 (define_insn "*negated_tsthi"
1154 [(set (cc0)
1155 (neg:HI (match_operand:HI 0 "register_operand" "r")))]
1156 ""
1157 "cp __zero_reg__,%A0
1158 cpc __zero_reg__,%B0"
1159 [(set_attr "cc" "compare")
1160 (set_attr "length" "2")])
1161
1162 (define_insn "tstsi"
1163 [(set (cc0)
1164 (match_operand:SI 0 "register_operand" "r"))]
1165 ""
1166 "* return out_tstsi (insn,NULL);"
1167 [(set_attr "cc" "compare")
1168 (set_attr "length" "4")])
1169
1170 (define_insn "*negated_tstsi"
1171 [(set (cc0)
1172 (neg:SI (match_operand:SI 0 "register_operand" "r")))]
1173 ""
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")])
1180
1181
1182 (define_insn "cmpqi"
1183 [(set (cc0)
1184 (compare (match_operand:QI 0 "register_operand" "r,d")
1185 (match_operand:QI 1 "nonmemory_operand" "r,i")))]
1186 ""
1187 "@
1188 cp %0,%1
1189 cpi %0,lo8(%1)"
1190 [(set_attr "cc" "compare,compare")
1191 (set_attr "length" "1,1")])
1192
1193 (define_insn "*cmpqi_sign_extend"
1194 [(set (cc0)
1195 (compare (sign_extend:HI
1196 (match_operand:QI 0 "register_operand" "d"))
1197 (match_operand:HI 1 "immediate_operand" "M")))]
1198 ""
1199 "cpi %0,lo8(%1)"
1200 [(set_attr "cc" "compare")
1201 (set_attr "length" "1")])
1202
1203 (define_insn "cmphi"
1204 [(set (cc0)
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"))]
1208 ""
1209 "*{
1210 switch (which_alternative)
1211 {
1212 case 0:
1213 return (AS2 (cp,%A0,%A1) CR_TAB
1214 AS2 (cpc,%B0,%B1));
1215 case 1:
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);
1220 else
1221 return (AS2 (cpi,%0,%1) CR_TAB
1222 AS2 (cpc,%B0,__zero_reg__));
1223 case 2:
1224 if (reg_unused_after (insn, operands[0]))
1225 return (AS2 (subi,%0,lo8(%1)) CR_TAB
1226 AS2 (sbci,%B0,hi8(%1)));
1227 else
1228 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
1229 AS2 (cpi, %A0,lo8(%1)) CR_TAB
1230 AS2 (cpc, %B0,%2));
1231 case 3:
1232 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1233 AS2 (cp, %A0,%2) CR_TAB
1234 AS2 (cpc, %B0,__zero_reg__));
1235
1236 case 4:
1237 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1238 AS2 (cp, %A0,%2) CR_TAB
1239 AS2 (ldi, %2,hi8(%1)) CR_TAB
1240 AS2 (cpc, %B0,%2));
1241 }
1242 return \"bug\";
1243 }"
1244 [(set_attr "cc" "compare,compare,compare,compare,compare")
1245 (set_attr "length" "2,2,3,3,4")])
1246
1247
1248 (define_insn "cmpsi"
1249 [(set (cc0)
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"))]
1253 ""
1254 "*{
1255 switch (which_alternative)
1256 {
1257 case 0:
1258 return (AS2 (cp,%A0,%A1) CR_TAB
1259 AS2 (cpc,%B0,%B1) CR_TAB
1260 AS2 (cpc,%C0,%C1) CR_TAB
1261 AS2 (cpc,%D0,%D1));
1262 case 1:
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__));
1269 else
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__));
1274 case 2:
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)));
1280 else
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
1287 AS2 (cpc, %D0,%2));
1288 case 3:
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__));
1294 case 4:
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
1302 AS2 (cpc, %D0,%2));
1303 }
1304 return \"bug\";
1305 }"
1306 [(set_attr "cc" "compare,compare,compare,compare,compare")
1307 (set_attr "length" "4,4,7,5,8")])
1308
1309 ;; ----------------------------------------------------------------------
1310 ;; JUMP INSTRUCTIONS
1311 ;; ----------------------------------------------------------------------
1312 ;; Conditional jump instructions
1313
1314 (define_expand "beq"
1315 [(set (pc)
1316 (if_then_else (eq (cc0) (const_int 0))
1317 (label_ref (match_operand 0 "" ""))
1318 (pc)))]
1319 ""
1320 "")
1321
1322 (define_expand "bne"
1323 [(set (pc)
1324 (if_then_else (ne (cc0) (const_int 0))
1325 (label_ref (match_operand 0 "" ""))
1326 (pc)))]
1327 ""
1328 "")
1329
1330 (define_expand "bge"
1331 [(set (pc)
1332 (if_then_else (ge (cc0) (const_int 0))
1333 (label_ref (match_operand 0 "" ""))
1334 (pc)))]
1335 ""
1336 "")
1337
1338 (define_expand "bgeu"
1339 [(set (pc)
1340 (if_then_else (geu (cc0) (const_int 0))
1341 (label_ref (match_operand 0 "" ""))
1342 (pc)))]
1343 ""
1344 "")
1345
1346 (define_expand "blt"
1347 [(set (pc)
1348 (if_then_else (lt (cc0) (const_int 0))
1349 (label_ref (match_operand 0 "" ""))
1350 (pc)))]
1351 ""
1352 "")
1353
1354 (define_expand "bltu"
1355 [(set (pc)
1356 (if_then_else (ltu (cc0) (const_int 0))
1357 (label_ref (match_operand 0 "" ""))
1358 (pc)))]
1359 ""
1360 "")
1361
1362
1363
1364 /****************************************************************
1365 AVR not have following conditional jumps: LE,LEU,GT,GTU.
1366 Convert them all to proper jumps.
1367 *****************************************************************/
1368
1369 (define_expand "ble"
1370 [(set (pc)
1371 (if_then_else (le (cc0) (const_int 0))
1372 (label_ref (match_operand 0 "" ""))
1373 (pc)))]
1374 ""
1375 "")
1376
1377 (define_expand "bleu"
1378 [(set (pc)
1379 (if_then_else (leu (cc0) (const_int 0))
1380 (label_ref (match_operand 0 "" ""))
1381 (pc)))]
1382 ""
1383 "")
1384
1385 (define_expand "bgt"
1386 [(set (pc)
1387 (if_then_else (gt (cc0) (const_int 0))
1388 (label_ref (match_operand 0 "" ""))
1389 (pc)))]
1390 ""
1391 "")
1392
1393 (define_expand "bgtu"
1394 [(set (pc)
1395 (if_then_else (gtu (cc0) (const_int 0))
1396 (label_ref (match_operand 0 "" ""))
1397 (pc)))]
1398 ""
1399 "")
1400
1401 (define_insn "*sbrx_branch"
1402 [(set (pc)
1403 (if_then_else
1404 (match_operator 0 "comparison_operator"
1405 [(zero_extract
1406 (match_operand:QI 1 "register_operand" "r")
1407 (const_int 1)
1408 (match_operand 2 "immediate_operand" "n"))
1409 (const_int 0)])
1410 (label_ref (match_operand 3 "" ""))
1411 (pc)))]
1412 "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)"
1413 "* {
1414 int comp = ((get_attr_length (insn) == 4)
1415 ? reverse_condition (GET_CODE (operands[0]))
1416 : GET_CODE (operands[0]));
1417 if (comp == EQ)
1418 output_asm_insn (AS2 (sbrs,%1,%2), operands);
1419 else
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
1424 AS1 (jmp,%3));
1425 }"
1426 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup 3))
1427 (const_int -2046))
1428 (le (minus (pc) (match_dup 3))
1429 (const_int 2046)))
1430 (const_int 2)
1431 (if_then_else (eq (symbol_ref "AVR_MEGA")
1432 (const_int 0))
1433 (const_int 2)
1434 (const_int 4))))
1435 (set_attr "cc" "clobber")])
1436
1437 (define_insn "*sbrx_and_branchsi"
1438 [(set (pc)
1439 (if_then_else
1440 (match_operator 0 "comparison_operator"
1441 [(and:SI
1442 (match_operand:SI 1 "register_operand" "r")
1443 (match_operand:SI 2 "immediate_operand" "n"))
1444 (const_int 0)])
1445 (label_ref (match_operand 3 "" ""))
1446 (pc)))]
1447 "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
1448 && mask_one_bit_p(INTVAL (operands[2]))"
1449 "* {
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);
1459
1460 if (get_attr_length (insn) != 4)
1461 return AS1 (rjmp,%3);
1462 return (AS1 (rjmp,_PC_+4) CR_TAB
1463 AS1 (jmp,%3));
1464 }"
1465 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup 3))
1466 (const_int -2046))
1467 (le (minus (pc) (match_dup 3))
1468 (const_int 2046)))
1469 (const_int 2)
1470 (if_then_else (eq (symbol_ref "AVR_MEGA")
1471 (const_int 0))
1472 (const_int 2)
1473 (const_int 4))))
1474 (set_attr "cc" "clobber")])
1475
1476 (define_insn "*sbrx_and_branchhi"
1477 [(set (pc)
1478 (if_then_else
1479 (match_operator 0 "comparison_operator"
1480 [(and:HI
1481 (match_operand:HI 1 "register_operand" "r")
1482 (match_operand:HI 2 "immediate_operand" "n"))
1483 (const_int 0)])
1484 (label_ref (match_operand 3 "" ""))
1485 (pc)))]
1486 "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
1487 && mask_one_bit_p(INTVAL (operands[2]))"
1488 "* {
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);
1498
1499 if (get_attr_length (insn) != 4)
1500 return AS1 (rjmp,%3);
1501 return (AS1 (rjmp,_PC_+4) CR_TAB
1502 AS1 (jmp,%3));
1503 }"
1504 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup 3))
1505 (const_int -2046))
1506 (le (minus (pc) (match_dup 3))
1507 (const_int 2046)))
1508 (const_int 2)
1509 (if_then_else (eq (symbol_ref "AVR_MEGA")
1510 (const_int 0))
1511 (const_int 2)
1512 (const_int 4))))
1513 (set_attr "cc" "clobber")])
1514
1515 ;; ************************************************************************
1516 ;; Implementation of conditional jumps here.
1517 ;; Compare with 0 (test) jumps
1518 ;; ************************************************************************
1519
1520 (define_insn "branch"
1521 [(set (pc)
1522 (if_then_else (match_operator 1 "comparison_operator"
1523 [(cc0)
1524 (const_int 0)])
1525 (label_ref (match_operand 0 "" ""))
1526 (pc)))]
1527 "! (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GTU
1528 || GET_CODE (operands[1]) == LE || GET_CODE (operands[1]) == LEU)"
1529 "*
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")])
1534
1535 (define_insn "difficult_branch"
1536 [(set (pc)
1537 (if_then_else (match_operator 1 "comparison_operator"
1538 [(cc0)
1539 (const_int 0)])
1540 (label_ref (match_operand 0 "" ""))
1541 (pc)))]
1542 "(GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GTU
1543 || GET_CODE (operands[1]) == LE || GET_CODE (operands[1]) == LEU)"
1544 "*
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")])
1549
1550 ;; revers branch
1551
1552 (define_insn "rvbranch"
1553 [(set (pc)
1554 (if_then_else (match_operator 1 "comparison_operator" [(cc0)
1555 (const_int 0)])
1556 (pc)
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)"
1560 "*
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")])
1565
1566 (define_insn "difficult_rvbranch"
1567 [(set (pc)
1568 (if_then_else (match_operator 1 "comparison_operator" [(cc0)
1569 (const_int 0)])
1570 (pc)
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)"
1574 "*
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")])
1579
1580 ;; **************************************************************************
1581 ;; Unconditional and other jump instructions.
1582
1583 (define_insn "jump"
1584 [(set (pc)
1585 (label_ref (match_operand 0 "" "")))]
1586 ""
1587 "*{
1588 if (AVR_MEGA && get_attr_length (insn) != 1)
1589 return \"jmp %0\";
1590 return \"rjmp %0\";
1591 }"
1592 [(set (attr "length") (if_then_else (and (ge (minus (pc) (match_dup 0))
1593 (const_int -2047))
1594 (le (minus (pc) (match_dup 0))
1595 (const_int 2047)))
1596 (const_int 1)
1597 (const_int 2)))
1598 (set_attr "cc" "none")])
1599
1600 ;; call
1601
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.
1606 ""
1607 "")
1608
1609 ;; call value
1610
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.
1616 ""
1617 "")
1618
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]))"
1626 "*
1627 {
1628 if (which_alternative==0)
1629 return \"icall\";
1630 else if (which_alternative==1)
1631 {
1632 if (AVR_ENHANCED)
1633 return (AS2 (movw, r30, %0) CR_TAB
1634 \"icall\");
1635 else
1636 return (AS2 (mov, r30, %A0) CR_TAB
1637 AS2 (mov, r31, %B0) CR_TAB
1638 \"icall\");
1639 }
1640 else if (!AVR_MEGA)
1641 return AS1(rcall,%c0);
1642 return AS1(call,%c0);
1643 }"
1644 [(set_attr "cc" "clobber,clobber,clobber")
1645 (set (attr "length")
1646 (cond [(eq (symbol_ref "which_alternative") (const_int 0))
1647 (const_int 1)
1648 (eq (symbol_ref "which_alternative") (const_int 1))
1649 (const_int 3)
1650 (eq (symbol_ref "!AVR_MEGA")
1651 (const_int 0))
1652 (const_int 2)]
1653 (const_int 1)))])
1654
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]))"
1663 "*
1664 {
1665 if (which_alternative==0)
1666 return \"icall\";
1667 else if (which_alternative==1)
1668 {
1669 if (AVR_ENHANCED)
1670 return (AS2 (movw, r30, %1) CR_TAB
1671 \"icall\");
1672 else
1673 return (AS2 (mov, r30, %A1) CR_TAB
1674 AS2 (mov, r31, %B1) CR_TAB
1675 \"icall\");
1676 }
1677 else if (!AVR_MEGA)
1678 return AS1(rcall,%c1);
1679 return AS1(call,%c1);
1680 }"
1681 [(set_attr "cc" "clobber,clobber,clobber")
1682 (set (attr "length")
1683 (cond [(eq (symbol_ref "which_alternative") (const_int 0))
1684 (const_int 1)
1685 (eq (symbol_ref "which_alternative") (const_int 1))
1686 (const_int 3)
1687 (eq (symbol_ref "!AVR_MEGA")
1688 (const_int 0))
1689 (const_int 2)]
1690 (const_int 1)))])
1691
1692 (define_insn "nop"
1693 [(const_int 0)]
1694 ""
1695 "nop"
1696 [(set_attr "cc" "none")
1697 (set_attr "length" "1")])
1698
1699 ; indirect jump
1700 (define_insn "indirect_jump"
1701 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
1702 ""
1703 "@
1704 ijmp
1705 push %A0\;push %B0\;ret"
1706 [(set_attr "length" "1,3")
1707 (set_attr "cc" "none,none")])
1708
1709 ;; table jump
1710 (define_expand "tablejump"
1711 [(parallel [(set (pc) (match_operand:HI 0 "register_operand" ""))
1712 (use (label_ref (match_operand 1 "" "")))])]
1713 "optimize"
1714 "")
1715
1716 ;; TODO: jump to __tabjejump__ in libgcc
1717
1718 (define_insn "*tablejump_enh"
1719 [(set (pc) (mem:HI
1720 (plus:HI (match_operand:HI 0 "register_operand" "=&z")
1721 (label_ref (match_operand 2 "" "")))))
1722 (use (label_ref (match_operand 1 "" "")))]
1723 "AVR_ENHANCED"
1724 "subi r30,lo8(-(%2))
1725 sbci r31,hi8(-(%2))
1726 lpm __tmp_reg__,Z+
1727 lpm r31,Z
1728 mov r30,__tmp_reg__
1729 ijmp"
1730 [(set_attr "length" "6")
1731 (set_attr "cc" "clobber")])
1732
1733 (define_insn "*tablejump"
1734 [(set (pc) (mem:HI
1735 (plus:HI (match_operand:HI 0 "register_operand" "=&z")
1736 (label_ref (match_operand 2 "" "")))))
1737 (use (label_ref (match_operand 1 "" "")))]
1738 ""
1739 "subi r30,lo8(-(%2))
1740 sbci r31,hi8(-(%2))
1741 lpm
1742 push r0
1743 adiw r30,1
1744 lpm
1745 push r0
1746 ret"
1747 [(set_attr "length" "8")
1748 (set_attr "cc" "clobber")])
1749
1750 (define_expand "casesi"
1751 [(set (match_dup 6)
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 ""))])
1758
1759 (set (pc)
1760 (if_then_else (gtu (cc0)
1761 (const_int 0))
1762 (label_ref (match_operand 4 "" ""))
1763 (pc)))
1764 (set (match_dup 6)
1765 (plus:HI (match_dup 6)
1766 (match_dup 6)))
1767 ;; (set (match_dup 6)
1768 ;; (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
1769
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)))])]
1774 "!optimize"
1775 "
1776 {
1777 operands[6] = gen_reg_rtx (HImode);
1778 }")
1779
1780
1781 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1782 ;; This instructin sets Z flag
1783
1784 (define_insn "sez"
1785 [(set (cc0) (const_int 0))]
1786 ""
1787 "sez"
1788 [(set_attr "length" "1")
1789 (set_attr "cc" "compare")])
1790
1791
1792 ;; ************************* Peepholes ********************************
1793
1794 (define_peephole
1795 [(set (match_operand:SI 0 "register_operand" "")
1796 (plus:SI (match_dup 0)
1797 (const_int -1)))
1798 (parallel
1799 [(set (cc0)
1800 (compare (match_dup 0)
1801 (const_int -1)))
1802 (clobber (match_operand:QI 1 "register_operand" ""))])
1803 (set (pc)
1804 (if_then_else (ne (cc0) (const_int 0))
1805 (label_ref (match_operand 2 "" ""))
1806 (pc)))]
1807 "(test_hard_reg_class (LD_REGS, operands[0])
1808 && test_hard_reg_class (LD_REGS, operands[1]))"
1809 "*
1810 {
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);
1815 else
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))
1821 {
1822 case 1:
1823 return AS1 (brcc,%2);
1824 case 2:
1825 return (AS1 (brcs,_PC_+2) CR_TAB
1826 AS1 (rjmp,%2));
1827 }
1828 return (AS1 (brcs,_PC_+4) CR_TAB
1829 AS1 (jmp,%2));
1830 }")
1831
1832 (define_peephole
1833 [(set (match_operand:HI 0 "register_operand" "")
1834 (plus:HI (match_dup 0)
1835 (const_int -1)))
1836 (parallel
1837 [(set (cc0)
1838 (compare (match_dup 0)
1839 (const_int 65535)))
1840 (clobber (match_operand:QI 1 "register_operand" ""))])
1841 (set (pc)
1842 (if_then_else (ne (cc0) (const_int 0))
1843 (label_ref (match_operand 2 "" ""))
1844 (pc)))]
1845 "(test_hard_reg_class (LD_REGS, operands[0])
1846 && test_hard_reg_class (LD_REGS, operands[1]))"
1847 "*
1848 {
1849 if (test_hard_reg_class (ADDW_REGS, operands[0]))
1850 output_asm_insn (AS2 (sbiw,%0,1), operands);
1851 else
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))
1855 {
1856 case 1:
1857 return AS1 (brcc,%2);
1858 case 2:
1859 return (AS1 (brcs,_PC_+2) CR_TAB
1860 AS1 (rjmp,%2));
1861 }
1862 return (AS1 (brcs,_PC_+4) CR_TAB
1863 AS1 (jmp,%2));
1864 }")
1865
1866 (define_peephole
1867 [(set (match_operand:QI 0 "register_operand" "")
1868 (plus:QI (match_dup 0)
1869 (const_int -1)))
1870 (set (cc0)
1871 (compare (match_dup 0)
1872 (const_int -1)))
1873 (set (pc)
1874 (if_then_else (ne (cc0) (const_int 0))
1875 (label_ref (match_operand 1 "" ""))
1876 (pc)))]
1877 "test_hard_reg_class (LD_REGS, operands[0])"
1878 "*
1879 {
1880 output_asm_insn (AS2 (subi,%A0,1), operands);
1881 switch (avr_jump_mode (operands[1],insn))
1882 {
1883 case 1:
1884 return AS1 (brcc,%1);
1885 case 2:
1886 return (AS1 (brcs,_PC_+2) CR_TAB
1887 AS1 (rjmp,%1));
1888 }
1889 return (AS1 (brcs,_PC_+4) CR_TAB
1890 AS1 (jmp,%1));
1891 }")
1892
1893 (define_peephole
1894 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1895 (set (pc)
1896 (if_then_else (lt (cc0) (const_int 0))
1897 (label_ref (match_operand 1 "" ""))
1898 (pc)))]
1899 "jump_over_one_insn_p (insn, operands[1])"
1900 "sbrs %0,7")
1901
1902 (define_peephole
1903 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1904 (set (pc)
1905 (if_then_else (ge (cc0) (const_int 0))
1906 (label_ref (match_operand 1 "" ""))
1907 (pc)))]
1908 "jump_over_one_insn_p (insn, operands[1])"
1909 "sbrc %0,7")
1910
1911 (define_peephole
1912 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1913 (set (pc)
1914 (if_then_else (lt (cc0) (const_int 0))
1915 (label_ref (match_operand 1 "" ""))
1916 (pc)))]
1917 "jump_over_one_insn_p (insn, operands[1])"
1918 "sbrs %B0,7")
1919
1920 (define_peephole
1921 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1922 (set (pc)
1923 (if_then_else (ge (cc0) (const_int 0))
1924 (label_ref (match_operand 1 "" ""))
1925 (pc)))]
1926 "jump_over_one_insn_p (insn, operands[1])"
1927 "sbrc %B0,7")
1928
1929 (define_peephole
1930 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1931 (set (pc)
1932 (if_then_else (lt (cc0) (const_int 0))
1933 (label_ref (match_operand 1 "" ""))
1934 (pc)))]
1935 "jump_over_one_insn_p (insn, operands[1])"
1936 "sbrs %D0,7")
1937
1938 (define_peephole
1939 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1940 (set (pc)
1941 (if_then_else (ge (cc0) (const_int 0))
1942 (label_ref (match_operand 1 "" ""))
1943 (pc)))]
1944 "jump_over_one_insn_p (insn, operands[1])"
1945 "sbrc %D0,7")
1946
1947 (define_peephole
1948 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1949 (set (pc)
1950 (if_then_else (eq (cc0) (const_int 0))
1951 (label_ref (match_operand 1 "" ""))
1952 (pc)))]
1953 "jump_over_one_insn_p (insn, operands[1])"
1954 "cpse %0,__zero_reg__")
1955
1956 (define_peephole
1957 [(set (cc0)
1958 (compare (match_operand:QI 0 "register_operand" "")
1959 (match_operand:QI 1 "register_operand" "")))
1960 (set (pc)
1961 (if_then_else (eq (cc0) (const_int 0))
1962 (label_ref (match_operand 2 "" ""))
1963 (pc)))]
1964 "jump_over_one_insn_p (insn, operands[2])"
1965 "cpse %0,%1")
This page took 0.126041 seconds and 5 git commands to generate.