38cee2d4d48bd5c9dc6d9aead53cfb7b73d8268b
[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, 2001, 2002, 2004, 2005, 2006, 2007
5 ;; Free Software Foundation, Inc.
6 ;; Contributed by Denis Chertykov (denisc@overta.ru)
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;; Special characters after '%':
26 ;; A No effect (add 0).
27 ;; B Add 1 to REG number, MEM address or CONST_INT.
28 ;; C Add 2.
29 ;; D Add 3.
30 ;; j Branch condition.
31 ;; k Reverse branch condition.
32 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
33 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
34 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
35 ;; ~ Output 'r' if not AVR_MEGA.
36
37 ;; UNSPEC usage:
38 ;; 0 Length of a string, see "strlenhi".
39 ;; 1 Jump by register pair Z or by table addressed by Z, see "casesi".
40
41 (define_constants
42 [(REG_X 26)
43 (REG_Y 28)
44 (REG_Z 30)
45 (REG_W 24)
46 (REG_SP 32)
47 (TMP_REGNO 0) ; temporary register r0
48 (ZERO_REGNO 1) ; zero register r1
49 (UNSPEC_STRLEN 0)
50 (UNSPEC_INDEX_JMP 1)])
51
52 (include "predicates.md")
53 (include "constraints.md")
54
55 ;; Condition code settings.
56 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
57 (const_string "none"))
58
59 (define_attr "type" "branch,branch1,arith,xcall"
60 (const_string "arith"))
61
62 (define_attr "mcu_have_movw" "yes,no"
63 (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
64 (const_string "yes")
65 (const_string "no"))))
66
67 (define_attr "mcu_mega" "yes,no"
68 (const (if_then_else (symbol_ref "AVR_MEGA")
69 (const_string "yes")
70 (const_string "no"))))
71
72
73 ;; The size of instructions in bytes.
74 ;; XXX may depend from "cc"
75
76 (define_attr "length" ""
77 (cond [(eq_attr "type" "branch")
78 (if_then_else (and (ge (minus (pc) (match_dup 0))
79 (const_int -63))
80 (le (minus (pc) (match_dup 0))
81 (const_int 62)))
82 (const_int 1)
83 (if_then_else (and (ge (minus (pc) (match_dup 0))
84 (const_int -2045))
85 (le (minus (pc) (match_dup 0))
86 (const_int 2045)))
87 (const_int 2)
88 (const_int 3)))
89 (eq_attr "type" "branch1")
90 (if_then_else (and (ge (minus (pc) (match_dup 0))
91 (const_int -62))
92 (le (minus (pc) (match_dup 0))
93 (const_int 61)))
94 (const_int 2)
95 (if_then_else (and (ge (minus (pc) (match_dup 0))
96 (const_int -2044))
97 (le (minus (pc) (match_dup 0))
98 (const_int 2043)))
99 (const_int 3)
100 (const_int 4)))
101 (eq_attr "type" "xcall")
102 (if_then_else (eq_attr "mcu_mega" "no")
103 (const_int 1)
104 (const_int 2))]
105 (const_int 2)))
106
107 (define_insn "*pop1"
108 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 1)))]
109 ""
110 "pop __tmp_reg__"
111 [(set_attr "length" "1")])
112
113 (define_insn "*pop2"
114 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 2)))]
115 ""
116 "pop __tmp_reg__
117 pop __tmp_reg__"
118 [(set_attr "length" "2")])
119
120 (define_insn "*pop3"
121 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 3)))]
122 ""
123 "pop __tmp_reg__
124 pop __tmp_reg__
125 pop __tmp_reg__"
126 [(set_attr "length" "3")])
127
128 (define_insn "*pop4"
129 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 4)))]
130 ""
131 "pop __tmp_reg__
132 pop __tmp_reg__
133 pop __tmp_reg__
134 pop __tmp_reg__"
135 [(set_attr "length" "4")])
136
137 (define_insn "*pop5"
138 [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 5)))]
139 ""
140 "pop __tmp_reg__
141 pop __tmp_reg__
142 pop __tmp_reg__
143 pop __tmp_reg__
144 pop __tmp_reg__"
145 [(set_attr "length" "5")])
146
147 (define_insn "*pushqi"
148 [(set (mem:QI (post_dec (reg:HI REG_SP)))
149 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
150 ""
151 "@
152 push %0
153 push __zero_reg__"
154 [(set_attr "length" "1,1")])
155
156
157 (define_insn "*pushhi"
158 [(set (mem:HI (post_dec (reg:HI REG_SP)))
159 (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
160 ""
161 "@
162 push %B0\;push %A0
163 push __zero_reg__\;push __zero_reg__"
164 [(set_attr "length" "2,2")])
165
166 (define_insn "*pushsi"
167 [(set (mem:SI (post_dec (reg:HI REG_SP)))
168 (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
169 ""
170 "@
171 push %D0\;push %C0\;push %B0\;push %A0
172 push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
173 [(set_attr "length" "4,4")])
174
175 (define_insn "*pushsf"
176 [(set (mem:SF (post_dec (reg:HI REG_SP)))
177 (match_operand:SF 0 "register_operand" "r"))]
178 ""
179 "push %D0
180 push %C0
181 push %B0
182 push %A0"
183 [(set_attr "length" "4")])
184
185 ;;========================================================================
186 ;; move byte
187 ;; The last alternative (any immediate constant to any register) is
188 ;; very expensive. It should be optimized by peephole2 if a scratch
189 ;; register is available, but then that register could just as well be
190 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
191 ;; are call-saved registers, and most of LD_REGS are call-used registers,
192 ;; so this may still be a win for registers live across function calls.
193
194 (define_expand "movqi"
195 [(set (match_operand:QI 0 "nonimmediate_operand" "")
196 (match_operand:QI 1 "general_operand" ""))]
197 ""
198 "/* One of the ops has to be in a register. */
199 if (!register_operand(operand0, QImode)
200 && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
201 operands[1] = copy_to_mode_reg(QImode, operand1);
202 ")
203
204 (define_insn "*movqi"
205 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
206 (match_operand:QI 1 "general_operand" "r,i,rL,Qm,r,q,i"))]
207 "(register_operand (operands[0],QImode)
208 || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
209 "* return output_movqi (insn, operands, NULL);"
210 [(set_attr "length" "1,1,5,5,1,1,4")
211 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
212
213 ;; This is used in peephole2 to optimize loading immediate constants
214 ;; if a scratch register from LD_REGS happens to be available.
215
216 (define_insn "*reload_inqi"
217 [(set (match_operand:QI 0 "register_operand" "=l")
218 (match_operand:QI 1 "immediate_operand" "i"))
219 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
220 "reload_completed"
221 "ldi %2,lo8(%1)
222 mov %0,%2"
223 [(set_attr "length" "2")
224 (set_attr "cc" "none")])
225
226 (define_peephole2
227 [(match_scratch:QI 2 "d")
228 (set (match_operand:QI 0 "l_register_operand" "")
229 (match_operand:QI 1 "immediate_operand" ""))]
230 "(operands[1] != const0_rtx
231 && operands[1] != const1_rtx
232 && operands[1] != constm1_rtx)"
233 [(parallel [(set (match_dup 0) (match_dup 1))
234 (clobber (match_dup 2))])]
235 "if (!avr_peep2_scratch_safe (operands[2]))
236 FAIL;")
237
238 ;;============================================================================
239 ;; move word (16 bit)
240
241 (define_expand "movhi"
242 [(set (match_operand:HI 0 "nonimmediate_operand" "")
243 (match_operand:HI 1 "general_operand" ""))]
244 ""
245 "
246 {
247 /* One of the ops has to be in a register. */
248 if (!register_operand(operand0, HImode)
249 && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
250 {
251 operands[1] = copy_to_mode_reg(HImode, operand1);
252 }
253 }")
254
255
256 (define_peephole2
257 [(match_scratch:QI 2 "d")
258 (set (match_operand:HI 0 "l_register_operand" "")
259 (match_operand:HI 1 "immediate_operand" ""))]
260 "(operands[1] != const0_rtx
261 && operands[1] != constm1_rtx)"
262 [(parallel [(set (match_dup 0) (match_dup 1))
263 (clobber (match_dup 2))])]
264 "if (!avr_peep2_scratch_safe (operands[2]))
265 FAIL;")
266
267 ;; '*' because it is not used in rtl generation, only in above peephole
268 (define_insn "*reload_inhi"
269 [(set (match_operand:HI 0 "register_operand" "=r")
270 (match_operand:HI 1 "immediate_operand" "i"))
271 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
272 "reload_completed"
273 "* return output_reload_inhi (insn, operands, NULL);"
274 [(set_attr "length" "4")
275 (set_attr "cc" "none")])
276
277 (define_insn "*movhi"
278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
279 (match_operand:HI 1 "general_operand" "r,m,rL,i,i,r,q"))]
280 "(register_operand (operands[0],HImode)
281 || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
282 "* return output_movhi (insn, operands, NULL);"
283 [(set_attr "length" "2,6,7,2,6,5,2")
284 (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
285
286 ;;==========================================================================
287 ;; move double word (32 bit)
288
289 (define_expand "movsi"
290 [(set (match_operand:SI 0 "nonimmediate_operand" "")
291 (match_operand:SI 1 "general_operand" ""))]
292 ""
293 "
294 {
295 /* One of the ops has to be in a register. */
296 if (!register_operand (operand0, SImode)
297 && !(register_operand (operand1, SImode) || const0_rtx == operand1))
298 {
299 operands[1] = copy_to_mode_reg (SImode, operand1);
300 }
301 }")
302
303
304
305 (define_peephole2
306 [(match_scratch:QI 2 "d")
307 (set (match_operand:SI 0 "l_register_operand" "")
308 (match_operand:SI 1 "immediate_operand" ""))]
309 "(operands[1] != const0_rtx
310 && operands[1] != constm1_rtx)"
311 [(parallel [(set (match_dup 0) (match_dup 1))
312 (clobber (match_dup 2))])]
313 "if (!avr_peep2_scratch_safe (operands[2]))
314 FAIL;")
315
316 ;; '*' because it is not used in rtl generation.
317 (define_insn "*reload_insi"
318 [(set (match_operand:SI 0 "register_operand" "=r")
319 (match_operand:SI 1 "immediate_operand" "i"))
320 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
321 "reload_completed"
322 "* return output_reload_insisf (insn, operands, NULL);"
323 [(set_attr "length" "8")
324 (set_attr "cc" "none")])
325
326
327 (define_insn "*movsi"
328 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
329 (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))]
330 "(register_operand (operands[0],SImode)
331 || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
332 "* return output_movsisf (insn, operands, NULL);"
333 [(set_attr "length" "4,4,8,9,4,10")
334 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
335
336 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
337 ;; move floating point numbers (32 bit)
338
339 (define_expand "movsf"
340 [(set (match_operand:SF 0 "nonimmediate_operand" "")
341 (match_operand:SF 1 "general_operand" ""))]
342 ""
343 "
344 {
345 /* One of the ops has to be in a register. */
346 if (!register_operand (operand1, SFmode)
347 && !register_operand (operand0, SFmode))
348 {
349 operands[1] = copy_to_mode_reg (SFmode, operand1);
350 }
351 }")
352
353 (define_insn "*movsf"
354 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
355 (match_operand:SF 1 "general_operand" "r,G,Qm,r,F,F"))]
356 "register_operand (operands[0], SFmode)
357 || register_operand (operands[1], SFmode)"
358 "* return output_movsisf (insn, operands, NULL);"
359 [(set_attr "length" "4,4,8,9,4,10")
360 (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
361
362 ;;=========================================================================
363 ;; move string (like memcpy)
364 ;; implement as RTL loop
365
366 (define_expand "movmemhi"
367 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
368 (match_operand:BLK 1 "memory_operand" ""))
369 (use (match_operand:HI 2 "const_int_operand" ""))
370 (use (match_operand:HI 3 "const_int_operand" ""))])]
371 ""
372 "{
373 int prob;
374 HOST_WIDE_INT count;
375 enum machine_mode mode;
376 rtx label = gen_label_rtx ();
377 rtx loop_reg;
378 rtx jump;
379
380 /* Copy pointers into new psuedos - they will be changed. */
381 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
382 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
383
384 /* Create rtx for tmp register - we use this as scratch. */
385 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
386
387 if (GET_CODE (operands[2]) != CONST_INT)
388 FAIL;
389
390 count = INTVAL (operands[2]);
391 if (count <= 0)
392 FAIL;
393
394 /* Work out branch probability for latter use. */
395 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
396
397 /* See if constant fit 8 bits. */
398 mode = (count < 0x100) ? QImode : HImode;
399 /* Create loop counter register. */
400 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
401
402 /* Now create RTL code for move loop. */
403 /* Label at top of loop. */
404 emit_label (label);
405
406 /* Move one byte into scratch and inc pointer. */
407 emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
408 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
409
410 /* Move to mem and inc pointer. */
411 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
412 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
413
414 /* Decrement count. */
415 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
416
417 /* Compare with zero and jump if not equal. */
418 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
419 label);
420 /* Set jump probability based on loop count. */
421 jump = get_last_insn ();
422 REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB,
423 GEN_INT (prob),
424 REG_NOTES (jump));
425 DONE;
426 }")
427
428 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
429 ;; memset (%0, %2, %1)
430
431 (define_expand "setmemhi"
432 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
433 (match_operand 2 "const_int_operand" ""))
434 (use (match_operand:HI 1 "const_int_operand" ""))
435 (use (match_operand:HI 3 "const_int_operand" "n"))
436 (clobber (match_scratch:HI 4 ""))
437 (clobber (match_dup 5))])]
438 ""
439 "{
440 rtx addr0;
441 int cnt8;
442 enum machine_mode mode;
443
444 /* If value to set is not zero, use the library routine. */
445 if (operands[2] != const0_rtx)
446 FAIL;
447
448 if (GET_CODE (operands[1]) != CONST_INT)
449 FAIL;
450
451 cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
452 mode = cnt8 ? QImode : HImode;
453 operands[5] = gen_rtx_SCRATCH (mode);
454 operands[1] = copy_to_mode_reg (mode,
455 gen_int_mode (INTVAL (operands[1]), mode));
456 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
457 operands[0] = gen_rtx_MEM (BLKmode, addr0);
458 }")
459
460 (define_insn "*clrmemqi"
461 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
462 (const_int 0))
463 (use (match_operand:QI 1 "register_operand" "r"))
464 (use (match_operand:QI 2 "const_int_operand" "n"))
465 (clobber (match_scratch:HI 3 "=0"))
466 (clobber (match_scratch:QI 4 "=1"))]
467 ""
468 "st %a0+,__zero_reg__
469 dec %1
470 brne .-6"
471 [(set_attr "length" "3")
472 (set_attr "cc" "clobber")])
473
474 (define_insn "*clrmemhi"
475 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
476 (const_int 0))
477 (use (match_operand:HI 1 "register_operand" "!w,d"))
478 (use (match_operand:HI 2 "const_int_operand" "n,n"))
479 (clobber (match_scratch:HI 3 "=0,0"))
480 (clobber (match_scratch:HI 4 "=1,1"))]
481 ""
482 "*{
483 if (which_alternative==0)
484 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
485 AS2 (sbiw,%A1,1) CR_TAB
486 AS1 (brne,.-6));
487 else
488 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
489 AS2 (subi,%A1,1) CR_TAB
490 AS2 (sbci,%B1,0) CR_TAB
491 AS1 (brne,.-8));
492 }"
493 [(set_attr "length" "3,4")
494 (set_attr "cc" "clobber,clobber")])
495
496 (define_expand "strlenhi"
497 [(set (match_dup 4)
498 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
499 (match_operand:QI 2 "const_int_operand" "")
500 (match_operand:HI 3 "immediate_operand" "")]
501 UNSPEC_STRLEN))
502 (set (match_dup 4) (plus:HI (match_dup 4)
503 (const_int -1)))
504 (set (match_operand:HI 0 "register_operand" "")
505 (minus:HI (match_dup 4)
506 (match_dup 5)))]
507 ""
508 "{
509 rtx addr;
510 if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
511 FAIL;
512 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
513 operands[1] = gen_rtx_MEM (BLKmode, addr);
514 operands[5] = addr;
515 operands[4] = gen_reg_rtx (HImode);
516 }")
517
518 (define_insn "*strlenhi"
519 [(set (match_operand:HI 0 "register_operand" "=e")
520 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
521 (const_int 0)
522 (match_operand:HI 2 "immediate_operand" "i")]
523 UNSPEC_STRLEN))]
524 ""
525 "ld __tmp_reg__,%a0+
526 tst __tmp_reg__
527 brne .-6"
528 [(set_attr "length" "3")
529 (set_attr "cc" "clobber")])
530
531 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
532 ; add bytes
533
534 (define_insn "addqi3"
535 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
536 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
537 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
538 ""
539 "@
540 add %0,%2
541 subi %0,lo8(-(%2))
542 inc %0
543 dec %0"
544 [(set_attr "length" "1,1,1,1")
545 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
546
547
548 (define_expand "addhi3"
549 [(set (match_operand:HI 0 "register_operand" "")
550 (plus:HI (match_operand:HI 1 "register_operand" "")
551 (match_operand:HI 2 "nonmemory_operand" "")))]
552 ""
553 "
554 {
555 if (GET_CODE (operands[2]) == CONST_INT)
556 {
557 short tmp = INTVAL (operands[2]);
558 operands[2] = GEN_INT(tmp);
559 }
560 }")
561
562
563 (define_insn "*addhi3_zero_extend"
564 [(set (match_operand:HI 0 "register_operand" "=r")
565 (plus:HI (zero_extend:HI
566 (match_operand:QI 1 "register_operand" "r"))
567 (match_operand:HI 2 "register_operand" "0")))]
568 ""
569 "add %A0,%1
570 adc %B0,__zero_reg__"
571 [(set_attr "length" "2")
572 (set_attr "cc" "set_n")])
573
574 (define_insn "*addhi3_zero_extend1"
575 [(set (match_operand:HI 0 "register_operand" "=r")
576 (plus:HI (match_operand:HI 1 "register_operand" "%0")
577 (zero_extend:HI
578 (match_operand:QI 2 "register_operand" "r"))))]
579 ""
580 "add %A0,%2
581 adc %B0,__zero_reg__"
582 [(set_attr "length" "2")
583 (set_attr "cc" "set_n")])
584
585 (define_insn "*addhi3_zero_extend2"
586 [(set (match_operand:HI 0 "register_operand" "=r")
587 (plus:HI
588 (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
589 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
590 ""
591 "add %0,%2
592 mov %B0,__zero_reg__
593 adc %B0,__zero_reg__"
594 [(set_attr "length" "3")
595 (set_attr "cc" "set_n")])
596
597 (define_insn "*addhi3"
598 [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
599 (plus:HI
600 (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
601 (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
602 ""
603 "@
604 add %A0,%A2\;adc %B0,%B2
605 adiw %A0,%2
606 sbiw %A0,%n2
607 subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
608 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
609 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
610 [(set_attr "length" "2,1,1,2,3,3")
611 (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
612
613 (define_insn "addsi3"
614 [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
615 (plus:SI
616 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
617 (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
618 ""
619 "@
620 add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
621 adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
622 sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
623 subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
624 sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
625 sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
626 [(set_attr "length" "4,3,3,4,5,5")
627 (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
628
629 (define_insn "*addsi3_zero_extend"
630 [(set (match_operand:SI 0 "register_operand" "=r")
631 (plus:SI (zero_extend:SI
632 (match_operand:QI 1 "register_operand" "r"))
633 (match_operand:SI 2 "register_operand" "0")))]
634 ""
635 "add %A0,%1
636 adc %B0,__zero_reg__
637 adc %C0,__zero_reg__
638 adc %D0,__zero_reg__"
639 [(set_attr "length" "4")
640 (set_attr "cc" "set_n")])
641
642 ;-----------------------------------------------------------------------------
643 ; sub bytes
644 (define_insn "subqi3"
645 [(set (match_operand:QI 0 "register_operand" "=r,d")
646 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
647 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
648 ""
649 "@
650 sub %0,%2
651 subi %0,lo8(%2)"
652 [(set_attr "length" "1,1")
653 (set_attr "cc" "set_czn,set_czn")])
654
655 (define_insn "subhi3"
656 [(set (match_operand:HI 0 "register_operand" "=r,d")
657 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
658 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
659 ""
660 "@
661 sub %A0,%A2\;sbc %B0,%B2
662 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
663 [(set_attr "length" "2,2")
664 (set_attr "cc" "set_czn,set_czn")])
665
666 (define_insn "*subhi3_zero_extend1"
667 [(set (match_operand:HI 0 "register_operand" "=r")
668 (minus:HI (match_operand:HI 1 "register_operand" "0")
669 (zero_extend:HI
670 (match_operand:QI 2 "register_operand" "r"))))]
671 ""
672 "sub %A0,%2
673 sbc %B0,__zero_reg__"
674 [(set_attr "length" "2")
675 (set_attr "cc" "set_n")])
676
677 (define_insn "subsi3"
678 [(set (match_operand:SI 0 "register_operand" "=r,d")
679 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
680 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
681 ""
682 "@
683 sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
684 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
685 [(set_attr "length" "4,4")
686 (set_attr "cc" "set_czn,set_czn")])
687
688 (define_insn "*subsi3_zero_extend"
689 [(set (match_operand:SI 0 "register_operand" "=r")
690 (minus:SI (match_operand:SI 1 "register_operand" "0")
691 (zero_extend:SI
692 (match_operand:QI 2 "register_operand" "r"))))]
693 ""
694 "sub %A0,%2
695 sbc %B0,__zero_reg__
696 sbc %C0,__zero_reg__
697 sbc %D0,__zero_reg__"
698 [(set_attr "length" "4")
699 (set_attr "cc" "set_n")])
700
701 ;******************************************************************************
702 ; mul
703
704 (define_expand "mulqi3"
705 [(set (match_operand:QI 0 "register_operand" "")
706 (mult:QI (match_operand:QI 1 "register_operand" "")
707 (match_operand:QI 2 "register_operand" "")))]
708 ""
709 "{
710 if (!AVR_ENHANCED)
711 {
712 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
713 DONE;
714 }
715 }")
716
717 (define_insn "*mulqi3_enh"
718 [(set (match_operand:QI 0 "register_operand" "=r")
719 (mult:QI (match_operand:QI 1 "register_operand" "r")
720 (match_operand:QI 2 "register_operand" "r")))]
721 "AVR_ENHANCED"
722 "mul %1,%2
723 mov %0,r0
724 clr r1"
725 [(set_attr "length" "3")
726 (set_attr "cc" "clobber")])
727
728 (define_expand "mulqi3_call"
729 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
730 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
731 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
732 (clobber (reg:QI 22))])
733 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
734 ""
735 "")
736
737 (define_insn "*mulqi3_call"
738 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
739 (clobber (reg:QI 22))]
740 "!AVR_ENHANCED"
741 "%~call __mulqi3"
742 [(set_attr "type" "xcall")
743 (set_attr "cc" "clobber")])
744
745 (define_insn "mulqihi3"
746 [(set (match_operand:HI 0 "register_operand" "=r")
747 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
748 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
749 "AVR_ENHANCED"
750 "muls %1,%2
751 movw %0,r0
752 clr r1"
753 [(set_attr "length" "3")
754 (set_attr "cc" "clobber")])
755
756 (define_insn "umulqihi3"
757 [(set (match_operand:HI 0 "register_operand" "=r")
758 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
759 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
760 "AVR_ENHANCED"
761 "mul %1,%2
762 movw %0,r0
763 clr r1"
764 [(set_attr "length" "3")
765 (set_attr "cc" "clobber")])
766
767 (define_expand "mulhi3"
768 [(set (match_operand:HI 0 "register_operand" "")
769 (mult:HI (match_operand:HI 1 "register_operand" "")
770 (match_operand:HI 2 "register_operand" "")))]
771 ""
772 "
773 {
774 if (!AVR_ENHANCED)
775 {
776 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
777 DONE;
778 }
779 }")
780
781 (define_insn "*mulhi3_enh"
782 [(set (match_operand:HI 0 "register_operand" "=&r")
783 (mult:HI (match_operand:HI 1 "register_operand" "r")
784 (match_operand:HI 2 "register_operand" "r")))]
785 "AVR_ENHANCED"
786 "mul %A1,%A2
787 movw %0,r0
788 mul %A1,%B2
789 add %B0,r0
790 mul %B1,%A2
791 add %B0,r0
792 clr r1"
793 [(set_attr "length" "7")
794 (set_attr "cc" "clobber")])
795
796 (define_expand "mulhi3_call"
797 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
798 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
799 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
800 (clobber (reg:HI 22))
801 (clobber (reg:QI 21))])
802 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
803 ""
804 "")
805
806 (define_insn "*mulhi3_call"
807 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
808 (clobber (reg:HI 22))
809 (clobber (reg:QI 21))]
810 "!AVR_ENHANCED"
811 "%~call __mulhi3"
812 [(set_attr "type" "xcall")
813 (set_attr "cc" "clobber")])
814
815 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
816 ;; All call-used registers clobbered otherwise - normal library call.
817 (define_expand "mulsi3"
818 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
819 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
820 (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
821 (clobber (reg:HI 26))
822 (clobber (reg:HI 30))])
823 (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
824 "AVR_ENHANCED"
825 "")
826
827 (define_insn "*mulsi3_call"
828 [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
829 (clobber (reg:HI 26))
830 (clobber (reg:HI 30))]
831 "AVR_ENHANCED"
832 "%~call __mulsi3"
833 [(set_attr "type" "xcall")
834 (set_attr "cc" "clobber")])
835
836 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
837 ; divmod
838
839 ;; Generate libgcc.S calls ourselves, because:
840 ;; - we know exactly which registers are clobbered (for QI and HI
841 ;; modes, some of the call-used registers are preserved)
842 ;; - we get both the quotient and the remainder at no extra cost
843
844 (define_expand "divmodqi4"
845 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
846 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
847 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
848 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
849 (clobber (reg:QI 22))
850 (clobber (reg:QI 23))])
851 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
852 (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
853 ""
854 "")
855
856 (define_insn "*divmodqi4_call"
857 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
858 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
859 (clobber (reg:QI 22))
860 (clobber (reg:QI 23))]
861 ""
862 "%~call __divmodqi4"
863 [(set_attr "type" "xcall")
864 (set_attr "cc" "clobber")])
865
866 (define_expand "udivmodqi4"
867 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
868 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
869 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
870 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
871 (clobber (reg:QI 23))])
872 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
873 (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
874 ""
875 "")
876
877 (define_insn "*udivmodqi4_call"
878 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
879 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
880 (clobber (reg:QI 23))]
881 ""
882 "%~call __udivmodqi4"
883 [(set_attr "type" "xcall")
884 (set_attr "cc" "clobber")])
885
886 (define_expand "divmodhi4"
887 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
888 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
889 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
890 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
891 (clobber (reg:HI 26))
892 (clobber (reg:QI 21))])
893 (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
894 (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
895 ""
896 "")
897
898 (define_insn "*divmodhi4_call"
899 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
900 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
901 (clobber (reg:HI 26))
902 (clobber (reg:QI 21))]
903 ""
904 "%~call __divmodhi4"
905 [(set_attr "type" "xcall")
906 (set_attr "cc" "clobber")])
907
908 (define_expand "udivmodhi4"
909 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
910 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
911 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
912 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
913 (clobber (reg:HI 26))
914 (clobber (reg:QI 21))])
915 (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
916 (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
917 ""
918 "")
919
920 (define_insn "*udivmodhi4_call"
921 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
922 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
923 (clobber (reg:HI 26))
924 (clobber (reg:QI 21))]
925 ""
926 "%~call __udivmodhi4"
927 [(set_attr "type" "xcall")
928 (set_attr "cc" "clobber")])
929
930 (define_expand "divmodsi4"
931 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
932 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
933 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
934 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
935 (clobber (reg:HI 26))
936 (clobber (reg:HI 30))])
937 (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
938 (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
939 ""
940 "")
941
942 (define_insn "*divmodsi4_call"
943 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
944 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
945 (clobber (reg:HI 26))
946 (clobber (reg:HI 30))]
947 ""
948 "%~call __divmodsi4"
949 [(set_attr "type" "xcall")
950 (set_attr "cc" "clobber")])
951
952 (define_expand "udivmodsi4"
953 [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
954 (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
955 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
956 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
957 (clobber (reg:HI 26))
958 (clobber (reg:HI 30))])
959 (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
960 (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
961 ""
962 "")
963
964 (define_insn "*udivmodsi4_call"
965 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
966 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
967 (clobber (reg:HI 26))
968 (clobber (reg:HI 30))]
969 ""
970 "%~call __udivmodsi4"
971 [(set_attr "type" "xcall")
972 (set_attr "cc" "clobber")])
973
974 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
975 ; and
976
977 (define_insn "andqi3"
978 [(set (match_operand:QI 0 "register_operand" "=r,d")
979 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
980 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
981 ""
982 "@
983 and %0,%2
984 andi %0,lo8(%2)"
985 [(set_attr "length" "1,1")
986 (set_attr "cc" "set_zn,set_zn")])
987
988 (define_insn "andhi3"
989 [(set (match_operand:HI 0 "register_operand" "=r,d,r")
990 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
991 (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
992 (clobber (match_scratch:QI 3 "=X,X,&d"))]
993 ""
994 "*{
995 if (which_alternative==0)
996 return (AS2 (and,%A0,%A2) CR_TAB
997 AS2 (and,%B0,%B2));
998 else if (which_alternative==1)
999 {
1000 if (GET_CODE (operands[2]) == CONST_INT)
1001 {
1002 int mask = INTVAL (operands[2]);
1003 if ((mask & 0xff) != 0xff)
1004 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1005 if ((mask & 0xff00) != 0xff00)
1006 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1007 return \"\";
1008 }
1009 return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1010 AS2 (andi,%B0,hi8(%2)));
1011 }
1012 return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1013 AS2 (and,%A0,%3) CR_TAB
1014 AS1 (clr,%B0));
1015 }"
1016 [(set_attr "length" "2,2,3")
1017 (set_attr "cc" "set_n,clobber,set_n")])
1018
1019 (define_insn "andsi3"
1020 [(set (match_operand:SI 0 "register_operand" "=r,d")
1021 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1022 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1023 ""
1024 "*{
1025 if (which_alternative==0)
1026 return (AS2 (and, %0,%2) CR_TAB
1027 AS2 (and, %B0,%B2) CR_TAB
1028 AS2 (and, %C0,%C2) CR_TAB
1029 AS2 (and, %D0,%D2));
1030 else if (which_alternative==1)
1031 {
1032 if (GET_CODE (operands[2]) == CONST_INT)
1033 {
1034 HOST_WIDE_INT mask = INTVAL (operands[2]);
1035 if ((mask & 0xff) != 0xff)
1036 output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1037 if ((mask & 0xff00) != 0xff00)
1038 output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1039 if ((mask & 0xff0000L) != 0xff0000L)
1040 output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1041 if ((mask & 0xff000000L) != 0xff000000L)
1042 output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1043 return \"\";
1044 }
1045 return (AS2 (andi, %A0,lo8(%2)) CR_TAB
1046 AS2 (andi, %B0,hi8(%2)) CR_TAB
1047 AS2 (andi, %C0,hlo8(%2)) CR_TAB
1048 AS2 (andi, %D0,hhi8(%2)));
1049 }
1050 return \"bug\";
1051 }"
1052 [(set_attr "length" "4,4")
1053 (set_attr "cc" "set_n,set_n")])
1054
1055 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1056 ;; ior
1057
1058 (define_insn "iorqi3"
1059 [(set (match_operand:QI 0 "register_operand" "=r,d")
1060 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1061 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1062 ""
1063 "@
1064 or %0,%2
1065 ori %0,lo8(%2)"
1066 [(set_attr "length" "1,1")
1067 (set_attr "cc" "set_zn,set_zn")])
1068
1069 (define_insn "iorhi3"
1070 [(set (match_operand:HI 0 "register_operand" "=r,d")
1071 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1072 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1073 ""
1074 "*{
1075 if (which_alternative==0)
1076 return (AS2 (or,%A0,%A2) CR_TAB
1077 AS2 (or,%B0,%B2));
1078 if (GET_CODE (operands[2]) == CONST_INT)
1079 {
1080 int mask = INTVAL (operands[2]);
1081 if (mask & 0xff)
1082 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1083 if (mask & 0xff00)
1084 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1085 return \"\";
1086 }
1087 return (AS2 (ori,%0,lo8(%2)) CR_TAB
1088 AS2 (ori,%B0,hi8(%2)));
1089 }"
1090 [(set_attr "length" "2,2")
1091 (set_attr "cc" "set_n,clobber")])
1092
1093 (define_insn "*iorhi3_clobber"
1094 [(set (match_operand:HI 0 "register_operand" "=r,r")
1095 (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1096 (match_operand:HI 2 "immediate_operand" "M,i")))
1097 (clobber (match_scratch:QI 3 "=&d,&d"))]
1098 ""
1099 "@
1100 ldi %3,lo8(%2)\;or %A0,%3
1101 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1102 [(set_attr "length" "2,4")
1103 (set_attr "cc" "clobber,set_n")])
1104
1105 (define_insn "iorsi3"
1106 [(set (match_operand:SI 0 "register_operand" "=r,d")
1107 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1108 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1109 ""
1110 "*{
1111 if (which_alternative==0)
1112 return (AS2 (or, %0,%2) CR_TAB
1113 AS2 (or, %B0,%B2) CR_TAB
1114 AS2 (or, %C0,%C2) CR_TAB
1115 AS2 (or, %D0,%D2));
1116 if (GET_CODE (operands[2]) == CONST_INT)
1117 {
1118 HOST_WIDE_INT mask = INTVAL (operands[2]);
1119 if (mask & 0xff)
1120 output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1121 if (mask & 0xff00)
1122 output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1123 if (mask & 0xff0000L)
1124 output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1125 if (mask & 0xff000000L)
1126 output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1127 return \"\";
1128 }
1129 return (AS2 (ori, %A0,lo8(%2)) CR_TAB
1130 AS2 (ori, %B0,hi8(%2)) CR_TAB
1131 AS2 (ori, %C0,hlo8(%2)) CR_TAB
1132 AS2 (ori, %D0,hhi8(%2)));
1133 }"
1134 [(set_attr "length" "4,4")
1135 (set_attr "cc" "set_n,clobber")])
1136
1137 (define_insn "*iorsi3_clobber"
1138 [(set (match_operand:SI 0 "register_operand" "=r,r")
1139 (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1140 (match_operand:SI 2 "immediate_operand" "M,i")))
1141 (clobber (match_scratch:QI 3 "=&d,&d"))]
1142 ""
1143 "@
1144 ldi %3,lo8(%2)\;or %A0,%3
1145 ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3"
1146 [(set_attr "length" "2,8")
1147 (set_attr "cc" "clobber,set_n")])
1148
1149 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1150 ;; xor
1151
1152 (define_insn "xorqi3"
1153 [(set (match_operand:QI 0 "register_operand" "=r")
1154 (xor:QI (match_operand:QI 1 "register_operand" "%0")
1155 (match_operand:QI 2 "register_operand" "r")))]
1156 ""
1157 "eor %0,%2"
1158 [(set_attr "length" "1")
1159 (set_attr "cc" "set_zn")])
1160
1161 (define_insn "xorhi3"
1162 [(set (match_operand:HI 0 "register_operand" "=r")
1163 (xor:HI (match_operand:HI 1 "register_operand" "%0")
1164 (match_operand:HI 2 "register_operand" "r")))]
1165 ""
1166 "eor %0,%2
1167 eor %B0,%B2"
1168 [(set_attr "length" "2")
1169 (set_attr "cc" "set_n")])
1170
1171 (define_insn "xorsi3"
1172 [(set (match_operand:SI 0 "register_operand" "=r")
1173 (xor:SI (match_operand:SI 1 "register_operand" "%0")
1174 (match_operand:SI 2 "register_operand" "r")))]
1175 ""
1176 "eor %0,%2
1177 eor %B0,%B2
1178 eor %C0,%C2
1179 eor %D0,%D2"
1180 [(set_attr "length" "4")
1181 (set_attr "cc" "set_n")])
1182
1183 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1184 ;; arithmetic shift left
1185
1186 (define_insn "ashlqi3"
1187 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
1188 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1189 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
1190 ""
1191 "* return ashlqi3_out (insn, operands, NULL);"
1192 [(set_attr "length" "5,0,1,2,4,6,9")
1193 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1194
1195 (define_insn "ashlhi3"
1196 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
1197 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1198 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1199 ""
1200 "* return ashlhi3_out (insn, operands, NULL);"
1201 [(set_attr "length" "6,0,2,2,4,10,10")
1202 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1203
1204 (define_insn "ashlsi3"
1205 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
1206 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1207 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1208 ""
1209 "* return ashlsi3_out (insn, operands, NULL);"
1210 [(set_attr "length" "8,0,4,4,8,10,12")
1211 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1212
1213 ;; Optimize if a scratch register from LD_REGS happens to be available.
1214
1215 (define_peephole2
1216 [(match_scratch:QI 3 "d")
1217 (set (match_operand:HI 0 "register_operand" "")
1218 (ashift:HI (match_operand:HI 1 "register_operand" "")
1219 (match_operand:QI 2 "const_int_operand" "")))]
1220 ""
1221 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1222 (clobber (match_dup 3))])]
1223 "if (!avr_peep2_scratch_safe (operands[3]))
1224 FAIL;")
1225
1226 (define_insn "*ashlhi3_const"
1227 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1228 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
1229 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1230 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1231 "reload_completed"
1232 "* return ashlhi3_out (insn, operands, NULL);"
1233 [(set_attr "length" "0,2,2,4,10")
1234 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
1235
1236 (define_peephole2
1237 [(match_scratch:QI 3 "d")
1238 (set (match_operand:SI 0 "register_operand" "")
1239 (ashift:SI (match_operand:SI 1 "register_operand" "")
1240 (match_operand:QI 2 "const_int_operand" "")))]
1241 ""
1242 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1243 (clobber (match_dup 3))])]
1244 "if (!avr_peep2_scratch_safe (operands[3]))
1245 FAIL;")
1246
1247 (define_insn "*ashlsi3_const"
1248 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1249 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
1250 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1251 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1252 "reload_completed"
1253 "* return ashlsi3_out (insn, operands, NULL);"
1254 [(set_attr "length" "0,4,4,10")
1255 (set_attr "cc" "none,set_n,clobber,clobber")])
1256
1257 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1258 ;; arithmetic shift right
1259
1260 (define_insn "ashrqi3"
1261 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1262 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1263 (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))]
1264 ""
1265 "* return ashrqi3_out (insn, operands, NULL);"
1266 [(set_attr "length" "5,0,1,2,5,9")
1267 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
1268
1269 (define_insn "ashrhi3"
1270 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
1271 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1272 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1273 ""
1274 "* return ashrhi3_out (insn, operands, NULL);"
1275 [(set_attr "length" "6,0,2,4,4,10,10")
1276 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1277
1278 (define_insn "ashrsi3"
1279 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
1280 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1281 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1282 ""
1283 "* return ashrsi3_out (insn, operands, NULL);"
1284 [(set_attr "length" "8,0,4,6,8,10,12")
1285 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1286
1287 ;; Optimize if a scratch register from LD_REGS happens to be available.
1288
1289 (define_peephole2
1290 [(match_scratch:QI 3 "d")
1291 (set (match_operand:HI 0 "register_operand" "")
1292 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1293 (match_operand:QI 2 "const_int_operand" "")))]
1294 ""
1295 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1296 (clobber (match_dup 3))])]
1297 "if (!avr_peep2_scratch_safe (operands[3]))
1298 FAIL;")
1299
1300 (define_insn "*ashrhi3_const"
1301 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1302 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
1303 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1304 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1305 "reload_completed"
1306 "* return ashrhi3_out (insn, operands, NULL);"
1307 [(set_attr "length" "0,2,4,4,10")
1308 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
1309
1310 (define_peephole2
1311 [(match_scratch:QI 3 "d")
1312 (set (match_operand:SI 0 "register_operand" "")
1313 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1314 (match_operand:QI 2 "const_int_operand" "")))]
1315 ""
1316 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1317 (clobber (match_dup 3))])]
1318 "if (!avr_peep2_scratch_safe (operands[3]))
1319 FAIL;")
1320
1321 (define_insn "*ashrsi3_const"
1322 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1323 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
1324 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1325 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1326 "reload_completed"
1327 "* return ashrsi3_out (insn, operands, NULL);"
1328 [(set_attr "length" "0,4,4,10")
1329 (set_attr "cc" "none,clobber,set_n,clobber")])
1330
1331 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1332 ;; logical shift right
1333
1334 (define_insn "lshrqi3"
1335 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
1336 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1337 (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))]
1338 ""
1339 "* return lshrqi3_out (insn, operands, NULL);"
1340 [(set_attr "length" "5,0,1,2,4,6,9")
1341 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1342
1343 (define_insn "lshrhi3"
1344 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
1345 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1346 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1347 ""
1348 "* return lshrhi3_out (insn, operands, NULL);"
1349 [(set_attr "length" "6,0,2,2,4,10,10")
1350 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1351
1352 (define_insn "lshrsi3"
1353 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
1354 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1355 (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))]
1356 ""
1357 "* return lshrsi3_out (insn, operands, NULL);"
1358 [(set_attr "length" "8,0,4,4,8,10,12")
1359 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1360
1361 ;; Optimize if a scratch register from LD_REGS happens to be available.
1362
1363 (define_peephole2
1364 [(match_scratch:QI 3 "d")
1365 (set (match_operand:HI 0 "register_operand" "")
1366 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1367 (match_operand:QI 2 "const_int_operand" "")))]
1368 ""
1369 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1370 (clobber (match_dup 3))])]
1371 "if (!avr_peep2_scratch_safe (operands[3]))
1372 FAIL;")
1373
1374 (define_insn "*lshrhi3_const"
1375 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1376 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
1377 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1378 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1379 "reload_completed"
1380 "* return lshrhi3_out (insn, operands, NULL);"
1381 [(set_attr "length" "0,2,2,4,10")
1382 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
1383
1384 (define_peephole2
1385 [(match_scratch:QI 3 "d")
1386 (set (match_operand:SI 0 "register_operand" "")
1387 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1388 (match_operand:QI 2 "const_int_operand" "")))]
1389 ""
1390 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1391 (clobber (match_dup 3))])]
1392 "if (!avr_peep2_scratch_safe (operands[3]))
1393 FAIL;")
1394
1395 (define_insn "*lshrsi3_const"
1396 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1397 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
1398 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1399 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1400 "reload_completed"
1401 "* return lshrsi3_out (insn, operands, NULL);"
1402 [(set_attr "length" "0,4,4,10")
1403 (set_attr "cc" "none,clobber,clobber,clobber")])
1404
1405 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
1406 ;; abs
1407
1408 (define_insn "absqi2"
1409 [(set (match_operand:QI 0 "register_operand" "=r")
1410 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
1411 ""
1412 "sbrc %0,7
1413 neg %0"
1414 [(set_attr "length" "2")
1415 (set_attr "cc" "clobber")])
1416
1417
1418 (define_insn "abssf2"
1419 [(set (match_operand:SF 0 "register_operand" "=d,r")
1420 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
1421 ""
1422 "@
1423 andi %D0,0x7f
1424 clt\;bld %D0,7"
1425 [(set_attr "length" "1,2")
1426 (set_attr "cc" "set_n,clobber")])
1427
1428 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
1429 ;; neg
1430
1431 (define_insn "negqi2"
1432 [(set (match_operand:QI 0 "register_operand" "=r")
1433 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1434 ""
1435 "neg %0"
1436 [(set_attr "length" "1")
1437 (set_attr "cc" "set_zn")])
1438
1439 (define_insn "neghi2"
1440 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
1441 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
1442 ""
1443 "@
1444 com %B0\;neg %A0\;sbci %B0,lo8(-1)
1445 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
1446 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
1447 [(set_attr "length" "3,4,4")
1448 (set_attr "cc" "set_czn,set_n,set_czn")])
1449
1450 (define_insn "negsi2"
1451 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r")
1452 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
1453 ""
1454 "@
1455 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
1456 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1457 clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1458 [(set_attr_alternative "length"
1459 [(const_int 7)
1460 (const_int 8)
1461 (if_then_else (eq_attr "mcu_have_movw" "yes")
1462 (const_int 7)
1463 (const_int 8))])
1464 (set_attr "cc" "set_czn,set_n,set_czn")])
1465
1466 (define_insn "negsf2"
1467 [(set (match_operand:SF 0 "register_operand" "=d,r")
1468 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
1469 ""
1470 "@
1471 subi %D0,0x80
1472 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
1473 [(set_attr "length" "1,4")
1474 (set_attr "cc" "set_n,set_n")])
1475
1476 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1477 ;; not
1478
1479 (define_insn "one_cmplqi2"
1480 [(set (match_operand:QI 0 "register_operand" "=r")
1481 (not:QI (match_operand:QI 1 "register_operand" "0")))]
1482 ""
1483 "com %0"
1484 [(set_attr "length" "1")
1485 (set_attr "cc" "set_czn")])
1486
1487 (define_insn "one_cmplhi2"
1488 [(set (match_operand:HI 0 "register_operand" "=r")
1489 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1490 ""
1491 "com %0
1492 com %B0"
1493 [(set_attr "length" "2")
1494 (set_attr "cc" "set_n")])
1495
1496 (define_insn "one_cmplsi2"
1497 [(set (match_operand:SI 0 "register_operand" "=r")
1498 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1499 ""
1500 "com %0
1501 com %B0
1502 com %C0
1503 com %D0"
1504 [(set_attr "length" "4")
1505 (set_attr "cc" "set_n")])
1506
1507 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1508 ;; sign extend
1509
1510 (define_insn "extendqihi2"
1511 [(set (match_operand:HI 0 "register_operand" "=r,r")
1512 (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1513 ""
1514 "@
1515 clr %B0\;sbrc %0,7\;com %B0
1516 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
1517 [(set_attr "length" "3,4")
1518 (set_attr "cc" "set_n,set_n")])
1519
1520 (define_insn "extendqisi2"
1521 [(set (match_operand:SI 0 "register_operand" "=r,r")
1522 (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1523 ""
1524 "@
1525 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
1526 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
1527 [(set_attr "length" "5,6")
1528 (set_attr "cc" "set_n,set_n")])
1529
1530 (define_insn "extendhisi2"
1531 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1532 (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1533 ""
1534 "@
1535 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
1536 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
1537 [(set_attr_alternative "length"
1538 [(const_int 4)
1539 (if_then_else (eq_attr "mcu_have_movw" "yes")
1540 (const_int 5)
1541 (const_int 6))])
1542 (set_attr "cc" "set_n,set_n")])
1543
1544 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1545 ;; zero extend
1546
1547 (define_insn "zero_extendqihi2"
1548 [(set (match_operand:HI 0 "register_operand" "=r,r")
1549 (zero_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1550 ""
1551 "@
1552 clr %B0
1553 mov %A0,%A1\;clr %B0"
1554 [(set_attr "length" "1,2")
1555 (set_attr "cc" "set_n,set_n")])
1556
1557 (define_insn "zero_extendqisi2"
1558 [(set (match_operand:SI 0 "register_operand" "=r,r")
1559 (zero_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1560 ""
1561 "@
1562 clr %B0\;clr %C0\;clr %D0
1563 mov %A0,%A1\;clr %B0\;clr %C0\;clr %D0"
1564 [(set_attr "length" "3,4")
1565 (set_attr "cc" "set_n,set_n")])
1566
1567 (define_insn "zero_extendhisi2"
1568 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1569 (zero_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1570 ""
1571 "@
1572 clr %C0\;clr %D0
1573 {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;clr %D0"
1574 [(set_attr_alternative "length"
1575 [(const_int 2)
1576 (if_then_else (eq_attr "mcu_have_movw" "yes")
1577 (const_int 3)
1578 (const_int 4))])
1579 (set_attr "cc" "set_n,set_n")])
1580
1581 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
1582 ;; compare
1583
1584 (define_insn "tstqi"
1585 [(set (cc0)
1586 (match_operand:QI 0 "register_operand" "r"))]
1587 ""
1588 "tst %0"
1589 [(set_attr "cc" "compare")
1590 (set_attr "length" "1")])
1591
1592 (define_insn "*negated_tstqi"
1593 [(set (cc0)
1594 (neg:QI (match_operand:QI 0 "register_operand" "r")))]
1595 ""
1596 "cp __zero_reg__,%0"
1597 [(set_attr "cc" "compare")
1598 (set_attr "length" "1")])
1599
1600 (define_insn "tsthi"
1601 [(set (cc0)
1602 (match_operand:HI 0 "register_operand" "!w,r"))]
1603 ""
1604 "* return out_tsthi (insn,NULL);"
1605 [(set_attr "cc" "compare,compare")
1606 (set_attr "length" "1,2")])
1607
1608 (define_insn "*negated_tsthi"
1609 [(set (cc0)
1610 (neg:HI (match_operand:HI 0 "register_operand" "r")))]
1611 ""
1612 "cp __zero_reg__,%A0
1613 cpc __zero_reg__,%B0"
1614 [(set_attr "cc" "compare")
1615 (set_attr "length" "2")])
1616
1617 (define_insn "tstsi"
1618 [(set (cc0)
1619 (match_operand:SI 0 "register_operand" "r"))]
1620 ""
1621 "* return out_tstsi (insn,NULL);"
1622 [(set_attr "cc" "compare")
1623 (set_attr "length" "4")])
1624
1625 (define_insn "*negated_tstsi"
1626 [(set (cc0)
1627 (neg:SI (match_operand:SI 0 "register_operand" "r")))]
1628 ""
1629 "cp __zero_reg__,%A0
1630 cpc __zero_reg__,%B0
1631 cpc __zero_reg__,%C0
1632 cpc __zero_reg__,%D0"
1633 [(set_attr "cc" "compare")
1634 (set_attr "length" "4")])
1635
1636
1637 (define_insn "cmpqi"
1638 [(set (cc0)
1639 (compare (match_operand:QI 0 "register_operand" "r,d")
1640 (match_operand:QI 1 "nonmemory_operand" "r,i")))]
1641 ""
1642 "@
1643 cp %0,%1
1644 cpi %0,lo8(%1)"
1645 [(set_attr "cc" "compare,compare")
1646 (set_attr "length" "1,1")])
1647
1648 (define_insn "*cmpqi_sign_extend"
1649 [(set (cc0)
1650 (compare (sign_extend:HI
1651 (match_operand:QI 0 "register_operand" "d"))
1652 (match_operand:HI 1 "const_int_operand" "n")))]
1653 "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
1654 "cpi %0,lo8(%1)"
1655 [(set_attr "cc" "compare")
1656 (set_attr "length" "1")])
1657
1658 (define_insn "cmphi"
1659 [(set (cc0)
1660 (compare (match_operand:HI 0 "register_operand" "r,d,d,r,r")
1661 (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
1662 (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1663 ""
1664 "*{
1665 switch (which_alternative)
1666 {
1667 case 0:
1668 return (AS2 (cp,%A0,%A1) CR_TAB
1669 AS2 (cpc,%B0,%B1));
1670 case 1:
1671 if (reg_unused_after (insn, operands[0])
1672 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1673 && test_hard_reg_class (ADDW_REGS, operands[0]))
1674 return AS2 (sbiw,%0,%1);
1675 else
1676 return (AS2 (cpi,%0,%1) CR_TAB
1677 AS2 (cpc,%B0,__zero_reg__));
1678 case 2:
1679 if (reg_unused_after (insn, operands[0]))
1680 return (AS2 (subi,%0,lo8(%1)) CR_TAB
1681 AS2 (sbci,%B0,hi8(%1)));
1682 else
1683 return (AS2 (ldi, %2,hi8(%1)) CR_TAB
1684 AS2 (cpi, %A0,lo8(%1)) CR_TAB
1685 AS2 (cpc, %B0,%2));
1686 case 3:
1687 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1688 AS2 (cp, %A0,%2) CR_TAB
1689 AS2 (cpc, %B0,__zero_reg__));
1690
1691 case 4:
1692 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1693 AS2 (cp, %A0,%2) CR_TAB
1694 AS2 (ldi, %2,hi8(%1)) CR_TAB
1695 AS2 (cpc, %B0,%2));
1696 }
1697 return \"bug\";
1698 }"
1699 [(set_attr "cc" "compare,compare,compare,compare,compare")
1700 (set_attr "length" "2,2,3,3,4")])
1701
1702
1703 (define_insn "cmpsi"
1704 [(set (cc0)
1705 (compare (match_operand:SI 0 "register_operand" "r,d,d,r,r")
1706 (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
1707 (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1708 ""
1709 "*{
1710 switch (which_alternative)
1711 {
1712 case 0:
1713 return (AS2 (cp,%A0,%A1) CR_TAB
1714 AS2 (cpc,%B0,%B1) CR_TAB
1715 AS2 (cpc,%C0,%C1) CR_TAB
1716 AS2 (cpc,%D0,%D1));
1717 case 1:
1718 if (reg_unused_after (insn, operands[0])
1719 && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1720 && test_hard_reg_class (ADDW_REGS, operands[0]))
1721 return (AS2 (sbiw,%0,%1) CR_TAB
1722 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1723 AS2 (cpc,%D0,__zero_reg__));
1724 else
1725 return (AS2 (cpi,%A0,lo8(%1)) CR_TAB
1726 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1727 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1728 AS2 (cpc,%D0,__zero_reg__));
1729 case 2:
1730 if (reg_unused_after (insn, operands[0]))
1731 return (AS2 (subi,%A0,lo8(%1)) CR_TAB
1732 AS2 (sbci,%B0,hi8(%1)) CR_TAB
1733 AS2 (sbci,%C0,hlo8(%1)) CR_TAB
1734 AS2 (sbci,%D0,hhi8(%1)));
1735 else
1736 return (AS2 (cpi, %A0,lo8(%1)) CR_TAB
1737 AS2 (ldi, %2,hi8(%1)) CR_TAB
1738 AS2 (cpc, %B0,%2) CR_TAB
1739 AS2 (ldi, %2,hlo8(%1)) CR_TAB
1740 AS2 (cpc, %C0,%2) CR_TAB
1741 AS2 (ldi, %2,hhi8(%1)) CR_TAB
1742 AS2 (cpc, %D0,%2));
1743 case 3:
1744 return (AS2 (ldi,%2,lo8(%1)) CR_TAB
1745 AS2 (cp,%A0,%2) CR_TAB
1746 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1747 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1748 AS2 (cpc,%D0,__zero_reg__));
1749 case 4:
1750 return (AS2 (ldi, %2,lo8(%1)) CR_TAB
1751 AS2 (cp, %A0,%2) CR_TAB
1752 AS2 (ldi, %2,hi8(%1)) CR_TAB
1753 AS2 (cpc, %B0,%2) CR_TAB
1754 AS2 (ldi, %2,hlo8(%1)) CR_TAB
1755 AS2 (cpc, %C0,%2) CR_TAB
1756 AS2 (ldi, %2,hhi8(%1)) CR_TAB
1757 AS2 (cpc, %D0,%2));
1758 }
1759 return \"bug\";
1760 }"
1761 [(set_attr "cc" "compare,compare,compare,compare,compare")
1762 (set_attr "length" "4,4,7,5,8")])
1763
1764 ;; ----------------------------------------------------------------------
1765 ;; JUMP INSTRUCTIONS
1766 ;; ----------------------------------------------------------------------
1767 ;; Conditional jump instructions
1768
1769 (define_expand "beq"
1770 [(set (pc)
1771 (if_then_else (eq (cc0) (const_int 0))
1772 (label_ref (match_operand 0 "" ""))
1773 (pc)))]
1774 ""
1775 "")
1776
1777 (define_expand "bne"
1778 [(set (pc)
1779 (if_then_else (ne (cc0) (const_int 0))
1780 (label_ref (match_operand 0 "" ""))
1781 (pc)))]
1782 ""
1783 "")
1784
1785 (define_expand "bge"
1786 [(set (pc)
1787 (if_then_else (ge (cc0) (const_int 0))
1788 (label_ref (match_operand 0 "" ""))
1789 (pc)))]
1790 ""
1791 "")
1792
1793 (define_expand "bgeu"
1794 [(set (pc)
1795 (if_then_else (geu (cc0) (const_int 0))
1796 (label_ref (match_operand 0 "" ""))
1797 (pc)))]
1798 ""
1799 "")
1800
1801 (define_expand "blt"
1802 [(set (pc)
1803 (if_then_else (lt (cc0) (const_int 0))
1804 (label_ref (match_operand 0 "" ""))
1805 (pc)))]
1806 ""
1807 "")
1808
1809 (define_expand "bltu"
1810 [(set (pc)
1811 (if_then_else (ltu (cc0) (const_int 0))
1812 (label_ref (match_operand 0 "" ""))
1813 (pc)))]
1814 ""
1815 "")
1816
1817
1818
1819 /****************************************************************
1820 AVR not have following conditional jumps: LE,LEU,GT,GTU.
1821 Convert them all to proper jumps.
1822 *****************************************************************/
1823
1824 (define_expand "ble"
1825 [(set (pc)
1826 (if_then_else (le (cc0) (const_int 0))
1827 (label_ref (match_operand 0 "" ""))
1828 (pc)))]
1829 ""
1830 "")
1831
1832 (define_expand "bleu"
1833 [(set (pc)
1834 (if_then_else (leu (cc0) (const_int 0))
1835 (label_ref (match_operand 0 "" ""))
1836 (pc)))]
1837 ""
1838 "")
1839
1840 (define_expand "bgt"
1841 [(set (pc)
1842 (if_then_else (gt (cc0) (const_int 0))
1843 (label_ref (match_operand 0 "" ""))
1844 (pc)))]
1845 ""
1846 "")
1847
1848 (define_expand "bgtu"
1849 [(set (pc)
1850 (if_then_else (gtu (cc0) (const_int 0))
1851 (label_ref (match_operand 0 "" ""))
1852 (pc)))]
1853 ""
1854 "")
1855
1856 ;; Test a single bit in a QI/HI/SImode register.
1857 (define_insn "*sbrx_branch"
1858 [(set (pc)
1859 (if_then_else
1860 (match_operator 0 "eqne_operator"
1861 [(zero_extract
1862 (match_operand:QI 1 "register_operand" "r")
1863 (const_int 1)
1864 (match_operand 2 "const_int_operand" "n"))
1865 (const_int 0)])
1866 (label_ref (match_operand 3 "" ""))
1867 (pc)))]
1868 ""
1869 "* return avr_out_sbxx_branch (insn, operands);"
1870 [(set (attr "length")
1871 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1872 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1873 (const_int 2)
1874 (if_then_else (eq_attr "mcu_mega" "no")
1875 (const_int 2)
1876 (const_int 4))))
1877 (set_attr "cc" "clobber")])
1878
1879 (define_insn "*sbrx_and_branchhi"
1880 [(set (pc)
1881 (if_then_else
1882 (match_operator 0 "eqne_operator"
1883 [(and:HI
1884 (match_operand:HI 1 "register_operand" "r")
1885 (match_operand:HI 2 "single_one_operand" "n"))
1886 (const_int 0)])
1887 (label_ref (match_operand 3 "" ""))
1888 (pc)))]
1889 ""
1890 "* return avr_out_sbxx_branch (insn, operands);"
1891 [(set (attr "length")
1892 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1893 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1894 (const_int 2)
1895 (if_then_else (eq_attr "mcu_mega" "no")
1896 (const_int 2)
1897 (const_int 4))))
1898 (set_attr "cc" "clobber")])
1899
1900 (define_insn "*sbrx_and_branchsi"
1901 [(set (pc)
1902 (if_then_else
1903 (match_operator 0 "eqne_operator"
1904 [(and:SI
1905 (match_operand:SI 1 "register_operand" "r")
1906 (match_operand:SI 2 "single_one_operand" "n"))
1907 (const_int 0)])
1908 (label_ref (match_operand 3 "" ""))
1909 (pc)))]
1910 ""
1911 "* return avr_out_sbxx_branch (insn, operands);"
1912 [(set (attr "length")
1913 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1914 (le (minus (pc) (match_dup 3)) (const_int 2046)))
1915 (const_int 2)
1916 (if_then_else (eq_attr "mcu_mega" "no")
1917 (const_int 2)
1918 (const_int 4))))
1919 (set_attr "cc" "clobber")])
1920
1921 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
1922 (define_peephole2
1923 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1924 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1925 (label_ref (match_operand 1 "" ""))
1926 (pc)))]
1927 ""
1928 [(set (pc) (if_then_else (eq (zero_extract (match_dup 0)
1929 (const_int 1)
1930 (const_int 7))
1931 (const_int 0))
1932 (label_ref (match_dup 1))
1933 (pc)))]
1934 "")
1935
1936 (define_peephole2
1937 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1938 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1939 (label_ref (match_operand 1 "" ""))
1940 (pc)))]
1941 ""
1942 [(set (pc) (if_then_else (ne (zero_extract (match_dup 0)
1943 (const_int 1)
1944 (const_int 7))
1945 (const_int 0))
1946 (label_ref (match_dup 1))
1947 (pc)))]
1948 "")
1949
1950 (define_peephole2
1951 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1952 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1953 (label_ref (match_operand 1 "" ""))
1954 (pc)))]
1955 ""
1956 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
1957 (const_int 0))
1958 (label_ref (match_dup 1))
1959 (pc)))]
1960 "")
1961
1962 (define_peephole2
1963 [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1964 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1965 (label_ref (match_operand 1 "" ""))
1966 (pc)))]
1967 ""
1968 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
1969 (const_int 0))
1970 (label_ref (match_dup 1))
1971 (pc)))]
1972 "")
1973
1974 (define_peephole2
1975 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1976 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1977 (label_ref (match_operand 1 "" ""))
1978 (pc)))]
1979 ""
1980 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
1981 (const_int 0))
1982 (label_ref (match_dup 1))
1983 (pc)))]
1984 "operands[2] = GEN_INT (-2147483647 - 1);")
1985
1986 (define_peephole2
1987 [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1988 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1989 (label_ref (match_operand 1 "" ""))
1990 (pc)))]
1991 ""
1992 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
1993 (const_int 0))
1994 (label_ref (match_dup 1))
1995 (pc)))]
1996 "operands[2] = GEN_INT (-2147483647 - 1);")
1997
1998 ;; ************************************************************************
1999 ;; Implementation of conditional jumps here.
2000 ;; Compare with 0 (test) jumps
2001 ;; ************************************************************************
2002
2003 (define_insn "branch"
2004 [(set (pc)
2005 (if_then_else (match_operator 1 "simple_comparison_operator"
2006 [(cc0)
2007 (const_int 0)])
2008 (label_ref (match_operand 0 "" ""))
2009 (pc)))]
2010 ""
2011 "*
2012 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2013 [(set_attr "type" "branch")
2014 (set_attr "cc" "clobber")])
2015
2016 (define_insn "difficult_branch"
2017 [(set (pc)
2018 (if_then_else (match_operator 1 "difficult_comparison_operator"
2019 [(cc0)
2020 (const_int 0)])
2021 (label_ref (match_operand 0 "" ""))
2022 (pc)))]
2023 ""
2024 "*
2025 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2026 [(set_attr "type" "branch1")
2027 (set_attr "cc" "clobber")])
2028
2029 ;; revers branch
2030
2031 (define_insn "rvbranch"
2032 [(set (pc)
2033 (if_then_else (match_operator 1 "simple_comparison_operator"
2034 [(cc0)
2035 (const_int 0)])
2036 (pc)
2037 (label_ref (match_operand 0 "" ""))))]
2038 ""
2039 "*
2040 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2041 [(set_attr "type" "branch1")
2042 (set_attr "cc" "clobber")])
2043
2044 (define_insn "difficult_rvbranch"
2045 [(set (pc)
2046 (if_then_else (match_operator 1 "difficult_comparison_operator"
2047 [(cc0)
2048 (const_int 0)])
2049 (pc)
2050 (label_ref (match_operand 0 "" ""))))]
2051 ""
2052 "*
2053 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2054 [(set_attr "type" "branch")
2055 (set_attr "cc" "clobber")])
2056
2057 ;; **************************************************************************
2058 ;; Unconditional and other jump instructions.
2059
2060 (define_insn "jump"
2061 [(set (pc)
2062 (label_ref (match_operand 0 "" "")))]
2063 ""
2064 "*{
2065 if (AVR_MEGA && get_attr_length (insn) != 1)
2066 return AS1 (jmp,%0);
2067 return AS1 (rjmp,%0);
2068 }"
2069 [(set (attr "length")
2070 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2071 (le (minus (pc) (match_dup 0)) (const_int 2047)))
2072 (const_int 1)
2073 (const_int 2)))
2074 (set_attr "cc" "none")])
2075
2076 ;; call
2077
2078 (define_expand "call"
2079 [(call (match_operand:HI 0 "call_insn_operand" "")
2080 (match_operand:HI 1 "general_operand" ""))]
2081 ;; Operand 1 not used on the AVR.
2082 ""
2083 "")
2084
2085 ;; call value
2086
2087 (define_expand "call_value"
2088 [(set (match_operand 0 "register_operand" "")
2089 (call (match_operand:HI 1 "call_insn_operand" "")
2090 (match_operand:HI 2 "general_operand" "")))]
2091 ;; Operand 2 not used on the AVR.
2092 ""
2093 "")
2094
2095 (define_insn "call_insn"
2096 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,s,n"))
2097 (match_operand:HI 1 "general_operand" "X,X,X,X"))]
2098 ;; We don't need in saving Z register because r30,r31 is a call used registers
2099 ;; Operand 1 not used on the AVR.
2100 "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
2101 "*{
2102 if (which_alternative==0)
2103 return \"icall\";
2104 else if (which_alternative==1)
2105 {
2106 if (AVR_HAVE_MOVW)
2107 return (AS2 (movw, r30, %0) CR_TAB
2108 \"icall\");
2109 else
2110 return (AS2 (mov, r30, %A0) CR_TAB
2111 AS2 (mov, r31, %B0) CR_TAB
2112 \"icall\");
2113 }
2114 else if (which_alternative==2)
2115 return AS1(%~call,%c0);
2116 return (AS2 (ldi,r30,lo8(%0)) CR_TAB
2117 AS2 (ldi,r31,hi8(%0)) CR_TAB
2118 \"icall\");
2119 }"
2120 [(set_attr "cc" "clobber,clobber,clobber,clobber")
2121 (set_attr_alternative "length"
2122 [(const_int 1)
2123 (if_then_else (eq_attr "mcu_have_movw" "yes")
2124 (const_int 2)
2125 (const_int 3))
2126 (if_then_else (eq_attr "mcu_mega" "yes")
2127 (const_int 2)
2128 (const_int 1))
2129 (const_int 3)])])
2130
2131 (define_insn "call_value_insn"
2132 [(set (match_operand 0 "register_operand" "=r,r,r,r")
2133 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,s,n"))
2134 ;; We don't need in saving Z register because r30,r31 is a call used registers
2135 (match_operand:HI 2 "general_operand" "X,X,X,X")))]
2136 ;; Operand 2 not used on the AVR.
2137 "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
2138 "*{
2139 if (which_alternative==0)
2140 return \"icall\";
2141 else if (which_alternative==1)
2142 {
2143 if (AVR_HAVE_MOVW)
2144 return (AS2 (movw, r30, %1) CR_TAB
2145 \"icall\");
2146 else
2147 return (AS2 (mov, r30, %A1) CR_TAB
2148 AS2 (mov, r31, %B1) CR_TAB
2149 \"icall\");
2150 }
2151 else if (which_alternative==2)
2152 return AS1(%~call,%c1);
2153 return (AS2 (ldi, r30, lo8(%1)) CR_TAB
2154 AS2 (ldi, r31, hi8(%1)) CR_TAB
2155 \"icall\");
2156 }"
2157 [(set_attr "cc" "clobber,clobber,clobber,clobber")
2158 (set_attr_alternative "length"
2159 [(const_int 1)
2160 (if_then_else (eq_attr "mcu_have_movw" "yes")
2161 (const_int 2)
2162 (const_int 3))
2163 (if_then_else (eq_attr "mcu_mega" "yes")
2164 (const_int 2)
2165 (const_int 1))
2166 (const_int 3)])])
2167
2168 (define_insn "return"
2169 [(return)]
2170 "reload_completed && avr_simple_epilogue ()"
2171 "ret"
2172 [(set_attr "cc" "none")
2173 (set_attr "length" "1")])
2174
2175 (define_insn "nop"
2176 [(const_int 0)]
2177 ""
2178 "nop"
2179 [(set_attr "cc" "none")
2180 (set_attr "length" "1")])
2181
2182 ; indirect jump
2183 (define_insn "indirect_jump"
2184 [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2185 ""
2186 "@
2187 ijmp
2188 push %A0\;push %B0\;ret"
2189 [(set_attr "length" "1,3")
2190 (set_attr "cc" "none,none")])
2191
2192 ;; table jump
2193
2194 ;; Table made from "rjmp" instructions for <=8K devices.
2195 (define_insn "*tablejump_rjmp"
2196 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
2197 UNSPEC_INDEX_JMP))
2198 (use (label_ref (match_operand 1 "" "")))
2199 (clobber (match_dup 0))]
2200 "!AVR_MEGA"
2201 "@
2202 ijmp
2203 push %A0\;push %B0\;ret"
2204 [(set_attr "length" "1,3")
2205 (set_attr "cc" "none,none")])
2206
2207 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2208 (define_insn "*tablejump_lib"
2209 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2210 UNSPEC_INDEX_JMP))
2211 (use (label_ref (match_operand 1 "" "")))
2212 (clobber (match_dup 0))]
2213 "AVR_MEGA && TARGET_CALL_PROLOGUES"
2214 "jmp __tablejump2__"
2215 [(set_attr "length" "2")
2216 (set_attr "cc" "clobber")])
2217
2218 (define_insn "*tablejump_enh"
2219 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2220 UNSPEC_INDEX_JMP))
2221 (use (label_ref (match_operand 1 "" "")))
2222 (clobber (match_dup 0))]
2223 "AVR_MEGA && AVR_ENHANCED"
2224 "lsl r30
2225 rol r31
2226 lpm __tmp_reg__,Z+
2227 lpm r31,Z
2228 mov r30,__tmp_reg__
2229 ijmp"
2230 [(set_attr "length" "6")
2231 (set_attr "cc" "clobber")])
2232
2233 (define_insn "*tablejump"
2234 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2235 UNSPEC_INDEX_JMP))
2236 (use (label_ref (match_operand 1 "" "")))
2237 (clobber (match_dup 0))]
2238 "AVR_MEGA"
2239 "lsl r30
2240 rol r31
2241 lpm
2242 inc r30
2243 push r0
2244 lpm
2245 push r0
2246 ret"
2247 [(set_attr "length" "8")
2248 (set_attr "cc" "clobber")])
2249
2250 (define_expand "casesi"
2251 [(set (match_dup 6)
2252 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2253 (match_operand:HI 1 "register_operand" "")))
2254 (parallel [(set (cc0)
2255 (compare (match_dup 6)
2256 (match_operand:HI 2 "register_operand" "")))
2257 (clobber (match_scratch:QI 9 ""))])
2258
2259 (set (pc)
2260 (if_then_else (gtu (cc0)
2261 (const_int 0))
2262 (label_ref (match_operand 4 "" ""))
2263 (pc)))
2264
2265 (set (match_dup 6)
2266 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2267
2268 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
2269 (use (label_ref (match_dup 3)))
2270 (clobber (match_dup 6))])]
2271 ""
2272 "
2273 {
2274 operands[6] = gen_reg_rtx (HImode);
2275 }")
2276
2277
2278 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2279 ;; This instruction sets Z flag
2280
2281 (define_insn "sez"
2282 [(set (cc0) (const_int 0))]
2283 ""
2284 "sez"
2285 [(set_attr "length" "1")
2286 (set_attr "cc" "compare")])
2287
2288 ;; Clear/set/test a single bit in I/O address space.
2289
2290 (define_insn "*cbi"
2291 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2292 (and:QI (mem:QI (match_dup 0))
2293 (match_operand:QI 1 "single_zero_operand" "n")))]
2294 "(optimize > 0)"
2295 {
2296 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2297 return AS2 (cbi,%0-0x20,%2);
2298 }
2299 [(set_attr "length" "1")
2300 (set_attr "cc" "none")])
2301
2302 (define_insn "*sbi"
2303 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2304 (ior:QI (mem:QI (match_dup 0))
2305 (match_operand:QI 1 "single_one_operand" "n")))]
2306 "(optimize > 0)"
2307 {
2308 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2309 return AS2 (sbi,%0-0x20,%2);
2310 }
2311 [(set_attr "length" "1")
2312 (set_attr "cc" "none")])
2313
2314 ;; Lower half of the I/O space - use sbic/sbis directly.
2315 (define_insn "*sbix_branch"
2316 [(set (pc)
2317 (if_then_else
2318 (match_operator 0 "eqne_operator"
2319 [(zero_extract
2320 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
2321 (const_int 1)
2322 (match_operand 2 "const_int_operand" "n"))
2323 (const_int 0)])
2324 (label_ref (match_operand 3 "" ""))
2325 (pc)))]
2326 "(optimize > 0)"
2327 "* return avr_out_sbxx_branch (insn, operands);"
2328 [(set (attr "length")
2329 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2330 (le (minus (pc) (match_dup 3)) (const_int 2046)))
2331 (const_int 2)
2332 (if_then_else (eq_attr "mcu_mega" "no")
2333 (const_int 2)
2334 (const_int 4))))
2335 (set_attr "cc" "clobber")])
2336
2337 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
2338 (define_insn "*sbix_branch_bit7"
2339 [(set (pc)
2340 (if_then_else
2341 (match_operator 0 "gelt_operator"
2342 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
2343 (const_int 0)])
2344 (label_ref (match_operand 2 "" ""))
2345 (pc)))]
2346 "(optimize > 0)"
2347 {
2348 operands[3] = operands[2];
2349 operands[2] = GEN_INT (7);
2350 return avr_out_sbxx_branch (insn, operands);
2351 }
2352 [(set (attr "length")
2353 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2354 (le (minus (pc) (match_dup 2)) (const_int 2046)))
2355 (const_int 2)
2356 (if_then_else (eq_attr "mcu_mega" "no")
2357 (const_int 2)
2358 (const_int 4))))
2359 (set_attr "cc" "clobber")])
2360
2361 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
2362 (define_insn "*sbix_branch_tmp"
2363 [(set (pc)
2364 (if_then_else
2365 (match_operator 0 "eqne_operator"
2366 [(zero_extract
2367 (mem:QI (match_operand 1 "higth_io_address_operand" "n"))
2368 (const_int 1)
2369 (match_operand 2 "const_int_operand" "n"))
2370 (const_int 0)])
2371 (label_ref (match_operand 3 "" ""))
2372 (pc)))]
2373 "(optimize > 0)"
2374 "* return avr_out_sbxx_branch (insn, operands);"
2375 [(set (attr "length")
2376 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2377 (le (minus (pc) (match_dup 3)) (const_int 2045)))
2378 (const_int 3)
2379 (if_then_else (eq_attr "mcu_mega" "no")
2380 (const_int 3)
2381 (const_int 5))))
2382 (set_attr "cc" "clobber")])
2383
2384 (define_insn "*sbix_branch_tmp_bit7"
2385 [(set (pc)
2386 (if_then_else
2387 (match_operator 0 "gelt_operator"
2388 [(mem:QI (match_operand 1 "higth_io_address_operand" "n"))
2389 (const_int 0)])
2390 (label_ref (match_operand 2 "" ""))
2391 (pc)))]
2392 "(optimize > 0)"
2393 {
2394 operands[3] = operands[2];
2395 operands[2] = GEN_INT (7);
2396 return avr_out_sbxx_branch (insn, operands);
2397 }
2398 [(set (attr "length")
2399 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2400 (le (minus (pc) (match_dup 2)) (const_int 2045)))
2401 (const_int 3)
2402 (if_then_else (eq_attr "mcu_mega" "no")
2403 (const_int 3)
2404 (const_int 5))))
2405 (set_attr "cc" "clobber")])
2406
2407 ;; ************************* Peepholes ********************************
2408
2409 (define_peephole
2410 [(set (match_operand:SI 0 "d_register_operand" "")
2411 (plus:SI (match_dup 0)
2412 (const_int -1)))
2413 (parallel
2414 [(set (cc0)
2415 (compare (match_dup 0)
2416 (const_int -1)))
2417 (clobber (match_operand:QI 1 "d_register_operand" ""))])
2418 (set (pc)
2419 (if_then_else (ne (cc0) (const_int 0))
2420 (label_ref (match_operand 2 "" ""))
2421 (pc)))]
2422 ""
2423 "*
2424 {
2425 CC_STATUS_INIT;
2426 if (test_hard_reg_class (ADDW_REGS, operands[0]))
2427 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
2428 AS2 (sbc,%C0,__zero_reg__) CR_TAB
2429 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2430 else
2431 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2432 AS2 (sbc,%B0,__zero_reg__) CR_TAB
2433 AS2 (sbc,%C0,__zero_reg__) CR_TAB
2434 AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2435 switch (avr_jump_mode (operands[2],insn))
2436 {
2437 case 1:
2438 return AS1 (brcc,%2);
2439 case 2:
2440 return (AS1 (brcs,.+2) CR_TAB
2441 AS1 (rjmp,%2));
2442 }
2443 return (AS1 (brcs,.+4) CR_TAB
2444 AS1 (jmp,%2));
2445 }")
2446
2447 (define_peephole
2448 [(set (match_operand:HI 0 "d_register_operand" "")
2449 (plus:HI (match_dup 0)
2450 (const_int -1)))
2451 (parallel
2452 [(set (cc0)
2453 (compare (match_dup 0)
2454 (const_int 65535)))
2455 (clobber (match_operand:QI 1 "d_register_operand" ""))])
2456 (set (pc)
2457 (if_then_else (ne (cc0) (const_int 0))
2458 (label_ref (match_operand 2 "" ""))
2459 (pc)))]
2460 ""
2461 "*
2462 {
2463 CC_STATUS_INIT;
2464 if (test_hard_reg_class (ADDW_REGS, operands[0]))
2465 output_asm_insn (AS2 (sbiw,%0,1), operands);
2466 else
2467 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2468 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
2469 switch (avr_jump_mode (operands[2],insn))
2470 {
2471 case 1:
2472 return AS1 (brcc,%2);
2473 case 2:
2474 return (AS1 (brcs,.+2) CR_TAB
2475 AS1 (rjmp,%2));
2476 }
2477 return (AS1 (brcs,.+4) CR_TAB
2478 AS1 (jmp,%2));
2479 }")
2480
2481 (define_peephole
2482 [(set (match_operand:QI 0 "d_register_operand" "")
2483 (plus:QI (match_dup 0)
2484 (const_int -1)))
2485 (set (cc0)
2486 (compare (match_dup 0)
2487 (const_int -1)))
2488 (set (pc)
2489 (if_then_else (ne (cc0) (const_int 0))
2490 (label_ref (match_operand 1 "" ""))
2491 (pc)))]
2492 ""
2493 "*
2494 {
2495 CC_STATUS_INIT;
2496 cc_status.value1 = operands[0];
2497 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2498 output_asm_insn (AS2 (subi,%A0,1), operands);
2499 switch (avr_jump_mode (operands[1],insn))
2500 {
2501 case 1:
2502 return AS1 (brcc,%1);
2503 case 2:
2504 return (AS1 (brcs,.+2) CR_TAB
2505 AS1 (rjmp,%1));
2506 }
2507 return (AS1 (brcs,.+4) CR_TAB
2508 AS1 (jmp,%1));
2509 }")
2510
2511 (define_peephole
2512 [(set (cc0) (match_operand:QI 0 "register_operand" ""))
2513 (set (pc)
2514 (if_then_else (eq (cc0) (const_int 0))
2515 (label_ref (match_operand 1 "" ""))
2516 (pc)))]
2517 "jump_over_one_insn_p (insn, operands[1])"
2518 "cpse %0,__zero_reg__")
2519
2520 (define_peephole
2521 [(set (cc0)
2522 (compare (match_operand:QI 0 "register_operand" "")
2523 (match_operand:QI 1 "register_operand" "")))
2524 (set (pc)
2525 (if_then_else (eq (cc0) (const_int 0))
2526 (label_ref (match_operand 2 "" ""))
2527 (pc)))]
2528 "jump_over_one_insn_p (insn, operands[2])"
2529 "cpse %0,%1")