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