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