73f273f69471e0bccf289ef16b2b7464b8bbdd35
[gcc.git] / gcc / config / avr / avr.md
1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
4 ;; 2009, 2010, 2011 Free Software Foundation, Inc.
5 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;; Special characters after '%':
24 ;; A No effect (add 0).
25 ;; B Add 1 to REG number, MEM address or CONST_INT.
26 ;; C Add 2.
27 ;; D Add 3.
28 ;; j Branch condition.
29 ;; k Reverse branch condition.
30 ;;..m..Constant Direct Data memory address.
31 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
32 ;; RAM address. The resulting addres is suitable to be used in IN/OUT.
33 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
34 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
35 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
36 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
37 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
38 ;; just cashes the operand for the next %T. The second %T gets
39 ;; a CONST_INT that represents a bit position.
40 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
41 ;; "%T0%T1" it will print "r19,5".
42 ;; Notice that you must not write a comma between %T0 and %T1.
43 ;; T/t Similar to above, but don't print the comma and the bit number.
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
45 ;; "%T0%t1" it will print "r19".
46 ;;..x..Constant Direct Program memory address.
47 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
48 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
49
50
51 (define_constants
52 [(REG_X 26)
53 (REG_Y 28)
54 (REG_Z 30)
55 (REG_W 24)
56 (REG_SP 32)
57 (LPM_REGNO 0) ; implicit target register of LPM
58 (TMP_REGNO 0) ; temporary register r0
59 (ZERO_REGNO 1) ; zero register r1
60 ])
61
62 (define_c_enum "unspec"
63 [UNSPEC_STRLEN
64 UNSPEC_MOVMEM
65 UNSPEC_INDEX_JMP
66 UNSPEC_FMUL
67 UNSPEC_FMULS
68 UNSPEC_FMULSU
69 UNSPEC_COPYSIGN
70 UNSPEC_IDENTITY
71 UNSPEC_INSERT_BITS
72 ])
73
74 (define_c_enum "unspecv"
75 [UNSPECV_PROLOGUE_SAVES
76 UNSPECV_EPILOGUE_RESTORES
77 UNSPECV_WRITE_SP
78 UNSPECV_GOTO_RECEIVER
79 UNSPECV_ENABLE_IRQS
80 UNSPECV_NOP
81 UNSPECV_SLEEP
82 UNSPECV_WDR
83 UNSPECV_DELAY_CYCLES
84 ])
85
86
87 (include "predicates.md")
88 (include "constraints.md")
89
90 ;; Condition code settings.
91 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
92 out_plus, out_plus_noclobber,ldi"
93 (const_string "none"))
94
95 (define_attr "type" "branch,branch1,arith,xcall"
96 (const_string "arith"))
97
98 ;; The size of instructions in bytes.
99 ;; XXX may depend from "cc"
100
101 (define_attr "length" ""
102 (cond [(eq_attr "type" "branch")
103 (if_then_else (and (ge (minus (pc) (match_dup 0))
104 (const_int -63))
105 (le (minus (pc) (match_dup 0))
106 (const_int 62)))
107 (const_int 1)
108 (if_then_else (and (ge (minus (pc) (match_dup 0))
109 (const_int -2045))
110 (le (minus (pc) (match_dup 0))
111 (const_int 2045)))
112 (const_int 2)
113 (const_int 3)))
114 (eq_attr "type" "branch1")
115 (if_then_else (and (ge (minus (pc) (match_dup 0))
116 (const_int -62))
117 (le (minus (pc) (match_dup 0))
118 (const_int 61)))
119 (const_int 2)
120 (if_then_else (and (ge (minus (pc) (match_dup 0))
121 (const_int -2044))
122 (le (minus (pc) (match_dup 0))
123 (const_int 2043)))
124 (const_int 3)
125 (const_int 4)))
126 (eq_attr "type" "xcall")
127 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
128 (const_int 1)
129 (const_int 2))]
130 (const_int 2)))
131
132 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
133 ;; Following insn attribute tells if and how the adjustment has to be
134 ;; done:
135 ;; no No adjustment needed; attribute "length" is fine.
136 ;; Otherwise do special processing depending on the attribute.
137
138 (define_attr "adjust_len"
139 "out_bitop, out_plus, out_plus_noclobber, plus64, addto_sp,
140 tsthi, tstpsi, tstsi, compare, compare64, call,
141 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
142 xload, movmem,
143 ashlqi, ashrqi, lshrqi,
144 ashlhi, ashrhi, lshrhi,
145 ashlsi, ashrsi, lshrsi,
146 ashlpsi, ashrpsi, lshrpsi,
147 insert_bits,
148 no"
149 (const_string "no"))
150
151 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
152
153 ;; mov : ISA has no MOVW movw : ISA has MOVW
154 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
155 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
156 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
157 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
158 ;; no_xmega: non-XMEGA core xmega : XMEGA core
159
160 (define_attr "isa"
161 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
162 standard"
163 (const_string "standard"))
164
165 (define_attr "enabled" ""
166 (cond [(eq_attr "isa" "standard")
167 (const_int 1)
168
169 (and (eq_attr "isa" "mov")
170 (match_test "!AVR_HAVE_MOVW"))
171 (const_int 1)
172
173 (and (eq_attr "isa" "movw")
174 (match_test "AVR_HAVE_MOVW"))
175 (const_int 1)
176
177 (and (eq_attr "isa" "rjmp")
178 (match_test "!AVR_HAVE_JMP_CALL"))
179 (const_int 1)
180
181 (and (eq_attr "isa" "jmp")
182 (match_test "AVR_HAVE_JMP_CALL"))
183 (const_int 1)
184
185 (and (eq_attr "isa" "ijmp")
186 (match_test "!AVR_HAVE_EIJMP_EICALL"))
187 (const_int 1)
188
189 (and (eq_attr "isa" "eijmp")
190 (match_test "AVR_HAVE_EIJMP_EICALL"))
191 (const_int 1)
192
193 (and (eq_attr "isa" "lpm")
194 (match_test "!AVR_HAVE_LPMX"))
195 (const_int 1)
196
197 (and (eq_attr "isa" "lpmx")
198 (match_test "AVR_HAVE_LPMX"))
199 (const_int 1)
200
201 (and (eq_attr "isa" "elpm")
202 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
203 (const_int 1)
204
205 (and (eq_attr "isa" "elpmx")
206 (match_test "AVR_HAVE_ELPMX"))
207 (const_int 1)
208
209 (and (eq_attr "isa" "xmega")
210 (match_test "AVR_XMEGA"))
211 (const_int 1)
212
213 (and (eq_attr "isa" "no_xmega")
214 (match_test "!AVR_XMEGA"))
215 (const_int 1)
216 ] (const_int 0)))
217
218
219 ;; Define mode iterators
220 (define_mode_iterator QIHI [(QI "") (HI "")])
221 (define_mode_iterator QIHI2 [(QI "") (HI "")])
222 (define_mode_iterator QISI [(QI "") (HI "") (PSI "") (SI "")])
223 (define_mode_iterator QIDI [(QI "") (HI "") (PSI "") (SI "") (DI "")])
224 (define_mode_iterator HISI [(HI "") (PSI "") (SI "")])
225
226 ;; All supported move-modes
227 (define_mode_iterator MOVMODE [(QI "") (HI "") (SI "") (SF "") (PSI "")])
228
229 ;; Define code iterators
230 ;; Define two incarnations so that we can build the cross product.
231 (define_code_iterator any_extend [sign_extend zero_extend])
232 (define_code_iterator any_extend2 [sign_extend zero_extend])
233
234 (define_code_iterator xior [xor ior])
235 (define_code_iterator eqne [eq ne])
236
237 ;; Define code attributes
238 (define_code_attr extend_su
239 [(sign_extend "s")
240 (zero_extend "u")])
241
242 (define_code_attr extend_u
243 [(sign_extend "")
244 (zero_extend "u")])
245
246 (define_code_attr extend_s
247 [(sign_extend "s")
248 (zero_extend "")])
249
250 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
251 (define_code_attr mul_r_d
252 [(zero_extend "r")
253 (sign_extend "d")])
254
255 ;; Map RTX code to its standard insn name
256 (define_code_attr code_stdname
257 [(ashift "ashl")
258 (ashiftrt "ashr")
259 (lshiftrt "lshr")
260 (ior "ior")
261 (xor "xor")
262 (rotate "rotl")])
263
264 ;;========================================================================
265 ;; The following is used by nonlocal_goto and setjmp.
266 ;; The receiver pattern will create no instructions since internally
267 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
268 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
269 ;; The 'null' receiver also avoids problems with optimisation
270 ;; not recognising incoming jmp and removing code that resets frame_pointer.
271 ;; The code derived from builtins.c.
272
273 (define_expand "nonlocal_goto_receiver"
274 [(set (reg:HI REG_Y)
275 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
276 ""
277 {
278 emit_move_insn (virtual_stack_vars_rtx,
279 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
280 gen_int_mode (STARTING_FRAME_OFFSET,
281 Pmode)));
282 /* This might change the hard frame pointer in ways that aren't
283 apparent to early optimization passes, so force a clobber. */
284 emit_clobber (hard_frame_pointer_rtx);
285 DONE;
286 })
287
288
289 ;; Defining nonlocal_goto_receiver means we must also define this.
290 ;; even though its function is identical to that in builtins.c
291
292 (define_expand "nonlocal_goto"
293 [(use (match_operand 0 "general_operand"))
294 (use (match_operand 1 "general_operand"))
295 (use (match_operand 2 "general_operand"))
296 (use (match_operand 3 "general_operand"))]
297 ""
298 {
299 rtx r_label = copy_to_reg (operands[1]);
300 rtx r_fp = operands[3];
301 rtx r_sp = operands[2];
302
303 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
304
305 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
306
307 emit_move_insn (hard_frame_pointer_rtx, r_fp);
308 emit_stack_restore (SAVE_NONLOCAL, r_sp);
309
310 emit_use (hard_frame_pointer_rtx);
311 emit_use (stack_pointer_rtx);
312
313 emit_indirect_jump (r_label);
314
315 DONE;
316 })
317
318 (define_insn "pushqi1"
319 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
320 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
321 ""
322 "@
323 push %0
324 push __zero_reg__"
325 [(set_attr "length" "1,1")])
326
327 ;; All modes for a multi-byte push. We must include complex modes here too,
328 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
329 (define_mode_iterator MPUSH
330 [(CQI "")
331 (HI "") (CHI "")
332 (PSI "")
333 (SI "") (CSI "")
334 (DI "") (CDI "")
335 (SF "") (SC "")])
336
337 (define_expand "push<mode>1"
338 [(match_operand:MPUSH 0 "" "")]
339 ""
340 {
341 int i;
342 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
343 {
344 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
345 if (part != const0_rtx)
346 part = force_reg (QImode, part);
347 emit_insn (gen_pushqi1 (part));
348 }
349 DONE;
350 })
351
352 ;; Notice a special-case when adding N to SP where N results in a
353 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
354 (define_split
355 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
356 "reload_completed
357 && frame_pointer_needed
358 && !cfun->calls_alloca
359 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
360 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
361 "")
362
363 ;;========================================================================
364 ;; Move stuff around
365
366 (define_expand "load<mode>_libgcc"
367 [(set (match_dup 3)
368 (match_dup 2))
369 (set (reg:MOVMODE 22)
370 (match_operand:MOVMODE 1 "memory_operand" ""))
371 (set (match_operand:MOVMODE 0 "register_operand" "")
372 (reg:MOVMODE 22))]
373 "avr_load_libgcc_p (operands[1])"
374 {
375 operands[3] = gen_rtx_REG (HImode, REG_Z);
376 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
377 operands[1] = replace_equiv_address (operands[1], operands[3]);
378 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
379 })
380
381 (define_insn "load_<mode>_libgcc"
382 [(set (reg:MOVMODE 22)
383 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
384 "avr_load_libgcc_p (operands[0])
385 && REG_P (XEXP (operands[0], 0))
386 && REG_Z == REGNO (XEXP (operands[0], 0))"
387 {
388 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
389 return "%~call __load_%0";
390 }
391 [(set_attr "length" "1,2")
392 (set_attr "isa" "rjmp,jmp")
393 (set_attr "cc" "clobber")])
394
395
396 (define_insn_and_split "xload8_A"
397 [(set (match_operand:QI 0 "register_operand" "=r")
398 (match_operand:QI 1 "memory_operand" "m"))
399 (clobber (reg:HI REG_Z))]
400 "can_create_pseudo_p()
401 && !avr_xload_libgcc_p (QImode)
402 && avr_mem_memx_p (operands[1])
403 && REG_P (XEXP (operands[1], 0))"
404 { gcc_unreachable(); }
405 "&& 1"
406 [(clobber (const_int 0))]
407 {
408 rtx insn, addr = XEXP (operands[1], 0);
409 rtx hi8 = gen_reg_rtx (QImode);
410 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
411
412 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
413 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
414
415 insn = emit_insn (gen_xload_8 (operands[0], hi8));
416 set_mem_addr_space (SET_SRC (single_set (insn)),
417 MEM_ADDR_SPACE (operands[1]));
418 DONE;
419 })
420
421 (define_insn_and_split "xload<mode>_A"
422 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
423 (match_operand:MOVMODE 1 "memory_operand" "m"))
424 (clobber (reg:QI 21))
425 (clobber (reg:HI REG_Z))]
426 "can_create_pseudo_p()
427 && avr_mem_memx_p (operands[1])
428 && REG_P (XEXP (operands[1], 0))"
429 { gcc_unreachable(); }
430 "&& 1"
431 [(clobber (const_int 0))]
432 {
433 rtx addr = XEXP (operands[1], 0);
434 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
435 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
436 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
437 rtx insn;
438
439 /* Split the address to R21:Z */
440 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
441 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
442
443 /* Load with code from libgcc */
444 insn = emit_insn (gen_xload_<mode>_libgcc ());
445 set_mem_addr_space (SET_SRC (single_set (insn)), as);
446
447 /* Move to destination */
448 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
449
450 DONE;
451 })
452
453 ;; Move value from address space memx to a register
454 ;; These insns must be prior to respective generic move insn.
455
456 (define_insn "xload_8"
457 [(set (match_operand:QI 0 "register_operand" "=&r,r")
458 (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
459 (reg:HI REG_Z))))]
460 "!avr_xload_libgcc_p (QImode)"
461 {
462 return avr_out_xload (insn, operands, NULL);
463 }
464 [(set_attr "length" "3,4")
465 (set_attr "adjust_len" "*,xload")
466 (set_attr "isa" "lpmx,lpm")
467 (set_attr "cc" "none")])
468
469 ;; R21:Z : 24-bit source address
470 ;; R22 : 1-4 byte output
471
472 ;; "xload_qi_libgcc"
473 ;; "xload_hi_libgcc"
474 ;; "xload_psi_libgcc"
475 ;; "xload_si_libgcc"
476 ;; "xload_sf_libgcc"
477 (define_insn "xload_<mode>_libgcc"
478 [(set (reg:MOVMODE 22)
479 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
480 (reg:HI REG_Z))))
481 (clobber (reg:QI 21))
482 (clobber (reg:HI REG_Z))]
483 "avr_xload_libgcc_p (<MODE>mode)"
484 {
485 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
486
487 output_asm_insn ("%~call __xload_%0", &x_bytes);
488 return "";
489 }
490 [(set_attr "type" "xcall")
491 (set_attr "cc" "clobber")])
492
493
494 ;; General move expanders
495
496 ;; "movqi"
497 ;; "movhi"
498 ;; "movsi"
499 ;; "movsf"
500 ;; "movpsi"
501 (define_expand "mov<mode>"
502 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
503 (match_operand:MOVMODE 1 "general_operand" ""))]
504 ""
505 {
506 rtx dest = operands[0];
507 rtx src = operands[1];
508
509 if (avr_mem_flash_p (dest))
510 DONE;
511
512 /* One of the operands has to be in a register. */
513 if (!register_operand (dest, <MODE>mode)
514 && !(register_operand (src, <MODE>mode)
515 || src == CONST0_RTX (<MODE>mode)))
516 {
517 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
518 }
519
520 if (avr_mem_memx_p (src))
521 {
522 rtx addr = XEXP (src, 0);
523
524 if (!REG_P (addr))
525 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
526
527 if (!avr_xload_libgcc_p (<MODE>mode))
528 emit_insn (gen_xload8_A (dest, src));
529 else
530 emit_insn (gen_xload<mode>_A (dest, src));
531
532 DONE;
533 }
534
535 if (avr_load_libgcc_p (src))
536 {
537 /* For the small devices, do loads per libgcc call. */
538 emit_insn (gen_load<mode>_libgcc (dest, src));
539 DONE;
540 }
541 })
542
543 ;;========================================================================
544 ;; move byte
545 ;; The last alternative (any immediate constant to any register) is
546 ;; very expensive. It should be optimized by peephole2 if a scratch
547 ;; register is available, but then that register could just as well be
548 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
549 ;; are call-saved registers, and most of LD_REGS are call-used registers,
550 ;; so this may still be a win for registers live across function calls.
551
552 (define_insn "movqi_insn"
553 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
554 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
555 "register_operand (operands[0], QImode)
556 || register_operand (operands[1], QImode)
557 || const0_rtx == operands[1]"
558 {
559 return output_movqi (insn, operands, NULL);
560 }
561 [(set_attr "length" "1,1,5,5,1,1,4")
562 (set_attr "adjust_len" "mov8")
563 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
564
565 ;; This is used in peephole2 to optimize loading immediate constants
566 ;; if a scratch register from LD_REGS happens to be available.
567
568 (define_insn "*reload_inqi"
569 [(set (match_operand:QI 0 "register_operand" "=l")
570 (match_operand:QI 1 "immediate_operand" "i"))
571 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
572 "reload_completed"
573 "ldi %2,lo8(%1)
574 mov %0,%2"
575 [(set_attr "length" "2")
576 (set_attr "cc" "none")])
577
578 (define_peephole2
579 [(match_scratch:QI 2 "d")
580 (set (match_operand:QI 0 "l_register_operand" "")
581 (match_operand:QI 1 "immediate_operand" ""))]
582 "(operands[1] != const0_rtx
583 && operands[1] != const1_rtx
584 && operands[1] != constm1_rtx)"
585 [(parallel [(set (match_dup 0) (match_dup 1))
586 (clobber (match_dup 2))])]
587 "")
588
589 ;;============================================================================
590 ;; move word (16 bit)
591
592 ;; Move register $1 to the Stack Pointer register SP.
593 ;; This insn is emit during function prologue/epilogue generation.
594 ;; $2 = 0: We know that IRQs are off
595 ;; $2 = 1: We know that IRQs are on
596 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
597 ;; $2 = -1: We don't know anything about IRQ on/off
598 ;; Always write SP via unspec, see PR50063
599
600 (define_insn "movhi_sp_r"
601 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
602 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
603 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
604 UNSPECV_WRITE_SP))]
605 ""
606 "@
607 out %B0,%B1\;out %A0,%A1
608 cli\;out %B0,%B1\;sei\;out %A0,%A1
609 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
610 out %A0,%A1
611 out %A0,%A1\;out %B0,%B1"
612 [(set_attr "length" "2,4,5,1,2")
613 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
614 (set_attr "cc" "none")])
615
616 (define_peephole2
617 [(match_scratch:QI 2 "d")
618 (set (match_operand:HI 0 "l_register_operand" "")
619 (match_operand:HI 1 "immediate_operand" ""))]
620 "(operands[1] != const0_rtx
621 && operands[1] != constm1_rtx)"
622 [(parallel [(set (match_dup 0) (match_dup 1))
623 (clobber (match_dup 2))])]
624 "")
625
626 ;; '*' because it is not used in rtl generation, only in above peephole
627 (define_insn "*reload_inhi"
628 [(set (match_operand:HI 0 "register_operand" "=r")
629 (match_operand:HI 1 "immediate_operand" "i"))
630 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
631 "reload_completed"
632 {
633 return output_reload_inhi (operands, operands[2], NULL);
634 }
635 [(set_attr "length" "4")
636 (set_attr "adjust_len" "reload_in16")
637 (set_attr "cc" "none")])
638
639 (define_insn "*movhi"
640 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
641 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
642 "register_operand (operands[0], HImode)
643 || register_operand (operands[1], HImode)
644 || const0_rtx == operands[1]"
645 {
646 return output_movhi (insn, operands, NULL);
647 }
648 [(set_attr "length" "2,2,6,7,2,6,5,2")
649 (set_attr "adjust_len" "mov16")
650 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
651
652 (define_peephole2 ; movw
653 [(set (match_operand:QI 0 "even_register_operand" "")
654 (match_operand:QI 1 "even_register_operand" ""))
655 (set (match_operand:QI 2 "odd_register_operand" "")
656 (match_operand:QI 3 "odd_register_operand" ""))]
657 "(AVR_HAVE_MOVW
658 && REGNO (operands[0]) == REGNO (operands[2]) - 1
659 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
660 [(set (match_dup 4) (match_dup 5))]
661 {
662 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
663 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
664 })
665
666 (define_peephole2 ; movw_r
667 [(set (match_operand:QI 0 "odd_register_operand" "")
668 (match_operand:QI 1 "odd_register_operand" ""))
669 (set (match_operand:QI 2 "even_register_operand" "")
670 (match_operand:QI 3 "even_register_operand" ""))]
671 "(AVR_HAVE_MOVW
672 && REGNO (operands[2]) == REGNO (operands[0]) - 1
673 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
674 [(set (match_dup 4) (match_dup 5))]
675 {
676 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
677 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
678 })
679
680 ;; For LPM loads from AS1 we split
681 ;; R = *Z
682 ;; to
683 ;; R = *Z++
684 ;; Z = Z - sizeof (R)
685 ;;
686 ;; so that the second instruction can be optimized out.
687
688 (define_split ; "split-lpmx"
689 [(set (match_operand:HISI 0 "register_operand" "")
690 (match_operand:HISI 1 "memory_operand" ""))]
691 "reload_completed
692 && AVR_HAVE_LPMX"
693 [(set (match_dup 0)
694 (match_dup 2))
695 (set (match_dup 3)
696 (plus:HI (match_dup 3)
697 (match_dup 4)))]
698 {
699 rtx addr = XEXP (operands[1], 0);
700
701 if (!avr_mem_flash_p (operands[1])
702 || !REG_P (addr)
703 || reg_overlap_mentioned_p (addr, operands[0]))
704 {
705 FAIL;
706 }
707
708 operands[2] = replace_equiv_address (operands[1],
709 gen_rtx_POST_INC (Pmode, addr));
710 operands[3] = addr;
711 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
712 })
713
714 ;;==========================================================================
715 ;; xpointer move (24 bit)
716
717 (define_peephole2 ; *reload_inpsi
718 [(match_scratch:QI 2 "d")
719 (set (match_operand:PSI 0 "l_register_operand" "")
720 (match_operand:PSI 1 "immediate_operand" ""))
721 (match_dup 2)]
722 "operands[1] != const0_rtx
723 && operands[1] != constm1_rtx"
724 [(parallel [(set (match_dup 0)
725 (match_dup 1))
726 (clobber (match_dup 2))])]
727 "")
728
729 ;; '*' because it is not used in rtl generation.
730 (define_insn "*reload_inpsi"
731 [(set (match_operand:PSI 0 "register_operand" "=r")
732 (match_operand:PSI 1 "immediate_operand" "i"))
733 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
734 "reload_completed"
735 {
736 return avr_out_reload_inpsi (operands, operands[2], NULL);
737 }
738 [(set_attr "length" "6")
739 (set_attr "adjust_len" "reload_in24")
740 (set_attr "cc" "clobber")])
741
742 (define_insn "*movpsi"
743 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
744 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
745 "register_operand (operands[0], PSImode)
746 || register_operand (operands[1], PSImode)
747 || const0_rtx == operands[1]"
748 {
749 return avr_out_movpsi (insn, operands, NULL);
750 }
751 [(set_attr "length" "3,3,8,9,4,10")
752 (set_attr "adjust_len" "mov24")
753 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
754
755 ;;==========================================================================
756 ;; move double word (32 bit)
757
758 (define_peephole2 ; *reload_insi
759 [(match_scratch:QI 2 "d")
760 (set (match_operand:SI 0 "l_register_operand" "")
761 (match_operand:SI 1 "const_int_operand" ""))
762 (match_dup 2)]
763 "(operands[1] != const0_rtx
764 && operands[1] != constm1_rtx)"
765 [(parallel [(set (match_dup 0) (match_dup 1))
766 (clobber (match_dup 2))])]
767 "")
768
769 ;; '*' because it is not used in rtl generation.
770 (define_insn "*reload_insi"
771 [(set (match_operand:SI 0 "register_operand" "=r")
772 (match_operand:SI 1 "const_int_operand" "n"))
773 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
774 "reload_completed"
775 {
776 return output_reload_insisf (operands, operands[2], NULL);
777 }
778 [(set_attr "length" "8")
779 (set_attr "adjust_len" "reload_in32")
780 (set_attr "cc" "clobber")])
781
782
783 (define_insn "*movsi"
784 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
785 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
786 "register_operand (operands[0], SImode)
787 || register_operand (operands[1], SImode)
788 || const0_rtx == operands[1]"
789 {
790 return output_movsisf (insn, operands, NULL);
791 }
792 [(set_attr "length" "4,4,8,9,4,10")
793 (set_attr "adjust_len" "mov32")
794 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
795
796 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
797 ;; move floating point numbers (32 bit)
798
799 (define_insn "*movsf"
800 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
801 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
802 "register_operand (operands[0], SFmode)
803 || register_operand (operands[1], SFmode)
804 || operands[1] == CONST0_RTX (SFmode)"
805 {
806 return output_movsisf (insn, operands, NULL);
807 }
808 [(set_attr "length" "4,4,8,9,4,10")
809 (set_attr "adjust_len" "mov32")
810 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
811
812 (define_peephole2 ; *reload_insf
813 [(match_scratch:QI 2 "d")
814 (set (match_operand:SF 0 "l_register_operand" "")
815 (match_operand:SF 1 "const_double_operand" ""))
816 (match_dup 2)]
817 "operands[1] != CONST0_RTX (SFmode)"
818 [(parallel [(set (match_dup 0)
819 (match_dup 1))
820 (clobber (match_dup 2))])]
821 "")
822
823 ;; '*' because it is not used in rtl generation.
824 (define_insn "*reload_insf"
825 [(set (match_operand:SF 0 "register_operand" "=r")
826 (match_operand:SF 1 "const_double_operand" "F"))
827 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
828 "reload_completed"
829 {
830 return output_reload_insisf (operands, operands[2], NULL);
831 }
832 [(set_attr "length" "8")
833 (set_attr "adjust_len" "reload_in32")
834 (set_attr "cc" "clobber")])
835
836 ;;=========================================================================
837 ;; move string (like memcpy)
838
839 (define_expand "movmemhi"
840 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
841 (match_operand:BLK 1 "memory_operand" ""))
842 (use (match_operand:HI 2 "const_int_operand" ""))
843 (use (match_operand:HI 3 "const_int_operand" ""))])]
844 ""
845 {
846 if (avr_emit_movmemhi (operands))
847 DONE;
848
849 FAIL;
850 })
851
852 (define_mode_attr MOVMEM_r_d [(QI "r")
853 (HI "wd")])
854
855 ;; $0 : Address Space
856 ;; $1, $2 : Loop register
857 ;; R30 : source address
858 ;; R26 : destination address
859
860 ;; "movmem_qi"
861 ;; "movmem_hi"
862 (define_insn "movmem_<mode>"
863 [(set (mem:BLK (reg:HI REG_X))
864 (mem:BLK (reg:HI REG_Z)))
865 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
866 UNSPEC_MOVMEM)
867 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
868 (clobber (reg:HI REG_X))
869 (clobber (reg:HI REG_Z))
870 (clobber (reg:QI LPM_REGNO))
871 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
872 ""
873 {
874 return avr_out_movmem (insn, operands, NULL);
875 }
876 [(set_attr "adjust_len" "movmem")
877 (set_attr "cc" "clobber")])
878
879
880 ;; $0 : Address Space
881 ;; $1 : RAMPZ RAM address
882 ;; R24 : #bytes and loop register
883 ;; R23:Z : 24-bit source address
884 ;; R26 : 16-bit destination address
885
886 ;; "movmemx_qi"
887 ;; "movmemx_hi"
888 (define_insn "movmemx_<mode>"
889 [(set (mem:BLK (reg:HI REG_X))
890 (mem:BLK (lo_sum:PSI (reg:QI 23)
891 (reg:HI REG_Z))))
892 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
893 UNSPEC_MOVMEM)
894 (use (reg:QIHI 24))
895 (clobber (reg:HI REG_X))
896 (clobber (reg:HI REG_Z))
897 (clobber (reg:QI LPM_REGNO))
898 (clobber (reg:HI 24))
899 (clobber (reg:QI 23))
900 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
901 ""
902 "%~call __movmemx_<mode>"
903 [(set_attr "type" "xcall")
904 (set_attr "cc" "clobber")])
905
906
907 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
908 ;; memset (%0, %2, %1)
909
910 (define_expand "setmemhi"
911 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
912 (match_operand 2 "const_int_operand" ""))
913 (use (match_operand:HI 1 "const_int_operand" ""))
914 (use (match_operand:HI 3 "const_int_operand" ""))
915 (clobber (match_scratch:HI 4 ""))
916 (clobber (match_dup 5))])]
917 ""
918 {
919 rtx addr0;
920 enum machine_mode mode;
921
922 /* If value to set is not zero, use the library routine. */
923 if (operands[2] != const0_rtx)
924 FAIL;
925
926 if (!CONST_INT_P (operands[1]))
927 FAIL;
928
929 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
930 operands[5] = gen_rtx_SCRATCH (mode);
931 operands[1] = copy_to_mode_reg (mode,
932 gen_int_mode (INTVAL (operands[1]), mode));
933 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
934 operands[0] = gen_rtx_MEM (BLKmode, addr0);
935 })
936
937
938 (define_insn "*clrmemqi"
939 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
940 (const_int 0))
941 (use (match_operand:QI 1 "register_operand" "r"))
942 (use (match_operand:QI 2 "const_int_operand" "n"))
943 (clobber (match_scratch:HI 3 "=0"))
944 (clobber (match_scratch:QI 4 "=&1"))]
945 ""
946 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
947 [(set_attr "length" "3")
948 (set_attr "cc" "clobber")])
949
950
951 (define_insn "*clrmemhi"
952 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
953 (const_int 0))
954 (use (match_operand:HI 1 "register_operand" "!w,d"))
955 (use (match_operand:HI 2 "const_int_operand" "n,n"))
956 (clobber (match_scratch:HI 3 "=0,0"))
957 (clobber (match_scratch:HI 4 "=&1,&1"))]
958 ""
959 "@
960 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
961 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
962 [(set_attr "length" "3,4")
963 (set_attr "cc" "clobber,clobber")])
964
965 (define_expand "strlenhi"
966 [(set (match_dup 4)
967 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
968 (match_operand:QI 2 "const_int_operand" "")
969 (match_operand:HI 3 "immediate_operand" "")]
970 UNSPEC_STRLEN))
971 (set (match_dup 4)
972 (plus:HI (match_dup 4)
973 (const_int -1)))
974 (set (match_operand:HI 0 "register_operand" "")
975 (minus:HI (match_dup 4)
976 (match_dup 5)))]
977 ""
978 {
979 rtx addr;
980 if (operands[2] != const0_rtx)
981 FAIL;
982 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
983 operands[1] = gen_rtx_MEM (BLKmode, addr);
984 operands[5] = addr;
985 operands[4] = gen_reg_rtx (HImode);
986 })
987
988 (define_insn "*strlenhi"
989 [(set (match_operand:HI 0 "register_operand" "=e")
990 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
991 (const_int 0)
992 (match_operand:HI 2 "immediate_operand" "i")]
993 UNSPEC_STRLEN))]
994 ""
995 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
996 [(set_attr "length" "3")
997 (set_attr "cc" "clobber")])
998
999 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1000 ; add bytes
1001
1002 (define_insn "addqi3"
1003 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
1004 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
1005 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
1006 ""
1007 "@
1008 add %0,%2
1009 subi %0,lo8(-(%2))
1010 inc %0
1011 dec %0
1012 inc %0\;inc %0
1013 dec %0\;dec %0"
1014 [(set_attr "length" "1,1,1,1,2,2")
1015 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1016
1017
1018 (define_expand "addhi3"
1019 [(set (match_operand:HI 0 "register_operand" "")
1020 (plus:HI (match_operand:HI 1 "register_operand" "")
1021 (match_operand:HI 2 "nonmemory_operand" "")))]
1022 ""
1023 {
1024 if (CONST_INT_P (operands[2]))
1025 {
1026 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1027
1028 if (can_create_pseudo_p()
1029 && !stack_register_operand (operands[0], HImode)
1030 && !stack_register_operand (operands[1], HImode)
1031 && !d_register_operand (operands[0], HImode)
1032 && !d_register_operand (operands[1], HImode))
1033 {
1034 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1035 DONE;
1036 }
1037 }
1038 })
1039
1040
1041 (define_insn "*addhi3_zero_extend"
1042 [(set (match_operand:HI 0 "register_operand" "=r")
1043 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1044 (match_operand:HI 2 "register_operand" "0")))]
1045 ""
1046 "add %A0,%1\;adc %B0,__zero_reg__"
1047 [(set_attr "length" "2")
1048 (set_attr "cc" "set_n")])
1049
1050 (define_insn "*addhi3_zero_extend1"
1051 [(set (match_operand:HI 0 "register_operand" "=r")
1052 (plus:HI (match_operand:HI 1 "register_operand" "0")
1053 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1054 ""
1055 "add %A0,%2\;adc %B0,__zero_reg__"
1056 [(set_attr "length" "2")
1057 (set_attr "cc" "set_n")])
1058
1059 (define_insn "*addhi3.sign_extend1"
1060 [(set (match_operand:HI 0 "register_operand" "=r")
1061 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1062 (match_operand:HI 2 "register_operand" "0")))]
1063 ""
1064 {
1065 return reg_overlap_mentioned_p (operands[0], operands[1])
1066 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1067 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1068 }
1069 [(set_attr "length" "5")
1070 (set_attr "cc" "clobber")])
1071
1072 (define_insn "*addhi3_sp"
1073 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1074 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1075 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1076 ""
1077 {
1078 return avr_out_addto_sp (operands, NULL);
1079 }
1080 [(set_attr "length" "6")
1081 (set_attr "adjust_len" "addto_sp")])
1082
1083 (define_insn "*addhi3"
1084 [(set (match_operand:HI 0 "register_operand" "=r,d,d")
1085 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1086 (match_operand:HI 2 "nonmemory_operand" "r,s,n")))]
1087 ""
1088 {
1089 static const char * const asm_code[] =
1090 {
1091 "add %A0,%A2\;adc %B0,%B2",
1092 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
1093 ""
1094 };
1095
1096 if (*asm_code[which_alternative])
1097 return asm_code[which_alternative];
1098
1099 return avr_out_plus_noclobber (operands, NULL, NULL);
1100 }
1101 [(set_attr "length" "2,2,2")
1102 (set_attr "adjust_len" "*,*,out_plus_noclobber")
1103 (set_attr "cc" "set_n,set_czn,out_plus_noclobber")])
1104
1105 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1106 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1107 ;; itself because that insn is special to reload.
1108
1109 (define_peephole2 ; addhi3_clobber
1110 [(set (match_operand:HI 0 "d_register_operand" "")
1111 (match_operand:HI 1 "const_int_operand" ""))
1112 (set (match_operand:HI 2 "l_register_operand" "")
1113 (plus:HI (match_dup 2)
1114 (match_dup 0)))]
1115 "peep2_reg_dead_p (2, operands[0])"
1116 [(parallel [(set (match_dup 2)
1117 (plus:HI (match_dup 2)
1118 (match_dup 1)))
1119 (clobber (match_dup 3))])]
1120 {
1121 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
1122 })
1123
1124 ;; Same, but with reload to NO_LD_REGS
1125 ;; Combine *reload_inhi with *addhi3
1126
1127 (define_peephole2 ; addhi3_clobber
1128 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
1129 (match_operand:HI 1 "const_int_operand" ""))
1130 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1131 (set (match_operand:HI 3 "l_register_operand" "")
1132 (plus:HI (match_dup 3)
1133 (match_dup 0)))]
1134 "peep2_reg_dead_p (2, operands[0])"
1135 [(parallel [(set (match_dup 3)
1136 (plus:HI (match_dup 3)
1137 (match_dup 1)))
1138 (clobber (match_dup 2))])])
1139
1140 (define_insn "addhi3_clobber"
1141 [(set (match_operand:HI 0 "register_operand" "=d,l")
1142 (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
1143 (match_operand:HI 2 "const_int_operand" "n,n")))
1144 (clobber (match_scratch:QI 3 "=X,&d"))]
1145 ""
1146 {
1147 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1148
1149 return avr_out_plus (operands, NULL, NULL);
1150 }
1151 [(set_attr "length" "4")
1152 (set_attr "adjust_len" "out_plus")
1153 (set_attr "cc" "out_plus")])
1154
1155
1156 (define_insn "addsi3"
1157 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1158 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1159 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1160 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1161 ""
1162 {
1163 static const char * const asm_code[] =
1164 {
1165 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
1166 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
1167 "",
1168 ""
1169 };
1170
1171 if (*asm_code[which_alternative])
1172 return asm_code[which_alternative];
1173
1174 return avr_out_plus (operands, NULL, NULL);
1175 }
1176 [(set_attr "length" "4,4,4,8")
1177 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1178 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1179
1180 (define_insn "*addpsi3_zero_extend.qi"
1181 [(set (match_operand:PSI 0 "register_operand" "=r")
1182 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1183 (match_operand:PSI 2 "register_operand" "0")))]
1184 ""
1185 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1186 [(set_attr "length" "3")
1187 (set_attr "cc" "set_n")])
1188
1189 (define_insn "*addpsi3_zero_extend.hi"
1190 [(set (match_operand:PSI 0 "register_operand" "=r")
1191 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1192 (match_operand:PSI 2 "register_operand" "0")))]
1193 ""
1194 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1195 [(set_attr "length" "3")
1196 (set_attr "cc" "set_n")])
1197
1198 (define_insn "*addpsi3_sign_extend.hi"
1199 [(set (match_operand:PSI 0 "register_operand" "=r")
1200 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1201 (match_operand:PSI 2 "register_operand" "0")))]
1202 ""
1203 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1204 [(set_attr "length" "5")
1205 (set_attr "cc" "set_n")])
1206
1207 (define_insn "*addsi3_zero_extend"
1208 [(set (match_operand:SI 0 "register_operand" "=r")
1209 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1210 (match_operand:SI 2 "register_operand" "0")))]
1211 ""
1212 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1213 [(set_attr "length" "4")
1214 (set_attr "cc" "set_n")])
1215
1216 (define_insn "*addsi3_zero_extend.hi"
1217 [(set (match_operand:SI 0 "register_operand" "=r")
1218 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1219 (match_operand:SI 2 "register_operand" "0")))]
1220 ""
1221 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1222 [(set_attr "length" "4")
1223 (set_attr "cc" "set_n")])
1224
1225 (define_insn "addpsi3"
1226 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1227 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1228 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1229 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1230 ""
1231 {
1232 static const char * const asm_code[] =
1233 {
1234 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1235 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1236 "",
1237 ""
1238 };
1239
1240 if (*asm_code[which_alternative])
1241 return asm_code[which_alternative];
1242
1243 return avr_out_plus (operands, NULL, NULL);
1244 }
1245 [(set_attr "length" "3,3,3,6")
1246 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1247 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1248
1249 (define_insn "subpsi3"
1250 [(set (match_operand:PSI 0 "register_operand" "=r")
1251 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1252 (match_operand:PSI 2 "register_operand" "r")))]
1253 ""
1254 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1255 [(set_attr "length" "3")
1256 (set_attr "cc" "set_czn")])
1257
1258 (define_insn "*subpsi3_zero_extend.qi"
1259 [(set (match_operand:PSI 0 "register_operand" "=r")
1260 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1261 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1262 ""
1263 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1264 [(set_attr "length" "3")
1265 (set_attr "cc" "set_czn")])
1266
1267 (define_insn "*subpsi3_zero_extend.hi"
1268 [(set (match_operand:PSI 0 "register_operand" "=r")
1269 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1270 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1271 ""
1272 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1273 [(set_attr "length" "3")
1274 (set_attr "cc" "set_czn")])
1275
1276 (define_insn "*subpsi3_sign_extend.hi"
1277 [(set (match_operand:PSI 0 "register_operand" "=r")
1278 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1279 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1280 ""
1281 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1282 [(set_attr "length" "5")
1283 (set_attr "cc" "set_czn")])
1284
1285 ;-----------------------------------------------------------------------------
1286 ; sub bytes
1287 (define_insn "subqi3"
1288 [(set (match_operand:QI 0 "register_operand" "=r,d")
1289 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1290 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1291 ""
1292 "@
1293 sub %0,%2
1294 subi %0,lo8(%2)"
1295 [(set_attr "length" "1,1")
1296 (set_attr "cc" "set_czn,set_czn")])
1297
1298 (define_insn "subhi3"
1299 [(set (match_operand:HI 0 "register_operand" "=r,d")
1300 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1301 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1302 ""
1303 "@
1304 sub %A0,%A2\;sbc %B0,%B2
1305 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1306 [(set_attr "length" "2,2")
1307 (set_attr "cc" "set_czn,set_czn")])
1308
1309 (define_insn "*subhi3_zero_extend1"
1310 [(set (match_operand:HI 0 "register_operand" "=r")
1311 (minus:HI (match_operand:HI 1 "register_operand" "0")
1312 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1313 ""
1314 "sub %A0,%2\;sbc %B0,__zero_reg__"
1315 [(set_attr "length" "2")
1316 (set_attr "cc" "set_czn")])
1317
1318 (define_insn "*subhi3.sign_extend2"
1319 [(set (match_operand:HI 0 "register_operand" "=r")
1320 (minus:HI (match_operand:HI 1 "register_operand" "0")
1321 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1322 ""
1323 {
1324 return reg_overlap_mentioned_p (operands[0], operands[2])
1325 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1326 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1327 }
1328 [(set_attr "length" "5")
1329 (set_attr "cc" "clobber")])
1330
1331 (define_insn "subsi3"
1332 [(set (match_operand:SI 0 "register_operand" "=r")
1333 (minus:SI (match_operand:SI 1 "register_operand" "0")
1334 (match_operand:SI 2 "register_operand" "r")))]
1335 ""
1336 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1337 [(set_attr "length" "4")
1338 (set_attr "cc" "set_czn")])
1339
1340 (define_insn "*subsi3_zero_extend"
1341 [(set (match_operand:SI 0 "register_operand" "=r")
1342 (minus:SI (match_operand:SI 1 "register_operand" "0")
1343 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1344 ""
1345 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1346 [(set_attr "length" "4")
1347 (set_attr "cc" "set_czn")])
1348
1349 (define_insn "*subsi3_zero_extend.hi"
1350 [(set (match_operand:SI 0 "register_operand" "=r")
1351 (minus:SI (match_operand:SI 1 "register_operand" "0")
1352 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1353 ""
1354 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1355 [(set_attr "length" "4")
1356 (set_attr "cc" "set_czn")])
1357
1358 ;******************************************************************************
1359 ; mul
1360
1361 (define_expand "mulqi3"
1362 [(set (match_operand:QI 0 "register_operand" "")
1363 (mult:QI (match_operand:QI 1 "register_operand" "")
1364 (match_operand:QI 2 "register_operand" "")))]
1365 ""
1366 {
1367 if (!AVR_HAVE_MUL)
1368 {
1369 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1370 DONE;
1371 }
1372 })
1373
1374 (define_insn "*mulqi3_enh"
1375 [(set (match_operand:QI 0 "register_operand" "=r")
1376 (mult:QI (match_operand:QI 1 "register_operand" "r")
1377 (match_operand:QI 2 "register_operand" "r")))]
1378 "AVR_HAVE_MUL"
1379 "mul %1,%2
1380 mov %0,r0
1381 clr r1"
1382 [(set_attr "length" "3")
1383 (set_attr "cc" "clobber")])
1384
1385 (define_expand "mulqi3_call"
1386 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1387 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1388 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1389 (clobber (reg:QI 22))])
1390 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1391 ""
1392 "")
1393
1394 (define_insn "*mulqi3_call"
1395 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1396 (clobber (reg:QI 22))]
1397 "!AVR_HAVE_MUL"
1398 "%~call __mulqi3"
1399 [(set_attr "type" "xcall")
1400 (set_attr "cc" "clobber")])
1401
1402 ;; "umulqi3_highpart"
1403 ;; "smulqi3_highpart"
1404 (define_insn "<extend_su>mulqi3_highpart"
1405 [(set (match_operand:QI 0 "register_operand" "=r")
1406 (truncate:QI
1407 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1408 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1409 (const_int 8))))]
1410 "AVR_HAVE_MUL"
1411 "mul<extend_s> %1,%2
1412 mov %0,r1
1413 clr __zero_reg__"
1414 [(set_attr "length" "3")
1415 (set_attr "cc" "clobber")])
1416
1417
1418 ;; Used when expanding div or mod inline for some special values
1419 (define_insn "*subqi3.ashiftrt7"
1420 [(set (match_operand:QI 0 "register_operand" "=r")
1421 (minus:QI (match_operand:QI 1 "register_operand" "0")
1422 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1423 (const_int 7))))]
1424 ""
1425 "sbrc %2,7\;inc %0"
1426 [(set_attr "length" "2")
1427 (set_attr "cc" "clobber")])
1428
1429 (define_insn "*addqi3.lt0"
1430 [(set (match_operand:QI 0 "register_operand" "=r")
1431 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1432 (const_int 0))
1433 (match_operand:QI 2 "register_operand" "0")))]
1434 ""
1435 "sbrc %1,7\;inc %0"
1436 [(set_attr "length" "2")
1437 (set_attr "cc" "clobber")])
1438
1439 (define_insn "*addhi3.lt0"
1440 [(set (match_operand:HI 0 "register_operand" "=w,r")
1441 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1442 (const_int 0))
1443 (match_operand:HI 2 "register_operand" "0,0")))
1444 (clobber (match_scratch:QI 3 "=X,&1"))]
1445 ""
1446 "@
1447 sbrc %1,7\;adiw %0,1
1448 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1449 [(set_attr "length" "2,3")
1450 (set_attr "cc" "clobber")])
1451
1452 (define_insn "*addpsi3.lt0"
1453 [(set (match_operand:PSI 0 "register_operand" "=r")
1454 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1455 (const_int 23))
1456 (match_operand:PSI 2 "register_operand" "0")))]
1457 ""
1458 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1459 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1460 [(set_attr "length" "5")
1461 (set_attr "cc" "clobber")])
1462
1463 (define_insn "*addsi3.lt0"
1464 [(set (match_operand:SI 0 "register_operand" "=r")
1465 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1466 (const_int 31))
1467 (match_operand:SI 2 "register_operand" "0")))]
1468 ""
1469 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1470 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1471 [(set_attr "length" "6")
1472 (set_attr "cc" "clobber")])
1473
1474
1475 ;; "umulqihi3"
1476 ;; "mulqihi3"
1477 (define_insn "<extend_u>mulqihi3"
1478 [(set (match_operand:HI 0 "register_operand" "=r")
1479 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1480 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1481 "AVR_HAVE_MUL"
1482 "mul<extend_s> %1,%2
1483 movw %0,r0
1484 clr __zero_reg__"
1485 [(set_attr "length" "3")
1486 (set_attr "cc" "clobber")])
1487
1488 (define_insn "usmulqihi3"
1489 [(set (match_operand:HI 0 "register_operand" "=r")
1490 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1491 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1492 "AVR_HAVE_MUL"
1493 "mulsu %2,%1
1494 movw %0,r0
1495 clr __zero_reg__"
1496 [(set_attr "length" "3")
1497 (set_attr "cc" "clobber")])
1498
1499 ;; Above insn is not canonicalized by insn combine, so here is a version with
1500 ;; operands swapped.
1501
1502 (define_insn "*sumulqihi3"
1503 [(set (match_operand:HI 0 "register_operand" "=r")
1504 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1505 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1506 "AVR_HAVE_MUL"
1507 "mulsu %1,%2
1508 movw %0,r0
1509 clr __zero_reg__"
1510 [(set_attr "length" "3")
1511 (set_attr "cc" "clobber")])
1512
1513 ;; One-extend operand 1
1514
1515 (define_insn "*osmulqihi3"
1516 [(set (match_operand:HI 0 "register_operand" "=&r")
1517 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1518 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1519 "AVR_HAVE_MUL"
1520 "mulsu %2,%1
1521 movw %0,r0
1522 sub %B0,%2
1523 clr __zero_reg__"
1524 [(set_attr "length" "4")
1525 (set_attr "cc" "clobber")])
1526
1527 (define_insn "*oumulqihi3"
1528 [(set (match_operand:HI 0 "register_operand" "=&r")
1529 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1530 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1531 "AVR_HAVE_MUL"
1532 "mul %2,%1
1533 movw %0,r0
1534 sub %B0,%2
1535 clr __zero_reg__"
1536 [(set_attr "length" "4")
1537 (set_attr "cc" "clobber")])
1538
1539 ;******************************************************************************
1540 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1541 ;******************************************************************************
1542
1543 (define_insn "*maddqi4"
1544 [(set (match_operand:QI 0 "register_operand" "=r")
1545 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1546 (match_operand:QI 2 "register_operand" "r"))
1547 (match_operand:QI 3 "register_operand" "0")))]
1548
1549 "AVR_HAVE_MUL"
1550 "mul %1,%2
1551 add %A0,r0
1552 clr __zero_reg__"
1553 [(set_attr "length" "4")
1554 (set_attr "cc" "clobber")])
1555
1556 (define_insn "*msubqi4"
1557 [(set (match_operand:QI 0 "register_operand" "=r")
1558 (minus:QI (match_operand:QI 3 "register_operand" "0")
1559 (mult:QI (match_operand:QI 1 "register_operand" "r")
1560 (match_operand:QI 2 "register_operand" "r"))))]
1561 "AVR_HAVE_MUL"
1562 "mul %1,%2
1563 sub %A0,r0
1564 clr __zero_reg__"
1565 [(set_attr "length" "4")
1566 (set_attr "cc" "clobber")])
1567
1568 (define_insn_and_split "*maddqi4.const"
1569 [(set (match_operand:QI 0 "register_operand" "=r")
1570 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1571 (match_operand:QI 2 "const_int_operand" "n"))
1572 (match_operand:QI 3 "register_operand" "0")))
1573 (clobber (match_scratch:QI 4 "=&d"))]
1574 "AVR_HAVE_MUL"
1575 "#"
1576 "&& reload_completed"
1577 [(set (match_dup 4)
1578 (match_dup 2))
1579 ; *maddqi4
1580 (set (match_dup 0)
1581 (plus:QI (mult:QI (match_dup 1)
1582 (match_dup 4))
1583 (match_dup 3)))]
1584 "")
1585
1586 (define_insn_and_split "*msubqi4.const"
1587 [(set (match_operand:QI 0 "register_operand" "=r")
1588 (minus:QI (match_operand:QI 3 "register_operand" "0")
1589 (mult:QI (match_operand:QI 1 "register_operand" "r")
1590 (match_operand:QI 2 "const_int_operand" "n"))))
1591 (clobber (match_scratch:QI 4 "=&d"))]
1592 "AVR_HAVE_MUL"
1593 "#"
1594 "&& reload_completed"
1595 [(set (match_dup 4)
1596 (match_dup 2))
1597 ; *msubqi4
1598 (set (match_dup 0)
1599 (minus:QI (match_dup 3)
1600 (mult:QI (match_dup 1)
1601 (match_dup 4))))]
1602 "")
1603
1604
1605 ;******************************************************************************
1606 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1607 ;******************************************************************************
1608
1609 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1610 ;; e.g,
1611 ;;
1612 ;; int foo (unsigned char z)
1613 ;; {
1614 ;; extern int aInt[];
1615 ;; return aInt[3*z+2];
1616 ;; }
1617 ;;
1618 ;; because the constant +4 then is added explicitely instead of consuming it
1619 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1620 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1621 ;; The implementational effort is the same so we are fine with that approach.
1622
1623
1624 ;; "*maddqihi4"
1625 ;; "*umaddqihi4"
1626 (define_insn "*<extend_u>maddqihi4"
1627 [(set (match_operand:HI 0 "register_operand" "=r")
1628 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1629 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1630 (match_operand:HI 3 "register_operand" "0")))]
1631
1632 "AVR_HAVE_MUL"
1633 "mul<extend_s> %1,%2
1634 add %A0,r0
1635 adc %B0,r1
1636 clr __zero_reg__"
1637 [(set_attr "length" "4")
1638 (set_attr "cc" "clobber")])
1639
1640 ;; "*msubqihi4"
1641 ;; "*umsubqihi4"
1642 (define_insn "*<extend_u>msubqihi4"
1643 [(set (match_operand:HI 0 "register_operand" "=r")
1644 (minus:HI (match_operand:HI 3 "register_operand" "0")
1645 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1646 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1647 "AVR_HAVE_MUL"
1648 "mul<extend_s> %1,%2
1649 sub %A0,r0
1650 sbc %B0,r1
1651 clr __zero_reg__"
1652 [(set_attr "length" "4")
1653 (set_attr "cc" "clobber")])
1654
1655 ;; "*usmaddqihi4"
1656 ;; "*sumaddqihi4"
1657 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1658 [(set (match_operand:HI 0 "register_operand" "=r")
1659 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1660 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1661 (match_operand:HI 3 "register_operand" "0")))]
1662 "AVR_HAVE_MUL
1663 && reload_completed
1664 && <any_extend:CODE> != <any_extend2:CODE>"
1665 {
1666 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1667 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1668
1669 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1670 }
1671 [(set_attr "length" "4")
1672 (set_attr "cc" "clobber")])
1673
1674 ;; "*usmsubqihi4"
1675 ;; "*sumsubqihi4"
1676 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1677 [(set (match_operand:HI 0 "register_operand" "=r")
1678 (minus:HI (match_operand:HI 3 "register_operand" "0")
1679 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1680 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1681 "AVR_HAVE_MUL
1682 && reload_completed
1683 && <any_extend:CODE> != <any_extend2:CODE>"
1684 {
1685 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1686 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1687
1688 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1689 }
1690 [(set_attr "length" "4")
1691 (set_attr "cc" "clobber")])
1692
1693 ;; Handle small constants
1694
1695 ;; "umaddqihi4.uconst"
1696 ;; "maddqihi4.sconst"
1697 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1698 [(set (match_operand:HI 0 "register_operand" "=r")
1699 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1700 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1701 (match_operand:HI 3 "register_operand" "0")))
1702 (clobber (match_scratch:QI 4 "=&d"))]
1703 "AVR_HAVE_MUL"
1704 "#"
1705 "&& reload_completed"
1706 [(set (match_dup 4)
1707 (match_dup 2))
1708 ; *umaddqihi4 resp. *maddqihi4
1709 (set (match_dup 0)
1710 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1711 (any_extend:HI (match_dup 4)))
1712 (match_dup 3)))]
1713 {
1714 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1715 })
1716
1717 ;; "*umsubqihi4.uconst"
1718 ;; "*msubqihi4.sconst"
1719 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1720 [(set (match_operand:HI 0 "register_operand" "=r")
1721 (minus:HI (match_operand:HI 3 "register_operand" "0")
1722 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1723 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1724 (clobber (match_scratch:QI 4 "=&d"))]
1725 "AVR_HAVE_MUL"
1726 "#"
1727 "&& reload_completed"
1728 [(set (match_dup 4)
1729 (match_dup 2))
1730 ; *umsubqihi4 resp. *msubqihi4
1731 (set (match_dup 0)
1732 (minus:HI (match_dup 3)
1733 (mult:HI (any_extend:HI (match_dup 1))
1734 (any_extend:HI (match_dup 4)))))]
1735 {
1736 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1737 })
1738
1739 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1740 ;; for MULT with power of 2 and skips trying MULT insn above.
1741
1742 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1743 [(set (match_operand:HI 0 "register_operand" "=r")
1744 (minus:HI (match_operand:HI 3 "register_operand" "0")
1745 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1746 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1747 (clobber (match_scratch:QI 4 "=&d"))]
1748 "AVR_HAVE_MUL"
1749 "#"
1750 "&& reload_completed"
1751 [(set (match_dup 4)
1752 (match_dup 2))
1753 ; *umsubqihi4
1754 (set (match_dup 0)
1755 (minus:HI (match_dup 3)
1756 (mult:HI (zero_extend:HI (match_dup 1))
1757 (zero_extend:HI (match_dup 4)))))]
1758 {
1759 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1760 })
1761
1762 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1763 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1764 ;; because this would require an extra pattern for just one value.
1765
1766 (define_insn_and_split "*msubqihi4.sconst.ashift"
1767 [(set (match_operand:HI 0 "register_operand" "=r")
1768 (minus:HI (match_operand:HI 3 "register_operand" "0")
1769 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1770 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1771 (clobber (match_scratch:QI 4 "=&d"))]
1772 "AVR_HAVE_MUL"
1773 "#"
1774 "&& reload_completed"
1775 [(set (match_dup 4)
1776 (match_dup 2))
1777 ; *smsubqihi4
1778 (set (match_dup 0)
1779 (minus:HI (match_dup 3)
1780 (mult:HI (sign_extend:HI (match_dup 1))
1781 (sign_extend:HI (match_dup 4)))))]
1782 {
1783 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1784 })
1785
1786 ;; For signed/unsigned combinations that require narrow constraint "a"
1787 ;; just provide a pattern if signed/unsigned combination is actually needed.
1788
1789 (define_insn_and_split "*sumaddqihi4.uconst"
1790 [(set (match_operand:HI 0 "register_operand" "=r")
1791 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1792 (match_operand:HI 2 "u8_operand" "M"))
1793 (match_operand:HI 3 "register_operand" "0")))
1794 (clobber (match_scratch:QI 4 "=&a"))]
1795 "AVR_HAVE_MUL
1796 && !s8_operand (operands[2], VOIDmode)"
1797 "#"
1798 "&& reload_completed"
1799 [(set (match_dup 4)
1800 (match_dup 2))
1801 ; *sumaddqihi4
1802 (set (match_dup 0)
1803 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1804 (zero_extend:HI (match_dup 4)))
1805 (match_dup 3)))]
1806 {
1807 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1808 })
1809
1810 (define_insn_and_split "*sumsubqihi4.uconst"
1811 [(set (match_operand:HI 0 "register_operand" "=r")
1812 (minus:HI (match_operand:HI 3 "register_operand" "0")
1813 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1814 (match_operand:HI 2 "u8_operand" "M"))))
1815 (clobber (match_scratch:QI 4 "=&a"))]
1816 "AVR_HAVE_MUL
1817 && !s8_operand (operands[2], VOIDmode)"
1818 "#"
1819 "&& reload_completed"
1820 [(set (match_dup 4)
1821 (match_dup 2))
1822 ; *sumsubqihi4
1823 (set (match_dup 0)
1824 (minus:HI (match_dup 3)
1825 (mult:HI (sign_extend:HI (match_dup 1))
1826 (zero_extend:HI (match_dup 4)))))]
1827 {
1828 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1829 })
1830
1831 ;******************************************************************************
1832 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1833 ;******************************************************************************
1834
1835 ;; "*muluqihi3.uconst"
1836 ;; "*mulsqihi3.sconst"
1837 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1838 [(set (match_operand:HI 0 "register_operand" "=r")
1839 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1840 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1841 (clobber (match_scratch:QI 3 "=&d"))]
1842 "AVR_HAVE_MUL"
1843 "#"
1844 "&& reload_completed"
1845 [(set (match_dup 3)
1846 (match_dup 2))
1847 ; umulqihi3 resp. mulqihi3
1848 (set (match_dup 0)
1849 (mult:HI (any_extend:HI (match_dup 1))
1850 (any_extend:HI (match_dup 3))))]
1851 {
1852 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1853 })
1854
1855 (define_insn_and_split "*muluqihi3.sconst"
1856 [(set (match_operand:HI 0 "register_operand" "=r")
1857 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1858 (match_operand:HI 2 "s8_operand" "n")))
1859 (clobber (match_scratch:QI 3 "=&a"))]
1860 "AVR_HAVE_MUL"
1861 "#"
1862 "&& reload_completed"
1863 [(set (match_dup 3)
1864 (match_dup 2))
1865 ; usmulqihi3
1866 (set (match_dup 0)
1867 (mult:HI (zero_extend:HI (match_dup 1))
1868 (sign_extend:HI (match_dup 3))))]
1869 {
1870 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1871 })
1872
1873 (define_insn_and_split "*mulsqihi3.uconst"
1874 [(set (match_operand:HI 0 "register_operand" "=r")
1875 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1876 (match_operand:HI 2 "u8_operand" "M")))
1877 (clobber (match_scratch:QI 3 "=&a"))]
1878 "AVR_HAVE_MUL"
1879 "#"
1880 "&& reload_completed"
1881 [(set (match_dup 3)
1882 (match_dup 2))
1883 ; usmulqihi3
1884 (set (match_dup 0)
1885 (mult:HI (zero_extend:HI (match_dup 3))
1886 (sign_extend:HI (match_dup 1))))]
1887 {
1888 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1889 })
1890
1891 (define_insn_and_split "*mulsqihi3.oconst"
1892 [(set (match_operand:HI 0 "register_operand" "=&r")
1893 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1894 (match_operand:HI 2 "o8_operand" "n")))
1895 (clobber (match_scratch:QI 3 "=&a"))]
1896 "AVR_HAVE_MUL"
1897 "#"
1898 "&& reload_completed"
1899 [(set (match_dup 3)
1900 (match_dup 2))
1901 ; *osmulqihi3
1902 (set (match_dup 0)
1903 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1904 (sign_extend:HI (match_dup 1))))]
1905 {
1906 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1907 })
1908
1909 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1910 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1911 ;; at that time. Fix that.
1912
1913 (define_insn "*ashiftqihi2.signx.1"
1914 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1915 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1916 (const_int 1)))]
1917 ""
1918 "@
1919 lsl %A0\;sbc %B0,%B0
1920 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1921 [(set_attr "length" "2,3")
1922 (set_attr "cc" "clobber")])
1923
1924 (define_insn_and_split "*ashifthi3.signx.const"
1925 [(set (match_operand:HI 0 "register_operand" "=r")
1926 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1927 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1928 (clobber (match_scratch:QI 3 "=&d"))]
1929 "AVR_HAVE_MUL"
1930 "#"
1931 "&& reload_completed"
1932 [(set (match_dup 3)
1933 (match_dup 2))
1934 ; mulqihi3
1935 (set (match_dup 0)
1936 (mult:HI (sign_extend:HI (match_dup 1))
1937 (sign_extend:HI (match_dup 3))))]
1938 {
1939 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1940 })
1941
1942 (define_insn_and_split "*ashifthi3.signx.const7"
1943 [(set (match_operand:HI 0 "register_operand" "=r")
1944 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1945 (const_int 7)))
1946 (clobber (match_scratch:QI 2 "=&a"))]
1947 "AVR_HAVE_MUL"
1948 "#"
1949 "&& reload_completed"
1950 [(set (match_dup 2)
1951 (match_dup 3))
1952 ; usmulqihi3
1953 (set (match_dup 0)
1954 (mult:HI (zero_extend:HI (match_dup 2))
1955 (sign_extend:HI (match_dup 1))))]
1956 {
1957 operands[3] = gen_int_mode (1 << 7, QImode);
1958 })
1959
1960 (define_insn_and_split "*ashifthi3.zerox.const"
1961 [(set (match_operand:HI 0 "register_operand" "=r")
1962 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1963 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1964 (clobber (match_scratch:QI 3 "=&d"))]
1965 "AVR_HAVE_MUL"
1966 "#"
1967 "&& reload_completed"
1968 [(set (match_dup 3)
1969 (match_dup 2))
1970 ; umulqihi3
1971 (set (match_dup 0)
1972 (mult:HI (zero_extend:HI (match_dup 1))
1973 (zero_extend:HI (match_dup 3))))]
1974 {
1975 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1976 })
1977
1978 ;******************************************************************************
1979 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1980 ;******************************************************************************
1981
1982 (define_insn "mulsqihi3"
1983 [(set (match_operand:HI 0 "register_operand" "=&r")
1984 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1985 (match_operand:HI 2 "register_operand" "a")))]
1986 "AVR_HAVE_MUL"
1987 "mulsu %1,%A2
1988 movw %0,r0
1989 mul %1,%B2
1990 add %B0,r0
1991 clr __zero_reg__"
1992 [(set_attr "length" "5")
1993 (set_attr "cc" "clobber")])
1994
1995 (define_insn "muluqihi3"
1996 [(set (match_operand:HI 0 "register_operand" "=&r")
1997 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1998 (match_operand:HI 2 "register_operand" "r")))]
1999 "AVR_HAVE_MUL"
2000 "mul %1,%A2
2001 movw %0,r0
2002 mul %1,%B2
2003 add %B0,r0
2004 clr __zero_reg__"
2005 [(set_attr "length" "5")
2006 (set_attr "cc" "clobber")])
2007
2008 ;; one-extend operand 1
2009
2010 (define_insn "muloqihi3"
2011 [(set (match_operand:HI 0 "register_operand" "=&r")
2012 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2013 (match_operand:HI 2 "register_operand" "r")))]
2014 "AVR_HAVE_MUL"
2015 "mul %1,%A2
2016 movw %0,r0
2017 mul %1,%B2
2018 add %B0,r0
2019 sub %B0,%A2
2020 clr __zero_reg__"
2021 [(set_attr "length" "6")
2022 (set_attr "cc" "clobber")])
2023
2024 ;******************************************************************************
2025
2026 (define_expand "mulhi3"
2027 [(set (match_operand:HI 0 "register_operand" "")
2028 (mult:HI (match_operand:HI 1 "register_operand" "")
2029 (match_operand:HI 2 "register_or_s9_operand" "")))]
2030 ""
2031 {
2032 if (!AVR_HAVE_MUL)
2033 {
2034 if (!register_operand (operands[2], HImode))
2035 operands[2] = force_reg (HImode, operands[2]);
2036
2037 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2038 DONE;
2039 }
2040
2041 /* For small constants we can do better by extending them on the fly.
2042 The constant can be loaded in one instruction and the widening
2043 multiplication is shorter. First try the unsigned variant because it
2044 allows constraint "d" instead of "a" for the signed version. */
2045
2046 if (s9_operand (operands[2], HImode))
2047 {
2048 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2049
2050 if (u8_operand (operands[2], HImode))
2051 {
2052 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2053 }
2054 else if (s8_operand (operands[2], HImode))
2055 {
2056 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2057 }
2058 else
2059 {
2060 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2061 }
2062
2063 DONE;
2064 }
2065
2066 if (!register_operand (operands[2], HImode))
2067 operands[2] = force_reg (HImode, operands[2]);
2068 })
2069
2070 (define_insn "*mulhi3_enh"
2071 [(set (match_operand:HI 0 "register_operand" "=&r")
2072 (mult:HI (match_operand:HI 1 "register_operand" "r")
2073 (match_operand:HI 2 "register_operand" "r")))]
2074 "AVR_HAVE_MUL"
2075 {
2076 return REGNO (operands[1]) == REGNO (operands[2])
2077 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2078 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2079 }
2080 [(set_attr "length" "7")
2081 (set_attr "cc" "clobber")])
2082
2083 (define_expand "mulhi3_call"
2084 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2085 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2086 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2087 (clobber (reg:HI 22))
2088 (clobber (reg:QI 21))])
2089 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2090 ""
2091 "")
2092
2093 (define_insn "*mulhi3_call"
2094 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2095 (clobber (reg:HI 22))
2096 (clobber (reg:QI 21))]
2097 "!AVR_HAVE_MUL"
2098 "%~call __mulhi3"
2099 [(set_attr "type" "xcall")
2100 (set_attr "cc" "clobber")])
2101
2102 ;; To support widening multiplication with constant we postpone
2103 ;; expanding to the implicit library call until post combine and
2104 ;; prior to register allocation. Clobber all hard registers that
2105 ;; might be used by the (widening) multiply until it is split and
2106 ;; it's final register footprint is worked out.
2107
2108 (define_expand "mulsi3"
2109 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2110 (mult:SI (match_operand:SI 1 "register_operand" "")
2111 (match_operand:SI 2 "nonmemory_operand" "")))
2112 (clobber (reg:HI 26))
2113 (clobber (reg:DI 18))])]
2114 "AVR_HAVE_MUL"
2115 {
2116 if (u16_operand (operands[2], SImode))
2117 {
2118 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2119 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2120 DONE;
2121 }
2122
2123 if (o16_operand (operands[2], SImode))
2124 {
2125 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2126 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2127 DONE;
2128 }
2129 })
2130
2131 (define_insn_and_split "*mulsi3"
2132 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2133 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2134 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2135 (clobber (reg:HI 26))
2136 (clobber (reg:DI 18))]
2137 "AVR_HAVE_MUL && !reload_completed"
2138 { gcc_unreachable(); }
2139 "&& 1"
2140 [(set (reg:SI 18)
2141 (match_dup 1))
2142 (set (reg:SI 22)
2143 (match_dup 2))
2144 (parallel [(set (reg:SI 22)
2145 (mult:SI (reg:SI 22)
2146 (reg:SI 18)))
2147 (clobber (reg:HI 26))])
2148 (set (match_dup 0)
2149 (reg:SI 22))]
2150 {
2151 if (u16_operand (operands[2], SImode))
2152 {
2153 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2154 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2155 DONE;
2156 }
2157
2158 if (o16_operand (operands[2], SImode))
2159 {
2160 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2161 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2162 DONE;
2163 }
2164 })
2165
2166 ;; "muluqisi3"
2167 ;; "muluhisi3"
2168 (define_insn_and_split "mulu<mode>si3"
2169 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2170 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2171 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2172 (clobber (reg:HI 26))
2173 (clobber (reg:DI 18))]
2174 "AVR_HAVE_MUL && !reload_completed"
2175 { gcc_unreachable(); }
2176 "&& 1"
2177 [(set (reg:HI 26)
2178 (match_dup 1))
2179 (set (reg:SI 18)
2180 (match_dup 2))
2181 (set (reg:SI 22)
2182 (mult:SI (zero_extend:SI (reg:HI 26))
2183 (reg:SI 18)))
2184 (set (match_dup 0)
2185 (reg:SI 22))]
2186 {
2187 /* Do the QI -> HI extension explicitely before the multiplication. */
2188 /* Do the HI -> SI extension implicitely and after the multiplication. */
2189
2190 if (QImode == <MODE>mode)
2191 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2192
2193 if (u16_operand (operands[2], SImode))
2194 {
2195 operands[1] = force_reg (HImode, operands[1]);
2196 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2197 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2198 DONE;
2199 }
2200 })
2201
2202 ;; "mulsqisi3"
2203 ;; "mulshisi3"
2204 (define_insn_and_split "muls<mode>si3"
2205 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2206 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2207 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2208 (clobber (reg:HI 26))
2209 (clobber (reg:DI 18))]
2210 "AVR_HAVE_MUL && !reload_completed"
2211 { gcc_unreachable(); }
2212 "&& 1"
2213 [(set (reg:HI 26)
2214 (match_dup 1))
2215 (set (reg:SI 18)
2216 (match_dup 2))
2217 (set (reg:SI 22)
2218 (mult:SI (sign_extend:SI (reg:HI 26))
2219 (reg:SI 18)))
2220 (set (match_dup 0)
2221 (reg:SI 22))]
2222 {
2223 /* Do the QI -> HI extension explicitely before the multiplication. */
2224 /* Do the HI -> SI extension implicitely and after the multiplication. */
2225
2226 if (QImode == <MODE>mode)
2227 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2228
2229 if (u16_operand (operands[2], SImode)
2230 || s16_operand (operands[2], SImode))
2231 {
2232 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2233
2234 operands[1] = force_reg (HImode, operands[1]);
2235
2236 if (u16_operand (operands[2], SImode))
2237 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2238 else
2239 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2240
2241 DONE;
2242 }
2243 })
2244
2245 ;; One-extend operand 1
2246
2247 (define_insn_and_split "mulohisi3"
2248 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2249 (mult:SI (not:SI (zero_extend:SI
2250 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2251 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2252 (clobber (reg:HI 26))
2253 (clobber (reg:DI 18))]
2254 "AVR_HAVE_MUL && !reload_completed"
2255 { gcc_unreachable(); }
2256 "&& 1"
2257 [(set (reg:HI 26)
2258 (match_dup 1))
2259 (set (reg:SI 18)
2260 (match_dup 2))
2261 (set (reg:SI 22)
2262 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2263 (reg:SI 18)))
2264 (set (match_dup 0)
2265 (reg:SI 22))]
2266 "")
2267
2268 ;; "mulhisi3"
2269 ;; "umulhisi3"
2270 (define_expand "<extend_u>mulhisi3"
2271 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2272 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2273 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2274 (clobber (reg:HI 26))
2275 (clobber (reg:DI 18))])]
2276 "AVR_HAVE_MUL"
2277 "")
2278
2279 (define_expand "usmulhisi3"
2280 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2281 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2282 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2283 (clobber (reg:HI 26))
2284 (clobber (reg:DI 18))])]
2285 "AVR_HAVE_MUL"
2286 "")
2287
2288 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2289 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2290 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2291 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2292 (define_insn_and_split
2293 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2294 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2295 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2296 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2297 (clobber (reg:HI 26))
2298 (clobber (reg:DI 18))]
2299 "AVR_HAVE_MUL && !reload_completed"
2300 { gcc_unreachable(); }
2301 "&& 1"
2302 [(set (reg:HI 18)
2303 (match_dup 1))
2304 (set (reg:HI 26)
2305 (match_dup 2))
2306 (set (reg:SI 22)
2307 (mult:SI (match_dup 3)
2308 (match_dup 4)))
2309 (set (match_dup 0)
2310 (reg:SI 22))]
2311 {
2312 rtx xop1 = operands[1];
2313 rtx xop2 = operands[2];
2314
2315 /* Do the QI -> HI extension explicitely before the multiplication. */
2316 /* Do the HI -> SI extension implicitely and after the multiplication. */
2317
2318 if (QImode == <QIHI:MODE>mode)
2319 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2320
2321 if (QImode == <QIHI2:MODE>mode)
2322 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2323
2324 if (<any_extend:CODE> == <any_extend2:CODE>
2325 || <any_extend:CODE> == ZERO_EXTEND)
2326 {
2327 operands[1] = xop1;
2328 operands[2] = xop2;
2329 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2330 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2331 }
2332 else
2333 {
2334 /* <any_extend:CODE> = SIGN_EXTEND */
2335 /* <any_extend2:CODE> = ZERO_EXTEND */
2336
2337 operands[1] = xop2;
2338 operands[2] = xop1;
2339 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2340 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2341 }
2342 })
2343
2344 ;; "smulhi3_highpart"
2345 ;; "umulhi3_highpart"
2346 (define_expand "<extend_su>mulhi3_highpart"
2347 [(set (reg:HI 18)
2348 (match_operand:HI 1 "nonmemory_operand" ""))
2349 (set (reg:HI 26)
2350 (match_operand:HI 2 "nonmemory_operand" ""))
2351 (parallel [(set (reg:HI 24)
2352 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2353 (any_extend:SI (reg:HI 26)))
2354 (const_int 16))))
2355 (clobber (reg:HI 22))])
2356 (set (match_operand:HI 0 "register_operand" "")
2357 (reg:HI 24))]
2358 "AVR_HAVE_MUL"
2359 "")
2360
2361
2362 (define_insn "*mulsi3_call"
2363 [(set (reg:SI 22)
2364 (mult:SI (reg:SI 22)
2365 (reg:SI 18)))
2366 (clobber (reg:HI 26))]
2367 "AVR_HAVE_MUL"
2368 "%~call __mulsi3"
2369 [(set_attr "type" "xcall")
2370 (set_attr "cc" "clobber")])
2371
2372 ;; "*mulhisi3_call"
2373 ;; "*umulhisi3_call"
2374 (define_insn "*<extend_u>mulhisi3_call"
2375 [(set (reg:SI 22)
2376 (mult:SI (any_extend:SI (reg:HI 18))
2377 (any_extend:SI (reg:HI 26))))]
2378 "AVR_HAVE_MUL"
2379 "%~call __<extend_u>mulhisi3"
2380 [(set_attr "type" "xcall")
2381 (set_attr "cc" "clobber")])
2382
2383 ;; "*umulhi3_highpart_call"
2384 ;; "*smulhi3_highpart_call"
2385 (define_insn "*<extend_su>mulhi3_highpart_call"
2386 [(set (reg:HI 24)
2387 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2388 (any_extend:SI (reg:HI 26)))
2389 (const_int 16))))
2390 (clobber (reg:HI 22))]
2391 "AVR_HAVE_MUL"
2392 "%~call __<extend_u>mulhisi3"
2393 [(set_attr "type" "xcall")
2394 (set_attr "cc" "clobber")])
2395
2396 (define_insn "*usmulhisi3_call"
2397 [(set (reg:SI 22)
2398 (mult:SI (zero_extend:SI (reg:HI 18))
2399 (sign_extend:SI (reg:HI 26))))]
2400 "AVR_HAVE_MUL"
2401 "%~call __usmulhisi3"
2402 [(set_attr "type" "xcall")
2403 (set_attr "cc" "clobber")])
2404
2405 (define_insn "*mul<extend_su>hisi3_call"
2406 [(set (reg:SI 22)
2407 (mult:SI (any_extend:SI (reg:HI 26))
2408 (reg:SI 18)))]
2409 "AVR_HAVE_MUL"
2410 "%~call __mul<extend_su>hisi3"
2411 [(set_attr "type" "xcall")
2412 (set_attr "cc" "clobber")])
2413
2414 (define_insn "*mulohisi3_call"
2415 [(set (reg:SI 22)
2416 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2417 (reg:SI 18)))]
2418 "AVR_HAVE_MUL"
2419 "%~call __mulohisi3"
2420 [(set_attr "type" "xcall")
2421 (set_attr "cc" "clobber")])
2422
2423 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2424 ; divmod
2425
2426 ;; Generate lib1funcs.S calls ourselves, because:
2427 ;; - we know exactly which registers are clobbered (for QI and HI
2428 ;; modes, some of the call-used registers are preserved)
2429 ;; - we get both the quotient and the remainder at no extra cost
2430 ;; - we split the patterns only after the first CSE passes because
2431 ;; CSE has problems to operate on hard regs.
2432 ;;
2433 (define_insn_and_split "divmodqi4"
2434 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2435 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2436 (match_operand:QI 2 "pseudo_register_operand" "")))
2437 (set (match_operand:QI 3 "pseudo_register_operand" "")
2438 (mod:QI (match_dup 1) (match_dup 2)))
2439 (clobber (reg:QI 22))
2440 (clobber (reg:QI 23))
2441 (clobber (reg:QI 24))
2442 (clobber (reg:QI 25))])]
2443 ""
2444 "this divmodqi4 pattern should have been splitted;"
2445 ""
2446 [(set (reg:QI 24) (match_dup 1))
2447 (set (reg:QI 22) (match_dup 2))
2448 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2449 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2450 (clobber (reg:QI 22))
2451 (clobber (reg:QI 23))])
2452 (set (match_dup 0) (reg:QI 24))
2453 (set (match_dup 3) (reg:QI 25))]
2454 "")
2455
2456 (define_insn "*divmodqi4_call"
2457 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2458 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2459 (clobber (reg:QI 22))
2460 (clobber (reg:QI 23))]
2461 ""
2462 "%~call __divmodqi4"
2463 [(set_attr "type" "xcall")
2464 (set_attr "cc" "clobber")])
2465
2466 (define_insn_and_split "udivmodqi4"
2467 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2468 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2469 (match_operand:QI 2 "pseudo_register_operand" "")))
2470 (set (match_operand:QI 3 "pseudo_register_operand" "")
2471 (umod:QI (match_dup 1) (match_dup 2)))
2472 (clobber (reg:QI 22))
2473 (clobber (reg:QI 23))
2474 (clobber (reg:QI 24))
2475 (clobber (reg:QI 25))])]
2476 ""
2477 "this udivmodqi4 pattern should have been splitted;"
2478 ""
2479 [(set (reg:QI 24) (match_dup 1))
2480 (set (reg:QI 22) (match_dup 2))
2481 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2482 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2483 (clobber (reg:QI 23))])
2484 (set (match_dup 0) (reg:QI 24))
2485 (set (match_dup 3) (reg:QI 25))]
2486 "")
2487
2488 (define_insn "*udivmodqi4_call"
2489 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2490 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2491 (clobber (reg:QI 23))]
2492 ""
2493 "%~call __udivmodqi4"
2494 [(set_attr "type" "xcall")
2495 (set_attr "cc" "clobber")])
2496
2497 (define_insn_and_split "divmodhi4"
2498 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2499 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2500 (match_operand:HI 2 "pseudo_register_operand" "")))
2501 (set (match_operand:HI 3 "pseudo_register_operand" "")
2502 (mod:HI (match_dup 1) (match_dup 2)))
2503 (clobber (reg:QI 21))
2504 (clobber (reg:HI 22))
2505 (clobber (reg:HI 24))
2506 (clobber (reg:HI 26))])]
2507 ""
2508 "this should have been splitted;"
2509 ""
2510 [(set (reg:HI 24) (match_dup 1))
2511 (set (reg:HI 22) (match_dup 2))
2512 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2513 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2514 (clobber (reg:HI 26))
2515 (clobber (reg:QI 21))])
2516 (set (match_dup 0) (reg:HI 22))
2517 (set (match_dup 3) (reg:HI 24))]
2518 "")
2519
2520 (define_insn "*divmodhi4_call"
2521 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2522 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2523 (clobber (reg:HI 26))
2524 (clobber (reg:QI 21))]
2525 ""
2526 "%~call __divmodhi4"
2527 [(set_attr "type" "xcall")
2528 (set_attr "cc" "clobber")])
2529
2530 (define_insn_and_split "udivmodhi4"
2531 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2532 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2533 (match_operand:HI 2 "pseudo_register_operand" "")))
2534 (set (match_operand:HI 3 "pseudo_register_operand" "")
2535 (umod:HI (match_dup 1) (match_dup 2)))
2536 (clobber (reg:QI 21))
2537 (clobber (reg:HI 22))
2538 (clobber (reg:HI 24))
2539 (clobber (reg:HI 26))])]
2540 ""
2541 "this udivmodhi4 pattern should have been splitted.;"
2542 ""
2543 [(set (reg:HI 24) (match_dup 1))
2544 (set (reg:HI 22) (match_dup 2))
2545 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2546 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2547 (clobber (reg:HI 26))
2548 (clobber (reg:QI 21))])
2549 (set (match_dup 0) (reg:HI 22))
2550 (set (match_dup 3) (reg:HI 24))]
2551 "")
2552
2553 (define_insn "*udivmodhi4_call"
2554 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2555 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2556 (clobber (reg:HI 26))
2557 (clobber (reg:QI 21))]
2558 ""
2559 "%~call __udivmodhi4"
2560 [(set_attr "type" "xcall")
2561 (set_attr "cc" "clobber")])
2562
2563 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2564 ;; 24-bit multiply
2565
2566 ;; To support widening multiplication with constant we postpone
2567 ;; expanding to the implicit library call until post combine and
2568 ;; prior to register allocation. Clobber all hard registers that
2569 ;; might be used by the (widening) multiply until it is split and
2570 ;; it's final register footprint is worked out.
2571
2572 (define_expand "mulpsi3"
2573 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2574 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2575 (match_operand:PSI 2 "nonmemory_operand" "")))
2576 (clobber (reg:HI 26))
2577 (clobber (reg:DI 18))])]
2578 "AVR_HAVE_MUL"
2579 {
2580 if (s8_operand (operands[2], PSImode))
2581 {
2582 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2583 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2584 DONE;
2585 }
2586 })
2587
2588 (define_insn "*umulqihipsi3"
2589 [(set (match_operand:PSI 0 "register_operand" "=&r")
2590 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2591 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2592 "AVR_HAVE_MUL"
2593 "mul %1,%A2
2594 movw %A0,r0
2595 mul %1,%B2
2596 clr %C0
2597 add %B0,r0
2598 adc %C0,r1
2599 clr __zero_reg__"
2600 [(set_attr "length" "7")
2601 (set_attr "cc" "clobber")])
2602
2603 (define_insn "*umulhiqipsi3"
2604 [(set (match_operand:PSI 0 "register_operand" "=&r")
2605 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2606 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2607 "AVR_HAVE_MUL"
2608 "mul %1,%A2
2609 movw %A0,r0
2610 mul %1,%B2
2611 add %B0,r0
2612 mov %C0,r1
2613 clr __zero_reg__
2614 adc %C0,__zero_reg__"
2615 [(set_attr "length" "7")
2616 (set_attr "cc" "clobber")])
2617
2618 (define_insn_and_split "mulsqipsi3"
2619 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2620 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2621 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2622 (clobber (reg:HI 26))
2623 (clobber (reg:DI 18))]
2624 "AVR_HAVE_MUL && !reload_completed"
2625 { gcc_unreachable(); }
2626 "&& 1"
2627 [(set (reg:QI 25)
2628 (match_dup 1))
2629 (set (reg:PSI 22)
2630 (match_dup 2))
2631 (set (reg:PSI 18)
2632 (mult:PSI (sign_extend:PSI (reg:QI 25))
2633 (reg:PSI 22)))
2634 (set (match_dup 0)
2635 (reg:PSI 18))])
2636
2637 (define_insn_and_split "*mulpsi3"
2638 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2639 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2640 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2641 (clobber (reg:HI 26))
2642 (clobber (reg:DI 18))]
2643 "AVR_HAVE_MUL && !reload_completed"
2644 { gcc_unreachable(); }
2645 "&& 1"
2646 [(set (reg:PSI 18)
2647 (match_dup 1))
2648 (set (reg:PSI 22)
2649 (match_dup 2))
2650 (parallel [(set (reg:PSI 22)
2651 (mult:PSI (reg:PSI 22)
2652 (reg:PSI 18)))
2653 (clobber (reg:QI 21))
2654 (clobber (reg:QI 25))
2655 (clobber (reg:HI 26))])
2656 (set (match_dup 0)
2657 (reg:PSI 22))]
2658 {
2659 if (s8_operand (operands[2], PSImode))
2660 {
2661 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2662 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2663 DONE;
2664 }
2665 })
2666
2667 (define_insn "*mulsqipsi3.libgcc"
2668 [(set (reg:PSI 18)
2669 (mult:PSI (sign_extend:PSI (reg:QI 25))
2670 (reg:PSI 22)))]
2671 "AVR_HAVE_MUL"
2672 "%~call __mulsqipsi3"
2673 [(set_attr "type" "xcall")
2674 (set_attr "cc" "clobber")])
2675
2676 (define_insn "*mulpsi3.libgcc"
2677 [(set (reg:PSI 22)
2678 (mult:PSI (reg:PSI 22)
2679 (reg:PSI 18)))
2680 (clobber (reg:QI 21))
2681 (clobber (reg:QI 25))
2682 (clobber (reg:HI 26))]
2683 "AVR_HAVE_MUL"
2684 "%~call __mulpsi3"
2685 [(set_attr "type" "xcall")
2686 (set_attr "cc" "clobber")])
2687
2688
2689 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2690 ;; 24-bit signed/unsigned division and modulo.
2691 ;; Notice that the libgcc implementation return the quotient in R22
2692 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2693 ;; implementation works the other way round.
2694
2695 (define_insn_and_split "divmodpsi4"
2696 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2697 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2698 (match_operand:PSI 2 "pseudo_register_operand" "")))
2699 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2700 (mod:PSI (match_dup 1)
2701 (match_dup 2)))
2702 (clobber (reg:DI 18))
2703 (clobber (reg:QI 26))])]
2704 ""
2705 { gcc_unreachable(); }
2706 ""
2707 [(set (reg:PSI 22) (match_dup 1))
2708 (set (reg:PSI 18) (match_dup 2))
2709 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2710 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2711 (clobber (reg:QI 21))
2712 (clobber (reg:QI 25))
2713 (clobber (reg:QI 26))])
2714 (set (match_dup 0) (reg:PSI 22))
2715 (set (match_dup 3) (reg:PSI 18))])
2716
2717 (define_insn "*divmodpsi4_call"
2718 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2719 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2720 (clobber (reg:QI 21))
2721 (clobber (reg:QI 25))
2722 (clobber (reg:QI 26))]
2723 ""
2724 "%~call __divmodpsi4"
2725 [(set_attr "type" "xcall")
2726 (set_attr "cc" "clobber")])
2727
2728 (define_insn_and_split "udivmodpsi4"
2729 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2730 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2731 (match_operand:PSI 2 "pseudo_register_operand" "")))
2732 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2733 (umod:PSI (match_dup 1)
2734 (match_dup 2)))
2735 (clobber (reg:DI 18))
2736 (clobber (reg:QI 26))])]
2737 ""
2738 { gcc_unreachable(); }
2739 ""
2740 [(set (reg:PSI 22) (match_dup 1))
2741 (set (reg:PSI 18) (match_dup 2))
2742 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2743 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2744 (clobber (reg:QI 21))
2745 (clobber (reg:QI 25))
2746 (clobber (reg:QI 26))])
2747 (set (match_dup 0) (reg:PSI 22))
2748 (set (match_dup 3) (reg:PSI 18))])
2749
2750 (define_insn "*udivmodpsi4_call"
2751 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2752 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2753 (clobber (reg:QI 21))
2754 (clobber (reg:QI 25))
2755 (clobber (reg:QI 26))]
2756 ""
2757 "%~call __udivmodpsi4"
2758 [(set_attr "type" "xcall")
2759 (set_attr "cc" "clobber")])
2760
2761 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2762
2763 (define_insn_and_split "divmodsi4"
2764 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2765 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2766 (match_operand:SI 2 "pseudo_register_operand" "")))
2767 (set (match_operand:SI 3 "pseudo_register_operand" "")
2768 (mod:SI (match_dup 1) (match_dup 2)))
2769 (clobber (reg:SI 18))
2770 (clobber (reg:SI 22))
2771 (clobber (reg:HI 26))
2772 (clobber (reg:HI 30))])]
2773 ""
2774 "this divmodsi4 pattern should have been splitted;"
2775 ""
2776 [(set (reg:SI 22) (match_dup 1))
2777 (set (reg:SI 18) (match_dup 2))
2778 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2779 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2780 (clobber (reg:HI 26))
2781 (clobber (reg:HI 30))])
2782 (set (match_dup 0) (reg:SI 18))
2783 (set (match_dup 3) (reg:SI 22))]
2784 "")
2785
2786 (define_insn "*divmodsi4_call"
2787 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2788 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2789 (clobber (reg:HI 26))
2790 (clobber (reg:HI 30))]
2791 ""
2792 "%~call __divmodsi4"
2793 [(set_attr "type" "xcall")
2794 (set_attr "cc" "clobber")])
2795
2796 (define_insn_and_split "udivmodsi4"
2797 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2798 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2799 (match_operand:SI 2 "pseudo_register_operand" "")))
2800 (set (match_operand:SI 3 "pseudo_register_operand" "")
2801 (umod:SI (match_dup 1) (match_dup 2)))
2802 (clobber (reg:SI 18))
2803 (clobber (reg:SI 22))
2804 (clobber (reg:HI 26))
2805 (clobber (reg:HI 30))])]
2806 ""
2807 "this udivmodsi4 pattern should have been splitted;"
2808 ""
2809 [(set (reg:SI 22) (match_dup 1))
2810 (set (reg:SI 18) (match_dup 2))
2811 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2812 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2813 (clobber (reg:HI 26))
2814 (clobber (reg:HI 30))])
2815 (set (match_dup 0) (reg:SI 18))
2816 (set (match_dup 3) (reg:SI 22))]
2817 "")
2818
2819 (define_insn "*udivmodsi4_call"
2820 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2821 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2822 (clobber (reg:HI 26))
2823 (clobber (reg:HI 30))]
2824 ""
2825 "%~call __udivmodsi4"
2826 [(set_attr "type" "xcall")
2827 (set_attr "cc" "clobber")])
2828
2829 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2830 ; and
2831
2832 (define_insn "andqi3"
2833 [(set (match_operand:QI 0 "register_operand" "=r,d")
2834 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2835 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2836 ""
2837 "@
2838 and %0,%2
2839 andi %0,lo8(%2)"
2840 [(set_attr "length" "1,1")
2841 (set_attr "cc" "set_zn,set_zn")])
2842
2843 (define_insn "andhi3"
2844 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2845 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2846 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2847 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2848 ""
2849 {
2850 if (which_alternative == 0)
2851 return "and %A0,%A2\;and %B0,%B2";
2852 else if (which_alternative == 1)
2853 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2854
2855 return avr_out_bitop (insn, operands, NULL);
2856 }
2857 [(set_attr "length" "2,2,2,4,4")
2858 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2859 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2860
2861 (define_insn "andpsi3"
2862 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2863 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2864 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2865 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2866 ""
2867 {
2868 if (which_alternative == 0)
2869 return "and %A0,%A2" CR_TAB
2870 "and %B0,%B2" CR_TAB
2871 "and %C0,%C2";
2872
2873 return avr_out_bitop (insn, operands, NULL);
2874 }
2875 [(set_attr "length" "3,3,6,6")
2876 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2877 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2878
2879 (define_insn "andsi3"
2880 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2881 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2882 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2883 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2884 ""
2885 {
2886 if (which_alternative == 0)
2887 return "and %0,%2" CR_TAB
2888 "and %B0,%B2" CR_TAB
2889 "and %C0,%C2" CR_TAB
2890 "and %D0,%D2";
2891
2892 return avr_out_bitop (insn, operands, NULL);
2893 }
2894 [(set_attr "length" "4,4,8,8")
2895 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2896 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2897
2898 (define_peephole2 ; andi
2899 [(set (match_operand:QI 0 "d_register_operand" "")
2900 (and:QI (match_dup 0)
2901 (match_operand:QI 1 "const_int_operand" "")))
2902 (set (match_dup 0)
2903 (and:QI (match_dup 0)
2904 (match_operand:QI 2 "const_int_operand" "")))]
2905 ""
2906 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2907 {
2908 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2909 })
2910
2911 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2912 ;; ior
2913
2914 (define_insn "iorqi3"
2915 [(set (match_operand:QI 0 "register_operand" "=r,d")
2916 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2917 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2918 ""
2919 "@
2920 or %0,%2
2921 ori %0,lo8(%2)"
2922 [(set_attr "length" "1,1")
2923 (set_attr "cc" "set_zn,set_zn")])
2924
2925 (define_insn "iorhi3"
2926 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2927 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2928 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2929 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2930 ""
2931 {
2932 if (which_alternative == 0)
2933 return "or %A0,%A2\;or %B0,%B2";
2934 else if (which_alternative == 1)
2935 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
2936
2937 return avr_out_bitop (insn, operands, NULL);
2938 }
2939 [(set_attr "length" "2,2,2,4,4")
2940 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2941 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2942
2943 (define_insn "iorpsi3"
2944 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2945 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2946 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
2947 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2948 ""
2949 {
2950 if (which_alternative == 0)
2951 return "or %A0,%A2" CR_TAB
2952 "or %B0,%B2" CR_TAB
2953 "or %C0,%C2";
2954
2955 return avr_out_bitop (insn, operands, NULL);
2956 }
2957 [(set_attr "length" "3,3,6,6")
2958 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2959 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2960
2961 (define_insn "iorsi3"
2962 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2963 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2964 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2965 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2966 ""
2967 {
2968 if (which_alternative == 0)
2969 return "or %0,%2" CR_TAB
2970 "or %B0,%B2" CR_TAB
2971 "or %C0,%C2" CR_TAB
2972 "or %D0,%D2";
2973
2974 return avr_out_bitop (insn, operands, NULL);
2975 }
2976 [(set_attr "length" "4,4,8,8")
2977 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2978 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2979
2980 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2981 ;; xor
2982
2983 (define_insn "xorqi3"
2984 [(set (match_operand:QI 0 "register_operand" "=r")
2985 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2986 (match_operand:QI 2 "register_operand" "r")))]
2987 ""
2988 "eor %0,%2"
2989 [(set_attr "length" "1")
2990 (set_attr "cc" "set_zn")])
2991
2992 (define_insn "xorhi3"
2993 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
2994 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
2995 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
2996 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2997 ""
2998 {
2999 if (which_alternative == 0)
3000 return "eor %A0,%A2\;eor %B0,%B2";
3001
3002 return avr_out_bitop (insn, operands, NULL);
3003 }
3004 [(set_attr "length" "2,2,4")
3005 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3006 (set_attr "cc" "set_n,clobber,clobber")])
3007
3008 (define_insn "xorpsi3"
3009 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3010 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3011 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3012 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3013 ""
3014 {
3015 if (which_alternative == 0)
3016 return "eor %A0,%A2" CR_TAB
3017 "eor %B0,%B2" CR_TAB
3018 "eor %C0,%C2";
3019
3020 return avr_out_bitop (insn, operands, NULL);
3021 }
3022 [(set_attr "length" "3,6,6")
3023 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3024 (set_attr "cc" "set_n,clobber,clobber")])
3025
3026 (define_insn "xorsi3"
3027 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3028 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3029 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3030 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3031 ""
3032 {
3033 if (which_alternative == 0)
3034 return "eor %0,%2" CR_TAB
3035 "eor %B0,%B2" CR_TAB
3036 "eor %C0,%C2" CR_TAB
3037 "eor %D0,%D2";
3038
3039 return avr_out_bitop (insn, operands, NULL);
3040 }
3041 [(set_attr "length" "4,8,8")
3042 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3043 (set_attr "cc" "set_n,clobber,clobber")])
3044
3045 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3046 ;; swap
3047
3048 (define_expand "rotlqi3"
3049 [(set (match_operand:QI 0 "register_operand" "")
3050 (rotate:QI (match_operand:QI 1 "register_operand" "")
3051 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3052 ""
3053 {
3054 if (!CONST_INT_P (operands[2]))
3055 FAIL;
3056
3057 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3058 })
3059
3060 ;; Expander used by __builtin_avr_swap
3061 (define_expand "rotlqi3_4"
3062 [(set (match_operand:QI 0 "register_operand" "")
3063 (rotate:QI (match_operand:QI 1 "register_operand" "")
3064 (const_int 4)))])
3065
3066 (define_insn "*rotlqi3"
3067 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3068 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3069 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3070 ""
3071 "@
3072 lsl %0\;adc %0,__zero_reg__
3073 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3074 swap %0\;bst %0,0\;ror %0\;bld %0,7
3075 swap %0
3076 swap %0\;lsl %0\;adc %0,__zero_reg__
3077 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3078 bst %0,0\;ror %0\;bld %0,7
3079 "
3080 [(set_attr "length" "2,4,4,1,3,5,3,0")
3081 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3082
3083 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3084 ;; a whole number of bytes. The split creates the appropriate moves and
3085 ;; considers all overlap situations.
3086
3087 ;; HImode does not need scratch. Use attribute for this constraint.
3088
3089 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3090 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3091
3092 ;; "rotlhi3"
3093 ;; "rotlpsi3"
3094 ;; "rotlsi3"
3095 (define_expand "rotl<mode>3"
3096 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3097 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3098 (match_operand:VOID 2 "const_int_operand" "")))
3099 (clobber (match_dup 3))])]
3100 ""
3101 {
3102 int offset;
3103
3104 if (!CONST_INT_P (operands[2]))
3105 FAIL;
3106
3107 offset = INTVAL (operands[2]);
3108
3109 if (0 == offset % 8)
3110 {
3111 if (AVR_HAVE_MOVW && 0 == offset % 16)
3112 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3113 else
3114 operands[3] = gen_rtx_SCRATCH (QImode);
3115 }
3116 else if (offset == 1
3117 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3118 {
3119 /*; Support rotate left/right by 1 */
3120
3121 emit_move_insn (operands[0],
3122 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3123 DONE;
3124 }
3125 else
3126 FAIL;
3127 })
3128
3129 (define_insn "*rotlhi2.1"
3130 [(set (match_operand:HI 0 "register_operand" "=r")
3131 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3132 (const_int 1)))]
3133 ""
3134 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3135 [(set_attr "length" "3")
3136 (set_attr "cc" "clobber")])
3137
3138 (define_insn "*rotlhi2.15"
3139 [(set (match_operand:HI 0 "register_operand" "=r")
3140 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3141 (const_int 15)))]
3142 ""
3143 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3144 [(set_attr "length" "4")
3145 (set_attr "cc" "clobber")])
3146
3147 (define_insn "*rotlpsi2.1"
3148 [(set (match_operand:PSI 0 "register_operand" "=r")
3149 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3150 (const_int 1)))]
3151 ""
3152 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3153 [(set_attr "length" "4")
3154 (set_attr "cc" "clobber")])
3155
3156 (define_insn "*rotlpsi2.23"
3157 [(set (match_operand:PSI 0 "register_operand" "=r")
3158 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3159 (const_int 23)))]
3160 ""
3161 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3162 [(set_attr "length" "5")
3163 (set_attr "cc" "clobber")])
3164
3165 (define_insn "*rotlsi2.1"
3166 [(set (match_operand:SI 0 "register_operand" "=r")
3167 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3168 (const_int 1)))]
3169 ""
3170 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3171 [(set_attr "length" "5")
3172 (set_attr "cc" "clobber")])
3173
3174 (define_insn "*rotlsi2.31"
3175 [(set (match_operand:SI 0 "register_operand" "=r")
3176 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3177 (const_int 31)))]
3178 ""
3179 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3180 [(set_attr "length" "6")
3181 (set_attr "cc" "clobber")])
3182
3183 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3184 ;; The best we can do is use early clobber alternative "#&r" so that
3185 ;; completely non-overlapping operands dont get a scratch but # so register
3186 ;; allocation does not prefer non-overlapping.
3187
3188
3189 ;; Split word aligned rotates using scratch that is mode dependent.
3190
3191 ;; "*rotwhi"
3192 ;; "*rotwsi"
3193 (define_insn_and_split "*rotw<mode>"
3194 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3195 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3196 (match_operand 2 "const_int_operand" "n,n,n")))
3197 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3198 "AVR_HAVE_MOVW
3199 && CONST_INT_P (operands[2])
3200 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3201 && 0 == INTVAL (operands[2]) % 16"
3202 "#"
3203 "&& reload_completed"
3204 [(const_int 0)]
3205 {
3206 avr_rotate_bytes (operands);
3207 DONE;
3208 })
3209
3210
3211 ;; Split byte aligned rotates using scratch that is always QI mode.
3212
3213 ;; "*rotbhi"
3214 ;; "*rotbpsi"
3215 ;; "*rotbsi"
3216 (define_insn_and_split "*rotb<mode>"
3217 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3218 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3219 (match_operand 2 "const_int_operand" "n,n,n")))
3220 (clobber (match_scratch:QI 3 "=<rotx>"))]
3221 "CONST_INT_P (operands[2])
3222 && (8 == INTVAL (operands[2]) % 16
3223 || ((!AVR_HAVE_MOVW
3224 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3225 && 0 == INTVAL (operands[2]) % 16))"
3226 "#"
3227 "&& reload_completed"
3228 [(const_int 0)]
3229 {
3230 avr_rotate_bytes (operands);
3231 DONE;
3232 })
3233
3234
3235 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3236 ;; arithmetic shift left
3237
3238 (define_expand "ashlqi3"
3239 [(set (match_operand:QI 0 "register_operand" "")
3240 (ashift:QI (match_operand:QI 1 "register_operand" "")
3241 (match_operand:QI 2 "nop_general_operand" "")))])
3242
3243 (define_split ; ashlqi3_const4
3244 [(set (match_operand:QI 0 "d_register_operand" "")
3245 (ashift:QI (match_dup 0)
3246 (const_int 4)))]
3247 ""
3248 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3249 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
3250 "")
3251
3252 (define_split ; ashlqi3_const5
3253 [(set (match_operand:QI 0 "d_register_operand" "")
3254 (ashift:QI (match_dup 0)
3255 (const_int 5)))]
3256 ""
3257 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3258 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3259 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
3260 "")
3261
3262 (define_split ; ashlqi3_const6
3263 [(set (match_operand:QI 0 "d_register_operand" "")
3264 (ashift:QI (match_dup 0)
3265 (const_int 6)))]
3266 ""
3267 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3268 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3269 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
3270 "")
3271
3272 (define_insn "*ashlqi3"
3273 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3274 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3275 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3276 ""
3277 {
3278 return ashlqi3_out (insn, operands, NULL);
3279 }
3280 [(set_attr "length" "5,0,1,2,4,6,9")
3281 (set_attr "adjust_len" "ashlqi")
3282 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3283
3284 (define_insn "ashlhi3"
3285 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3286 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3287 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3288 ""
3289 {
3290 return ashlhi3_out (insn, operands, NULL);
3291 }
3292 [(set_attr "length" "6,0,2,2,4,10,10")
3293 (set_attr "adjust_len" "ashlhi")
3294 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3295
3296
3297 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3298 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3299
3300 ;; "*ashluqihiqi3"
3301 ;; "*ashlsqihiqi3"
3302 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3303 [(set (match_operand:QI 0 "register_operand" "=r")
3304 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3305 (match_operand:QI 2 "register_operand" "r"))
3306 0))]
3307 ""
3308 "#"
3309 ""
3310 [(set (match_dup 0)
3311 (ashift:QI (match_dup 1)
3312 (match_dup 2)))]
3313 "")
3314
3315 ;; ??? Combiner does not recognize that it could split the following insn;
3316 ;; presumably because he has no register handy?
3317
3318 ;; "*ashluqihiqi3.mem"
3319 ;; "*ashlsqihiqi3.mem"
3320 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3321 [(set (match_operand:QI 0 "memory_operand" "=m")
3322 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3323 (match_operand:QI 2 "register_operand" "r"))
3324 0))]
3325 "!reload_completed"
3326 { gcc_unreachable(); }
3327 "&& 1"
3328 [(set (match_dup 3)
3329 (ashift:QI (match_dup 1)
3330 (match_dup 2)))
3331 (set (match_dup 0)
3332 (match_dup 3))]
3333 {
3334 operands[3] = gen_reg_rtx (QImode);
3335 })
3336
3337 ;; Similar.
3338
3339 (define_insn_and_split "*ashlhiqi3"
3340 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3341 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3342 (match_operand:QI 2 "register_operand" "r")) 0))]
3343 "!reload_completed"
3344 { gcc_unreachable(); }
3345 "&& 1"
3346 [(set (match_dup 4)
3347 (ashift:QI (match_dup 3)
3348 (match_dup 2)))
3349 (set (match_dup 0)
3350 (match_dup 4))]
3351 {
3352 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3353 operands[4] = gen_reg_rtx (QImode);
3354 })
3355
3356 ;; High part of 16-bit shift is unused after the instruction:
3357 ;; No need to compute it, map to 8-bit shift.
3358
3359 (define_peephole2
3360 [(set (match_operand:HI 0 "register_operand" "")
3361 (ashift:HI (match_dup 0)
3362 (match_operand:QI 1 "register_operand" "")))]
3363 ""
3364 [(set (match_dup 2)
3365 (ashift:QI (match_dup 2)
3366 (match_dup 1)))
3367 (clobber (match_dup 3))]
3368 {
3369 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3370
3371 if (!peep2_reg_dead_p (1, operands[3]))
3372 FAIL;
3373
3374 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3375 })
3376
3377
3378 (define_insn "ashlsi3"
3379 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3380 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3381 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3382 ""
3383 {
3384 return ashlsi3_out (insn, operands, NULL);
3385 }
3386 [(set_attr "length" "8,0,4,4,8,10,12")
3387 (set_attr "adjust_len" "ashlsi")
3388 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3389
3390 ;; Optimize if a scratch register from LD_REGS happens to be available.
3391
3392 (define_peephole2 ; ashlqi3_l_const4
3393 [(set (match_operand:QI 0 "l_register_operand" "")
3394 (ashift:QI (match_dup 0)
3395 (const_int 4)))
3396 (match_scratch:QI 1 "d")]
3397 ""
3398 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3399 (set (match_dup 1) (const_int -16))
3400 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3401 "")
3402
3403 (define_peephole2 ; ashlqi3_l_const5
3404 [(set (match_operand:QI 0 "l_register_operand" "")
3405 (ashift:QI (match_dup 0)
3406 (const_int 5)))
3407 (match_scratch:QI 1 "d")]
3408 ""
3409 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3410 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3411 (set (match_dup 1) (const_int -32))
3412 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3413 "")
3414
3415 (define_peephole2 ; ashlqi3_l_const6
3416 [(set (match_operand:QI 0 "l_register_operand" "")
3417 (ashift:QI (match_dup 0)
3418 (const_int 6)))
3419 (match_scratch:QI 1 "d")]
3420 ""
3421 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3422 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3423 (set (match_dup 1) (const_int -64))
3424 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3425 "")
3426
3427 (define_peephole2
3428 [(match_scratch:QI 3 "d")
3429 (set (match_operand:HI 0 "register_operand" "")
3430 (ashift:HI (match_operand:HI 1 "register_operand" "")
3431 (match_operand:QI 2 "const_int_operand" "")))]
3432 ""
3433 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3434 (clobber (match_dup 3))])]
3435 "")
3436
3437 (define_insn "*ashlhi3_const"
3438 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3439 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3440 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3441 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3442 "reload_completed"
3443 {
3444 return ashlhi3_out (insn, operands, NULL);
3445 }
3446 [(set_attr "length" "0,2,2,4,10")
3447 (set_attr "adjust_len" "ashlhi")
3448 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3449
3450 (define_peephole2
3451 [(match_scratch:QI 3 "d")
3452 (set (match_operand:SI 0 "register_operand" "")
3453 (ashift:SI (match_operand:SI 1 "register_operand" "")
3454 (match_operand:QI 2 "const_int_operand" "")))]
3455 ""
3456 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3457 (clobber (match_dup 3))])]
3458 "")
3459
3460 (define_insn "*ashlsi3_const"
3461 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3462 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3463 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3464 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3465 "reload_completed"
3466 {
3467 return ashlsi3_out (insn, operands, NULL);
3468 }
3469 [(set_attr "length" "0,4,4,10")
3470 (set_attr "adjust_len" "ashlsi")
3471 (set_attr "cc" "none,set_n,clobber,clobber")])
3472
3473 (define_expand "ashlpsi3"
3474 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3475 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3476 (match_operand:QI 2 "nonmemory_operand" "")))
3477 (clobber (scratch:QI))])]
3478 ""
3479 {
3480 if (AVR_HAVE_MUL
3481 && CONST_INT_P (operands[2]))
3482 {
3483 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3484 {
3485 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3486 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3487 DONE;
3488 }
3489 else if (optimize_insn_for_speed_p ()
3490 && INTVAL (operands[2]) != 16
3491 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3492 {
3493 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3494 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3495 DONE;
3496 }
3497 }
3498 })
3499
3500 (define_insn "*ashlpsi3"
3501 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3502 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3503 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3504 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3505 ""
3506 {
3507 return avr_out_ashlpsi3 (insn, operands, NULL);
3508 }
3509 [(set_attr "adjust_len" "ashlpsi")
3510 (set_attr "cc" "clobber")])
3511
3512 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3513 ;; arithmetic shift right
3514
3515 (define_insn "ashrqi3"
3516 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3517 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3518 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3519 ""
3520 {
3521 return ashrqi3_out (insn, operands, NULL);
3522 }
3523 [(set_attr "length" "5,0,1,2,5,4,9")
3524 (set_attr "adjust_len" "ashrqi")
3525 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3526
3527 (define_insn "ashrhi3"
3528 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3529 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3530 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3531 ""
3532 {
3533 return ashrhi3_out (insn, operands, NULL);
3534 }
3535 [(set_attr "length" "6,0,2,4,4,10,10")
3536 (set_attr "adjust_len" "ashrhi")
3537 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3538
3539 (define_insn "ashrpsi3"
3540 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3541 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3542 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3543 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3544 ""
3545 {
3546 return avr_out_ashrpsi3 (insn, operands, NULL);
3547 }
3548 [(set_attr "adjust_len" "ashrpsi")
3549 (set_attr "cc" "clobber")])
3550
3551 (define_insn "ashrsi3"
3552 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3553 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3554 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3555 ""
3556 {
3557 return ashrsi3_out (insn, operands, NULL);
3558 }
3559 [(set_attr "length" "8,0,4,6,8,10,12")
3560 (set_attr "adjust_len" "ashrsi")
3561 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3562
3563 ;; Optimize if a scratch register from LD_REGS happens to be available.
3564
3565 (define_peephole2
3566 [(match_scratch:QI 3 "d")
3567 (set (match_operand:HI 0 "register_operand" "")
3568 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3569 (match_operand:QI 2 "const_int_operand" "")))]
3570 ""
3571 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3572 (clobber (match_dup 3))])]
3573 "")
3574
3575 (define_insn "*ashrhi3_const"
3576 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3577 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3578 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3579 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3580 "reload_completed"
3581 {
3582 return ashrhi3_out (insn, operands, NULL);
3583 }
3584 [(set_attr "length" "0,2,4,4,10")
3585 (set_attr "adjust_len" "ashrhi")
3586 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3587
3588 (define_peephole2
3589 [(match_scratch:QI 3 "d")
3590 (set (match_operand:SI 0 "register_operand" "")
3591 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3592 (match_operand:QI 2 "const_int_operand" "")))]
3593 ""
3594 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3595 (clobber (match_dup 3))])]
3596 "")
3597
3598 (define_insn "*ashrsi3_const"
3599 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3600 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3601 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3602 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3603 "reload_completed"
3604 {
3605 return ashrsi3_out (insn, operands, NULL);
3606 }
3607 [(set_attr "length" "0,4,4,10")
3608 (set_attr "adjust_len" "ashrsi")
3609 (set_attr "cc" "none,clobber,set_n,clobber")])
3610
3611 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3612 ;; logical shift right
3613
3614 (define_expand "lshrqi3"
3615 [(set (match_operand:QI 0 "register_operand" "")
3616 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3617 (match_operand:QI 2 "nop_general_operand" "")))])
3618
3619 (define_split ; lshrqi3_const4
3620 [(set (match_operand:QI 0 "d_register_operand" "")
3621 (lshiftrt:QI (match_dup 0)
3622 (const_int 4)))]
3623 ""
3624 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3625 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3626 "")
3627
3628 (define_split ; lshrqi3_const5
3629 [(set (match_operand:QI 0 "d_register_operand" "")
3630 (lshiftrt:QI (match_dup 0)
3631 (const_int 5)))]
3632 ""
3633 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3634 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3635 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3636 "")
3637
3638 (define_split ; lshrqi3_const6
3639 [(set (match_operand:QI 0 "d_register_operand" "")
3640 (lshiftrt:QI (match_dup 0)
3641 (const_int 6)))]
3642 ""
3643 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3644 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3645 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3646 "")
3647
3648 (define_insn "*lshrqi3"
3649 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3650 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3651 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3652 ""
3653 {
3654 return lshrqi3_out (insn, operands, NULL);
3655 }
3656 [(set_attr "length" "5,0,1,2,4,6,9")
3657 (set_attr "adjust_len" "lshrqi")
3658 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3659
3660 (define_insn "lshrhi3"
3661 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3662 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3663 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3664 ""
3665 {
3666 return lshrhi3_out (insn, operands, NULL);
3667 }
3668 [(set_attr "length" "6,0,2,2,4,10,10")
3669 (set_attr "adjust_len" "lshrhi")
3670 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3671
3672 (define_insn "lshrpsi3"
3673 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3674 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3675 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3676 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3677 ""
3678 {
3679 return avr_out_lshrpsi3 (insn, operands, NULL);
3680 }
3681 [(set_attr "adjust_len" "lshrpsi")
3682 (set_attr "cc" "clobber")])
3683
3684 (define_insn "lshrsi3"
3685 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3686 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3687 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3688 ""
3689 {
3690 return lshrsi3_out (insn, operands, NULL);
3691 }
3692 [(set_attr "length" "8,0,4,4,8,10,12")
3693 (set_attr "adjust_len" "lshrsi")
3694 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3695
3696 ;; Optimize if a scratch register from LD_REGS happens to be available.
3697
3698 (define_peephole2 ; lshrqi3_l_const4
3699 [(set (match_operand:QI 0 "l_register_operand" "")
3700 (lshiftrt:QI (match_dup 0)
3701 (const_int 4)))
3702 (match_scratch:QI 1 "d")]
3703 ""
3704 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3705 (set (match_dup 1) (const_int 15))
3706 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3707 "")
3708
3709 (define_peephole2 ; lshrqi3_l_const5
3710 [(set (match_operand:QI 0 "l_register_operand" "")
3711 (lshiftrt:QI (match_dup 0)
3712 (const_int 5)))
3713 (match_scratch:QI 1 "d")]
3714 ""
3715 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3716 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3717 (set (match_dup 1) (const_int 7))
3718 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3719 "")
3720
3721 (define_peephole2 ; lshrqi3_l_const6
3722 [(set (match_operand:QI 0 "l_register_operand" "")
3723 (lshiftrt:QI (match_dup 0)
3724 (const_int 6)))
3725 (match_scratch:QI 1 "d")]
3726 ""
3727 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3728 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3729 (set (match_dup 1) (const_int 3))
3730 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3731 "")
3732
3733 (define_peephole2
3734 [(match_scratch:QI 3 "d")
3735 (set (match_operand:HI 0 "register_operand" "")
3736 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3737 (match_operand:QI 2 "const_int_operand" "")))]
3738 ""
3739 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3740 (clobber (match_dup 3))])]
3741 "")
3742
3743 (define_insn "*lshrhi3_const"
3744 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3745 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3746 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3747 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3748 "reload_completed"
3749 {
3750 return lshrhi3_out (insn, operands, NULL);
3751 }
3752 [(set_attr "length" "0,2,2,4,10")
3753 (set_attr "adjust_len" "lshrhi")
3754 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3755
3756 (define_peephole2
3757 [(match_scratch:QI 3 "d")
3758 (set (match_operand:SI 0 "register_operand" "")
3759 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3760 (match_operand:QI 2 "const_int_operand" "")))]
3761 ""
3762 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3763 (clobber (match_dup 3))])]
3764 "")
3765
3766 (define_insn "*lshrsi3_const"
3767 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3768 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3769 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3770 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3771 "reload_completed"
3772 {
3773 return lshrsi3_out (insn, operands, NULL);
3774 }
3775 [(set_attr "length" "0,4,4,10")
3776 (set_attr "adjust_len" "lshrsi")
3777 (set_attr "cc" "none,clobber,clobber,clobber")])
3778
3779 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3780 ;; abs
3781
3782 (define_insn "absqi2"
3783 [(set (match_operand:QI 0 "register_operand" "=r")
3784 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3785 ""
3786 "sbrc %0,7
3787 neg %0"
3788 [(set_attr "length" "2")
3789 (set_attr "cc" "clobber")])
3790
3791
3792 (define_insn "abssf2"
3793 [(set (match_operand:SF 0 "register_operand" "=d,r")
3794 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3795 ""
3796 "@
3797 andi %D0,0x7f
3798 clt\;bld %D0,7"
3799 [(set_attr "length" "1,2")
3800 (set_attr "cc" "set_n,clobber")])
3801
3802 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3803 ;; neg
3804
3805 (define_insn "negqi2"
3806 [(set (match_operand:QI 0 "register_operand" "=r")
3807 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3808 ""
3809 "neg %0"
3810 [(set_attr "length" "1")
3811 (set_attr "cc" "set_zn")])
3812
3813 (define_insn "*negqihi2"
3814 [(set (match_operand:HI 0 "register_operand" "=r")
3815 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3816 ""
3817 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3818 [(set_attr "length" "4")
3819 (set_attr "cc" "set_n")])
3820
3821 (define_insn "neghi2"
3822 [(set (match_operand:HI 0 "register_operand" "=r,&r")
3823 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
3824 ""
3825 "@
3826 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
3827 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3828 [(set_attr "length" "3,4")
3829 (set_attr "cc" "set_czn")])
3830
3831 (define_insn "negpsi2"
3832 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3833 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3834 ""
3835 "@
3836 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3837 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3838 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3839 [(set_attr "length" "5,6,6")
3840 (set_attr "cc" "set_czn,set_n,set_czn")])
3841
3842 (define_insn "negsi2"
3843 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3844 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
3845 ""
3846 "@
3847 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3848 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3849 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3850 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3851 [(set_attr "length" "7,8,8,7")
3852 (set_attr "isa" "*,*,mov,movw")
3853 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
3854
3855 (define_insn "negsf2"
3856 [(set (match_operand:SF 0 "register_operand" "=d,r")
3857 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3858 ""
3859 "@
3860 subi %D0,0x80
3861 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3862 [(set_attr "length" "1,4")
3863 (set_attr "cc" "set_n,set_n")])
3864
3865 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3866 ;; not
3867
3868 (define_insn "one_cmplqi2"
3869 [(set (match_operand:QI 0 "register_operand" "=r")
3870 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3871 ""
3872 "com %0"
3873 [(set_attr "length" "1")
3874 (set_attr "cc" "set_czn")])
3875
3876 (define_insn "one_cmplhi2"
3877 [(set (match_operand:HI 0 "register_operand" "=r")
3878 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3879 ""
3880 "com %0
3881 com %B0"
3882 [(set_attr "length" "2")
3883 (set_attr "cc" "set_n")])
3884
3885 (define_insn "one_cmplpsi2"
3886 [(set (match_operand:PSI 0 "register_operand" "=r")
3887 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3888 ""
3889 "com %0\;com %B0\;com %C0"
3890 [(set_attr "length" "3")
3891 (set_attr "cc" "set_n")])
3892
3893 (define_insn "one_cmplsi2"
3894 [(set (match_operand:SI 0 "register_operand" "=r")
3895 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3896 ""
3897 "com %0
3898 com %B0
3899 com %C0
3900 com %D0"
3901 [(set_attr "length" "4")
3902 (set_attr "cc" "set_n")])
3903
3904 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3905 ;; sign extend
3906
3907 ;; We keep combiner from inserting hard registers into the input of sign- and
3908 ;; zero-extends. A hard register in the input operand is not wanted because
3909 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3910 ;; hard register that overlaps these clobbers won't be combined to a widening
3911 ;; multiplication. There is no need for combine to propagate hard registers,
3912 ;; register allocation can do it just as well.
3913
3914 (define_insn "extendqihi2"
3915 [(set (match_operand:HI 0 "register_operand" "=r,r")
3916 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3917 ""
3918 "@
3919 clr %B0\;sbrc %0,7\;com %B0
3920 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3921 [(set_attr "length" "3,4")
3922 (set_attr "cc" "set_n,set_n")])
3923
3924 (define_insn "extendqipsi2"
3925 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3926 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3927 ""
3928 "@
3929 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3930 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3931 [(set_attr "length" "4,5")
3932 (set_attr "cc" "set_n,set_n")])
3933
3934 (define_insn "extendqisi2"
3935 [(set (match_operand:SI 0 "register_operand" "=r,r")
3936 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3937 ""
3938 "@
3939 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3940 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3941 [(set_attr "length" "5,6")
3942 (set_attr "cc" "set_n,set_n")])
3943
3944 (define_insn "extendhipsi2"
3945 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3946 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3947 ""
3948 "@
3949 clr %C0\;sbrc %B0,7\;com %C0
3950 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
3951 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
3952 [(set_attr "length" "3,5,4")
3953 (set_attr "isa" "*,mov,movw")
3954 (set_attr "cc" "set_n")])
3955
3956 (define_insn "extendhisi2"
3957 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3958 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3959 ""
3960 "@
3961 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3962 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3963 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3964 [(set_attr "length" "4,6,5")
3965 (set_attr "isa" "*,mov,movw")
3966 (set_attr "cc" "set_n")])
3967
3968 (define_insn "extendpsisi2"
3969 [(set (match_operand:SI 0 "register_operand" "=r")
3970 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
3971 ""
3972 "clr %D0\;sbrc %C0,7\;com %D0"
3973 [(set_attr "length" "3")
3974 (set_attr "cc" "set_n")])
3975
3976 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3977 ;; zero extend
3978
3979 (define_insn_and_split "zero_extendqihi2"
3980 [(set (match_operand:HI 0 "register_operand" "=r")
3981 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3982 ""
3983 "#"
3984 "reload_completed"
3985 [(set (match_dup 2) (match_dup 1))
3986 (set (match_dup 3) (const_int 0))]
3987 {
3988 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
3989 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
3990
3991 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
3992 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
3993 })
3994
3995 (define_insn_and_split "zero_extendqipsi2"
3996 [(set (match_operand:PSI 0 "register_operand" "=r")
3997 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3998 ""
3999 "#"
4000 "reload_completed"
4001 [(set (match_dup 2) (match_dup 1))
4002 (set (match_dup 3) (const_int 0))
4003 (set (match_dup 4) (const_int 0))]
4004 {
4005 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4006 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4007 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4008 })
4009
4010 (define_insn_and_split "zero_extendqisi2"
4011 [(set (match_operand:SI 0 "register_operand" "=r")
4012 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4013 ""
4014 "#"
4015 "reload_completed"
4016 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4017 (set (match_dup 3) (const_int 0))]
4018 {
4019 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4020 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4021
4022 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4023 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4024 })
4025
4026 (define_insn_and_split "zero_extendhipsi2"
4027 [(set (match_operand:PSI 0 "register_operand" "=r")
4028 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4029 ""
4030 "#"
4031 "reload_completed"
4032 [(set (match_dup 2) (match_dup 1))
4033 (set (match_dup 3) (const_int 0))]
4034 {
4035 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4036 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4037 })
4038
4039 (define_insn_and_split "n_extendhipsi2"
4040 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4041 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4042 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4043 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4044 ""
4045 "#"
4046 "reload_completed"
4047 [(set (match_dup 4) (match_dup 2))
4048 (set (match_dup 3) (match_dup 6))
4049 ; no-op move in the case where no scratch is needed
4050 (set (match_dup 5) (match_dup 3))]
4051 {
4052 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4053 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4054 operands[6] = operands[1];
4055
4056 if (GET_CODE (operands[3]) == SCRATCH)
4057 operands[3] = operands[5];
4058 })
4059
4060 (define_insn_and_split "zero_extendhisi2"
4061 [(set (match_operand:SI 0 "register_operand" "=r")
4062 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4063 ""
4064 "#"
4065 "reload_completed"
4066 [(set (match_dup 2) (match_dup 1))
4067 (set (match_dup 3) (const_int 0))]
4068 {
4069 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4070 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4071
4072 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4073 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4074 })
4075
4076 (define_insn_and_split "zero_extendpsisi2"
4077 [(set (match_operand:SI 0 "register_operand" "=r")
4078 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4079 ""
4080 "#"
4081 "reload_completed"
4082 [(set (match_dup 2) (match_dup 1))
4083 (set (match_dup 3) (const_int 0))]
4084 {
4085 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4086 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4087 })
4088
4089 (define_insn_and_split "zero_extendqidi2"
4090 [(set (match_operand:DI 0 "register_operand" "=r")
4091 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4092 ""
4093 "#"
4094 "reload_completed"
4095 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4096 (set (match_dup 3) (const_int 0))]
4097 {
4098 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4099 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4100
4101 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4102 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4103 })
4104
4105 (define_insn_and_split "zero_extendhidi2"
4106 [(set (match_operand:DI 0 "register_operand" "=r")
4107 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4108 ""
4109 "#"
4110 "reload_completed"
4111 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4112 (set (match_dup 3) (const_int 0))]
4113 {
4114 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4115 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4116
4117 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4118 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4119 })
4120
4121 (define_insn_and_split "zero_extendsidi2"
4122 [(set (match_operand:DI 0 "register_operand" "=r")
4123 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4124 ""
4125 "#"
4126 "reload_completed"
4127 [(set (match_dup 2) (match_dup 1))
4128 (set (match_dup 3) (const_int 0))]
4129 {
4130 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4131 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4132
4133 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4134 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4135 })
4136
4137 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4138 ;; compare
4139
4140 ; Optimize negated tests into reverse compare if overflow is undefined.
4141 (define_insn "*negated_tstqi"
4142 [(set (cc0)
4143 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4144 (const_int 0)))]
4145 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4146 "cp __zero_reg__,%0"
4147 [(set_attr "cc" "compare")
4148 (set_attr "length" "1")])
4149
4150 (define_insn "*reversed_tstqi"
4151 [(set (cc0)
4152 (compare (const_int 0)
4153 (match_operand:QI 0 "register_operand" "r")))]
4154 ""
4155 "cp __zero_reg__,%0"
4156 [(set_attr "cc" "compare")
4157 (set_attr "length" "2")])
4158
4159 (define_insn "*negated_tsthi"
4160 [(set (cc0)
4161 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4162 (const_int 0)))]
4163 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4164 "cp __zero_reg__,%A0
4165 cpc __zero_reg__,%B0"
4166 [(set_attr "cc" "compare")
4167 (set_attr "length" "2")])
4168
4169 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4170 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4171 (define_insn "*reversed_tsthi"
4172 [(set (cc0)
4173 (compare (const_int 0)
4174 (match_operand:HI 0 "register_operand" "r")))
4175 (clobber (match_scratch:QI 1 "=X"))]
4176 ""
4177 "cp __zero_reg__,%A0
4178 cpc __zero_reg__,%B0"
4179 [(set_attr "cc" "compare")
4180 (set_attr "length" "2")])
4181
4182 (define_insn "*negated_tstpsi"
4183 [(set (cc0)
4184 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4185 (const_int 0)))]
4186 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4187 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4188 [(set_attr "cc" "compare")
4189 (set_attr "length" "3")])
4190
4191 (define_insn "*reversed_tstpsi"
4192 [(set (cc0)
4193 (compare (const_int 0)
4194 (match_operand:PSI 0 "register_operand" "r")))
4195 (clobber (match_scratch:QI 1 "=X"))]
4196 ""
4197 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4198 [(set_attr "cc" "compare")
4199 (set_attr "length" "3")])
4200
4201 (define_insn "*negated_tstsi"
4202 [(set (cc0)
4203 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4204 (const_int 0)))]
4205 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4206 "cp __zero_reg__,%A0
4207 cpc __zero_reg__,%B0
4208 cpc __zero_reg__,%C0
4209 cpc __zero_reg__,%D0"
4210 [(set_attr "cc" "compare")
4211 (set_attr "length" "4")])
4212
4213 (define_insn "*reversed_tstsi"
4214 [(set (cc0)
4215 (compare (const_int 0)
4216 (match_operand:SI 0 "register_operand" "r")))
4217 (clobber (match_scratch:QI 1 "=X"))]
4218 ""
4219 "cp __zero_reg__,%A0
4220 cpc __zero_reg__,%B0
4221 cpc __zero_reg__,%C0
4222 cpc __zero_reg__,%D0"
4223 [(set_attr "cc" "compare")
4224 (set_attr "length" "4")])
4225
4226
4227 (define_insn "*cmpqi"
4228 [(set (cc0)
4229 (compare (match_operand:QI 0 "register_operand" "r,r,d")
4230 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
4231 ""
4232 "@
4233 tst %0
4234 cp %0,%1
4235 cpi %0,lo8(%1)"
4236 [(set_attr "cc" "compare,compare,compare")
4237 (set_attr "length" "1,1,1")])
4238
4239 (define_insn "*cmpqi_sign_extend"
4240 [(set (cc0)
4241 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4242 (match_operand:HI 1 "s8_operand" "n")))]
4243 ""
4244 "cpi %0,lo8(%1)"
4245 [(set_attr "cc" "compare")
4246 (set_attr "length" "1")])
4247
4248 (define_insn "*cmphi"
4249 [(set (cc0)
4250 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
4251 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
4252 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
4253 ""
4254 {
4255 switch (which_alternative)
4256 {
4257 case 0:
4258 case 1:
4259 return avr_out_tsthi (insn, operands, NULL);
4260
4261 case 2:
4262 return "cp %A0,%A1\;cpc %B0,%B1";
4263
4264 case 3:
4265 return reg_unused_after (insn, operands[0])
4266 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4267 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4268
4269 case 4:
4270 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4271 }
4272
4273 return avr_out_compare (insn, operands, NULL);
4274 }
4275 [(set_attr "cc" "compare")
4276 (set_attr "length" "1,2,2,3,4,2,4")
4277 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4278
4279 (define_insn "*cmppsi"
4280 [(set (cc0)
4281 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4282 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4283 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4284 ""
4285 {
4286 switch (which_alternative)
4287 {
4288 case 0:
4289 return avr_out_tstpsi (insn, operands, NULL);
4290
4291 case 1:
4292 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4293
4294 case 2:
4295 return reg_unused_after (insn, operands[0])
4296 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4297 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4298
4299 case 3:
4300 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4301 }
4302
4303 return avr_out_compare (insn, operands, NULL);
4304 }
4305 [(set_attr "cc" "compare")
4306 (set_attr "length" "3,3,5,6,3,7")
4307 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4308
4309 (define_insn "*cmpsi"
4310 [(set (cc0)
4311 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
4312 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
4313 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
4314 ""
4315 {
4316 if (0 == which_alternative)
4317 return avr_out_tstsi (insn, operands, NULL);
4318 else if (1 == which_alternative)
4319 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4320
4321 return avr_out_compare (insn, operands, NULL);
4322 }
4323 [(set_attr "cc" "compare")
4324 (set_attr "length" "4,4,4,5,8")
4325 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4326
4327
4328 ;; ----------------------------------------------------------------------
4329 ;; JUMP INSTRUCTIONS
4330 ;; ----------------------------------------------------------------------
4331 ;; Conditional jump instructions
4332
4333 (define_expand "cbranchsi4"
4334 [(parallel [(set (cc0)
4335 (compare (match_operand:SI 1 "register_operand" "")
4336 (match_operand:SI 2 "nonmemory_operand" "")))
4337 (clobber (match_scratch:QI 4 ""))])
4338 (set (pc)
4339 (if_then_else
4340 (match_operator 0 "ordered_comparison_operator" [(cc0)
4341 (const_int 0)])
4342 (label_ref (match_operand 3 "" ""))
4343 (pc)))]
4344 "")
4345
4346 (define_expand "cbranchpsi4"
4347 [(parallel [(set (cc0)
4348 (compare (match_operand:PSI 1 "register_operand" "")
4349 (match_operand:PSI 2 "nonmemory_operand" "")))
4350 (clobber (match_scratch:QI 4 ""))])
4351 (set (pc)
4352 (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0)
4353 (const_int 0)])
4354 (label_ref (match_operand 3 "" ""))
4355 (pc)))]
4356 "")
4357
4358 (define_expand "cbranchhi4"
4359 [(parallel [(set (cc0)
4360 (compare (match_operand:HI 1 "register_operand" "")
4361 (match_operand:HI 2 "nonmemory_operand" "")))
4362 (clobber (match_scratch:QI 4 ""))])
4363 (set (pc)
4364 (if_then_else
4365 (match_operator 0 "ordered_comparison_operator" [(cc0)
4366 (const_int 0)])
4367 (label_ref (match_operand 3 "" ""))
4368 (pc)))]
4369 "")
4370
4371 (define_expand "cbranchqi4"
4372 [(set (cc0)
4373 (compare (match_operand:QI 1 "register_operand" "")
4374 (match_operand:QI 2 "nonmemory_operand" "")))
4375 (set (pc)
4376 (if_then_else
4377 (match_operator 0 "ordered_comparison_operator" [(cc0)
4378 (const_int 0)])
4379 (label_ref (match_operand 3 "" ""))
4380 (pc)))]
4381 "")
4382
4383
4384 ;; Test a single bit in a QI/HI/SImode register.
4385 ;; Combine will create zero extract patterns for single bit tests.
4386 ;; permit any mode in source pattern by using VOIDmode.
4387
4388 (define_insn "*sbrx_branch<mode>"
4389 [(set (pc)
4390 (if_then_else
4391 (match_operator 0 "eqne_operator"
4392 [(zero_extract:QIDI
4393 (match_operand:VOID 1 "register_operand" "r")
4394 (const_int 1)
4395 (match_operand 2 "const_int_operand" "n"))
4396 (const_int 0)])
4397 (label_ref (match_operand 3 "" ""))
4398 (pc)))]
4399 ""
4400 {
4401 return avr_out_sbxx_branch (insn, operands);
4402 }
4403 [(set (attr "length")
4404 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4405 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4406 (const_int 2)
4407 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4408 (const_int 2)
4409 (const_int 4))))
4410 (set_attr "cc" "clobber")])
4411
4412 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
4413 ;; or for old peepholes.
4414 ;; Fixme - bitwise Mask will not work for DImode
4415
4416 (define_insn "*sbrx_and_branch<mode>"
4417 [(set (pc)
4418 (if_then_else
4419 (match_operator 0 "eqne_operator"
4420 [(and:QISI
4421 (match_operand:QISI 1 "register_operand" "r")
4422 (match_operand:QISI 2 "single_one_operand" "n"))
4423 (const_int 0)])
4424 (label_ref (match_operand 3 "" ""))
4425 (pc)))]
4426 ""
4427 {
4428 HOST_WIDE_INT bitnumber;
4429 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4430 operands[2] = GEN_INT (bitnumber);
4431 return avr_out_sbxx_branch (insn, operands);
4432 }
4433 [(set (attr "length")
4434 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4435 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4436 (const_int 2)
4437 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4438 (const_int 2)
4439 (const_int 4))))
4440 (set_attr "cc" "clobber")])
4441
4442 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4443 (define_peephole2
4444 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4445 (const_int 0)))
4446 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4447 (label_ref (match_operand 1 "" ""))
4448 (pc)))]
4449 ""
4450 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4451 (const_int 1)
4452 (const_int 7))
4453 (const_int 0))
4454 (label_ref (match_dup 1))
4455 (pc)))]
4456 "")
4457
4458 (define_peephole2
4459 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4460 (const_int 0)))
4461 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4462 (label_ref (match_operand 1 "" ""))
4463 (pc)))]
4464 ""
4465 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4466 (const_int 1)
4467 (const_int 7))
4468 (const_int 0))
4469 (label_ref (match_dup 1))
4470 (pc)))]
4471 "")
4472
4473 (define_peephole2
4474 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4475 (const_int 0)))
4476 (clobber (match_operand:HI 2 ""))])
4477 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4478 (label_ref (match_operand 1 "" ""))
4479 (pc)))]
4480 ""
4481 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4482 (const_int 0))
4483 (label_ref (match_dup 1))
4484 (pc)))]
4485 "")
4486
4487 (define_peephole2
4488 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4489 (const_int 0)))
4490 (clobber (match_operand:HI 2 ""))])
4491 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4492 (label_ref (match_operand 1 "" ""))
4493 (pc)))]
4494 ""
4495 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4496 (const_int 0))
4497 (label_ref (match_dup 1))
4498 (pc)))]
4499 "")
4500
4501 (define_peephole2
4502 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4503 (const_int 0)))
4504 (clobber (match_operand:SI 2 ""))])
4505 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4506 (label_ref (match_operand 1 "" ""))
4507 (pc)))]
4508 ""
4509 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4510 (const_int 0))
4511 (label_ref (match_dup 1))
4512 (pc)))]
4513 "operands[2] = GEN_INT (-2147483647 - 1);")
4514
4515 (define_peephole2
4516 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4517 (const_int 0)))
4518 (clobber (match_operand:SI 2 ""))])
4519 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4520 (label_ref (match_operand 1 "" ""))
4521 (pc)))]
4522 ""
4523 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4524 (const_int 0))
4525 (label_ref (match_dup 1))
4526 (pc)))]
4527 "operands[2] = GEN_INT (-2147483647 - 1);")
4528
4529 ;; ************************************************************************
4530 ;; Implementation of conditional jumps here.
4531 ;; Compare with 0 (test) jumps
4532 ;; ************************************************************************
4533
4534 (define_insn "branch"
4535 [(set (pc)
4536 (if_then_else (match_operator 1 "simple_comparison_operator"
4537 [(cc0)
4538 (const_int 0)])
4539 (label_ref (match_operand 0 "" ""))
4540 (pc)))]
4541 ""
4542 {
4543 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4544 }
4545 [(set_attr "type" "branch")
4546 (set_attr "cc" "clobber")])
4547
4548
4549 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4550 ;; or optimized in the remainder.
4551
4552 (define_insn "branch_unspec"
4553 [(set (pc)
4554 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4555 [(cc0)
4556 (const_int 0)])
4557 (label_ref (match_operand 0 "" ""))
4558 (pc))
4559 ] UNSPEC_IDENTITY))]
4560 ""
4561 {
4562 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4563 }
4564 [(set_attr "type" "branch")
4565 (set_attr "cc" "none")])
4566
4567 ;; ****************************************************************
4568 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4569 ;; Convert them all to proper jumps.
4570 ;; ****************************************************************/
4571
4572 (define_insn "difficult_branch"
4573 [(set (pc)
4574 (if_then_else (match_operator 1 "difficult_comparison_operator"
4575 [(cc0)
4576 (const_int 0)])
4577 (label_ref (match_operand 0 "" ""))
4578 (pc)))]
4579 ""
4580 {
4581 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4582 }
4583 [(set_attr "type" "branch1")
4584 (set_attr "cc" "clobber")])
4585
4586 ;; revers branch
4587
4588 (define_insn "rvbranch"
4589 [(set (pc)
4590 (if_then_else (match_operator 1 "simple_comparison_operator"
4591 [(cc0)
4592 (const_int 0)])
4593 (pc)
4594 (label_ref (match_operand 0 "" ""))))]
4595 ""
4596 {
4597 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4598 }
4599 [(set_attr "type" "branch1")
4600 (set_attr "cc" "clobber")])
4601
4602 (define_insn "difficult_rvbranch"
4603 [(set (pc)
4604 (if_then_else (match_operator 1 "difficult_comparison_operator"
4605 [(cc0)
4606 (const_int 0)])
4607 (pc)
4608 (label_ref (match_operand 0 "" ""))))]
4609 ""
4610 {
4611 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4612 }
4613 [(set_attr "type" "branch")
4614 (set_attr "cc" "clobber")])
4615
4616 ;; **************************************************************************
4617 ;; Unconditional and other jump instructions.
4618
4619 (define_insn "jump"
4620 [(set (pc)
4621 (label_ref (match_operand 0 "" "")))]
4622 ""
4623 {
4624 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4625 ? "jmp %x0"
4626 : "rjmp %x0";
4627 }
4628 [(set (attr "length")
4629 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4630 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4631 (const_int 1)
4632 (const_int 2))
4633 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4634 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4635 (const_int 1)
4636 (const_int 2))))
4637 (set_attr "cc" "none")])
4638
4639 ;; call
4640
4641 (define_expand "call"
4642 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4643 (match_operand:HI 1 "general_operand" ""))
4644 (use (const_int 0))])]
4645 ;; Operand 1 not used on the AVR.
4646 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4647 ""
4648 "")
4649
4650 (define_expand "sibcall"
4651 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4652 (match_operand:HI 1 "general_operand" ""))
4653 (use (const_int 1))])]
4654 ;; Operand 1 not used on the AVR.
4655 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4656 ""
4657 "")
4658
4659 ;; call value
4660
4661 (define_expand "call_value"
4662 [(parallel[(set (match_operand 0 "register_operand" "")
4663 (call (match_operand:HI 1 "call_insn_operand" "")
4664 (match_operand:HI 2 "general_operand" "")))
4665 (use (const_int 0))])]
4666 ;; Operand 2 not used on the AVR.
4667 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4668 ""
4669 "")
4670
4671 (define_expand "sibcall_value"
4672 [(parallel[(set (match_operand 0 "register_operand" "")
4673 (call (match_operand:HI 1 "call_insn_operand" "")
4674 (match_operand:HI 2 "general_operand" "")))
4675 (use (const_int 1))])]
4676 ;; Operand 2 not used on the AVR.
4677 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4678 ""
4679 "")
4680
4681 (define_insn "call_insn"
4682 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4683 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4684 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4685 ;; Operand 1 not used on the AVR.
4686 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4687 ""
4688 "@
4689 %!icall
4690 %~call %x0
4691 %!ijmp
4692 %~jmp %x0"
4693 [(set_attr "cc" "clobber")
4694 (set_attr "length" "1,*,1,*")
4695 (set_attr "adjust_len" "*,call,*,call")])
4696
4697 (define_insn "call_value_insn"
4698 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4699 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4700 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4701 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4702 ;; Operand 2 not used on the AVR.
4703 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4704 ""
4705 "@
4706 %!icall
4707 %~call %x1
4708 %!ijmp
4709 %~jmp %x1"
4710 [(set_attr "cc" "clobber")
4711 (set_attr "length" "1,*,1,*")
4712 (set_attr "adjust_len" "*,call,*,call")])
4713
4714 (define_insn "nop"
4715 [(const_int 0)]
4716 ""
4717 "nop"
4718 [(set_attr "cc" "none")
4719 (set_attr "length" "1")])
4720
4721 ; indirect jump
4722
4723 (define_expand "indirect_jump"
4724 [(set (pc)
4725 (match_operand:HI 0 "nonmemory_operand" ""))]
4726 ""
4727 {
4728 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4729 {
4730 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4731 }
4732 })
4733
4734 ; indirect jump
4735 (define_insn "*indirect_jump"
4736 [(set (pc)
4737 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4738 ""
4739 "@
4740 rjmp %x0
4741 jmp %x0
4742 ijmp
4743 push %A0\;push %B0\;ret
4744 eijmp"
4745 [(set_attr "length" "1,2,1,3,1")
4746 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4747 (set_attr "cc" "none")])
4748
4749 ;; table jump
4750 ;; For entries in jump table see avr_output_addr_vec_elt.
4751
4752 ;; Table made from
4753 ;; "rjmp .L<n>" instructions for <= 8K devices
4754 ;; ".word gs(.L<n>)" addresses for > 8K devices
4755 (define_insn "*tablejump"
4756 [(set (pc)
4757 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4758 UNSPEC_INDEX_JMP))
4759 (use (label_ref (match_operand 1 "" "")))
4760 (clobber (match_dup 0))]
4761 ""
4762 "@
4763 ijmp
4764 push %A0\;push %B0\;ret
4765 jmp __tablejump2__"
4766 [(set_attr "length" "1,3,2")
4767 (set_attr "isa" "rjmp,rjmp,jmp")
4768 (set_attr "cc" "none,none,clobber")])
4769
4770
4771 (define_expand "casesi"
4772 [(set (match_dup 6)
4773 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4774 (match_operand:HI 1 "register_operand" "")))
4775 (parallel [(set (cc0)
4776 (compare (match_dup 6)
4777 (match_operand:HI 2 "register_operand" "")))
4778 (clobber (match_scratch:QI 9 ""))])
4779
4780 (set (pc)
4781 (if_then_else (gtu (cc0)
4782 (const_int 0))
4783 (label_ref (match_operand 4 "" ""))
4784 (pc)))
4785
4786 (set (match_dup 6)
4787 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4788
4789 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4790 (use (label_ref (match_dup 3)))
4791 (clobber (match_dup 6))])]
4792 ""
4793 {
4794 operands[6] = gen_reg_rtx (HImode);
4795 })
4796
4797
4798 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4799 ;; This instruction sets Z flag
4800
4801 (define_insn "sez"
4802 [(set (cc0) (const_int 0))]
4803 ""
4804 "sez"
4805 [(set_attr "length" "1")
4806 (set_attr "cc" "compare")])
4807
4808 ;; Clear/set/test a single bit in I/O address space.
4809
4810 (define_insn "*cbi"
4811 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4812 (and:QI (mem:QI (match_dup 0))
4813 (match_operand:QI 1 "single_zero_operand" "n")))]
4814 ""
4815 {
4816 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4817 return "cbi %i0,%2";
4818 }
4819 [(set_attr "length" "1")
4820 (set_attr "cc" "none")])
4821
4822 (define_insn "*sbi"
4823 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4824 (ior:QI (mem:QI (match_dup 0))
4825 (match_operand:QI 1 "single_one_operand" "n")))]
4826 ""
4827 {
4828 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4829 return "sbi %i0,%2";
4830 }
4831 [(set_attr "length" "1")
4832 (set_attr "cc" "none")])
4833
4834 ;; Lower half of the I/O space - use sbic/sbis directly.
4835 (define_insn "*sbix_branch"
4836 [(set (pc)
4837 (if_then_else
4838 (match_operator 0 "eqne_operator"
4839 [(zero_extract:QIHI
4840 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
4841 (const_int 1)
4842 (match_operand 2 "const_int_operand" "n"))
4843 (const_int 0)])
4844 (label_ref (match_operand 3 "" ""))
4845 (pc)))]
4846 ""
4847 {
4848 return avr_out_sbxx_branch (insn, operands);
4849 }
4850 [(set (attr "length")
4851 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4852 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4853 (const_int 2)
4854 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4855 (const_int 2)
4856 (const_int 4))))
4857 (set_attr "cc" "clobber")])
4858
4859 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4860 (define_insn "*sbix_branch_bit7"
4861 [(set (pc)
4862 (if_then_else
4863 (match_operator 0 "gelt_operator"
4864 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
4865 (const_int 0)])
4866 (label_ref (match_operand 2 "" ""))
4867 (pc)))]
4868 ""
4869 {
4870 operands[3] = operands[2];
4871 operands[2] = GEN_INT (7);
4872 return avr_out_sbxx_branch (insn, operands);
4873 }
4874 [(set (attr "length")
4875 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4876 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4877 (const_int 2)
4878 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4879 (const_int 2)
4880 (const_int 4))))
4881 (set_attr "cc" "clobber")])
4882
4883 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4884 (define_insn "*sbix_branch_tmp"
4885 [(set (pc)
4886 (if_then_else
4887 (match_operator 0 "eqne_operator"
4888 [(zero_extract:QIHI
4889 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
4890 (const_int 1)
4891 (match_operand 2 "const_int_operand" "n"))
4892 (const_int 0)])
4893 (label_ref (match_operand 3 "" ""))
4894 (pc)))]
4895 ""
4896 {
4897 return avr_out_sbxx_branch (insn, operands);
4898 }
4899 [(set (attr "length")
4900 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4901 (le (minus (pc) (match_dup 3)) (const_int 2045)))
4902 (const_int 3)
4903 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4904 (const_int 3)
4905 (const_int 5))))
4906 (set_attr "cc" "clobber")])
4907
4908 (define_insn "*sbix_branch_tmp_bit7"
4909 [(set (pc)
4910 (if_then_else
4911 (match_operator 0 "gelt_operator"
4912 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
4913 (const_int 0)])
4914 (label_ref (match_operand 2 "" ""))
4915 (pc)))]
4916 ""
4917 {
4918 operands[3] = operands[2];
4919 operands[2] = GEN_INT (7);
4920 return avr_out_sbxx_branch (insn, operands);
4921 }
4922 [(set (attr "length")
4923 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4924 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4925 (const_int 3)
4926 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4927 (const_int 3)
4928 (const_int 5))))
4929 (set_attr "cc" "clobber")])
4930
4931 ;; ************************* Peepholes ********************************
4932
4933 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
4934 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
4935 (plus:SI (match_dup 0)
4936 (const_int -1)))
4937 (clobber (scratch:QI))])
4938 (parallel [(set (cc0)
4939 (compare (match_dup 0)
4940 (const_int -1)))
4941 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4942 (set (pc)
4943 (if_then_else (eqne (cc0)
4944 (const_int 0))
4945 (label_ref (match_operand 2 "" ""))
4946 (pc)))]
4947 ""
4948 {
4949 const char *op;
4950 int jump_mode;
4951 CC_STATUS_INIT;
4952 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4953 output_asm_insn ("sbiw %0,1" CR_TAB
4954 "sbc %C0,__zero_reg__" CR_TAB
4955 "sbc %D0,__zero_reg__", operands);
4956 else
4957 output_asm_insn ("subi %A0,1" CR_TAB
4958 "sbc %B0,__zero_reg__" CR_TAB
4959 "sbc %C0,__zero_reg__" CR_TAB
4960 "sbc %D0,__zero_reg__", operands);
4961
4962 jump_mode = avr_jump_mode (operands[2], insn);
4963 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
4964 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
4965
4966 switch (jump_mode)
4967 {
4968 case 1: return "%1 %2";
4969 case 2: return "%1 .+2\;rjmp %2";
4970 case 3: return "%1 .+4\;jmp %2";
4971 }
4972
4973 gcc_unreachable();
4974 return "";
4975 })
4976
4977 (define_peephole ; "*dec-and-branchhi!=-1"
4978 [(set (match_operand:HI 0 "d_register_operand" "")
4979 (plus:HI (match_dup 0)
4980 (const_int -1)))
4981 (parallel [(set (cc0)
4982 (compare (match_dup 0)
4983 (const_int -1)))
4984 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4985 (set (pc)
4986 (if_then_else (eqne (cc0)
4987 (const_int 0))
4988 (label_ref (match_operand 2 "" ""))
4989 (pc)))]
4990 ""
4991 {
4992 const char *op;
4993 int jump_mode;
4994 CC_STATUS_INIT;
4995 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4996 output_asm_insn ("sbiw %0,1", operands);
4997 else
4998 output_asm_insn ("subi %A0,1" CR_TAB
4999 "sbc %B0,__zero_reg__", operands);
5000
5001 jump_mode = avr_jump_mode (operands[2], insn);
5002 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5003 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5004
5005 switch (jump_mode)
5006 {
5007 case 1: return "%1 %2";
5008 case 2: return "%1 .+2\;rjmp %2";
5009 case 3: return "%1 .+4\;jmp %2";
5010 }
5011
5012 gcc_unreachable();
5013 return "";
5014 })
5015
5016 ;; Same as above but with clobber flavour of addhi3
5017 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5018 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5019 (plus:HI (match_dup 0)
5020 (const_int -1)))
5021 (clobber (scratch:QI))])
5022 (parallel [(set (cc0)
5023 (compare (match_dup 0)
5024 (const_int -1)))
5025 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5026 (set (pc)
5027 (if_then_else (eqne (cc0)
5028 (const_int 0))
5029 (label_ref (match_operand 2 "" ""))
5030 (pc)))]
5031 ""
5032 {
5033 const char *op;
5034 int jump_mode;
5035 CC_STATUS_INIT;
5036 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5037 output_asm_insn ("sbiw %0,1", operands);
5038 else
5039 output_asm_insn ("subi %A0,1" CR_TAB
5040 "sbc %B0,__zero_reg__", operands);
5041
5042 jump_mode = avr_jump_mode (operands[2], insn);
5043 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5044 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5045
5046 switch (jump_mode)
5047 {
5048 case 1: return "%1 %2";
5049 case 2: return "%1 .+2\;rjmp %2";
5050 case 3: return "%1 .+4\;jmp %2";
5051 }
5052
5053 gcc_unreachable();
5054 return "";
5055 })
5056
5057 ;; Same as above but with clobber flavour of addhi3
5058 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5059 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5060 (plus:HI (match_dup 0)
5061 (const_int -1)))
5062 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5063 (parallel [(set (cc0)
5064 (compare (match_dup 0)
5065 (const_int -1)))
5066 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5067 (set (pc)
5068 (if_then_else (eqne (cc0)
5069 (const_int 0))
5070 (label_ref (match_operand 2 "" ""))
5071 (pc)))]
5072 ""
5073 {
5074 const char *op;
5075 int jump_mode;
5076 CC_STATUS_INIT;
5077 output_asm_insn ("ldi %3,1" CR_TAB
5078 "sub %A0,%3" CR_TAB
5079 "sbc %B0,__zero_reg__", operands);
5080
5081 jump_mode = avr_jump_mode (operands[2], insn);
5082 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5083 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5084
5085 switch (jump_mode)
5086 {
5087 case 1: return "%1 %2";
5088 case 2: return "%1 .+2\;rjmp %2";
5089 case 3: return "%1 .+4\;jmp %2";
5090 }
5091
5092 gcc_unreachable();
5093 return "";
5094 })
5095
5096 (define_peephole ; "*dec-and-branchqi!=-1"
5097 [(set (match_operand:QI 0 "d_register_operand" "")
5098 (plus:QI (match_dup 0)
5099 (const_int -1)))
5100 (set (cc0)
5101 (compare (match_dup 0)
5102 (const_int -1)))
5103 (set (pc)
5104 (if_then_else (eqne (cc0)
5105 (const_int 0))
5106 (label_ref (match_operand 1 "" ""))
5107 (pc)))]
5108 ""
5109 {
5110 const char *op;
5111 int jump_mode;
5112 CC_STATUS_INIT;
5113 cc_status.value1 = operands[0];
5114 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5115
5116 output_asm_insn ("subi %A0,1", operands);
5117
5118 jump_mode = avr_jump_mode (operands[1], insn);
5119 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5120 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5121
5122 switch (jump_mode)
5123 {
5124 case 1: return "%0 %1";
5125 case 2: return "%0 .+2\;rjmp %1";
5126 case 3: return "%0 .+4\;jmp %1";
5127 }
5128
5129 gcc_unreachable();
5130 return "";
5131 })
5132
5133
5134 (define_peephole ; "*cpse.eq"
5135 [(set (cc0)
5136 (compare (match_operand:QI 1 "register_operand" "r,r")
5137 (match_operand:QI 2 "reg_or_0_operand" "r,L")))
5138 (set (pc)
5139 (if_then_else (eq (cc0)
5140 (const_int 0))
5141 (label_ref (match_operand 0 "" ""))
5142 (pc)))]
5143 "jump_over_one_insn_p (insn, operands[0])"
5144 "@
5145 cpse %1,%2
5146 cpse %1,__zero_reg__")
5147
5148 ;; This peephole avoids code like
5149 ;;
5150 ;; TST Rn ; *cmpqi
5151 ;; BREQ .+2 ; branch
5152 ;; RJMP .Lm
5153 ;;
5154 ;; Notice that the peephole is always shorter than cmpqi + branch.
5155 ;; The reason to write it as peephole is that sequences like
5156 ;;
5157 ;; AND Rm, Rn
5158 ;; BRNE .La
5159 ;;
5160 ;; shall not be superseeded. With a respective combine pattern
5161 ;; the latter sequence would be
5162 ;;
5163 ;; AND Rm, Rn
5164 ;; CPSE Rm, __zero_reg__
5165 ;; RJMP .La
5166 ;;
5167 ;; and thus longer and slower and not easy to be rolled back.
5168
5169 (define_peephole ; "*cpse.ne"
5170 [(set (cc0)
5171 (compare (match_operand:QI 1 "register_operand" "")
5172 (match_operand:QI 2 "reg_or_0_operand" "")))
5173 (set (pc)
5174 (if_then_else (ne (cc0)
5175 (const_int 0))
5176 (label_ref (match_operand 0 "" ""))
5177 (pc)))]
5178 "!AVR_HAVE_JMP_CALL
5179 || !avr_current_device->errata_skip"
5180 {
5181 if (operands[2] == const0_rtx)
5182 operands[2] = zero_reg_rtx;
5183
5184 return 3 == avr_jump_mode (operands[0], insn)
5185 ? "cpse %1,%2\;jmp %0"
5186 : "cpse %1,%2\;rjmp %0";
5187 })
5188
5189 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5190 ;;prologue/epilogue support instructions
5191
5192 (define_insn "popqi"
5193 [(set (match_operand:QI 0 "register_operand" "=r")
5194 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5195 ""
5196 "pop %0"
5197 [(set_attr "cc" "none")
5198 (set_attr "length" "1")])
5199
5200 ;; Enable Interrupts
5201 (define_insn "enable_interrupt"
5202 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
5203 ""
5204 "sei"
5205 [(set_attr "length" "1")
5206 (set_attr "cc" "none")])
5207
5208 ;; Disable Interrupts
5209 (define_insn "disable_interrupt"
5210 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
5211 ""
5212 "cli"
5213 [(set_attr "length" "1")
5214 (set_attr "cc" "none")])
5215
5216 ;; Library prologue saves
5217 (define_insn "call_prologue_saves"
5218 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5219 (match_operand:HI 0 "immediate_operand" "i,i")
5220 (set (reg:HI REG_SP)
5221 (minus:HI (reg:HI REG_SP)
5222 (match_operand:HI 1 "immediate_operand" "i,i")))
5223 (use (reg:HI REG_X))
5224 (clobber (reg:HI REG_Z))]
5225 ""
5226 "ldi r30,lo8(gs(1f))
5227 ldi r31,hi8(gs(1f))
5228 %~jmp __prologue_saves__+((18 - %0) * 2)
5229 1:"
5230 [(set_attr "length" "5,6")
5231 (set_attr "cc" "clobber")
5232 (set_attr "isa" "rjmp,jmp")])
5233
5234 ; epilogue restores using library
5235 (define_insn "epilogue_restores"
5236 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5237 (set (reg:HI REG_Y)
5238 (plus:HI (reg:HI REG_Y)
5239 (match_operand:HI 0 "immediate_operand" "i,i")))
5240 (set (reg:HI REG_SP)
5241 (plus:HI (reg:HI REG_Y)
5242 (match_dup 0)))
5243 (clobber (reg:QI REG_Z))]
5244 ""
5245 "ldi r30, lo8(%0)
5246 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5247 [(set_attr "length" "2,3")
5248 (set_attr "cc" "clobber")
5249 (set_attr "isa" "rjmp,jmp")])
5250
5251 ; return
5252 (define_insn "return"
5253 [(return)]
5254 "reload_completed && avr_simple_epilogue ()"
5255 "ret"
5256 [(set_attr "cc" "none")
5257 (set_attr "length" "1")])
5258
5259 (define_insn "return_from_epilogue"
5260 [(return)]
5261 "(reload_completed
5262 && cfun->machine
5263 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5264 && !cfun->machine->is_naked)"
5265 "ret"
5266 [(set_attr "cc" "none")
5267 (set_attr "length" "1")])
5268
5269 (define_insn "return_from_interrupt_epilogue"
5270 [(return)]
5271 "(reload_completed
5272 && cfun->machine
5273 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5274 && !cfun->machine->is_naked)"
5275 "reti"
5276 [(set_attr "cc" "none")
5277 (set_attr "length" "1")])
5278
5279 (define_insn "return_from_naked_epilogue"
5280 [(return)]
5281 "(reload_completed
5282 && cfun->machine
5283 && cfun->machine->is_naked)"
5284 ""
5285 [(set_attr "cc" "none")
5286 (set_attr "length" "0")])
5287
5288 (define_expand "prologue"
5289 [(const_int 0)]
5290 ""
5291 {
5292 expand_prologue ();
5293 DONE;
5294 })
5295
5296 (define_expand "epilogue"
5297 [(const_int 0)]
5298 ""
5299 {
5300 expand_epilogue (false /* sibcall_p */);
5301 DONE;
5302 })
5303
5304 (define_expand "sibcall_epilogue"
5305 [(const_int 0)]
5306 ""
5307 {
5308 expand_epilogue (true /* sibcall_p */);
5309 DONE;
5310 })
5311
5312 ;; Some instructions resp. instruction sequences available
5313 ;; via builtins.
5314
5315 (define_insn "delay_cycles_1"
5316 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5317 (const_int 1)]
5318 UNSPECV_DELAY_CYCLES)
5319 (clobber (match_scratch:QI 1 "=&d"))]
5320 ""
5321 "ldi %1,lo8(%0)
5322 1: dec %1
5323 brne 1b"
5324 [(set_attr "length" "3")
5325 (set_attr "cc" "clobber")])
5326
5327 (define_insn "delay_cycles_2"
5328 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5329 (const_int 2)]
5330 UNSPECV_DELAY_CYCLES)
5331 (clobber (match_scratch:HI 1 "=&w"))]
5332 ""
5333 "ldi %A1,lo8(%0)
5334 ldi %B1,hi8(%0)
5335 1: sbiw %A1,1
5336 brne 1b"
5337 [(set_attr "length" "4")
5338 (set_attr "cc" "clobber")])
5339
5340 (define_insn "delay_cycles_3"
5341 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5342 (const_int 3)]
5343 UNSPECV_DELAY_CYCLES)
5344 (clobber (match_scratch:QI 1 "=&d"))
5345 (clobber (match_scratch:QI 2 "=&d"))
5346 (clobber (match_scratch:QI 3 "=&d"))]
5347 ""
5348 "ldi %1,lo8(%0)
5349 ldi %2,hi8(%0)
5350 ldi %3,hlo8(%0)
5351 1: subi %1,1
5352 sbci %2,0
5353 sbci %3,0
5354 brne 1b"
5355 [(set_attr "length" "7")
5356 (set_attr "cc" "clobber")])
5357
5358 (define_insn "delay_cycles_4"
5359 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5360 (const_int 4)]
5361 UNSPECV_DELAY_CYCLES)
5362 (clobber (match_scratch:QI 1 "=&d"))
5363 (clobber (match_scratch:QI 2 "=&d"))
5364 (clobber (match_scratch:QI 3 "=&d"))
5365 (clobber (match_scratch:QI 4 "=&d"))]
5366 ""
5367 "ldi %1,lo8(%0)
5368 ldi %2,hi8(%0)
5369 ldi %3,hlo8(%0)
5370 ldi %4,hhi8(%0)
5371 1: subi %1,1
5372 sbci %2,0
5373 sbci %3,0
5374 sbci %4,0
5375 brne 1b"
5376 [(set_attr "length" "9")
5377 (set_attr "cc" "clobber")])
5378
5379
5380 ;; __builtin_avr_insert_bits
5381
5382 (define_insn "insert_bits"
5383 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5384 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5385 (match_operand:QI 2 "register_operand" "r ,r ,r")
5386 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5387 UNSPEC_INSERT_BITS))]
5388 ""
5389 {
5390 return avr_out_insert_bits (operands, NULL);
5391 }
5392 [(set_attr "adjust_len" "insert_bits")
5393 (set_attr "cc" "clobber")])
5394
5395
5396 ;; Parity
5397
5398 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5399 ;; better 8-bit parity recognition.
5400
5401 (define_expand "parityhi2"
5402 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5403 (parity:HI (match_operand:HI 1 "register_operand" "")))
5404 (clobber (reg:HI 24))])])
5405
5406 (define_insn_and_split "*parityhi2"
5407 [(set (match_operand:HI 0 "register_operand" "=r")
5408 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5409 (clobber (reg:HI 24))]
5410 "!reload_completed"
5411 { gcc_unreachable(); }
5412 "&& 1"
5413 [(set (reg:HI 24)
5414 (match_dup 1))
5415 (set (reg:HI 24)
5416 (parity:HI (reg:HI 24)))
5417 (set (match_dup 0)
5418 (reg:HI 24))])
5419
5420 (define_insn_and_split "*parityqihi2"
5421 [(set (match_operand:HI 0 "register_operand" "=r")
5422 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5423 (clobber (reg:HI 24))]
5424 "!reload_completed"
5425 { gcc_unreachable(); }
5426 "&& 1"
5427 [(set (reg:QI 24)
5428 (match_dup 1))
5429 (set (reg:HI 24)
5430 (zero_extend:HI (parity:QI (reg:QI 24))))
5431 (set (match_dup 0)
5432 (reg:HI 24))])
5433
5434 (define_expand "paritysi2"
5435 [(set (reg:SI 22)
5436 (match_operand:SI 1 "register_operand" ""))
5437 (set (reg:HI 24)
5438 (truncate:HI (parity:SI (reg:SI 22))))
5439 (set (match_dup 2)
5440 (reg:HI 24))
5441 (set (match_operand:SI 0 "register_operand" "")
5442 (zero_extend:SI (match_dup 2)))]
5443 ""
5444 {
5445 operands[2] = gen_reg_rtx (HImode);
5446 })
5447
5448 (define_insn "*parityhi2.libgcc"
5449 [(set (reg:HI 24)
5450 (parity:HI (reg:HI 24)))]
5451 ""
5452 "%~call __parityhi2"
5453 [(set_attr "type" "xcall")
5454 (set_attr "cc" "clobber")])
5455
5456 (define_insn "*parityqihi2.libgcc"
5457 [(set (reg:HI 24)
5458 (zero_extend:HI (parity:QI (reg:QI 24))))]
5459 ""
5460 "%~call __parityqi2"
5461 [(set_attr "type" "xcall")
5462 (set_attr "cc" "clobber")])
5463
5464 (define_insn "*paritysihi2.libgcc"
5465 [(set (reg:HI 24)
5466 (truncate:HI (parity:SI (reg:SI 22))))]
5467 ""
5468 "%~call __paritysi2"
5469 [(set_attr "type" "xcall")
5470 (set_attr "cc" "clobber")])
5471
5472
5473 ;; Popcount
5474
5475 (define_expand "popcounthi2"
5476 [(set (reg:HI 24)
5477 (match_operand:HI 1 "register_operand" ""))
5478 (set (reg:HI 24)
5479 (popcount:HI (reg:HI 24)))
5480 (set (match_operand:HI 0 "register_operand" "")
5481 (reg:HI 24))]
5482 ""
5483 "")
5484
5485 (define_expand "popcountsi2"
5486 [(set (reg:SI 22)
5487 (match_operand:SI 1 "register_operand" ""))
5488 (set (reg:HI 24)
5489 (truncate:HI (popcount:SI (reg:SI 22))))
5490 (set (match_dup 2)
5491 (reg:HI 24))
5492 (set (match_operand:SI 0 "register_operand" "")
5493 (zero_extend:SI (match_dup 2)))]
5494 ""
5495 {
5496 operands[2] = gen_reg_rtx (HImode);
5497 })
5498
5499 (define_insn "*popcounthi2.libgcc"
5500 [(set (reg:HI 24)
5501 (popcount:HI (reg:HI 24)))]
5502 ""
5503 "%~call __popcounthi2"
5504 [(set_attr "type" "xcall")
5505 (set_attr "cc" "clobber")])
5506
5507 (define_insn "*popcountsi2.libgcc"
5508 [(set (reg:HI 24)
5509 (truncate:HI (popcount:SI (reg:SI 22))))]
5510 ""
5511 "%~call __popcountsi2"
5512 [(set_attr "type" "xcall")
5513 (set_attr "cc" "clobber")])
5514
5515 (define_insn "*popcountqi2.libgcc"
5516 [(set (reg:QI 24)
5517 (popcount:QI (reg:QI 24)))]
5518 ""
5519 "%~call __popcountqi2"
5520 [(set_attr "type" "xcall")
5521 (set_attr "cc" "clobber")])
5522
5523 (define_insn_and_split "*popcountqihi2.libgcc"
5524 [(set (reg:HI 24)
5525 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5526 ""
5527 "#"
5528 ""
5529 [(set (reg:QI 24)
5530 (popcount:QI (reg:QI 24)))
5531 (set (reg:QI 25)
5532 (const_int 0))]
5533 "")
5534
5535 ;; Count Leading Zeros
5536
5537 (define_expand "clzhi2"
5538 [(set (reg:HI 24)
5539 (match_operand:HI 1 "register_operand" ""))
5540 (parallel [(set (reg:HI 24)
5541 (clz:HI (reg:HI 24)))
5542 (clobber (reg:QI 26))])
5543 (set (match_operand:HI 0 "register_operand" "")
5544 (reg:HI 24))]
5545 ""
5546 "")
5547
5548 (define_expand "clzsi2"
5549 [(set (reg:SI 22)
5550 (match_operand:SI 1 "register_operand" ""))
5551 (parallel [(set (reg:HI 24)
5552 (truncate:HI (clz:SI (reg:SI 22))))
5553 (clobber (reg:QI 26))])
5554 (set (match_dup 2)
5555 (reg:HI 24))
5556 (set (match_operand:SI 0 "register_operand" "")
5557 (zero_extend:SI (match_dup 2)))]
5558 ""
5559 {
5560 operands[2] = gen_reg_rtx (HImode);
5561 })
5562
5563 (define_insn "*clzhi2.libgcc"
5564 [(set (reg:HI 24)
5565 (clz:HI (reg:HI 24)))
5566 (clobber (reg:QI 26))]
5567 ""
5568 "%~call __clzhi2"
5569 [(set_attr "type" "xcall")
5570 (set_attr "cc" "clobber")])
5571
5572 (define_insn "*clzsihi2.libgcc"
5573 [(set (reg:HI 24)
5574 (truncate:HI (clz:SI (reg:SI 22))))
5575 (clobber (reg:QI 26))]
5576 ""
5577 "%~call __clzsi2"
5578 [(set_attr "type" "xcall")
5579 (set_attr "cc" "clobber")])
5580
5581 ;; Count Trailing Zeros
5582
5583 (define_expand "ctzhi2"
5584 [(set (reg:HI 24)
5585 (match_operand:HI 1 "register_operand" ""))
5586 (parallel [(set (reg:HI 24)
5587 (ctz:HI (reg:HI 24)))
5588 (clobber (reg:QI 26))])
5589 (set (match_operand:HI 0 "register_operand" "")
5590 (reg:HI 24))]
5591 ""
5592 "")
5593
5594 (define_expand "ctzsi2"
5595 [(set (reg:SI 22)
5596 (match_operand:SI 1 "register_operand" ""))
5597 (parallel [(set (reg:HI 24)
5598 (truncate:HI (ctz:SI (reg:SI 22))))
5599 (clobber (reg:QI 22))
5600 (clobber (reg:QI 26))])
5601 (set (match_dup 2)
5602 (reg:HI 24))
5603 (set (match_operand:SI 0 "register_operand" "")
5604 (zero_extend:SI (match_dup 2)))]
5605 ""
5606 {
5607 operands[2] = gen_reg_rtx (HImode);
5608 })
5609
5610 (define_insn "*ctzhi2.libgcc"
5611 [(set (reg:HI 24)
5612 (ctz:HI (reg:HI 24)))
5613 (clobber (reg:QI 26))]
5614 ""
5615 "%~call __ctzhi2"
5616 [(set_attr "type" "xcall")
5617 (set_attr "cc" "clobber")])
5618
5619 (define_insn "*ctzsihi2.libgcc"
5620 [(set (reg:HI 24)
5621 (truncate:HI (ctz:SI (reg:SI 22))))
5622 (clobber (reg:QI 22))
5623 (clobber (reg:QI 26))]
5624 ""
5625 "%~call __ctzsi2"
5626 [(set_attr "type" "xcall")
5627 (set_attr "cc" "clobber")])
5628
5629 ;; Find First Set
5630
5631 (define_expand "ffshi2"
5632 [(set (reg:HI 24)
5633 (match_operand:HI 1 "register_operand" ""))
5634 (parallel [(set (reg:HI 24)
5635 (ffs:HI (reg:HI 24)))
5636 (clobber (reg:QI 26))])
5637 (set (match_operand:HI 0 "register_operand" "")
5638 (reg:HI 24))]
5639 ""
5640 "")
5641
5642 (define_expand "ffssi2"
5643 [(set (reg:SI 22)
5644 (match_operand:SI 1 "register_operand" ""))
5645 (parallel [(set (reg:HI 24)
5646 (truncate:HI (ffs:SI (reg:SI 22))))
5647 (clobber (reg:QI 22))
5648 (clobber (reg:QI 26))])
5649 (set (match_dup 2)
5650 (reg:HI 24))
5651 (set (match_operand:SI 0 "register_operand" "")
5652 (zero_extend:SI (match_dup 2)))]
5653 ""
5654 {
5655 operands[2] = gen_reg_rtx (HImode);
5656 })
5657
5658 (define_insn "*ffshi2.libgcc"
5659 [(set (reg:HI 24)
5660 (ffs:HI (reg:HI 24)))
5661 (clobber (reg:QI 26))]
5662 ""
5663 "%~call __ffshi2"
5664 [(set_attr "type" "xcall")
5665 (set_attr "cc" "clobber")])
5666
5667 (define_insn "*ffssihi2.libgcc"
5668 [(set (reg:HI 24)
5669 (truncate:HI (ffs:SI (reg:SI 22))))
5670 (clobber (reg:QI 22))
5671 (clobber (reg:QI 26))]
5672 ""
5673 "%~call __ffssi2"
5674 [(set_attr "type" "xcall")
5675 (set_attr "cc" "clobber")])
5676
5677 ;; Copysign
5678
5679 (define_insn "copysignsf3"
5680 [(set (match_operand:SF 0 "register_operand" "=r")
5681 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5682 (match_operand:SF 2 "register_operand" "r")]
5683 UNSPEC_COPYSIGN))]
5684 ""
5685 "bst %D2,7\;bld %D0,7"
5686 [(set_attr "length" "2")
5687 (set_attr "cc" "none")])
5688
5689 ;; Swap Bytes (change byte-endianess)
5690
5691 (define_expand "bswapsi2"
5692 [(set (reg:SI 22)
5693 (match_operand:SI 1 "register_operand" ""))
5694 (set (reg:SI 22)
5695 (bswap:SI (reg:SI 22)))
5696 (set (match_operand:SI 0 "register_operand" "")
5697 (reg:SI 22))]
5698 ""
5699 "")
5700
5701 (define_insn "*bswapsi2.libgcc"
5702 [(set (reg:SI 22)
5703 (bswap:SI (reg:SI 22)))]
5704 ""
5705 "%~call __bswapsi2"
5706 [(set_attr "type" "xcall")
5707 (set_attr "cc" "clobber")])
5708
5709
5710 ;; CPU instructions
5711
5712 ;; NOP taking 1 or 2 Ticks
5713 (define_insn "nopv"
5714 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5715 UNSPECV_NOP)]
5716 ""
5717 "@
5718 nop
5719 rjmp ."
5720 [(set_attr "length" "1")
5721 (set_attr "cc" "none")])
5722
5723 ;; SLEEP
5724 (define_insn "sleep"
5725 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
5726 ""
5727 "sleep"
5728 [(set_attr "length" "1")
5729 (set_attr "cc" "none")])
5730
5731 ;; WDR
5732 (define_insn "wdr"
5733 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
5734 ""
5735 "wdr"
5736 [(set_attr "length" "1")
5737 (set_attr "cc" "none")])
5738
5739 ;; FMUL
5740 (define_expand "fmul"
5741 [(set (reg:QI 24)
5742 (match_operand:QI 1 "register_operand" ""))
5743 (set (reg:QI 25)
5744 (match_operand:QI 2 "register_operand" ""))
5745 (parallel [(set (reg:HI 22)
5746 (unspec:HI [(reg:QI 24)
5747 (reg:QI 25)] UNSPEC_FMUL))
5748 (clobber (reg:HI 24))])
5749 (set (match_operand:HI 0 "register_operand" "")
5750 (reg:HI 22))]
5751 ""
5752 {
5753 if (AVR_HAVE_MUL)
5754 {
5755 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
5756 DONE;
5757 }
5758 })
5759
5760 (define_insn "fmul_insn"
5761 [(set (match_operand:HI 0 "register_operand" "=r")
5762 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5763 (match_operand:QI 2 "register_operand" "a")]
5764 UNSPEC_FMUL))]
5765 "AVR_HAVE_MUL"
5766 "fmul %1,%2
5767 movw %0,r0
5768 clr __zero_reg__"
5769 [(set_attr "length" "3")
5770 (set_attr "cc" "clobber")])
5771
5772 (define_insn "*fmul.call"
5773 [(set (reg:HI 22)
5774 (unspec:HI [(reg:QI 24)
5775 (reg:QI 25)] UNSPEC_FMUL))
5776 (clobber (reg:HI 24))]
5777 "!AVR_HAVE_MUL"
5778 "%~call __fmul"
5779 [(set_attr "type" "xcall")
5780 (set_attr "cc" "clobber")])
5781
5782 ;; FMULS
5783 (define_expand "fmuls"
5784 [(set (reg:QI 24)
5785 (match_operand:QI 1 "register_operand" ""))
5786 (set (reg:QI 25)
5787 (match_operand:QI 2 "register_operand" ""))
5788 (parallel [(set (reg:HI 22)
5789 (unspec:HI [(reg:QI 24)
5790 (reg:QI 25)] UNSPEC_FMULS))
5791 (clobber (reg:HI 24))])
5792 (set (match_operand:HI 0 "register_operand" "")
5793 (reg:HI 22))]
5794 ""
5795 {
5796 if (AVR_HAVE_MUL)
5797 {
5798 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
5799 DONE;
5800 }
5801 })
5802
5803 (define_insn "fmuls_insn"
5804 [(set (match_operand:HI 0 "register_operand" "=r")
5805 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5806 (match_operand:QI 2 "register_operand" "a")]
5807 UNSPEC_FMULS))]
5808 "AVR_HAVE_MUL"
5809 "fmuls %1,%2
5810 movw %0,r0
5811 clr __zero_reg__"
5812 [(set_attr "length" "3")
5813 (set_attr "cc" "clobber")])
5814
5815 (define_insn "*fmuls.call"
5816 [(set (reg:HI 22)
5817 (unspec:HI [(reg:QI 24)
5818 (reg:QI 25)] UNSPEC_FMULS))
5819 (clobber (reg:HI 24))]
5820 "!AVR_HAVE_MUL"
5821 "%~call __fmuls"
5822 [(set_attr "type" "xcall")
5823 (set_attr "cc" "clobber")])
5824
5825 ;; FMULSU
5826 (define_expand "fmulsu"
5827 [(set (reg:QI 24)
5828 (match_operand:QI 1 "register_operand" ""))
5829 (set (reg:QI 25)
5830 (match_operand:QI 2 "register_operand" ""))
5831 (parallel [(set (reg:HI 22)
5832 (unspec:HI [(reg:QI 24)
5833 (reg:QI 25)] UNSPEC_FMULSU))
5834 (clobber (reg:HI 24))])
5835 (set (match_operand:HI 0 "register_operand" "")
5836 (reg:HI 22))]
5837 ""
5838 {
5839 if (AVR_HAVE_MUL)
5840 {
5841 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
5842 DONE;
5843 }
5844 })
5845
5846 (define_insn "fmulsu_insn"
5847 [(set (match_operand:HI 0 "register_operand" "=r")
5848 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5849 (match_operand:QI 2 "register_operand" "a")]
5850 UNSPEC_FMULSU))]
5851 "AVR_HAVE_MUL"
5852 "fmulsu %1,%2
5853 movw %0,r0
5854 clr __zero_reg__"
5855 [(set_attr "length" "3")
5856 (set_attr "cc" "clobber")])
5857
5858 (define_insn "*fmulsu.call"
5859 [(set (reg:HI 22)
5860 (unspec:HI [(reg:QI 24)
5861 (reg:QI 25)] UNSPEC_FMULSU))
5862 (clobber (reg:HI 24))]
5863 "!AVR_HAVE_MUL"
5864 "%~call __fmulsu"
5865 [(set_attr "type" "xcall")
5866 (set_attr "cc" "clobber")])
5867
5868 \f
5869 ;; Some combiner patterns dealing with bits.
5870 ;; See PR42210
5871
5872 ;; Move bit $3.0 into bit $0.$4
5873 (define_insn "*movbitqi.1-6.a"
5874 [(set (match_operand:QI 0 "register_operand" "=r")
5875 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5876 (match_operand:QI 2 "single_zero_operand" "n"))
5877 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
5878 (match_operand:QI 4 "const_0_to_7_operand" "n"))
5879 (match_operand:QI 5 "single_one_operand" "n"))))]
5880 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
5881 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
5882 "bst %3,0\;bld %0,%4"
5883 [(set_attr "length" "2")
5884 (set_attr "cc" "none")])
5885
5886 ;; Move bit $3.0 into bit $0.$4
5887 ;; Variation of above. Unfortunately, there is no canonicalized representation
5888 ;; of moving around bits. So what we see here depends on how user writes down
5889 ;; bit manipulations.
5890 (define_insn "*movbitqi.1-6.b"
5891 [(set (match_operand:QI 0 "register_operand" "=r")
5892 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5893 (match_operand:QI 2 "single_zero_operand" "n"))
5894 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
5895 (const_int 1))
5896 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
5897 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5898 "bst %3,0\;bld %0,%4"
5899 [(set_attr "length" "2")
5900 (set_attr "cc" "none")])
5901
5902 ;; Move bit $3.0 into bit $0.0.
5903 ;; For bit 0, combiner generates slightly different pattern.
5904 (define_insn "*movbitqi.0"
5905 [(set (match_operand:QI 0 "register_operand" "=r")
5906 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5907 (match_operand:QI 2 "single_zero_operand" "n"))
5908 (and:QI (match_operand:QI 3 "register_operand" "r")
5909 (const_int 1))))]
5910 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5911 "bst %3,0\;bld %0,0"
5912 [(set_attr "length" "2")
5913 (set_attr "cc" "none")])
5914
5915 ;; Move bit $2.0 into bit $0.7.
5916 ;; For bit 7, combiner generates slightly different pattern
5917 (define_insn "*movbitqi.7"
5918 [(set (match_operand:QI 0 "register_operand" "=r")
5919 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5920 (const_int 127))
5921 (ashift:QI (match_operand:QI 2 "register_operand" "r")
5922 (const_int 7))))]
5923 ""
5924 "bst %2,0\;bld %0,7"
5925 [(set_attr "length" "2")
5926 (set_attr "cc" "none")])
5927
5928 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
5929 ;; and input/output match. We provide a special pattern for this, because
5930 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
5931 ;; operation on I/O is atomic.
5932 (define_insn "*insv.io"
5933 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
5934 (const_int 1)
5935 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
5936 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
5937 ""
5938 "@
5939 cbi %i0,%1
5940 sbi %i0,%1
5941 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
5942 [(set_attr "length" "1,1,4")
5943 (set_attr "cc" "none")])
5944
5945 (define_insn "*insv.not.io"
5946 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5947 (const_int 1)
5948 (match_operand:QI 1 "const_0_to_7_operand" "n"))
5949 (not:QI (match_operand:QI 2 "register_operand" "r")))]
5950 ""
5951 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
5952 [(set_attr "length" "4")
5953 (set_attr "cc" "none")])
5954
5955 ;; The insv expander.
5956 ;; We only support 1-bit inserts
5957 (define_expand "insv"
5958 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
5959 (match_operand:QI 1 "const1_operand" "") ; width
5960 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
5961 (match_operand:QI 3 "nonmemory_operand" ""))]
5962 "optimize"
5963 "")
5964
5965 ;; Insert bit $2.0 into $0.$1
5966 (define_insn "*insv.reg"
5967 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
5968 (const_int 1)
5969 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
5970 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
5971 ""
5972 "@
5973 bst %2,0\;bld %0,%1
5974 andi %0,lo8(~(1<<%1))
5975 ori %0,lo8(1<<%1)
5976 clt\;bld %0,%1
5977 set\;bld %0,%1"
5978 [(set_attr "length" "2,1,1,2,2")
5979 (set_attr "cc" "none,set_zn,set_zn,none,none")])
5980
5981 \f
5982 ;; Some combine patterns that try to fix bad code when a value is composed
5983 ;; from byte parts like in PR27663.
5984 ;; The patterns give some release but the code still is not optimal,
5985 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
5986 ;; That switch obfuscates things here and in many other places.
5987
5988 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
5989 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
5990 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
5991 [(set (match_operand:HISI 0 "register_operand" "=r")
5992 (xior:HISI
5993 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5994 (match_operand:HISI 2 "register_operand" "0")))]
5995 ""
5996 "#"
5997 "reload_completed"
5998 [(set (match_dup 3)
5999 (xior:QI (match_dup 3)
6000 (match_dup 1)))]
6001 {
6002 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6003 })
6004
6005 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6006 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6007 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6008 [(set (match_operand:HISI 0 "register_operand" "=r")
6009 (xior:HISI
6010 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6011 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6012 (match_operand:HISI 3 "register_operand" "0")))]
6013 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6014 "#"
6015 "&& reload_completed"
6016 [(set (match_dup 4)
6017 (xior:QI (match_dup 4)
6018 (match_dup 1)))]
6019 {
6020 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6021 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6022 })
6023
6024 (define_expand "extzv"
6025 [(set (match_operand:QI 0 "register_operand" "")
6026 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6027 (match_operand:QI 2 "const1_operand" "")
6028 (match_operand:QI 3 "const_0_to_7_operand" "")))]
6029 ""
6030 "")
6031
6032 (define_insn "*extzv"
6033 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6034 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6035 (const_int 1)
6036 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6037 ""
6038 "@
6039 andi %0,1
6040 mov %0,%1\;andi %0,1
6041 lsr %0\;andi %0,1
6042 swap %0\;andi %0,1
6043 bst %1,%2\;clr %0\;bld %0,0"
6044 [(set_attr "length" "1,2,2,2,3")
6045 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6046
6047 (define_insn_and_split "*extzv.qihi1"
6048 [(set (match_operand:HI 0 "register_operand" "=r")
6049 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6050 (const_int 1)
6051 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6052 ""
6053 "#"
6054 ""
6055 [(set (match_dup 3)
6056 (zero_extract:QI (match_dup 1)
6057 (const_int 1)
6058 (match_dup 2)))
6059 (set (match_dup 4)
6060 (const_int 0))]
6061 {
6062 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6063 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6064 })
6065
6066 (define_insn_and_split "*extzv.qihi2"
6067 [(set (match_operand:HI 0 "register_operand" "=r")
6068 (zero_extend:HI
6069 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6070 (const_int 1)
6071 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6072 ""
6073 "#"
6074 ""
6075 [(set (match_dup 3)
6076 (zero_extract:QI (match_dup 1)
6077 (const_int 1)
6078 (match_dup 2)))
6079 (set (match_dup 4)
6080 (const_int 0))]
6081 {
6082 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6083 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6084 })
6085
6086 \f
6087 (include "avr-dimode.md")