]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/avr/avr.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / avr / avr.md
1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
4 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
5
6 ;; This file is part of GCC.
7
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22 ;; Special characters after '%':
23 ;; A No effect (add 0).
24 ;; B Add 1 to REG number, MEM address or CONST_INT.
25 ;; C Add 2.
26 ;; D Add 3.
27 ;; E reg number in XEXP(x, 0).
28 ;; F Add 1 to reg number.
29 ;; I reg number in XEXP(XEXP(x, 0), 0).
30 ;; J Add 1 to reg number.
31 ;; j Branch condition.
32 ;; k Reverse branch condition.
33 ;;..m..Constant Direct Data memory address.
34 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
35 ;; RAM address. The resulting address is suitable to be used in IN/OUT.
36 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
37 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
38 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
39 ;; r Print a REG without the register prefix 'r'.
40 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
41 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
42 ;; just cashes the operand for the next %T. The second %T gets
43 ;; a CONST_INT that represents a bit position.
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
45 ;; "%T0%T1" it will print "r19,5".
46 ;; Notice that you must not write a comma between %T0 and %T1.
47 ;; T/t Similar to above, but don't print the comma and the bit number.
48 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
49 ;; "%T0%t1" it will print "r19".
50 ;;..x..Constant Direct Program memory address.
51 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
52 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
53
54
55 (define_constants
56 [(REG_X 26)
57 (REG_Y 28)
58 (REG_Z 30)
59 (REG_W 24)
60 (REG_SP 32)
61 (REG_CC 36)
62 (LPM_REGNO 0) ; implicit target register of LPM
63 (TMP_REGNO 0) ; temporary register r0
64 (ZERO_REGNO 1) ; zero register r1
65 ])
66
67 (define_constants
68 [(TMP_REGNO_TINY 16) ; r16 is temp register for AVR_TINY
69 (ZERO_REGNO_TINY 17) ; r17 is zero register for AVR_TINY
70 ])
71
72 (define_c_enum "unspec"
73 [UNSPEC_STRLEN
74 UNSPEC_CPYMEM
75 UNSPEC_INDEX_JMP
76 UNSPEC_FMUL
77 UNSPEC_FMULS
78 UNSPEC_FMULSU
79 UNSPEC_COPYSIGN
80 UNSPEC_IDENTITY
81 UNSPEC_INSERT_BITS
82 UNSPEC_ROUND
83 ])
84
85 (define_c_enum "unspecv"
86 [UNSPECV_PROLOGUE_SAVES
87 UNSPECV_EPILOGUE_RESTORES
88 UNSPECV_WRITE_SP
89 UNSPECV_GASISR
90 UNSPECV_GOTO_RECEIVER
91 UNSPECV_ENABLE_IRQS
92 UNSPECV_MEMORY_BARRIER
93 UNSPECV_NOP
94 UNSPECV_SLEEP
95 UNSPECV_WDR
96 UNSPECV_DELAY_CYCLES
97 ])
98
99 ;; Chunk numbers for __gcc_isr are hard-coded in GAS.
100 (define_constants
101 [(GASISR_Prologue 1)
102 (GASISR_Epilogue 2)
103 (GASISR_Done 0)
104 ])
105
106 (include "predicates.md")
107 (include "constraints.md")
108
109 ;; Condition code settings.
110 (define_attr "cc" "none,set_czn,set_zn,set_vzn,set_n,compare,clobber,
111 plus,ldi"
112 (const_string "none"))
113
114 (define_attr "type" "branch,branch1,arith,xcall"
115 (const_string "arith"))
116
117 ;; The size of instructions in bytes.
118 ;; XXX may depend from "cc"
119
120 (define_attr "length" ""
121 (cond [(eq_attr "type" "branch")
122 (if_then_else (and (ge (minus (pc) (match_dup 0))
123 (const_int -62))
124 (le (minus (pc) (match_dup 0))
125 (const_int 62)))
126 (const_int 1)
127 (if_then_else (and (ge (minus (pc) (match_dup 0))
128 (const_int -2044))
129 (le (minus (pc) (match_dup 0))
130 (const_int 2045)))
131 (const_int 2)
132 (const_int 3)))
133 (eq_attr "type" "branch1")
134 (if_then_else (and (ge (minus (pc) (match_dup 0))
135 (const_int -62))
136 (le (minus (pc) (match_dup 0))
137 (const_int 61)))
138 (const_int 2)
139 (if_then_else (and (ge (minus (pc) (match_dup 0))
140 (const_int -2044))
141 (le (minus (pc) (match_dup 0))
142 (const_int 2043)))
143 (const_int 3)
144 (const_int 4)))
145 (eq_attr "type" "xcall")
146 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
147 (const_int 1)
148 (const_int 2))]
149 (const_int 2)))
150
151 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
152 ;; Following insn attribute tells if and how the adjustment has to be
153 ;; done:
154 ;; no No adjustment needed; attribute "length" is fine.
155 ;; Otherwise do special processing depending on the attribute.
156
157 (define_attr "adjust_len"
158 "out_bitop, plus, addto_sp, sext,
159 tsthi, tstpsi, tstsi, compare, compare64, call,
160 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
161 ufract, sfract, round,
162 xload, cpymem,
163 ashlqi, ashrqi, lshrqi,
164 ashlhi, ashrhi, lshrhi,
165 ashlsi, ashrsi, lshrsi,
166 ashlpsi, ashrpsi, lshrpsi,
167 insert_bits, insv_notbit, insv_notbit_0, insv_notbit_7,
168 no"
169 (const_string "no"))
170
171 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
172
173 ;; mov : ISA has no MOVW movw : ISA has MOVW
174 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
175 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
176 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
177 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
178 ;; no_xmega: non-XMEGA core xmega : XMEGA core
179 ;; no_tiny: non-TINY core tiny : TINY core
180
181 (define_attr "isa"
182 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, no_tiny,tiny,
183 standard"
184 (const_string "standard"))
185
186 (define_attr "enabled" ""
187 (cond [(eq_attr "isa" "standard")
188 (const_int 1)
189
190 (and (eq_attr "isa" "mov")
191 (match_test "!AVR_HAVE_MOVW"))
192 (const_int 1)
193
194 (and (eq_attr "isa" "movw")
195 (match_test "AVR_HAVE_MOVW"))
196 (const_int 1)
197
198 (and (eq_attr "isa" "rjmp")
199 (match_test "!AVR_HAVE_JMP_CALL"))
200 (const_int 1)
201
202 (and (eq_attr "isa" "jmp")
203 (match_test "AVR_HAVE_JMP_CALL"))
204 (const_int 1)
205
206 (and (eq_attr "isa" "ijmp")
207 (match_test "!AVR_HAVE_EIJMP_EICALL"))
208 (const_int 1)
209
210 (and (eq_attr "isa" "eijmp")
211 (match_test "AVR_HAVE_EIJMP_EICALL"))
212 (const_int 1)
213
214 (and (eq_attr "isa" "lpm")
215 (match_test "!AVR_HAVE_LPMX"))
216 (const_int 1)
217
218 (and (eq_attr "isa" "lpmx")
219 (match_test "AVR_HAVE_LPMX"))
220 (const_int 1)
221
222 (and (eq_attr "isa" "elpm")
223 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
224 (const_int 1)
225
226 (and (eq_attr "isa" "elpmx")
227 (match_test "AVR_HAVE_ELPMX"))
228 (const_int 1)
229
230 (and (eq_attr "isa" "xmega")
231 (match_test "AVR_XMEGA"))
232 (const_int 1)
233
234 (and (eq_attr "isa" "tiny")
235 (match_test "AVR_TINY"))
236 (const_int 1)
237
238 (and (eq_attr "isa" "no_xmega")
239 (match_test "!AVR_XMEGA"))
240 (const_int 1)
241
242 (and (eq_attr "isa" "no_tiny")
243 (match_test "!AVR_TINY"))
244 (const_int 1)
245
246 ] (const_int 0)))
247
248
249 ;; Define mode iterators
250 (define_mode_iterator QIHI [QI HI])
251 (define_mode_iterator QIHI2 [QI HI])
252 (define_mode_iterator QISI [QI HI PSI SI])
253 (define_mode_iterator QIDI [QI HI PSI SI DI])
254 (define_mode_iterator HISI [HI PSI SI])
255
256 (define_mode_iterator ALL1 [QI QQ UQQ])
257 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
258 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
259
260 ;; All supported move-modes
261 (define_mode_iterator MOVMODE [QI QQ UQQ
262 HI HQ UHQ HA UHA
263 SI SQ USQ SA USA
264 SF PSI])
265
266 ;; Supported ordered modes that are 2, 3, 4 bytes wide
267 (define_mode_iterator ORDERED234 [HI SI PSI
268 HQ UHQ HA UHA
269 SQ USQ SA USA])
270
271 ;; Post-reload split of 3, 4 bytes wide moves.
272 (define_mode_iterator SPLIT34 [SI SF PSI
273 SQ USQ SA USA])
274
275 ;; Define code iterators
276 ;; Define two incarnations so that we can build the cross product.
277 (define_code_iterator any_extend [sign_extend zero_extend])
278 (define_code_iterator any_extend2 [sign_extend zero_extend])
279 (define_code_iterator any_extract [sign_extract zero_extract])
280 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
281
282 (define_code_iterator bitop [xor ior and])
283 (define_code_iterator xior [xor ior])
284 (define_code_iterator eqne [eq ne])
285
286 (define_code_iterator ss_addsub [ss_plus ss_minus])
287 (define_code_iterator us_addsub [us_plus us_minus])
288 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
289
290 ;; Define code attributes
291 (define_code_attr extend_su
292 [(sign_extend "s")
293 (zero_extend "u")])
294
295 (define_code_attr extend_u
296 [(sign_extend "")
297 (zero_extend "u")])
298
299 (define_code_attr extend_s
300 [(sign_extend "s")
301 (zero_extend "")])
302
303 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
304 (define_code_attr mul_r_d
305 [(zero_extend "r")
306 (sign_extend "d")])
307
308 (define_code_attr abelian
309 [(ss_minus "") (us_minus "")
310 (ss_plus "%") (us_plus "%")])
311
312 ;; Map RTX code to its standard insn name
313 (define_code_attr code_stdname
314 [(ashift "ashl")
315 (ashiftrt "ashr")
316 (lshiftrt "lshr")
317 (ior "ior")
318 (xor "xor")
319 (rotate "rotl")
320 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
321 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
322 ])
323
324 ;;========================================================================
325 ;; The following is used by nonlocal_goto and setjmp.
326 ;; The receiver pattern will create no instructions since internally
327 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
328 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
329 ;; The 'null' receiver also avoids problems with optimisation
330 ;; not recognising incoming jmp and removing code that resets frame_pointer.
331 ;; The code derived from builtins.c.
332
333 (define_expand "nonlocal_goto_receiver"
334 [(set (reg:HI REG_Y)
335 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
336 ""
337 {
338 rtx offset = gen_int_mode (targetm.starting_frame_offset (), Pmode);
339 emit_move_insn (virtual_stack_vars_rtx,
340 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, offset));
341 /* ; This might change the hard frame pointer in ways that aren't
342 ; apparent to early optimization passes, so force a clobber. */
343 emit_clobber (hard_frame_pointer_rtx);
344 DONE;
345 })
346
347
348 ;; Defining nonlocal_goto_receiver means we must also define this
349 ;; even though its function is identical to that in builtins.c
350
351 (define_expand "nonlocal_goto"
352 [(use (match_operand 0 "general_operand"))
353 (use (match_operand 1 "general_operand"))
354 (use (match_operand 2 "general_operand"))
355 (use (match_operand 3 "general_operand"))]
356 ""
357 {
358 rtx r_label = copy_to_reg (operands[1]);
359 rtx r_fp = operands[3];
360 rtx r_sp = operands[2];
361
362 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
363
364 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
365
366 emit_move_insn (hard_frame_pointer_rtx, r_fp);
367 emit_stack_restore (SAVE_NONLOCAL, r_sp);
368
369 emit_use (hard_frame_pointer_rtx);
370 emit_use (stack_pointer_rtx);
371
372 emit_indirect_jump (r_label);
373
374 DONE;
375 })
376
377 ;; "pushqi1"
378 ;; "pushqq1" "pushuqq1"
379 (define_insn "push<mode>1"
380 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
381 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
382 ""
383 "@
384 push %0
385 push __zero_reg__"
386 [(set_attr "length" "1,1")])
387
388 (define_insn "pushhi1_insn"
389 [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
390 (match_operand:HI 0 "register_operand" "r"))]
391 ""
392 "push %B0\;push %A0"
393 [(set_attr "length" "2")])
394
395 ;; All modes for a multi-byte push. We must include complex modes here too,
396 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
397 (define_mode_iterator MPUSH
398 [CQI
399 HI CHI HA UHA HQ UHQ
400 SI CSI SA USA SQ USQ
401 DI CDI DA UDA DQ UDQ
402 TA UTA
403 SF DF SC DC
404 PSI])
405
406 (define_expand "push<mode>1"
407 [(match_operand:MPUSH 0 "" "")]
408 ""
409 {
410 if (MEM_P (operands[0])
411 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0])))
412 {
413 // Avoid (subreg (mem)) for non-generic address spaces. Because
414 // of the poor addressing capabilities of these spaces it's better to
415 // load them in one chunk. And it avoids PR61443.
416
417 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]);
418 }
419 else if (REG_P (operands[0])
420 && IN_RANGE (REGNO (operands[0]), FIRST_VIRTUAL_REGISTER,
421 LAST_VIRTUAL_REGISTER))
422 {
423 // Byte-wise pushing of virtual regs might result in something like
424 //
425 // (set (mem:QI (post_dec:HI (reg:HI 32 SP)))
426 // (subreg:QI (plus:HI (reg:HI 28)
427 // (const_int 17)) 0))
428 //
429 // after elimination. This cannot be handled by reload, cf. PR64452.
430 // Reload virtuals in one chunk. That way it's possible to reload
431 // above situation and finally
432 //
433 // (set (reg:HI **)
434 // (const_int 17))
435 // (set (reg:HI **)
436 // (plus:HI (reg:HI **)
437 // (reg:HI 28)))
438 // (set (mem:HI (post_dec:HI (reg:HI 32 SP))
439 // (reg:HI **)))
440
441 emit_insn (gen_pushhi1_insn (operands[0]));
442 DONE;
443 }
444
445 for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
446 {
447 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
448 if (part != const0_rtx)
449 part = force_reg (QImode, part);
450 emit_insn (gen_pushqi1 (part));
451 }
452 DONE;
453 })
454
455 ;; Notice a special-case when adding N to SP where N results in a
456 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
457 (define_split
458 [(set (reg:HI REG_SP)
459 (match_operand:HI 0 "register_operand" ""))]
460 "reload_completed
461 && frame_pointer_needed
462 && !cfun->calls_alloca
463 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)
464 && REGNO (operands[0]) != REG_Y"
465 [(set (reg:HI REG_SP)
466 (reg:HI REG_Y))])
467
468 ;;========================================================================
469 ;; Move stuff around
470
471 ;; "loadqi_libgcc"
472 ;; "loadhi_libgcc"
473 ;; "loadpsi_libgcc"
474 ;; "loadsi_libgcc"
475 ;; "loadsf_libgcc"
476 (define_expand "load<mode>_libgcc"
477 [(set (match_dup 3)
478 (match_dup 2))
479 (set (reg:MOVMODE 22)
480 (match_operand:MOVMODE 1 "memory_operand" ""))
481 (set (match_operand:MOVMODE 0 "register_operand" "")
482 (reg:MOVMODE 22))]
483 "avr_load_libgcc_p (operands[1])"
484 {
485 operands[3] = gen_rtx_REG (HImode, REG_Z);
486 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
487 operands[1] = replace_equiv_address (operands[1], operands[3]);
488 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
489 })
490
491 ;; "load_qi_libgcc"
492 ;; "load_hi_libgcc"
493 ;; "load_psi_libgcc"
494 ;; "load_si_libgcc"
495 ;; "load_sf_libgcc"
496 (define_insn_and_split "load_<mode>_libgcc"
497 [(set (reg:MOVMODE 22)
498 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
499 "avr_load_libgcc_p (operands[0])
500 && REG_P (XEXP (operands[0], 0))
501 && REG_Z == REGNO (XEXP (operands[0], 0))"
502 "#"
503 "&& reload_completed"
504 [(parallel [(set (reg:MOVMODE 22)
505 (match_dup 0))
506 (clobber (reg:CC REG_CC))])]
507 ""
508 [(set_attr "isa" "rjmp,jmp")])
509
510 (define_insn "*load_<mode>_libgcc"
511 [(set (reg:MOVMODE 22)
512 (match_operand:MOVMODE 0 "memory_operand" "m,m"))
513 (clobber (reg:CC REG_CC))]
514 "avr_load_libgcc_p (operands[0])
515 && REG_P (XEXP (operands[0], 0))
516 && REG_Z == REGNO (XEXP (operands[0], 0))
517 && reload_completed"
518 {
519 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
520 return "%~call __load_%0";
521 }
522 [(set_attr "length" "1,2")
523 (set_attr "isa" "rjmp,jmp")])
524
525
526 ;; "xload8qi_A"
527 ;; "xload8qq_A" "xload8uqq_A"
528 (define_insn_and_split "xload8<mode>_A"
529 [(set (match_operand:ALL1 0 "register_operand" "=r")
530 (match_operand:ALL1 1 "memory_operand" "m"))
531 (clobber (reg:HI REG_Z))]
532 "can_create_pseudo_p()
533 && !avr_xload_libgcc_p (<MODE>mode)
534 && avr_mem_memx_p (operands[1])
535 && REG_P (XEXP (operands[1], 0))"
536 { gcc_unreachable(); }
537 "&& 1"
538 [(clobber (const_int 0))]
539 {
540 /* ; Split away the high part of the address. GCC's register allocator
541 ; in not able to allocate segment registers and reload the resulting
542 ; expressions. Notice that no address register can hold a PSImode. */
543
544 rtx_insn *insn;
545 rtx addr = XEXP (operands[1], 0);
546 rtx hi8 = gen_reg_rtx (QImode);
547 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
548
549 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
550 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
551
552 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
553 set_mem_addr_space (SET_SRC (single_set (insn)),
554 MEM_ADDR_SPACE (operands[1]));
555 DONE;
556 })
557
558 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
559 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
560 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
561 ;; "xloadpsi_A"
562 ;; "xloadsf_A"
563 (define_insn_and_split "xload<mode>_A"
564 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
565 (match_operand:MOVMODE 1 "memory_operand" "m"))
566 (clobber (reg:MOVMODE 22))
567 (clobber (reg:QI 21))
568 (clobber (reg:HI REG_Z))]
569 "can_create_pseudo_p()
570 && avr_mem_memx_p (operands[1])
571 && REG_P (XEXP (operands[1], 0))"
572 { gcc_unreachable(); }
573 "&& 1"
574 [(clobber (const_int 0))]
575 {
576 rtx addr = XEXP (operands[1], 0);
577 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
578 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
579 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
580 rtx_insn *insn;
581
582 /* Split the address to R21:Z */
583 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
584 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
585
586 /* Load with code from libgcc */
587 insn = emit_insn (gen_xload_<mode>_libgcc ());
588 set_mem_addr_space (SET_SRC (single_set (insn)), as);
589
590 /* Move to destination */
591 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
592
593 DONE;
594 })
595
596 ;; Move value from address space memx to a register
597 ;; These insns must be prior to respective generic move insn.
598
599 ;; "xloadqi_8"
600 ;; "xloadqq_8" "xloaduqq_8"
601 (define_insn "xload<mode>_8"
602 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
603 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
604 (reg:HI REG_Z))))]
605 "!avr_xload_libgcc_p (<MODE>mode)"
606 {
607 return avr_out_xload (insn, operands, NULL);
608 }
609 [(set_attr "length" "4,4")
610 (set_attr "adjust_len" "*,xload")
611 (set_attr "isa" "lpmx,lpm")])
612
613 ;; R21:Z : 24-bit source address
614 ;; R22 : 1-4 byte output
615
616 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
617 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
618 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
619 ;; "xload_sf_libgcc"
620 ;; "xload_psi_libgcc"
621
622 (define_insn_and_split "xload_<mode>_libgcc"
623 [(set (reg:MOVMODE 22)
624 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
625 (reg:HI REG_Z))))
626 (clobber (reg:QI 21))
627 (clobber (reg:HI REG_Z))]
628 "avr_xload_libgcc_p (<MODE>mode)"
629 "#"
630 "&& reload_completed"
631 [(parallel [(set (reg:MOVMODE 22)
632 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
633 (reg:HI REG_Z))))
634 (clobber (reg:CC REG_CC))])])
635
636 (define_insn "*xload_<mode>_libgcc"
637 [(set (reg:MOVMODE 22)
638 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
639 (reg:HI REG_Z))))
640 (clobber (reg:CC REG_CC))]
641 "avr_xload_libgcc_p (<MODE>mode)
642 && reload_completed"
643 {
644 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
645
646 output_asm_insn ("%~call __xload_%0", &x_bytes);
647 return "";
648 }
649 [(set_attr "type" "xcall")])
650
651
652 ;; General move expanders
653
654 ;; "movqi" "movqq" "movuqq"
655 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
656 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
657 ;; "movsf"
658 ;; "movpsi"
659 (define_expand "mov<mode>"
660 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
661 (match_operand:MOVMODE 1 "general_operand" ""))]
662 ""
663 {
664 rtx dest = operands[0];
665 rtx src = avr_eval_addr_attrib (operands[1]);
666
667 if (avr_mem_flash_p (dest))
668 DONE;
669
670 if (QImode == <MODE>mode
671 && SUBREG_P (src)
672 && CONSTANT_ADDRESS_P (SUBREG_REG (src))
673 && can_create_pseudo_p())
674 {
675 // store_bitfield may want to store a SYMBOL_REF or CONST in a
676 // structure that's represented as PSImode. As the upper 16 bits
677 // of PSImode cannot be expressed as an HImode subreg, the rhs is
678 // decomposed into QImode (word_mode) subregs of SYMBOL_REF,
679 // CONST or LABEL_REF; cf. PR71103.
680
681 rtx const_addr = SUBREG_REG (src);
682 operands[1] = src = copy_rtx (src);
683 SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr);
684 }
685
686 /* One of the operands has to be in a register. */
687 if (!register_operand (dest, <MODE>mode)
688 && !reg_or_0_operand (src, <MODE>mode))
689 {
690 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
691 }
692
693 if (avr_mem_memx_p (src))
694 {
695 rtx addr = XEXP (src, 0);
696
697 if (!REG_P (addr))
698 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
699
700 if (!avr_xload_libgcc_p (<MODE>mode))
701 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
702 ; insn-emit does not depend on the mode, it's all about operands. */
703 emit_insn (gen_xload8qi_A (dest, src));
704 else
705 emit_insn (gen_xload<mode>_A (dest, src));
706
707 DONE;
708 }
709
710 if (avr_load_libgcc_p (src))
711 {
712 /* For the small devices, do loads per libgcc call. */
713 emit_insn (gen_load<mode>_libgcc (dest, src));
714 DONE;
715 }
716 })
717
718 ;;========================================================================
719 ;; move byte
720 ;; The last alternative (any immediate constant to any register) is
721 ;; very expensive. It should be optimized by peephole2 if a scratch
722 ;; register is available, but then that register could just as well be
723 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
724 ;; are call-saved registers, and most of LD_REGS are call-used registers,
725 ;; so this may still be a win for registers live across function calls.
726
727 (define_insn_and_split "mov<mode>_insn_split"
728 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
729 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
730 "register_operand (operands[0], <MODE>mode)
731 || reg_or_0_operand (operands[1], <MODE>mode)"
732 "#"
733 "&& reload_completed"
734 [(parallel [(set (match_dup 0)
735 (match_dup 1))
736 (clobber (reg:CC REG_CC))])])
737
738 ;; "movqi_insn"
739 ;; "movqq_insn" "movuqq_insn"
740 (define_insn "mov<mode>_insn"
741 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
742 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))
743 (clobber (reg:CC REG_CC))]
744 "(register_operand (operands[0], <MODE>mode)
745 || reg_or_0_operand (operands[1], <MODE>mode))
746 && reload_completed"
747 {
748 return output_movqi (insn, operands, NULL);
749 }
750 [(set_attr "length" "1,1,5,5,1,1,4")
751 (set_attr "adjust_len" "mov8")])
752
753 ;; This is used in peephole2 to optimize loading immediate constants
754 ;; if a scratch register from LD_REGS happens to be available.
755
756 ;; "*reload_inqi"
757 ;; "*reload_inqq" "*reload_inuqq"
758 (define_insn "*reload_in<mode>"
759 [(set (match_operand:ALL1 0 "register_operand" "=l")
760 (match_operand:ALL1 1 "const_operand" "i"))
761 (clobber (match_operand:QI 2 "register_operand" "=&d"))
762 (clobber (reg:CC REG_CC))]
763 "reload_completed"
764 "ldi %2,lo8(%1)
765 mov %0,%2"
766 [(set_attr "length" "2")])
767
768 (define_peephole2
769 [(match_scratch:QI 2 "d")
770 (parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
771 (match_operand:ALL1 1 "const_operand" ""))
772 (clobber (reg:CC REG_CC))])]
773 ; No need for a clobber reg for 0x0, 0x01 or 0xff
774 "!satisfies_constraint_Y00 (operands[1])
775 && !satisfies_constraint_Y01 (operands[1])
776 && !satisfies_constraint_Ym1 (operands[1])"
777 [(parallel [(set (match_dup 0)
778 (match_dup 1))
779 (clobber (match_dup 2))
780 (clobber (reg:CC REG_CC))])])
781
782 ;;============================================================================
783 ;; move word (16 bit)
784
785 ;; Move register $1 to the Stack Pointer register SP.
786 ;; This insn is emit during function prologue/epilogue generation.
787 ;; $2 = 0: We know that IRQs are off
788 ;; $2 = 1: We know that IRQs are on
789 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
790 ;; $2 = -1: We don't know anything about IRQ on/off
791 ;; Always write SP via unspec, see PR50063
792
793 (define_insn "movhi_sp_r"
794 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
795 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
796 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
797 UNSPECV_WRITE_SP))]
798 ""
799 "@
800 out %B0,%B1\;out %A0,%A1
801 cli\;out %B0,%B1\;sei\;out %A0,%A1
802 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
803 out %A0,%A1
804 out %A0,%A1\;out %B0,%B1"
805 [(set_attr "length" "2,4,5,1,2")
806 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")])
807
808 (define_peephole2
809 [(match_scratch:QI 2 "d")
810 (parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
811 (match_operand:ALL2 1 "const_or_immediate_operand" ""))
812 (clobber (reg:CC REG_CC))])]
813 "operands[1] != CONST0_RTX (<MODE>mode)"
814 [(parallel [(set (match_dup 0)
815 (match_dup 1))
816 (clobber (match_dup 2))
817 (clobber (reg:CC REG_CC))])])
818
819 ;; '*' because it is not used in rtl generation, only in above peephole
820 ;; "*reload_inhi"
821 ;; "*reload_inhq" "*reload_inuhq"
822 ;; "*reload_inha" "*reload_inuha"
823 (define_insn "*reload_in<mode>"
824 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
825 (match_operand:ALL2 1 "immediate_operand" "i"))
826 (clobber (match_operand:QI 2 "register_operand" "=&d"))
827 (clobber (reg:CC REG_CC))]
828 "reload_completed"
829 {
830 return output_reload_inhi (operands, operands[2], NULL);
831 }
832 [(set_attr "length" "4")
833 (set_attr "adjust_len" "reload_in16")])
834
835 ;; "*movhi"
836 ;; "*movhq" "*movuhq"
837 ;; "*movha" "*movuha"
838 (define_insn_and_split "*mov<mode>_split"
839 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
840 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
841 "register_operand (operands[0], <MODE>mode)
842 || reg_or_0_operand (operands[1], <MODE>mode)"
843 "#"
844 "&& reload_completed"
845 [(parallel [(set (match_dup 0)
846 (match_dup 1))
847 (clobber (reg:CC REG_CC))])])
848
849 (define_insn "*mov<mode>"
850 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
851 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))
852 (clobber (reg:CC REG_CC))]
853 "(register_operand (operands[0], <MODE>mode)
854 || reg_or_0_operand (operands[1], <MODE>mode))
855 && reload_completed"
856 {
857 return output_movhi (insn, operands, NULL);
858 }
859 [(set_attr "length" "2,2,6,7,2,6,5,2")
860 (set_attr "adjust_len" "mov16")])
861
862 (define_peephole2 ; movw
863 [(parallel [(set (match_operand:ALL1 0 "even_register_operand" "")
864 (match_operand:ALL1 1 "even_register_operand" ""))
865 (clobber (reg:CC REG_CC))])
866 (parallel [(set (match_operand:ALL1 2 "odd_register_operand" "")
867 (match_operand:ALL1 3 "odd_register_operand" ""))
868 (clobber (reg:CC REG_CC))])]
869 "AVR_HAVE_MOVW
870 && REGNO (operands[0]) == REGNO (operands[2]) - 1
871 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
872 [(parallel [(set (match_dup 4)
873 (match_dup 5))
874 (clobber (reg:CC REG_CC))])]
875 {
876 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
877 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
878 })
879
880 (define_peephole2 ; movw_r
881 [(parallel [(set (match_operand:ALL1 0 "odd_register_operand" "")
882 (match_operand:ALL1 1 "odd_register_operand" ""))
883 (clobber (reg:CC REG_CC))])
884 (parallel [(set (match_operand:ALL1 2 "even_register_operand" "")
885 (match_operand:ALL1 3 "even_register_operand" ""))
886 (clobber (reg:CC REG_CC))])]
887 "AVR_HAVE_MOVW
888 && REGNO (operands[2]) == REGNO (operands[0]) - 1
889 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
890 [(parallel [(set (match_dup 4)
891 (match_dup 5))
892 (clobber (reg:CC REG_CC))])]
893 {
894 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
895 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
896 })
897
898 ;; For LPM loads from AS1 we split
899 ;; R = *Z
900 ;; to
901 ;; R = *Z++
902 ;; Z = Z - sizeof (R)
903 ;;
904 ;; so that the second instruction can be optimized out.
905
906 (define_split ; "split-lpmx"
907 [(set (match_operand:HISI 0 "register_operand" "")
908 (match_operand:HISI 1 "memory_operand" ""))]
909 "reload_completed
910 && AVR_HAVE_LPMX
911 && avr_mem_flash_p (operands[1])
912 && REG_P (XEXP (operands[1], 0))
913 && !reg_overlap_mentioned_p (XEXP (operands[1], 0), operands[0])"
914 [(set (match_dup 0)
915 (match_dup 2))
916 (set (match_dup 3)
917 (plus:HI (match_dup 3)
918 (match_dup 4)))]
919 {
920 rtx addr = XEXP (operands[1], 0);
921
922 operands[2] = replace_equiv_address (operands[1],
923 gen_rtx_POST_INC (Pmode, addr));
924 operands[3] = addr;
925 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
926 })
927
928 ;;==========================================================================
929 ;; xpointer move (24 bit)
930
931 (define_peephole2 ; *reload_inpsi
932 [(match_scratch:QI 2 "d")
933 (parallel [(set (match_operand:PSI 0 "l_register_operand" "")
934 (match_operand:PSI 1 "immediate_operand" ""))
935 (clobber (reg:CC REG_CC))])
936 (match_dup 2)]
937 "operands[1] != const0_rtx
938 && operands[1] != constm1_rtx"
939 [(parallel [(set (match_dup 0)
940 (match_dup 1))
941 (clobber (match_dup 2))
942 (clobber (reg:CC REG_CC))])])
943
944 ;; '*' because it is not used in rtl generation.
945 (define_insn "*reload_inpsi"
946 [(set (match_operand:PSI 0 "register_operand" "=r")
947 (match_operand:PSI 1 "immediate_operand" "i"))
948 (clobber (match_operand:QI 2 "register_operand" "=&d"))
949 (clobber (reg:CC REG_CC))]
950 "reload_completed"
951 {
952 return avr_out_reload_inpsi (operands, operands[2], NULL);
953 }
954 [(set_attr "length" "6")
955 (set_attr "adjust_len" "reload_in24")])
956
957 (define_insn_and_split "*movpsi_split"
958 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
959 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
960 "register_operand (operands[0], PSImode)
961 || register_operand (operands[1], PSImode)
962 || const0_rtx == operands[1]"
963 "#"
964 "&& reload_completed"
965 [(parallel [(set (match_dup 0)
966 (match_dup 1))
967 (clobber (reg:CC REG_CC))])])
968
969 (define_insn "*movpsi"
970 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
971 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))
972 (clobber (reg:CC REG_CC))]
973 "(register_operand (operands[0], PSImode)
974 || register_operand (operands[1], PSImode)
975 || const0_rtx == operands[1])
976 && reload_completed"
977 {
978 return avr_out_movpsi (insn, operands, NULL);
979 }
980 [(set_attr "length" "3,3,8,9,4,10")
981 (set_attr "adjust_len" "mov24")])
982
983 ;;==========================================================================
984 ;; move double word (32 bit)
985
986 (define_peephole2 ; *reload_insi
987 [(match_scratch:QI 2 "d")
988 (parallel [(set (match_operand:ALL4 0 "l_register_operand" "")
989 (match_operand:ALL4 1 "immediate_operand" ""))
990 (clobber (reg:CC REG_CC))])
991 (match_dup 2)]
992 "operands[1] != CONST0_RTX (<MODE>mode)"
993 [(parallel [(set (match_dup 0)
994 (match_dup 1))
995 (clobber (match_dup 2))
996 (clobber (reg:CC REG_CC))])])
997
998 ;; '*' because it is not used in rtl generation.
999 ;; "*reload_insi"
1000 ;; "*reload_insq" "*reload_inusq"
1001 ;; "*reload_insa" "*reload_inusa"
1002 (define_insn "*reload_insi"
1003 [(set (match_operand:ALL4 0 "register_operand" "=r")
1004 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
1005 (clobber (match_operand:QI 2 "register_operand" "=&d"))
1006 (clobber (reg:CC REG_CC))]
1007 "reload_completed"
1008 {
1009 return output_reload_insisf (operands, operands[2], NULL);
1010 }
1011 [(set_attr "length" "8")
1012 (set_attr "adjust_len" "reload_in32")])
1013
1014
1015 ;; "*movsi"
1016 ;; "*movsq" "*movusq"
1017 ;; "*movsa" "*movusa"
1018 (define_insn_and_split "*mov<mode>_split"
1019 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
1020 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
1021 "register_operand (operands[0], <MODE>mode)
1022 || reg_or_0_operand (operands[1], <MODE>mode)"
1023 "#"
1024 "&& reload_completed"
1025 [(parallel [(set (match_dup 0)
1026 (match_dup 1))
1027 (clobber (reg:CC REG_CC))])])
1028
1029 (define_insn "*mov<mode>"
1030 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
1031 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))
1032 (clobber (reg:CC REG_CC))]
1033 "(register_operand (operands[0], <MODE>mode)
1034 || reg_or_0_operand (operands[1], <MODE>mode))
1035 && reload_completed"
1036 {
1037 return output_movsisf (insn, operands, NULL);
1038 }
1039 [(set_attr "length" "4,4,8,9,4,10")
1040 (set_attr "adjust_len" "mov32")])
1041
1042 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
1043 ;; move floating point numbers (32 bit)
1044
1045 (define_insn_and_split "*movsf_split"
1046 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
1047 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
1048 "register_operand (operands[0], SFmode)
1049 || reg_or_0_operand (operands[1], SFmode)"
1050 "#"
1051 "&& reload_completed"
1052 [(parallel [(set (match_dup 0)
1053 (match_dup 1))
1054 (clobber (reg:CC REG_CC))])])
1055
1056 (define_insn "*movsf"
1057 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
1058 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))
1059 (clobber (reg:CC REG_CC))]
1060 "(register_operand (operands[0], SFmode)
1061 || reg_or_0_operand (operands[1], SFmode))
1062 && reload_completed"
1063 {
1064 return output_movsisf (insn, operands, NULL);
1065 }
1066 [(set_attr "length" "4,4,8,9,4,10")
1067 (set_attr "adjust_len" "mov32")])
1068
1069 (define_peephole2 ; *reload_insf
1070 [(match_scratch:QI 2 "d")
1071 (parallel [(set (match_operand:SF 0 "l_register_operand" "")
1072 (match_operand:SF 1 "const_double_operand" ""))
1073 (clobber (reg:CC REG_CC))])
1074 (match_dup 2)]
1075 "operands[1] != CONST0_RTX (SFmode)"
1076 [(parallel [(set (match_dup 0)
1077 (match_dup 1))
1078 (clobber (match_dup 2))
1079 (clobber (reg:CC REG_CC))])])
1080
1081 ;; '*' because it is not used in rtl generation.
1082 (define_insn "*reload_insf"
1083 [(set (match_operand:SF 0 "register_operand" "=r")
1084 (match_operand:SF 1 "const_double_operand" "F"))
1085 (clobber (match_operand:QI 2 "register_operand" "=&d"))
1086 (clobber (reg:CC REG_CC))]
1087 "reload_completed"
1088 {
1089 return output_reload_insisf (operands, operands[2], NULL);
1090 }
1091 [(set_attr "length" "8")
1092 (set_attr "adjust_len" "reload_in32")])
1093
1094 ;;=========================================================================
1095 ;; move string (like memcpy)
1096
1097 (define_expand "cpymemhi"
1098 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1099 (match_operand:BLK 1 "memory_operand" ""))
1100 (use (match_operand:HI 2 "const_int_operand" ""))
1101 (use (match_operand:HI 3 "const_int_operand" ""))])]
1102 ""
1103 {
1104 if (avr_emit_cpymemhi (operands))
1105 DONE;
1106
1107 FAIL;
1108 })
1109
1110 (define_mode_attr CPYMEM_r_d [(QI "r")
1111 (HI "wd")])
1112
1113 ;; $0 : Address Space
1114 ;; $1, $2 : Loop register
1115 ;; R30 : source address
1116 ;; R26 : destination address
1117
1118 ;; "cpymem_qi"
1119 ;; "cpymem_hi"
1120 (define_insn_and_split "cpymem_<mode>"
1121 [(set (mem:BLK (reg:HI REG_X))
1122 (mem:BLK (reg:HI REG_Z)))
1123 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1124 UNSPEC_CPYMEM)
1125 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_r_d>"))
1126 (clobber (reg:HI REG_X))
1127 (clobber (reg:HI REG_Z))
1128 (clobber (reg:QI LPM_REGNO))
1129 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
1130 ""
1131 "#"
1132 "&& reload_completed"
1133 [(parallel [(set (mem:BLK (reg:HI REG_X))
1134 (mem:BLK (reg:HI REG_Z)))
1135 (unspec [(match_dup 0)]
1136 UNSPEC_CPYMEM)
1137 (use (match_dup 1))
1138 (clobber (reg:HI REG_X))
1139 (clobber (reg:HI REG_Z))
1140 (clobber (reg:QI LPM_REGNO))
1141 (clobber (match_dup 2))
1142 (clobber (reg:CC REG_CC))])])
1143
1144 (define_insn "*cpymem_<mode>"
1145 [(set (mem:BLK (reg:HI REG_X))
1146 (mem:BLK (reg:HI REG_Z)))
1147 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1148 UNSPEC_CPYMEM)
1149 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_r_d>"))
1150 (clobber (reg:HI REG_X))
1151 (clobber (reg:HI REG_Z))
1152 (clobber (reg:QI LPM_REGNO))
1153 (clobber (match_operand:QIHI 2 "register_operand" "=1"))
1154 (clobber (reg:CC REG_CC))]
1155 "reload_completed"
1156 {
1157 return avr_out_cpymem (insn, operands, NULL);
1158 }
1159 [(set_attr "adjust_len" "cpymem")])
1160
1161
1162 ;; $0 : Address Space
1163 ;; $1 : RAMPZ RAM address
1164 ;; R24 : #bytes and loop register
1165 ;; R23:Z : 24-bit source address
1166 ;; R26 : 16-bit destination address
1167
1168 ;; "cpymemx_qi"
1169 ;; "cpymemx_hi"
1170
1171 (define_insn_and_split "cpymemx_<mode>"
1172 [(set (mem:BLK (reg:HI REG_X))
1173 (mem:BLK (lo_sum:PSI (reg:QI 23)
1174 (reg:HI REG_Z))))
1175 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1176 UNSPEC_CPYMEM)
1177 (use (reg:QIHI 24))
1178 (clobber (reg:HI REG_X))
1179 (clobber (reg:HI REG_Z))
1180 (clobber (reg:QI LPM_REGNO))
1181 (clobber (reg:HI 24))
1182 (clobber (reg:QI 23))
1183 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
1184 ""
1185 "#"
1186 "&& reload_completed"
1187 [(parallel [(set (mem:BLK (reg:HI REG_X))
1188 (mem:BLK (lo_sum:PSI (reg:QI 23)
1189 (reg:HI REG_Z))))
1190 (unspec [(match_dup 0)]
1191 UNSPEC_CPYMEM)
1192 (use (reg:QIHI 24))
1193 (clobber (reg:HI REG_X))
1194 (clobber (reg:HI REG_Z))
1195 (clobber (reg:QI LPM_REGNO))
1196 (clobber (reg:HI 24))
1197 (clobber (reg:QI 23))
1198 (clobber (mem:QI (match_dup 1)))
1199 (clobber (reg:CC REG_CC))])])
1200
1201 (define_insn "*cpymemx_<mode>"
1202 [(set (mem:BLK (reg:HI REG_X))
1203 (mem:BLK (lo_sum:PSI (reg:QI 23)
1204 (reg:HI REG_Z))))
1205 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1206 UNSPEC_CPYMEM)
1207 (use (reg:QIHI 24))
1208 (clobber (reg:HI REG_X))
1209 (clobber (reg:HI REG_Z))
1210 (clobber (reg:QI LPM_REGNO))
1211 (clobber (reg:HI 24))
1212 (clobber (reg:QI 23))
1213 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))
1214 (clobber (reg:CC REG_CC))]
1215 "reload_completed"
1216 "%~call __movmemx_<mode>"
1217 [(set_attr "type" "xcall")])
1218
1219
1220 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
1221 ;; memset (%0, %2, %1)
1222
1223 (define_expand "setmemhi"
1224 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1225 (match_operand 2 "const_int_operand" ""))
1226 (use (match_operand:HI 1 "const_int_operand" ""))
1227 (use (match_operand:HI 3 "const_int_operand" ""))
1228 (clobber (match_scratch:HI 5 ""))
1229 (clobber (match_dup 4))])]
1230 ""
1231 {
1232 rtx addr0;
1233 machine_mode mode;
1234
1235 /* If value to set is not zero, use the library routine. */
1236 if (operands[2] != const0_rtx)
1237 FAIL;
1238
1239 if (!CONST_INT_P (operands[1]))
1240 FAIL;
1241
1242 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1243 operands[4] = gen_rtx_SCRATCH (mode);
1244 operands[1] = copy_to_mode_reg (mode,
1245 gen_int_mode (INTVAL (operands[1]), mode));
1246 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1247 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1248 })
1249
1250
1251 (define_insn_and_split "*clrmemqi_split"
1252 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1253 (const_int 0))
1254 (use (match_operand:QI 1 "register_operand" "r"))
1255 (use (match_operand:QI 2 "const_int_operand" "n"))
1256 (clobber (match_scratch:HI 3 "=0"))
1257 (clobber (match_scratch:QI 4 "=&1"))]
1258 ""
1259 "#"
1260 "&& reload_completed"
1261 [(parallel [(set (mem:BLK (match_dup 0))
1262 (const_int 0))
1263 (use (match_dup 1))
1264 (use (match_dup 2))
1265 (clobber (match_dup 3))
1266 (clobber (match_dup 4))
1267 (clobber (reg:CC REG_CC))])])
1268
1269 (define_insn "*clrmemqi"
1270 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1271 (const_int 0))
1272 (use (match_operand:QI 1 "register_operand" "r"))
1273 (use (match_operand:QI 2 "const_int_operand" "n"))
1274 (clobber (match_scratch:HI 3 "=0"))
1275 (clobber (match_scratch:QI 4 "=&1"))
1276 (clobber (reg:CC REG_CC))]
1277 "reload_completed"
1278 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1279 [(set_attr "length" "3")])
1280
1281
1282 (define_insn_and_split "*clrmemhi_split"
1283 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1284 (const_int 0))
1285 (use (match_operand:HI 1 "register_operand" "!w,d"))
1286 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1287 (clobber (match_scratch:HI 3 "=0,0"))
1288 (clobber (match_scratch:HI 4 "=&1,&1"))]
1289 ""
1290 "#"
1291 "&& reload_completed"
1292 [(parallel [(set (mem:BLK (match_dup 0))
1293 (const_int 0))
1294 (use (match_dup 1))
1295 (use (match_dup 2))
1296 (clobber (match_dup 3))
1297 (clobber (match_dup 4))
1298 (clobber (reg:CC REG_CC))])])
1299
1300
1301 (define_insn "*clrmemhi"
1302 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1303 (const_int 0))
1304 (use (match_operand:HI 1 "register_operand" "!w,d"))
1305 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1306 (clobber (match_scratch:HI 3 "=0,0"))
1307 (clobber (match_scratch:HI 4 "=&1,&1"))
1308 (clobber (reg:CC REG_CC))]
1309 "reload_completed"
1310 "@
1311 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1312 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1313 [(set_attr "length" "3,4")])
1314
1315 (define_expand "strlenhi"
1316 [(set (match_dup 4)
1317 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1318 (match_operand:QI 2 "const_int_operand" "")
1319 (match_operand:HI 3 "immediate_operand" "")]
1320 UNSPEC_STRLEN))
1321 (set (match_dup 4)
1322 (plus:HI (match_dup 4)
1323 (const_int -1)))
1324 (parallel [(set (match_operand:HI 0 "register_operand" "")
1325 (minus:HI (match_dup 4)
1326 (match_dup 5)))
1327 (clobber (scratch:QI))])]
1328 ""
1329 {
1330 rtx addr;
1331 if (operands[2] != const0_rtx)
1332 FAIL;
1333 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1334 operands[1] = gen_rtx_MEM (BLKmode, addr);
1335 operands[5] = addr;
1336 operands[4] = gen_reg_rtx (HImode);
1337 })
1338
1339 (define_insn_and_split "*strlenhi_split"
1340 [(set (match_operand:HI 0 "register_operand" "=e")
1341 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1342 (const_int 0)
1343 (match_operand:HI 2 "immediate_operand" "i")]
1344 UNSPEC_STRLEN))]
1345 ""
1346 "#"
1347 "&& reload_completed"
1348 [(parallel
1349 [(set (match_dup 0)
1350 (unspec:HI [(mem:BLK (match_dup 1))
1351 (const_int 0)
1352 (match_dup 2)]
1353 UNSPEC_STRLEN))
1354 (clobber (reg:CC REG_CC))])])
1355
1356 (define_insn "*strlenhi"
1357 [(set (match_operand:HI 0 "register_operand" "=e")
1358 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1359 (const_int 0)
1360 (match_operand:HI 2 "immediate_operand" "i")]
1361 UNSPEC_STRLEN))
1362 (clobber (reg:CC REG_CC))]
1363 "reload_completed"
1364 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1365 [(set_attr "length" "3")])
1366
1367 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1368 ; add bytes
1369
1370 ;; "addqi3"
1371 ;; "addqq3" "adduqq3"
1372 (define_insn_and_split "add<mode>3"
1373 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1374 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1375 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1376 ""
1377 "#"
1378 "&& reload_completed"
1379 [(parallel [(set (match_dup 0)
1380 (plus:ALL1 (match_dup 1)
1381 (match_dup 2)))
1382 (clobber (reg:CC REG_CC))])])
1383
1384 (define_insn "*add<mode>3"
1385 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1386 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1387 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))
1388 (clobber (reg:CC REG_CC))]
1389 "reload_completed"
1390 "@
1391 add %0,%2
1392 subi %0,lo8(-(%2))
1393 inc %0
1394 dec %0
1395 inc %0\;inc %0
1396 dec %0\;dec %0"
1397 [(set_attr "length" "1,1,1,1,2,2")])
1398
1399 ;; "addhi3"
1400 ;; "addhq3" "adduhq3"
1401 ;; "addha3" "adduha3"
1402 (define_expand "add<mode>3"
1403 [(set (match_operand:ALL2 0 "register_operand" "")
1404 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1405 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1406 ""
1407 {
1408 if (CONST_INT_P (operands[2]))
1409 {
1410 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1411
1412 if (can_create_pseudo_p()
1413 && !stack_register_operand (operands[0], HImode)
1414 && !stack_register_operand (operands[1], HImode)
1415 && !d_register_operand (operands[0], HImode)
1416 && !d_register_operand (operands[1], HImode))
1417 {
1418 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1419 DONE;
1420 }
1421 }
1422
1423 if (CONST_FIXED_P (operands[2]))
1424 {
1425 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1426 DONE;
1427 }
1428 })
1429
1430
1431 (define_insn_and_split "*addhi3_zero_extend_split"
1432 [(set (match_operand:HI 0 "register_operand" "=r,*?r")
1433 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0"))
1434 (match_operand:HI 2 "register_operand" "0 ,r")))]
1435 ""
1436 "#"
1437 "&& reload_completed"
1438 [(parallel [(set (match_dup 0)
1439 (plus:HI (zero_extend:HI (match_dup 1))
1440 (match_dup 2)))
1441 (clobber (reg:CC REG_CC))])])
1442
1443 (define_insn "*addhi3_zero_extend"
1444 [(set (match_operand:HI 0 "register_operand" "=r,*?r")
1445 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0"))
1446 (match_operand:HI 2 "register_operand" "0 ,r")))
1447 (clobber (reg:CC REG_CC))]
1448 "reload_completed"
1449 "@
1450 add %A0,%1\;adc %B0,__zero_reg__
1451 add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__"
1452 [(set_attr "length" "2,3")])
1453
1454 (define_insn_and_split "*addhi3_zero_extend1_split"
1455 [(set (match_operand:HI 0 "register_operand" "=r")
1456 (plus:HI (match_operand:HI 1 "register_operand" "0")
1457 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1458 ""
1459 "#"
1460 "&& reload_completed"
1461 [(parallel [(set (match_dup 0)
1462 (plus:HI (match_dup 1)
1463 (zero_extend:HI (match_dup 2))))
1464 (clobber (reg:CC REG_CC))])])
1465
1466 (define_insn "*addhi3_zero_extend1"
1467 [(set (match_operand:HI 0 "register_operand" "=r")
1468 (plus:HI (match_operand:HI 1 "register_operand" "0")
1469 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
1470 (clobber (reg:CC REG_CC))]
1471 "reload_completed"
1472 "add %A0,%2\;adc %B0,__zero_reg__"
1473 [(set_attr "length" "2")])
1474
1475 (define_insn_and_split "*addhi3.sign_extend1_split"
1476 [(set (match_operand:HI 0 "register_operand" "=r")
1477 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1478 (match_operand:HI 2 "register_operand" "0")))]
1479 ""
1480 "#"
1481 "&& reload_completed"
1482 [(parallel
1483 [(set (match_dup 0)
1484 (plus:HI
1485 (sign_extend:HI (match_dup 1))
1486 (match_dup 2)))
1487 (clobber (reg:CC REG_CC))])])
1488
1489
1490 (define_insn "*addhi3.sign_extend1"
1491 [(set (match_operand:HI 0 "register_operand" "=r")
1492 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1493 (match_operand:HI 2 "register_operand" "0")))
1494 (clobber (reg:CC REG_CC))]
1495 "reload_completed"
1496 {
1497 return reg_overlap_mentioned_p (operands[0], operands[1])
1498 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1499 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1500 }
1501 [(set_attr "length" "5")])
1502
1503 (define_insn_and_split "*addhi3_zero_extend.const_split"
1504 [(set (match_operand:HI 0 "register_operand" "=d")
1505 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1506 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))]
1507 ""
1508 "#"
1509 "&& reload_completed"
1510 [(parallel [(set (match_dup 0)
1511 (plus:HI (zero_extend:HI (match_dup 1))
1512 (match_dup 2)))
1513 (clobber (reg:CC REG_CC))])])
1514
1515 (define_insn "*addhi3_zero_extend.const"
1516 [(set (match_operand:HI 0 "register_operand" "=d")
1517 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1518 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))
1519 (clobber (reg:CC REG_CC))]
1520 "reload_completed"
1521 "subi %A0,%n2\;sbc %B0,%B0"
1522 [(set_attr "length" "2")])
1523
1524 (define_insn_and_split "*usum_widenqihi3_split"
1525 [(set (match_operand:HI 0 "register_operand" "=r")
1526 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1527 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1528 ""
1529 "#"
1530 "&& reload_completed"
1531 [(parallel [(set (match_dup 0)
1532 (plus:HI
1533 (zero_extend:HI (match_dup 1))
1534 (zero_extend:HI (match_dup 2))))
1535 (clobber (reg:CC REG_CC))])])
1536
1537
1538 (define_insn "*usum_widenqihi3"
1539 [(set (match_operand:HI 0 "register_operand" "=r")
1540 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1541 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
1542 (clobber (reg:CC REG_CC))]
1543 "reload_completed"
1544 "add %A0,%2\;clr %B0\;rol %B0"
1545 [(set_attr "length" "3")])
1546
1547 (define_insn_and_split "*udiff_widenqihi3_split"
1548 [(set (match_operand:HI 0 "register_operand" "=r")
1549 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1550 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1551 ""
1552 "#"
1553 "&& reload_completed"
1554 [(parallel [(set (match_dup 0)
1555 (minus:HI (zero_extend:HI (match_dup 1))
1556 (zero_extend:HI (match_dup 2))))
1557 (clobber (reg:CC REG_CC))])])
1558
1559 (define_insn "*udiff_widenqihi3"
1560 [(set (match_operand:HI 0 "register_operand" "=r")
1561 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1562 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
1563 (clobber (reg:CC REG_CC))]
1564 "reload_completed"
1565 "sub %A0,%2\;sbc %B0,%B0"
1566 [(set_attr "length" "2")])
1567
1568 (define_insn_and_split "*addhi3_sp"
1569 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1570 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1571 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1572 ""
1573 {
1574 return avr_out_addto_sp (operands, NULL);
1575 }
1576 ""
1577 [(const_int 0)]
1578 {
1579 /* Do not attempt to split this pattern. This FAIL is necessary
1580 to prevent the splitter from matching *add<ALL2>3_split, splitting
1581 it, and then failing later because constraints don't match, as split
1582 does not look at constraints. */
1583 FAIL;
1584 }
1585 [(set_attr "length" "6")
1586 (set_attr "adjust_len" "addto_sp")])
1587
1588 ;; "*addhi3"
1589 ;; "*addhq3" "*adduhq3"
1590 ;; "*addha3" "*adduha3"
1591 (define_insn_and_split "*add<mode>3_split"
1592 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1593 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1594 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1595 ""
1596 "#"
1597 "&& reload_completed"
1598 [(parallel [(set (match_dup 0)
1599 (plus:ALL2 (match_dup 1)
1600 (match_dup 2)))
1601 (clobber (reg:CC REG_CC))])])
1602
1603 (define_insn "*add<mode>3"
1604 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1605 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1606 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))
1607 (clobber (reg:CC REG_CC))]
1608 "reload_completed"
1609 {
1610 return avr_out_plus (insn, operands);
1611 }
1612 [(set_attr "length" "2")
1613 (set_attr "adjust_len" "plus")])
1614
1615 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1616 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1617 ;; itself because that insn is special to reload.
1618
1619 (define_peephole2 ; addhi3_clobber
1620 [(parallel [(set (match_operand:ALL2 0 "d_register_operand" "")
1621 (match_operand:ALL2 1 "const_operand" ""))
1622 (clobber (reg:CC REG_CC))])
1623 (parallel [(set (match_operand:ALL2 2 "l_register_operand" "")
1624 (plus:ALL2 (match_dup 2)
1625 (match_dup 0)))
1626 (clobber (reg:CC REG_CC))])]
1627 "peep2_reg_dead_p (2, operands[0])"
1628 [(parallel [(set (match_dup 2)
1629 (plus:ALL2 (match_dup 2)
1630 (match_dup 1)))
1631 (clobber (match_dup 3))
1632 (clobber (reg:CC REG_CC))])]
1633 {
1634 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1635 })
1636
1637 ;; Same, but with reload to NO_LD_REGS
1638 ;; Combine *reload_inhi with *addhi3
1639
1640 (define_peephole2 ; addhi3_clobber
1641 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1642 (match_operand:ALL2 1 "const_operand" ""))
1643 (clobber (match_operand:QI 2 "d_register_operand" ""))
1644 (clobber (reg:CC REG_CC))])
1645 (parallel [(set (match_operand:ALL2 3 "l_register_operand" "")
1646 (plus:ALL2 (match_dup 3)
1647 (match_dup 0)))
1648 (clobber (reg:CC REG_CC))])]
1649 "peep2_reg_dead_p (2, operands[0])"
1650 [(parallel [(set (match_dup 3)
1651 (plus:ALL2 (match_dup 3)
1652 (match_dup 1)))
1653 (clobber (match_dup 2))
1654 (clobber (reg:CC REG_CC))])])
1655
1656 ;; "addhi3_clobber"
1657 ;; "addhq3_clobber" "adduhq3_clobber"
1658 ;; "addha3_clobber" "adduha3_clobber"
1659 (define_insn_and_split "add<mode>3_clobber"
1660 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1661 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1662 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1663 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1664 ""
1665 "#"
1666 "&& reload_completed"
1667 [(parallel [(set (match_dup 0)
1668 (plus:ALL2 (match_dup 1)
1669 (match_dup 2)))
1670 (clobber (match_dup 3))
1671 (clobber (reg:CC REG_CC))])])
1672
1673 (define_insn "*add<mode>3_clobber"
1674 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1675 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1676 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1677 (clobber (match_scratch:QI 3 "=X ,X ,&d"))
1678 (clobber (reg:CC REG_CC))]
1679 "reload_completed"
1680 {
1681 return avr_out_plus (insn, operands);
1682 }
1683 [(set_attr "length" "4")
1684 (set_attr "adjust_len" "plus")])
1685
1686
1687 ;; "addsi3"
1688 ;; "addsq3" "addusq3"
1689 ;; "addsa3" "addusa3"
1690 (define_insn_and_split "add<mode>3"
1691 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1692 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1693 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1694 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1695 ""
1696 "#"
1697 "&& reload_completed"
1698 [(parallel [(set (match_dup 0)
1699 (plus:ALL4 (match_dup 1)
1700 (match_dup 2)))
1701 (clobber (match_dup 3))
1702 (clobber (reg:CC REG_CC))])])
1703
1704 (define_insn "*add<mode>3"
1705 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1706 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1707 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1708 (clobber (match_scratch:QI 3 "=X,X ,&d"))
1709 (clobber (reg:CC REG_CC))]
1710 "reload_completed"
1711 {
1712 return avr_out_plus (insn, operands);
1713 }
1714 [(set_attr "length" "4")
1715 (set_attr "adjust_len" "plus")])
1716
1717 (define_insn_and_split "*addpsi3_zero_extend.qi_split"
1718 [(set (match_operand:PSI 0 "register_operand" "=r")
1719 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1720 (match_operand:PSI 2 "register_operand" "0")))]
1721 ""
1722 "#"
1723 "&& reload_completed"
1724 [(parallel [(set (match_dup 0)
1725 (plus:PSI (zero_extend:PSI (match_dup 1))
1726 (match_dup 2)))
1727 (clobber (reg:CC REG_CC))])])
1728
1729 (define_insn "*addpsi3_zero_extend.qi"
1730 [(set (match_operand:PSI 0 "register_operand" "=r")
1731 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1732 (match_operand:PSI 2 "register_operand" "0")))
1733 (clobber (reg:CC REG_CC))]
1734 "reload_completed"
1735 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1736 [(set_attr "length" "3")])
1737
1738 (define_insn_and_split "*addpsi3_zero_extend.hi_split"
1739 [(set (match_operand:PSI 0 "register_operand" "=r")
1740 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1741 (match_operand:PSI 2 "register_operand" "0")))]
1742 ""
1743 "#"
1744 "&& reload_completed"
1745 [(parallel [(set (match_dup 0)
1746 (plus:PSI (zero_extend:PSI (match_dup 1))
1747 (match_dup 2)))
1748 (clobber (reg:CC REG_CC))])])
1749
1750 (define_insn "*addpsi3_zero_extend.hi"
1751 [(set (match_operand:PSI 0 "register_operand" "=r")
1752 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1753 (match_operand:PSI 2 "register_operand" "0")))
1754 (clobber (reg:CC REG_CC))]
1755 "reload_completed"
1756 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1757 [(set_attr "length" "3")])
1758
1759 (define_insn_and_split "*addpsi3_sign_extend.hi_split"
1760 [(set (match_operand:PSI 0 "register_operand" "=r")
1761 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1762 (match_operand:PSI 2 "register_operand" "0")))]
1763 ""
1764 "#"
1765 "&& reload_completed"
1766 [(parallel [(set (match_dup 0)
1767 (plus:PSI (sign_extend:PSI (match_dup 1))
1768 (match_dup 2)))
1769 (clobber (reg:CC REG_CC))])])
1770
1771 (define_insn "*addpsi3_sign_extend.hi"
1772 [(set (match_operand:PSI 0 "register_operand" "=r")
1773 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1774 (match_operand:PSI 2 "register_operand" "0")))
1775 (clobber (reg:CC REG_CC))]
1776 "reload_completed"
1777 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1778 [(set_attr "length" "5")])
1779
1780 (define_insn_and_split "*addsi3_zero_extend_split"
1781 [(set (match_operand:SI 0 "register_operand" "=r")
1782 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1783 (match_operand:SI 2 "register_operand" "0")))]
1784 ""
1785 "#"
1786 "&& reload_completed"
1787 [(parallel [(set (match_dup 0)
1788 (plus:SI (zero_extend:SI (match_dup 1))
1789 (match_dup 2)))
1790 (clobber (reg:CC REG_CC))])])
1791
1792 (define_insn "*addsi3_zero_extend"
1793 [(set (match_operand:SI 0 "register_operand" "=r")
1794 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1795 (match_operand:SI 2 "register_operand" "0")))
1796 (clobber (reg:CC REG_CC))]
1797 "reload_completed"
1798 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1799 [(set_attr "length" "4")])
1800
1801 (define_insn_and_split "*addsi3_zero_extend.hi_split"
1802 [(set (match_operand:SI 0 "register_operand" "=r")
1803 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1804 (match_operand:SI 2 "register_operand" "0")))]
1805 ""
1806 "#"
1807 "&& reload_completed"
1808 [(parallel [(set (match_dup 0)
1809 (plus:SI (zero_extend:SI (match_dup 1))
1810 (match_dup 2)))
1811 (clobber (reg:CC REG_CC))])])
1812
1813 (define_insn "*addsi3_zero_extend.hi"
1814 [(set (match_operand:SI 0 "register_operand" "=r")
1815 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1816 (match_operand:SI 2 "register_operand" "0")))
1817 (clobber (reg:CC REG_CC))]
1818 "reload_completed"
1819 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1820 [(set_attr "length" "4")])
1821
1822 (define_insn_and_split "addpsi3"
1823 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1824 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1825 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1826 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1827 ""
1828 "#"
1829 "&& reload_completed"
1830 [(parallel [(set (match_dup 0)
1831 (plus:PSI (match_dup 1)
1832 (match_dup 2)))
1833 (clobber (match_dup 3 ))
1834 (clobber (reg:CC REG_CC))])])
1835
1836 (define_insn "*addpsi3"
1837 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1838 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1839 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1840 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))
1841 (clobber (reg:CC REG_CC))]
1842 "reload_completed"
1843 {
1844 return avr_out_plus (insn, operands);
1845 }
1846 [(set_attr "length" "3")
1847 (set_attr "adjust_len" "plus")])
1848
1849 (define_insn_and_split "subpsi3"
1850 [(set (match_operand:PSI 0 "register_operand" "=r")
1851 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1852 (match_operand:PSI 2 "register_operand" "r")))]
1853 ""
1854 "#"
1855 "&& reload_completed"
1856 [(parallel [(set (match_dup 0)
1857 (minus:PSI (match_dup 1)
1858 (match_dup 2)))
1859 (clobber (reg:CC REG_CC))])])
1860
1861 (define_insn "*subpsi3"
1862 [(set (match_operand:PSI 0 "register_operand" "=r")
1863 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1864 (match_operand:PSI 2 "register_operand" "r")))
1865 (clobber (reg:CC REG_CC))]
1866 "reload_completed"
1867 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1868 [(set_attr "length" "3")])
1869
1870 (define_insn_and_split "*subpsi3_zero_extend.qi_split"
1871 [(set (match_operand:PSI 0 "register_operand" "=r")
1872 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1873 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1874 ""
1875 "#"
1876 "&& reload_completed"
1877 [(parallel [(set (match_dup 0)
1878 (minus:PSI (match_dup 1)
1879 (zero_extend:PSI (match_dup 2))))
1880 (clobber (reg:CC REG_CC))])])
1881
1882 (define_insn "*subpsi3_zero_extend.qi"
1883 [(set (match_operand:PSI 0 "register_operand" "=r")
1884 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1885 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))
1886 (clobber (reg:CC REG_CC))]
1887 "reload_completed"
1888 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1889 [(set_attr "length" "3")])
1890
1891 (define_insn_and_split "*subpsi3_zero_extend.hi_split"
1892 [(set (match_operand:PSI 0 "register_operand" "=r")
1893 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1894 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1895 ""
1896 "#"
1897 "&& reload_completed"
1898 [(parallel [(set (match_dup 0)
1899 (minus:PSI (match_dup 1)
1900 (zero_extend:PSI (match_dup 2))))
1901 (clobber (reg:CC REG_CC))])])
1902
1903 (define_insn "*subpsi3_zero_extend.hi"
1904 [(set (match_operand:PSI 0 "register_operand" "=r")
1905 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1906 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))
1907 (clobber (reg:CC REG_CC))]
1908 "reload_completed"
1909 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1910 [(set_attr "length" "3")])
1911
1912 (define_insn_and_split "*subpsi3_sign_extend.hi_split"
1913 [(set (match_operand:PSI 0 "register_operand" "=r")
1914 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1915 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1916 ""
1917 "#"
1918 "&& reload_completed"
1919 [(parallel [(set (match_dup 0)
1920 (minus:PSI (match_dup 1)
1921 (sign_extend:PSI (match_dup 2))))
1922 (clobber (reg:CC REG_CC))])])
1923
1924 (define_insn "*subpsi3_sign_extend.hi"
1925 [(set (match_operand:PSI 0 "register_operand" "=r")
1926 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1927 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))
1928 (clobber (reg:CC REG_CC))]
1929 "reload_completed"
1930 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1931 [(set_attr "length" "5")])
1932
1933 ;-----------------------------------------------------------------------------
1934 ; sub bytes
1935
1936 ;; "subqi3"
1937 ;; "subqq3" "subuqq3"
1938 (define_insn_and_split "sub<mode>3"
1939 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1940 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1941 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1942 ""
1943 "#"
1944 "&& reload_completed"
1945 [(parallel [(set (match_dup 0)
1946 (minus:ALL1 (match_dup 1)
1947 (match_dup 2)))
1948 (clobber (reg:CC REG_CC))])])
1949
1950 (define_insn "*sub<mode>3"
1951 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1952 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1953 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))
1954 (clobber (reg:CC REG_CC))]
1955 "reload_completed"
1956 "@
1957 sub %0,%2
1958 subi %0,lo8(%2)
1959 dec %0
1960 inc %0
1961 dec %0\;dec %0
1962 inc %0\;inc %0"
1963 [(set_attr "length" "1,1,1,1,2,2")])
1964
1965 ;; "subhi3"
1966 ;; "subhq3" "subuhq3"
1967 ;; "subha3" "subuha3"
1968 (define_insn_and_split "sub<mode>3"
1969 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1970 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1971 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1972 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1973 ""
1974 "#"
1975 "&& reload_completed"
1976 [(parallel [(set (match_dup 0)
1977 (minus:ALL2 (match_dup 1)
1978 (match_dup 2)))
1979 (clobber (match_dup 3))
1980 (clobber (reg:CC REG_CC))])])
1981
1982 (define_insn "*sub<mode>3"
1983 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1984 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1985 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1986 (clobber (match_scratch:QI 3 "=X,X ,&d"))
1987 (clobber (reg:CC REG_CC))]
1988 "reload_completed"
1989 {
1990 return avr_out_plus (insn, operands);
1991 }
1992 [(set_attr "adjust_len" "plus")])
1993
1994 (define_insn_and_split "*subhi3_zero_extend1_split"
1995 [(set (match_operand:HI 0 "register_operand" "=r")
1996 (minus:HI (match_operand:HI 1 "register_operand" "0")
1997 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1998 ""
1999 "#"
2000 "&& reload_completed"
2001 [(parallel [(set (match_dup 0)
2002 (minus:HI (match_dup 1)
2003 (zero_extend:HI (match_dup 2))))
2004 (clobber (reg:CC REG_CC))])])
2005
2006 (define_insn "*subhi3_zero_extend1"
2007 [(set (match_operand:HI 0 "register_operand" "=r")
2008 (minus:HI (match_operand:HI 1 "register_operand" "0")
2009 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
2010 (clobber (reg:CC REG_CC))]
2011 "reload_completed"
2012 "sub %A0,%2\;sbc %B0,__zero_reg__"
2013 [(set_attr "length" "2")])
2014
2015 (define_insn_and_split "*subhi3.sign_extend2_split"
2016 [(set (match_operand:HI 0 "register_operand" "=r")
2017 (minus:HI (match_operand:HI 1 "register_operand" "0")
2018 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
2019 ""
2020 "#"
2021 "&& reload_completed"
2022 [(parallel [(set (match_dup 0)
2023 (minus:HI (match_dup 1)
2024 (sign_extend:HI (match_dup 2))))
2025 (clobber (reg:CC REG_CC))])])
2026
2027
2028 (define_insn "*subhi3.sign_extend2"
2029 [(set (match_operand:HI 0 "register_operand" "=r")
2030 (minus:HI (match_operand:HI 1 "register_operand" "0")
2031 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))
2032 (clobber (reg:CC REG_CC))]
2033 "reload_completed"
2034 {
2035 return reg_overlap_mentioned_p (operands[0], operands[2])
2036 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
2037 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
2038 }
2039 [(set_attr "length" "5")])
2040
2041 ;; "subsi3"
2042 ;; "subsq3" "subusq3"
2043 ;; "subsa3" "subusa3"
2044 (define_insn_and_split "sub<mode>3"
2045 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
2046 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
2047 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
2048 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2049 ""
2050 "#"
2051 "&& reload_completed"
2052 [(parallel [(set (match_dup 0)
2053 (minus:ALL4 (match_dup 1)
2054 (match_dup 2)))
2055 (clobber (match_dup 3))
2056 (clobber (reg:CC REG_CC))])])
2057
2058 (define_insn "*sub<mode>3"
2059 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
2060 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
2061 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
2062 (clobber (match_scratch:QI 3 "=X,X ,&d"))
2063 (clobber (reg:CC REG_CC))]
2064 "reload_completed"
2065 {
2066 return avr_out_plus (insn, operands);
2067 }
2068 [(set_attr "adjust_len" "plus")])
2069
2070 (define_insn_and_split "*subsi3_zero_extend_split"
2071 [(set (match_operand:SI 0 "register_operand" "=r")
2072 (minus:SI (match_operand:SI 1 "register_operand" "0")
2073 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
2074 ""
2075 "#"
2076 "&& reload_completed"
2077 [(parallel [(set (match_dup 0)
2078 (minus:SI (match_dup 1)
2079 (zero_extend:SI (match_dup 2))))
2080 (clobber (reg:CC REG_CC))])])
2081
2082 (define_insn "*subsi3_zero_extend"
2083 [(set (match_operand:SI 0 "register_operand" "=r")
2084 (minus:SI (match_operand:SI 1 "register_operand" "0")
2085 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))
2086 (clobber (reg:CC REG_CC))]
2087 "reload_completed"
2088 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
2089 [(set_attr "length" "4")
2090 ])
2091
2092 (define_insn_and_split "*subsi3_zero_extend.hi_split"
2093 [(set (match_operand:SI 0 "register_operand" "=r")
2094 (minus:SI (match_operand:SI 1 "register_operand" "0")
2095 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
2096 ""
2097 "#"
2098 "&& reload_completed"
2099 [(parallel [(set (match_dup 0)
2100 (minus:SI (match_dup 1)
2101 (zero_extend:SI (match_dup 2))))
2102 (clobber (reg:CC REG_CC))])])
2103
2104 (define_insn "*subsi3_zero_extend.hi"
2105 [(set (match_operand:SI 0 "register_operand" "=r")
2106 (minus:SI (match_operand:SI 1 "register_operand" "0")
2107 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))
2108 (clobber (reg:CC REG_CC))]
2109 "reload_completed"
2110 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
2111 [(set_attr "length" "4")])
2112
2113 ;******************************************************************************
2114 ; mul
2115
2116 (define_expand "mulqi3"
2117 [(set (match_operand:QI 0 "register_operand" "")
2118 (mult:QI (match_operand:QI 1 "register_operand" "")
2119 (match_operand:QI 2 "register_operand" "")))]
2120 ""
2121 {
2122 if (!AVR_HAVE_MUL)
2123 {
2124 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
2125 DONE;
2126 }
2127 })
2128
2129 (define_insn_and_split "*mulqi3_enh_split"
2130 [(set (match_operand:QI 0 "register_operand" "=r")
2131 (mult:QI (match_operand:QI 1 "register_operand" "r")
2132 (match_operand:QI 2 "register_operand" "r")))]
2133 "AVR_HAVE_MUL"
2134 "#"
2135 "&& reload_completed"
2136 [(parallel [(set (match_dup 0)
2137 (mult:QI (match_dup 1)
2138 (match_dup 2)))
2139 (clobber (reg:CC REG_CC))])])
2140
2141 (define_insn "*mulqi3_enh"
2142 [(set (match_operand:QI 0 "register_operand" "=r")
2143 (mult:QI (match_operand:QI 1 "register_operand" "r")
2144 (match_operand:QI 2 "register_operand" "r")))
2145 (clobber (reg:CC REG_CC))]
2146 "AVR_HAVE_MUL && reload_completed"
2147 "mul %1,%2
2148 mov %0,r0
2149 clr r1"
2150 [(set_attr "length" "3")])
2151
2152 (define_expand "mulqi3_call"
2153 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
2154 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
2155 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
2156 (clobber (reg:QI 22))])
2157 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
2158 ""
2159 {
2160 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
2161 })
2162
2163 (define_insn_and_split "*mulqi3_call_split"
2164 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
2165 (clobber (reg:QI 22))]
2166 "!AVR_HAVE_MUL"
2167 "#"
2168 "&& reload_completed"
2169 [(parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
2170 (clobber (reg:QI 22))
2171 (clobber (reg:CC REG_CC))])])
2172
2173 (define_insn "*mulqi3_call"
2174 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
2175 (clobber (reg:QI 22))
2176 (clobber (reg:CC REG_CC))]
2177 "!AVR_HAVE_MUL && reload_completed"
2178 "%~call __mulqi3"
2179 [(set_attr "type" "xcall")])
2180
2181 ;; "umulqi3_highpart"
2182 ;; "smulqi3_highpart"
2183
2184 (define_insn_and_split "<extend_su>mulqi3_highpart"
2185 [(set (match_operand:QI 0 "register_operand" "=r")
2186 (truncate:QI
2187 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2188 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2189 (const_int 8))))]
2190 "AVR_HAVE_MUL"
2191 "#"
2192 "&& reload_completed"
2193 [(parallel [(set (match_dup 0)
2194 (truncate:QI
2195 (lshiftrt:HI (mult:HI (any_extend:HI (match_dup 1))
2196 (any_extend:HI (match_dup 2)))
2197 (const_int 8))))
2198 (clobber (reg:CC REG_CC))])])
2199
2200 (define_insn "*<extend_su>mulqi3_highpart"
2201 [(set (match_operand:QI 0 "register_operand" "=r")
2202 (truncate:QI
2203 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2204 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2205 (const_int 8))))
2206 (clobber (reg:CC REG_CC))]
2207 "AVR_HAVE_MUL && reload_completed"
2208 "mul<extend_s> %1,%2
2209 mov %0,r1
2210 clr __zero_reg__"
2211 [(set_attr "length" "3")])
2212
2213
2214 ;; Used when expanding div or mod inline for some special values
2215 (define_insn_and_split "*subqi3.ashiftrt7_split"
2216 [(set (match_operand:QI 0 "register_operand" "=r")
2217 (minus:QI (match_operand:QI 1 "register_operand" "0")
2218 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
2219 (const_int 7))))]
2220 ""
2221 "#"
2222 "&& reload_completed"
2223 [(parallel [(set (match_dup 0)
2224 (minus:QI (match_dup 1)
2225 (ashiftrt:QI (match_dup 2)
2226 (const_int 7))))
2227 (clobber (reg:CC REG_CC))])])
2228
2229 (define_insn "*subqi3.ashiftrt7"
2230 [(set (match_operand:QI 0 "register_operand" "=r")
2231 (minus:QI (match_operand:QI 1 "register_operand" "0")
2232 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
2233 (const_int 7))))
2234 (clobber (reg:CC REG_CC))]
2235 "reload_completed"
2236 "sbrc %2,7\;inc %0"
2237 [(set_attr "length" "2")])
2238
2239 (define_insn_and_split "*addqi3.lt0_split"
2240 [(set (match_operand:QI 0 "register_operand" "=r")
2241 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
2242 (const_int 0))
2243 (match_operand:QI 2 "register_operand" "0")))]
2244 ""
2245 "#"
2246 "&& reload_completed"
2247 [(parallel [(set (match_dup 0)
2248 (plus:QI (lt:QI (match_dup 1)
2249 (const_int 0))
2250 (match_dup 2)))
2251 (clobber (reg:CC REG_CC))])])
2252
2253 (define_insn "*addqi3.lt0"
2254 [(set (match_operand:QI 0 "register_operand" "=r")
2255 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
2256 (const_int 0))
2257 (match_operand:QI 2 "register_operand" "0")))
2258 (clobber (reg:CC REG_CC))]
2259 "reload_completed"
2260 "sbrc %1,7\;inc %0"
2261 [(set_attr "length" "2")])
2262
2263 (define_insn_and_split "*addhi3.lt0_split"
2264 [(set (match_operand:HI 0 "register_operand" "=w,r")
2265 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
2266 (const_int 0))
2267 (match_operand:HI 2 "register_operand" "0,0")))
2268 (clobber (match_scratch:QI 3 "=X,&1"))]
2269 ""
2270 "#"
2271 "&& reload_completed"
2272 [(parallel [(set (match_dup 0)
2273 (plus:HI (lt:HI (match_dup 1)
2274 (const_int 0))
2275 (match_dup 2)))
2276 (clobber (match_dup 3))
2277 (clobber (reg:CC REG_CC))])])
2278
2279 (define_insn "*addhi3.lt0"
2280 [(set (match_operand:HI 0 "register_operand" "=w,r")
2281 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
2282 (const_int 0))
2283 (match_operand:HI 2 "register_operand" "0,0")))
2284 (clobber (match_scratch:QI 3 "=X,&1"))
2285 (clobber (reg:CC REG_CC))]
2286 "reload_completed"
2287 "@
2288 sbrc %1,7\;adiw %0,1
2289 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
2290 [(set_attr "length" "2,3")])
2291
2292 (define_insn_and_split "*addpsi3.lt0_split"
2293 [(set (match_operand:PSI 0 "register_operand" "=r")
2294 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
2295 (const_int 23))
2296 (match_operand:PSI 2 "register_operand" "0")))]
2297 ""
2298 "#"
2299 "&& reload_completed"
2300 [(parallel [(set (match_dup 0)
2301 (plus:PSI (lshiftrt:PSI (match_dup 1)
2302 (const_int 23))
2303 (match_dup 2)))
2304 (clobber (reg:CC REG_CC))])])
2305
2306 (define_insn "*addpsi3.lt0"
2307 [(set (match_operand:PSI 0 "register_operand" "=r")
2308 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
2309 (const_int 23))
2310 (match_operand:PSI 2 "register_operand" "0")))
2311 (clobber (reg:CC REG_CC))]
2312 "reload_completed"
2313 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
2314 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
2315 [(set_attr "length" "5")])
2316
2317 (define_insn_and_split "*addsi3.lt0_split"
2318 [(set (match_operand:SI 0 "register_operand" "=r")
2319 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2320 (const_int 31))
2321 (match_operand:SI 2 "register_operand" "0")))]
2322 ""
2323 "#"
2324 "&& reload_completed"
2325 [(parallel [(set (match_dup 0)
2326 (plus:SI (lshiftrt:SI (match_dup 1)
2327 (const_int 31))
2328 (match_dup 2)))
2329 (clobber (reg:CC REG_CC))])])
2330
2331 (define_insn "*addsi3.lt0"
2332 [(set (match_operand:SI 0 "register_operand" "=r")
2333 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2334 (const_int 31))
2335 (match_operand:SI 2 "register_operand" "0")))
2336 (clobber (reg:CC REG_CC))]
2337 "reload_completed"
2338 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
2339 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
2340 [(set_attr "length" "6")])
2341
2342 (define_insn_and_split "*umulqihi3.call_split"
2343 [(set (reg:HI 24)
2344 (mult:HI (zero_extend:HI (reg:QI 22))
2345 (zero_extend:HI (reg:QI 24))))
2346 (clobber (reg:QI 21))
2347 (clobber (reg:HI 22))]
2348 "!AVR_HAVE_MUL"
2349 "#"
2350 "&& reload_completed"
2351 [(parallel [(set (reg:HI 24)
2352 (mult:HI (zero_extend:HI (reg:QI 22))
2353 (zero_extend:HI (reg:QI 24))))
2354 (clobber (reg:QI 21))
2355 (clobber (reg:HI 22))
2356 (clobber (reg:CC REG_CC))])])
2357
2358 (define_insn "*umulqihi3.call"
2359 [(set (reg:HI 24)
2360 (mult:HI (zero_extend:HI (reg:QI 22))
2361 (zero_extend:HI (reg:QI 24))))
2362 (clobber (reg:QI 21))
2363 (clobber (reg:HI 22))
2364 (clobber (reg:CC REG_CC))]
2365 "!AVR_HAVE_MUL && reload_completed"
2366 "%~call __umulqihi3"
2367 [(set_attr "type" "xcall")])
2368
2369 ;; "umulqihi3"
2370 ;; "mulqihi3"
2371
2372 (define_insn_and_split "<extend_u>mulqihi3_split"
2373 [(set (match_operand:HI 0 "register_operand" "=r")
2374 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2375 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
2376 "AVR_HAVE_MUL"
2377 "#"
2378 "&& reload_completed"
2379 [(parallel [(set (match_dup 0)
2380 (mult:HI (any_extend:HI (match_dup 1))
2381 (any_extend:HI (match_dup 2))))
2382 (clobber (reg:CC REG_CC))])])
2383
2384 (define_insn "<extend_u>mulqihi3"
2385 [(set (match_operand:HI 0 "register_operand" "=r")
2386 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2387 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))
2388 (clobber (reg:CC REG_CC))]
2389 "AVR_HAVE_MUL && reload_completed"
2390 "mul<extend_s> %1,%2
2391 movw %0,r0
2392 clr __zero_reg__"
2393 [(set_attr "length" "3")])
2394
2395 (define_insn_and_split "usmulqihi3"
2396 [(set (match_operand:HI 0 "register_operand" "=r")
2397 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2398 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
2399 "AVR_HAVE_MUL"
2400 "#"
2401 "&& reload_completed"
2402 [(parallel [(set (match_dup 0)
2403 (mult:HI (zero_extend:HI (match_dup 1))
2404 (sign_extend:HI (match_dup 2))))
2405 (clobber (reg:CC REG_CC))])])
2406
2407 (define_insn "*usmulqihi3"
2408 [(set (match_operand:HI 0 "register_operand" "=r")
2409 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2410 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))
2411 (clobber (reg:CC REG_CC))]
2412 "AVR_HAVE_MUL && reload_completed"
2413 "mulsu %2,%1
2414 movw %0,r0
2415 clr __zero_reg__"
2416 [(set_attr "length" "3")])
2417
2418 ;; Above insn is not canonicalized by insn combine, so here is a version with
2419 ;; operands swapped.
2420 (define_insn_and_split "*sumulqihi3_split"
2421 [(set (match_operand:HI 0 "register_operand" "=r")
2422 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2423 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
2424 "AVR_HAVE_MUL"
2425 "#"
2426 "&& reload_completed"
2427 [(parallel [(set (match_dup 0)
2428 (mult:HI (sign_extend:HI (match_dup 1))
2429 (zero_extend:HI (match_dup 2))))
2430 (clobber (reg:CC REG_CC))])])
2431
2432 (define_insn "*sumulqihi3"
2433 [(set (match_operand:HI 0 "register_operand" "=r")
2434 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2435 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))
2436 (clobber (reg:CC REG_CC))]
2437 "AVR_HAVE_MUL && reload_completed"
2438 "mulsu %1,%2
2439 movw %0,r0
2440 clr __zero_reg__"
2441 [(set_attr "length" "3")])
2442
2443 ;; One-extend operand 1
2444
2445 (define_insn_and_split "*osmulqihi3_split"
2446 [(set (match_operand:HI 0 "register_operand" "=&r")
2447 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
2448 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
2449 "AVR_HAVE_MUL"
2450 "#"
2451 "&& reload_completed"
2452 [(parallel [(set (match_dup 0)
2453 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1))))
2454 (sign_extend:HI (match_dup 2))))
2455 (clobber (reg:CC REG_CC))])])
2456
2457 (define_insn "*osmulqihi3"
2458 [(set (match_operand:HI 0 "register_operand" "=&r")
2459 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
2460 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))
2461 (clobber (reg:CC REG_CC))]
2462 "AVR_HAVE_MUL && reload_completed"
2463 "mulsu %2,%1
2464 movw %0,r0
2465 sub %B0,%2
2466 clr __zero_reg__"
2467 [(set_attr "length" "4")])
2468
2469 (define_insn_and_split "*oumulqihi3_split"
2470 [(set (match_operand:HI 0 "register_operand" "=&r")
2471 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2472 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
2473 "AVR_HAVE_MUL"
2474 "#"
2475 "&& reload_completed"
2476 [(parallel [(set (match_dup 0)
2477 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1))))
2478 (zero_extend:HI (match_dup 2))))
2479 (clobber (reg:CC REG_CC))])])
2480
2481 (define_insn "*oumulqihi3"
2482 [(set (match_operand:HI 0 "register_operand" "=&r")
2483 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2484 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
2485 (clobber (reg:CC REG_CC))]
2486 "AVR_HAVE_MUL && reload_completed"
2487 "mul %2,%1
2488 movw %0,r0
2489 sub %B0,%2
2490 clr __zero_reg__"
2491 [(set_attr "length" "4")])
2492
2493 ;******************************************************************************
2494 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
2495 ;******************************************************************************
2496
2497 (define_insn_and_split "*maddqi4_split"
2498 [(set (match_operand:QI 0 "register_operand" "=r")
2499 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
2500 (match_operand:QI 2 "register_operand" "r"))
2501 (match_operand:QI 3 "register_operand" "0")))]
2502
2503 "AVR_HAVE_MUL"
2504 "#"
2505 "&& reload_completed"
2506 [(parallel [(set (match_dup 0)
2507 (plus:QI (mult:QI (match_dup 1)
2508 (match_dup 2))
2509 (match_dup 3)))
2510 (clobber (reg:CC REG_CC))])])
2511
2512 (define_insn "*maddqi4"
2513 [(set (match_operand:QI 0 "register_operand" "=r")
2514 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
2515 (match_operand:QI 2 "register_operand" "r"))
2516 (match_operand:QI 3 "register_operand" "0")))
2517 (clobber (reg:CC REG_CC))]
2518 "AVR_HAVE_MUL && reload_completed"
2519 "mul %1,%2
2520 add %A0,r0
2521 clr __zero_reg__"
2522 [(set_attr "length" "4")])
2523
2524 (define_insn_and_split "*msubqi4_split"
2525 [(set (match_operand:QI 0 "register_operand" "=r")
2526 (minus:QI (match_operand:QI 3 "register_operand" "0")
2527 (mult:QI (match_operand:QI 1 "register_operand" "r")
2528 (match_operand:QI 2 "register_operand" "r"))))]
2529 "AVR_HAVE_MUL"
2530 "#"
2531 "&& reload_completed"
2532 [(parallel [(set (match_dup 0)
2533 (minus:QI (match_dup 3)
2534 (mult:QI (match_dup 1)
2535 (match_dup 2))))
2536 (clobber (reg:CC REG_CC))])])
2537
2538 (define_insn "*msubqi4"
2539 [(set (match_operand:QI 0 "register_operand" "=r")
2540 (minus:QI (match_operand:QI 3 "register_operand" "0")
2541 (mult:QI (match_operand:QI 1 "register_operand" "r")
2542 (match_operand:QI 2 "register_operand" "r"))))
2543 (clobber (reg:CC REG_CC))]
2544 "AVR_HAVE_MUL && reload_completed"
2545 "mul %1,%2
2546 sub %A0,r0
2547 clr __zero_reg__"
2548 [(set_attr "length" "4")])
2549
2550 (define_insn_and_split "*maddqi4.const"
2551 [(set (match_operand:QI 0 "register_operand" "=r")
2552 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
2553 (match_operand:QI 2 "const_int_operand" "n"))
2554 (match_operand:QI 3 "register_operand" "0")))
2555 (clobber (match_scratch:QI 4 "=&d"))]
2556 "AVR_HAVE_MUL"
2557 "#"
2558 "&& reload_completed"
2559 [(set (match_dup 4)
2560 (match_dup 2))
2561 ; *maddqi4
2562 (set (match_dup 0)
2563 (plus:QI (mult:QI (match_dup 1)
2564 (match_dup 4))
2565 (match_dup 3)))])
2566
2567 (define_insn_and_split "*msubqi4.const"
2568 [(set (match_operand:QI 0 "register_operand" "=r")
2569 (minus:QI (match_operand:QI 3 "register_operand" "0")
2570 (mult:QI (match_operand:QI 1 "register_operand" "r")
2571 (match_operand:QI 2 "const_int_operand" "n"))))
2572 (clobber (match_scratch:QI 4 "=&d"))]
2573 "AVR_HAVE_MUL"
2574 "#"
2575 "&& reload_completed"
2576 [(set (match_dup 4)
2577 (match_dup 2))
2578 ; *msubqi4
2579 (set (match_dup 0)
2580 (minus:QI (match_dup 3)
2581 (mult:QI (match_dup 1)
2582 (match_dup 4))))])
2583
2584
2585 ;******************************************************************************
2586 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
2587 ;******************************************************************************
2588
2589 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
2590 ;; e.g,
2591 ;;
2592 ;; int foo (unsigned char z)
2593 ;; {
2594 ;; extern int aInt[];
2595 ;; return aInt[3*z+2];
2596 ;; }
2597 ;;
2598 ;; because the constant +4 then is added explicitely instead of consuming it
2599 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
2600 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
2601 ;; The implementational effort is the same so we are fine with that approach.
2602
2603
2604 ;; "*maddqihi4"
2605 ;; "*umaddqihi4"
2606 (define_insn_and_split "*<extend_u>maddqihi4_split"
2607 [(set (match_operand:HI 0 "register_operand" "=r")
2608 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2609 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2610 (match_operand:HI 3 "register_operand" "0")))]
2611
2612 "AVR_HAVE_MUL"
2613 "#"
2614 "&& reload_completed"
2615 [(parallel [(set (match_dup 0)
2616 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
2617 (any_extend:HI (match_dup 2)))
2618 (match_dup 3)))
2619 (clobber (reg:CC REG_CC))])])
2620
2621 (define_insn "*<extend_u>maddqihi4"
2622 [(set (match_operand:HI 0 "register_operand" "=r")
2623 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2624 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2625 (match_operand:HI 3 "register_operand" "0")))
2626 (clobber (reg:CC REG_CC))]
2627 "AVR_HAVE_MUL && reload_completed"
2628 "mul<extend_s> %1,%2
2629 add %A0,r0
2630 adc %B0,r1
2631 clr __zero_reg__"
2632 [(set_attr "length" "4")])
2633
2634 ;; "*msubqihi4"
2635 ;; "*umsubqihi4"
2636 (define_insn_and_split "*<extend_u>msubqihi4_split"
2637 [(set (match_operand:HI 0 "register_operand" "=r")
2638 (minus:HI (match_operand:HI 3 "register_operand" "0")
2639 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2640 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
2641 "AVR_HAVE_MUL"
2642 "#"
2643 "&& reload_completed"
2644 [(parallel [(set (match_dup 0)
2645 (minus:HI (match_dup 3)
2646 (mult:HI (any_extend:HI (match_dup 1))
2647 (any_extend:HI (match_dup 2)))))
2648 (clobber (reg:CC REG_CC))])])
2649
2650 (define_insn "*<extend_u>msubqihi4"
2651 [(set (match_operand:HI 0 "register_operand" "=r")
2652 (minus:HI (match_operand:HI 3 "register_operand" "0")
2653 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2654 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))
2655 (clobber (reg:CC REG_CC))]
2656 "AVR_HAVE_MUL && reload_completed"
2657 "mul<extend_s> %1,%2
2658 sub %A0,r0
2659 sbc %B0,r1
2660 clr __zero_reg__"
2661 [(set_attr "length" "4")])
2662
2663 ;; "*usmaddqihi4"
2664 ;; "*sumaddqihi4"
2665 (define_insn_and_split "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4_split"
2666 [(set (match_operand:HI 0 "register_operand" "=r")
2667 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2668 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
2669 (match_operand:HI 3 "register_operand" "0")))]
2670 "AVR_HAVE_MUL
2671 && reload_completed
2672 && <any_extend:CODE> != <any_extend2:CODE>"
2673 "#"
2674 "&& reload_completed"
2675 [(parallel [(set (match_dup 0)
2676 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
2677 (any_extend2:HI (match_dup 2)))
2678 (match_dup 3)))
2679 (clobber (reg:CC REG_CC))])])
2680
2681 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
2682 [(set (match_operand:HI 0 "register_operand" "=r")
2683 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2684 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
2685 (match_operand:HI 3 "register_operand" "0")))
2686 (clobber (reg:CC REG_CC))]
2687 "AVR_HAVE_MUL
2688 && reload_completed
2689 && <any_extend:CODE> != <any_extend2:CODE>"
2690 {
2691 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
2692 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
2693
2694 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
2695 }
2696 [(set_attr "length" "4")])
2697
2698 ;; "*usmsubqihi4"
2699 ;; "*sumsubqihi4"
2700 (define_insn_and_split "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4_split"
2701 [(set (match_operand:HI 0 "register_operand" "=r")
2702 (minus:HI (match_operand:HI 3 "register_operand" "0")
2703 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2704 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
2705 "AVR_HAVE_MUL
2706 && reload_completed
2707 && <any_extend:CODE> != <any_extend2:CODE>"
2708 "#"
2709 "&& reload_completed"
2710 [(parallel [(set (match_dup 0)
2711 (minus:HI (match_dup 3)
2712 (mult:HI (any_extend:HI (match_dup 1))
2713 (any_extend2:HI (match_dup 2)))))
2714 (clobber (reg:CC REG_CC))])])
2715
2716 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
2717 [(set (match_operand:HI 0 "register_operand" "=r")
2718 (minus:HI (match_operand:HI 3 "register_operand" "0")
2719 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2720 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))
2721 (clobber (reg:CC REG_CC))]
2722 "AVR_HAVE_MUL
2723 && reload_completed
2724 && <any_extend:CODE> != <any_extend2:CODE>"
2725 {
2726 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
2727 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
2728
2729 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
2730 }
2731 [(set_attr "length" "4")])
2732
2733 ;; Handle small constants
2734
2735 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
2736 ;; This is shorter, faster than MUL and has lower register pressure.
2737
2738 (define_insn_and_split "*umaddqihi4.2"
2739 [(set (match_operand:HI 0 "register_operand" "=r")
2740 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2741 (const_int 2))
2742 (match_operand:HI 2 "register_operand" "r")))]
2743 "!reload_completed
2744 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2745 { gcc_unreachable(); }
2746 "&& 1"
2747 [(set (match_dup 0)
2748 (match_dup 2))
2749 ; *addhi3_zero_extend
2750 (set (match_dup 0)
2751 (plus:HI (zero_extend:HI (match_dup 1))
2752 (match_dup 0)))
2753 ; *addhi3_zero_extend
2754 (set (match_dup 0)
2755 (plus:HI (zero_extend:HI (match_dup 1))
2756 (match_dup 0)))])
2757
2758 ;; "umaddqihi4.uconst"
2759 ;; "maddqihi4.sconst"
2760 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
2761 [(set (match_operand:HI 0 "register_operand" "=r")
2762 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2763 (match_operand:HI 2 "<extend_su>8_operand" "n"))
2764 (match_operand:HI 3 "register_operand" "0")))
2765 (clobber (match_scratch:QI 4 "=&d"))]
2766 "AVR_HAVE_MUL"
2767 "#"
2768 "&& reload_completed"
2769 [(set (match_dup 4)
2770 (match_dup 2))
2771 ; *umaddqihi4 resp. *maddqihi4
2772 (set (match_dup 0)
2773 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
2774 (any_extend:HI (match_dup 4)))
2775 (match_dup 3)))]
2776 {
2777 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2778 })
2779
2780 ;; "*umsubqihi4.uconst"
2781 ;; "*msubqihi4.sconst"
2782 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
2783 [(set (match_operand:HI 0 "register_operand" "=r")
2784 (minus:HI (match_operand:HI 3 "register_operand" "0")
2785 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2786 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
2787 (clobber (match_scratch:QI 4 "=&d"))]
2788 "AVR_HAVE_MUL"
2789 "#"
2790 "&& reload_completed"
2791 [(set (match_dup 4)
2792 (match_dup 2))
2793 ; *umsubqihi4 resp. *msubqihi4
2794 (set (match_dup 0)
2795 (minus:HI (match_dup 3)
2796 (mult:HI (any_extend:HI (match_dup 1))
2797 (any_extend:HI (match_dup 4)))))]
2798 {
2799 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2800 })
2801
2802 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
2803 ;; for MULT with power of 2 and skips trying MULT insn above.
2804
2805 (define_insn_and_split "*umsubqihi4.uconst.ashift"
2806 [(set (match_operand:HI 0 "register_operand" "=r")
2807 (minus:HI (match_operand:HI 3 "register_operand" "0")
2808 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2809 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
2810 (clobber (match_scratch:QI 4 "=&d"))]
2811 "AVR_HAVE_MUL"
2812 "#"
2813 "&& reload_completed"
2814 [(set (match_dup 4)
2815 (match_dup 2))
2816 ; *umsubqihi4
2817 (set (match_dup 0)
2818 (minus:HI (match_dup 3)
2819 (mult:HI (zero_extend:HI (match_dup 1))
2820 (zero_extend:HI (match_dup 4)))))]
2821 {
2822 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2823 })
2824
2825 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
2826 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
2827 ;; because this would require an extra pattern for just one value.
2828
2829 (define_insn_and_split "*msubqihi4.sconst.ashift"
2830 [(set (match_operand:HI 0 "register_operand" "=r")
2831 (minus:HI (match_operand:HI 3 "register_operand" "0")
2832 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2833 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
2834 (clobber (match_scratch:QI 4 "=&d"))]
2835 "AVR_HAVE_MUL"
2836 "#"
2837 "&& reload_completed"
2838 [(set (match_dup 4)
2839 (match_dup 2))
2840 ; *smsubqihi4
2841 (set (match_dup 0)
2842 (minus:HI (match_dup 3)
2843 (mult:HI (sign_extend:HI (match_dup 1))
2844 (sign_extend:HI (match_dup 4)))))]
2845 {
2846 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2847 })
2848
2849 ;; For signed/unsigned combinations that require narrow constraint "a"
2850 ;; just provide a pattern if signed/unsigned combination is actually needed.
2851
2852 (define_insn_and_split "*sumaddqihi4.uconst"
2853 [(set (match_operand:HI 0 "register_operand" "=r")
2854 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2855 (match_operand:HI 2 "u8_operand" "M"))
2856 (match_operand:HI 3 "register_operand" "0")))
2857 (clobber (match_scratch:QI 4 "=&a"))]
2858 "AVR_HAVE_MUL
2859 && !s8_operand (operands[2], VOIDmode)"
2860 "#"
2861 "&& reload_completed"
2862 [(set (match_dup 4)
2863 (match_dup 2))
2864 ; *sumaddqihi4
2865 (set (match_dup 0)
2866 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
2867 (zero_extend:HI (match_dup 4)))
2868 (match_dup 3)))]
2869 {
2870 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2871 })
2872
2873 (define_insn_and_split "*sumsubqihi4.uconst"
2874 [(set (match_operand:HI 0 "register_operand" "=r")
2875 (minus:HI (match_operand:HI 3 "register_operand" "0")
2876 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2877 (match_operand:HI 2 "u8_operand" "M"))))
2878 (clobber (match_scratch:QI 4 "=&a"))]
2879 "AVR_HAVE_MUL
2880 && !s8_operand (operands[2], VOIDmode)"
2881 "#"
2882 "&& reload_completed"
2883 [(set (match_dup 4)
2884 (match_dup 2))
2885 ; *sumsubqihi4
2886 (set (match_dup 0)
2887 (minus:HI (match_dup 3)
2888 (mult:HI (sign_extend:HI (match_dup 1))
2889 (zero_extend:HI (match_dup 4)))))]
2890 {
2891 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2892 })
2893
2894 ;******************************************************************************
2895 ; mul HI: $1 = sign/zero-extend, $2 = small constant
2896 ;******************************************************************************
2897
2898 ;; "*muluqihi3.uconst"
2899 ;; "*mulsqihi3.sconst"
2900 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
2901 [(set (match_operand:HI 0 "register_operand" "=r")
2902 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2903 (match_operand:HI 2 "<extend_su>8_operand" "n")))
2904 (clobber (match_scratch:QI 3 "=&d"))]
2905 "AVR_HAVE_MUL"
2906 "#"
2907 "&& reload_completed"
2908 [(set (match_dup 3)
2909 (match_dup 2))
2910 ; umulqihi3 resp. mulqihi3
2911 (set (match_dup 0)
2912 (mult:HI (any_extend:HI (match_dup 1))
2913 (any_extend:HI (match_dup 3))))]
2914 {
2915 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2916 })
2917
2918 (define_insn_and_split "*muluqihi3.sconst"
2919 [(set (match_operand:HI 0 "register_operand" "=r")
2920 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2921 (match_operand:HI 2 "s8_operand" "n")))
2922 (clobber (match_scratch:QI 3 "=&a"))]
2923 "AVR_HAVE_MUL"
2924 "#"
2925 "&& reload_completed"
2926 [(set (match_dup 3)
2927 (match_dup 2))
2928 ; usmulqihi3
2929 (set (match_dup 0)
2930 (mult:HI (zero_extend:HI (match_dup 1))
2931 (sign_extend:HI (match_dup 3))))]
2932 {
2933 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2934 })
2935
2936 (define_insn_and_split "*mulsqihi3.uconst"
2937 [(set (match_operand:HI 0 "register_operand" "=r")
2938 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2939 (match_operand:HI 2 "u8_operand" "M")))
2940 (clobber (match_scratch:QI 3 "=&a"))]
2941 "AVR_HAVE_MUL"
2942 "#"
2943 "&& reload_completed"
2944 [(set (match_dup 3)
2945 (match_dup 2))
2946 ; usmulqihi3
2947 (set (match_dup 0)
2948 (mult:HI (zero_extend:HI (match_dup 3))
2949 (sign_extend:HI (match_dup 1))))]
2950 {
2951 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2952 })
2953
2954 (define_insn_and_split "*mulsqihi3.oconst"
2955 [(set (match_operand:HI 0 "register_operand" "=&r")
2956 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2957 (match_operand:HI 2 "o8_operand" "n")))
2958 (clobber (match_scratch:QI 3 "=&a"))]
2959 "AVR_HAVE_MUL"
2960 "#"
2961 "&& reload_completed"
2962 [(set (match_dup 3)
2963 (match_dup 2))
2964 ; *osmulqihi3
2965 (set (match_dup 0)
2966 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2967 (sign_extend:HI (match_dup 1))))]
2968 {
2969 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2970 })
2971
2972 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2973 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2974 ;; at that time. Fix that.
2975 (define_insn_and_split "*ashiftqihi2.signx.1_split"
2976 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2977 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2978 (const_int 1)))]
2979 ""
2980 "#"
2981 "&& reload_completed"
2982 [(parallel [(set (match_dup 0)
2983 (ashift:HI (sign_extend:HI (match_dup 1))
2984 (const_int 1)))
2985 (clobber (reg:CC REG_CC))])])
2986
2987 (define_insn "*ashiftqihi2.signx.1"
2988 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2989 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2990 (const_int 1)))
2991 (clobber (reg:CC REG_CC)) ]
2992 "reload_completed"
2993 "@
2994 lsl %A0\;sbc %B0,%B0
2995 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2996 [(set_attr "length" "2,3")])
2997
2998 (define_insn_and_split "*ashifthi3.signx.const"
2999 [(set (match_operand:HI 0 "register_operand" "=r")
3000 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
3001 (match_operand:HI 2 "const_2_to_6_operand" "I")))
3002 (clobber (match_scratch:QI 3 "=&d"))]
3003 "AVR_HAVE_MUL"
3004 "#"
3005 "&& reload_completed"
3006 [(set (match_dup 3)
3007 (match_dup 2))
3008 ; mulqihi3
3009 (set (match_dup 0)
3010 (mult:HI (sign_extend:HI (match_dup 1))
3011 (sign_extend:HI (match_dup 3))))]
3012 {
3013 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
3014 })
3015
3016 (define_insn_and_split "*ashifthi3.signx.const7"
3017 [(set (match_operand:HI 0 "register_operand" "=r")
3018 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
3019 (const_int 7)))
3020 (clobber (match_scratch:QI 2 "=&a"))]
3021 "AVR_HAVE_MUL"
3022 "#"
3023 "&& reload_completed"
3024 [(set (match_dup 2)
3025 (match_dup 3))
3026 ; usmulqihi3
3027 (set (match_dup 0)
3028 (mult:HI (zero_extend:HI (match_dup 2))
3029 (sign_extend:HI (match_dup 1))))]
3030 {
3031 operands[3] = gen_int_mode (1 << 7, QImode);
3032 })
3033
3034 (define_insn_and_split "*ashifthi3.zerox.const"
3035 [(set (match_operand:HI 0 "register_operand" "=r")
3036 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
3037 (match_operand:HI 2 "const_2_to_7_operand" "I")))
3038 (clobber (match_scratch:QI 3 "=&d"))]
3039 "AVR_HAVE_MUL"
3040 "#"
3041 "&& reload_completed"
3042 [(set (match_dup 3)
3043 (match_dup 2))
3044 ; umulqihi3
3045 (set (match_dup 0)
3046 (mult:HI (zero_extend:HI (match_dup 1))
3047 (zero_extend:HI (match_dup 3))))]
3048 {
3049 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
3050 })
3051
3052 ;******************************************************************************
3053 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
3054 ;******************************************************************************
3055
3056 (define_insn_and_split "mulsqihi3"
3057 [(set (match_operand:HI 0 "register_operand" "=&r")
3058 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
3059 (match_operand:HI 2 "register_operand" "a")))]
3060 "AVR_HAVE_MUL"
3061 "#"
3062 "&& reload_completed"
3063 [(parallel [(set (match_dup 0)
3064 (mult:HI (sign_extend:HI (match_dup 1))
3065 (match_dup 2)))
3066 (clobber (reg:CC REG_CC))])])
3067
3068 (define_insn "*mulsqihi3"
3069 [(set (match_operand:HI 0 "register_operand" "=&r")
3070 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
3071 (match_operand:HI 2 "register_operand" "a")))
3072 (clobber (reg:CC REG_CC))]
3073 "AVR_HAVE_MUL && reload_completed"
3074 "mulsu %1,%A2
3075 movw %0,r0
3076 mul %1,%B2
3077 add %B0,r0
3078 clr __zero_reg__"
3079 [(set_attr "length" "5")])
3080
3081 (define_insn_and_split "muluqihi3"
3082 [(set (match_operand:HI 0 "register_operand" "=&r")
3083 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
3084 (match_operand:HI 2 "register_operand" "r")))]
3085 "AVR_HAVE_MUL"
3086 "#"
3087 "&& reload_completed"
3088 [(parallel [(set (match_dup 0)
3089 (mult:HI (zero_extend:HI (match_dup 1))
3090 (match_dup 2)))
3091 (clobber (reg:CC REG_CC))])])
3092
3093 (define_insn "*muluqihi3"
3094 [(set (match_operand:HI 0 "register_operand" "=&r")
3095 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
3096 (match_operand:HI 2 "register_operand" "r")))
3097 (clobber (reg:CC REG_CC))]
3098 "AVR_HAVE_MUL && reload_completed"
3099 "mul %1,%A2
3100 movw %0,r0
3101 mul %1,%B2
3102 add %B0,r0
3103 clr __zero_reg__"
3104 [(set_attr "length" "5")])
3105
3106 ;; one-extend operand 1
3107
3108 (define_insn_and_split "muloqihi3"
3109 [(set (match_operand:HI 0 "register_operand" "=&r")
3110 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
3111 (match_operand:HI 2 "register_operand" "r")))]
3112 "AVR_HAVE_MUL"
3113 "#"
3114 "&& reload_completed"
3115 [(parallel [(set (match_dup 0)
3116 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1))))
3117 (match_dup 2)))
3118 (clobber (reg:CC REG_CC))])])
3119
3120 (define_insn "*muloqihi3"
3121 [(set (match_operand:HI 0 "register_operand" "=&r")
3122 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
3123 (match_operand:HI 2 "register_operand" "r")))
3124 (clobber (reg:CC REG_CC))]
3125 "AVR_HAVE_MUL && reload_completed"
3126 "mul %1,%A2
3127 movw %0,r0
3128 mul %1,%B2
3129 add %B0,r0
3130 sub %B0,%A2
3131 clr __zero_reg__"
3132 [(set_attr "length" "6")])
3133
3134 ;******************************************************************************
3135
3136 (define_expand "mulhi3"
3137 [(set (match_operand:HI 0 "register_operand" "")
3138 (mult:HI (match_operand:HI 1 "register_operand" "")
3139 (match_operand:HI 2 "register_or_s9_operand" "")))]
3140 ""
3141 {
3142 if (!AVR_HAVE_MUL)
3143 {
3144 if (!register_operand (operands[2], HImode))
3145 operands[2] = force_reg (HImode, operands[2]);
3146
3147 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
3148 DONE;
3149 }
3150
3151 /* ; For small constants we can do better by extending them on the fly.
3152 ; The constant can be loaded in one instruction and the widening
3153 ; multiplication is shorter. First try the unsigned variant because it
3154 ; allows constraint "d" instead of "a" for the signed version. */
3155
3156 if (s9_operand (operands[2], HImode))
3157 {
3158 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
3159
3160 if (u8_operand (operands[2], HImode))
3161 {
3162 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
3163 }
3164 else if (s8_operand (operands[2], HImode))
3165 {
3166 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
3167 }
3168 else
3169 {
3170 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
3171 }
3172
3173 DONE;
3174 }
3175
3176 if (!register_operand (operands[2], HImode))
3177 operands[2] = force_reg (HImode, operands[2]);
3178 })
3179
3180 (define_insn_and_split "*mulhi3_enh_split"
3181 [(set (match_operand:HI 0 "register_operand" "=&r")
3182 (mult:HI (match_operand:HI 1 "register_operand" "r")
3183 (match_operand:HI 2 "register_operand" "r")))]
3184 "AVR_HAVE_MUL"
3185 "#"
3186 "&& reload_completed"
3187 [(parallel [(set (match_dup 0)
3188 (mult:HI (match_dup 1)
3189 (match_dup 2)))
3190 (clobber (reg:CC REG_CC))])])
3191
3192 (define_insn "*mulhi3_enh"
3193 [(set (match_operand:HI 0 "register_operand" "=&r")
3194 (mult:HI (match_operand:HI 1 "register_operand" "r")
3195 (match_operand:HI 2 "register_operand" "r")))
3196 (clobber (reg:CC REG_CC))]
3197 "AVR_HAVE_MUL && reload_completed"
3198 {
3199 return REGNO (operands[1]) == REGNO (operands[2])
3200 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
3201 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
3202 }
3203 [(set_attr "length" "7")])
3204
3205 (define_expand "mulhi3_call"
3206 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
3207 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
3208 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3209 (clobber (reg:HI 22))
3210 (clobber (reg:QI 21))])
3211 (set (match_operand:HI 0 "register_operand" "")
3212 (reg:HI 24))]
3213 ""
3214 {
3215 avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24));
3216 })
3217
3218
3219 (define_insn_and_split "*mulhi3_call_split"
3220 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3221 (clobber (reg:HI 22))
3222 (clobber (reg:QI 21))]
3223 "!AVR_HAVE_MUL"
3224 "#"
3225 "&& reload_completed"
3226 [(parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3227 (clobber (reg:HI 22))
3228 (clobber (reg:QI 21))
3229 (clobber (reg:CC REG_CC))])])
3230
3231 (define_insn "*mulhi3_call"
3232 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3233 (clobber (reg:HI 22))
3234 (clobber (reg:QI 21))
3235 (clobber (reg:CC REG_CC))]
3236 "!AVR_HAVE_MUL && reload_completed"
3237 "%~call __mulhi3"
3238 [(set_attr "type" "xcall")])
3239
3240 ;; To support widening multiplication with constant we postpone
3241 ;; expanding to the implicit library call until post combine and
3242 ;; prior to register allocation. Clobber all hard registers that
3243 ;; might be used by the (widening) multiply until it is split and
3244 ;; it's final register footprint is worked out.
3245
3246 (define_expand "mulsi3"
3247 [(parallel [(set (match_operand:SI 0 "register_operand" "")
3248 (mult:SI (match_operand:SI 1 "register_operand" "")
3249 (match_operand:SI 2 "nonmemory_operand" "")))
3250 (clobber (reg:HI 26))
3251 (clobber (reg:DI 18))])]
3252 "AVR_HAVE_MUL"
3253 {
3254 if (u16_operand (operands[2], SImode))
3255 {
3256 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3257 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
3258 DONE;
3259 }
3260
3261 if (o16_operand (operands[2], SImode))
3262 {
3263 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3264 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
3265 DONE;
3266 }
3267
3268 if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0,
3269 regmask (DImode, 18) | regmask (HImode, 26)))
3270 DONE;
3271 })
3272
3273 (define_insn_and_split "*mulsi3"
3274 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3275 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
3276 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3277 (clobber (reg:HI 26))
3278 (clobber (reg:DI 18))]
3279 "AVR_HAVE_MUL && !reload_completed"
3280 { gcc_unreachable(); }
3281 "&& 1"
3282 [(set (reg:SI 18)
3283 (match_dup 1))
3284 (set (reg:SI 22)
3285 (match_dup 2))
3286 (parallel [(set (reg:SI 22)
3287 (mult:SI (reg:SI 22)
3288 (reg:SI 18)))
3289 (clobber (reg:HI 26))])
3290 (set (match_dup 0)
3291 (reg:SI 22))]
3292 {
3293 if (u16_operand (operands[2], SImode))
3294 {
3295 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3296 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
3297 DONE;
3298 }
3299
3300 if (o16_operand (operands[2], SImode))
3301 {
3302 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3303 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
3304 DONE;
3305 }
3306 })
3307
3308 ;; "muluqisi3"
3309 ;; "muluhisi3"
3310 (define_expand "mulu<mode>si3"
3311 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3312 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
3313 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
3314 (clobber (reg:HI 26))
3315 (clobber (reg:DI 18))])]
3316 "AVR_HAVE_MUL"
3317 {
3318 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
3319 if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0,
3320 regmask (DImode, 18) | regmask (HImode, 26)))
3321 DONE;
3322 })
3323
3324 ;; "*muluqisi3"
3325 ;; "*muluhisi3"
3326 (define_insn_and_split "*mulu<mode>si3"
3327 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3328 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
3329 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3330 (clobber (reg:HI 26))
3331 (clobber (reg:DI 18))]
3332 "AVR_HAVE_MUL && !reload_completed"
3333 { gcc_unreachable(); }
3334 "&& 1"
3335 [(set (reg:HI 26)
3336 (match_dup 1))
3337 (set (reg:SI 18)
3338 (match_dup 2))
3339 (set (reg:SI 22)
3340 (mult:SI (zero_extend:SI (reg:HI 26))
3341 (reg:SI 18)))
3342 (set (match_dup 0)
3343 (reg:SI 22))]
3344 {
3345 /* Do the QI -> HI extension explicitely before the multiplication. */
3346 /* Do the HI -> SI extension implicitely and after the multiplication. */
3347
3348 if (QImode == <MODE>mode)
3349 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
3350
3351 if (u16_operand (operands[2], SImode))
3352 {
3353 operands[1] = force_reg (HImode, operands[1]);
3354 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3355 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
3356 DONE;
3357 }
3358 })
3359
3360 ;; "mulsqisi3"
3361 ;; "mulshisi3"
3362 (define_expand "muls<mode>si3"
3363 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3364 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
3365 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
3366 (clobber (reg:HI 26))
3367 (clobber (reg:DI 18))])]
3368 "AVR_HAVE_MUL"
3369 {
3370 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
3371 if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0,
3372 regmask (DImode, 18) | regmask (HImode, 26)))
3373 DONE;
3374 })
3375
3376 ;; "*mulsqisi3"
3377 ;; "*mulshisi3"
3378 (define_insn_and_split "*muls<mode>si3"
3379 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3380 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
3381 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3382 (clobber (reg:HI 26))
3383 (clobber (reg:DI 18))]
3384 "AVR_HAVE_MUL && !reload_completed"
3385 { gcc_unreachable(); }
3386 "&& 1"
3387 [(set (reg:HI 26)
3388 (match_dup 1))
3389 (set (reg:SI 18)
3390 (match_dup 2))
3391 (set (reg:SI 22)
3392 (mult:SI (sign_extend:SI (reg:HI 26))
3393 (reg:SI 18)))
3394 (set (match_dup 0)
3395 (reg:SI 22))]
3396 {
3397 /* Do the QI -> HI extension explicitely before the multiplication. */
3398 /* Do the HI -> SI extension implicitely and after the multiplication. */
3399
3400 if (QImode == <MODE>mode)
3401 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
3402
3403 if (u16_operand (operands[2], SImode)
3404 || s16_operand (operands[2], SImode))
3405 {
3406 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3407
3408 operands[1] = force_reg (HImode, operands[1]);
3409
3410 if (u16_operand (operands[2], SImode))
3411 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
3412 else
3413 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
3414
3415 DONE;
3416 }
3417 })
3418
3419 ;; One-extend operand 1
3420
3421 (define_expand "mulohisi3"
3422 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3423 (mult:SI (not:SI (zero_extend:SI
3424 (not:HI (match_operand:HI 1 "pseudo_register_operand" ""))))
3425 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
3426 (clobber (reg:HI 26))
3427 (clobber (reg:DI 18))])]
3428 "AVR_HAVE_MUL"
3429 {
3430 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
3431 if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0,
3432 regmask (DImode, 18) | regmask (HImode, 26)))
3433 DONE;
3434 })
3435
3436 (define_insn_and_split "*mulohisi3"
3437 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3438 (mult:SI (not:SI (zero_extend:SI
3439 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
3440 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3441 (clobber (reg:HI 26))
3442 (clobber (reg:DI 18))]
3443 "AVR_HAVE_MUL && !reload_completed"
3444 { gcc_unreachable(); }
3445 "&& 1"
3446 [(set (reg:HI 26)
3447 (match_dup 1))
3448 (set (reg:SI 18)
3449 (match_dup 2))
3450 (set (reg:SI 22)
3451 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3452 (reg:SI 18)))
3453 (set (match_dup 0)
3454 (reg:SI 22))])
3455
3456 ;; "mulhisi3"
3457 ;; "umulhisi3"
3458 (define_expand "<extend_u>mulhisi3"
3459 [(parallel [(set (match_operand:SI 0 "register_operand" "")
3460 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
3461 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
3462 (clobber (reg:HI 26))
3463 (clobber (reg:DI 18))])]
3464 "AVR_HAVE_MUL"
3465 {
3466 if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0,
3467 regmask (DImode, 18) | regmask (HImode, 26)))
3468 DONE;
3469 })
3470
3471 (define_expand "usmulhisi3"
3472 [(parallel [(set (match_operand:SI 0 "register_operand" "")
3473 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
3474 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
3475 (clobber (reg:HI 26))
3476 (clobber (reg:DI 18))])]
3477 "AVR_HAVE_MUL"
3478 {
3479 if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0,
3480 regmask (DImode, 18) | regmask (HImode, 26)))
3481 DONE;
3482 })
3483
3484 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
3485 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
3486 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
3487 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
3488 (define_insn_and_split
3489 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
3490 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3491 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
3492 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
3493 (clobber (reg:HI 26))
3494 (clobber (reg:DI 18))]
3495 "AVR_HAVE_MUL && !reload_completed"
3496 { gcc_unreachable(); }
3497 "&& 1"
3498 [(set (reg:HI 18)
3499 (match_dup 1))
3500 (set (reg:HI 26)
3501 (match_dup 2))
3502 (set (reg:SI 22)
3503 (mult:SI (match_dup 3)
3504 (match_dup 4)))
3505 (set (match_dup 0)
3506 (reg:SI 22))]
3507 {
3508 rtx xop1 = operands[1];
3509 rtx xop2 = operands[2];
3510
3511 /* Do the QI -> HI extension explicitely before the multiplication. */
3512 /* Do the HI -> SI extension implicitely and after the multiplication. */
3513
3514 if (QImode == <QIHI:MODE>mode)
3515 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
3516
3517 if (QImode == <QIHI2:MODE>mode)
3518 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
3519
3520 if (<any_extend:CODE> == <any_extend2:CODE>
3521 || <any_extend:CODE> == ZERO_EXTEND)
3522 {
3523 operands[1] = xop1;
3524 operands[2] = xop2;
3525 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
3526 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
3527 }
3528 else
3529 {
3530 /* <any_extend:CODE> = SIGN_EXTEND */
3531 /* <any_extend2:CODE> = ZERO_EXTEND */
3532
3533 operands[1] = xop2;
3534 operands[2] = xop1;
3535 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
3536 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
3537 }
3538 })
3539
3540 ;; "smulhi3_highpart"
3541 ;; "umulhi3_highpart"
3542 (define_expand "<extend_su>mulhi3_highpart"
3543 [(set (reg:HI 18)
3544 (match_operand:HI 1 "nonmemory_operand" ""))
3545 (set (reg:HI 26)
3546 (match_operand:HI 2 "nonmemory_operand" ""))
3547 (parallel [(set (reg:HI 24)
3548 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3549 (any_extend:SI (reg:HI 26)))
3550 (const_int 16))))
3551 (clobber (reg:HI 22))])
3552 (set (match_operand:HI 0 "register_operand" "")
3553 (reg:HI 24))]
3554 "AVR_HAVE_MUL"
3555 {
3556 avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18));
3557 })
3558
3559 (define_insn_and_split "*mulsi3_call_split"
3560 [(set (reg:SI 22)
3561 (mult:SI (reg:SI 22)
3562 (reg:SI 18)))
3563 (clobber (reg:HI 26))]
3564 "AVR_HAVE_MUL"
3565 "#"
3566 "&& reload_completed"
3567 [(parallel [(set (reg:SI 22)
3568 (mult:SI (reg:SI 22)
3569 (reg:SI 18)))
3570 (clobber (reg:HI 26))
3571 (clobber (reg:CC REG_CC))])])
3572
3573 (define_insn "*mulsi3_call"
3574 [(set (reg:SI 22)
3575 (mult:SI (reg:SI 22)
3576 (reg:SI 18)))
3577 (clobber (reg:HI 26))
3578 (clobber (reg:CC REG_CC))]
3579 "AVR_HAVE_MUL && reload_completed"
3580 "%~call __mulsi3"
3581 [(set_attr "type" "xcall")])
3582
3583 ;; "*mulhisi3_call"
3584 ;; "*umulhisi3_call"
3585 (define_insn_and_split "*<extend_u>mulhisi3_call_split"
3586 [(set (reg:SI 22)
3587 (mult:SI (any_extend:SI (reg:HI 18))
3588 (any_extend:SI (reg:HI 26))))]
3589 "AVR_HAVE_MUL"
3590 "#"
3591 "&& reload_completed"
3592 [(parallel [(set (reg:SI 22)
3593 (mult:SI (any_extend:SI (reg:HI 18))
3594 (any_extend:SI (reg:HI 26))))
3595 (clobber (reg:CC REG_CC))])])
3596
3597 (define_insn "*<extend_u>mulhisi3_call"
3598 [(set (reg:SI 22)
3599 (mult:SI (any_extend:SI (reg:HI 18))
3600 (any_extend:SI (reg:HI 26))))
3601 (clobber (reg:CC REG_CC))]
3602 "AVR_HAVE_MUL && reload_completed"
3603 "%~call __<extend_u>mulhisi3"
3604 [(set_attr "type" "xcall")])
3605
3606 ;; "*umulhi3_highpart_call"
3607 ;; "*smulhi3_highpart_call"
3608 (define_insn_and_split "*<extend_su>mulhi3_highpart_call_split"
3609 [(set (reg:HI 24)
3610 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3611 (any_extend:SI (reg:HI 26)))
3612 (const_int 16))))
3613 (clobber (reg:HI 22))]
3614 "AVR_HAVE_MUL"
3615 "#"
3616 "&& reload_completed"
3617 [(parallel [(set (reg:HI 24)
3618 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3619 (any_extend:SI (reg:HI 26)))
3620 (const_int 16))))
3621 (clobber (reg:HI 22))
3622 (clobber (reg:CC REG_CC))])])
3623
3624 (define_insn "*<extend_su>mulhi3_highpart_call"
3625 [(set (reg:HI 24)
3626 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3627 (any_extend:SI (reg:HI 26)))
3628 (const_int 16))))
3629 (clobber (reg:HI 22))
3630 (clobber (reg:CC REG_CC))]
3631 "AVR_HAVE_MUL && reload_completed"
3632 "%~call __<extend_u>mulhisi3"
3633 [(set_attr "type" "xcall")])
3634
3635 (define_insn_and_split "*usmulhisi3_call_split"
3636 [(set (reg:SI 22)
3637 (mult:SI (zero_extend:SI (reg:HI 18))
3638 (sign_extend:SI (reg:HI 26))))]
3639 "AVR_HAVE_MUL"
3640 "#"
3641 "&& reload_completed"
3642 [(parallel [(set (reg:SI 22)
3643 (mult:SI (zero_extend:SI (reg:HI 18))
3644 (sign_extend:SI (reg:HI 26))))
3645 (clobber (reg:CC REG_CC))])])
3646
3647 (define_insn "*usmulhisi3_call"
3648 [(set (reg:SI 22)
3649 (mult:SI (zero_extend:SI (reg:HI 18))
3650 (sign_extend:SI (reg:HI 26))))
3651 (clobber (reg:CC REG_CC))]
3652 "AVR_HAVE_MUL && reload_completed"
3653 "%~call __usmulhisi3"
3654 [(set_attr "type" "xcall")])
3655
3656 (define_insn_and_split "*mul<extend_su>hisi3_call_split"
3657 [(set (reg:SI 22)
3658 (mult:SI (any_extend:SI (reg:HI 26))
3659 (reg:SI 18)))]
3660 "AVR_HAVE_MUL"
3661 "#"
3662 "&& reload_completed"
3663 [(parallel [(set (reg:SI 22)
3664 (mult:SI (any_extend:SI (reg:HI 26))
3665 (reg:SI 18)))
3666 (clobber (reg:CC REG_CC))])])
3667
3668 (define_insn "*mul<extend_su>hisi3_call"
3669 [(set (reg:SI 22)
3670 (mult:SI (any_extend:SI (reg:HI 26))
3671 (reg:SI 18)))
3672 (clobber (reg:CC REG_CC))]
3673 "AVR_HAVE_MUL && reload_completed"
3674 "%~call __mul<extend_su>hisi3"
3675 [(set_attr "type" "xcall")])
3676
3677 (define_insn_and_split "*mulohisi3_call_split"
3678 [(set (reg:SI 22)
3679 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3680 (reg:SI 18)))]
3681 "AVR_HAVE_MUL"
3682 "#"
3683 "&& reload_completed"
3684 [(parallel [(set (reg:SI 22)
3685 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3686 (reg:SI 18)))
3687 (clobber (reg:CC REG_CC))])])
3688
3689 (define_insn "*mulohisi3_call"
3690 [(set (reg:SI 22)
3691 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3692 (reg:SI 18)))
3693 (clobber (reg:CC REG_CC))]
3694 "AVR_HAVE_MUL && reload_completed"
3695 "%~call __mulohisi3"
3696 [(set_attr "type" "xcall")])
3697
3698 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
3699 ; divmod
3700
3701 ;; Generate lib1funcs.S calls ourselves, because:
3702 ;; - we know exactly which registers are clobbered (for QI and HI
3703 ;; modes, some of the call-used registers are preserved)
3704 ;; - we get both the quotient and the remainder at no extra cost
3705 ;; - we split the patterns only after the first CSE passes because
3706 ;; CSE has problems to operate on hard regs.
3707 ;;
3708 (define_insn_and_split "divmodqi4"
3709 [(set (match_operand:QI 0 "pseudo_register_operand" "")
3710 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
3711 (match_operand:QI 2 "pseudo_register_operand" "")))
3712 (set (match_operand:QI 3 "pseudo_register_operand" "")
3713 (mod:QI (match_dup 1) (match_dup 2)))
3714 (clobber (reg:QI 22))
3715 (clobber (reg:QI 23))
3716 (clobber (reg:QI 24))
3717 (clobber (reg:QI 25))]
3718 ""
3719 "this divmodqi4 pattern should have been splitted;"
3720 ""
3721 [(set (reg:QI 24) (match_dup 1))
3722 (set (reg:QI 22) (match_dup 2))
3723 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3724 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3725 (clobber (reg:QI 22))
3726 (clobber (reg:QI 23))])
3727 (set (match_dup 0) (reg:QI 24))
3728 (set (match_dup 3) (reg:QI 25))])
3729
3730 (define_insn_and_split "*divmodqi4_call_split"
3731 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3732 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3733 (clobber (reg:QI 22))
3734 (clobber (reg:QI 23))]
3735 ""
3736 "#"
3737 "&& reload_completed"
3738 [(parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3739 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3740 (clobber (reg:QI 22))
3741 (clobber (reg:QI 23))
3742 (clobber (reg:CC REG_CC))])])
3743
3744 (define_insn "*divmodqi4_call"
3745 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3746 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3747 (clobber (reg:QI 22))
3748 (clobber (reg:QI 23))
3749 (clobber (reg:CC REG_CC))]
3750 "reload_completed"
3751 "%~call __divmodqi4"
3752 [(set_attr "type" "xcall")])
3753
3754 (define_insn_and_split "udivmodqi4"
3755 [(set (match_operand:QI 0 "pseudo_register_operand" "")
3756 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
3757 (match_operand:QI 2 "pseudo_register_operand" "")))
3758 (set (match_operand:QI 3 "pseudo_register_operand" "")
3759 (umod:QI (match_dup 1) (match_dup 2)))
3760 (clobber (reg:QI 22))
3761 (clobber (reg:QI 23))
3762 (clobber (reg:QI 24))
3763 (clobber (reg:QI 25))]
3764 ""
3765 "this udivmodqi4 pattern should have been splitted;"
3766 ""
3767 [(set (reg:QI 24) (match_dup 1))
3768 (set (reg:QI 22) (match_dup 2))
3769 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3770 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3771 (clobber (reg:QI 23))])
3772 (set (match_dup 0) (reg:QI 24))
3773 (set (match_dup 3) (reg:QI 25))])
3774
3775 (define_insn_and_split "*udivmodqi4_call_split"
3776 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3777 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3778 (clobber (reg:QI 23))]
3779 ""
3780 "#"
3781 "&& reload_completed"
3782 [(parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3783 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3784 (clobber (reg:QI 23))
3785 (clobber (reg:CC REG_CC))])])
3786
3787 (define_insn "*udivmodqi4_call"
3788 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3789 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3790 (clobber (reg:QI 23))
3791 (clobber (reg:CC REG_CC))]
3792 "reload_completed"
3793 "%~call __udivmodqi4"
3794 [(set_attr "type" "xcall")])
3795
3796 (define_insn_and_split "divmodhi4"
3797 [(set (match_operand:HI 0 "pseudo_register_operand" "")
3798 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
3799 (match_operand:HI 2 "pseudo_register_operand" "")))
3800 (set (match_operand:HI 3 "pseudo_register_operand" "")
3801 (mod:HI (match_dup 1) (match_dup 2)))
3802 (clobber (reg:QI 21))
3803 (clobber (reg:HI 22))
3804 (clobber (reg:HI 24))
3805 (clobber (reg:HI 26))]
3806 ""
3807 "this should have been splitted;"
3808 ""
3809 [(set (reg:HI 24) (match_dup 1))
3810 (set (reg:HI 22) (match_dup 2))
3811 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3812 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3813 (clobber (reg:HI 26))
3814 (clobber (reg:QI 21))])
3815 (set (match_dup 0) (reg:HI 22))
3816 (set (match_dup 3) (reg:HI 24))])
3817
3818 (define_insn_and_split "*divmodhi4_call_split"
3819 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3820 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3821 (clobber (reg:HI 26))
3822 (clobber (reg:QI 21))]
3823 ""
3824 "#"
3825 "&& reload_completed"
3826 [(parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3827 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3828 (clobber (reg:HI 26))
3829 (clobber (reg:QI 21))
3830 (clobber (reg:CC REG_CC))])])
3831
3832 (define_insn "*divmodhi4_call"
3833 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3834 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3835 (clobber (reg:HI 26))
3836 (clobber (reg:QI 21))
3837 (clobber (reg:CC REG_CC))]
3838 "reload_completed"
3839 "%~call __divmodhi4"
3840 [(set_attr "type" "xcall")])
3841
3842 (define_insn_and_split "udivmodhi4"
3843 [(set (match_operand:HI 0 "pseudo_register_operand" "")
3844 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
3845 (match_operand:HI 2 "pseudo_register_operand" "")))
3846 (set (match_operand:HI 3 "pseudo_register_operand" "")
3847 (umod:HI (match_dup 1) (match_dup 2)))
3848 (clobber (reg:QI 21))
3849 (clobber (reg:HI 22))
3850 (clobber (reg:HI 24))
3851 (clobber (reg:HI 26))]
3852 ""
3853 "this udivmodhi4 pattern should have been splitted.;"
3854 ""
3855 [(set (reg:HI 24) (match_dup 1))
3856 (set (reg:HI 22) (match_dup 2))
3857 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3858 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3859 (clobber (reg:HI 26))
3860 (clobber (reg:QI 21))])
3861 (set (match_dup 0) (reg:HI 22))
3862 (set (match_dup 3) (reg:HI 24))])
3863
3864 (define_insn_and_split "*udivmodhi4_call_split"
3865 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3866 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3867 (clobber (reg:HI 26))
3868 (clobber (reg:QI 21))]
3869 ""
3870 "#"
3871 "&& reload_completed"
3872 [(parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3873 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3874 (clobber (reg:HI 26))
3875 (clobber (reg:QI 21))
3876 (clobber (reg:CC REG_CC))])])
3877
3878 (define_insn "*udivmodhi4_call"
3879 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3880 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3881 (clobber (reg:HI 26))
3882 (clobber (reg:QI 21))
3883 (clobber (reg:CC REG_CC))
3884 ]
3885 "reload_completed"
3886 "%~call __udivmodhi4"
3887 [(set_attr "type" "xcall")])
3888
3889 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3890 ;; 24-bit multiply
3891
3892 ;; To support widening multiplication with constant we postpone
3893 ;; expanding to the implicit library call until post combine and
3894 ;; prior to register allocation. Clobber all hard registers that
3895 ;; might be used by the (widening) multiply until it is split and
3896 ;; it's final register footprint is worked out.
3897
3898 (define_expand "mulpsi3"
3899 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3900 (mult:PSI (match_operand:PSI 1 "register_operand" "")
3901 (match_operand:PSI 2 "nonmemory_operand" "")))
3902 (clobber (reg:HI 26))
3903 (clobber (reg:DI 18))])]
3904 "AVR_HAVE_MUL"
3905 {
3906 if (s8_operand (operands[2], PSImode))
3907 {
3908 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
3909 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
3910 DONE;
3911 }
3912
3913 if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0,
3914 regmask (DImode, 18) | regmask (HImode, 26)))
3915 DONE;
3916 })
3917
3918 (define_insn_and_split "*umulqihipsi3_split"
3919 [(set (match_operand:PSI 0 "register_operand" "=&r")
3920 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
3921 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
3922 "AVR_HAVE_MUL"
3923 "#"
3924 "&& reload_completed"
3925 [(parallel [(set (match_dup 0)
3926 (mult:PSI (zero_extend:PSI (match_dup 1))
3927 (zero_extend:PSI (match_dup 2))))
3928 (clobber (reg:CC REG_CC))])])
3929
3930 (define_insn "*umulqihipsi3"
3931 [(set (match_operand:PSI 0 "register_operand" "=&r")
3932 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
3933 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))
3934 (clobber (reg:CC REG_CC))]
3935 "AVR_HAVE_MUL && reload_completed"
3936 "mul %1,%A2
3937 movw %A0,r0
3938 mul %1,%B2
3939 clr %C0
3940 add %B0,r0
3941 adc %C0,r1
3942 clr __zero_reg__"
3943 [(set_attr "length" "7")])
3944
3945 (define_insn_and_split "*umulhiqipsi3_split"
3946 [(set (match_operand:PSI 0 "register_operand" "=&r")
3947 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
3948 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
3949 "AVR_HAVE_MUL"
3950 "#"
3951 "&& reload_completed"
3952 [(parallel [(set (match_dup 0)
3953 (mult:PSI (zero_extend:PSI (match_dup 2))
3954 (zero_extend:PSI (match_dup 1))))
3955 (clobber (reg:CC REG_CC))])])
3956
3957 (define_insn "*umulhiqipsi3"
3958 [(set (match_operand:PSI 0 "register_operand" "=&r")
3959 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
3960 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))
3961 (clobber (reg:CC REG_CC))]
3962 "AVR_HAVE_MUL && reload_completed"
3963 "mul %1,%A2
3964 movw %A0,r0
3965 mul %1,%B2
3966 add %B0,r0
3967 mov %C0,r1
3968 clr __zero_reg__
3969 adc %C0,__zero_reg__"
3970 [(set_attr "length" "7")])
3971
3972 (define_expand "mulsqipsi3"
3973 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
3974 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" ""))
3975 (match_operand:PSI 2 "pseudo_register_or_const_int_operand""")))
3976 (clobber (reg:HI 26))
3977 (clobber (reg:DI 18))])]
3978 "AVR_HAVE_MUL"
3979 {
3980 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
3981 if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0,
3982 regmask (DImode, 18) | regmask (HImode, 26)))
3983 DONE;
3984 })
3985
3986 (define_insn_and_split "*mulsqipsi3"
3987 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
3988 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
3989 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
3990 (clobber (reg:HI 26))
3991 (clobber (reg:DI 18))]
3992 "AVR_HAVE_MUL && !reload_completed"
3993 { gcc_unreachable(); }
3994 "&& 1"
3995 [(set (reg:QI 25)
3996 (match_dup 1))
3997 (set (reg:PSI 22)
3998 (match_dup 2))
3999 (set (reg:PSI 18)
4000 (mult:PSI (sign_extend:PSI (reg:QI 25))
4001 (reg:PSI 22)))
4002 (set (match_dup 0)
4003 (reg:PSI 18))])
4004
4005 (define_insn_and_split "*mulpsi3"
4006 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
4007 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
4008 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
4009 (clobber (reg:HI 26))
4010 (clobber (reg:DI 18))]
4011 "AVR_HAVE_MUL && !reload_completed"
4012 { gcc_unreachable(); }
4013 "&& 1"
4014 [(set (reg:PSI 18)
4015 (match_dup 1))
4016 (set (reg:PSI 22)
4017 (match_dup 2))
4018 (parallel [(set (reg:PSI 22)
4019 (mult:PSI (reg:PSI 22)
4020 (reg:PSI 18)))
4021 (clobber (reg:QI 21))
4022 (clobber (reg:QI 25))
4023 (clobber (reg:HI 26))])
4024 (set (match_dup 0)
4025 (reg:PSI 22))]
4026 {
4027 if (s8_operand (operands[2], PSImode))
4028 {
4029 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
4030 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
4031 DONE;
4032 }
4033 })
4034
4035 (define_insn_and_split "*mulsqipsi3.libgcc_split"
4036 [(set (reg:PSI 18)
4037 (mult:PSI (sign_extend:PSI (reg:QI 25))
4038 (reg:PSI 22)))]
4039 "AVR_HAVE_MUL"
4040 "#"
4041 "&& reload_completed"
4042 [(parallel [(set (reg:PSI 18)
4043 (mult:PSI (sign_extend:PSI (reg:QI 25))
4044 (reg:PSI 22)))
4045 (clobber (reg:CC REG_CC))])])
4046
4047 (define_insn "*mulsqipsi3.libgcc"
4048 [(set (reg:PSI 18)
4049 (mult:PSI (sign_extend:PSI (reg:QI 25))
4050 (reg:PSI 22)))
4051 (clobber (reg:CC REG_CC))]
4052 "AVR_HAVE_MUL && reload_completed"
4053 "%~call __mulsqipsi3"
4054 [(set_attr "type" "xcall")])
4055
4056 (define_insn_and_split "*mulpsi3.libgcc_split"
4057 [(set (reg:PSI 22)
4058 (mult:PSI (reg:PSI 22)
4059 (reg:PSI 18)))
4060 (clobber (reg:QI 21))
4061 (clobber (reg:QI 25))
4062 (clobber (reg:HI 26))]
4063 "AVR_HAVE_MUL"
4064 "#"
4065 "&& reload_completed"
4066 [(parallel [(set (reg:PSI 22)
4067 (mult:PSI (reg:PSI 22)
4068 (reg:PSI 18)))
4069 (clobber (reg:QI 21))
4070 (clobber (reg:QI 25))
4071 (clobber (reg:HI 26))
4072 (clobber (reg:CC REG_CC))])])
4073
4074 (define_insn "*mulpsi3.libgcc"
4075 [(set (reg:PSI 22)
4076 (mult:PSI (reg:PSI 22)
4077 (reg:PSI 18)))
4078 (clobber (reg:QI 21))
4079 (clobber (reg:QI 25))
4080 (clobber (reg:HI 26))
4081 (clobber (reg:CC REG_CC))]
4082 "AVR_HAVE_MUL && reload_completed"
4083 "%~call __mulpsi3"
4084 [(set_attr "type" "xcall")])
4085
4086
4087 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4088 ;; 24-bit signed/unsigned division and modulo.
4089 ;; Notice that the libgcc implementation return the quotient in R22
4090 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
4091 ;; implementation works the other way round.
4092
4093 (define_insn_and_split "divmodpsi4"
4094 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
4095 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
4096 (match_operand:PSI 2 "pseudo_register_operand" "")))
4097 (set (match_operand:PSI 3 "pseudo_register_operand" "")
4098 (mod:PSI (match_dup 1)
4099 (match_dup 2)))
4100 (clobber (reg:DI 18))
4101 (clobber (reg:QI 26))])]
4102 ""
4103 { gcc_unreachable(); }
4104 ""
4105 [(set (reg:PSI 22) (match_dup 1))
4106 (set (reg:PSI 18) (match_dup 2))
4107 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4108 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4109 (clobber (reg:QI 21))
4110 (clobber (reg:QI 25))
4111 (clobber (reg:QI 26))])
4112 (set (match_dup 0) (reg:PSI 22))
4113 (set (match_dup 3) (reg:PSI 18))])
4114
4115 (define_insn_and_split "*divmodpsi4_call_split"
4116 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4117 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4118 (clobber (reg:QI 21))
4119 (clobber (reg:QI 25))
4120 (clobber (reg:QI 26))]
4121 ""
4122 "#"
4123 "&& reload_completed"
4124 [(parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4125 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4126 (clobber (reg:QI 21))
4127 (clobber (reg:QI 25))
4128 (clobber (reg:QI 26))
4129 (clobber (reg:CC REG_CC))])])
4130
4131 (define_insn "*divmodpsi4_call"
4132 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4133 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4134 (clobber (reg:QI 21))
4135 (clobber (reg:QI 25))
4136 (clobber (reg:QI 26))
4137 (clobber (reg:CC REG_CC))]
4138 "reload_completed"
4139 "%~call __divmodpsi4"
4140 [(set_attr "type" "xcall")])
4141
4142 (define_insn_and_split "udivmodpsi4"
4143 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
4144 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
4145 (match_operand:PSI 2 "pseudo_register_operand" "")))
4146 (set (match_operand:PSI 3 "pseudo_register_operand" "")
4147 (umod:PSI (match_dup 1)
4148 (match_dup 2)))
4149 (clobber (reg:DI 18))
4150 (clobber (reg:QI 26))])]
4151 ""
4152 { gcc_unreachable(); }
4153 ""
4154 [(set (reg:PSI 22) (match_dup 1))
4155 (set (reg:PSI 18) (match_dup 2))
4156 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4157 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4158 (clobber (reg:QI 21))
4159 (clobber (reg:QI 25))
4160 (clobber (reg:QI 26))])
4161 (set (match_dup 0) (reg:PSI 22))
4162 (set (match_dup 3) (reg:PSI 18))])
4163
4164 (define_insn_and_split "*udivmodpsi4_call_split"
4165 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4166 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4167 (clobber (reg:QI 21))
4168 (clobber (reg:QI 25))
4169 (clobber (reg:QI 26))]
4170 ""
4171 "#"
4172 "&& reload_completed"
4173 [(parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4174 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4175 (clobber (reg:QI 21))
4176 (clobber (reg:QI 25))
4177 (clobber (reg:QI 26))
4178 (clobber (reg:CC REG_CC))])])
4179
4180 (define_insn "*udivmodpsi4_call"
4181 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4182 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4183 (clobber (reg:QI 21))
4184 (clobber (reg:QI 25))
4185 (clobber (reg:QI 26))
4186 (clobber (reg:CC REG_CC))]
4187 "reload_completed"
4188 "%~call __udivmodpsi4"
4189 [(set_attr "type" "xcall")])
4190
4191 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4192
4193 (define_insn_and_split "divmodsi4"
4194 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
4195 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
4196 (match_operand:SI 2 "pseudo_register_operand" "")))
4197 (set (match_operand:SI 3 "pseudo_register_operand" "")
4198 (mod:SI (match_dup 1) (match_dup 2)))
4199 (clobber (reg:SI 18))
4200 (clobber (reg:SI 22))
4201 (clobber (reg:HI 26))
4202 (clobber (reg:HI 30))])]
4203 ""
4204 "this divmodsi4 pattern should have been splitted;"
4205 ""
4206 [(set (reg:SI 22) (match_dup 1))
4207 (set (reg:SI 18) (match_dup 2))
4208 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4209 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4210 (clobber (reg:HI 26))
4211 (clobber (reg:HI 30))])
4212 (set (match_dup 0) (reg:SI 18))
4213 (set (match_dup 3) (reg:SI 22))])
4214
4215 (define_insn_and_split "*divmodsi4_call_split"
4216 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4217 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4218 (clobber (reg:HI 26))
4219 (clobber (reg:HI 30))]
4220 ""
4221 "#"
4222 "&& reload_completed"
4223 [(parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4224 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4225 (clobber (reg:HI 26))
4226 (clobber (reg:HI 30))
4227 (clobber (reg:CC REG_CC))])])
4228
4229 (define_insn "*divmodsi4_call"
4230 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4231 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4232 (clobber (reg:HI 26))
4233 (clobber (reg:HI 30))
4234 (clobber (reg:CC REG_CC))]
4235 "reload_completed"
4236 "%~call __divmodsi4"
4237 [(set_attr "type" "xcall")])
4238
4239 (define_insn_and_split "udivmodsi4"
4240 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
4241 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
4242 (match_operand:SI 2 "pseudo_register_operand" "")))
4243 (set (match_operand:SI 3 "pseudo_register_operand" "")
4244 (umod:SI (match_dup 1) (match_dup 2)))
4245 (clobber (reg:SI 18))
4246 (clobber (reg:SI 22))
4247 (clobber (reg:HI 26))
4248 (clobber (reg:HI 30))])]
4249 ""
4250 "this udivmodsi4 pattern should have been splitted;"
4251 ""
4252 [(set (reg:SI 22) (match_dup 1))
4253 (set (reg:SI 18) (match_dup 2))
4254 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4255 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4256 (clobber (reg:HI 26))
4257 (clobber (reg:HI 30))])
4258 (set (match_dup 0) (reg:SI 18))
4259 (set (match_dup 3) (reg:SI 22))])
4260
4261 (define_insn_and_split "*udivmodsi4_call_split"
4262 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4263 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4264 (clobber (reg:HI 26))
4265 (clobber (reg:HI 30))]
4266 ""
4267 "#"
4268 "&& reload_completed"
4269 [(parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4270 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4271 (clobber (reg:HI 26))
4272 (clobber (reg:HI 30))
4273 (clobber (reg:CC REG_CC))])])
4274
4275 (define_insn "*udivmodsi4_call"
4276 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4277 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4278 (clobber (reg:HI 26))
4279 (clobber (reg:HI 30))
4280 (clobber (reg:CC REG_CC))]
4281 "reload_completed"
4282 "%~call __udivmodsi4"
4283 [(set_attr "type" "xcall")])
4284
4285 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4286 ; and
4287
4288 (define_insn_and_split "andqi3"
4289 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4290 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4291 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))]
4292 ""
4293 "#"
4294 "&& reload_completed"
4295 [(parallel [(set (match_dup 0)
4296 (and:QI (match_dup 1)
4297 (match_dup 2)))
4298 (clobber (reg:CC REG_CC))])])
4299
4300 (define_insn "*andqi3"
4301 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4302 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4303 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))
4304 (clobber (reg:CC REG_CC))]
4305 "reload_completed"
4306 "@
4307 and %0,%2
4308 andi %0,lo8(%2)
4309 * return avr_out_bitop (insn, operands, NULL);"
4310 [(set_attr "length" "1,1,2")])
4311
4312 (define_insn_and_split "andhi3"
4313 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4314 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4315 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
4316 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
4317 ""
4318 "#"
4319 "&& reload_completed"
4320 [(parallel [(set (match_dup 0)
4321 (and:HI (match_dup 1)
4322 (match_dup 2)))
4323 (clobber (match_dup 3))
4324 (clobber (reg:CC REG_CC))])])
4325
4326 (define_insn "*andhi3"
4327 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4328 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4329 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
4330 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))
4331 (clobber (reg:CC REG_CC))]
4332 "reload_completed"
4333 {
4334 if (which_alternative == 0)
4335 return "and %A0,%A2\;and %B0,%B2";
4336 else if (which_alternative == 1)
4337 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
4338
4339 return avr_out_bitop (insn, operands, NULL);
4340 }
4341 [(set_attr "length" "2,2,2,4,4")
4342 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")])
4343
4344 (define_insn_and_split "andpsi3"
4345 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4346 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4347 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
4348 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4349 ""
4350 "#"
4351 "&& reload_completed"
4352 [(parallel [(set (match_dup 0)
4353 (and:PSI (match_dup 1)
4354 (match_dup 2)))
4355 (clobber (match_dup 3))
4356 (clobber (reg:CC REG_CC))])])
4357
4358 (define_insn "*andpsi3"
4359 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4360 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4361 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
4362 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4363 (clobber (reg:CC REG_CC))]
4364 "reload_completed"
4365 {
4366 if (which_alternative == 0)
4367 return "and %A0,%A2" CR_TAB
4368 "and %B0,%B2" CR_TAB
4369 "and %C0,%C2";
4370
4371 return avr_out_bitop (insn, operands, NULL);
4372 }
4373 [(set_attr "length" "3,3,6,6")
4374 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4375
4376 (define_insn_and_split "andsi3"
4377 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4378 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4379 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
4380 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4381 ""
4382 "#"
4383 "&& reload_completed"
4384 [(parallel [(set (match_dup 0)
4385 (and:SI (match_dup 1)
4386 (match_dup 2)))
4387 (clobber (match_dup 3))
4388 (clobber (reg:CC REG_CC))])])
4389
4390 (define_insn "*andsi3"
4391 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4392 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4393 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
4394 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4395 (clobber (reg:CC REG_CC))]
4396 "reload_completed"
4397 {
4398 if (which_alternative == 0)
4399 return "and %0,%2" CR_TAB
4400 "and %B0,%B2" CR_TAB
4401 "and %C0,%C2" CR_TAB
4402 "and %D0,%D2";
4403
4404 return avr_out_bitop (insn, operands, NULL);
4405 }
4406 [(set_attr "length" "4,4,8,8")
4407 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4408
4409 (define_peephole2 ; andi
4410 [(parallel [(set (match_operand:QI 0 "d_register_operand" "")
4411 (and:QI (match_dup 0)
4412 (match_operand:QI 1 "const_int_operand" "")))
4413 (clobber (reg:CC REG_CC))])
4414 (parallel [(set (match_dup 0)
4415 (and:QI (match_dup 0)
4416 (match_operand:QI 2 "const_int_operand" "")))
4417 (clobber (reg:CC REG_CC))])]
4418 ""
4419 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
4420 (clobber (reg:CC REG_CC))])]
4421 {
4422 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
4423 })
4424
4425 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4426 ;; ior
4427
4428 (define_insn_and_split "iorqi3"
4429 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4430 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4431 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))]
4432 ""
4433 "#"
4434 "&& reload_completed"
4435 [(parallel [(set (match_dup 0)
4436 (ior:QI (match_dup 1)
4437 (match_dup 2)))
4438 (clobber (reg:CC REG_CC))])])
4439
4440 (define_insn "*iorqi3"
4441 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4442 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4443 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))
4444 (clobber (reg:CC REG_CC))]
4445 "reload_completed"
4446 "@
4447 or %0,%2
4448 ori %0,lo8(%2)
4449 * return avr_out_bitop (insn, operands, NULL);"
4450 [(set_attr "length" "1,1,2")])
4451
4452 (define_insn_and_split "iorhi3"
4453 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4454 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4455 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
4456 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
4457 ""
4458 "#"
4459 "&& reload_completed"
4460 [(parallel [(set (match_dup 0)
4461 (ior:HI (match_dup 1)
4462 (match_dup 2)))
4463 (clobber (match_dup 3))
4464 (clobber (reg:CC REG_CC))])])
4465
4466 (define_insn "*iorhi3"
4467 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4468 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4469 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
4470 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))
4471 (clobber (reg:CC REG_CC))]
4472 "reload_completed"
4473 {
4474 if (which_alternative == 0)
4475 return "or %A0,%A2\;or %B0,%B2";
4476 else if (which_alternative == 1)
4477 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
4478
4479 return avr_out_bitop (insn, operands, NULL);
4480 }
4481 [(set_attr "length" "2,2,2,4,4")
4482 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")])
4483
4484 (define_insn_and_split "iorpsi3"
4485 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4486 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4487 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
4488 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4489 ""
4490 "#"
4491 "&& reload_completed"
4492 [(parallel [(set (match_dup 0)
4493 (ior:PSI (match_dup 1)
4494 (match_dup 2)))
4495 (clobber (match_dup 3))
4496 (clobber (reg:CC REG_CC))])])
4497
4498 (define_insn "*iorpsi3"
4499 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4500 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4501 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
4502 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4503 (clobber (reg:CC REG_CC))]
4504 "reload_completed"
4505 {
4506 if (which_alternative == 0)
4507 return "or %A0,%A2" CR_TAB
4508 "or %B0,%B2" CR_TAB
4509 "or %C0,%C2";
4510
4511 return avr_out_bitop (insn, operands, NULL);
4512 }
4513 [(set_attr "length" "3,3,6,6")
4514 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4515
4516 (define_insn_and_split "iorsi3"
4517 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4518 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4519 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
4520 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4521 ""
4522 "#"
4523 "&& reload_completed"
4524 [(parallel [(set (match_dup 0)
4525 (ior:SI (match_dup 1)
4526 (match_dup 2)))
4527 (clobber (match_dup 3))
4528 (clobber (reg:CC REG_CC))])])
4529
4530 (define_insn "*iorsi3"
4531 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4532 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4533 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
4534 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4535 (clobber (reg:CC REG_CC))]
4536 "reload_completed"
4537 {
4538 if (which_alternative == 0)
4539 return "or %0,%2" CR_TAB
4540 "or %B0,%B2" CR_TAB
4541 "or %C0,%C2" CR_TAB
4542 "or %D0,%D2";
4543
4544 return avr_out_bitop (insn, operands, NULL);
4545 }
4546 [(set_attr "length" "4,4,8,8")
4547 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4548
4549 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4550 ;; xor
4551
4552 (define_insn_and_split "xorqi3"
4553 [(set (match_operand:QI 0 "register_operand" "=r")
4554 (xor:QI (match_operand:QI 1 "register_operand" "%0")
4555 (match_operand:QI 2 "register_operand" "r")))]
4556 ""
4557 "#"
4558 "&& reload_completed"
4559 [(parallel [(set (match_dup 0)
4560 (xor:QI (match_dup 1)
4561 (match_dup 2)))
4562 (clobber (reg:CC REG_CC))])])
4563
4564 (define_insn "*xorqi3"
4565 [(set (match_operand:QI 0 "register_operand" "=r")
4566 (xor:QI (match_operand:QI 1 "register_operand" "%0")
4567 (match_operand:QI 2 "register_operand" "r")))
4568 (clobber (reg:CC REG_CC))]
4569 "reload_completed"
4570 "eor %0,%2"
4571 [(set_attr "length" "1")])
4572
4573 (define_insn_and_split "xorhi3"
4574 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
4575 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
4576 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
4577 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
4578 ""
4579 "#"
4580 "&& reload_completed"
4581 [(parallel [(set (match_dup 0)
4582 (xor:HI (match_dup 1)
4583 (match_dup 2)))
4584 (clobber (match_dup 3))
4585 (clobber (reg:CC REG_CC))])])
4586
4587 (define_insn "*xorhi3"
4588 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
4589 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
4590 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
4591 (clobber (match_scratch:QI 3 "=X,X ,&d"))
4592 (clobber (reg:CC REG_CC))]
4593 "reload_completed"
4594 {
4595 if (which_alternative == 0)
4596 return "eor %A0,%A2\;eor %B0,%B2";
4597
4598 return avr_out_bitop (insn, operands, NULL);
4599 }
4600 [(set_attr "length" "2,2,4")
4601 (set_attr "adjust_len" "*,out_bitop,out_bitop")])
4602
4603 (define_insn_and_split "xorpsi3"
4604 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
4605 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
4606 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
4607 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
4608 ""
4609 "#"
4610 "&& reload_completed"
4611 [(parallel [(set (match_dup 0)
4612 (xor:PSI (match_dup 1)
4613 (match_dup 2)))
4614 (clobber (match_dup 3))
4615 (clobber (reg:CC REG_CC))])])
4616
4617 (define_insn "*xorpsi3"
4618 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
4619 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
4620 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
4621 (clobber (match_scratch:QI 3 "=X,X ,&d"))
4622 (clobber (reg:CC REG_CC))]
4623 "reload_completed"
4624 {
4625 if (which_alternative == 0)
4626 return "eor %A0,%A2" CR_TAB
4627 "eor %B0,%B2" CR_TAB
4628 "eor %C0,%C2";
4629
4630 return avr_out_bitop (insn, operands, NULL);
4631 }
4632 [(set_attr "length" "3,6,6")
4633 (set_attr "adjust_len" "*,out_bitop,out_bitop")])
4634
4635 (define_insn_and_split "xorsi3"
4636 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
4637 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
4638 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
4639 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
4640 ""
4641 "#"
4642 "&& reload_completed"
4643 [(parallel [(set (match_dup 0)
4644 (xor:SI (match_dup 1)
4645 (match_dup 2)))
4646 (clobber (match_dup 3))
4647 (clobber (reg:CC REG_CC))])])
4648
4649 (define_insn "*xorsi3"
4650 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
4651 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
4652 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
4653 (clobber (match_scratch:QI 3 "=X,X ,&d"))
4654 (clobber (reg:CC REG_CC))]
4655 "reload_completed"
4656 {
4657 if (which_alternative == 0)
4658 return "eor %0,%2" CR_TAB
4659 "eor %B0,%B2" CR_TAB
4660 "eor %C0,%C2" CR_TAB
4661 "eor %D0,%D2";
4662
4663 return avr_out_bitop (insn, operands, NULL);
4664 }
4665 [(set_attr "length" "4,8,8")
4666 (set_attr "adjust_len" "*,out_bitop,out_bitop")])
4667
4668
4669 (define_split
4670 [(set (match_operand:SPLIT34 0 "register_operand")
4671 (match_operand:SPLIT34 1 "register_operand"))]
4672 "optimize
4673 && reload_completed"
4674 [(set (match_dup 2) (match_dup 3))
4675 (set (match_dup 4) (match_dup 5))]
4676 {
4677 machine_mode mode_hi = 4 == GET_MODE_SIZE (<MODE>mode) ? HImode : QImode;
4678 bool lo_first = REGNO (operands[0]) < REGNO (operands[1]);
4679 rtx dst_lo = simplify_gen_subreg (HImode, operands[0], <MODE>mode, 0);
4680 rtx src_lo = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 0);
4681 rtx dst_hi = simplify_gen_subreg (mode_hi, operands[0], <MODE>mode, 2);
4682 rtx src_hi = simplify_gen_subreg (mode_hi, operands[1], <MODE>mode, 2);
4683
4684 operands[2] = lo_first ? dst_lo : dst_hi;
4685 operands[3] = lo_first ? src_lo : src_hi;
4686 operands[4] = lo_first ? dst_hi : dst_lo;
4687 operands[5] = lo_first ? src_hi : src_lo;
4688 })
4689
4690 (define_split
4691 [(set (match_operand:HI 0 "register_operand")
4692 (match_operand:HI 1 "reg_or_0_operand"))]
4693 "optimize
4694 && reload_completed
4695 && GENERAL_REG_P (operands[0])
4696 && (operands[1] == const0_rtx || GENERAL_REG_P (operands[1]))
4697 && (!AVR_HAVE_MOVW
4698 || const0_rtx == operands[1])"
4699 [(set (match_dup 2) (match_dup 3))
4700 (set (match_dup 4) (match_dup 5))]
4701 {
4702 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4703 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1);
4704 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4705 operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
4706 })
4707
4708 ;; Split andhi3, andpsi3, andsi3.
4709 ;; Split iorhi3, iorpsi3, iorsi3.
4710 ;; Split xorhi3, xorpsi3, xorsi3.
4711 (define_split
4712 [(parallel [(set (match_operand:HISI 0 "register_operand")
4713 (bitop:HISI (match_dup 0)
4714 (match_operand:HISI 1 "register_operand")))
4715 (clobber (scratch:QI))])]
4716 "optimize
4717 && reload_completed"
4718 [(const_int 1)]
4719 {
4720 for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++)
4721 {
4722 rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
4723 rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i);
4724 emit_insn (gen_<code>qi3 (dst, dst, src));
4725 }
4726 DONE;
4727 })
4728
4729
4730 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
4731 ;; swap
4732
4733 (define_expand "rotlqi3"
4734 [(set (match_operand:QI 0 "register_operand" "")
4735 (rotate:QI (match_operand:QI 1 "register_operand" "")
4736 (match_operand:QI 2 "const_0_to_7_operand" "")))]
4737 ""
4738 {
4739 if (!CONST_INT_P (operands[2]))
4740 FAIL;
4741
4742 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
4743 })
4744
4745 ;; Expander used by __builtin_avr_swap
4746 (define_expand "rotlqi3_4"
4747 [(set (match_operand:QI 0 "register_operand" "")
4748 (rotate:QI (match_operand:QI 1 "register_operand" "")
4749 (const_int 4)))])
4750
4751 (define_insn_and_split "*rotlqi3_split"
4752 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
4753 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
4754 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
4755 ""
4756 "#"
4757 "&& reload_completed"
4758 [(parallel [(set (match_dup 0)
4759 (rotate:QI (match_dup 1)
4760 (match_dup 2)))
4761 (clobber (reg:CC REG_CC))])])
4762
4763 (define_insn "*rotlqi3"
4764 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
4765 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
4766 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))
4767 (clobber (reg:CC REG_CC))]
4768 "reload_completed"
4769 "@
4770 lsl %0\;adc %0,__zero_reg__
4771 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
4772 swap %0\;bst %0,0\;ror %0\;bld %0,7
4773 swap %0
4774 swap %0\;lsl %0\;adc %0,__zero_reg__
4775 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
4776 bst %0,0\;ror %0\;bld %0,7
4777 " ; empty
4778 [(set_attr "length" "2,4,4,1,3,5,3,0")])
4779
4780 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
4781 ;; a whole number of bytes. The split creates the appropriate moves and
4782 ;; considers all overlap situations.
4783
4784 ;; HImode does not need scratch. Use attribute for this constraint.
4785
4786 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
4787 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
4788
4789 ;; "rotlhi3"
4790 ;; "rotlpsi3"
4791 ;; "rotlsi3"
4792 (define_expand "rotl<mode>3"
4793 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
4794 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
4795 (match_operand:HISI 2 "const_int_operand" "")))
4796 (clobber (match_dup 3))])]
4797 ""
4798 {
4799 int offset;
4800
4801 if (!CONST_INT_P (operands[2]))
4802 FAIL;
4803
4804 offset = INTVAL (operands[2]);
4805
4806 if (0 == offset % 8)
4807 {
4808 if (AVR_HAVE_MOVW && 0 == offset % 16)
4809 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
4810 else
4811 operands[3] = gen_rtx_SCRATCH (QImode);
4812 }
4813 else if (offset == 1
4814 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
4815 {
4816 /*; Support rotate left/right by 1 */
4817
4818 emit_move_insn (operands[0],
4819 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
4820 DONE;
4821 }
4822 else
4823 FAIL;
4824 })
4825
4826 (define_insn_and_split "*rotlhi2.1_split"
4827 [(set (match_operand:HI 0 "register_operand" "=r")
4828 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4829 (const_int 1)))]
4830 ""
4831 "#"
4832 "&& reload_completed"
4833 [(parallel [(set (match_dup 0)
4834 (rotate:HI (match_dup 1)
4835 (const_int 1)))
4836 (clobber (reg:CC REG_CC))])])
4837
4838 (define_insn "*rotlhi2.1"
4839 [(set (match_operand:HI 0 "register_operand" "=r")
4840 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4841 (const_int 1)))
4842 (clobber (reg:CC REG_CC))]
4843 "reload_completed"
4844 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
4845 [(set_attr "length" "3")])
4846
4847 (define_insn_and_split "*rotlhi2.15_split"
4848 [(set (match_operand:HI 0 "register_operand" "=r")
4849 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4850 (const_int 15)))]
4851 ""
4852 "#"
4853 "&& reload_completed"
4854 [(parallel [(set (match_dup 0)
4855 (rotate:HI (match_dup 1)
4856 (const_int 15)))
4857 (clobber (reg:CC REG_CC))])])
4858
4859 (define_insn "*rotlhi2.15"
4860 [(set (match_operand:HI 0 "register_operand" "=r")
4861 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4862 (const_int 15)))
4863 (clobber (reg:CC REG_CC))]
4864 "reload_completed"
4865 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
4866 [(set_attr "length" "4")])
4867
4868 (define_insn_and_split "*rotlpsi2.1_split"
4869 [(set (match_operand:PSI 0 "register_operand" "=r")
4870 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4871 (const_int 1)))]
4872 ""
4873 "#"
4874 "&& reload_completed"
4875 [(parallel [(set (match_dup 0)
4876 (rotate:PSI (match_dup 1)
4877 (const_int 1)))
4878 (clobber (reg:CC REG_CC))])])
4879
4880 (define_insn "*rotlpsi2.1"
4881 [(set (match_operand:PSI 0 "register_operand" "=r")
4882 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4883 (const_int 1)))
4884 (clobber (reg:CC REG_CC))]
4885 "reload_completed"
4886 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
4887 [(set_attr "length" "4")])
4888
4889 (define_insn_and_split "*rotlpsi2.23_split"
4890 [(set (match_operand:PSI 0 "register_operand" "=r")
4891 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4892 (const_int 23)))]
4893 ""
4894 "#"
4895 "&& reload_completed"
4896 [(parallel [(set (match_dup 0)
4897 (rotate:PSI (match_dup 1)
4898 (const_int 23)))
4899 (clobber (reg:CC REG_CC))])])
4900
4901 (define_insn "*rotlpsi2.23"
4902 [(set (match_operand:PSI 0 "register_operand" "=r")
4903 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4904 (const_int 23)))
4905 (clobber (reg:CC REG_CC))]
4906 "reload_completed"
4907 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
4908 [(set_attr "length" "5")])
4909
4910 (define_insn_and_split "*rotlsi2.1_split"
4911 [(set (match_operand:SI 0 "register_operand" "=r")
4912 (rotate:SI (match_operand:SI 1 "register_operand" "0")
4913 (const_int 1)))]
4914 ""
4915 "#"
4916 "&& reload_completed"
4917 [(parallel [(set (match_dup 0)
4918 (rotate:SI (match_dup 1)
4919 (const_int 1)))
4920 (clobber (reg:CC REG_CC))])])
4921
4922 (define_insn "*rotlsi2.1"
4923 [(set (match_operand:SI 0 "register_operand" "=r")
4924 (rotate:SI (match_operand:SI 1 "register_operand" "0")
4925 (const_int 1)))
4926 (clobber (reg:CC REG_CC))]
4927 "reload_completed"
4928 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
4929 [(set_attr "length" "5")])
4930
4931 (define_insn_and_split "*rotlsi2.31_split"
4932 [(set (match_operand:SI 0 "register_operand" "=r")
4933 (rotate:SI (match_operand:SI 1 "register_operand" "0")
4934 (const_int 31)))]
4935 ""
4936 "#"
4937 "&& reload_completed"
4938 [(parallel [(set (match_dup 0)
4939 (rotate:SI (match_dup 1)
4940 (const_int 31)))
4941 (clobber (reg:CC REG_CC))])])
4942
4943 (define_insn "*rotlsi2.31"
4944 [(set (match_operand:SI 0 "register_operand" "=r")
4945 (rotate:SI (match_operand:SI 1 "register_operand" "0")
4946 (const_int 31)))
4947 (clobber (reg:CC REG_CC))]
4948 "reload_completed"
4949 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
4950 [(set_attr "length" "6")])
4951
4952 ;; Overlapping non-HImode registers often (but not always) need a scratch.
4953 ;; The best we can do is use early clobber alternative "#&r" so that
4954 ;; completely non-overlapping operands dont get a scratch but # so register
4955 ;; allocation does not prefer non-overlapping.
4956
4957
4958 ;; Split word aligned rotates using scratch that is mode dependent.
4959
4960 ;; "*rotwhi"
4961 ;; "*rotwsi"
4962 (define_insn_and_split "*rotw<mode>"
4963 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
4964 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
4965 (match_operand 2 "const_int_operand" "n,n,n")))
4966 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
4967 "AVR_HAVE_MOVW
4968 && CONST_INT_P (operands[2])
4969 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
4970 && 0 == INTVAL (operands[2]) % 16"
4971 "#"
4972 "&& reload_completed"
4973 [(const_int 0)]
4974 {
4975 avr_rotate_bytes (operands);
4976 DONE;
4977 })
4978
4979
4980 ;; Split byte aligned rotates using scratch that is always QI mode.
4981
4982 ;; "*rotbhi"
4983 ;; "*rotbpsi"
4984 ;; "*rotbsi"
4985 (define_insn_and_split "*rotb<mode>"
4986 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
4987 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
4988 (match_operand 2 "const_int_operand" "n,n,n")))
4989 (clobber (match_scratch:QI 3 "=<rotx>"))]
4990 "CONST_INT_P (operands[2])
4991 && (8 == INTVAL (operands[2]) % 16
4992 || ((!AVR_HAVE_MOVW
4993 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
4994 && 0 == INTVAL (operands[2]) % 16))"
4995 "#"
4996 "&& reload_completed"
4997 [(const_int 0)]
4998 {
4999 avr_rotate_bytes (operands);
5000 DONE;
5001 })
5002
5003
5004 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
5005 ;; arithmetic shift left
5006
5007 ;; "ashlqi3"
5008 ;; "ashlqq3" "ashluqq3"
5009 (define_expand "ashl<mode>3"
5010 [(set (match_operand:ALL1 0 "register_operand" "")
5011 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
5012 (match_operand:QI 2 "nop_general_operand" "")))])
5013
5014 (define_split ; ashlqi3_const4
5015 [(set (match_operand:ALL1 0 "d_register_operand" "")
5016 (ashift:ALL1 (match_dup 0)
5017 (const_int 4)))]
5018 ""
5019 [(set (match_dup 1)
5020 (rotate:QI (match_dup 1)
5021 (const_int 4)))
5022 (set (match_dup 1)
5023 (and:QI (match_dup 1)
5024 (const_int -16)))]
5025 {
5026 operands[1] = avr_to_int_mode (operands[0]);
5027 })
5028
5029 (define_split ; ashlqi3_const5
5030 [(set (match_operand:ALL1 0 "d_register_operand" "")
5031 (ashift:ALL1 (match_dup 0)
5032 (const_int 5)))]
5033 ""
5034 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5035 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
5036 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
5037 {
5038 operands[1] = avr_to_int_mode (operands[0]);
5039 })
5040
5041 (define_split ; ashlqi3_const6
5042 [(set (match_operand:ALL1 0 "d_register_operand" "")
5043 (ashift:ALL1 (match_dup 0)
5044 (const_int 6)))]
5045 ""
5046 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5047 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
5048 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
5049 {
5050 operands[1] = avr_to_int_mode (operands[0]);
5051 })
5052
5053 ;; "*ashlqi3"
5054 ;; "*ashlqq3" "*ashluqq3"
5055 (define_insn_and_split "*ashl<mode>3_split"
5056 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5057 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5058 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
5059 ""
5060 "#"
5061 "&& reload_completed"
5062 [(parallel [(set (match_dup 0)
5063 (ashift:ALL1 (match_dup 1)
5064 (match_dup 2)))
5065 (clobber (reg:CC REG_CC))])])
5066
5067 (define_insn "*ashl<mode>3"
5068 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5069 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5070 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))
5071 (clobber (reg:CC REG_CC))]
5072 "reload_completed"
5073 {
5074 return ashlqi3_out (insn, operands, NULL);
5075 }
5076 [(set_attr "length" "5,0,1,2,4,6,9")
5077 (set_attr "adjust_len" "ashlqi")])
5078
5079 (define_insn_and_split "ashl<mode>3"
5080 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5081 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5082 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5083 ""
5084 "#"
5085 "&& reload_completed"
5086 [(parallel [(set (match_dup 0)
5087 (ashift:ALL2 (match_dup 1)
5088 (match_dup 2)))
5089 (clobber (reg:CC REG_CC))])])
5090
5091 (define_insn "*ashl<mode>3"
5092 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5093 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5094 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5095 (clobber (reg:CC REG_CC))]
5096 "reload_completed"
5097 {
5098 return ashlhi3_out (insn, operands, NULL);
5099 }
5100 [(set_attr "length" "6,0,2,2,4,10,10")
5101 (set_attr "adjust_len" "ashlhi")])
5102
5103
5104 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
5105 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
5106
5107 ;; "*ashluqihiqi3"
5108 ;; "*ashlsqihiqi3"
5109 (define_insn_and_split "*ashl<extend_su>qihiqi3"
5110 [(set (match_operand:QI 0 "register_operand" "=r")
5111 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
5112 (match_operand:QI 2 "register_operand" "r"))
5113 0))]
5114 ""
5115 "#"
5116 ""
5117 [(set (match_dup 0)
5118 (ashift:QI (match_dup 1)
5119 (match_dup 2)))])
5120
5121 ;; ??? Combiner does not recognize that it could split the following insn;
5122 ;; presumably because he has no register handy?
5123
5124 ;; "*ashluqihiqi3.mem"
5125 ;; "*ashlsqihiqi3.mem"
5126 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
5127 [(set (match_operand:QI 0 "memory_operand" "=m")
5128 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
5129 (match_operand:QI 2 "register_operand" "r"))
5130 0))]
5131 "!reload_completed"
5132 { gcc_unreachable(); }
5133 "&& 1"
5134 [(set (match_dup 3)
5135 (ashift:QI (match_dup 1)
5136 (match_dup 2)))
5137 (set (match_dup 0)
5138 (match_dup 3))]
5139 {
5140 operands[3] = gen_reg_rtx (QImode);
5141 })
5142
5143 ;; Similar.
5144
5145 (define_insn_and_split "*ashlhiqi3"
5146 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
5147 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
5148 (match_operand:QI 2 "register_operand" "r")) 0))]
5149 "!reload_completed"
5150 { gcc_unreachable(); }
5151 "&& 1"
5152 [(set (match_dup 4)
5153 (ashift:QI (match_dup 3)
5154 (match_dup 2)))
5155 (set (match_dup 0)
5156 (match_dup 4))]
5157 {
5158 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
5159 operands[4] = gen_reg_rtx (QImode);
5160 })
5161
5162 ;; High part of 16-bit shift is unused after the instruction:
5163 ;; No need to compute it, map to 8-bit shift.
5164
5165 (define_peephole2
5166 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5167 (ashift:HI (match_dup 0)
5168 (match_operand:QI 1 "register_operand" "")))
5169 (clobber (reg:CC REG_CC))])]
5170 ""
5171 [(parallel [(set (match_dup 2)
5172 (ashift:QI (match_dup 2)
5173 (match_dup 1)))
5174 (clobber (reg:CC REG_CC))])
5175 (clobber (match_dup 3))]
5176 {
5177 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5178
5179 if (!peep2_reg_dead_p (1, operands[3]))
5180 FAIL;
5181
5182 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5183 })
5184
5185
5186 ;; "ashlsi3"
5187 ;; "ashlsq3" "ashlusq3"
5188 ;; "ashlsa3" "ashlusa3"
5189 (define_insn_and_split "ashl<mode>3"
5190 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5191 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5192 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5193 ""
5194 "#"
5195 "&& reload_completed"
5196 [(parallel [(set (match_dup 0)
5197 (ashift:ALL4 (match_dup 1)
5198 (match_dup 2)))
5199 (clobber (reg:CC REG_CC))])])
5200
5201 (define_insn "*ashl<mode>3"
5202 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5203 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5204 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5205 (clobber (reg:CC REG_CC))]
5206 "reload_completed"
5207 {
5208 return ashlsi3_out (insn, operands, NULL);
5209 }
5210 [(set_attr "length" "8,0,4,4,8,10,12")
5211 (set_attr "adjust_len" "ashlsi")])
5212
5213 ;; Optimize if a scratch register from LD_REGS happens to be available.
5214
5215 (define_peephole2 ; ashlqi3_l_const4
5216 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5217 (ashift:ALL1 (match_dup 0)
5218 (const_int 4)))
5219 (clobber (reg:CC REG_CC))])
5220 (match_scratch:QI 1 "d")]
5221 ""
5222 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5223 (clobber (reg:CC REG_CC))])
5224 (parallel [(set (match_dup 1) (const_int -16))
5225 (clobber (reg:CC REG_CC))])
5226 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5227 (clobber (reg:CC REG_CC))])]
5228 {
5229 operands[2] = avr_to_int_mode (operands[0]);
5230 })
5231
5232 (define_peephole2 ; ashlqi3_l_const5
5233 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5234 (ashift:ALL1 (match_dup 0)
5235 (const_int 5)))
5236 (clobber (reg:CC REG_CC))])
5237 (match_scratch:QI 1 "d")]
5238 ""
5239 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5240 (clobber (reg:CC REG_CC))])
5241 (parallel [(set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
5242 (clobber (reg:CC REG_CC))])
5243 (parallel [(set (match_dup 1) (const_int -32))
5244 (clobber (reg:CC REG_CC))])
5245 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5246 (clobber (reg:CC REG_CC))])]
5247 {
5248 operands[2] = avr_to_int_mode (operands[0]);
5249 })
5250
5251 (define_peephole2 ; ashlqi3_l_const6
5252 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5253 (ashift:ALL1 (match_dup 0)
5254 (const_int 6)))
5255 (clobber (reg:CC REG_CC))])
5256 (match_scratch:QI 1 "d")]
5257 ""
5258 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5259 (clobber (reg:CC REG_CC))])
5260 (parallel [(set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
5261 (clobber (reg:CC REG_CC))])
5262 (parallel [(set (match_dup 1) (const_int -64))
5263 (clobber (reg:CC REG_CC))])
5264 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5265 (clobber (reg:CC REG_CC))])]
5266 {
5267 operands[2] = avr_to_int_mode (operands[0]);
5268 })
5269
5270 (define_peephole2
5271 [(match_scratch:QI 3 "d")
5272 (parallel [(set (match_operand:ALL2 0 "register_operand" "")
5273 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
5274 (match_operand:QI 2 "const_int_operand" "")))
5275 (clobber (reg:CC REG_CC))])]
5276 ""
5277 [(parallel [(set (match_dup 0)
5278 (ashift:ALL2 (match_dup 1)
5279 (match_dup 2)))
5280 (clobber (match_dup 3))
5281 (clobber (reg:CC REG_CC))])])
5282
5283 ;; "*ashlhi3_const"
5284 ;; "*ashlhq3_const" "*ashluhq3_const"
5285 ;; "*ashlha3_const" "*ashluha3_const"
5286 (define_insn_and_split "*ashl<mode>3_const_split"
5287 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5288 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5289 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5290 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5291 "reload_completed"
5292 "#"
5293 "&& reload_completed"
5294 [(parallel [(set (match_dup 0)
5295 (ashift:ALL2 (match_dup 1)
5296 (match_dup 2)))
5297 (clobber (match_dup 3))
5298 (clobber (reg:CC REG_CC))])])
5299
5300 (define_insn "*ashl<mode>3_const"
5301 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5302 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5303 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5304 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5305 (clobber (reg:CC REG_CC))]
5306 "reload_completed"
5307 {
5308 return ashlhi3_out (insn, operands, NULL);
5309 }
5310 [(set_attr "length" "0,2,2,4,10")
5311 (set_attr "adjust_len" "ashlhi")])
5312
5313 (define_peephole2
5314 [(match_scratch:QI 3 "d")
5315 (parallel [(set (match_operand:ALL4 0 "register_operand" "")
5316 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
5317 (match_operand:QI 2 "const_int_operand" "")))
5318 (clobber (reg:CC REG_CC))])]
5319 ""
5320 [(parallel [(set (match_dup 0)
5321 (ashift:ALL4 (match_dup 1)
5322 (match_dup 2)))
5323 (clobber (match_dup 3))
5324 (clobber (reg:CC REG_CC))])])
5325
5326 ;; "*ashlsi3_const"
5327 ;; "*ashlsq3_const" "*ashlusq3_const"
5328 ;; "*ashlsa3_const" "*ashlusa3_const"
5329 (define_insn_and_split "*ashl<mode>3_const_split"
5330 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5331 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5332 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5333 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5334 "reload_completed"
5335 "#"
5336 "&& reload_completed"
5337 [(parallel [(set (match_dup 0)
5338 (ashift:ALL4 (match_dup 1)
5339 (match_dup 2)))
5340 (clobber (match_dup 3))
5341 (clobber (reg:CC REG_CC))])])
5342
5343 (define_insn "*ashl<mode>3_const"
5344 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5345 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5346 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5347 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5348 (clobber (reg:CC REG_CC))]
5349 "reload_completed"
5350 {
5351 return ashlsi3_out (insn, operands, NULL);
5352 }
5353 [(set_attr "length" "0,4,4,10")
5354 (set_attr "adjust_len" "ashlsi")])
5355
5356 (define_expand "ashlpsi3"
5357 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
5358 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
5359 (match_operand:QI 2 "nonmemory_operand" "")))
5360 (clobber (scratch:QI))])]
5361 ""
5362 {
5363 if (AVR_HAVE_MUL
5364 && CONST_INT_P (operands[2]))
5365 {
5366 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
5367 {
5368 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
5369 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
5370 DONE;
5371 }
5372 else if (optimize_insn_for_speed_p ()
5373 && INTVAL (operands[2]) != 16
5374 && IN_RANGE (INTVAL (operands[2]), 9, 22))
5375 {
5376 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
5377 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
5378 DONE;
5379 }
5380 }
5381 })
5382
5383 (define_insn_and_split "*ashlpsi3_split"
5384 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
5385 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
5386 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
5387 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5388 ""
5389 "#"
5390 "&& reload_completed"
5391 [(parallel [(set (match_dup 0)
5392 (ashift:PSI (match_dup 1)
5393 (match_dup 2)))
5394 (clobber (match_dup 3))
5395 (clobber (reg:CC REG_CC))])])
5396
5397 (define_insn "*ashlpsi3"
5398 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
5399 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
5400 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
5401 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5402 (clobber (reg:CC REG_CC))]
5403 "reload_completed"
5404 {
5405 return avr_out_ashlpsi3 (insn, operands, NULL);
5406 }
5407 [(set_attr "adjust_len" "ashlpsi")])
5408
5409 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
5410 ;; arithmetic shift right
5411
5412 ;; "ashrqi3"
5413 ;; "ashrqq3" "ashruqq3"
5414 (define_insn_and_split "ashr<mode>3"
5415 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
5416 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
5417 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
5418 ""
5419 "#"
5420 "&& reload_completed"
5421 [(parallel [(set (match_dup 0)
5422 (ashiftrt:ALL1 (match_dup 1)
5423 (match_dup 2)))
5424 (clobber (reg:CC REG_CC))])])
5425
5426 (define_insn "*ashr<mode>3"
5427 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
5428 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
5429 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))
5430 (clobber (reg:CC REG_CC))]
5431 "reload_completed"
5432 {
5433 return ashrqi3_out (insn, operands, NULL);
5434 }
5435 [(set_attr "length" "5,0,1,2,5,4,9")
5436 (set_attr "adjust_len" "ashrqi")])
5437
5438 ;; "ashrhi3"
5439 ;; "ashrhq3" "ashruhq3"
5440 ;; "ashrha3" "ashruha3"
5441 (define_insn_and_split "ashr<mode>3"
5442 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5443 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5444 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5445 ""
5446 "#"
5447 "&& reload_completed"
5448 [(parallel [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5449 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5450 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5451 (clobber (reg:CC REG_CC))])])
5452
5453 (define_insn "*ashr<mode>3"
5454 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5455 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5456 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5457 (clobber (reg:CC REG_CC))]
5458 "reload_completed"
5459 {
5460 return ashrhi3_out (insn, operands, NULL);
5461 }
5462 [(set_attr "length" "6,0,2,4,4,10,10")
5463 (set_attr "adjust_len" "ashrhi")])
5464
5465 (define_insn_and_split "ashrpsi3"
5466 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5467 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
5468 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
5469 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5470 ""
5471 "#"
5472 "&& reload_completed"
5473 [(parallel [(set (match_dup 0)
5474 (ashiftrt:PSI (match_dup 1)
5475 (match_dup 2)))
5476 (clobber (match_dup 3))
5477 (clobber (reg:CC REG_CC))])])
5478
5479 (define_insn "*ashrpsi3"
5480 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5481 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
5482 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
5483 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5484 (clobber (reg:CC REG_CC))]
5485 "reload_completed"
5486 {
5487 return avr_out_ashrpsi3 (insn, operands, NULL);
5488 }
5489 [(set_attr "adjust_len" "ashrpsi")])
5490
5491 ;; "ashrsi3"
5492 ;; "ashrsq3" "ashrusq3"
5493 ;; "ashrsa3" "ashrusa3"
5494 (define_insn_and_split "ashr<mode>3"
5495 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5496 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5497 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5498 ""
5499 "#"
5500 "&& reload_completed"
5501 [(parallel [(set (match_dup 0)
5502 (ashiftrt:ALL4 (match_dup 1)
5503 (match_dup 2)))
5504 (clobber (reg:CC REG_CC))])])
5505
5506 (define_insn "*ashr<mode>3"
5507 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5508 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5509 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5510 (clobber (reg:CC REG_CC))]
5511 "reload_completed"
5512 {
5513 return ashrsi3_out (insn, operands, NULL);
5514 }
5515 [(set_attr "length" "8,0,4,6,8,10,12")
5516 (set_attr "adjust_len" "ashrsi")])
5517
5518 ;; Optimize if a scratch register from LD_REGS happens to be available.
5519
5520 (define_peephole2
5521 [(match_scratch:QI 3 "d")
5522 (parallel [(set (match_operand:ALL2 0 "register_operand" "")
5523 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
5524 (match_operand:QI 2 "const_int_operand" "")))
5525 (clobber (reg:CC REG_CC))])]
5526 ""
5527 [(parallel [(set (match_dup 0)
5528 (ashiftrt:ALL2 (match_dup 1)
5529 (match_dup 2)))
5530 (clobber (match_dup 3))
5531 (clobber (reg:CC REG_CC))])])
5532
5533 ;; "*ashrhi3_const"
5534 ;; "*ashrhq3_const" "*ashruhq3_const"
5535 ;; "*ashrha3_const" "*ashruha3_const"
5536 (define_insn_and_split "*ashr<mode>3_const_split"
5537 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5538 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5539 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5540 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5541 "reload_completed"
5542 "#"
5543 "&& reload_completed"
5544 [(parallel [(set (match_dup 0)
5545 (ashiftrt:ALL2 (match_dup 1)
5546 (match_dup 2)))
5547 (clobber (match_dup 3))
5548 (clobber (reg:CC REG_CC))])])
5549
5550 (define_insn "*ashr<mode>3_const"
5551 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5552 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5553 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5554 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5555 (clobber (reg:CC REG_CC))]
5556 "reload_completed"
5557 {
5558 return ashrhi3_out (insn, operands, NULL);
5559 }
5560 [(set_attr "length" "0,2,4,4,10")
5561 (set_attr "adjust_len" "ashrhi")])
5562
5563 (define_peephole2
5564 [(match_scratch:QI 3 "d")
5565 (parallel [(set (match_operand:ALL4 0 "register_operand" "")
5566 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
5567 (match_operand:QI 2 "const_int_operand" "")))
5568 (clobber (reg:CC REG_CC))])]
5569 ""
5570 [(parallel [(set (match_dup 0)
5571 (ashiftrt:ALL4 (match_dup 1)
5572 (match_dup 2)))
5573 (clobber (match_dup 3))
5574 (clobber (reg:CC REG_CC))])])
5575
5576 ;; "*ashrsi3_const"
5577 ;; "*ashrsq3_const" "*ashrusq3_const"
5578 ;; "*ashrsa3_const" "*ashrusa3_const"
5579 (define_insn_and_split "*ashr<mode>3_const_split"
5580 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5581 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5582 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5583 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5584 "reload_completed"
5585 "#"
5586 "&& reload_completed"
5587 [(parallel [(set (match_dup 0)
5588 (ashiftrt:ALL4 (match_dup 1)
5589 (match_dup 2)))
5590 (clobber (match_dup 3))
5591 (clobber (reg:CC REG_CC))])])
5592
5593 (define_insn "*ashr<mode>3_const"
5594 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5595 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5596 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5597 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5598 (clobber (reg:CC REG_CC))]
5599 "reload_completed"
5600 {
5601 return ashrsi3_out (insn, operands, NULL);
5602 }
5603 [(set_attr "length" "0,4,4,10")
5604 (set_attr "adjust_len" "ashrsi")])
5605
5606 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
5607 ;; logical shift right
5608
5609 ;; "lshrqi3"
5610 ;; "lshrqq3" "lshruqq3"
5611 (define_expand "lshr<mode>3"
5612 [(set (match_operand:ALL1 0 "register_operand" "")
5613 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
5614 (match_operand:QI 2 "nop_general_operand" "")))])
5615
5616 (define_split ; lshrqi3_const4
5617 [(set (match_operand:ALL1 0 "d_register_operand" "")
5618 (lshiftrt:ALL1 (match_dup 0)
5619 (const_int 4)))]
5620 ""
5621 [(set (match_dup 1)
5622 (rotate:QI (match_dup 1)
5623 (const_int 4)))
5624 (set (match_dup 1)
5625 (and:QI (match_dup 1)
5626 (const_int 15)))]
5627 {
5628 operands[1] = avr_to_int_mode (operands[0]);
5629 })
5630
5631 (define_split ; lshrqi3_const5
5632 [(set (match_operand:ALL1 0 "d_register_operand" "")
5633 (lshiftrt:ALL1 (match_dup 0)
5634 (const_int 5)))]
5635 ""
5636 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5637 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
5638 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
5639 {
5640 operands[1] = avr_to_int_mode (operands[0]);
5641 })
5642
5643 (define_split ; lshrqi3_const6
5644 [(set (match_operand:QI 0 "d_register_operand" "")
5645 (lshiftrt:QI (match_dup 0)
5646 (const_int 6)))]
5647 ""
5648 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5649 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
5650 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
5651 {
5652 operands[1] = avr_to_int_mode (operands[0]);
5653 })
5654
5655 ;; "*lshrqi3"
5656 ;; "*lshrqq3"
5657 ;; "*lshruqq3"
5658 (define_insn_and_split "*lshr<mode>3_split"
5659 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5660 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5661 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
5662 ""
5663 "#"
5664 "&& reload_completed"
5665 [(parallel [(set (match_dup 0)
5666 (lshiftrt:ALL1 (match_dup 1)
5667 (match_dup 2)))
5668 (clobber (reg:CC REG_CC))])])
5669
5670 (define_insn "*lshr<mode>3"
5671 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5672 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5673 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))
5674 (clobber (reg:CC REG_CC))]
5675 "reload_completed"
5676 {
5677 return lshrqi3_out (insn, operands, NULL);
5678 }
5679 [(set_attr "length" "5,0,1,2,4,6,9")
5680 (set_attr "adjust_len" "lshrqi")])
5681
5682 ;; "lshrhi3"
5683 ;; "lshrhq3" "lshruhq3"
5684 ;; "lshrha3" "lshruha3"
5685 (define_insn_and_split "lshr<mode>3"
5686 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5687 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5688 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5689 ""
5690 "#"
5691 "&& reload_completed"
5692 [(parallel [(set (match_dup 0)
5693 (lshiftrt:ALL2 (match_dup 1)
5694 (match_dup 2)))
5695 (clobber (reg:CC REG_CC))])])
5696
5697 (define_insn "*lshr<mode>3"
5698 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5699 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5700 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5701 (clobber (reg:CC REG_CC))]
5702 "reload_completed"
5703 {
5704 return lshrhi3_out (insn, operands, NULL);
5705 }
5706 [(set_attr "length" "6,0,2,2,4,10,10")
5707 (set_attr "adjust_len" "lshrhi")])
5708
5709 (define_insn_and_split "lshrpsi3"
5710 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5711 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
5712 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
5713 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5714 ""
5715 "#"
5716 "&& reload_completed"
5717 [(parallel [(set (match_dup 0)
5718 (lshiftrt:PSI (match_dup 1)
5719 (match_dup 2)))
5720 (clobber (match_dup 3))
5721 (clobber (reg:CC REG_CC))])])
5722
5723 (define_insn "*lshrpsi3"
5724 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5725 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
5726 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
5727 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5728 (clobber (reg:CC REG_CC))]
5729 "reload_completed"
5730 {
5731 return avr_out_lshrpsi3 (insn, operands, NULL);
5732 }
5733 [(set_attr "adjust_len" "lshrpsi")])
5734
5735 ;; "lshrsi3"
5736 ;; "lshrsq3" "lshrusq3"
5737 ;; "lshrsa3" "lshrusa3"
5738 (define_insn_and_split "lshr<mode>3"
5739 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5740 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5741 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5742 ""
5743 "#"
5744 "&& reload_completed"
5745 [(parallel [(set (match_dup 0)
5746 (lshiftrt:ALL4 (match_dup 1)
5747 (match_dup 2)))
5748 (clobber (reg:CC REG_CC))])])
5749
5750 (define_insn "*lshr<mode>3"
5751 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5752 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5753 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5754 (clobber (reg:CC REG_CC))]
5755 "reload_completed"
5756 {
5757 return lshrsi3_out (insn, operands, NULL);
5758 }
5759 [(set_attr "length" "8,0,4,4,8,10,12")
5760 (set_attr "adjust_len" "lshrsi")])
5761
5762 ;; Optimize if a scratch register from LD_REGS happens to be available.
5763
5764 (define_peephole2 ; lshrqi3_l_const4
5765 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5766 (lshiftrt:ALL1 (match_dup 0)
5767 (const_int 4)))
5768 (clobber (reg:CC REG_CC))])
5769 (match_scratch:QI 1 "d")]
5770 ""
5771 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5772 (clobber (reg:CC REG_CC))])
5773 (parallel [(set (match_dup 1) (const_int 15))
5774 (clobber (reg:CC REG_CC))])
5775 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5776 (clobber (reg:CC REG_CC))])]
5777 {
5778 operands[2] = avr_to_int_mode (operands[0]);
5779 })
5780
5781 (define_peephole2 ; lshrqi3_l_const5
5782 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5783 (lshiftrt:ALL1 (match_dup 0)
5784 (const_int 5)))
5785 (clobber (reg:CC REG_CC))])
5786 (match_scratch:QI 1 "d")]
5787 ""
5788 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5789 (clobber (reg:CC REG_CC))])
5790 (parallel [(set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
5791 (clobber (reg:CC REG_CC))])
5792 (parallel [(set (match_dup 1) (const_int 7))
5793 (clobber (reg:CC REG_CC))])
5794 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5795 (clobber (reg:CC REG_CC))])]
5796 {
5797 operands[2] = avr_to_int_mode (operands[0]);
5798 })
5799
5800 (define_peephole2 ; lshrqi3_l_const6
5801 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5802 (lshiftrt:ALL1 (match_dup 0)
5803 (const_int 6)))
5804 (clobber (reg:CC REG_CC))])
5805 (match_scratch:QI 1 "d")]
5806 ""
5807 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5808 (clobber (reg:CC REG_CC))])
5809 (parallel [(set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
5810 (clobber (reg:CC REG_CC))])
5811 (parallel [(set (match_dup 1) (const_int 3))
5812 (clobber (reg:CC REG_CC))])
5813 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5814 (clobber (reg:CC REG_CC))])]
5815 {
5816 operands[2] = avr_to_int_mode (operands[0]);
5817 })
5818
5819 (define_peephole2
5820 [(match_scratch:QI 3 "d")
5821 (parallel [(set (match_operand:ALL2 0 "register_operand" "")
5822 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
5823 (match_operand:QI 2 "const_int_operand" "")))
5824 (clobber (reg:CC REG_CC))])]
5825 ""
5826 [(parallel [(set (match_dup 0)
5827 (lshiftrt:ALL2 (match_dup 1)
5828 (match_dup 2)))
5829 (clobber (match_dup 3))
5830 (clobber (reg:CC REG_CC))])])
5831
5832 ;; "*lshrhi3_const"
5833 ;; "*lshrhq3_const" "*lshruhq3_const"
5834 ;; "*lshrha3_const" "*lshruha3_const"
5835 (define_insn_and_split "*lshr<mode>3_const_split"
5836 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5837 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5838 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5839 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5840 "reload_completed"
5841 "#"
5842 "&& reload_completed"
5843 [(parallel [(set (match_dup 0)
5844 (lshiftrt:ALL2 (match_dup 1)
5845 (match_dup 2)))
5846 (clobber (match_dup 3))
5847 (clobber (reg:CC REG_CC))])])
5848
5849 (define_insn "*lshr<mode>3_const"
5850 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5851 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5852 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5853 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5854 (clobber (reg:CC REG_CC))]
5855 "reload_completed"
5856 {
5857 return lshrhi3_out (insn, operands, NULL);
5858 }
5859 [(set_attr "length" "0,2,2,4,10")
5860 (set_attr "adjust_len" "lshrhi")])
5861
5862 (define_peephole2
5863 [(match_scratch:QI 3 "d")
5864 (parallel [(set (match_operand:ALL4 0 "register_operand" "")
5865 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
5866 (match_operand:QI 2 "const_int_operand" "")))
5867 (clobber (reg:CC REG_CC))])]
5868 ""
5869 [(parallel [(set (match_dup 0)
5870 (lshiftrt:ALL4 (match_dup 1)
5871 (match_dup 2)))
5872 (clobber (match_dup 3))
5873 (clobber (reg:CC REG_CC))])])
5874
5875 ;; "*lshrsi3_const"
5876 ;; "*lshrsq3_const" "*lshrusq3_const"
5877 ;; "*lshrsa3_const" "*lshrusa3_const"
5878 (define_insn_and_split "*lshr<mode>3_const_split"
5879 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5880 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5881 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5882 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5883 "reload_completed"
5884 "#"
5885 "&& reload_completed"
5886 [(parallel [(set (match_dup 0)
5887 (lshiftrt:ALL4 (match_dup 1)
5888 (match_dup 2)))
5889 (clobber (match_dup 3))
5890 (clobber (reg:CC REG_CC))])])
5891
5892 (define_insn "*lshr<mode>3_const"
5893 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5894 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5895 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5896 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5897 (clobber (reg:CC REG_CC))]
5898 "reload_completed"
5899 {
5900 return lshrsi3_out (insn, operands, NULL);
5901 }
5902 [(set_attr "length" "0,4,4,10")
5903 (set_attr "adjust_len" "lshrsi")])
5904
5905 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
5906 ;; abs
5907
5908 (define_insn_and_split "absqi2"
5909 [(set (match_operand:QI 0 "register_operand" "=r")
5910 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
5911 ""
5912 "#"
5913 "&& reload_completed"
5914 [(parallel [(set (match_dup 0)
5915 (abs:QI (match_dup 1)))
5916 (clobber (reg:CC REG_CC))])])
5917
5918 (define_insn "*absqi2"
5919 [(set (match_operand:QI 0 "register_operand" "=r")
5920 (abs:QI (match_operand:QI 1 "register_operand" "0")))
5921 (clobber (reg:CC REG_CC))]
5922 "reload_completed"
5923 "sbrc %0,7
5924 neg %0"
5925 [(set_attr "length" "2")])
5926
5927
5928 (define_insn_and_split "abssf2"
5929 [(set (match_operand:SF 0 "register_operand" "=d,r")
5930 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
5931 ""
5932 "#"
5933 "&& reload_completed"
5934 [(parallel [(set (match_dup 0)
5935 (abs:SF (match_dup 1)))
5936 (clobber (reg:CC REG_CC))])])
5937
5938 (define_insn "*abssf2"
5939 [(set (match_operand:SF 0 "register_operand" "=d,r")
5940 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))
5941 (clobber (reg:CC REG_CC))]
5942 "reload_completed"
5943 "@
5944 andi %D0,0x7f
5945 clt\;bld %D0,7"
5946 [(set_attr "length" "1,2")])
5947
5948 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
5949 ;; neg
5950
5951 (define_insn_and_split "negqi2"
5952 [(set (match_operand:QI 0 "register_operand" "=r")
5953 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
5954 ""
5955 "#"
5956 "&& reload_completed"
5957 [(parallel [(set (match_dup 0)
5958 (neg:QI (match_dup 1)))
5959 (clobber (reg:CC REG_CC))])])
5960
5961 (define_insn "*negqi2"
5962 [(set (match_operand:QI 0 "register_operand" "=r")
5963 (neg:QI (match_operand:QI 1 "register_operand" "0")))
5964 (clobber (reg:CC REG_CC))]
5965 "reload_completed"
5966 "neg %0"
5967 [(set_attr "length" "1")])
5968
5969 (define_insn_and_split "*negqihi2_split"
5970 [(set (match_operand:HI 0 "register_operand" "=r")
5971 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
5972 ""
5973 "#"
5974 "&& reload_completed"
5975 [(parallel [(set (match_dup 0)
5976 (neg:HI (sign_extend:HI (match_dup 1))))
5977 (clobber (reg:CC REG_CC))])])
5978
5979 (define_insn "*negqihi2"
5980 [(set (match_operand:HI 0 "register_operand" "=r")
5981 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))
5982 (clobber (reg:CC REG_CC))]
5983 "reload_completed"
5984 "clr %B0\;neg %A0\;brge .+2\;com %B0"
5985 [(set_attr "length" "4")])
5986
5987 (define_insn_and_split "neghi2"
5988 [(set (match_operand:HI 0 "register_operand" "=r,&r")
5989 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
5990 ""
5991 "#"
5992 "&& reload_completed"
5993 [(parallel [(set (match_dup 0)
5994 (neg:HI (match_dup 1)))
5995 (clobber (reg:CC REG_CC))])])
5996
5997 (define_insn "*neghi2"
5998 [(set (match_operand:HI 0 "register_operand" "=r,&r")
5999 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))
6000 (clobber (reg:CC REG_CC))]
6001 "reload_completed"
6002 "@
6003 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
6004 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
6005 [(set_attr "length" "3,4")])
6006
6007 (define_insn_and_split "negpsi2"
6008 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
6009 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
6010 ""
6011 "#"
6012 "&& reload_completed"
6013 [(parallel [(set (match_dup 0)
6014 (neg:PSI (match_dup 1)))
6015 (clobber (reg:CC REG_CC))])])
6016
6017 (define_insn "*negpsi2"
6018 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
6019 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))
6020 (clobber (reg:CC REG_CC))]
6021 "reload_completed"
6022 "@
6023 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
6024 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
6025 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
6026 [(set_attr "length" "5,6,6")])
6027
6028 (define_insn_and_split "negsi2"
6029 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
6030 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
6031 ""
6032 "#"
6033 "&& reload_completed"
6034 [(parallel [(set (match_dup 0)
6035 (neg:SI (match_dup 1)))
6036 (clobber (reg:CC REG_CC))])]
6037 ""
6038 [(set_attr "isa" "*,*,mov,movw")])
6039
6040 (define_insn "*negsi2"
6041 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
6042 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))
6043 (clobber (reg:CC REG_CC))]
6044 "reload_completed"
6045 "@
6046 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
6047 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
6048 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
6049 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
6050 [(set_attr "length" "7,8,8,7")
6051 (set_attr "isa" "*,*,mov,movw")])
6052
6053 (define_insn_and_split "negsf2"
6054 [(set (match_operand:SF 0 "register_operand" "=d,r")
6055 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
6056 ""
6057 "#"
6058 "&& reload_completed"
6059 [(parallel [(set (match_dup 0)
6060 (neg:SF (match_dup 1)))
6061 (clobber (reg:CC REG_CC))])])
6062
6063 (define_insn "*negsf2"
6064 [(set (match_operand:SF 0 "register_operand" "=d,r")
6065 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))
6066 (clobber (reg:CC REG_CC))]
6067 "reload_completed"
6068 "@
6069 subi %D0,0x80
6070 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
6071 [(set_attr "length" "1,4")])
6072
6073 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6074 ;; not
6075
6076 (define_insn_and_split "one_cmplqi2"
6077 [(set (match_operand:QI 0 "register_operand" "=r")
6078 (not:QI (match_operand:QI 1 "register_operand" "0")))]
6079 ""
6080 "#"
6081 "&& reload_completed"
6082 [(parallel [(set (match_dup 0)
6083 (not:QI (match_dup 1)))
6084 (clobber (reg:CC REG_CC))])])
6085
6086 (define_insn "*one_cmplqi2"
6087 [(set (match_operand:QI 0 "register_operand" "=r")
6088 (not:QI (match_operand:QI 1 "register_operand" "0")))
6089 (clobber (reg:CC REG_CC))]
6090 "reload_completed"
6091 "com %0"
6092 [(set_attr "length" "1")])
6093
6094 (define_insn_and_split "one_cmplhi2"
6095 [(set (match_operand:HI 0 "register_operand" "=r")
6096 (not:HI (match_operand:HI 1 "register_operand" "0")))]
6097 ""
6098 "#"
6099 "&& reload_completed"
6100 [(parallel [(set (match_dup 0)
6101 (not:HI (match_dup 1)))
6102 (clobber (reg:CC REG_CC))])])
6103
6104 (define_insn "*one_cmplhi2"
6105 [(set (match_operand:HI 0 "register_operand" "=r")
6106 (not:HI (match_operand:HI 1 "register_operand" "0")))
6107 (clobber (reg:CC REG_CC))]
6108 "reload_completed"
6109 "com %0
6110 com %B0"
6111 [(set_attr "length" "2")])
6112
6113 (define_insn_and_split "one_cmplpsi2"
6114 [(set (match_operand:PSI 0 "register_operand" "=r")
6115 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
6116 ""
6117 "#"
6118 "&& reload_completed"
6119 [(parallel [(set (match_dup 0)
6120 (not:PSI (match_dup 1)))
6121 (clobber (reg:CC REG_CC))])])
6122
6123 (define_insn "*one_cmplpsi2"
6124 [(set (match_operand:PSI 0 "register_operand" "=r")
6125 (not:PSI (match_operand:PSI 1 "register_operand" "0")))
6126 (clobber (reg:CC REG_CC))]
6127 "reload_completed"
6128 "com %0\;com %B0\;com %C0"
6129 [(set_attr "length" "3")])
6130
6131 (define_insn_and_split "one_cmplsi2"
6132 [(set (match_operand:SI 0 "register_operand" "=r")
6133 (not:SI (match_operand:SI 1 "register_operand" "0")))]
6134 ""
6135 "#"
6136 "&& reload_completed"
6137 [(parallel [(set (match_dup 0)
6138 (not:SI (match_dup 1)))
6139 (clobber (reg:CC REG_CC))])])
6140
6141 (define_insn "*one_cmplsi2"
6142 [(set (match_operand:SI 0 "register_operand" "=r")
6143 (not:SI (match_operand:SI 1 "register_operand" "0")))
6144 (clobber (reg:CC REG_CC))]
6145 "reload_completed"
6146 "com %0
6147 com %B0
6148 com %C0
6149 com %D0"
6150 [(set_attr "length" "4")])
6151
6152 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
6153 ;; sign extend
6154
6155 ;; We keep combiner from inserting hard registers into the input of sign- and
6156 ;; zero-extends. A hard register in the input operand is not wanted because
6157 ;; 32-bit multiply patterns clobber some hard registers and extends with a
6158 ;; hard register that overlaps these clobbers won't be combined to a widening
6159 ;; multiplication. There is no need for combine to propagate hard registers,
6160 ;; register allocation can do it just as well.
6161
6162 (define_insn_and_split "extendqihi2"
6163 [(set (match_operand:HI 0 "register_operand" "=r,r")
6164 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
6165 ""
6166 "#"
6167 "&& reload_completed"
6168 [(parallel [(set (match_dup 0)
6169 (sign_extend:HI (match_dup 1)))
6170 (clobber (reg:CC REG_CC))])])
6171
6172 (define_insn "*extendqihi2"
6173 [(set (match_operand:HI 0 "register_operand" "=r,r")
6174 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))
6175 (clobber (reg:CC REG_CC))]
6176 "reload_completed"
6177 {
6178 return avr_out_sign_extend (insn, operands, NULL);
6179 }
6180 [(set_attr "length" "3,4")
6181 (set_attr "adjust_len" "sext")])
6182
6183 (define_insn_and_split "extendqipsi2"
6184 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6185 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
6186 ""
6187 "#"
6188 "&& reload_completed"
6189 [(parallel [(set (match_dup 0)
6190 (sign_extend:PSI (match_dup 1)))
6191 (clobber (reg:CC REG_CC))])])
6192
6193 (define_insn "*extendqipsi2"
6194 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6195 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))
6196 (clobber (reg:CC REG_CC))]
6197 "reload_completed"
6198 {
6199 return avr_out_sign_extend (insn, operands, NULL);
6200 }
6201 [(set_attr "length" "4,5")
6202 (set_attr "adjust_len" "sext")])
6203
6204 (define_insn_and_split "extendqisi2"
6205 [(set (match_operand:SI 0 "register_operand" "=r,r")
6206 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
6207 ""
6208 "#"
6209 "&& reload_completed"
6210 [(parallel [(set (match_dup 0)
6211 (sign_extend:SI (match_dup 1)))
6212 (clobber (reg:CC REG_CC))])])
6213
6214 (define_insn "*extendqisi2"
6215 [(set (match_operand:SI 0 "register_operand" "=r,r")
6216 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))
6217 (clobber (reg:CC REG_CC))]
6218 "reload_completed"
6219 {
6220 return avr_out_sign_extend (insn, operands, NULL);
6221 }
6222 [(set_attr "length" "5,6")
6223 (set_attr "adjust_len" "sext")])
6224
6225 (define_insn_and_split "extendhipsi2"
6226 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6227 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
6228 ""
6229 "#"
6230 "&& reload_completed"
6231 [(parallel [(set (match_dup 0)
6232 (sign_extend:PSI (match_dup 1)))
6233 (clobber (reg:CC REG_CC))])])
6234
6235 (define_insn "*extendhipsi2"
6236 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6237 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))
6238 (clobber (reg:CC REG_CC))]
6239 "reload_completed"
6240 {
6241 return avr_out_sign_extend (insn, operands, NULL);
6242 }
6243 [(set_attr "length" "3,5")
6244 (set_attr "adjust_len" "sext")])
6245
6246 (define_insn_and_split "extendhisi2"
6247 [(set (match_operand:SI 0 "register_operand" "=r,r")
6248 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
6249 ""
6250 "#"
6251 "&& reload_completed"
6252 [(parallel [(set (match_dup 0)
6253 (sign_extend:SI (match_dup 1)))
6254 (clobber (reg:CC REG_CC))])])
6255
6256 (define_insn "*extendhisi2"
6257 [(set (match_operand:SI 0 "register_operand" "=r,r")
6258 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))
6259 (clobber (reg:CC REG_CC))]
6260 "reload_completed"
6261 {
6262 return avr_out_sign_extend (insn, operands, NULL);
6263 }
6264 [(set_attr "length" "4,6")
6265 (set_attr "adjust_len" "sext")])
6266
6267 (define_insn_and_split "extendpsisi2"
6268 [(set (match_operand:SI 0 "register_operand" "=r")
6269 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
6270 ""
6271 "#"
6272 "&& reload_completed"
6273 [(parallel [(set (match_dup 0)
6274 (sign_extend:SI (match_dup 1)))
6275 (clobber (reg:CC REG_CC))])])
6276
6277 (define_insn "*extendpsisi2"
6278 [(set (match_operand:SI 0 "register_operand" "=r")
6279 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))
6280 (clobber (reg:CC REG_CC))]
6281 "reload_completed"
6282 {
6283 return avr_out_sign_extend (insn, operands, NULL);
6284 }
6285 [(set_attr "length" "3")
6286 (set_attr "adjust_len" "sext")])
6287
6288 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
6289 ;; zero extend
6290
6291 (define_insn_and_split "zero_extendqihi2"
6292 [(set (match_operand:HI 0 "register_operand" "=r")
6293 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
6294 ""
6295 "#"
6296 "reload_completed"
6297 [(set (match_dup 2) (match_dup 1))
6298 (set (match_dup 3) (const_int 0))]
6299 {
6300 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
6301 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
6302
6303 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
6304 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
6305 })
6306
6307 (define_insn_and_split "zero_extendqipsi2"
6308 [(set (match_operand:PSI 0 "register_operand" "=r")
6309 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
6310 ""
6311 "#"
6312 "reload_completed"
6313 [(set (match_dup 2) (match_dup 1))
6314 (set (match_dup 3) (const_int 0))
6315 (set (match_dup 4) (const_int 0))]
6316 {
6317 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
6318 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
6319 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
6320 })
6321
6322 (define_insn_and_split "zero_extendqisi2"
6323 [(set (match_operand:SI 0 "register_operand" "=r")
6324 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
6325 ""
6326 "#"
6327 "reload_completed"
6328 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
6329 (set (match_dup 3) (const_int 0))]
6330 {
6331 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
6332 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
6333
6334 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
6335 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
6336 })
6337
6338 (define_insn_and_split "zero_extendhipsi2"
6339 [(set (match_operand:PSI 0 "register_operand" "=r")
6340 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
6341 ""
6342 "#"
6343 "reload_completed"
6344 [(set (match_dup 2) (match_dup 1))
6345 (set (match_dup 3) (const_int 0))]
6346 {
6347 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
6348 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
6349 })
6350
6351 (define_insn_and_split "n_extendhipsi2"
6352 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
6353 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
6354 (match_operand:HI 2 "register_operand" "r,r,r,r")))
6355 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
6356 ""
6357 "#"
6358 "reload_completed"
6359 [(set (match_dup 4) (match_dup 2))
6360 (set (match_dup 3) (match_dup 6))
6361 ; no-op move in the case where no scratch is needed
6362 (set (match_dup 5) (match_dup 3))]
6363 {
6364 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
6365 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
6366 operands[6] = operands[1];
6367
6368 if (GET_CODE (operands[3]) == SCRATCH)
6369 operands[3] = operands[5];
6370 })
6371
6372 (define_insn_and_split "zero_extendhisi2"
6373 [(set (match_operand:SI 0 "register_operand" "=r")
6374 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
6375 ""
6376 "#"
6377 "reload_completed"
6378 [(set (match_dup 2) (match_dup 1))
6379 (set (match_dup 3) (const_int 0))]
6380 {
6381 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
6382 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
6383
6384 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
6385 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
6386 })
6387
6388 (define_insn_and_split "zero_extendpsisi2"
6389 [(set (match_operand:SI 0 "register_operand" "=r")
6390 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
6391 ""
6392 "#"
6393 "reload_completed"
6394 [(set (match_dup 2) (match_dup 1))
6395 (set (match_dup 3) (const_int 0))]
6396 {
6397 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
6398 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
6399 })
6400
6401 (define_insn_and_split "zero_extendqidi2"
6402 [(set (match_operand:DI 0 "register_operand" "=r")
6403 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
6404 ""
6405 "#"
6406 "reload_completed"
6407 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
6408 (set (match_dup 3) (const_int 0))]
6409 {
6410 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
6411 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
6412
6413 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
6414 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
6415 })
6416
6417 (define_insn_and_split "zero_extendhidi2"
6418 [(set (match_operand:DI 0 "register_operand" "=r")
6419 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
6420 ""
6421 "#"
6422 "reload_completed"
6423 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
6424 (set (match_dup 3) (const_int 0))]
6425 {
6426 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
6427 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
6428
6429 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
6430 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
6431 })
6432
6433 (define_insn_and_split "zero_extendsidi2"
6434 [(set (match_operand:DI 0 "register_operand" "=r")
6435 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
6436 ""
6437 "#"
6438 "reload_completed"
6439 [(set (match_dup 2) (match_dup 1))
6440 (set (match_dup 3) (const_int 0))]
6441 {
6442 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
6443 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
6444
6445 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
6446 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
6447 })
6448
6449 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
6450 ;; compare
6451
6452 ; Optimize negated tests into reverse compare if overflow is undefined.
6453 (define_insn "*negated_tstqi"
6454 [(set (reg:CC REG_CC)
6455 (compare:CC (neg:QI (match_operand:QI 0 "register_operand" "r"))
6456 (const_int 0)))]
6457 "reload_completed && !flag_wrapv && !flag_trapv"
6458 "cp __zero_reg__,%0"
6459 [(set_attr "length" "1")])
6460
6461 (define_insn "*reversed_tstqi"
6462 [(set (reg:CC REG_CC)
6463 (compare:CC (const_int 0)
6464 (match_operand:QI 0 "register_operand" "r")))]
6465 "reload_completed"
6466 "cp __zero_reg__,%0"
6467 [(set_attr "length" "2")])
6468
6469 (define_insn "*negated_tsthi"
6470 [(set (reg:CC REG_CC)
6471 (compare:CC (neg:HI (match_operand:HI 0 "register_operand" "r"))
6472 (const_int 0)))]
6473 "reload_completed && !flag_wrapv && !flag_trapv"
6474 "cp __zero_reg__,%A0
6475 cpc __zero_reg__,%B0"
6476 [(set_attr "length" "2")])
6477
6478 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
6479 ;; though it is unused, because this pattern is synthesized by avr_reorg.
6480 (define_insn "*reversed_tsthi"
6481 [(set (reg:CC REG_CC)
6482 (compare:CC (const_int 0)
6483 (match_operand:HI 0 "register_operand" "r")))
6484 (clobber (match_scratch:QI 1 "=X"))]
6485 "reload_completed"
6486 "cp __zero_reg__,%A0
6487 cpc __zero_reg__,%B0"
6488 [(set_attr "length" "2")])
6489
6490 (define_insn "*negated_tstpsi"
6491 [(set (reg:CC REG_CC)
6492 (compare:CC (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
6493 (const_int 0)))]
6494 "reload_completed && !flag_wrapv && !flag_trapv"
6495 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
6496 [(set_attr "length" "3")])
6497
6498 (define_insn "*reversed_tstpsi"
6499 [(set (reg:CC REG_CC)
6500 (compare:CC (const_int 0)
6501 (match_operand:PSI 0 "register_operand" "r")))
6502 (clobber (match_scratch:QI 1 "=X"))]
6503 "reload_completed"
6504 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
6505 [(set_attr "length" "3")])
6506
6507 (define_insn "*negated_tstsi"
6508 [(set (reg:CC REG_CC)
6509 (compare:CC (neg:SI (match_operand:SI 0 "register_operand" "r"))
6510 (const_int 0)))]
6511 "reload_completed && !flag_wrapv && !flag_trapv"
6512 "cp __zero_reg__,%A0
6513 cpc __zero_reg__,%B0
6514 cpc __zero_reg__,%C0
6515 cpc __zero_reg__,%D0"
6516 [(set_attr "length" "4")])
6517
6518 ;; "*reversed_tstsi"
6519 ;; "*reversed_tstsq" "*reversed_tstusq"
6520 ;; "*reversed_tstsa" "*reversed_tstusa"
6521 (define_insn "*reversed_tst<mode>"
6522 [(set (reg:CC REG_CC)
6523 (compare:CC (match_operand:ALL4 0 "const0_operand" "Y00")
6524 (match_operand:ALL4 1 "register_operand" "r")))
6525 (clobber (match_scratch:QI 2 "=X"))]
6526 "reload_completed"
6527 "cp __zero_reg__,%A1
6528 cpc __zero_reg__,%B1
6529 cpc __zero_reg__,%C1
6530 cpc __zero_reg__,%D1"
6531 [(set_attr "length" "4")])
6532
6533
6534 ;; "cmpqi3"
6535 ;; "cmpqq3" "cmpuqq3"
6536 (define_insn "cmp<mode>3"
6537 [(set (reg:CC REG_CC)
6538 (compare:CC (match_operand:ALL1 0 "register_operand" "r ,r,d")
6539 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
6540 "reload_completed"
6541 "@
6542 tst %0
6543 cp %0,%1
6544 cpi %0,lo8(%1)"
6545 [(set_attr "length" "1,1,1")])
6546
6547 (define_insn "*cmpqi_sign_extend"
6548 [(set (reg:CC REG_CC)
6549 (compare:CC (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
6550 (match_operand:HI 1 "s8_operand" "n")))]
6551 "reload_completed"
6552 "cpi %0,lo8(%1)"
6553 [(set_attr "length" "1")])
6554
6555
6556 (define_insn "*cmphi.zero-extend.0"
6557 [(set (reg:CC REG_CC)
6558 (compare:CC (zero_extend:HI (match_operand:QI 0 "register_operand" "r"))
6559 (match_operand:HI 1 "register_operand" "r")))]
6560 "reload_completed"
6561 "cp %0,%A1\;cpc __zero_reg__,%B1"
6562 [(set_attr "length" "2")])
6563
6564 (define_insn "*cmphi.zero-extend.1"
6565 [(set (reg:CC REG_CC)
6566 (compare:CC (match_operand:HI 0 "register_operand" "r")
6567 (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))))]
6568 "reload_completed"
6569 "cp %A0,%1\;cpc %B0,__zero_reg__"
6570 [(set_attr "length" "2")])
6571
6572 ;; "cmphi3"
6573 ;; "cmphq3" "cmpuhq3"
6574 ;; "cmpha3" "cmpuha3"
6575 (define_insn "cmp<mode>3"
6576 [(set (reg:CC REG_CC)
6577 (compare:CC (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
6578 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
6579 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
6580 "reload_completed"
6581 {
6582 switch (which_alternative)
6583 {
6584 case 0:
6585 case 1:
6586 return avr_out_tsthi (insn, operands, NULL);
6587
6588 case 2:
6589 return "cp %A0,%A1\;cpc %B0,%B1";
6590
6591 case 3:
6592 if (<MODE>mode != HImode)
6593 break;
6594 return reg_unused_after (insn, operands[0])
6595 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
6596 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
6597
6598 case 4:
6599 if (<MODE>mode != HImode)
6600 break;
6601 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
6602 }
6603
6604 return avr_out_compare (insn, operands, NULL);
6605 }
6606 [(set_attr "length" "1,2,2,3,4,2,4")
6607 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
6608
6609 (define_insn "*cmppsi"
6610 [(set (reg:CC REG_CC)
6611 (compare:CC (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
6612 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
6613 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
6614 "reload_completed"
6615 {
6616 switch (which_alternative)
6617 {
6618 case 0:
6619 return avr_out_tstpsi (insn, operands, NULL);
6620
6621 case 1:
6622 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
6623
6624 case 2:
6625 return reg_unused_after (insn, operands[0])
6626 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
6627 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
6628
6629 case 3:
6630 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
6631 }
6632
6633 return avr_out_compare (insn, operands, NULL);
6634 }
6635 [(set_attr "length" "3,3,5,6,3,7")
6636 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
6637
6638 ;; "*cmpsi"
6639 ;; "*cmpsq" "*cmpusq"
6640 ;; "*cmpsa" "*cmpusa"
6641 (define_insn "*cmp<mode>"
6642 [(set (reg:CC REG_CC)
6643 (compare:CC (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
6644 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
6645 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
6646 "reload_completed"
6647 {
6648 if (0 == which_alternative)
6649 return avr_out_tstsi (insn, operands, NULL);
6650 else if (1 == which_alternative)
6651 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
6652
6653 return avr_out_compare (insn, operands, NULL);
6654 }
6655 [(set_attr "length" "4,4,4,5,8")
6656 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
6657
6658
6659 ;; ----------------------------------------------------------------------
6660 ;; JUMP INSTRUCTIONS
6661 ;; ----------------------------------------------------------------------
6662 ;; Conditional jump instructions
6663
6664 (define_expand "cbranch<mode>4"
6665 [(set (pc)
6666 (if_then_else (match_operator 0 "ordered_comparison_operator"
6667 [(match_operand:ALL1 1 "register_operand" "")
6668 (match_operand:ALL1 2 "nonmemory_operand" "")])
6669 (label_ref (match_operand 3 "" ""))
6670 (pc)))])
6671
6672 (define_expand "cbranch<mode>4"
6673 [(parallel
6674 [(set (pc)
6675 (if_then_else
6676 (match_operator 0 "ordered_comparison_operator"
6677 [(match_operand:ORDERED234 1 "register_operand" "")
6678 (match_operand:ORDERED234 2 "nonmemory_operand" "")])
6679 (label_ref (match_operand 3 "" ""))
6680 (pc)))
6681 (clobber (match_scratch:QI 4 ""))])])
6682
6683 ;; "*cbranchqi4"
6684 ;; "*cbranchqq4" "*cbranchuqq4"
6685 (define_insn_and_split "*cbranch<mode>4"
6686 [(set (pc)
6687 (if_then_else (match_operator 0 "ordered_comparison_operator"
6688 [(match_operand:ALL1 1 "register_operand" "r ,r,d")
6689 (match_operand:ALL1 2 "nonmemory_operand" "Y00,r,i")])
6690 (label_ref (match_operand 3 "" ""))
6691 (pc)))]
6692 ""
6693 "#"
6694 "reload_completed"
6695 [(set (reg:CC REG_CC)
6696 (compare:CC (match_dup 1) (match_dup 2)))
6697 (set (pc)
6698 (if_then_else (match_op_dup 0
6699 [(reg:CC REG_CC) (const_int 0)])
6700 (label_ref (match_dup 3))
6701 (pc)))]
6702 "")
6703
6704 ;; "*cbranchsi4" "*cbranchsq4" "*cbranchusq4" "*cbranchsa4" "*cbranchusa4"
6705 (define_insn_and_split "*cbranch<mode>4"
6706 [(set (pc)
6707 (if_then_else
6708 (match_operator 0 "ordered_comparison_operator"
6709 [(match_operand:ALL4 1 "register_operand" "r ,r ,d,r ,r")
6710 (match_operand:ALL4 2 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")])
6711 (label_ref (match_operand 3 "" ""))
6712 (pc)))
6713 (clobber (match_scratch:QI 4 "=X ,X ,X,&d,&d"))]
6714 ""
6715 "#"
6716 "reload_completed"
6717 [(parallel [(set (reg:CC REG_CC)
6718 (compare:CC (match_dup 1) (match_dup 2)))
6719 (clobber (match_dup 4))])
6720 (set (pc)
6721 (if_then_else (match_op_dup 0
6722 [(reg:CC REG_CC) (const_int 0)])
6723 (label_ref (match_dup 3))
6724 (pc)))]
6725 "")
6726
6727 ;; "*cbranchpsi4"
6728 (define_insn_and_split "*cbranchpsi4"
6729 [(set (pc)
6730 (if_then_else
6731 (match_operator 0 "ordered_comparison_operator"
6732 [(match_operand:PSI 1 "register_operand" "r,r,d ,r ,d,r")
6733 (match_operand:PSI 2 "nonmemory_operand" "L,r,s ,s ,M,n")])
6734 (label_ref (match_operand 3 "" ""))
6735 (pc)))
6736 (clobber (match_scratch:QI 4 "=X,X,&d,&d ,X,&d"))]
6737 ""
6738 "#"
6739 "reload_completed"
6740 [(parallel [(set (reg:CC REG_CC)
6741 (compare:CC (match_dup 1) (match_dup 2)))
6742 (clobber (match_dup 4))])
6743 (set (pc)
6744 (if_then_else (match_op_dup 0
6745 [(reg:CC REG_CC) (const_int 0)])
6746 (label_ref (match_dup 3))
6747 (pc)))]
6748 "")
6749
6750 ;; "*cbranchhi4" "*cbranchhq4" "*cbranchuhq4" "*cbranchha4" "*cbranchuha4"
6751 (define_insn_and_split "*cbranch<mode>4"
6752 [(set (pc)
6753 (if_then_else
6754 (match_operator 0 "ordered_comparison_operator"
6755 [(match_operand:ALL2 1 "register_operand" "!w ,r ,r,d ,r ,d,r")
6756 (match_operand:ALL2 2 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")])
6757 (label_ref (match_operand 3 "" ""))
6758 (pc)))
6759 (clobber (match_scratch:QI 4 "=X ,X ,X,&d,&d ,X,&d"))]
6760 ""
6761 "#"
6762 "reload_completed"
6763 [(parallel [(set (reg:CC REG_CC)
6764 (compare:CC (match_dup 1) (match_dup 2)))
6765 (clobber (match_dup 4))])
6766 (set (pc)
6767 (if_then_else (match_op_dup 0
6768 [(reg:CC REG_CC) (const_int 0)])
6769 (label_ref (match_dup 3))
6770 (pc)))]
6771 "")
6772
6773 ;; Test a single bit in a QI/HI/SImode register.
6774 ;; Combine will create zero extract patterns for single bit tests.
6775 ;; permit any mode in source pattern by using VOIDmode.
6776
6777 (define_insn_and_split "*sbrx_branch<mode>_split"
6778 [(set (pc)
6779 (if_then_else
6780 (match_operator 0 "eqne_operator"
6781 [(zero_extract:QIDI
6782 (match_operand:VOID 1 "register_operand" "r")
6783 (const_int 1)
6784 (match_operand 2 "const_int_operand" "n"))
6785 (const_int 0)])
6786 (label_ref (match_operand 3 "" ""))
6787 (pc)))]
6788 ""
6789 "#"
6790 "&& reload_completed"
6791 [(parallel [(set (pc)
6792 (if_then_else
6793 (match_op_dup 0
6794 [(zero_extract:QIDI
6795 (match_dup 1)
6796 (const_int 1)
6797 (match_dup 2))
6798 (const_int 0)])
6799 (label_ref (match_dup 3))
6800 (pc)))
6801 (clobber (reg:CC REG_CC))])])
6802
6803 (define_insn "*sbrx_branch<mode>"
6804 [(set (pc)
6805 (if_then_else
6806 (match_operator 0 "eqne_operator"
6807 [(zero_extract:QIDI
6808 (match_operand:VOID 1 "register_operand" "r")
6809 (const_int 1)
6810 (match_operand 2 "const_int_operand" "n"))
6811 (const_int 0)])
6812 (label_ref (match_operand 3 "" ""))
6813 (pc)))
6814 (clobber (reg:CC REG_CC))]
6815 "reload_completed"
6816 {
6817 return avr_out_sbxx_branch (insn, operands);
6818 }
6819 [(set (attr "length")
6820 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
6821 (le (minus (pc) (match_dup 3)) (const_int 2046)))
6822 (const_int 2)
6823 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
6824 (const_int 2)
6825 (const_int 4))))])
6826
6827 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
6828 ;; or for old peepholes.
6829 ;; Fixme - bitwise Mask will not work for DImode
6830
6831 (define_insn_and_split "*sbrx_and_branch<mode>_split"
6832 [(set (pc)
6833 (if_then_else
6834 (match_operator 0 "eqne_operator"
6835 [(and:QISI
6836 (match_operand:QISI 1 "register_operand" "r")
6837 (match_operand:QISI 2 "single_one_operand" "n"))
6838 (const_int 0)])
6839 (label_ref (match_operand 3 "" ""))
6840 (pc)))]
6841 ""
6842 "#"
6843 "&& reload_completed"
6844 [(parallel [(set (pc)
6845 (if_then_else
6846 (match_op_dup 0
6847 [(and:QISI
6848 (match_dup 1)
6849 (match_dup 2))
6850 (const_int 0)])
6851 (label_ref (match_dup 3))
6852 (pc)))
6853 (clobber (reg:CC REG_CC))])])
6854
6855 (define_insn "*sbrx_and_branch<mode>"
6856 [(set (pc)
6857 (if_then_else
6858 (match_operator 0 "eqne_operator"
6859 [(and:QISI
6860 (match_operand:QISI 1 "register_operand" "r")
6861 (match_operand:QISI 2 "single_one_operand" "n"))
6862 (const_int 0)])
6863 (label_ref (match_operand 3 "" ""))
6864 (pc)))
6865 (clobber (reg:CC REG_CC))]
6866 "reload_completed"
6867 {
6868 HOST_WIDE_INT bitnumber;
6869 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
6870 operands[2] = GEN_INT (bitnumber);
6871 return avr_out_sbxx_branch (insn, operands);
6872 }
6873 [(set (attr "length")
6874 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
6875 (le (minus (pc) (match_dup 3)) (const_int 2046)))
6876 (const_int 2)
6877 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
6878 (const_int 2)
6879 (const_int 4))))])
6880
6881 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
6882 (define_peephole2
6883 [(set (reg:CC REG_CC) (compare:CC (match_operand:QI 0 "register_operand" "")
6884 (const_int 0)))
6885 (parallel [(set (pc) (if_then_else (ge (reg:CC REG_CC) (const_int 0))
6886 (label_ref (match_operand 1 "" ""))
6887 (pc)))
6888 (clobber (reg:CC REG_CC))])]
6889 ""
6890 [(parallel [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
6891 (const_int 1)
6892 (const_int 7))
6893 (const_int 0))
6894 (label_ref (match_dup 1))
6895 (pc)))
6896 (clobber (reg:CC REG_CC))])])
6897
6898 (define_peephole2
6899 [(set (reg:CC REG_CC) (compare:CC (match_operand:QI 0 "register_operand" "")
6900 (const_int 0)))
6901 (parallel [(set (pc) (if_then_else (lt (reg:CC REG_CC) (const_int 0))
6902 (label_ref (match_operand 1 "" ""))
6903 (pc)))
6904 (clobber (reg:CC REG_CC))])]
6905 ""
6906 [(parallel [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
6907 (const_int 1)
6908 (const_int 7))
6909 (const_int 0))
6910 (label_ref (match_dup 1))
6911 (pc)))
6912 (clobber (reg:CC REG_CC))])])
6913
6914 (define_peephole2
6915 [(parallel [(set (reg:CC REG_CC) (compare:CC (match_operand:HI 0 "register_operand" "")
6916 (const_int 0)))
6917 (clobber (match_operand:HI 2 ""))])
6918 (parallel [(set (pc) (if_then_else (ge (reg:CC REG_CC) (const_int 0))
6919 (label_ref (match_operand 1 "" ""))
6920 (pc)))
6921 (clobber (reg:CC REG_CC))])]
6922 ""
6923 [(parallel [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
6924 (const_int 0))
6925 (label_ref (match_dup 1))
6926 (pc)))
6927 (clobber (reg:CC REG_CC))])])
6928
6929 (define_peephole2
6930 [(parallel [(set (reg:CC REG_CC) (compare:CC (match_operand:HI 0 "register_operand" "")
6931 (const_int 0)))
6932 (clobber (match_operand:HI 2 ""))])
6933 (parallel [(set (pc) (if_then_else (lt (reg:CC REG_CC) (const_int 0))
6934 (label_ref (match_operand 1 "" ""))
6935 (pc)))
6936 (clobber (reg:CC REG_CC))])]
6937 ""
6938 [(parallel [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
6939 (const_int 0))
6940 (label_ref (match_dup 1))
6941 (pc)))
6942 (clobber (reg:CC REG_CC))])])
6943
6944 (define_peephole2
6945 [(parallel [(set (reg:CC REG_CC) (compare:CC (match_operand:SI 0 "register_operand" "")
6946 (const_int 0)))
6947 (clobber (match_operand:SI 2 ""))])
6948 (parallel [(set (pc) (if_then_else (ge (reg:CC REG_CC) (const_int 0))
6949 (label_ref (match_operand 1 "" ""))
6950 (pc)))
6951 (clobber (reg:CC REG_CC))])]
6952 ""
6953 [(parallel [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
6954 (const_int 0))
6955 (label_ref (match_dup 1))
6956 (pc)))
6957 (clobber (reg:CC REG_CC))])]
6958 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
6959
6960 (define_peephole2
6961 [(parallel [(set (reg:CC REG_CC) (compare:CC (match_operand:SI 0 "register_operand" "")
6962 (const_int 0)))
6963 (clobber (match_operand:SI 2 ""))])
6964 (parallel [(set (pc) (if_then_else (lt (reg:CC REG_CC) (const_int 0))
6965 (label_ref (match_operand 1 "" ""))
6966 (pc)))
6967 (clobber (reg:CC REG_CC))])]
6968 ""
6969 [(parallel [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
6970 (const_int 0))
6971 (label_ref (match_dup 1))
6972 (pc)))
6973 (clobber (reg:CC REG_CC))])]
6974 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
6975
6976 ;; ************************************************************************
6977 ;; Implementation of conditional jumps here.
6978 ;; Compare with 0 (test) jumps
6979 ;; ************************************************************************
6980
6981 (define_insn_and_split "branch"
6982 [(set (pc)
6983 (if_then_else (match_operator 1 "simple_comparison_operator"
6984 [(reg:CC REG_CC)
6985 (const_int 0)])
6986 (label_ref (match_operand 0 "" ""))
6987 (pc)))]
6988 "reload_completed"
6989 "#"
6990 "&& reload_completed"
6991 [(parallel [(set (pc)
6992 (if_then_else (match_op_dup 1
6993 [(reg:CC REG_CC)
6994 (const_int 0)])
6995 (label_ref (match_dup 0))
6996 (pc)))
6997 (clobber (reg:CC REG_CC))])])
6998
6999 (define_insn "*branch"
7000 [(set (pc)
7001 (if_then_else (match_operator 1 "simple_comparison_operator"
7002 [(reg:CC REG_CC)
7003 (const_int 0)])
7004 (label_ref (match_operand 0 "" ""))
7005 (pc)))
7006 (clobber (reg:CC REG_CC))]
7007 "reload_completed"
7008 {
7009 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
7010 }
7011 [(set_attr "type" "branch")])
7012
7013
7014 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
7015 ;; or optimized in the remainder.
7016
7017 (define_insn "branch_unspec"
7018 [(set (pc)
7019 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
7020 [(reg:CC REG_CC)
7021 (const_int 0)])
7022 (label_ref (match_operand 0 "" ""))
7023 (pc))
7024 ] UNSPEC_IDENTITY))
7025 (clobber (reg:CC REG_CC))]
7026 "reload_completed"
7027 {
7028 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
7029 }
7030 [(set_attr "type" "branch")])
7031
7032 ;; ****************************************************************
7033 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
7034 ;; Convert them all to proper jumps.
7035 ;; ****************************************************************/
7036
7037 (define_insn_and_split "difficult_branch"
7038 [(set (pc)
7039 (if_then_else (match_operator 1 "difficult_comparison_operator"
7040 [(reg:CC REG_CC)
7041 (const_int 0)])
7042 (label_ref (match_operand 0 "" ""))
7043 (pc)))]
7044 "reload_completed"
7045 "#"
7046 "&& reload_completed"
7047 [(parallel [(set (pc)
7048 (if_then_else (match_op_dup 1
7049 [(reg:CC REG_CC)
7050 (const_int 0)])
7051 (label_ref (match_dup 0))
7052 (pc)))
7053 (clobber (reg:CC REG_CC))])])
7054
7055 (define_insn "*difficult_branch"
7056 [(set (pc)
7057 (if_then_else (match_operator 1 "difficult_comparison_operator"
7058 [(reg:CC REG_CC)
7059 (const_int 0)])
7060 (label_ref (match_operand 0 "" ""))
7061 (pc)))
7062 (clobber (reg:CC REG_CC))]
7063 "reload_completed"
7064 {
7065 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
7066 }
7067 [(set_attr "type" "branch1")])
7068
7069 ;; revers branch
7070
7071 (define_insn_and_split "rvbranch"
7072 [(set (pc)
7073 (if_then_else (match_operator 1 "simple_comparison_operator"
7074 [(reg:CC REG_CC)
7075 (const_int 0)])
7076 (pc)
7077 (label_ref (match_operand 0 "" ""))))]
7078 "reload_completed"
7079 "#"
7080 "&& reload_completed"
7081 [(parallel [(set (pc)
7082 (if_then_else (match_op_dup 1
7083 [(reg:CC REG_CC)
7084 (const_int 0)])
7085 (pc)
7086 (label_ref (match_dup 0))))
7087 (clobber (reg:CC REG_CC))])])
7088
7089 (define_insn "*rvbranch"
7090 [(set (pc)
7091 (if_then_else (match_operator 1 "simple_comparison_operator"
7092 [(reg:CC REG_CC)
7093 (const_int 0)])
7094 (pc)
7095 (label_ref (match_operand 0 "" ""))))
7096 (clobber (reg:CC REG_CC))]
7097 "reload_completed"
7098 {
7099 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
7100 }
7101 [(set_attr "type" "branch1")])
7102
7103 (define_insn_and_split "difficult_rvbranch"
7104 [(set (pc)
7105 (if_then_else (match_operator 1 "difficult_comparison_operator"
7106 [(reg:CC REG_CC)
7107 (const_int 0)])
7108 (pc)
7109 (label_ref (match_operand 0 "" ""))))]
7110 "reload_completed"
7111 "#"
7112 "&& reload_completed"
7113 [(parallel [(set (pc)
7114 (if_then_else (match_op_dup 1
7115 [(reg:CC REG_CC)
7116 (const_int 0)])
7117 (pc)
7118 (label_ref (match_dup 0))))
7119 (clobber (reg:CC REG_CC))])])
7120
7121 (define_insn "*difficult_rvbranch"
7122 [(set (pc)
7123 (if_then_else (match_operator 1 "difficult_comparison_operator"
7124 [(reg:CC REG_CC)
7125 (const_int 0)])
7126 (pc)
7127 (label_ref (match_operand 0 "" ""))))
7128 (clobber (reg:CC REG_CC))]
7129 "reload_completed"
7130 {
7131 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
7132 }
7133 [(set_attr "type" "branch")])
7134
7135 ;; **************************************************************************
7136 ;; Unconditional and other jump instructions.
7137
7138 (define_insn "jump"
7139 [(set (pc)
7140 (label_ref (match_operand 0 "" "")))]
7141 ""
7142 {
7143 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
7144 ? "jmp %x0"
7145 : "rjmp %x0";
7146 }
7147 [(set (attr "length")
7148 (if_then_else (match_operand 0 "symbol_ref_operand" "")
7149 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7150 (const_int 1)
7151 (const_int 2))
7152 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
7153 (le (minus (pc) (match_dup 0)) (const_int 2047)))
7154 (const_int 1)
7155 (const_int 2))))])
7156
7157 ;; call
7158
7159 ;; Operand 1 not used on the AVR.
7160 ;; Operand 2 is 1 for tail-call, 0 otherwise.
7161 (define_expand "call"
7162 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
7163 (match_operand:HI 1 "general_operand" ""))
7164 (use (const_int 0))])])
7165
7166 ;; Operand 1 not used on the AVR.
7167 ;; Operand 2 is 1 for tail-call, 0 otherwise.
7168 (define_expand "sibcall"
7169 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
7170 (match_operand:HI 1 "general_operand" ""))
7171 (use (const_int 1))])])
7172
7173 ;; call value
7174
7175 ;; Operand 2 not used on the AVR.
7176 ;; Operand 3 is 1 for tail-call, 0 otherwise.
7177 (define_expand "call_value"
7178 [(parallel[(set (match_operand 0 "register_operand" "")
7179 (call (match_operand:HI 1 "call_insn_operand" "")
7180 (match_operand:HI 2 "general_operand" "")))
7181 (use (const_int 0))])])
7182
7183 ;; Operand 2 not used on the AVR.
7184 ;; Operand 3 is 1 for tail-call, 0 otherwise.
7185 (define_expand "sibcall_value"
7186 [(parallel[(set (match_operand 0 "register_operand" "")
7187 (call (match_operand:HI 1 "call_insn_operand" "")
7188 (match_operand:HI 2 "general_operand" "")))
7189 (use (const_int 1))])])
7190
7191 (define_insn "call_insn"
7192 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
7193 (match_operand:HI 1 "general_operand" "X,X,X,X"))
7194 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
7195 ;; Operand 1 not used on the AVR.
7196 ;; Operand 2 is 1 for tail-call, 0 otherwise.
7197 ""
7198 "@
7199 %!icall
7200 %~call %x0
7201 %!ijmp
7202 %~jmp %x0"
7203 [(set_attr "length" "1,*,1,*")
7204 (set_attr "adjust_len" "*,call,*,call")])
7205
7206 (define_insn "call_value_insn"
7207 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
7208 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
7209 (match_operand:HI 2 "general_operand" "X,X,X,X")))
7210 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
7211 ;; Operand 2 not used on the AVR.
7212 ;; Operand 3 is 1 for tail-call, 0 otherwise.
7213 ""
7214 "@
7215 %!icall
7216 %~call %x1
7217 %!ijmp
7218 %~jmp %x1"
7219 [(set_attr "length" "1,*,1,*")
7220 (set_attr "adjust_len" "*,call,*,call")])
7221
7222 (define_insn "nop"
7223 [(const_int 0)]
7224 ""
7225 "nop"
7226 [(set_attr "length" "1")])
7227
7228 ; indirect jump
7229
7230 (define_expand "indirect_jump"
7231 [(set (pc)
7232 (match_operand:HI 0 "nonmemory_operand" ""))]
7233 ""
7234 {
7235 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
7236 {
7237 operands[0] = copy_to_mode_reg (HImode, operands[0]);
7238 }
7239 })
7240
7241 ; indirect jump
7242 (define_insn "*indirect_jump"
7243 [(set (pc)
7244 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
7245 ""
7246 "@
7247 rjmp %x0
7248 jmp %x0
7249 ijmp
7250 push %A0\;push %B0\;ret
7251 eijmp"
7252 [(set_attr "length" "1,2,1,3,1")
7253 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")])
7254
7255 ;; table jump
7256 ;; For entries in jump table see avr_output_addr_vec.
7257
7258 ;; Table made from
7259 ;; "rjmp .L<n>" instructions for <= 8K devices
7260 ;; ".word gs(.L<n>)" addresses for > 8K devices
7261 (define_insn_and_split "*tablejump_split"
7262 [(set (pc)
7263 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
7264 UNSPEC_INDEX_JMP))
7265 (use (label_ref (match_operand 1 "" "")))
7266 (clobber (match_dup 0))
7267 (clobber (const_int 0))]
7268 "!AVR_HAVE_EIJMP_EICALL"
7269 "#"
7270 "&& reload_completed"
7271 [(parallel [(set (pc)
7272 (unspec:HI [(match_dup 0)]
7273 UNSPEC_INDEX_JMP))
7274 (use (label_ref (match_dup 1)))
7275 (clobber (match_dup 0))
7276 (clobber (const_int 0))
7277 (clobber (reg:CC REG_CC))])]
7278 ""
7279 [(set_attr "isa" "rjmp,rjmp,jmp")])
7280
7281 (define_insn "*tablejump"
7282 [(set (pc)
7283 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
7284 UNSPEC_INDEX_JMP))
7285 (use (label_ref (match_operand 1 "" "")))
7286 (clobber (match_dup 0))
7287 (clobber (const_int 0))
7288 (clobber (reg:CC REG_CC))]
7289 "!AVR_HAVE_EIJMP_EICALL && reload_completed"
7290 "@
7291 ijmp
7292 push %A0\;push %B0\;ret
7293 jmp __tablejump2__"
7294 [(set_attr "length" "1,3,2")
7295 (set_attr "isa" "rjmp,rjmp,jmp")])
7296
7297 (define_insn_and_split "*tablejump.3byte-pc_split"
7298 [(set (pc)
7299 (unspec:HI [(reg:HI REG_Z)]
7300 UNSPEC_INDEX_JMP))
7301 (use (label_ref (match_operand 0 "" "")))
7302 (clobber (reg:HI REG_Z))
7303 (clobber (reg:QI 24))]
7304 "AVR_HAVE_EIJMP_EICALL"
7305 "#"
7306 "&& reload_completed"
7307 [(parallel [(set (pc)
7308 (unspec:HI [(reg:HI REG_Z)]
7309 UNSPEC_INDEX_JMP))
7310 (use (label_ref (match_dup 0)))
7311 (clobber (reg:HI REG_Z))
7312 (clobber (reg:QI 24))
7313 (clobber (reg:CC REG_CC))])]
7314 ""
7315 [(set_attr "isa" "eijmp")])
7316
7317
7318 (define_insn "*tablejump.3byte-pc"
7319 [(set (pc)
7320 (unspec:HI [(reg:HI REG_Z)]
7321 UNSPEC_INDEX_JMP))
7322 (use (label_ref (match_operand 0 "" "")))
7323 (clobber (reg:HI REG_Z))
7324 (clobber (reg:QI 24))
7325 (clobber (reg:CC REG_CC))]
7326 "AVR_HAVE_EIJMP_EICALL && reload_completed"
7327 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
7328 [(set_attr "length" "6")
7329 (set_attr "isa" "eijmp")])
7330
7331
7332 ;; FIXME: casesi comes up with an SImode switch value $0 which
7333 ;; is quite some overhead because most code would use HI or
7334 ;; even QI. We add an AVR specific pass .avr-casesi which
7335 ;; tries to recover from the superfluous extension to SImode.
7336 ;;
7337 ;; Using "tablejump" could be a way out, but this also does
7338 ;; not perform in a satisfying manner as the middle end will
7339 ;; already multiply the table index by 2. Note that this
7340 ;; multiplication is performed by libgcc's __tablejump2__.
7341 ;; The multiplication there, however, runs *after* the table
7342 ;; start (a byte address) has been added, not before it like
7343 ;; "tablejump" will do.
7344 ;;
7345 ;; The preferred solution would be to let the middle ends pass
7346 ;; down information on the index as an additional casesi operand.
7347 ;;
7348 ;; If this expander is changed, you'll likely have to go through
7349 ;; "casesi_<mode>_sequence" (used to recog + extract casesi
7350 ;; sequences in pass .avr-casesi) and propagate all adjustments
7351 ;; also to that pattern and the code of the extra pass.
7352
7353 (define_expand "casesi"
7354 [(parallel [(set (match_dup 5)
7355 (plus:SI (match_operand:SI 0 "register_operand")
7356 (match_operand:SI 1 "const_int_operand")))
7357 (clobber (scratch:QI))])
7358
7359 (parallel [(set (pc)
7360 (if_then_else (gtu (match_dup 5)
7361 (match_operand:SI 2 "const_int_operand"))
7362 (label_ref (match_operand 4))
7363 (pc)))
7364 (clobber (scratch:QI))])
7365
7366 (set (match_dup 7)
7367 (match_dup 6))
7368
7369 (parallel [(set (pc)
7370 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
7371 (use (label_ref (match_dup 3)))
7372 (clobber (match_dup 7))
7373 (clobber (match_dup 8))])]
7374 ""
7375 {
7376 operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode);
7377 operands[5] = gen_reg_rtx (SImode);
7378 operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0);
7379
7380 if (AVR_HAVE_EIJMP_EICALL)
7381 {
7382 operands[7] = gen_rtx_REG (HImode, REG_Z);
7383 operands[8] = all_regs_rtx[24];
7384 }
7385 else
7386 {
7387 operands[6] = gen_rtx_PLUS (HImode, operands[6],
7388 gen_rtx_LABEL_REF (VOIDmode, operands[3]));
7389 operands[7] = gen_reg_rtx (HImode);
7390 operands[8] = const0_rtx;
7391 }
7392 })
7393
7394
7395 ;; This insn is used only for easy operand extraction.
7396 ;; The elements must match an extension to SImode plus
7397 ;; a sequence generated by casesi above.
7398
7399 ;; "casesi_qi_sequence"
7400 ;; "casesi_hi_sequence"
7401 (define_insn "casesi_<mode>_sequence"
7402 [(set (match_operand:SI 0 "register_operand")
7403 (match_operator:SI 9 "extend_operator"
7404 [(match_operand:QIHI 10 "register_operand")]))
7405
7406 ;; What follows is a matcher for code from casesi.
7407 ;; We keep the same operand numbering (except for $9 and $10
7408 ;; which don't appear in casesi).
7409 (parallel [(set (match_operand:SI 5 "register_operand")
7410 (plus:SI (match_dup 0)
7411 (match_operand:SI 1 "const_int_operand")))
7412 (clobber (scratch:QI))])
7413
7414 (parallel [(set (pc)
7415 (if_then_else (gtu (match_dup 5)
7416 (match_operand:SI 2 "const_int_operand"))
7417 (label_ref (match_operand 4))
7418 (pc)))
7419 (clobber (scratch:QI))])
7420
7421 (set (match_operand:HI 7 "register_operand")
7422 (match_operand:HI 6))
7423
7424 (parallel [(set (pc)
7425 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
7426 (use (label_ref (match_operand 3)))
7427 (clobber (match_dup 7))
7428 (clobber (match_operand:QI 8))])]
7429 "optimize
7430 && avr_casei_sequence_check_operands (operands)"
7431 { gcc_unreachable(); }
7432 )
7433
7434
7435 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7436 ;; Clear/set/test a single bit in I/O address space.
7437
7438 (define_insn "*cbi"
7439 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
7440 (and:QI (mem:QI (match_dup 0))
7441 (match_operand:QI 1 "single_zero_operand" "n")))]
7442 ""
7443 {
7444 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
7445 return "cbi %i0,%2";
7446 }
7447 [(set_attr "length" "1")])
7448
7449 (define_insn "*sbi"
7450 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
7451 (ior:QI (mem:QI (match_dup 0))
7452 (match_operand:QI 1 "single_one_operand" "n")))]
7453 ""
7454 {
7455 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
7456 return "sbi %i0,%2";
7457 }
7458 [(set_attr "length" "1")])
7459
7460 ;; Lower half of the I/O space - use sbic/sbis directly.
7461 (define_insn_and_split "*sbix_branch_split"
7462 [(set (pc)
7463 (if_then_else
7464 (match_operator 0 "eqne_operator"
7465 [(zero_extract:QIHI
7466 (mem:QI (match_operand 1 "low_io_address_operand" "i"))
7467 (const_int 1)
7468 (match_operand 2 "const_int_operand" "n"))
7469 (const_int 0)])
7470 (label_ref (match_operand 3 "" ""))
7471 (pc)))]
7472 ""
7473 "#"
7474 "&& reload_completed"
7475 [(parallel [(set (pc)
7476 (if_then_else
7477 (match_operator 0 "eqne_operator"
7478 [(zero_extract:QIHI
7479 (mem:QI (match_dup 1))
7480 (const_int 1)
7481 (match_dup 2))
7482 (const_int 0)])
7483 (label_ref (match_dup 3))
7484 (pc)))
7485 (clobber (reg:CC REG_CC))])])
7486
7487 (define_insn "*sbix_branch"
7488 [(set (pc)
7489 (if_then_else
7490 (match_operator 0 "eqne_operator"
7491 [(zero_extract:QIHI
7492 (mem:QI (match_operand 1 "low_io_address_operand" "i"))
7493 (const_int 1)
7494 (match_operand 2 "const_int_operand" "n"))
7495 (const_int 0)])
7496 (label_ref (match_operand 3 "" ""))
7497 (pc)))
7498 (clobber (reg:CC REG_CC))]
7499 "reload_completed"
7500 {
7501 return avr_out_sbxx_branch (insn, operands);
7502 }
7503 [(set (attr "length")
7504 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
7505 (le (minus (pc) (match_dup 3)) (const_int 2046)))
7506 (const_int 2)
7507 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7508 (const_int 2)
7509 (const_int 4))))])
7510
7511 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
7512 (define_insn_and_split "*sbix_branch_bit7_split"
7513 [(set (pc)
7514 (if_then_else
7515 (match_operator 0 "gelt_operator"
7516 [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
7517 (const_int 0)])
7518 (label_ref (match_operand 2 "" ""))
7519 (pc)))]
7520 ""
7521 "#"
7522 "&& reload_completed"
7523 [(parallel [(set (pc)
7524 (if_then_else
7525 (match_operator 0 "gelt_operator"
7526 [(mem:QI (match_dup 1))
7527 (const_int 0)])
7528 (label_ref (match_dup 2))
7529 (pc)))
7530 (clobber (reg:CC REG_CC))])])
7531
7532 (define_insn "*sbix_branch_bit7"
7533 [(set (pc)
7534 (if_then_else
7535 (match_operator 0 "gelt_operator"
7536 [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
7537 (const_int 0)])
7538 (label_ref (match_operand 2 "" ""))
7539 (pc)))
7540 (clobber (reg:CC REG_CC))]
7541 "reload_completed"
7542 {
7543 operands[3] = operands[2];
7544 operands[2] = GEN_INT (7);
7545 return avr_out_sbxx_branch (insn, operands);
7546 }
7547 [(set (attr "length")
7548 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
7549 (le (minus (pc) (match_dup 2)) (const_int 2046)))
7550 (const_int 2)
7551 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7552 (const_int 2)
7553 (const_int 4))))])
7554
7555 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
7556 (define_insn_and_split "*sbix_branch_tmp_split"
7557 [(set (pc)
7558 (if_then_else
7559 (match_operator 0 "eqne_operator"
7560 [(zero_extract:QIHI
7561 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
7562 (const_int 1)
7563 (match_operand 2 "const_int_operand" "n"))
7564 (const_int 0)])
7565 (label_ref (match_operand 3 "" ""))
7566 (pc)))]
7567 ""
7568 "#"
7569 "&& reload_completed"
7570 [(parallel [(set (pc)
7571 (if_then_else
7572 (match_operator 0 "eqne_operator"
7573 [(zero_extract:QIHI
7574 (mem:QI (match_dup 1))
7575 (const_int 1)
7576 (match_dup 2))
7577 (const_int 0)])
7578 (label_ref (match_dup 3))
7579 (pc)))
7580 (clobber (reg:CC REG_CC))])])
7581
7582 (define_insn "*sbix_branch_tmp"
7583 [(set (pc)
7584 (if_then_else
7585 (match_operator 0 "eqne_operator"
7586 [(zero_extract:QIHI
7587 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
7588 (const_int 1)
7589 (match_operand 2 "const_int_operand" "n"))
7590 (const_int 0)])
7591 (label_ref (match_operand 3 "" ""))
7592 (pc)))
7593 (clobber (reg:CC REG_CC))]
7594 "reload_completed"
7595 {
7596 return avr_out_sbxx_branch (insn, operands);
7597 }
7598 [(set (attr "length")
7599 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
7600 (le (minus (pc) (match_dup 3)) (const_int 2045)))
7601 (const_int 3)
7602 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7603 (const_int 3)
7604 (const_int 5))))])
7605
7606 (define_insn_and_split "*sbix_branch_tmp_bit7_split"
7607 [(set (pc)
7608 (if_then_else
7609 (match_operator 0 "gelt_operator"
7610 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
7611 (const_int 0)])
7612 (label_ref (match_operand 2 "" ""))
7613 (pc)))]
7614 ""
7615 "#"
7616 "&& reload_completed"
7617 [(parallel [(set (pc)
7618 (if_then_else
7619 (match_operator 0 "gelt_operator"
7620 [(mem:QI (match_dup 1))
7621 (const_int 0)])
7622 (label_ref (match_dup 2))
7623 (pc)))
7624 (clobber (reg:CC REG_CC))])])
7625
7626 (define_insn "*sbix_branch_tmp_bit7"
7627 [(set (pc)
7628 (if_then_else
7629 (match_operator 0 "gelt_operator"
7630 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
7631 (const_int 0)])
7632 (label_ref (match_operand 2 "" ""))
7633 (pc)))
7634 (clobber (reg:CC REG_CC))]
7635 "reload_completed"
7636 {
7637 operands[3] = operands[2];
7638 operands[2] = GEN_INT (7);
7639 return avr_out_sbxx_branch (insn, operands);
7640 }
7641 [(set (attr "length")
7642 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
7643 (le (minus (pc) (match_dup 2)) (const_int 2045)))
7644 (const_int 3)
7645 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7646 (const_int 3)
7647 (const_int 5))))])
7648
7649 ;; ************************* Peepholes ********************************
7650
7651 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
7652 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
7653 (plus:SI (match_dup 0)
7654 (const_int -1)))
7655 (clobber (scratch:QI))
7656 (clobber (reg:CC REG_CC))])
7657 (parallel [(set (reg:CC REG_CC)
7658 (compare:CC (match_dup 0)
7659 (const_int -1)))
7660 (clobber (match_operand:QI 1 "d_register_operand" ""))])
7661 (parallel [(set (pc)
7662 (if_then_else (eqne (reg:CC REG_CC)
7663 (const_int 0))
7664 (label_ref (match_operand 2 "" ""))
7665 (pc)))
7666 (clobber (reg:CC REG_CC))])]
7667 ""
7668 {
7669 const char *op;
7670 int jump_mode;
7671 if (test_hard_reg_class (ADDW_REGS, operands[0]))
7672 output_asm_insn ("sbiw %0,1" CR_TAB
7673 "sbc %C0,__zero_reg__" CR_TAB
7674 "sbc %D0,__zero_reg__", operands);
7675 else
7676 output_asm_insn ("subi %A0,1" CR_TAB
7677 "sbc %B0,__zero_reg__" CR_TAB
7678 "sbc %C0,__zero_reg__" CR_TAB
7679 "sbc %D0,__zero_reg__", operands);
7680
7681 jump_mode = avr_jump_mode (operands[2], insn);
7682 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7683 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7684
7685 switch (jump_mode)
7686 {
7687 case 1: return "%1 %2";
7688 case 2: return "%1 .+2\;rjmp %2";
7689 case 3: return "%1 .+4\;jmp %2";
7690 }
7691
7692 gcc_unreachable();
7693 return "";
7694 })
7695
7696 (define_peephole ; "*dec-and-branchhi!=-1"
7697 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
7698 (plus:HI (match_dup 0)
7699 (const_int -1)))
7700 (clobber (reg:CC REG_CC))])
7701 (parallel [(set (reg:CC REG_CC)
7702 (compare:CC (match_dup 0)
7703 (const_int -1)))
7704 (clobber (match_operand:QI 1 "d_register_operand" ""))])
7705 (parallel [(set (pc)
7706 (if_then_else (eqne (reg:CC REG_CC)
7707 (const_int 0))
7708 (label_ref (match_operand 2 "" ""))
7709 (pc)))
7710 (clobber (reg:CC REG_CC))])]
7711 ""
7712 {
7713 const char *op;
7714 int jump_mode;
7715 if (test_hard_reg_class (ADDW_REGS, operands[0]))
7716 output_asm_insn ("sbiw %0,1", operands);
7717 else
7718 output_asm_insn ("subi %A0,1" CR_TAB
7719 "sbc %B0,__zero_reg__", operands);
7720
7721 jump_mode = avr_jump_mode (operands[2], insn);
7722 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7723 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7724
7725 switch (jump_mode)
7726 {
7727 case 1: return "%1 %2";
7728 case 2: return "%1 .+2\;rjmp %2";
7729 case 3: return "%1 .+4\;jmp %2";
7730 }
7731
7732 gcc_unreachable();
7733 return "";
7734 })
7735
7736 ;; Same as above but with clobber flavour of addhi3
7737 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
7738 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
7739 (plus:HI (match_dup 0)
7740 (const_int -1)))
7741 (clobber (scratch:QI))
7742 (clobber (reg:CC REG_CC))])
7743 (parallel [(set (reg:CC REG_CC)
7744 (compare:CC (match_dup 0)
7745 (const_int -1)))
7746 (clobber (match_operand:QI 1 "d_register_operand" ""))])
7747 (parallel [(set (pc)
7748 (if_then_else (eqne (reg:CC REG_CC)
7749 (const_int 0))
7750 (label_ref (match_operand 2 "" ""))
7751 (pc)))
7752 (clobber (reg:CC REG_CC))])]
7753 ""
7754 {
7755 const char *op;
7756 int jump_mode;
7757 if (test_hard_reg_class (ADDW_REGS, operands[0]))
7758 output_asm_insn ("sbiw %0,1", operands);
7759 else
7760 output_asm_insn ("subi %A0,1" CR_TAB
7761 "sbc %B0,__zero_reg__", operands);
7762
7763 jump_mode = avr_jump_mode (operands[2], insn);
7764 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7765 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7766
7767 switch (jump_mode)
7768 {
7769 case 1: return "%1 %2";
7770 case 2: return "%1 .+2\;rjmp %2";
7771 case 3: return "%1 .+4\;jmp %2";
7772 }
7773
7774 gcc_unreachable();
7775 return "";
7776 })
7777
7778 ;; Same as above but with clobber flavour of addhi3
7779 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
7780 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
7781 (plus:HI (match_dup 0)
7782 (const_int -1)))
7783 (clobber (match_operand:QI 3 "d_register_operand" ""))
7784 (clobber (reg:CC REG_CC))])
7785 (parallel [(set (reg:CC REG_CC)
7786 (compare:CC (match_dup 0)
7787 (const_int -1)))
7788 (clobber (match_operand:QI 1 "d_register_operand" ""))])
7789 (parallel [(set (pc)
7790 (if_then_else (eqne (reg:CC REG_CC)
7791 (const_int 0))
7792 (label_ref (match_operand 2 "" ""))
7793 (pc)))
7794 (clobber (reg:CC REG_CC))])]
7795 ""
7796 {
7797 const char *op;
7798 int jump_mode;
7799 output_asm_insn ("ldi %3,1" CR_TAB
7800 "sub %A0,%3" CR_TAB
7801 "sbc %B0,__zero_reg__", operands);
7802
7803 jump_mode = avr_jump_mode (operands[2], insn);
7804 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7805 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7806
7807 switch (jump_mode)
7808 {
7809 case 1: return "%1 %2";
7810 case 2: return "%1 .+2\;rjmp %2";
7811 case 3: return "%1 .+4\;jmp %2";
7812 }
7813
7814 gcc_unreachable();
7815 return "";
7816 })
7817
7818 (define_peephole ; "*dec-and-branchqi!=-1"
7819 [(parallel [(set (match_operand:QI 0 "d_register_operand" "")
7820 (plus:QI (match_dup 0)
7821 (const_int -1)))
7822 (clobber (reg:CC REG_CC))])
7823 (set (reg:CC REG_CC)
7824 (compare:CC (match_dup 0)
7825 (const_int -1)))
7826 (parallel [(set (pc)
7827 (if_then_else (eqne (reg:CC REG_CC)
7828 (const_int 0))
7829 (label_ref (match_operand 1 "" ""))
7830 (pc)))
7831 (clobber (reg:CC REG_CC))])]
7832 ""
7833 {
7834 const char *op;
7835 int jump_mode;
7836
7837 output_asm_insn ("subi %A0,1", operands);
7838
7839 jump_mode = avr_jump_mode (operands[1], insn);
7840 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7841 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
7842
7843 switch (jump_mode)
7844 {
7845 case 1: return "%0 %1";
7846 case 2: return "%0 .+2\;rjmp %1";
7847 case 3: return "%0 .+4\;jmp %1";
7848 }
7849
7850 gcc_unreachable();
7851 return "";
7852 })
7853
7854
7855 (define_peephole ; "*cpse.eq"
7856 [(set (reg:CC REG_CC)
7857 (compare:CC (match_operand:ALL1 1 "register_operand" "r,r")
7858 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
7859 (parallel [(set (pc)
7860 (if_then_else (eq (reg:CC REG_CC)
7861 (const_int 0))
7862 (label_ref (match_operand 0 "" ""))
7863 (pc)))
7864 (clobber (reg:CC REG_CC))])]
7865 "jump_over_one_insn_p (insn, operands[0])"
7866 "@
7867 cpse %1,%2
7868 cpse %1,__zero_reg__")
7869
7870 ;; This peephole avoids code like
7871 ;;
7872 ;; TST Rn ; cmpqi3
7873 ;; BREQ .+2 ; branch
7874 ;; RJMP .Lm
7875 ;;
7876 ;; Notice that the peephole is always shorter than cmpqi + branch.
7877 ;; The reason to write it as peephole is that sequences like
7878 ;;
7879 ;; AND Rm, Rn
7880 ;; BRNE .La
7881 ;;
7882 ;; shall not be superseeded. With a respective combine pattern
7883 ;; the latter sequence would be
7884 ;;
7885 ;; AND Rm, Rn
7886 ;; CPSE Rm, __zero_reg__
7887 ;; RJMP .La
7888 ;;
7889 ;; and thus longer and slower and not easy to be rolled back.
7890
7891 (define_peephole ; "*cpse.ne"
7892 [(set (reg:CC REG_CC)
7893 (compare:CC (match_operand:ALL1 1 "register_operand" "")
7894 (match_operand:ALL1 2 "reg_or_0_operand" "")))
7895 (parallel [(set (pc)
7896 (if_then_else (ne (reg:CC REG_CC)
7897 (const_int 0))
7898 (label_ref (match_operand 0 "" ""))
7899 (pc)))
7900 (clobber (reg:CC REG_CC))])]
7901 "!AVR_HAVE_JMP_CALL
7902 || !TARGET_SKIP_BUG"
7903 {
7904 if (operands[2] == CONST0_RTX (<MODE>mode))
7905 operands[2] = zero_reg_rtx;
7906
7907 return 3 == avr_jump_mode (operands[0], insn)
7908 ? "cpse %1,%2\;jmp %0"
7909 : "cpse %1,%2\;rjmp %0";
7910 })
7911
7912 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
7913 ;;prologue/epilogue support instructions
7914
7915 (define_insn "popqi"
7916 [(set (match_operand:QI 0 "register_operand" "=r")
7917 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
7918 ""
7919 "pop %0"
7920 [(set_attr "length" "1")])
7921
7922 ;; Enable Interrupts
7923 (define_expand "enable_interrupt"
7924 [(clobber (const_int 0))]
7925 ""
7926 {
7927 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7928 MEM_VOLATILE_P (mem) = 1;
7929 emit_insn (gen_cli_sei (const1_rtx, mem));
7930 DONE;
7931 })
7932
7933 ;; Disable Interrupts
7934 (define_expand "disable_interrupt"
7935 [(clobber (const_int 0))]
7936 ""
7937 {
7938 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7939 MEM_VOLATILE_P (mem) = 1;
7940 emit_insn (gen_cli_sei (const0_rtx, mem));
7941 DONE;
7942 })
7943
7944 (define_insn "cli_sei"
7945 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
7946 UNSPECV_ENABLE_IRQS)
7947 (set (match_operand:BLK 1 "" "")
7948 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
7949 ""
7950 "@
7951 cli
7952 sei"
7953 [(set_attr "length" "1")])
7954
7955 ;; Library prologue saves
7956 (define_insn "call_prologue_saves"
7957 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
7958 (match_operand:HI 0 "immediate_operand" "i,i")
7959 (set (reg:HI REG_SP)
7960 (minus:HI (reg:HI REG_SP)
7961 (match_operand:HI 1 "immediate_operand" "i,i")))
7962 (use (reg:HI REG_X))
7963 (clobber (reg:HI REG_Z))
7964 (clobber (reg:CC REG_CC))]
7965 ""
7966 "ldi r30,lo8(gs(1f))
7967 ldi r31,hi8(gs(1f))
7968 %~jmp __prologue_saves__+((18 - %0) * 2)
7969 1:"
7970 [(set_attr "length" "5,6")
7971 (set_attr "isa" "rjmp,jmp")])
7972
7973 ; epilogue restores using library
7974 (define_insn "epilogue_restores"
7975 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
7976 (set (reg:HI REG_Y)
7977 (plus:HI (reg:HI REG_Y)
7978 (match_operand:HI 0 "immediate_operand" "i,i")))
7979 (set (reg:HI REG_SP)
7980 (plus:HI (reg:HI REG_Y)
7981 (match_dup 0)))
7982 (clobber (reg:QI REG_Z))
7983 (clobber (reg:CC REG_CC))]
7984 ""
7985 "ldi r30, lo8(%0)
7986 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
7987 [(set_attr "length" "2,3")
7988 (set_attr "isa" "rjmp,jmp")])
7989
7990
7991 ;; $0 = Chunk: 1 = Prologue, 2 = Epilogue
7992 ;; $1 = Register as printed by chunk 0 (Done) in final postscan.
7993 (define_expand "gasisr"
7994 [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand")
7995 (match_operand:QI 1 "const_int_operand")]
7996 UNSPECV_GASISR)
7997 (set (reg:HI REG_SP)
7998 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
7999 (set (match_dup 2)
8000 (unspec_volatile:BLK [(match_dup 2)]
8001 UNSPECV_MEMORY_BARRIER))
8002 (clobber (reg:CC REG_CC))])]
8003 "avr_gasisr_prologues"
8004 {
8005 operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8006 MEM_VOLATILE_P (operands[2]) = 1;
8007 })
8008
8009 (define_insn "*gasisr"
8010 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K")
8011 (match_operand:QI 1 "const_int_operand" "n,n")]
8012 UNSPECV_GASISR)
8013 (set (reg:HI REG_SP)
8014 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
8015 (set (match_operand:BLK 2)
8016 (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER))
8017 (clobber (reg:CC REG_CC))]
8018 "avr_gasisr_prologues"
8019 "__gcc_isr %0"
8020 [(set_attr "length" "6,5")])
8021
8022
8023 ; return
8024 (define_insn "return"
8025 [(return)]
8026 "reload_completed && avr_simple_epilogue ()"
8027 "ret"
8028 [(set_attr "length" "1")])
8029
8030 (define_insn "return_from_epilogue"
8031 [(return)]
8032 "reload_completed
8033 && cfun->machine
8034 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
8035 && !cfun->machine->is_naked"
8036 "ret"
8037 [(set_attr "length" "1")])
8038
8039 (define_insn "return_from_interrupt_epilogue"
8040 [(return)]
8041 "reload_completed
8042 && cfun->machine
8043 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
8044 && !cfun->machine->is_naked"
8045 "reti"
8046 [(set_attr "length" "1")])
8047
8048 (define_insn "return_from_naked_epilogue"
8049 [(return)]
8050 "reload_completed
8051 && cfun->machine
8052 && cfun->machine->is_naked"
8053 ""
8054 [(set_attr "length" "0")])
8055
8056 (define_expand "prologue"
8057 [(const_int 0)]
8058 ""
8059 {
8060 avr_expand_prologue ();
8061 DONE;
8062 })
8063
8064 (define_expand "epilogue"
8065 [(const_int 0)]
8066 ""
8067 {
8068 avr_expand_epilogue (false /* sibcall_p */);
8069 DONE;
8070 })
8071
8072 (define_expand "sibcall_epilogue"
8073 [(const_int 0)]
8074 ""
8075 {
8076 avr_expand_epilogue (true /* sibcall_p */);
8077 DONE;
8078 })
8079
8080 ;; Some instructions resp. instruction sequences available
8081 ;; via builtins.
8082
8083 (define_insn_and_split "delay_cycles_1"
8084 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
8085 (const_int 1)]
8086 UNSPECV_DELAY_CYCLES)
8087 (set (match_operand:BLK 1 "" "")
8088 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8089 (clobber (match_scratch:QI 2 "=&d"))]
8090 ""
8091 "#"
8092 "&& reload_completed"
8093 [(parallel [(unspec_volatile [(match_dup 0)
8094 (const_int 1)]
8095 UNSPECV_DELAY_CYCLES)
8096 (set (match_dup 1)
8097 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8098 (clobber (match_dup 2))
8099 (clobber (reg:CC REG_CC))])])
8100
8101 (define_insn "*delay_cycles_1"
8102 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
8103 (const_int 1)]
8104 UNSPECV_DELAY_CYCLES)
8105 (set (match_operand:BLK 1 "" "")
8106 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8107 (clobber (match_scratch:QI 2 "=&d"))
8108 (clobber (reg:CC REG_CC))]
8109 "reload_completed"
8110 "ldi %2,lo8(%0)
8111 1: dec %2
8112 brne 1b"
8113 [(set_attr "length" "3")])
8114
8115 (define_insn_and_split "delay_cycles_2"
8116 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
8117 (const_int 2)]
8118 UNSPECV_DELAY_CYCLES)
8119 (set (match_operand:BLK 1 "" "")
8120 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8121 (clobber (match_scratch:HI 2 "=&w,&d"))]
8122 ""
8123 "#"
8124 "&& reload_completed"
8125 [(parallel [(unspec_volatile [(match_dup 0)
8126 (const_int 2)]
8127 UNSPECV_DELAY_CYCLES)
8128 (set (match_dup 1)
8129 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8130 (clobber (match_dup 2))
8131 (clobber (reg:CC REG_CC))])]
8132 ""
8133 [(set_attr "isa" "no_tiny,tiny")])
8134
8135 (define_insn "*delay_cycles_2"
8136 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
8137 (const_int 2)]
8138 UNSPECV_DELAY_CYCLES)
8139 (set (match_operand:BLK 1 "" "")
8140 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8141 (clobber (match_scratch:HI 2 "=&w,&d"))
8142 (clobber (reg:CC REG_CC))]
8143 "reload_completed"
8144 "@
8145 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: sbiw %A2,1\;brne 1b
8146 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: subi %A2,1\;sbci %B2,0\;brne 1b"
8147 [(set_attr "length" "4,5")
8148 (set_attr "isa" "no_tiny,tiny")])
8149
8150 (define_insn_and_split "delay_cycles_3"
8151 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8152 (const_int 3)]
8153 UNSPECV_DELAY_CYCLES)
8154 (set (match_operand:BLK 1 "" "")
8155 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8156 (clobber (match_scratch:QI 2 "=&d"))
8157 (clobber (match_scratch:QI 3 "=&d"))
8158 (clobber (match_scratch:QI 4 "=&d"))]
8159 ""
8160 "#"
8161 "&& reload_completed"
8162 [(parallel [(unspec_volatile [(match_dup 0)
8163 (const_int 3)]
8164 UNSPECV_DELAY_CYCLES)
8165 (set (match_dup 1)
8166 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8167 (clobber (match_dup 2))
8168 (clobber (match_dup 3))
8169 (clobber (match_dup 4))
8170 (clobber (reg:CC REG_CC))])])
8171
8172 (define_insn "*delay_cycles_3"
8173 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8174 (const_int 3)]
8175 UNSPECV_DELAY_CYCLES)
8176 (set (match_operand:BLK 1 "" "")
8177 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8178 (clobber (match_scratch:QI 2 "=&d"))
8179 (clobber (match_scratch:QI 3 "=&d"))
8180 (clobber (match_scratch:QI 4 "=&d"))
8181 (clobber (reg:CC REG_CC))]
8182 "reload_completed"
8183 "ldi %2,lo8(%0)
8184 ldi %3,hi8(%0)
8185 ldi %4,hlo8(%0)
8186 1: subi %2,1
8187 sbci %3,0
8188 sbci %4,0
8189 brne 1b"
8190 [(set_attr "length" "7")])
8191
8192 (define_insn_and_split "delay_cycles_4"
8193 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8194 (const_int 4)]
8195 UNSPECV_DELAY_CYCLES)
8196 (set (match_operand:BLK 1 "" "")
8197 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8198 (clobber (match_scratch:QI 2 "=&d"))
8199 (clobber (match_scratch:QI 3 "=&d"))
8200 (clobber (match_scratch:QI 4 "=&d"))
8201 (clobber (match_scratch:QI 5 "=&d"))]
8202 ""
8203 "#"
8204 "&& reload_completed"
8205 [(parallel [(unspec_volatile [(match_dup 0)
8206 (const_int 4)]
8207 UNSPECV_DELAY_CYCLES)
8208 (set (match_dup 1)
8209 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8210 (clobber (match_dup 2))
8211 (clobber (match_dup 3))
8212 (clobber (match_dup 4))
8213 (clobber (match_dup 5))
8214 (clobber (reg:CC REG_CC))])])
8215
8216 (define_insn "*delay_cycles_4"
8217 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8218 (const_int 4)]
8219 UNSPECV_DELAY_CYCLES)
8220 (set (match_operand:BLK 1 "" "")
8221 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8222 (clobber (match_scratch:QI 2 "=&d"))
8223 (clobber (match_scratch:QI 3 "=&d"))
8224 (clobber (match_scratch:QI 4 "=&d"))
8225 (clobber (match_scratch:QI 5 "=&d"))
8226 (clobber (reg:CC REG_CC))]
8227 "reload_completed"
8228 "ldi %2,lo8(%0)
8229 ldi %3,hi8(%0)
8230 ldi %4,hlo8(%0)
8231 ldi %5,hhi8(%0)
8232 1: subi %2,1
8233 sbci %3,0
8234 sbci %4,0
8235 sbci %5,0
8236 brne 1b"
8237 [(set_attr "length" "9")])
8238
8239
8240 ;; __builtin_avr_insert_bits
8241
8242 (define_insn_and_split "insert_bits"
8243 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
8244 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
8245 (match_operand:QI 2 "register_operand" "r ,r ,r")
8246 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
8247 UNSPEC_INSERT_BITS))]
8248 ""
8249 "#"
8250 "&& reload_completed"
8251 [(parallel [(set (match_dup 0)
8252 (unspec:QI [(match_dup 1)
8253 (match_dup 2)
8254 (match_dup 3)]
8255 UNSPEC_INSERT_BITS))
8256 (clobber (reg:CC REG_CC))])])
8257
8258 (define_insn "*insert_bits"
8259 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
8260 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
8261 (match_operand:QI 2 "register_operand" "r ,r ,r")
8262 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
8263 UNSPEC_INSERT_BITS))
8264 (clobber (reg:CC REG_CC))]
8265 "reload_completed"
8266 {
8267 return avr_out_insert_bits (operands, NULL);
8268 }
8269 [(set_attr "adjust_len" "insert_bits")])
8270
8271
8272 ;; __builtin_avr_flash_segment
8273
8274 ;; Just a helper for the next "official" expander.
8275
8276 (define_expand "flash_segment1"
8277 [(set (match_operand:QI 0 "register_operand" "")
8278 (subreg:QI (match_operand:PSI 1 "register_operand" "")
8279 2))
8280 (set (pc)
8281 (if_then_else (ge (match_dup 0)
8282 (const_int 0))
8283 (label_ref (match_operand 2 "" ""))
8284 (pc)))
8285 (set (match_dup 0)
8286 (const_int -1))])
8287
8288 (define_insn_and_split "*flash_segment1"
8289 [(set (pc)
8290 (if_then_else (ge (match_operand:QI 0 "register_operand" "")
8291 (const_int 0))
8292 (label_ref (match_operand 1 "" ""))
8293 (pc)))]
8294 ""
8295 "#"
8296 "reload_completed"
8297 [(set (reg:CC REG_CC)
8298 (compare:CC (match_dup 0) (const_int 0)))
8299 (set (pc)
8300 (if_then_else (ge (reg:CC REG_CC) (const_int 0))
8301 (label_ref (match_dup 1))
8302 (pc)))]
8303 "")
8304
8305 (define_expand "flash_segment"
8306 [(parallel [(match_operand:QI 0 "register_operand" "")
8307 (match_operand:PSI 1 "register_operand" "")])]
8308 ""
8309 {
8310 rtx label = gen_label_rtx ();
8311 emit (gen_flash_segment1 (operands[0], operands[1], label));
8312 emit_label (label);
8313 DONE;
8314 })
8315
8316 ;; Actually, it's too late now to work out address spaces known at compiletime.
8317 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
8318 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
8319 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
8320
8321 (define_insn_and_split "*split.flash_segment"
8322 [(set (match_operand:QI 0 "register_operand" "=d")
8323 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
8324 (match_operand:HI 2 "register_operand" "r"))
8325 2))]
8326 ""
8327 { gcc_unreachable(); }
8328 ""
8329 [(set (match_dup 0)
8330 (match_dup 1))])
8331
8332
8333 ;; Parity
8334
8335 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
8336 ;; better 8-bit parity recognition.
8337
8338 (define_expand "parityhi2"
8339 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8340 (parity:HI (match_operand:HI 1 "register_operand" "")))
8341 (clobber (reg:HI 24))])])
8342
8343 (define_insn_and_split "*parityhi2"
8344 [(set (match_operand:HI 0 "register_operand" "=r")
8345 (parity:HI (match_operand:HI 1 "register_operand" "r")))
8346 (clobber (reg:HI 24))]
8347 "!reload_completed"
8348 { gcc_unreachable(); }
8349 "&& 1"
8350 [(set (reg:HI 24)
8351 (match_dup 1))
8352 (set (reg:HI 24)
8353 (parity:HI (reg:HI 24)))
8354 (set (match_dup 0)
8355 (reg:HI 24))])
8356
8357 (define_insn_and_split "*parityqihi2"
8358 [(set (match_operand:HI 0 "register_operand" "=r")
8359 (parity:HI (match_operand:QI 1 "register_operand" "r")))
8360 (clobber (reg:HI 24))]
8361 "!reload_completed"
8362 { gcc_unreachable(); }
8363 "&& 1"
8364 [(set (reg:QI 24)
8365 (match_dup 1))
8366 (set (reg:HI 24)
8367 (zero_extend:HI (parity:QI (reg:QI 24))))
8368 (set (match_dup 0)
8369 (reg:HI 24))])
8370
8371 (define_expand "paritysi2"
8372 [(set (reg:SI 22)
8373 (match_operand:SI 1 "register_operand" ""))
8374 (set (reg:HI 24)
8375 (truncate:HI (parity:SI (reg:SI 22))))
8376 (set (match_dup 2)
8377 (reg:HI 24))
8378 (set (match_operand:SI 0 "register_operand" "")
8379 (zero_extend:SI (match_dup 2)))]
8380 ""
8381 {
8382 operands[2] = gen_reg_rtx (HImode);
8383 })
8384
8385 (define_insn_and_split "*parityhi2.libgcc_split"
8386 [(set (reg:HI 24)
8387 (parity:HI (reg:HI 24)))]
8388 ""
8389 "#"
8390 "&& reload_completed"
8391 [(parallel [(set (reg:HI 24)
8392 (parity:HI (reg:HI 24)))
8393 (clobber (reg:CC REG_CC))])])
8394
8395 (define_insn "*parityhi2.libgcc"
8396 [(set (reg:HI 24)
8397 (parity:HI (reg:HI 24)))
8398 (clobber (reg:CC REG_CC))]
8399 "reload_completed"
8400 "%~call __parityhi2"
8401 [(set_attr "type" "xcall")])
8402
8403 (define_insn_and_split "*parityqihi2.libgcc_split"
8404 [(set (reg:HI 24)
8405 (zero_extend:HI (parity:QI (reg:QI 24))))]
8406 ""
8407 "#"
8408 "&& reload_completed"
8409 [(parallel [(set (reg:HI 24)
8410 (zero_extend:HI (parity:QI (reg:QI 24))))
8411 (clobber (reg:CC REG_CC))])])
8412
8413 (define_insn "*parityqihi2.libgcc"
8414 [(set (reg:HI 24)
8415 (zero_extend:HI (parity:QI (reg:QI 24))))
8416 (clobber (reg:CC REG_CC))]
8417 "reload_completed"
8418 "%~call __parityqi2"
8419 [(set_attr "type" "xcall")])
8420
8421 (define_insn_and_split "*paritysihi2.libgcc_split"
8422 [(set (reg:HI 24)
8423 (truncate:HI (parity:SI (reg:SI 22))))]
8424 ""
8425 "#"
8426 "&& reload_completed"
8427 [(parallel [(set (reg:HI 24)
8428 (truncate:HI (parity:SI (reg:SI 22))))
8429 (clobber (reg:CC REG_CC))])])
8430
8431 (define_insn "*paritysihi2.libgcc"
8432 [(set (reg:HI 24)
8433 (truncate:HI (parity:SI (reg:SI 22))))
8434 (clobber (reg:CC REG_CC))]
8435 "reload_completed"
8436 "%~call __paritysi2"
8437 [(set_attr "type" "xcall")])
8438
8439
8440 ;; Popcount
8441
8442 (define_expand "popcounthi2"
8443 [(set (reg:HI 24)
8444 (match_operand:HI 1 "register_operand" ""))
8445 (set (reg:HI 24)
8446 (popcount:HI (reg:HI 24)))
8447 (set (match_operand:HI 0 "register_operand" "")
8448 (reg:HI 24))]
8449 ""
8450 "")
8451
8452 (define_expand "popcountsi2"
8453 [(set (reg:SI 22)
8454 (match_operand:SI 1 "register_operand" ""))
8455 (set (reg:HI 24)
8456 (truncate:HI (popcount:SI (reg:SI 22))))
8457 (set (match_dup 2)
8458 (reg:HI 24))
8459 (set (match_operand:SI 0 "register_operand" "")
8460 (zero_extend:SI (match_dup 2)))]
8461 ""
8462 {
8463 operands[2] = gen_reg_rtx (HImode);
8464 })
8465
8466 (define_insn_and_split "*popcounthi2.libgcc_split"
8467 [(set (reg:HI 24)
8468 (popcount:HI (reg:HI 24)))]
8469 ""
8470 "#"
8471 "&& reload_completed"
8472 [(parallel [(set (reg:HI 24)
8473 (popcount:HI (reg:HI 24)))
8474 (clobber (reg:CC REG_CC))])])
8475
8476 (define_insn "*popcounthi2.libgcc"
8477 [(set (reg:HI 24)
8478 (popcount:HI (reg:HI 24)))
8479 (clobber (reg:CC REG_CC))]
8480 "reload_completed"
8481 "%~call __popcounthi2"
8482 [(set_attr "type" "xcall")])
8483
8484 (define_insn_and_split "*popcountsi2.libgcc_split"
8485 [(set (reg:HI 24)
8486 (truncate:HI (popcount:SI (reg:SI 22))))]
8487 ""
8488 "#"
8489 "&& reload_completed"
8490 [(parallel [(set (reg:HI 24)
8491 (truncate:HI (popcount:SI (reg:SI 22))))
8492 (clobber (reg:CC REG_CC))])])
8493
8494 (define_insn "*popcountsi2.libgcc"
8495 [(set (reg:HI 24)
8496 (truncate:HI (popcount:SI (reg:SI 22))))
8497 (clobber (reg:CC REG_CC))]
8498 "reload_completed"
8499 "%~call __popcountsi2"
8500 [(set_attr "type" "xcall")])
8501
8502 (define_insn_and_split "*popcountqi2.libgcc_split"
8503 [(set (reg:QI 24)
8504 (popcount:QI (reg:QI 24)))]
8505 ""
8506 "#"
8507 "&& reload_completed"
8508 [(parallel [(set (reg:QI 24)
8509 (popcount:QI (reg:QI 24)))
8510 (clobber (reg:CC REG_CC))])])
8511
8512 (define_insn "*popcountqi2.libgcc"
8513 [(set (reg:QI 24)
8514 (popcount:QI (reg:QI 24)))
8515 (clobber (reg:CC REG_CC))]
8516 "reload_completed"
8517 "%~call __popcountqi2"
8518 [(set_attr "type" "xcall")])
8519
8520 (define_insn_and_split "*popcountqihi2.libgcc"
8521 [(set (reg:HI 24)
8522 (zero_extend:HI (popcount:QI (reg:QI 24))))]
8523 ""
8524 "#"
8525 ""
8526 [(set (reg:QI 24)
8527 (popcount:QI (reg:QI 24)))
8528 (set (reg:QI 25)
8529 (const_int 0))])
8530
8531 ;; Count Leading Zeros
8532
8533 (define_expand "clzhi2"
8534 [(set (reg:HI 24)
8535 (match_operand:HI 1 "register_operand" ""))
8536 (parallel [(set (reg:HI 24)
8537 (clz:HI (reg:HI 24)))
8538 (clobber (reg:QI 26))])
8539 (set (match_operand:HI 0 "register_operand" "")
8540 (reg:HI 24))])
8541
8542 (define_expand "clzsi2"
8543 [(set (reg:SI 22)
8544 (match_operand:SI 1 "register_operand" ""))
8545 (parallel [(set (reg:HI 24)
8546 (truncate:HI (clz:SI (reg:SI 22))))
8547 (clobber (reg:QI 26))])
8548 (set (match_dup 2)
8549 (reg:HI 24))
8550 (set (match_operand:SI 0 "register_operand" "")
8551 (zero_extend:SI (match_dup 2)))]
8552 ""
8553 {
8554 operands[2] = gen_reg_rtx (HImode);
8555 })
8556
8557 (define_insn_and_split "*clzhi2.libgcc_split"
8558 [(set (reg:HI 24)
8559 (clz:HI (reg:HI 24)))
8560 (clobber (reg:QI 26))]
8561 ""
8562 "#"
8563 "&& reload_completed"
8564 [(parallel [(set (reg:HI 24)
8565 (clz:HI (reg:HI 24)))
8566 (clobber (reg:QI 26))
8567 (clobber (reg:CC REG_CC))])])
8568
8569 (define_insn "*clzhi2.libgcc"
8570 [(set (reg:HI 24)
8571 (clz:HI (reg:HI 24)))
8572 (clobber (reg:QI 26))
8573 (clobber (reg:CC REG_CC))]
8574 "reload_completed"
8575 "%~call __clzhi2"
8576 [(set_attr "type" "xcall")])
8577
8578 (define_insn_and_split "*clzsihi2.libgcc_split"
8579 [(set (reg:HI 24)
8580 (truncate:HI (clz:SI (reg:SI 22))))
8581 (clobber (reg:QI 26))]
8582 ""
8583 "#"
8584 "&& reload_completed"
8585 [(parallel [(set (reg:HI 24)
8586 (truncate:HI (clz:SI (reg:SI 22))))
8587 (clobber (reg:QI 26))
8588 (clobber (reg:CC REG_CC))])])
8589
8590 (define_insn "*clzsihi2.libgcc"
8591 [(set (reg:HI 24)
8592 (truncate:HI (clz:SI (reg:SI 22))))
8593 (clobber (reg:QI 26))
8594 (clobber (reg:CC REG_CC))]
8595 "reload_completed"
8596 "%~call __clzsi2"
8597 [(set_attr "type" "xcall")])
8598
8599 ;; Count Trailing Zeros
8600
8601 (define_expand "ctzhi2"
8602 [(set (reg:HI 24)
8603 (match_operand:HI 1 "register_operand" ""))
8604 (parallel [(set (reg:HI 24)
8605 (ctz:HI (reg:HI 24)))
8606 (clobber (reg:QI 26))])
8607 (set (match_operand:HI 0 "register_operand" "")
8608 (reg:HI 24))])
8609
8610 (define_expand "ctzsi2"
8611 [(set (reg:SI 22)
8612 (match_operand:SI 1 "register_operand" ""))
8613 (parallel [(set (reg:HI 24)
8614 (truncate:HI (ctz:SI (reg:SI 22))))
8615 (clobber (reg:QI 22))
8616 (clobber (reg:QI 26))])
8617 (set (match_dup 2)
8618 (reg:HI 24))
8619 (set (match_operand:SI 0 "register_operand" "")
8620 (zero_extend:SI (match_dup 2)))]
8621 ""
8622 {
8623 operands[2] = gen_reg_rtx (HImode);
8624 })
8625
8626 (define_insn_and_split "*ctzhi2.libgcc_split"
8627 [(set (reg:HI 24)
8628 (ctz:HI (reg:HI 24)))
8629 (clobber (reg:QI 26))]
8630 ""
8631 "#"
8632 "&& reload_completed"
8633 [(parallel [(set (reg:HI 24)
8634 (ctz:HI (reg:HI 24)))
8635 (clobber (reg:QI 26))
8636 (clobber (reg:CC REG_CC))])])
8637
8638 (define_insn "*ctzhi2.libgcc"
8639 [(set (reg:HI 24)
8640 (ctz:HI (reg:HI 24)))
8641 (clobber (reg:QI 26))
8642 (clobber (reg:CC REG_CC))]
8643 "reload_completed"
8644 "%~call __ctzhi2"
8645 [(set_attr "type" "xcall")])
8646
8647 (define_insn_and_split "*ctzsihi2.libgcc_split"
8648 [(set (reg:HI 24)
8649 (truncate:HI (ctz:SI (reg:SI 22))))
8650 (clobber (reg:QI 22))
8651 (clobber (reg:QI 26))]
8652 ""
8653 "#"
8654 "&& reload_completed"
8655 [(parallel [(set (reg:HI 24)
8656 (truncate:HI (ctz:SI (reg:SI 22))))
8657 (clobber (reg:QI 22))
8658 (clobber (reg:QI 26))
8659 (clobber (reg:CC REG_CC))])])
8660
8661 (define_insn "*ctzsihi2.libgcc"
8662 [(set (reg:HI 24)
8663 (truncate:HI (ctz:SI (reg:SI 22))))
8664 (clobber (reg:QI 22))
8665 (clobber (reg:QI 26))
8666 (clobber (reg:CC REG_CC))]
8667 "reload_completed"
8668 "%~call __ctzsi2"
8669 [(set_attr "type" "xcall")])
8670
8671 ;; Find First Set
8672
8673 (define_expand "ffshi2"
8674 [(set (reg:HI 24)
8675 (match_operand:HI 1 "register_operand" ""))
8676 (parallel [(set (reg:HI 24)
8677 (ffs:HI (reg:HI 24)))
8678 (clobber (reg:QI 26))])
8679 (set (match_operand:HI 0 "register_operand" "")
8680 (reg:HI 24))])
8681
8682 (define_expand "ffssi2"
8683 [(set (reg:SI 22)
8684 (match_operand:SI 1 "register_operand" ""))
8685 (parallel [(set (reg:HI 24)
8686 (truncate:HI (ffs:SI (reg:SI 22))))
8687 (clobber (reg:QI 22))
8688 (clobber (reg:QI 26))])
8689 (set (match_dup 2)
8690 (reg:HI 24))
8691 (set (match_operand:SI 0 "register_operand" "")
8692 (zero_extend:SI (match_dup 2)))]
8693 ""
8694 {
8695 operands[2] = gen_reg_rtx (HImode);
8696 })
8697
8698 (define_insn_and_split "*ffshi2.libgcc_split"
8699 [(set (reg:HI 24)
8700 (ffs:HI (reg:HI 24)))
8701 (clobber (reg:QI 26))]
8702 ""
8703 "#"
8704 "&& reload_completed"
8705 [(parallel [(set (reg:HI 24)
8706 (ffs:HI (reg:HI 24)))
8707 (clobber (reg:QI 26))
8708 (clobber (reg:CC REG_CC))])])
8709
8710 (define_insn "*ffshi2.libgcc"
8711 [(set (reg:HI 24)
8712 (ffs:HI (reg:HI 24)))
8713 (clobber (reg:QI 26))
8714 (clobber (reg:CC REG_CC))]
8715 "reload_completed"
8716 "%~call __ffshi2"
8717 [(set_attr "type" "xcall")])
8718
8719 (define_insn_and_split "*ffssihi2.libgcc_split"
8720 [(set (reg:HI 24)
8721 (truncate:HI (ffs:SI (reg:SI 22))))
8722 (clobber (reg:QI 22))
8723 (clobber (reg:QI 26))]
8724 ""
8725 "#"
8726 "&& reload_completed"
8727 [(parallel [(set (reg:HI 24)
8728 (truncate:HI (ffs:SI (reg:SI 22))))
8729 (clobber (reg:QI 22))
8730 (clobber (reg:QI 26))
8731 (clobber (reg:CC REG_CC))])])
8732
8733 (define_insn "*ffssihi2.libgcc"
8734 [(set (reg:HI 24)
8735 (truncate:HI (ffs:SI (reg:SI 22))))
8736 (clobber (reg:QI 22))
8737 (clobber (reg:QI 26))
8738 (clobber (reg:CC REG_CC))]
8739 "reload_completed"
8740 "%~call __ffssi2"
8741 [(set_attr "type" "xcall")])
8742
8743 ;; Copysign
8744
8745 (define_insn "copysignsf3"
8746 [(set (match_operand:SF 0 "register_operand" "=r")
8747 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
8748 (match_operand:SF 2 "register_operand" "r")]
8749 UNSPEC_COPYSIGN))]
8750 ""
8751 "bst %D2,7\;bld %D0,7"
8752 [(set_attr "length" "2")])
8753
8754 ;; Swap Bytes (change byte-endianness)
8755
8756 (define_expand "bswapsi2"
8757 [(set (reg:SI 22)
8758 (match_operand:SI 1 "register_operand" ""))
8759 (set (reg:SI 22)
8760 (bswap:SI (reg:SI 22)))
8761 (set (match_operand:SI 0 "register_operand" "")
8762 (reg:SI 22))])
8763
8764 (define_insn_and_split "*bswapsi2.libgcc_split"
8765 [(set (reg:SI 22)
8766 (bswap:SI (reg:SI 22)))]
8767 ""
8768 "#"
8769 "&& reload_completed"
8770 [(parallel [(set (reg:SI 22)
8771 (bswap:SI (reg:SI 22)))
8772 (clobber (reg:CC REG_CC))])])
8773
8774 (define_insn "*bswapsi2.libgcc"
8775 [(set (reg:SI 22)
8776 (bswap:SI (reg:SI 22)))
8777 (clobber (reg:CC REG_CC))]
8778 "reload_completed"
8779 "%~call __bswapsi2"
8780 [(set_attr "type" "xcall")])
8781
8782
8783 ;; CPU instructions
8784
8785 ;; NOP taking 1 or 2 Ticks
8786 (define_expand "nopv"
8787 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
8788 UNSPECV_NOP)
8789 (set (match_dup 1)
8790 (unspec_volatile:BLK [(match_dup 1)]
8791 UNSPECV_MEMORY_BARRIER))])]
8792 ""
8793 {
8794 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8795 MEM_VOLATILE_P (operands[1]) = 1;
8796 })
8797
8798 (define_insn "*nopv"
8799 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
8800 UNSPECV_NOP)
8801 (set (match_operand:BLK 1 "" "")
8802 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
8803 ""
8804 "@
8805 nop
8806 rjmp ."
8807 [(set_attr "length" "1")])
8808
8809 ;; SLEEP
8810 (define_expand "sleep"
8811 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
8812 (set (match_dup 0)
8813 (unspec_volatile:BLK [(match_dup 0)]
8814 UNSPECV_MEMORY_BARRIER))])]
8815 ""
8816 {
8817 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8818 MEM_VOLATILE_P (operands[0]) = 1;
8819 })
8820
8821 (define_insn "*sleep"
8822 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
8823 (set (match_operand:BLK 0 "" "")
8824 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
8825 ""
8826 "sleep"
8827 [(set_attr "length" "1")])
8828
8829 ;; WDR
8830 (define_expand "wdr"
8831 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
8832 (set (match_dup 0)
8833 (unspec_volatile:BLK [(match_dup 0)]
8834 UNSPECV_MEMORY_BARRIER))])]
8835 ""
8836 {
8837 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8838 MEM_VOLATILE_P (operands[0]) = 1;
8839 })
8840
8841 (define_insn "*wdr"
8842 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
8843 (set (match_operand:BLK 0 "" "")
8844 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
8845 ""
8846 "wdr"
8847 [(set_attr "length" "1")])
8848
8849 ;; FMUL
8850 (define_expand "fmul"
8851 [(set (reg:QI 24)
8852 (match_operand:QI 1 "register_operand" ""))
8853 (set (reg:QI 25)
8854 (match_operand:QI 2 "register_operand" ""))
8855 (parallel [(set (reg:HI 22)
8856 (unspec:HI [(reg:QI 24)
8857 (reg:QI 25)] UNSPEC_FMUL))
8858 (clobber (reg:HI 24))])
8859 (set (match_operand:HI 0 "register_operand" "")
8860 (reg:HI 22))]
8861 ""
8862 {
8863 if (AVR_HAVE_MUL)
8864 {
8865 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
8866 DONE;
8867 }
8868 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
8869 })
8870
8871 (define_insn_and_split "fmul_insn"
8872 [(set (match_operand:HI 0 "register_operand" "=r")
8873 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8874 (match_operand:QI 2 "register_operand" "a")]
8875 UNSPEC_FMUL))]
8876 "AVR_HAVE_MUL"
8877 "#"
8878 "&& reload_completed"
8879 [(parallel [(set (match_dup 0)
8880 (unspec:HI [(match_dup 1)
8881 (match_dup 2)]
8882 UNSPEC_FMUL))
8883 (clobber (reg:CC REG_CC))])])
8884
8885 (define_insn "*fmul_insn"
8886 [(set (match_operand:HI 0 "register_operand" "=r")
8887 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8888 (match_operand:QI 2 "register_operand" "a")]
8889 UNSPEC_FMUL))
8890 (clobber (reg:CC REG_CC))]
8891 "AVR_HAVE_MUL && reload_completed"
8892 "fmul %1,%2
8893 movw %0,r0
8894 clr __zero_reg__"
8895 [(set_attr "length" "3")])
8896
8897 (define_insn_and_split "*fmul.call_split"
8898 [(set (reg:HI 22)
8899 (unspec:HI [(reg:QI 24)
8900 (reg:QI 25)] UNSPEC_FMUL))
8901 (clobber (reg:HI 24))]
8902 "!AVR_HAVE_MUL"
8903 "#"
8904 "&& reload_completed"
8905 [(parallel [(set (reg:HI 22)
8906 (unspec:HI [(reg:QI 24)
8907 (reg:QI 25)] UNSPEC_FMUL))
8908 (clobber (reg:HI 24))
8909 (clobber (reg:CC REG_CC))])])
8910
8911 (define_insn "*fmul.call"
8912 [(set (reg:HI 22)
8913 (unspec:HI [(reg:QI 24)
8914 (reg:QI 25)] UNSPEC_FMUL))
8915 (clobber (reg:HI 24))
8916 (clobber (reg:CC REG_CC))]
8917 "!AVR_HAVE_MUL && reload_completed"
8918 "%~call __fmul"
8919 [(set_attr "type" "xcall")])
8920
8921 ;; FMULS
8922 (define_expand "fmuls"
8923 [(set (reg:QI 24)
8924 (match_operand:QI 1 "register_operand" ""))
8925 (set (reg:QI 25)
8926 (match_operand:QI 2 "register_operand" ""))
8927 (parallel [(set (reg:HI 22)
8928 (unspec:HI [(reg:QI 24)
8929 (reg:QI 25)] UNSPEC_FMULS))
8930 (clobber (reg:HI 24))])
8931 (set (match_operand:HI 0 "register_operand" "")
8932 (reg:HI 22))]
8933 ""
8934 {
8935 if (AVR_HAVE_MUL)
8936 {
8937 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
8938 DONE;
8939 }
8940 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
8941 })
8942
8943 (define_insn_and_split "fmuls_insn"
8944 [(set (match_operand:HI 0 "register_operand" "=r")
8945 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8946 (match_operand:QI 2 "register_operand" "a")]
8947 UNSPEC_FMULS))]
8948 "AVR_HAVE_MUL"
8949 "#"
8950 "&& reload_completed"
8951 [(parallel [(set (match_dup 0)
8952 (unspec:HI [(match_dup 1)
8953 (match_dup 2)]
8954 UNSPEC_FMULS))
8955 (clobber (reg:CC REG_CC))])])
8956
8957 (define_insn "*fmuls_insn"
8958 [(set (match_operand:HI 0 "register_operand" "=r")
8959 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8960 (match_operand:QI 2 "register_operand" "a")]
8961 UNSPEC_FMULS))
8962 (clobber (reg:CC REG_CC))]
8963 "AVR_HAVE_MUL && reload_completed"
8964 "fmuls %1,%2
8965 movw %0,r0
8966 clr __zero_reg__"
8967 [(set_attr "length" "3")])
8968
8969 (define_insn_and_split "*fmuls.call_split"
8970 [(set (reg:HI 22)
8971 (unspec:HI [(reg:QI 24)
8972 (reg:QI 25)] UNSPEC_FMULS))
8973 (clobber (reg:HI 24))]
8974 "!AVR_HAVE_MUL"
8975 "#"
8976 "&& reload_completed"
8977 [(parallel [(set (reg:HI 22)
8978 (unspec:HI [(reg:QI 24)
8979 (reg:QI 25)] UNSPEC_FMULS))
8980 (clobber (reg:HI 24))
8981 (clobber (reg:CC REG_CC))])])
8982
8983 (define_insn "*fmuls.call"
8984 [(set (reg:HI 22)
8985 (unspec:HI [(reg:QI 24)
8986 (reg:QI 25)] UNSPEC_FMULS))
8987 (clobber (reg:HI 24))
8988 (clobber (reg:CC REG_CC))]
8989 "!AVR_HAVE_MUL && reload_completed"
8990 "%~call __fmuls"
8991 [(set_attr "type" "xcall")])
8992
8993 ;; FMULSU
8994 (define_expand "fmulsu"
8995 [(set (reg:QI 24)
8996 (match_operand:QI 1 "register_operand" ""))
8997 (set (reg:QI 25)
8998 (match_operand:QI 2 "register_operand" ""))
8999 (parallel [(set (reg:HI 22)
9000 (unspec:HI [(reg:QI 24)
9001 (reg:QI 25)] UNSPEC_FMULSU))
9002 (clobber (reg:HI 24))])
9003 (set (match_operand:HI 0 "register_operand" "")
9004 (reg:HI 22))]
9005 ""
9006 {
9007 if (AVR_HAVE_MUL)
9008 {
9009 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
9010 DONE;
9011 }
9012 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
9013 })
9014
9015 (define_insn_and_split "fmulsu_insn"
9016 [(set (match_operand:HI 0 "register_operand" "=r")
9017 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
9018 (match_operand:QI 2 "register_operand" "a")]
9019 UNSPEC_FMULSU))]
9020 "AVR_HAVE_MUL"
9021 "#"
9022 "&& reload_completed"
9023 [(parallel [(set (match_dup 0)
9024 (unspec:HI [(match_dup 1)
9025 (match_dup 2)]
9026 UNSPEC_FMULSU))
9027 (clobber (reg:CC REG_CC))])])
9028
9029 (define_insn "*fmulsu_insn"
9030 [(set (match_operand:HI 0 "register_operand" "=r")
9031 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
9032 (match_operand:QI 2 "register_operand" "a")]
9033 UNSPEC_FMULSU))
9034 (clobber (reg:CC REG_CC))]
9035 "AVR_HAVE_MUL && reload_completed"
9036 "fmulsu %1,%2
9037 movw %0,r0
9038 clr __zero_reg__"
9039 [(set_attr "length" "3")])
9040
9041 (define_insn_and_split "*fmulsu.call_split"
9042 [(set (reg:HI 22)
9043 (unspec:HI [(reg:QI 24)
9044 (reg:QI 25)] UNSPEC_FMULSU))
9045 (clobber (reg:HI 24))]
9046 "!AVR_HAVE_MUL"
9047 "#"
9048 "&& reload_completed"
9049 [(parallel [(set (reg:HI 22)
9050 (unspec:HI [(reg:QI 24)
9051 (reg:QI 25)] UNSPEC_FMULSU))
9052 (clobber (reg:HI 24))
9053 (clobber (reg:CC REG_CC))])])
9054
9055 (define_insn "*fmulsu.call"
9056 [(set (reg:HI 22)
9057 (unspec:HI [(reg:QI 24)
9058 (reg:QI 25)] UNSPEC_FMULSU))
9059 (clobber (reg:HI 24))
9060 (clobber (reg:CC REG_CC))]
9061 "!AVR_HAVE_MUL && reload_completed"
9062 "%~call __fmulsu"
9063 [(set_attr "type" "xcall")
9064 ])
9065
9066 \f
9067 ;; Some combiner patterns dealing with bits.
9068 ;; See PR42210
9069
9070 ;; Move bit $3.0 into bit $0.$4
9071 (define_insn "*movbitqi.1-6.a"
9072 [(set (match_operand:QI 0 "register_operand" "=r")
9073 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
9074 (match_operand:QI 2 "single_zero_operand" "n"))
9075 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
9076 (match_operand:QI 4 "const_0_to_7_operand" "n"))
9077 (match_operand:QI 5 "single_one_operand" "n"))))]
9078 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
9079 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
9080 "bst %3,0\;bld %0,%4"
9081 [(set_attr "length" "2")])
9082
9083 ;; Move bit $3.0 into bit $0.$4
9084 ;; Variation of above. Unfortunately, there is no canonicalized representation
9085 ;; of moving around bits. So what we see here depends on how user writes down
9086 ;; bit manipulations.
9087 (define_insn "*movbitqi.1-6.b"
9088 [(set (match_operand:QI 0 "register_operand" "=r")
9089 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
9090 (match_operand:QI 2 "single_zero_operand" "n"))
9091 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
9092 (const_int 1))
9093 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
9094 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
9095 "bst %3,0\;bld %0,%4"
9096 [(set_attr "length" "2")])
9097
9098 ;; Move bit $3.0 into bit $0.0.
9099 ;; For bit 0, combiner generates slightly different pattern.
9100 (define_insn "*movbitqi.0"
9101 [(set (match_operand:QI 0 "register_operand" "=r")
9102 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
9103 (match_operand:QI 2 "single_zero_operand" "n"))
9104 (and:QI (match_operand:QI 3 "register_operand" "r")
9105 (const_int 1))))]
9106 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
9107 "bst %3,0\;bld %0,0"
9108 [(set_attr "length" "2")])
9109
9110 ;; Move bit $2.0 into bit $0.7.
9111 ;; For bit 7, combiner generates slightly different pattern
9112 (define_insn "*movbitqi.7"
9113 [(set (match_operand:QI 0 "register_operand" "=r")
9114 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
9115 (const_int 127))
9116 (ashift:QI (match_operand:QI 2 "register_operand" "r")
9117 (const_int 7))))]
9118 ""
9119 "bst %2,0\;bld %0,7"
9120 [(set_attr "length" "2")])
9121
9122 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
9123 ;; and input/output match. We provide a special pattern for this, because
9124 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
9125 ;; operation on I/O is atomic.
9126 (define_insn "*insv.io"
9127 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i"))
9128 (const_int 1)
9129 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
9130 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
9131 ""
9132 "@
9133 cbi %i0,%1
9134 sbi %i0,%1
9135 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
9136 [(set_attr "length" "1,1,4")])
9137
9138 (define_insn "*insv.not.io"
9139 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i"))
9140 (const_int 1)
9141 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9142 (not:QI (match_operand:QI 2 "register_operand" "r")))]
9143 ""
9144 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
9145 [(set_attr "length" "4")])
9146
9147 ;; The insv expander.
9148 ;; We only support 1-bit inserts
9149 (define_expand "insv"
9150 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
9151 (match_operand:QI 1 "const1_operand" "") ; width
9152 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
9153 (match_operand:QI 3 "nonmemory_operand" ""))]
9154 "optimize")
9155
9156 ;; Some more patterns to support moving around one bit which can be accomplished
9157 ;; by BST + BLD in most situations. Unfortunately, there is no canonical
9158 ;; representation, and we just implement some more cases that are not too
9159 ;; complicated.
9160
9161 ;; Insert bit $2.0 into $0.$1
9162 (define_insn_and_split "*insv.reg_split"
9163 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
9164 (const_int 1)
9165 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
9166 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
9167 ""
9168 "#"
9169 "&& reload_completed"
9170 [(parallel [(set (zero_extract:QI (match_dup 0)
9171 (const_int 1)
9172 (match_dup 1))
9173 (match_dup 2))
9174 (clobber (reg:CC REG_CC))])])
9175
9176 (define_insn "*insv.reg"
9177 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
9178 (const_int 1)
9179 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
9180 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))
9181 (clobber (reg:CC REG_CC))]
9182 "reload_completed"
9183 "@
9184 bst %2,0\;bld %0,%1
9185 andi %0,lo8(~(1<<%1))
9186 ori %0,lo8(1<<%1)
9187 clt\;bld %0,%1
9188 set\;bld %0,%1"
9189 [(set_attr "length" "2,1,1,2,2")])
9190
9191 ;; Insert bit $2.$3 into $0.$1
9192 (define_insn "*insv.extract"
9193 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9194 (const_int 1)
9195 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9196 (any_extract:QI (match_operand:QI 2 "register_operand" "r")
9197 (const_int 1)
9198 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
9199 ""
9200 "bst %2,%3\;bld %0,%1"
9201 [(set_attr "length" "2")])
9202
9203 ;; Insert bit $2.$3 into $0.$1
9204 (define_insn "*insv.shiftrt"
9205 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9206 (const_int 1)
9207 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9208 (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
9209 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
9210 ""
9211 "bst %2,%3\;bld %0,%1"
9212 [(set_attr "length" "2")])
9213
9214 ;; Same, but with a NOT inverting the source bit.
9215 ;; Insert bit ~$2.$3 into $0.$1
9216 (define_insn_and_split "*insv.not-shiftrt_split"
9217 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9218 (const_int 1)
9219 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9220 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
9221 (match_operand:QI 3 "const_0_to_7_operand" "n"))))]
9222 ""
9223 "#"
9224 "&& reload_completed"
9225 [(parallel [(set (zero_extract:QI (match_dup 0)
9226 (const_int 1)
9227 (match_dup 1))
9228 (not:QI (any_shiftrt:QI (match_dup 2)
9229 (match_dup 3))))
9230 (clobber (reg:CC REG_CC))])])
9231
9232 (define_insn "*insv.not-shiftrt"
9233 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9234 (const_int 1)
9235 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9236 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
9237 (match_operand:QI 3 "const_0_to_7_operand" "n"))))
9238 (clobber (reg:CC REG_CC))]
9239 "reload_completed"
9240 {
9241 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
9242 }
9243 [(set_attr "adjust_len" "insv_notbit")])
9244
9245 ;; Insert bit ~$2.0 into $0.$1
9246 (define_insn_and_split "*insv.xor1-bit.0_split"
9247 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9248 (const_int 1)
9249 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9250 (xor:QI (match_operand:QI 2 "register_operand" "r")
9251 (const_int 1)))]
9252 ""
9253 "#"
9254 "&& reload_completed"
9255 [(parallel [(set (zero_extract:QI (match_dup 0)
9256 (const_int 1)
9257 (match_dup 1))
9258 (xor:QI (match_dup 2)
9259 (const_int 1)))
9260 (clobber (reg:CC REG_CC))])])
9261
9262 (define_insn "*insv.xor1-bit.0"
9263 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9264 (const_int 1)
9265 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9266 (xor:QI (match_operand:QI 2 "register_operand" "r")
9267 (const_int 1)))
9268 (clobber (reg:CC REG_CC))]
9269 "reload_completed"
9270 {
9271 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
9272 }
9273 [(set_attr "adjust_len" "insv_notbit_0")])
9274
9275 ;; Insert bit ~$2.0 into $0.$1
9276 (define_insn_and_split "*insv.not-bit.0_split"
9277 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9278 (const_int 1)
9279 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9280 (not:QI (match_operand:QI 2 "register_operand" "r")))]
9281 ""
9282 "#"
9283 "&& reload_completed"
9284 [(parallel [(set (zero_extract:QI (match_dup 0)
9285 (const_int 1)
9286 (match_dup 1))
9287 (not:QI (match_dup 2)))
9288 (clobber (reg:CC REG_CC))])])
9289
9290 (define_insn "*insv.not-bit.0"
9291 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9292 (const_int 1)
9293 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9294 (not:QI (match_operand:QI 2 "register_operand" "r")))
9295 (clobber (reg:CC REG_CC))]
9296 "reload_completed"
9297 {
9298 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
9299 }
9300 [(set_attr "adjust_len" "insv_notbit_0")])
9301
9302 ;; Insert bit ~$2.7 into $0.$1
9303 (define_insn_and_split "*insv.not-bit.7_split"
9304 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9305 (const_int 1)
9306 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9307 (ge:QI (match_operand:QI 2 "register_operand" "r")
9308 (const_int 0)))]
9309 ""
9310 "#"
9311 "&& reload_completed"
9312 [(parallel [(set (zero_extract:QI (match_dup 0)
9313 (const_int 1)
9314 (match_dup 1))
9315 (ge:QI (match_dup 2)
9316 (const_int 0)))
9317 (clobber (reg:CC REG_CC))])])
9318
9319 (define_insn "*insv.not-bit.7"
9320 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9321 (const_int 1)
9322 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9323 (ge:QI (match_operand:QI 2 "register_operand" "r")
9324 (const_int 0)))
9325 (clobber (reg:CC REG_CC))]
9326 "reload_completed"
9327 {
9328 return avr_out_insert_notbit (insn, operands, GEN_INT (7), NULL);
9329 }
9330 [(set_attr "adjust_len" "insv_notbit_7")])
9331
9332 ;; Insert bit ~$2.$3 into $0.$1
9333 (define_insn_and_split "*insv.xor-extract_split"
9334 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9335 (const_int 1)
9336 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9337 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r")
9338 (match_operand:QI 4 "const_int_operand" "n"))
9339 (const_int 1)
9340 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
9341 "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))"
9342 "#"
9343 "&& reload_completed"
9344 [(parallel [(set (zero_extract:QI (match_dup 0)
9345 (const_int 1)
9346 (match_dup 1))
9347 (any_extract:QI (xor:QI (match_dup 2)
9348 (match_dup 4))
9349 (const_int 1)
9350 (match_dup 3)))
9351 (clobber (reg:CC REG_CC))])])
9352
9353 (define_insn "*insv.xor-extract"
9354 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9355 (const_int 1)
9356 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9357 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r")
9358 (match_operand:QI 4 "const_int_operand" "n"))
9359 (const_int 1)
9360 (match_operand:QI 3 "const_0_to_7_operand" "n")))
9361 (clobber (reg:CC REG_CC))]
9362 "INTVAL (operands[4]) & (1 << INTVAL (operands[3])) && reload_completed"
9363 {
9364 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
9365 }
9366 [(set_attr "adjust_len" "insv_notbit")])
9367
9368 \f
9369 ;; Some combine patterns that try to fix bad code when a value is composed
9370 ;; from byte parts like in PR27663.
9371 ;; The patterns give some release but the code still is not optimal,
9372 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
9373 ;; That switch obfuscates things here and in many other places.
9374
9375 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
9376 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
9377 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
9378 [(set (match_operand:HISI 0 "register_operand" "=r")
9379 (xior:HISI
9380 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
9381 (match_operand:HISI 2 "register_operand" "0")))]
9382 ""
9383 "#"
9384 "reload_completed"
9385 [(set (match_dup 3)
9386 (xior:QI (match_dup 3)
9387 (match_dup 1)))]
9388 {
9389 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
9390 })
9391
9392 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
9393 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
9394 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
9395 [(set (match_operand:HISI 0 "register_operand" "=r")
9396 (xior:HISI
9397 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
9398 (match_operand:QI 2 "const_8_16_24_operand" "n"))
9399 (match_operand:HISI 3 "register_operand" "0")))]
9400 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
9401 "#"
9402 "&& reload_completed"
9403 [(set (match_dup 4)
9404 (xior:QI (match_dup 4)
9405 (match_dup 1)))]
9406 {
9407 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
9408 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
9409 })
9410
9411
9412 (define_insn_and_split "*iorhi3.ashift8-ext.zerox"
9413 [(set (match_operand:HI 0 "register_operand" "=r,r")
9414 (ior:HI (ashift:HI (any_extend:HI
9415 (match_operand:QI 1 "register_operand" "r,r"))
9416 (const_int 8))
9417 (zero_extend:HI (match_operand:QI 2 "register_operand" "0,r"))))]
9418 "optimize"
9419 { gcc_unreachable(); }
9420 "&& reload_completed"
9421 [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))
9422 (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1)))
9423 (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))]
9424 {
9425 rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9426 rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0);
9427
9428 if (!reg_overlap_mentioned_p (hi, operands[2]))
9429 {
9430 emit_move_insn (hi, operands[1]);
9431 emit_move_insn (lo, operands[2]);
9432 DONE;
9433 }
9434 else if (!reg_overlap_mentioned_p (lo, operands[1]))
9435 {
9436 emit_move_insn (lo, operands[2]);
9437 emit_move_insn (hi, operands[1]);
9438 DONE;
9439 }
9440
9441 gcc_assert (REGNO (operands[1]) == REGNO (operands[0]));
9442 gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0]));
9443 })
9444
9445 (define_insn_and_split "*iorhi3.ashift8-ext.reg"
9446 [(set (match_operand:HI 0 "register_operand" "=r")
9447 (ior:HI (ashift:HI (any_extend:HI
9448 (match_operand:QI 1 "register_operand" "r"))
9449 (const_int 8))
9450 (match_operand:HI 2 "register_operand" "0")))]
9451 "optimize"
9452 { gcc_unreachable(); }
9453 "&& reload_completed"
9454 [(set (match_dup 3)
9455 (ior:QI (match_dup 4)
9456 (match_dup 1)))]
9457 {
9458 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9459 operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1);
9460 })
9461
9462 (define_insn_and_split "*iorhi3.ashift8-reg.zerox"
9463 [(set (match_operand:HI 0 "register_operand" "=r")
9464 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
9465 (const_int 8))
9466 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))]
9467 "optimize"
9468 { gcc_unreachable(); }
9469 "&& reload_completed"
9470 [(set (match_dup 3)
9471 (match_dup 4))]
9472 {
9473 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9474 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
9475 })
9476
9477
9478 (define_peephole2
9479 [(parallel [(set (match_operand:QI 0 "register_operand")
9480 (const_int 0))
9481 (clobber (reg:CC REG_CC))])
9482 (parallel [(set (match_dup 0)
9483 (ior:QI (match_dup 0)
9484 (match_operand:QI 1 "register_operand")))
9485 (clobber (reg:CC REG_CC))])]
9486 ""
9487 [(parallel [(set (match_dup 0)
9488 (match_dup 1))
9489 (clobber (reg:CC REG_CC))])])
9490
9491
9492 (define_expand "extzv"
9493 [(set (match_operand:QI 0 "register_operand" "")
9494 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
9495 (match_operand:QI 2 "const1_operand" "")
9496 (match_operand:QI 3 "const_0_to_7_operand" "")))])
9497
9498 (define_insn_and_split "*extzv_split"
9499 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
9500 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
9501 (const_int 1)
9502 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
9503 ""
9504 "#"
9505 "&& reload_completed"
9506 [(parallel [(set (match_dup 0)
9507 (zero_extract:QI (match_dup 1)
9508 (const_int 1)
9509 (match_dup 2)))
9510 (clobber (reg:CC REG_CC))])])
9511
9512 (define_insn "*extzv"
9513 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
9514 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
9515 (const_int 1)
9516 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))
9517 (clobber (reg:CC REG_CC))]
9518 "reload_completed"
9519 "@
9520 andi %0,1
9521 mov %0,%1\;andi %0,1
9522 lsr %0\;andi %0,1
9523 swap %0\;andi %0,1
9524 bst %1,%2\;clr %0\;bld %0,0"
9525 [(set_attr "length" "1,2,2,2,3")])
9526
9527 (define_insn_and_split "*extzv.qihi1"
9528 [(set (match_operand:HI 0 "register_operand" "=r")
9529 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
9530 (const_int 1)
9531 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
9532 ""
9533 "#"
9534 ""
9535 [(set (match_dup 3)
9536 (zero_extract:QI (match_dup 1)
9537 (const_int 1)
9538 (match_dup 2)))
9539 (set (match_dup 4)
9540 (const_int 0))]
9541 {
9542 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
9543 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9544 })
9545
9546 (define_insn_and_split "*extzv.qihi2"
9547 [(set (match_operand:HI 0 "register_operand" "=r")
9548 (zero_extend:HI
9549 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
9550 (const_int 1)
9551 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
9552 ""
9553 "#"
9554 ""
9555 [(set (match_dup 3)
9556 (zero_extract:QI (match_dup 1)
9557 (const_int 1)
9558 (match_dup 2)))
9559 (set (match_dup 4)
9560 (const_int 0))]
9561 {
9562 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
9563 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9564 })
9565
9566 ;; ??? do_store_flag emits a hard-coded right shift to extract a bit without
9567 ;; even considering rtx_costs, extzv, or a bit-test. See PR 55181 for an example.
9568 (define_insn_and_split "*extract.subreg.bit"
9569 [(set (match_operand:QI 0 "register_operand" "=r")
9570 (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r")
9571 (match_operand:QI 2 "const_int_operand" "n"))
9572 0)
9573 (const_int 1)))]
9574 "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
9575 { gcc_unreachable(); }
9576 "&& reload_completed"
9577 [;; "*extzv"
9578 (set (match_dup 0)
9579 (zero_extract:QI (match_dup 3)
9580 (const_int 1)
9581 (match_dup 4)))]
9582 {
9583 int bitno = INTVAL (operands[2]);
9584 operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8);
9585 operands[4] = GEN_INT (bitno % 8);
9586 })
9587
9588 \f
9589 ;; Fixed-point instructions
9590 (include "avr-fixed.md")
9591
9592 ;; Operations on 64-bit registers
9593 (include "avr-dimode.md")