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