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