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