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