]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/avr/avr.md
re PR target/49868 (Implement named address space to place/access data in flash memory)
[thirdparty/gcc.git] / gcc / config / avr / avr.md
CommitLineData
90e7678c
DC
1;; Machine description for GNU compiler,
2;; for ATMEL AVR micro controllers.
5a82ecd9 3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
e2f00837 4;; 2009, 2010, 2011 Free Software Foundation, Inc.
92bffc14 5;; Contributed by Denis Chertykov (chertykov@gmail.com)
90e7678c 6
7ec022b2 7;; This file is part of GCC.
90e7678c 8
7ec022b2 9;; GCC is free software; you can redistribute it and/or modify
90e7678c 10;; it under the terms of the GNU General Public License as published by
2f83c7d6 11;; the Free Software Foundation; either version 3, or (at your option)
90e7678c
DC
12;; any later version.
13
7ec022b2 14;; GCC is distributed in the hope that it will be useful,
90e7678c
DC
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
20;; along with GCC; see the file COPYING3. If not see
21;; <http://www.gnu.org/licenses/>.
90e7678c 22
1d26ac96
MM
23;; Special characters after '%':
24;; A No effect (add 0).
25;; B Add 1 to REG number, MEM address or CONST_INT.
26;; C Add 2.
27;; D Add 3.
28;; j Branch condition.
29;; k Reverse branch condition.
846428f1 30;;..m..Constant Direct Data memory address.
1d26ac96 31;; o Displacement for (mem (plus (reg) (const_int))) operands.
a6990185
MM
32;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
33;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
846428f1 34;;..x..Constant Direct Program memory address.
5dc77808 35;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
693092fb 36;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
1d26ac96 37
2d67effa
DC
38
39(define_constants
40 [(REG_X 26)
41 (REG_Y 28)
42 (REG_Z 30)
43 (REG_W 24)
413fc59a 44 (REG_SP 32)
7c209481 45 (LPM_REGNO 0) ; implicit target register of LPM
2d67effa
DC
46 (TMP_REGNO 0) ; temporary register r0
47 (ZERO_REGNO 1) ; zero register r1
4fc2b4ff
AH
48
49 (SREG_ADDR 0x5F)
d6f77715 50 (RAMPZ_ADDR 0x5B)
43ea6502
AS
51 ])
52
53(define_c_enum "unspec"
54 [UNSPEC_STRLEN
55 UNSPEC_INDEX_JMP
56 UNSPEC_FMUL
57 UNSPEC_FMULS
58 UNSPEC_FMULSU
6130646b 59 UNSPEC_COPYSIGN
f3713778 60 UNSPEC_IDENTITY
43ea6502
AS
61 ])
62
63(define_c_enum "unspecv"
64 [UNSPECV_PROLOGUE_SAVES
65 UNSPECV_EPILOGUE_RESTORES
d702f362 66 UNSPECV_WRITE_SP
43ea6502
AS
67 UNSPECV_GOTO_RECEIVER
68 UNSPECV_ENABLE_IRQS
69 UNSPECV_NOP
70 UNSPECV_SLEEP
71 UNSPECV_WDR
72 UNSPECV_DELAY_CYCLES
73 ])
74
2d67effa 75
413fc59a 76(include "predicates.md")
2d67effa
DC
77(include "constraints.md")
78
90e7678c 79;; Condition code settings.
05058b6e 80(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
2f47b8d3 81 out_plus, out_plus_noclobber"
90e7678c
DC
82 (const_string "none"))
83
25f2e176 84(define_attr "type" "branch,branch1,arith,xcall"
90e7678c
DC
85 (const_string "arith"))
86
87;; The size of instructions in bytes.
88;; XXX may depend from "cc"
89
90(define_attr "length" ""
91 (cond [(eq_attr "type" "branch")
92 (if_then_else (and (ge (minus (pc) (match_dup 0))
93 (const_int -63))
94 (le (minus (pc) (match_dup 0))
95 (const_int 62)))
96 (const_int 1)
97 (if_then_else (and (ge (minus (pc) (match_dup 0))
98 (const_int -2045))
99 (le (minus (pc) (match_dup 0))
100 (const_int 2045)))
101 (const_int 2)
239b8b9d 102 (const_int 3)))
90e7678c
DC
103 (eq_attr "type" "branch1")
104 (if_then_else (and (ge (minus (pc) (match_dup 0))
105 (const_int -62))
106 (le (minus (pc) (match_dup 0))
107 (const_int 61)))
108 (const_int 2)
109 (if_then_else (and (ge (minus (pc) (match_dup 0))
110 (const_int -2044))
111 (le (minus (pc) (match_dup 0))
112 (const_int 2043)))
113 (const_int 3)
25f2e176
MM
114 (const_int 4)))
115 (eq_attr "type" "xcall")
7c3297ce 116 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
25f2e176
MM
117 (const_int 1)
118 (const_int 2))]
90e7678c
DC
119 (const_int 2)))
120
8dab2ba5
GJL
121;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
122;; Following insn attribute tells if and how the adjustment has to be
123;; done:
124;; no No adjustment needed; attribute "length" is fine.
8dab2ba5
GJL
125;; Otherwise do special processing depending on the attribute.
126
127(define_attr "adjust_len"
2f47b8d3 128 "out_bitop, out_plus, out_plus_noclobber, addto_sp,
e4fe948a
GJL
129 tsthi, tstpsi, tstsi, compare, call,
130 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
8a6a05ce
GJL
131 ashlqi, ashrqi, lshrqi,
132 ashlhi, ashrhi, lshrhi,
133 ashlsi, ashrsi, lshrsi,
e4fe948a 134 ashlpsi, ashrpsi, lshrpsi,
8a6a05ce
GJL
135 no"
136 (const_string "no"))
8dab2ba5 137
7c3297ce
GJL
138;; Flavours of instruction set architecture (ISA), used in enabled attribute
139
140;; mov: ISA has no MOVW
141;; movw: ISA has MOVW
142;; rjmp: ISA has no CALL/JMP
143;; jmp: ISA has CALL/JMP
144;; ijmp: ISA has no EICALL/EIJMP
145;; eijmp: ISA has EICALL/EIJMP
146
147(define_attr "isa"
148 "mov,movw, rjmp,jmp, ijmp,eijmp,
149 standard"
150 (const_string "standard"))
151
152(define_attr "enabled" ""
153 (cond [(eq_attr "isa" "standard")
154 (const_int 1)
155
156 (and (eq_attr "isa" "mov")
157 (match_test "!AVR_HAVE_MOVW"))
158 (const_int 1)
159
160 (and (eq_attr "isa" "movw")
161 (match_test "AVR_HAVE_MOVW"))
162 (const_int 1)
163
164 (and (eq_attr "isa" "rjmp")
165 (match_test "!AVR_HAVE_JMP_CALL"))
166 (const_int 1)
167
168 (and (eq_attr "isa" "jmp")
169 (match_test "AVR_HAVE_JMP_CALL"))
170 (const_int 1)
171
172 (and (eq_attr "isa" "ijmp")
173 (match_test "!AVR_HAVE_EIJMP_EICALL"))
174 (const_int 1)
175
176 (and (eq_attr "isa" "eijmp")
177 (match_test "AVR_HAVE_EIJMP_EICALL"))
178 (const_int 1)
179 ] (const_int 0)))
180
181
296799ba
GJL
182;; Define mode iterators
183(define_mode_iterator QIHI [(QI "") (HI "")])
184(define_mode_iterator QIHI2 [(QI "") (HI "")])
e4fe948a
GJL
185(define_mode_iterator QISI [(QI "") (HI "") (PSI "") (SI "")])
186(define_mode_iterator QIDI [(QI "") (HI "") (PSI "") (SI "") (DI "")])
187(define_mode_iterator HIDI [(HI "") (PSI "") (SI "") (DI "")])
188(define_mode_iterator HISI [(HI "") (PSI "") (SI "")])
189
190;; All supported move-modes
191(define_mode_iterator MOVMODE [(QI "") (HI "") (SI "") (SF "") (PSI "")])
3d709466 192
296799ba
GJL
193;; Define code iterators
194;; Define two incarnations so that we can build the cross product.
195(define_code_iterator any_extend [sign_extend zero_extend])
196(define_code_iterator any_extend2 [sign_extend zero_extend])
197
198;; Define code attributes
7ece3881 199(define_code_attr extend_su
296799ba
GJL
200 [(sign_extend "s")
201 (zero_extend "u")])
202
7ece3881
GJL
203(define_code_attr extend_u
204 [(sign_extend "")
205 (zero_extend "u")])
206
3e0cef6d
GJL
207(define_code_attr extend_s
208 [(sign_extend "s")
209 (zero_extend "")])
210
211;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
212(define_code_attr mul_r_d
213 [(zero_extend "r")
214 (sign_extend "d")])
215
296799ba 216
1bf29643
AH
217;;========================================================================
218;; The following is used by nonlocal_goto and setjmp.
219;; The receiver pattern will create no instructions since internally
220;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
221;; This avoids creating add/sub offsets in frame_pointer save/resore.
222;; The 'null' receiver also avoids problems with optimisation
223;; not recognising incoming jmp and removing code that resets frame_pointer.
224;; The code derived from builtins.c.
225
226(define_expand "nonlocal_goto_receiver"
227 [(set (reg:HI REG_Y)
228 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
229 ""
230 {
231 emit_move_insn (virtual_stack_vars_rtx,
232 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
233 gen_int_mode (STARTING_FRAME_OFFSET,
234 Pmode)));
235 /* This might change the hard frame pointer in ways that aren't
236 apparent to early optimization passes, so force a clobber. */
237 emit_clobber (hard_frame_pointer_rtx);
238 DONE;
239 })
240
241
242;; Defining nonlocal_goto_receiver means we must also define this.
243;; even though its function is identical to that in builtins.c
244
245(define_expand "nonlocal_goto"
246 [
247 (use (match_operand 0 "general_operand"))
248 (use (match_operand 1 "general_operand"))
249 (use (match_operand 2 "general_operand"))
250 (use (match_operand 3 "general_operand"))
251 ]
252 ""
253{
254 rtx r_label = copy_to_reg (operands[1]);
255 rtx r_fp = operands[3];
256 rtx r_sp = operands[2];
257
258 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
259
260 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
261
262 emit_move_insn (hard_frame_pointer_rtx, r_fp);
9eac0f2a 263 emit_stack_restore (SAVE_NONLOCAL, r_sp);
1bf29643
AH
264
265 emit_use (hard_frame_pointer_rtx);
266 emit_use (stack_pointer_rtx);
267
268 emit_indirect_jump (r_label);
269
270 DONE;
271})
272
172c08a5 273(define_insn "pushqi1"
bdfe906f 274 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
696e990b
AS
275 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
276 ""
90e7678c
DC
277 "@
278 push %0
279 push __zero_reg__"
280 [(set_attr "length" "1,1")])
281
172c08a5
RH
282;; All modes for a multi-byte push. We must include complex modes here too,
283;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
284(define_mode_iterator MPUSH
285 [(CQI "")
286 (HI "") (CHI "")
e4fe948a 287 (PSI "")
172c08a5
RH
288 (SI "") (CSI "")
289 (DI "") (CDI "")
290 (SF "") (SC "")])
291
292(define_expand "push<mode>1"
b7cef595 293 [(match_operand:MPUSH 0 "" "")]
90e7678c 294 ""
172c08a5
RH
295{
296 int i;
297 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
298 {
299 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
300 if (part != const0_rtx)
301 part = force_reg (QImode, part);
302 emit_insn (gen_pushqi1 (part));
303 }
304 DONE;
305})
90e7678c 306
a6365e99
RH
307;; Notice a special-case when adding N to SP where N results in a
308;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
309(define_split
310 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
311 "reload_completed
312 && frame_pointer_needed
313 && !cfun->calls_alloca
314 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
315 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
316 "")
317
e4fe948a 318;;========================================================================
7c209481
GJL
319;; Move stuff around
320
321(define_expand "load<mode>_libgcc"
322 [(set (match_dup 3)
323 (match_dup 2))
324 (set (reg:MOVMODE 22)
325 (match_operand:MOVMODE 1 "memory_operand" ""))
326 (set (match_operand:MOVMODE 0 "register_operand" "")
327 (reg:MOVMODE 22))]
328 "avr_load_libgcc_p (operands[1])"
329 {
330 operands[3] = gen_rtx_REG (HImode, REG_Z);
331 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
332 operands[1] = replace_equiv_address (operands[1], operands[3]);
333 set_mem_addr_space (operands[1], ADDR_SPACE_PGM);
334 })
335
336(define_insn "*load.<mode>.libgcc"
337 [(set (reg:MOVMODE 22)
338 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
339 "avr_load_libgcc_p (operands[0])
340 && REG_P (XEXP (operands[0], 0))
341 && REG_Z == REGNO (XEXP (operands[0], 0))"
342 {
343 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
344 return "%~call __load_%0";
345 }
346 [(set_attr "length" "1,2")
347 (set_attr "isa" "rjmp,jmp")
348 (set_attr "cc" "clobber")])
349
350
351;; General move expanders
e4fe948a
GJL
352
353;; "movqi"
354;; "movhi"
355;; "movsi"
356;; "movsf"
357;; "movpsi"
358
359(define_expand "mov<mode>"
360 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
361 (match_operand:MOVMODE 1 "general_operand" ""))]
362 ""
363 {
7c209481
GJL
364 rtx dest = operands[0];
365 rtx src = operands[1];
366
367 if (avr_mem_pgm_p (dest))
368 DONE;
369
370 /* One of the operands has to be in a register. */
371 if (!register_operand (dest, <MODE>mode)
372 && !(register_operand (src, <MODE>mode)
373 || src == CONST0_RTX (<MODE>mode)))
374 {
375 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
376 }
377
378 if (avr_load_libgcc_p (src))
e4fe948a 379 {
7c209481
GJL
380 /* For the small devices, do loads per libgcc call. */
381 emit_insn (gen_load<mode>_libgcc (dest, src));
382 DONE;
e4fe948a
GJL
383 }
384 })
385
90e7678c
DC
386;;========================================================================
387;; move byte
6bec29c9
DC
388;; The last alternative (any immediate constant to any register) is
389;; very expensive. It should be optimized by peephole2 if a scratch
390;; register is available, but then that register could just as well be
391;; allocated for the variable we are loading. But, most of NO_LD_REGS
392;; are call-saved registers, and most of LD_REGS are call-used registers,
393;; so this may still be a win for registers live across function calls.
394
9bc9ee67 395(define_insn "movqi_insn"
7c209481
GJL
396 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
397 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
398 "register_operand (operands[0], QImode)
399 || register_operand (operands[1], QImode)
400 || const0_rtx == operands[1]"
401 {
402 return output_movqi (insn, operands, NULL);
403 }
6bec29c9 404 [(set_attr "length" "1,1,5,5,1,1,4")
8a6a05ce 405 (set_attr "adjust_len" "mov8")
6bec29c9
DC
406 (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
407
408;; This is used in peephole2 to optimize loading immediate constants
409;; if a scratch register from LD_REGS happens to be available.
410
411(define_insn "*reload_inqi"
412 [(set (match_operand:QI 0 "register_operand" "=l")
413 (match_operand:QI 1 "immediate_operand" "i"))
414 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
afee2a52 415 "reload_completed"
6bec29c9
DC
416 "ldi %2,lo8(%1)
417 mov %0,%2"
418 [(set_attr "length" "2")
419 (set_attr "cc" "none")])
90e7678c 420
80b8585d
MM
421(define_peephole2
422 [(match_scratch:QI 2 "d")
413fc59a 423 (set (match_operand:QI 0 "l_register_operand" "")
80b8585d
MM
424 (match_operand:QI 1 "immediate_operand" ""))]
425 "(operands[1] != const0_rtx
413fc59a
AS
426 && operands[1] != const1_rtx
427 && operands[1] != constm1_rtx)"
80b8585d
MM
428 [(parallel [(set (match_dup 0) (match_dup 1))
429 (clobber (match_dup 2))])]
1cf0a7f1 430 "")
80b8585d 431
90e7678c
DC
432;;============================================================================
433;; move word (16 bit)
434
d702f362
GJL
435;; Move register $1 to the Stack Pointer register SP.
436;; This insn is emit during function prologue/epilogue generation.
437;; $2 = 0: We know that IRQs are off
438;; $2 = 1: We know that IRQs are on
439;; Remaining cases when the state of the I-Flag is unknown are
440;; handled by generic movhi insn.
441
442(define_insn "movhi_sp_r"
443 [(set (match_operand:HI 0 "stack_register_operand" "=q,q")
444 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r")
445 (match_operand:HI 2 "const_int_operand" "L,P")]
446 UNSPECV_WRITE_SP))]
794cb45e 447 ""
d702f362
GJL
448 "@
449 out __SP_H__,%B1\;out __SP_L__,%A1
450 cli\;out __SP_H__,%B1\;sei\;out __SP_L__,%A1"
451 [(set_attr "length" "2,4")
794cb45e
AS
452 (set_attr "cc" "none")])
453
6bec29c9
DC
454(define_peephole2
455 [(match_scratch:QI 2 "d")
413fc59a
AS
456 (set (match_operand:HI 0 "l_register_operand" "")
457 (match_operand:HI 1 "immediate_operand" ""))]
458 "(operands[1] != const0_rtx
459 && operands[1] != constm1_rtx)"
6bec29c9
DC
460 [(parallel [(set (match_dup 0) (match_dup 1))
461 (clobber (match_dup 2))])]
1cf0a7f1 462 "")
6bec29c9
DC
463
464;; '*' because it is not used in rtl generation, only in above peephole
465(define_insn "*reload_inhi"
466 [(set (match_operand:HI 0 "register_operand" "=r")
467 (match_operand:HI 1 "immediate_operand" "i"))
468 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
afee2a52 469 "reload_completed"
20633efc
GJL
470 {
471 return output_reload_inhi (operands, operands[2], NULL);
472 }
6bec29c9 473 [(set_attr "length" "4")
20633efc 474 (set_attr "adjust_len" "reload_in16")
6bec29c9
DC
475 (set_attr "cc" "none")])
476
90e7678c 477(define_insn "*movhi"
7c209481
GJL
478 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
479 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
480 "register_operand (operands[0], HImode)
481 || register_operand (operands[1], HImode)
482 || const0_rtx == operands[1]"
483 {
484 return output_movhi (insn, operands, NULL);
485 }
20633efc 486 [(set_attr "length" "2,2,6,7,2,6,5,2")
8a6a05ce 487 (set_attr "adjust_len" "mov16")
20633efc 488 (set_attr "cc" "none,clobber,clobber,clobber,none,clobber,none,none")])
90e7678c 489
d54a92b5
AS
490(define_peephole2 ; movw
491 [(set (match_operand:QI 0 "even_register_operand" "")
492 (match_operand:QI 1 "even_register_operand" ""))
493 (set (match_operand:QI 2 "odd_register_operand" "")
494 (match_operand:QI 3 "odd_register_operand" ""))]
495 "(AVR_HAVE_MOVW
496 && REGNO (operands[0]) == REGNO (operands[2]) - 1
497 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
498 [(set (match_dup 4) (match_dup 5))]
499 {
500 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
501 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
502 })
503
504(define_peephole2 ; movw_r
505 [(set (match_operand:QI 0 "odd_register_operand" "")
506 (match_operand:QI 1 "odd_register_operand" ""))
507 (set (match_operand:QI 2 "even_register_operand" "")
508 (match_operand:QI 3 "even_register_operand" ""))]
509 "(AVR_HAVE_MOVW
510 && REGNO (operands[2]) == REGNO (operands[0]) - 1
511 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
512 [(set (match_dup 4) (match_dup 5))]
513 {
514 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
515 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
516 })
517
7c209481
GJL
518;; For LPM loads from AS1 we split
519;; R = *Z
520;; to
521;; R = *Z++
522;; Z = Z - sizeof (R)
523;;
524;; so that the second instruction can be optimized out.
525
526(define_split ; "split-lpmx"
527 [(set (match_operand:HISI 0 "register_operand" "")
528 (match_operand:HISI 1 "memory_operand" ""))]
529 "reload_completed
530 && AVR_HAVE_LPMX"
531 [(set (match_dup 0)
532 (match_dup 2))
533 (set (match_dup 3)
534 (plus:HI (match_dup 3)
535 (match_dup 4)))]
536 {
537 rtx addr = XEXP (operands[1], 0);
538
539 if (!avr_mem_pgm_p (operands[1])
540 || !REG_P (addr)
541 || reg_overlap_mentioned_p (addr, operands[0]))
542 {
543 FAIL;
544 }
545
546 operands[2] = replace_equiv_address (operands[1],
547 gen_rtx_POST_INC (Pmode, addr));
548 operands[3] = addr;
549 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
550 })
551
90e7678c 552;;==========================================================================
e4fe948a
GJL
553;; xpointer move (24 bit)
554
555(define_peephole2 ; *reload_inpsi
556 [(match_scratch:QI 2 "d")
557 (set (match_operand:PSI 0 "l_register_operand" "")
558 (match_operand:PSI 1 "immediate_operand" ""))
559 (match_dup 2)]
560 "operands[1] != const0_rtx
561 && operands[1] != constm1_rtx"
562 [(parallel [(set (match_dup 0)
563 (match_dup 1))
564 (clobber (match_dup 2))])]
565 "")
566
567;; '*' because it is not used in rtl generation.
568(define_insn "*reload_inpsi"
569 [(set (match_operand:PSI 0 "register_operand" "=r")
570 (match_operand:PSI 1 "immediate_operand" "i"))
571 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
572 "reload_completed"
573 {
574 return avr_out_reload_inpsi (operands, operands[2], NULL);
575 }
576 [(set_attr "length" "6")
577 (set_attr "adjust_len" "reload_in24")
578 (set_attr "cc" "clobber")])
6bec29c9 579
e4fe948a
GJL
580(define_insn "*movpsi"
581 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
7c209481 582 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
e4fe948a
GJL
583 "register_operand (operands[0], PSImode)
584 || register_operand (operands[1], PSImode)
585 || const0_rtx == operands[1]"
586 {
587 return avr_out_movpsi (insn, operands, NULL);
588 }
589 [(set_attr "length" "3,3,8,9,4,10")
590 (set_attr "adjust_len" "mov24")
591 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
592
593;;==========================================================================
594;; move double word (32 bit)
6bec29c9 595
1e6a67d1 596(define_peephole2 ; *reload_insi
6bec29c9 597 [(match_scratch:QI 2 "d")
413fc59a 598 (set (match_operand:SI 0 "l_register_operand" "")
1e6a67d1 599 (match_operand:SI 1 "const_int_operand" ""))
6ff5d1e4 600 (match_dup 2)]
6bec29c9 601 "(operands[1] != const0_rtx
413fc59a 602 && operands[1] != constm1_rtx)"
6bec29c9
DC
603 [(parallel [(set (match_dup 0) (match_dup 1))
604 (clobber (match_dup 2))])]
1cf0a7f1 605 "")
6bec29c9
DC
606
607;; '*' because it is not used in rtl generation.
608(define_insn "*reload_insi"
609 [(set (match_operand:SI 0 "register_operand" "=r")
1e6a67d1 610 (match_operand:SI 1 "const_int_operand" "n"))
6bec29c9 611 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
afee2a52 612 "reload_completed"
1e6a67d1 613 {
8a6a05ce 614 return output_reload_insisf (operands, operands[2], NULL);
1e6a67d1 615 }
6bec29c9 616 [(set_attr "length" "8")
8dab2ba5 617 (set_attr "adjust_len" "reload_in32")
1e6a67d1 618 (set_attr "cc" "clobber")])
6bec29c9
DC
619
620
90e7678c 621(define_insn "*movsi"
7c209481
GJL
622 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
623 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
624 "register_operand (operands[0], SImode)
625 || register_operand (operands[1], SImode)
626 || const0_rtx == operands[1]"
1e6a67d1 627 {
8dab2ba5 628 return output_movsisf (insn, operands, NULL);
1e6a67d1 629 }
dfaf5abf 630 [(set_attr "length" "4,4,8,9,4,10")
8a6a05ce 631 (set_attr "adjust_len" "mov32")
1e6a67d1 632 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
90e7678c
DC
633
634;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
635;; move floating point numbers (32 bit)
636
90e7678c 637(define_insn "*movsf"
7c209481
GJL
638 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
639 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
90e7678c 640 "register_operand (operands[0], SFmode)
1e6a67d1
GJL
641 || register_operand (operands[1], SFmode)
642 || operands[1] == CONST0_RTX (SFmode)"
643 {
8dab2ba5 644 return output_movsisf (insn, operands, NULL);
1e6a67d1 645 }
dfaf5abf 646 [(set_attr "length" "4,4,8,9,4,10")
8a6a05ce 647 (set_attr "adjust_len" "mov32")
1e6a67d1
GJL
648 (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
649
650(define_peephole2 ; *reload_insf
651 [(match_scratch:QI 2 "d")
652 (set (match_operand:SF 0 "l_register_operand" "")
653 (match_operand:SF 1 "const_double_operand" ""))
654 (match_dup 2)]
655 "operands[1] != CONST0_RTX (SFmode)"
656 [(parallel [(set (match_dup 0)
657 (match_dup 1))
658 (clobber (match_dup 2))])]
659 "")
660
661;; '*' because it is not used in rtl generation.
662(define_insn "*reload_insf"
663 [(set (match_operand:SF 0 "register_operand" "=r")
664 (match_operand:SF 1 "const_double_operand" "F"))
665 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
666 "reload_completed"
667 {
8a6a05ce 668 return output_reload_insisf (operands, operands[2], NULL);
1e6a67d1
GJL
669 }
670 [(set_attr "length" "8")
8dab2ba5 671 (set_attr "adjust_len" "reload_in32")
1e6a67d1 672 (set_attr "cc" "clobber")])
90e7678c
DC
673
674;;=========================================================================
675;; move string (like memcpy)
6bbaec09 676;; implement as RTL loop
90e7678c 677
70128ad9 678(define_expand "movmemhi"
90e7678c 679 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6bbaec09
AH
680 (match_operand:BLK 1 "memory_operand" ""))
681 (use (match_operand:HI 2 "const_int_operand" ""))
682 (use (match_operand:HI 3 "const_int_operand" ""))])]
90e7678c
DC
683 ""
684 "{
6bbaec09
AH
685 int prob;
686 HOST_WIDE_INT count;
a9738643 687 enum machine_mode mode;
6bbaec09
AH
688 rtx label = gen_label_rtx ();
689 rtx loop_reg;
7c209481 690 rtx jump, src;
6bbaec09
AH
691
692 /* Copy pointers into new psuedos - they will be changed. */
693 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
694 rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
695
696 /* Create rtx for tmp register - we use this as scratch. */
697 rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
90e7678c 698
7c209481
GJL
699 if (avr_mem_pgm_p (operands[0]))
700 DONE;
701
90e7678c
DC
702 if (GET_CODE (operands[2]) != CONST_INT)
703 FAIL;
90e7678c 704
6bbaec09
AH
705 count = INTVAL (operands[2]);
706 if (count <= 0)
707 FAIL;
708
709 /* Work out branch probability for latter use. */
710 prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
711
712 /* See if constant fit 8 bits. */
713 mode = (count < 0x100) ? QImode : HImode;
714 /* Create loop counter register. */
715 loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
716
717 /* Now create RTL code for move loop. */
718 /* Label at top of loop. */
719 emit_label (label);
720
721 /* Move one byte into scratch and inc pointer. */
7c209481
GJL
722 src = gen_rtx_MEM (QImode, addr1);
723 set_mem_addr_space (src, MEM_ADDR_SPACE (operands[1]));
724 emit_move_insn (tmp_reg_rtx, src);
6bbaec09
AH
725 emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
726
727 /* Move to mem and inc pointer. */
728 emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
729 emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
730
731 /* Decrement count. */
732 emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
733
734 /* Compare with zero and jump if not equal. */
735 emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
736 label);
737 /* Set jump probability based on loop count. */
738 jump = get_last_insn ();
5a82ecd9 739 add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
6bbaec09
AH
740 DONE;
741}")
90e7678c 742
57e84f18
AS
743;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
744;; memset (%0, %2, %1)
90e7678c 745
57e84f18 746(define_expand "setmemhi"
90e7678c 747 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
57e84f18 748 (match_operand 2 "const_int_operand" ""))
90e7678c 749 (use (match_operand:HI 1 "const_int_operand" ""))
57e84f18
AS
750 (use (match_operand:HI 3 "const_int_operand" "n"))
751 (clobber (match_scratch:HI 4 ""))
752 (clobber (match_dup 5))])]
90e7678c
DC
753 ""
754 "{
755 rtx addr0;
a9738643 756 enum machine_mode mode;
90e7678c 757
57e84f18
AS
758 /* If value to set is not zero, use the library routine. */
759 if (operands[2] != const0_rtx)
760 FAIL;
761
c331eabe 762 if (!CONST_INT_P (operands[1]))
90e7678c
DC
763 FAIL;
764
c331eabe 765 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
57e84f18 766 operands[5] = gen_rtx_SCRATCH (mode);
a9738643
DC
767 operands[1] = copy_to_mode_reg (mode,
768 gen_int_mode (INTVAL (operands[1]), mode));
90e7678c 769 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
f1c25d3b 770 operands[0] = gen_rtx_MEM (BLKmode, addr0);
90e7678c
DC
771}")
772
70128ad9 773(define_insn "*clrmemqi"
90e7678c
DC
774 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
775 (const_int 0))
776 (use (match_operand:QI 1 "register_operand" "r"))
777 (use (match_operand:QI 2 "const_int_operand" "n"))
3f1f9228 778 (clobber (match_scratch:HI 3 "=0"))
ee57a661 779 (clobber (match_scratch:QI 4 "=&1"))]
90e7678c 780 ""
1ca04dc8 781 "st %a0+,__zero_reg__
90e7678c 782 dec %1
13e8651c 783 brne .-6"
90e7678c
DC
784 [(set_attr "length" "3")
785 (set_attr "cc" "clobber")])
786
70128ad9 787(define_insn "*clrmemhi"
90e7678c
DC
788 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
789 (const_int 0))
790 (use (match_operand:HI 1 "register_operand" "!w,d"))
791 (use (match_operand:HI 2 "const_int_operand" "n,n"))
3f1f9228 792 (clobber (match_scratch:HI 3 "=0,0"))
ee57a661 793 (clobber (match_scratch:HI 4 "=&1,&1"))]
90e7678c
DC
794 ""
795 "*{
796 if (which_alternative==0)
797 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
798 AS2 (sbiw,%A1,1) CR_TAB
13e8651c 799 AS1 (brne,.-6));
90e7678c
DC
800 else
801 return (AS2 (st,%a0+,__zero_reg__) CR_TAB
802 AS2 (subi,%A1,1) CR_TAB
803 AS2 (sbci,%B1,0) CR_TAB
13e8651c 804 AS1 (brne,.-8));
90e7678c
DC
805}"
806 [(set_attr "length" "3,4")
807 (set_attr "cc" "clobber,clobber")])
808
809(define_expand "strlenhi"
48ccfb40
DC
810 [(set (match_dup 4)
811 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
812 (match_operand:QI 2 "const_int_operand" "")
2d67effa
DC
813 (match_operand:HI 3 "immediate_operand" "")]
814 UNSPEC_STRLEN))
90e7678c
DC
815 (set (match_dup 4) (plus:HI (match_dup 4)
816 (const_int -1)))
817 (set (match_operand:HI 0 "register_operand" "")
818 (minus:HI (match_dup 4)
819 (match_dup 5)))]
820 ""
821 "{
63eaee71 822 rtx addr;
c331eabe 823 if (operands[2] != const0_rtx)
90e7678c 824 FAIL;
63eaee71 825 addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
f1c25d3b 826 operands[1] = gen_rtx_MEM (BLKmode, addr);
63eaee71 827 operands[5] = addr;
90e7678c
DC
828 operands[4] = gen_reg_rtx (HImode);
829}")
830
831(define_insn "*strlenhi"
832 [(set (match_operand:HI 0 "register_operand" "=e")
833 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
834 (const_int 0)
2d67effa
DC
835 (match_operand:HI 2 "immediate_operand" "i")]
836 UNSPEC_STRLEN))]
90e7678c
DC
837 ""
838 "ld __tmp_reg__,%a0+
839 tst __tmp_reg__
13e8651c 840 brne .-6"
90e7678c
DC
841 [(set_attr "length" "3")
842 (set_attr "cc" "clobber")])
843
844;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
845; add bytes
846
847(define_insn "addqi3"
8b42d3de
GJL
848 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
849 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
850 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
90e7678c
DC
851 ""
852 "@
853 add %0,%2
854 subi %0,lo8(-(%2))
855 inc %0
8b42d3de
GJL
856 dec %0
857 inc %0\;inc %0
858 dec %0\;dec %0"
859 [(set_attr "length" "1,1,1,1,2,2")
860 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
90e7678c
DC
861
862
863(define_expand "addhi3"
864 [(set (match_operand:HI 0 "register_operand" "")
865 (plus:HI (match_operand:HI 1 "register_operand" "")
866 (match_operand:HI 2 "nonmemory_operand" "")))]
867 ""
2f47b8d3
GJL
868 {
869 if (CONST_INT_P (operands[2]))
870 {
871 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
872
873 if (can_create_pseudo_p()
874 && !stack_register_operand (operands[0], HImode)
875 && !stack_register_operand (operands[1], HImode)
876 && !d_register_operand (operands[0], HImode)
877 && !d_register_operand (operands[1], HImode))
878 {
879 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
880 DONE;
881 }
882 }
883 })
90e7678c
DC
884
885
886(define_insn "*addhi3_zero_extend"
f1f59bc7
GJL
887 [(set (match_operand:HI 0 "register_operand" "=r")
888 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
889 (match_operand:HI 2 "register_operand" "0")))]
90e7678c 890 ""
f1f59bc7 891 "add %A0,%1\;adc %B0,__zero_reg__"
90e7678c
DC
892 [(set_attr "length" "2")
893 (set_attr "cc" "set_n")])
894
895(define_insn "*addhi3_zero_extend1"
f1f59bc7
GJL
896 [(set (match_operand:HI 0 "register_operand" "=r")
897 (plus:HI (match_operand:HI 1 "register_operand" "0")
898 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
90e7678c 899 ""
f1f59bc7 900 "add %A0,%2\;adc %B0,__zero_reg__"
90e7678c
DC
901 [(set_attr "length" "2")
902 (set_attr "cc" "set_n")])
903
f1f59bc7
GJL
904(define_insn "*addhi3.sign_extend1"
905 [(set (match_operand:HI 0 "register_operand" "=r")
906 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
907 (match_operand:HI 2 "register_operand" "0")))]
908 ""
909 {
910 return reg_overlap_mentioned_p (operands[0], operands[1])
911 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
912 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
913 }
914 [(set_attr "length" "5")
915 (set_attr "cc" "clobber")])
916
d702f362
GJL
917(define_insn "*addhi3_sp"
918 [(set (match_operand:HI 1 "stack_register_operand" "=q")
919 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
920 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
180ee6d1
GJL
921 ""
922 {
923 return avr_out_addto_sp (operands, NULL);
924 }
d702f362 925 [(set_attr "length" "6")
180ee6d1 926 (set_attr "adjust_len" "addto_sp")])
4fc2b4ff 927
90e7678c 928(define_insn "*addhi3"
2f47b8d3
GJL
929 [(set (match_operand:HI 0 "register_operand" "=r,d,d")
930 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
931 (match_operand:HI 2 "nonmemory_operand" "r,s,n")))]
90e7678c 932 ""
2f47b8d3
GJL
933 {
934 static const char * const asm_code[] =
935 {
936 "add %A0,%A2\;adc %B0,%B2",
937 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
938 ""
939 };
940
941 if (*asm_code[which_alternative])
942 return asm_code[which_alternative];
943
944 return avr_out_plus_noclobber (operands, NULL, NULL);
945 }
946 [(set_attr "length" "2,2,2")
947 (set_attr "adjust_len" "*,*,out_plus_noclobber")
948 (set_attr "cc" "set_n,set_czn,out_plus_noclobber")])
949
950;; Adding a constant to NO_LD_REGS might have lead to a reload of
951;; that constant to LD_REGS. We don't add a scratch to *addhi3
952;; itself because that insn is special to reload.
953
954(define_peephole2 ; addhi3_clobber
955 [(set (match_operand:HI 0 "d_register_operand" "")
956 (match_operand:HI 1 "const_int_operand" ""))
957 (set (match_operand:HI 2 "l_register_operand" "")
958 (plus:HI (match_dup 2)
959 (match_dup 0)))]
960 "peep2_reg_dead_p (2, operands[0])"
961 [(parallel [(set (match_dup 2)
962 (plus:HI (match_dup 2)
963 (match_dup 1)))
964 (clobber (match_dup 3))])]
965 {
966 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
967 })
968
969;; Same, but with reload to NO_LD_REGS
970;; Combine *reload_inhi with *addhi3
971
972(define_peephole2 ; addhi3_clobber
973 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
974 (match_operand:HI 1 "const_int_operand" ""))
975 (clobber (match_operand:QI 2 "d_register_operand" ""))])
976 (set (match_operand:HI 3 "l_register_operand" "")
977 (plus:HI (match_dup 3)
978 (match_dup 0)))]
979 "peep2_reg_dead_p (2, operands[0])"
980 [(parallel [(set (match_dup 3)
981 (plus:HI (match_dup 3)
982 (match_dup 1)))
983 (clobber (match_dup 2))])])
984
985(define_insn "addhi3_clobber"
986 [(set (match_operand:HI 0 "register_operand" "=d,l")
987 (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
988 (match_operand:HI 2 "const_int_operand" "n,n")))
989 (clobber (match_scratch:QI 3 "=X,&d"))]
990 ""
991 {
992 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
993
994 return avr_out_plus (operands, NULL, NULL);
995 }
996 [(set_attr "length" "4")
997 (set_attr "adjust_len" "out_plus")
998 (set_attr "cc" "out_plus")])
999
90e7678c
DC
1000
1001(define_insn "addsi3"
05058b6e
GJL
1002 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1003 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1004 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1005 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
90e7678c 1006 ""
59024515
GJL
1007 {
1008 static const char * const asm_code[] =
1009 {
1010 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
59024515 1011 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
05058b6e
GJL
1012 "",
1013 ""
59024515
GJL
1014 };
1015
05058b6e
GJL
1016 if (*asm_code[which_alternative])
1017 return asm_code [which_alternative];
59024515 1018
05058b6e 1019 return avr_out_plus (operands, NULL, NULL);
59024515 1020 }
05058b6e
GJL
1021 [(set_attr "length" "4,4,4,8")
1022 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1023 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
90e7678c 1024
e4fe948a
GJL
1025(define_insn "*addpsi3_zero_extend.qi"
1026 [(set (match_operand:PSI 0 "register_operand" "=r")
1027 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1028 (match_operand:PSI 2 "register_operand" "0")))]
1029 ""
1030 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1031 [(set_attr "length" "3")
1032 (set_attr "cc" "set_n")])
1033
1034(define_insn "*addpsi3_zero_extend.hi"
1035 [(set (match_operand:PSI 0 "register_operand" "=r")
1036 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1037 (match_operand:PSI 2 "register_operand" "0")))]
1038 ""
1039 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1040 [(set_attr "length" "3")
1041 (set_attr "cc" "set_n")])
1042
1043(define_insn "*addpsi3_sign_extend.hi"
1044 [(set (match_operand:PSI 0 "register_operand" "=r")
1045 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1046 (match_operand:PSI 2 "register_operand" "0")))]
1047 ""
1048 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1049 [(set_attr "length" "5")
1050 (set_attr "cc" "set_n")])
1051
e2ec05a6 1052(define_insn "*addsi3_zero_extend"
59024515
GJL
1053 [(set (match_operand:SI 0 "register_operand" "=r")
1054 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1055 (match_operand:SI 2 "register_operand" "0")))]
e2ec05a6 1056 ""
59024515
GJL
1057 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1058 [(set_attr "length" "4")
1059 (set_attr "cc" "set_n")])
1060
1061(define_insn "*addsi3_zero_extend.hi"
1062 [(set (match_operand:SI 0 "register_operand" "=r")
1063 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1064 (match_operand:SI 2 "register_operand" "0")))]
1065 ""
1066 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
e2ec05a6
TG
1067 [(set_attr "length" "4")
1068 (set_attr "cc" "set_n")])
1069
e4fe948a
GJL
1070(define_insn "addpsi3"
1071 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1072 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1073 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1074 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1075 ""
1076 {
1077 static const char * const asm_code[] =
1078 {
1079 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1080 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1081 "",
1082 ""
1083 };
1084
1085 if (*asm_code[which_alternative])
1086 return asm_code [which_alternative];
1087
1088 return avr_out_plus (operands, NULL, NULL);
1089 }
1090 [(set_attr "length" "3,3,3,6")
1091 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1092 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1093
1094(define_insn "subpsi3"
1095 [(set (match_operand:PSI 0 "register_operand" "=r")
1096 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1097 (match_operand:PSI 2 "register_operand" "r")))]
1098 ""
1099 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1100 [(set_attr "length" "3")
1101 (set_attr "cc" "set_czn")])
1102
1103(define_insn "*subpsi3_zero_extend.qi"
1104 [(set (match_operand:PSI 0 "register_operand" "=r")
1105 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1106 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1107 ""
1108 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1109 [(set_attr "length" "3")
1110 (set_attr "cc" "set_czn")])
1111
1112(define_insn "*subpsi3_zero_extend.hi"
1113 [(set (match_operand:PSI 0 "register_operand" "=r")
1114 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1115 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1116 ""
1117 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1118 [(set_attr "length" "3")
1119 (set_attr "cc" "set_czn")])
1120
1121(define_insn "*subpsi3_sign_extend.hi"
1122 [(set (match_operand:PSI 0 "register_operand" "=r")
1123 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1124 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1125 ""
1126 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1127 [(set_attr "length" "5")
1128 (set_attr "cc" "set_czn")])
1129
90e7678c
DC
1130;-----------------------------------------------------------------------------
1131; sub bytes
1132(define_insn "subqi3"
1133 [(set (match_operand:QI 0 "register_operand" "=r,d")
1134 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1135 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1136 ""
1137 "@
1138 sub %0,%2
1139 subi %0,lo8(%2)"
1140 [(set_attr "length" "1,1")
1141 (set_attr "cc" "set_czn,set_czn")])
1142
1143(define_insn "subhi3"
1144 [(set (match_operand:HI 0 "register_operand" "=r,d")
1145 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1146 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1147 ""
1148 "@
1149 sub %A0,%A2\;sbc %B0,%B2
1150 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1151 [(set_attr "length" "2,2")
1152 (set_attr "cc" "set_czn,set_czn")])
1153
e2ec05a6 1154(define_insn "*subhi3_zero_extend1"
59024515
GJL
1155 [(set (match_operand:HI 0 "register_operand" "=r")
1156 (minus:HI (match_operand:HI 1 "register_operand" "0")
1157 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
e2ec05a6 1158 ""
59024515 1159 "sub %A0,%2\;sbc %B0,__zero_reg__"
e2ec05a6 1160 [(set_attr "length" "2")
59024515 1161 (set_attr "cc" "set_czn")])
e2ec05a6 1162
f1f59bc7
GJL
1163(define_insn "*subhi3.sign_extend2"
1164 [(set (match_operand:HI 0 "register_operand" "=r")
1165 (minus:HI (match_operand:HI 1 "register_operand" "0")
1166 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1167 ""
1168 {
1169 return reg_overlap_mentioned_p (operands[0], operands[2])
1170 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1171 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1172 }
1173 [(set_attr "length" "5")
1174 (set_attr "cc" "clobber")])
1175
90e7678c 1176(define_insn "subsi3"
59024515
GJL
1177 [(set (match_operand:SI 0 "register_operand" "=r")
1178 (minus:SI (match_operand:SI 1 "register_operand" "0")
1179 (match_operand:SI 2 "register_operand" "r")))]
90e7678c 1180 ""
59024515
GJL
1181 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1182 [(set_attr "length" "4")
1183 (set_attr "cc" "set_czn")])
90e7678c 1184
e2ec05a6 1185(define_insn "*subsi3_zero_extend"
59024515
GJL
1186 [(set (match_operand:SI 0 "register_operand" "=r")
1187 (minus:SI (match_operand:SI 1 "register_operand" "0")
1188 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1189 ""
1190 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
e2ec05a6 1191 [(set_attr "length" "4")
59024515
GJL
1192 (set_attr "cc" "set_czn")])
1193
1194(define_insn "*subsi3_zero_extend.hi"
1195 [(set (match_operand:SI 0 "register_operand" "=r")
1196 (minus:SI (match_operand:SI 1 "register_operand" "0")
1197 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1198 ""
1199 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1200 [(set_attr "length" "4")
1201 (set_attr "cc" "set_czn")])
e2ec05a6 1202
c4984bad
MM
1203;******************************************************************************
1204; mul
1205
1d26ac96
MM
1206(define_expand "mulqi3"
1207 [(set (match_operand:QI 0 "register_operand" "")
1208 (mult:QI (match_operand:QI 1 "register_operand" "")
1209 (match_operand:QI 2 "register_operand" "")))]
1210 ""
1211 "{
dd6d1f8c 1212 if (!AVR_HAVE_MUL)
1d26ac96
MM
1213 {
1214 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1215 DONE;
1216 }
1217}")
1218
1219(define_insn "*mulqi3_enh"
c4984bad
MM
1220 [(set (match_operand:QI 0 "register_operand" "=r")
1221 (mult:QI (match_operand:QI 1 "register_operand" "r")
1222 (match_operand:QI 2 "register_operand" "r")))]
dd6d1f8c 1223 "AVR_HAVE_MUL"
c4984bad
MM
1224 "mul %1,%2
1225 mov %0,r0
1226 clr r1"
1227 [(set_attr "length" "3")
1228 (set_attr "cc" "clobber")])
1229
1d26ac96
MM
1230(define_expand "mulqi3_call"
1231 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1232 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1233 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1234 (clobber (reg:QI 22))])
1235 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1236 ""
1237 "")
1238
1239(define_insn "*mulqi3_call"
1240 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1241 (clobber (reg:QI 22))]
dd6d1f8c 1242 "!AVR_HAVE_MUL"
1d26ac96 1243 "%~call __mulqi3"
25f2e176 1244 [(set_attr "type" "xcall")
1d26ac96
MM
1245 (set_attr "cc" "clobber")])
1246
6deb5197
GJL
1247;; "umulqi3_highpart"
1248;; "smulqi3_highpart"
1249(define_insn "<extend_su>mulqi3_highpart"
1250 [(set (match_operand:QI 0 "register_operand" "=r")
1251 (truncate:QI
1252 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1253 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
7ece3881
GJL
1254 (const_int 8))))]
1255 "AVR_HAVE_MUL"
6deb5197 1256 "mul<extend_s> %1,%2
7ece3881
GJL
1257 mov %0,r1
1258 clr __zero_reg__"
1259 [(set_attr "length" "3")
1260 (set_attr "cc" "clobber")])
1261
7ece3881
GJL
1262
1263;; Used when expanding div or mod inline for some special values
1264(define_insn "*subqi3.ashiftrt7"
1265 [(set (match_operand:QI 0 "register_operand" "=r")
1266 (minus:QI (match_operand:QI 1 "register_operand" "0")
1267 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1268 (const_int 7))))]
1269 ""
1270 "sbrc %2,7\;inc %0"
1271 [(set_attr "length" "2")
1272 (set_attr "cc" "clobber")])
1273
f1f59bc7
GJL
1274(define_insn "*addqi3.lt0"
1275 [(set (match_operand:QI 0 "register_operand" "=r")
1276 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1277 (const_int 0))
1278 (match_operand:QI 2 "register_operand" "0")))]
1279 ""
1280 "sbrc %1,7\;inc %0"
1281 [(set_attr "length" "2")
1282 (set_attr "cc" "clobber")])
1283
1284(define_insn "*addhi3.lt0"
1285 [(set (match_operand:HI 0 "register_operand" "=w,r")
1286 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1287 (const_int 0))
1288 (match_operand:HI 2 "register_operand" "0,0")))
1289 (clobber (match_scratch:QI 3 "=X,&1"))]
1290 ""
1291 "@
1292 sbrc %1,7\;adiw %0,1
1293 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1294 [(set_attr "length" "2,3")
1295 (set_attr "cc" "clobber")])
1296
e4fe948a
GJL
1297(define_insn "*addpsi3.lt0"
1298 [(set (match_operand:PSI 0 "register_operand" "=r")
1299 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1300 (const_int 23))
1301 (match_operand:PSI 2 "register_operand" "0")))]
1302 ""
1303 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1304 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1305 [(set_attr "length" "5")
1306 (set_attr "cc" "clobber")])
1307
f1f59bc7
GJL
1308(define_insn "*addsi3.lt0"
1309 [(set (match_operand:SI 0 "register_operand" "=r")
1310 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1311 (const_int 31))
1312 (match_operand:SI 2 "register_operand" "0")))]
1313 ""
1314 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1315 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1316 [(set_attr "length" "6")
1317 (set_attr "cc" "clobber")])
1318
1319
6deb5197
GJL
1320;; "umulqihi3"
1321;; "mulqihi3"
1322(define_insn "<extend_u>mulqihi3"
1323 [(set (match_operand:HI 0 "register_operand" "=r")
1324 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1325 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
dd6d1f8c 1326 "AVR_HAVE_MUL"
6deb5197 1327 "mul<extend_s> %1,%2
c4984bad 1328 movw %0,r0
6deb5197 1329 clr __zero_reg__"
c4984bad
MM
1330 [(set_attr "length" "3")
1331 (set_attr "cc" "clobber")])
1332
8c352fa8
GJL
1333(define_insn "usmulqihi3"
1334 [(set (match_operand:HI 0 "register_operand" "=r")
1335 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1336 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1337 "AVR_HAVE_MUL"
1338 "mulsu %2,%1
1339 movw %0,r0
1340 clr __zero_reg__"
1341 [(set_attr "length" "3")
1342 (set_attr "cc" "clobber")])
1343
1344;; Above insn is not canonicalized by insn combine, so here is a version with
1345;; operands swapped.
1346
1347(define_insn "*sumulqihi3"
1348 [(set (match_operand:HI 0 "register_operand" "=r")
1349 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1350 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1351 "AVR_HAVE_MUL"
1352 "mulsu %1,%2
1353 movw %0,r0
1354 clr __zero_reg__"
1355 [(set_attr "length" "3")
1356 (set_attr "cc" "clobber")])
1357
1358;; One-extend operand 1
1359
1360(define_insn "*osmulqihi3"
1361 [(set (match_operand:HI 0 "register_operand" "=&r")
1362 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1363 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1364 "AVR_HAVE_MUL"
1365 "mulsu %2,%1
1366 movw %0,r0
1367 sub %B0,%2
1368 clr __zero_reg__"
1369 [(set_attr "length" "4")
1370 (set_attr "cc" "clobber")])
1371
1372(define_insn "*oumulqihi3"
1373 [(set (match_operand:HI 0 "register_operand" "=&r")
1374 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1375 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1376 "AVR_HAVE_MUL"
1377 "mul %2,%1
1378 movw %0,r0
1379 sub %B0,%2
1380 clr __zero_reg__"
1381 [(set_attr "length" "4")
1382 (set_attr "cc" "clobber")])
1383
1b65da7d
GJL
1384;******************************************************************************
1385; multiply-add/sub QI: $0 = $3 +/- $1*$2
1386;******************************************************************************
1387
1388(define_insn "*maddqi4"
1389 [(set (match_operand:QI 0 "register_operand" "=r")
1390 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1391 (match_operand:QI 2 "register_operand" "r"))
1392 (match_operand:QI 3 "register_operand" "0")))]
1393
1394 "AVR_HAVE_MUL"
1395 "mul %1,%2
1396 add %A0,r0
1397 clr __zero_reg__"
1398 [(set_attr "length" "4")
1399 (set_attr "cc" "clobber")])
1400
1401(define_insn "*msubqi4"
1402 [(set (match_operand:QI 0 "register_operand" "=r")
1403 (minus:QI (match_operand:QI 3 "register_operand" "0")
1404 (mult:QI (match_operand:QI 1 "register_operand" "r")
1405 (match_operand:QI 2 "register_operand" "r"))))]
1406 "AVR_HAVE_MUL"
1407 "mul %1,%2
1408 sub %A0,r0
1409 clr __zero_reg__"
1410 [(set_attr "length" "4")
1411 (set_attr "cc" "clobber")])
1412
1413(define_insn_and_split "*maddqi4.const"
1414 [(set (match_operand:QI 0 "register_operand" "=r")
1415 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1416 (match_operand:QI 2 "const_int_operand" "n"))
1417 (match_operand:QI 3 "register_operand" "0")))
1418 (clobber (match_scratch:QI 4 "=&d"))]
1419 "AVR_HAVE_MUL"
1420 "#"
1421 "&& reload_completed"
1422 [(set (match_dup 4)
1423 (match_dup 2))
1424 ; *maddqi4
1425 (set (match_dup 0)
1426 (plus:QI (mult:QI (match_dup 1)
1427 (match_dup 4))
1428 (match_dup 3)))]
1429 "")
1430
1431(define_insn_and_split "*msubqi4.const"
1432 [(set (match_operand:QI 0 "register_operand" "=r")
1433 (minus:QI (match_operand:QI 3 "register_operand" "0")
1434 (mult:QI (match_operand:QI 1 "register_operand" "r")
1435 (match_operand:QI 2 "const_int_operand" "n"))))
1436 (clobber (match_scratch:QI 4 "=&d"))]
1437 "AVR_HAVE_MUL"
1438 "#"
1439 "&& reload_completed"
1440 [(set (match_dup 4)
1441 (match_dup 2))
1442 ; *msubqi4
1443 (set (match_dup 0)
1444 (minus:QI (match_dup 3)
1445 (mult:QI (match_dup 1)
1446 (match_dup 4))))]
1447 "")
1448
1449
3e0cef6d
GJL
1450;******************************************************************************
1451; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1452;******************************************************************************
1453
1454;; We don't use standard insns/expanders as they lead to cumbersome code for,
1455;; e.g,
1456;;
1457;; int foo (unsigned char z)
1458;; {
1459;; extern int aInt[];
1460;; return aInt[3*z+2];
1461;; }
1462;;
1463;; because the constant +4 then is added explicitely instead of consuming it
1464;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1465;; into account more accurately and doesn't do burte-force multiply-add/sub.
1466;; The implementational effort is the same so we are fine with that approach.
1467
1468
1469;; "*maddqihi4"
1470;; "*umaddqihi4"
1471(define_insn "*<extend_u>maddqihi4"
1472 [(set (match_operand:HI 0 "register_operand" "=r")
1473 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1474 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1475 (match_operand:HI 3 "register_operand" "0")))]
1476
1477 "AVR_HAVE_MUL"
1478 "mul<extend_s> %1,%2
1479 add %A0,r0
1480 adc %B0,r1
1481 clr __zero_reg__"
1482 [(set_attr "length" "4")
1483 (set_attr "cc" "clobber")])
1484
1485;; "*msubqihi4"
1486;; "*umsubqihi4"
1487(define_insn "*<extend_u>msubqihi4"
1488 [(set (match_operand:HI 0 "register_operand" "=r")
1489 (minus:HI (match_operand:HI 3 "register_operand" "0")
1490 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1491 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1492 "AVR_HAVE_MUL"
1493 "mul<extend_s> %1,%2
1494 sub %A0,r0
1495 sbc %B0,r1
1496 clr __zero_reg__"
1497 [(set_attr "length" "4")
1498 (set_attr "cc" "clobber")])
1499
1500;; "*usmaddqihi4"
1501;; "*sumaddqihi4"
1502(define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1503 [(set (match_operand:HI 0 "register_operand" "=r")
1504 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1505 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1506 (match_operand:HI 3 "register_operand" "0")))]
1507 "AVR_HAVE_MUL
1508 && reload_completed
1509 && <any_extend:CODE> != <any_extend2:CODE>"
1510 {
1511 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1512 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1513
1514 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1515 }
1516 [(set_attr "length" "4")
1517 (set_attr "cc" "clobber")])
1518
1519;; "*usmsubqihi4"
1520;; "*sumsubqihi4"
1521(define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1522 [(set (match_operand:HI 0 "register_operand" "=r")
1523 (minus:HI (match_operand:HI 3 "register_operand" "0")
1524 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1525 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1526 "AVR_HAVE_MUL
1527 && reload_completed
1528 && <any_extend:CODE> != <any_extend2:CODE>"
1529 {
1530 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1531 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1532
1533 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1534 }
1535 [(set_attr "length" "4")
1536 (set_attr "cc" "clobber")])
1537
1538;; Handle small constants
1539
6deb5197
GJL
1540;; "umaddqihi4.uconst"
1541;; "maddqihi4.sconst"
1542(define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1543 [(set (match_operand:HI 0 "register_operand" "=r")
1544 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1545 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1546 (match_operand:HI 3 "register_operand" "0")))
3e0cef6d
GJL
1547 (clobber (match_scratch:QI 4 "=&d"))]
1548 "AVR_HAVE_MUL"
1549 "#"
1550 "&& reload_completed"
1551 [(set (match_dup 4)
1552 (match_dup 2))
6deb5197 1553 ; *umaddqihi4 resp. *maddqihi4
3e0cef6d 1554 (set (match_dup 0)
6deb5197
GJL
1555 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1556 (any_extend:HI (match_dup 4)))
3e0cef6d
GJL
1557 (match_dup 3)))]
1558 {
1559 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1560 })
1561
6deb5197
GJL
1562;; "*umsubqihi4.uconst"
1563;; "*msubqihi4.sconst"
1564(define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1565 [(set (match_operand:HI 0 "register_operand" "=r")
1566 (minus:HI (match_operand:HI 3 "register_operand" "0")
1567 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1568 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
3e0cef6d
GJL
1569 (clobber (match_scratch:QI 4 "=&d"))]
1570 "AVR_HAVE_MUL"
1571 "#"
1572 "&& reload_completed"
1573 [(set (match_dup 4)
1574 (match_dup 2))
6deb5197 1575 ; *umsubqihi4 resp. *msubqihi4
3e0cef6d
GJL
1576 (set (match_dup 0)
1577 (minus:HI (match_dup 3)
6deb5197
GJL
1578 (mult:HI (any_extend:HI (match_dup 1))
1579 (any_extend:HI (match_dup 4)))))]
3e0cef6d
GJL
1580 {
1581 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1582 })
1583
1584;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1585;; for MULT with power of 2 and skips trying MULT insn above.
1586
1587(define_insn_and_split "*umsubqihi4.uconst.ashift"
1588 [(set (match_operand:HI 0 "register_operand" "=r")
1589 (minus:HI (match_operand:HI 3 "register_operand" "0")
1590 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1591 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1592 (clobber (match_scratch:QI 4 "=&d"))]
1593 "AVR_HAVE_MUL"
1594 "#"
1595 "&& reload_completed"
1596 [(set (match_dup 4)
1597 (match_dup 2))
1598 ; *umsubqihi4
1599 (set (match_dup 0)
1600 (minus:HI (match_dup 3)
1601 (mult:HI (zero_extend:HI (match_dup 1))
1602 (zero_extend:HI (match_dup 4)))))]
1603 {
1604 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1605 })
1606
3e0cef6d
GJL
1607;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1608;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1609;; because this would require an extra pattern for just one value.
1610
1611(define_insn_and_split "*msubqihi4.sconst.ashift"
1612 [(set (match_operand:HI 0 "register_operand" "=r")
1613 (minus:HI (match_operand:HI 3 "register_operand" "0")
1614 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1615 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1616 (clobber (match_scratch:QI 4 "=&d"))]
1617 "AVR_HAVE_MUL"
1618 "#"
1619 "&& reload_completed"
1620 [(set (match_dup 4)
1621 (match_dup 2))
1622 ; *smsubqihi4
1623 (set (match_dup 0)
1624 (minus:HI (match_dup 3)
1625 (mult:HI (sign_extend:HI (match_dup 1))
1626 (sign_extend:HI (match_dup 4)))))]
1627 {
1628 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1629 })
1630
1631;; For signed/unsigned combinations that require narrow constraint "a"
1632;; just provide a pattern if signed/unsigned combination is actually needed.
1633
1634(define_insn_and_split "*sumaddqihi4.uconst"
1635 [(set (match_operand:HI 0 "register_operand" "=r")
1636 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1637 (match_operand:HI 2 "u8_operand" "M"))
1638 (match_operand:HI 3 "register_operand" "0")))
1639 (clobber (match_scratch:QI 4 "=&a"))]
1640 "AVR_HAVE_MUL
1641 && !s8_operand (operands[2], VOIDmode)"
1642 "#"
1643 "&& reload_completed"
1644 [(set (match_dup 4)
1645 (match_dup 2))
1646 ; *sumaddqihi4
1647 (set (match_dup 0)
1648 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1649 (zero_extend:HI (match_dup 4)))
1650 (match_dup 3)))]
1651 {
1652 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1653 })
1654
1655(define_insn_and_split "*sumsubqihi4.uconst"
1656 [(set (match_operand:HI 0 "register_operand" "=r")
1657 (minus:HI (match_operand:HI 3 "register_operand" "0")
1658 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1659 (match_operand:HI 2 "u8_operand" "M"))))
1660 (clobber (match_scratch:QI 4 "=&a"))]
1661 "AVR_HAVE_MUL
1662 && !s8_operand (operands[2], VOIDmode)"
1663 "#"
1664 "&& reload_completed"
1665 [(set (match_dup 4)
1666 (match_dup 2))
1667 ; *sumsubqihi4
1668 (set (match_dup 0)
1669 (minus:HI (match_dup 3)
1670 (mult:HI (sign_extend:HI (match_dup 1))
1671 (zero_extend:HI (match_dup 4)))))]
1672 {
1673 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1674 })
8c352fa8
GJL
1675
1676;******************************************************************************
1677; mul HI: $1 = sign/zero-extend, $2 = small constant
1678;******************************************************************************
1679
6deb5197
GJL
1680;; "*muluqihi3.uconst"
1681;; "*mulsqihi3.sconst"
1682(define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
8c352fa8 1683 [(set (match_operand:HI 0 "register_operand" "=r")
6deb5197
GJL
1684 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1685 (match_operand:HI 2 "<extend_su>8_operand" "n")))
8c352fa8
GJL
1686 (clobber (match_scratch:QI 3 "=&d"))]
1687 "AVR_HAVE_MUL"
1688 "#"
1689 "&& reload_completed"
1690 [(set (match_dup 3)
1691 (match_dup 2))
6deb5197 1692 ; umulqihi3 resp. mulqihi3
8c352fa8 1693 (set (match_dup 0)
6deb5197
GJL
1694 (mult:HI (any_extend:HI (match_dup 1))
1695 (any_extend:HI (match_dup 3))))]
8c352fa8
GJL
1696 {
1697 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1698 })
1699
1700(define_insn_and_split "*muluqihi3.sconst"
1701 [(set (match_operand:HI 0 "register_operand" "=r")
1702 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1703 (match_operand:HI 2 "s8_operand" "n")))
1704 (clobber (match_scratch:QI 3 "=&a"))]
1705 "AVR_HAVE_MUL"
1706 "#"
1707 "&& reload_completed"
1708 [(set (match_dup 3)
1709 (match_dup 2))
1710 ; usmulqihi3
1711 (set (match_dup 0)
1712 (mult:HI (zero_extend:HI (match_dup 1))
1713 (sign_extend:HI (match_dup 3))))]
1714 {
1715 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1716 })
1717
8c352fa8
GJL
1718(define_insn_and_split "*mulsqihi3.uconst"
1719 [(set (match_operand:HI 0 "register_operand" "=r")
1720 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1721 (match_operand:HI 2 "u8_operand" "M")))
1722 (clobber (match_scratch:QI 3 "=&a"))]
1723 "AVR_HAVE_MUL"
1724 "#"
1725 "&& reload_completed"
1726 [(set (match_dup 3)
1727 (match_dup 2))
1728 ; usmulqihi3
1729 (set (match_dup 0)
1730 (mult:HI (zero_extend:HI (match_dup 3))
1731 (sign_extend:HI (match_dup 1))))]
1732 {
1733 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1734 })
1735
1736(define_insn_and_split "*mulsqihi3.oconst"
1737 [(set (match_operand:HI 0 "register_operand" "=&r")
1738 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1739 (match_operand:HI 2 "o8_operand" "n")))
1740 (clobber (match_scratch:QI 3 "=&a"))]
1741 "AVR_HAVE_MUL"
1742 "#"
1743 "&& reload_completed"
1744 [(set (match_dup 3)
1745 (match_dup 2))
1746 ; *osmulqihi3
1747 (set (match_dup 0)
1748 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1749 (sign_extend:HI (match_dup 1))))]
1750 {
1751 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1752 })
1753
1754;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1755;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1756;; at that time. Fix that.
1757
1b65da7d
GJL
1758(define_insn "*ashiftqihi2.signx.1"
1759 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1760 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1761 (const_int 1)))]
1762 ""
1763 "@
1764 lsl %A0\;sbc %B0,%B0
1765 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1766 [(set_attr "length" "2,3")
1767 (set_attr "cc" "clobber")])
1768
8c352fa8
GJL
1769(define_insn_and_split "*ashifthi3.signx.const"
1770 [(set (match_operand:HI 0 "register_operand" "=r")
1771 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1772 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1773 (clobber (match_scratch:QI 3 "=&d"))]
1774 "AVR_HAVE_MUL"
1775 "#"
1776 "&& reload_completed"
1777 [(set (match_dup 3)
1778 (match_dup 2))
1779 ; mulqihi3
1780 (set (match_dup 0)
1781 (mult:HI (sign_extend:HI (match_dup 1))
1782 (sign_extend:HI (match_dup 3))))]
1783 {
1784 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1785 })
1786
1787(define_insn_and_split "*ashifthi3.signx.const7"
1788 [(set (match_operand:HI 0 "register_operand" "=r")
1789 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1790 (const_int 7)))
1791 (clobber (match_scratch:QI 2 "=&a"))]
1792 "AVR_HAVE_MUL"
1793 "#"
1794 "&& reload_completed"
1795 [(set (match_dup 2)
1796 (match_dup 3))
1797 ; usmulqihi3
1798 (set (match_dup 0)
1799 (mult:HI (zero_extend:HI (match_dup 2))
1800 (sign_extend:HI (match_dup 1))))]
1801 {
1802 operands[3] = gen_int_mode (1 << 7, QImode);
1803 })
1804
1805(define_insn_and_split "*ashifthi3.zerox.const"
1806 [(set (match_operand:HI 0 "register_operand" "=r")
1807 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1808 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1809 (clobber (match_scratch:QI 3 "=&d"))]
1810 "AVR_HAVE_MUL"
1811 "#"
1812 "&& reload_completed"
1813 [(set (match_dup 3)
1814 (match_dup 2))
1815 ; umulqihi3
1816 (set (match_dup 0)
1817 (mult:HI (zero_extend:HI (match_dup 1))
1818 (zero_extend:HI (match_dup 3))))]
1819 {
1820 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1821 })
1822
1823;******************************************************************************
1824; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1825;******************************************************************************
1826
1827(define_insn "mulsqihi3"
1828 [(set (match_operand:HI 0 "register_operand" "=&r")
1829 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1830 (match_operand:HI 2 "register_operand" "a")))]
1831 "AVR_HAVE_MUL"
1832 "mulsu %1,%A2
1833 movw %0,r0
1834 mul %1,%B2
1835 add %B0,r0
1836 clr __zero_reg__"
1837 [(set_attr "length" "5")
1838 (set_attr "cc" "clobber")])
1839
1840(define_insn "muluqihi3"
1841 [(set (match_operand:HI 0 "register_operand" "=&r")
1842 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1843 (match_operand:HI 2 "register_operand" "r")))]
1844 "AVR_HAVE_MUL"
1845 "mul %1,%A2
1846 movw %0,r0
1847 mul %1,%B2
1848 add %B0,r0
1849 clr __zero_reg__"
1850 [(set_attr "length" "5")
1851 (set_attr "cc" "clobber")])
1852
1853;; one-extend operand 1
1854
1855(define_insn "muloqihi3"
1856 [(set (match_operand:HI 0 "register_operand" "=&r")
1857 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1858 (match_operand:HI 2 "register_operand" "r")))]
1859 "AVR_HAVE_MUL"
1860 "mul %1,%A2
1861 movw %0,r0
1862 mul %1,%B2
1863 add %B0,r0
1864 sub %B0,%A2
1865 clr __zero_reg__"
1866 [(set_attr "length" "6")
1867 (set_attr "cc" "clobber")])
1868
1869;******************************************************************************
1870
1d26ac96
MM
1871(define_expand "mulhi3"
1872 [(set (match_operand:HI 0 "register_operand" "")
8c352fa8
GJL
1873 (mult:HI (match_operand:HI 1 "register_operand" "")
1874 (match_operand:HI 2 "register_or_s9_operand" "")))]
1d26ac96 1875 ""
8c352fa8
GJL
1876 {
1877 if (!AVR_HAVE_MUL)
1878 {
1879 if (!register_operand (operands[2], HImode))
1880 operands[2] = force_reg (HImode, operands[2]);
1881
1882 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1883 DONE;
1884 }
1885
1886 /* For small constants we can do better by extending them on the fly.
1887 The constant can be loaded in one instruction and the widening
1888 multiplication is shorter. First try the unsigned variant because it
1889 allows constraint "d" instead of "a" for the signed version. */
1890
1891 if (s9_operand (operands[2], HImode))
1892 {
1893 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1894
1895 if (u8_operand (operands[2], HImode))
1896 {
1897 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1898 }
1899 else if (s8_operand (operands[2], HImode))
1900 {
1901 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1902 }
1903 else
1904 {
1905 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1906 }
1907
1908 DONE;
1909 }
1910
1911 if (!register_operand (operands[2], HImode))
1912 operands[2] = force_reg (HImode, operands[2]);
1913 })
1d26ac96
MM
1914
1915(define_insn "*mulhi3_enh"
c4984bad
MM
1916 [(set (match_operand:HI 0 "register_operand" "=&r")
1917 (mult:HI (match_operand:HI 1 "register_operand" "r")
1918 (match_operand:HI 2 "register_operand" "r")))]
dd6d1f8c 1919 "AVR_HAVE_MUL"
beddf669
GJL
1920 {
1921 return REGNO (operands[1]) == REGNO (operands[2])
1922 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
1923 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
1924 }
c4984bad
MM
1925 [(set_attr "length" "7")
1926 (set_attr "cc" "clobber")])
1927
1d26ac96
MM
1928(define_expand "mulhi3_call"
1929 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1930 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1931 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1932 (clobber (reg:HI 22))
1933 (clobber (reg:QI 21))])
1934 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1935 ""
1936 "")
1937
1938(define_insn "*mulhi3_call"
1939 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1940 (clobber (reg:HI 22))
1941 (clobber (reg:QI 21))]
dd6d1f8c 1942 "!AVR_HAVE_MUL"
1d26ac96 1943 "%~call __mulhi3"
25f2e176 1944 [(set_attr "type" "xcall")
1d26ac96
MM
1945 (set_attr "cc" "clobber")])
1946
7ece3881 1947;; To support widening multiplicatioon with constant we postpone
296799ba
GJL
1948;; expanding to the implicit library call until post combine and
1949;; prior to register allocation. Clobber all hard registers that
1950;; might be used by the (widening) multiply until it is split and
1951;; it's final register footprint is worked out.
1952
1d26ac96 1953(define_expand "mulsi3"
296799ba
GJL
1954 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1955 (mult:SI (match_operand:SI 1 "register_operand" "")
1956 (match_operand:SI 2 "nonmemory_operand" "")))
db7ccee2 1957 (clobber (reg:HI 26))
296799ba 1958 (clobber (reg:DI 18))])]
dd6d1f8c 1959 "AVR_HAVE_MUL"
296799ba
GJL
1960 {
1961 if (u16_operand (operands[2], SImode))
1962 {
1963 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1964 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1965 DONE;
1966 }
1d26ac96 1967
296799ba
GJL
1968 if (o16_operand (operands[2], SImode))
1969 {
1970 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1971 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1972 DONE;
1973 }
1974 })
1d26ac96 1975
296799ba
GJL
1976(define_insn_and_split "*mulsi3"
1977 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
1978 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
1979 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
db7ccee2 1980 (clobber (reg:HI 26))
296799ba
GJL
1981 (clobber (reg:DI 18))]
1982 "AVR_HAVE_MUL && !reload_completed"
1983 { gcc_unreachable(); }
1984 "&& 1"
1985 [(set (reg:SI 18)
1986 (match_dup 1))
9a63dee4 1987 (set (reg:SI 22)
296799ba
GJL
1988 (match_dup 2))
1989 (parallel [(set (reg:SI 22)
1990 (mult:SI (reg:SI 22)
1991 (reg:SI 18)))
1992 (clobber (reg:HI 26))])
1993 (set (match_dup 0)
1994 (reg:SI 22))]
1995 {
1996 if (u16_operand (operands[2], SImode))
1997 {
1998 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1999 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2000 DONE;
2001 }
2002
2003 if (o16_operand (operands[2], SImode))
2004 {
2005 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2006 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2007 DONE;
2008 }
2009 })
2010
2011;; "muluqisi3"
2012;; "muluhisi3"
2013(define_insn_and_split "mulu<mode>si3"
2014 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2015 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2016 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
db7ccee2 2017 (clobber (reg:HI 26))
296799ba
GJL
2018 (clobber (reg:DI 18))]
2019 "AVR_HAVE_MUL && !reload_completed"
2020 { gcc_unreachable(); }
2021 "&& 1"
2022 [(set (reg:HI 26)
2023 (match_dup 1))
2024 (set (reg:SI 18)
2025 (match_dup 2))
2026 (set (reg:SI 22)
2027 (mult:SI (zero_extend:SI (reg:HI 26))
2028 (reg:SI 18)))
2029 (set (match_dup 0)
2030 (reg:SI 22))]
2031 {
2032 /* Do the QI -> HI extension explicitely before the multiplication. */
2033 /* Do the HI -> SI extension implicitely and after the multiplication. */
2034
2035 if (QImode == <MODE>mode)
2036 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2037
2038 if (u16_operand (operands[2], SImode))
2039 {
2040 operands[1] = force_reg (HImode, operands[1]);
2041 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2042 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2043 DONE;
2044 }
2045 })
2046
2047;; "mulsqisi3"
2048;; "mulshisi3"
2049(define_insn_and_split "muls<mode>si3"
2050 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2051 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2052 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
db7ccee2 2053 (clobber (reg:HI 26))
296799ba
GJL
2054 (clobber (reg:DI 18))]
2055 "AVR_HAVE_MUL && !reload_completed"
2056 { gcc_unreachable(); }
2057 "&& 1"
2058 [(set (reg:HI 26)
2059 (match_dup 1))
2060 (set (reg:SI 18)
2061 (match_dup 2))
2062 (set (reg:SI 22)
2063 (mult:SI (sign_extend:SI (reg:HI 26))
2064 (reg:SI 18)))
2065 (set (match_dup 0)
2066 (reg:SI 22))]
2067 {
2068 /* Do the QI -> HI extension explicitely before the multiplication. */
2069 /* Do the HI -> SI extension implicitely and after the multiplication. */
2070
2071 if (QImode == <MODE>mode)
2072 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2073
2074 if (u16_operand (operands[2], SImode)
2075 || s16_operand (operands[2], SImode))
2076 {
2077 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2078
2079 operands[1] = force_reg (HImode, operands[1]);
2080
2081 if (u16_operand (operands[2], SImode))
2082 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2083 else
2084 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2085
2086 DONE;
2087 }
2088 })
2089
2090;; One-extend operand 1
2091
2092(define_insn_and_split "mulohisi3"
2093 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2094 (mult:SI (not:SI (zero_extend:SI
2095 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2096 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
db7ccee2 2097 (clobber (reg:HI 26))
296799ba
GJL
2098 (clobber (reg:DI 18))]
2099 "AVR_HAVE_MUL && !reload_completed"
2100 { gcc_unreachable(); }
2101 "&& 1"
2102 [(set (reg:HI 26)
2103 (match_dup 1))
2104 (set (reg:SI 18)
2105 (match_dup 2))
2106 (set (reg:SI 22)
2107 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2108 (reg:SI 18)))
2109 (set (match_dup 0)
9a63dee4 2110 (reg:SI 22))]
296799ba
GJL
2111 "")
2112
7ece3881
GJL
2113;; "mulhisi3"
2114;; "umulhisi3"
2115(define_expand "<extend_u>mulhisi3"
296799ba 2116 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7ece3881
GJL
2117 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2118 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
db7ccee2 2119 (clobber (reg:HI 26))
296799ba
GJL
2120 (clobber (reg:DI 18))])]
2121 "AVR_HAVE_MUL"
2122 "")
2123
2124(define_expand "usmulhisi3"
2125 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2126 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2127 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
db7ccee2 2128 (clobber (reg:HI 26))
296799ba
GJL
2129 (clobber (reg:DI 18))])]
2130 "AVR_HAVE_MUL"
2131 "")
2132
2133;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2134;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2135;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2136;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2137(define_insn_and_split
7ece3881 2138 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
296799ba
GJL
2139 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2140 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2141 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
db7ccee2 2142 (clobber (reg:HI 26))
296799ba
GJL
2143 (clobber (reg:DI 18))]
2144 "AVR_HAVE_MUL && !reload_completed"
2145 { gcc_unreachable(); }
2146 "&& 1"
9a63dee4 2147 [(set (reg:HI 18)
296799ba
GJL
2148 (match_dup 1))
2149 (set (reg:HI 26)
2150 (match_dup 2))
2151 (set (reg:SI 22)
2152 (mult:SI (match_dup 3)
2153 (match_dup 4)))
2154 (set (match_dup 0)
9a63dee4 2155 (reg:SI 22))]
296799ba
GJL
2156 {
2157 rtx xop1 = operands[1];
2158 rtx xop2 = operands[2];
2159
2160 /* Do the QI -> HI extension explicitely before the multiplication. */
2161 /* Do the HI -> SI extension implicitely and after the multiplication. */
2162
2163 if (QImode == <QIHI:MODE>mode)
2164 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2165
2166 if (QImode == <QIHI2:MODE>mode)
2167 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2168
2169 if (<any_extend:CODE> == <any_extend2:CODE>
2170 || <any_extend:CODE> == ZERO_EXTEND)
2171 {
2172 operands[1] = xop1;
2173 operands[2] = xop2;
2174 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2175 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2176 }
2177 else
2178 {
2179 /* <any_extend:CODE> = SIGN_EXTEND */
2180 /* <any_extend2:CODE> = ZERO_EXTEND */
2181
2182 operands[1] = xop2;
2183 operands[2] = xop1;
2184 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2185 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2186 }
2187 })
2188
7ece3881
GJL
2189;; "smulhi3_highpart"
2190;; "umulhi3_highpart"
2191(define_expand "<extend_su>mulhi3_highpart"
2192 [(set (reg:HI 18)
2193 (match_operand:HI 1 "nonmemory_operand" ""))
2194 (set (reg:HI 26)
2195 (match_operand:HI 2 "nonmemory_operand" ""))
2196 (parallel [(set (reg:HI 24)
2197 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2198 (any_extend:SI (reg:HI 26)))
2199 (const_int 16))))
2200 (clobber (reg:HI 22))])
2201 (set (match_operand:HI 0 "register_operand" "")
2202 (reg:HI 24))]
2203 "AVR_HAVE_MUL"
2204 "")
2205
2206
296799ba
GJL
2207(define_insn "*mulsi3_call"
2208 [(set (reg:SI 22)
2209 (mult:SI (reg:SI 22)
2210 (reg:SI 18)))
2211 (clobber (reg:HI 26))]
9a63dee4 2212 "AVR_HAVE_MUL"
296799ba
GJL
2213 "%~call __mulsi3"
2214 [(set_attr "type" "xcall")
2215 (set_attr "cc" "clobber")])
9a63dee4 2216
7ece3881
GJL
2217;; "*mulhisi3_call"
2218;; "*umulhisi3_call"
2219(define_insn "*<extend_u>mulhisi3_call"
296799ba 2220 [(set (reg:SI 22)
7ece3881
GJL
2221 (mult:SI (any_extend:SI (reg:HI 18))
2222 (any_extend:SI (reg:HI 26))))]
9a63dee4 2223 "AVR_HAVE_MUL"
7ece3881 2224 "%~call __<extend_u>mulhisi3"
9a63dee4
GJL
2225 [(set_attr "type" "xcall")
2226 (set_attr "cc" "clobber")])
2227
7ece3881
GJL
2228;; "*umulhi3_highpart_call"
2229;; "*smulhi3_highpart_call"
2230(define_insn "*<extend_su>mulhi3_highpart_call"
2231 [(set (reg:HI 24)
2232 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2233 (any_extend:SI (reg:HI 26)))
2234 (const_int 16))))
2235 (clobber (reg:HI 22))]
9a63dee4 2236 "AVR_HAVE_MUL"
7ece3881 2237 "%~call __<extend_u>mulhisi3"
9a63dee4
GJL
2238 [(set_attr "type" "xcall")
2239 (set_attr "cc" "clobber")])
2240
296799ba
GJL
2241(define_insn "*usmulhisi3_call"
2242 [(set (reg:SI 22)
2243 (mult:SI (zero_extend:SI (reg:HI 18))
2244 (sign_extend:SI (reg:HI 26))))]
2245 "AVR_HAVE_MUL"
2246 "%~call __usmulhisi3"
2247 [(set_attr "type" "xcall")
2248 (set_attr "cc" "clobber")])
2249
7ece3881 2250(define_insn "*mul<extend_su>hisi3_call"
296799ba 2251 [(set (reg:SI 22)
7ece3881 2252 (mult:SI (any_extend:SI (reg:HI 26))
296799ba
GJL
2253 (reg:SI 18)))]
2254 "AVR_HAVE_MUL"
7ece3881 2255 "%~call __mul<extend_su>hisi3"
296799ba
GJL
2256 [(set_attr "type" "xcall")
2257 (set_attr "cc" "clobber")])
2258
2259(define_insn "*mulohisi3_call"
2260 [(set (reg:SI 22)
2261 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2262 (reg:SI 18)))]
2263 "AVR_HAVE_MUL"
2264 "%~call __mulohisi3"
2265 [(set_attr "type" "xcall")
2266 (set_attr "cc" "clobber")])
2267
1d26ac96
MM
2268; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2269; divmod
2270
e4fe948a 2271;; Generate lib1funcs.S calls ourselves, because:
1d26ac96
MM
2272;; - we know exactly which registers are clobbered (for QI and HI
2273;; modes, some of the call-used registers are preserved)
2274;; - we get both the quotient and the remainder at no extra cost
83613dbe
AH
2275;; - we split the patterns only after the first CSE passes because
2276;; CSE has problems to operate on hard regs.
2277;;
2278(define_insn_and_split "divmodqi4"
2279 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2280 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2281 (match_operand:QI 2 "pseudo_register_operand" "")))
2282 (set (match_operand:QI 3 "pseudo_register_operand" "")
2283 (mod:QI (match_dup 1) (match_dup 2)))
2284 (clobber (reg:QI 22))
2285 (clobber (reg:QI 23))
2286 (clobber (reg:QI 24))
2287 (clobber (reg:QI 25))])]
2288 ""
2289 "this divmodqi4 pattern should have been splitted;"
2290 ""
2291 [(set (reg:QI 24) (match_dup 1))
2292 (set (reg:QI 22) (match_dup 2))
1d26ac96
MM
2293 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2294 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2295 (clobber (reg:QI 22))
2296 (clobber (reg:QI 23))])
83613dbe
AH
2297 (set (match_dup 0) (reg:QI 24))
2298 (set (match_dup 3) (reg:QI 25))]
1d26ac96
MM
2299 "")
2300
2301(define_insn "*divmodqi4_call"
2302 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2303 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2304 (clobber (reg:QI 22))
2305 (clobber (reg:QI 23))]
2306 ""
2307 "%~call __divmodqi4"
25f2e176 2308 [(set_attr "type" "xcall")
1d26ac96
MM
2309 (set_attr "cc" "clobber")])
2310
83613dbe
AH
2311(define_insn_and_split "udivmodqi4"
2312 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2313 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2314 (match_operand:QI 2 "pseudo_register_operand" "")))
2315 (set (match_operand:QI 3 "pseudo_register_operand" "")
2316 (umod:QI (match_dup 1) (match_dup 2)))
2317 (clobber (reg:QI 22))
2318 (clobber (reg:QI 23))
2319 (clobber (reg:QI 24))
2320 (clobber (reg:QI 25))])]
2321 ""
2322 "this udivmodqi4 pattern should have been splitted;"
2323 ""
2324 [(set (reg:QI 24) (match_dup 1))
2325 (set (reg:QI 22) (match_dup 2))
1d26ac96
MM
2326 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2327 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2328 (clobber (reg:QI 23))])
83613dbe
AH
2329 (set (match_dup 0) (reg:QI 24))
2330 (set (match_dup 3) (reg:QI 25))]
1d26ac96
MM
2331 "")
2332
2333(define_insn "*udivmodqi4_call"
2334 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2335 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2336 (clobber (reg:QI 23))]
2337 ""
2338 "%~call __udivmodqi4"
25f2e176 2339 [(set_attr "type" "xcall")
1d26ac96
MM
2340 (set_attr "cc" "clobber")])
2341
83613dbe
AH
2342(define_insn_and_split "divmodhi4"
2343 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2344 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2345 (match_operand:HI 2 "pseudo_register_operand" "")))
2346 (set (match_operand:HI 3 "pseudo_register_operand" "")
2347 (mod:HI (match_dup 1) (match_dup 2)))
2348 (clobber (reg:QI 21))
2349 (clobber (reg:HI 22))
2350 (clobber (reg:HI 24))
2351 (clobber (reg:HI 26))])]
2352 ""
2353 "this should have been splitted;"
2354 ""
2355 [(set (reg:HI 24) (match_dup 1))
2356 (set (reg:HI 22) (match_dup 2))
1d26ac96
MM
2357 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2358 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2359 (clobber (reg:HI 26))
2360 (clobber (reg:QI 21))])
83613dbe
AH
2361 (set (match_dup 0) (reg:HI 22))
2362 (set (match_dup 3) (reg:HI 24))]
2363 "")
1d26ac96
MM
2364
2365(define_insn "*divmodhi4_call"
2366 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2367 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2368 (clobber (reg:HI 26))
2369 (clobber (reg:QI 21))]
2370 ""
2371 "%~call __divmodhi4"
25f2e176 2372 [(set_attr "type" "xcall")
1d26ac96
MM
2373 (set_attr "cc" "clobber")])
2374
83613dbe
AH
2375(define_insn_and_split "udivmodhi4"
2376 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2377 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2378 (match_operand:HI 2 "pseudo_register_operand" "")))
2379 (set (match_operand:HI 3 "pseudo_register_operand" "")
2380 (umod:HI (match_dup 1) (match_dup 2)))
2381 (clobber (reg:QI 21))
2382 (clobber (reg:HI 22))
2383 (clobber (reg:HI 24))
2384 (clobber (reg:HI 26))])]
2385 ""
2386 "this udivmodhi4 pattern should have been splitted.;"
2387 ""
2388 [(set (reg:HI 24) (match_dup 1))
2389 (set (reg:HI 22) (match_dup 2))
1d26ac96
MM
2390 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2391 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2392 (clobber (reg:HI 26))
2393 (clobber (reg:QI 21))])
83613dbe
AH
2394 (set (match_dup 0) (reg:HI 22))
2395 (set (match_dup 3) (reg:HI 24))]
1d26ac96
MM
2396 "")
2397
2398(define_insn "*udivmodhi4_call"
2399 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2400 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2401 (clobber (reg:HI 26))
2402 (clobber (reg:QI 21))]
2403 ""
2404 "%~call __udivmodhi4"
25f2e176 2405 [(set_attr "type" "xcall")
1d26ac96
MM
2406 (set_attr "cc" "clobber")])
2407
e4fe948a
GJL
2408;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2409;; 24-bit signed/unsigned division and modulo.
2410;; Notice that the libgcc implementation return the quotient in R22
2411;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2412;; implementation works the other way round.
2413
2414(define_insn_and_split "divmodpsi4"
2415 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2416 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2417 (match_operand:PSI 2 "pseudo_register_operand" "")))
2418 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2419 (mod:PSI (match_dup 1)
2420 (match_dup 2)))
2421 (clobber (reg:DI 18))
2422 (clobber (reg:QI 26))])]
2423 ""
2424 { gcc_unreachable(); }
2425 ""
2426 [(set (reg:PSI 22) (match_dup 1))
2427 (set (reg:PSI 18) (match_dup 2))
2428 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2429 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2430 (clobber (reg:QI 21))
2431 (clobber (reg:QI 25))
2432 (clobber (reg:QI 26))])
2433 (set (match_dup 0) (reg:PSI 22))
2434 (set (match_dup 3) (reg:PSI 18))])
2435
2436(define_insn "*divmodpsi4_call"
2437 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2438 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2439 (clobber (reg:QI 21))
2440 (clobber (reg:QI 25))
2441 (clobber (reg:QI 26))]
2442 ""
2443 "%~call __divmodpsi4"
2444 [(set_attr "type" "xcall")
2445 (set_attr "cc" "clobber")])
2446
2447(define_insn_and_split "udivmodpsi4"
2448 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2449 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2450 (match_operand:PSI 2 "pseudo_register_operand" "")))
2451 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2452 (umod:PSI (match_dup 1)
2453 (match_dup 2)))
2454 (clobber (reg:DI 18))
2455 (clobber (reg:QI 26))])]
2456 ""
2457 { gcc_unreachable(); }
2458 ""
2459 [(set (reg:PSI 22) (match_dup 1))
2460 (set (reg:PSI 18) (match_dup 2))
2461 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2462 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2463 (clobber (reg:QI 21))
2464 (clobber (reg:QI 25))
2465 (clobber (reg:QI 26))])
2466 (set (match_dup 0) (reg:PSI 22))
2467 (set (match_dup 3) (reg:PSI 18))])
2468
2469(define_insn "*udivmodpsi4_call"
2470 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2471 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2472 (clobber (reg:QI 21))
2473 (clobber (reg:QI 25))
2474 (clobber (reg:QI 26))]
2475 ""
2476 "%~call __udivmodpsi4"
2477 [(set_attr "type" "xcall")
2478 (set_attr "cc" "clobber")])
2479
2480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2481
83613dbe
AH
2482(define_insn_and_split "divmodsi4"
2483 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2484 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2485 (match_operand:SI 2 "pseudo_register_operand" "")))
2486 (set (match_operand:SI 3 "pseudo_register_operand" "")
2487 (mod:SI (match_dup 1) (match_dup 2)))
2488 (clobber (reg:SI 18))
2489 (clobber (reg:SI 22))
2490 (clobber (reg:HI 26))
2491 (clobber (reg:HI 30))])]
2492 ""
2493 "this divmodsi4 pattern should have been splitted;"
2494 ""
2495 [(set (reg:SI 22) (match_dup 1))
2496 (set (reg:SI 18) (match_dup 2))
1d26ac96
MM
2497 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2498 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2499 (clobber (reg:HI 26))
2500 (clobber (reg:HI 30))])
83613dbe
AH
2501 (set (match_dup 0) (reg:SI 18))
2502 (set (match_dup 3) (reg:SI 22))]
1d26ac96
MM
2503 "")
2504
2505(define_insn "*divmodsi4_call"
2506 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2507 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2508 (clobber (reg:HI 26))
2509 (clobber (reg:HI 30))]
2510 ""
2511 "%~call __divmodsi4"
25f2e176 2512 [(set_attr "type" "xcall")
1d26ac96
MM
2513 (set_attr "cc" "clobber")])
2514
83613dbe
AH
2515(define_insn_and_split "udivmodsi4"
2516 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2517 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2518 (match_operand:SI 2 "pseudo_register_operand" "")))
2519 (set (match_operand:SI 3 "pseudo_register_operand" "")
2520 (umod:SI (match_dup 1) (match_dup 2)))
2521 (clobber (reg:SI 18))
2522 (clobber (reg:SI 22))
2523 (clobber (reg:HI 26))
2524 (clobber (reg:HI 30))])]
2525 ""
2526 "this udivmodsi4 pattern should have been splitted;"
2527 ""
2528 [(set (reg:SI 22) (match_dup 1))
2529 (set (reg:SI 18) (match_dup 2))
1d26ac96
MM
2530 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2531 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2532 (clobber (reg:HI 26))
2533 (clobber (reg:HI 30))])
83613dbe
AH
2534 (set (match_dup 0) (reg:SI 18))
2535 (set (match_dup 3) (reg:SI 22))]
1d26ac96
MM
2536 "")
2537
2538(define_insn "*udivmodsi4_call"
2539 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2540 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2541 (clobber (reg:HI 26))
2542 (clobber (reg:HI 30))]
2543 ""
2544 "%~call __udivmodsi4"
25f2e176 2545 [(set_attr "type" "xcall")
1d26ac96
MM
2546 (set_attr "cc" "clobber")])
2547
90e7678c
DC
2548;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2549; and
2550
2551(define_insn "andqi3"
2552 [(set (match_operand:QI 0 "register_operand" "=r,d")
2553 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2554 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2555 ""
2556 "@
2557 and %0,%2
2558 andi %0,lo8(%2)"
2559 [(set_attr "length" "1,1")
2560 (set_attr "cc" "set_zn,set_zn")])
2561
2562(define_insn "andhi3"
6ebe2d6c
GJL
2563 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2564 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2565 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2566 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
90e7678c 2567 ""
6ebe2d6c
GJL
2568 {
2569 if (which_alternative == 0)
2570 return "and %A0,%A2\;and %B0,%B2";
2571 else if (which_alternative == 1)
2572 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2573
2574 return avr_out_bitop (insn, operands, NULL);
2575 }
2576 [(set_attr "length" "2,2,2,4,4")
8a6a05ce 2577 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
6ebe2d6c 2578 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
90e7678c 2579
e4fe948a
GJL
2580(define_insn "andpsi3"
2581 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2582 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2583 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2584 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2585 ""
2586 {
2587 if (which_alternative == 0)
2588 return "and %A0,%A2" CR_TAB
2589 "and %B0,%B2" CR_TAB
2590 "and %C0,%C2";
2591
2592 return avr_out_bitop (insn, operands, NULL);
2593 }
2594 [(set_attr "length" "3,3,6,6")
2595 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2596 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2597
90e7678c 2598(define_insn "andsi3"
6ebe2d6c
GJL
2599 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2600 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2601 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2602 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
90e7678c 2603 ""
6ebe2d6c
GJL
2604 {
2605 if (which_alternative == 0)
2606 return "and %0,%2" CR_TAB
2607 "and %B0,%B2" CR_TAB
2608 "and %C0,%C2" CR_TAB
2609 "and %D0,%D2";
2610
2611 return avr_out_bitop (insn, operands, NULL);
2612 }
2613 [(set_attr "length" "4,4,8,8")
8a6a05ce 2614 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
6ebe2d6c 2615 (set_attr "cc" "set_n,clobber,clobber,clobber")])
90e7678c 2616
d3dd4dbd
AS
2617(define_peephole2 ; andi
2618 [(set (match_operand:QI 0 "d_register_operand" "")
2619 (and:QI (match_dup 0)
2620 (match_operand:QI 1 "const_int_operand" "")))
2621 (set (match_dup 0)
2622 (and:QI (match_dup 0)
2623 (match_operand:QI 2 "const_int_operand" "")))]
2624 ""
2625 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2626 {
2627 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2628 })
2629
90e7678c
DC
2630;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2631;; ior
2632
2633(define_insn "iorqi3"
2634 [(set (match_operand:QI 0 "register_operand" "=r,d")
2635 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2636 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2637 ""
2638 "@
2639 or %0,%2
2640 ori %0,lo8(%2)"
2641 [(set_attr "length" "1,1")
2642 (set_attr "cc" "set_zn,set_zn")])
2643
2644(define_insn "iorhi3"
6ebe2d6c
GJL
2645 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2646 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2647 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2648 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
90e7678c 2649 ""
6ebe2d6c
GJL
2650 {
2651 if (which_alternative == 0)
2652 return "or %A0,%A2\;or %B0,%B2";
2653 else if (which_alternative == 1)
2654 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
90e7678c 2655
6ebe2d6c
GJL
2656 return avr_out_bitop (insn, operands, NULL);
2657 }
2658 [(set_attr "length" "2,2,2,4,4")
8a6a05ce 2659 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
6ebe2d6c 2660 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
90e7678c 2661
e4fe948a
GJL
2662(define_insn "iorpsi3"
2663 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2664 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2665 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
2666 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2667 ""
2668 {
2669 if (which_alternative == 0)
2670 return "or %A0,%A2" CR_TAB
2671 "or %B0,%B2" CR_TAB
2672 "or %C0,%C2";
2673
2674 return avr_out_bitop (insn, operands, NULL);
2675 }
2676 [(set_attr "length" "3,3,6,6")
2677 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2678 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2679
90e7678c 2680(define_insn "iorsi3"
6ebe2d6c
GJL
2681 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2682 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2683 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2684 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
90e7678c 2685 ""
6ebe2d6c
GJL
2686 {
2687 if (which_alternative == 0)
2688 return "or %0,%2" CR_TAB
2689 "or %B0,%B2" CR_TAB
2690 "or %C0,%C2" CR_TAB
2691 "or %D0,%D2";
90e7678c 2692
6ebe2d6c
GJL
2693 return avr_out_bitop (insn, operands, NULL);
2694 }
2695 [(set_attr "length" "4,4,8,8")
8a6a05ce 2696 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
6ebe2d6c 2697 (set_attr "cc" "set_n,clobber,clobber,clobber")])
90e7678c
DC
2698
2699;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2700;; xor
2701
2702(define_insn "xorqi3"
2703 [(set (match_operand:QI 0 "register_operand" "=r")
2704 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2705 (match_operand:QI 2 "register_operand" "r")))]
2706 ""
2707 "eor %0,%2"
2708 [(set_attr "length" "1")
2709 (set_attr "cc" "set_zn")])
2710
2711(define_insn "xorhi3"
6ebe2d6c
GJL
2712 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
2713 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
2714 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
2715 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
90e7678c 2716 ""
6ebe2d6c
GJL
2717 {
2718 if (which_alternative == 0)
2719 return "eor %A0,%A2\;eor %B0,%B2";
2720
2721 return avr_out_bitop (insn, operands, NULL);
2722 }
2723 [(set_attr "length" "2,2,4")
8a6a05ce 2724 (set_attr "adjust_len" "*,out_bitop,out_bitop")
6ebe2d6c 2725 (set_attr "cc" "set_n,clobber,clobber")])
90e7678c 2726
e4fe948a
GJL
2727(define_insn "xorpsi3"
2728 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
2729 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
2730 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
2731 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2732 ""
2733 {
2734 if (which_alternative == 0)
2735 return "eor %A0,%A2" CR_TAB
2736 "eor %B0,%B2" CR_TAB
2737 "eor %C0,%C2";
2738
2739 return avr_out_bitop (insn, operands, NULL);
2740 }
2741 [(set_attr "length" "3,6,6")
2742 (set_attr "adjust_len" "*,out_bitop,out_bitop")
2743 (set_attr "cc" "set_n,clobber,clobber")])
2744
90e7678c 2745(define_insn "xorsi3"
6ebe2d6c
GJL
2746 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
2747 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
2748 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
2749 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
90e7678c 2750 ""
6ebe2d6c
GJL
2751 {
2752 if (which_alternative == 0)
2753 return "eor %0,%2" CR_TAB
2754 "eor %B0,%B2" CR_TAB
2755 "eor %C0,%C2" CR_TAB
2756 "eor %D0,%D2";
2757
2758 return avr_out_bitop (insn, operands, NULL);
2759 }
2760 [(set_attr "length" "4,8,8")
8a6a05ce 2761 (set_attr "adjust_len" "*,out_bitop,out_bitop")
6ebe2d6c 2762 (set_attr "cc" "set_n,clobber,clobber")])
90e7678c 2763
15fe850f 2764;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
d3dd4dbd
AS
2765;; swap
2766
15fe850f
AS
2767(define_expand "rotlqi3"
2768 [(set (match_operand:QI 0 "register_operand" "")
5d94b988
GJL
2769 (rotate:QI (match_operand:QI 1 "register_operand" "")
2770 (match_operand:QI 2 "const_0_to_7_operand" "")))]
15fe850f 2771 ""
5d94b988
GJL
2772 {
2773 if (!CONST_INT_P (operands[2]))
2774 FAIL;
15fe850f 2775
5d94b988
GJL
2776 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
2777 })
2778
2779;; Expander used by __builtin_avr_swap
2780(define_expand "rotlqi3_4"
2781 [(set (match_operand:QI 0 "register_operand" "")
2782 (rotate:QI (match_operand:QI 1 "register_operand" "")
2783 (const_int 4)))])
2784
2785(define_insn "*rotlqi3"
2786 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
2787 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
2788 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
d3dd4dbd 2789 ""
5d94b988
GJL
2790 "@
2791 lsl %0\;adc %0,__zero_reg__
2792 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
2793 swap %0\;bst %0,0\;ror %0\;bld %0,7
2794 swap %0
2795 swap %0\;lsl %0\;adc %0,__zero_reg__
2796 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
2797 bst %0,0\;ror %0\;bld %0,7
2798 "
2799 [(set_attr "length" "2,4,4,1,3,5,3,0")
2800 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
d3dd4dbd 2801
58f0ea2f
AH
2802;; Split all rotates of HI,SI and DImode registers where rotation is by
2803;; a whole number of bytes. The split creates the appropriate moves and
2804;; considers all overlap situations. DImode is split before reload.
15fe850f 2805
58f0ea2f
AH
2806;; HImode does not need scratch. Use attribute for this constraint.
2807;; Use QI scratch for DI mode as this is often split into byte sized operands.
15fe850f 2808
e4fe948a
GJL
2809(define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
2810(define_mode_attr rotsmode [(DI "QI") (SI "HI") (PSI "QI") (HI "QI")])
58f0ea2f 2811
5d94b988 2812;; "rotlhi3"
e4fe948a 2813;; "rotlpsi3"
5d94b988
GJL
2814;; "rotlsi3"
2815;; "rotldi3"
58f0ea2f
AH
2816(define_expand "rotl<mode>3"
2817 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
5d94b988
GJL
2818 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2819 (match_operand:VOID 2 "const_int_operand" "")))
2820 (clobber (match_dup 3))])]
15fe850f 2821 ""
58f0ea2f 2822 {
5d94b988
GJL
2823 int offset;
2824
2825 if (!CONST_INT_P (operands[2]))
2826 FAIL;
2827
2828 offset = INTVAL (operands[2]);
2829
2830 if (0 == offset % 8)
d772f97c 2831 {
5d94b988 2832 if (AVR_HAVE_MOVW && 0 == offset % 16)
d772f97c
GJL
2833 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2834 else
2835 operands[3] = gen_rtx_SCRATCH (QImode);
2836 }
5d94b988
GJL
2837 else if (<MODE>mode != DImode
2838 && (offset == 1
2839 || offset == GET_MODE_BITSIZE (<MODE>mode) -1))
2840 {
2841 /*; Support rotate left/right by 1 */
2842
2843 emit_move_insn (operands[0],
2844 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
2845 DONE;
2846 }
d772f97c
GJL
2847 else
2848 FAIL;
2849 })
15fe850f 2850
5d94b988
GJL
2851(define_insn "*rotlhi2.1"
2852 [(set (match_operand:HI 0 "register_operand" "=r")
2853 (rotate:HI (match_operand:HI 1 "register_operand" "0")
2854 (const_int 1)))]
2855 ""
2856 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
2857 [(set_attr "length" "3")
2858 (set_attr "cc" "clobber")])
2859
2860(define_insn "*rotlhi2.15"
2861 [(set (match_operand:HI 0 "register_operand" "=r")
2862 (rotate:HI (match_operand:HI 1 "register_operand" "0")
2863 (const_int 15)))]
2864 ""
2865 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
2866 [(set_attr "length" "3")
2867 (set_attr "cc" "clobber")])
2868
e4fe948a
GJL
2869(define_insn "*rotlpsi2.1"
2870 [(set (match_operand:PSI 0 "register_operand" "=r")
2871 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
2872 (const_int 1)))]
2873 ""
2874 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
2875 [(set_attr "length" "4")
2876 (set_attr "cc" "clobber")])
2877
2878(define_insn "*rotlpsi2.23"
2879 [(set (match_operand:PSI 0 "register_operand" "=r")
2880 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
2881 (const_int 23)))]
2882 ""
2883 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
2884 [(set_attr "length" "5")
2885 (set_attr "cc" "clobber")])
2886
5d94b988
GJL
2887(define_insn "*rotlsi2.1"
2888 [(set (match_operand:SI 0 "register_operand" "=r")
2889 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2890 (const_int 1)))]
2891 ""
2892 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
2893 [(set_attr "length" "5")
2894 (set_attr "cc" "clobber")])
2895
2896(define_insn "*rotlsi2.31"
2897 [(set (match_operand:SI 0 "register_operand" "=r")
2898 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2899 (const_int 31)))]
2900 ""
2901 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
2902 [(set_attr "length" "6")
2903 (set_attr "cc" "clobber")])
15fe850f 2904
58f0ea2f
AH
2905;; Overlapping non-HImode registers often (but not always) need a scratch.
2906;; The best we can do is use early clobber alternative "#&r" so that
2907;; completely non-overlapping operands dont get a scratch but # so register
2908;; allocation does not prefer non-overlapping.
15fe850f 2909
ee7e3ad3 2910
5d94b988
GJL
2911;; Split word aligned rotates using scratch that is mode dependent.
2912
2913;; "*rotwhi"
2914;; "*rotwsi"
2915;; "*rotwdi"
58f0ea2f
AH
2916(define_insn_and_split "*rotw<mode>"
2917 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
d772f97c
GJL
2918 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2919 (match_operand 2 "const_int_operand" "n,n,n")))
2920 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2921 "AVR_HAVE_MOVW
2922 && CONST_INT_P (operands[2])
e4fe948a 2923 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
d772f97c 2924 && 0 == INTVAL (operands[2]) % 16"
58f0ea2f
AH
2925 "#"
2926 "&& (reload_completed || <MODE>mode == DImode)"
ee7e3ad3 2927 [(const_int 0)]
d772f97c
GJL
2928 {
2929 avr_rotate_bytes (operands);
2930 DONE;
2931 })
58f0ea2f
AH
2932
2933
5d94b988
GJL
2934;; Split byte aligned rotates using scratch that is always QI mode.
2935
2936;; "*rotbhi"
e4fe948a 2937;; "*rotbpsi"
5d94b988
GJL
2938;; "*rotbsi"
2939;; "*rotbdi"
58f0ea2f
AH
2940(define_insn_and_split "*rotb<mode>"
2941 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
d772f97c
GJL
2942 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2943 (match_operand 2 "const_int_operand" "n,n,n")))
2944 (clobber (match_scratch:QI 3 "=<rotx>"))]
2945 "CONST_INT_P (operands[2])
2946 && (8 == INTVAL (operands[2]) % 16
e4fe948a
GJL
2947 || ((!AVR_HAVE_MOVW
2948 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
d772f97c 2949 && 0 == INTVAL (operands[2]) % 16))"
58f0ea2f
AH
2950 "#"
2951 "&& (reload_completed || <MODE>mode == DImode)"
ee7e3ad3 2952 [(const_int 0)]
d772f97c
GJL
2953 {
2954 avr_rotate_bytes (operands);
2955 DONE;
2956 })
58f0ea2f 2957
15fe850f 2958
90e7678c
DC
2959;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2960;; arithmetic shift left
2961
d3dd4dbd
AS
2962(define_expand "ashlqi3"
2963 [(set (match_operand:QI 0 "register_operand" "")
7c209481
GJL
2964 (ashift:QI (match_operand:QI 1 "register_operand" "")
2965 (match_operand:QI 2 "nop_general_operand" "")))])
d3dd4dbd
AS
2966
2967(define_split ; ashlqi3_const4
2968 [(set (match_operand:QI 0 "d_register_operand" "")
2969 (ashift:QI (match_dup 0)
2970 (const_int 4)))]
2971 ""
15fe850f 2972 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
2973 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2974 "")
2975
2976(define_split ; ashlqi3_const5
2977 [(set (match_operand:QI 0 "d_register_operand" "")
2978 (ashift:QI (match_dup 0)
2979 (const_int 5)))]
2980 ""
15fe850f 2981 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
2982 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2983 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2984 "")
2985
2986(define_split ; ashlqi3_const6
2987 [(set (match_operand:QI 0 "d_register_operand" "")
2988 (ashift:QI (match_dup 0)
2989 (const_int 6)))]
2990 ""
15fe850f 2991 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
2992 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2993 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2994 "")
2995
2996(define_insn "*ashlqi3"
7c209481
GJL
2997 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
2998 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
2999 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
90e7678c 3000 ""
7c209481
GJL
3001 {
3002 return ashlqi3_out (insn, operands, NULL);
3003 }
a3cf5992 3004 [(set_attr "length" "5,0,1,2,4,6,9")
8a6a05ce 3005 (set_attr "adjust_len" "ashlqi")
a3cf5992 3006 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
90e7678c 3007
28e801e2 3008(define_insn "ashlhi3"
7c209481
GJL
3009 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3010 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3011 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
90e7678c 3012 ""
7c209481
GJL
3013 {
3014 return ashlhi3_out (insn, operands, NULL);
3015 }
a3cf5992 3016 [(set_attr "length" "6,0,2,2,4,10,10")
8a6a05ce 3017 (set_attr "adjust_len" "ashlhi")
a3cf5992 3018 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
90e7678c 3019
4ada410b
GJL
3020
3021;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3022;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3023
3024;; "*ashluqihiqi3"
3025;; "*ashlsqihiqi3"
7ece3881 3026(define_insn_and_split "*ashl<extend_su>qihiqi3"
4ada410b
GJL
3027 [(set (match_operand:QI 0 "register_operand" "=r")
3028 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3029 (match_operand:QI 2 "register_operand" "r"))
3030 0))]
3031 ""
3032 "#"
3033 ""
3034 [(set (match_dup 0)
3035 (ashift:QI (match_dup 1)
3036 (match_dup 2)))]
3037 "")
3038
3039;; ??? Combiner does not recognize that it could split the following insn;
3040;; presumably because he has no register handy?
3041
3042;; "*ashluqihiqi3.mem"
3043;; "*ashlsqihiqi3.mem"
7ece3881 3044(define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
4ada410b
GJL
3045 [(set (match_operand:QI 0 "memory_operand" "=m")
3046 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3047 (match_operand:QI 2 "register_operand" "r"))
3048 0))]
3049 "!reload_completed"
3050 { gcc_unreachable(); }
3051 "&& 1"
3052 [(set (match_dup 3)
3053 (ashift:QI (match_dup 1)
3054 (match_dup 2)))
3055 (set (match_dup 0)
3056 (match_dup 3))]
3057 {
7ece3881 3058 operands[3] = gen_reg_rtx (QImode);
4ada410b
GJL
3059 })
3060
3061;; Similar.
3062
3063(define_insn_and_split "*ashlhiqi3"
3064 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3065 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3066 (match_operand:QI 2 "register_operand" "r")) 0))]
3067 "!reload_completed"
3068 { gcc_unreachable(); }
3069 "&& 1"
3070 [(set (match_dup 4)
3071 (ashift:QI (match_dup 3)
3072 (match_dup 2)))
3073 (set (match_dup 0)
3074 (match_dup 4))]
3075 {
3076 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
7ece3881 3077 operands[4] = gen_reg_rtx (QImode);
4ada410b
GJL
3078 })
3079
3080;; High part of 16-bit shift is unused after the instruction:
3081;; No need to compute it, map to 8-bit shift.
3082
3083(define_peephole2
3084 [(set (match_operand:HI 0 "register_operand" "")
3085 (ashift:HI (match_dup 0)
3086 (match_operand:QI 1 "register_operand" "")))]
3087 ""
3088 [(set (match_dup 2)
3089 (ashift:QI (match_dup 2)
3090 (match_dup 1)))
3091 (clobber (match_dup 3))]
3092 {
3093 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3094
3095 if (!peep2_reg_dead_p (1, operands[3]))
3096 FAIL;
3097
3098 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3099 })
3100
3101
28e801e2 3102(define_insn "ashlsi3"
7c209481
GJL
3103 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3104 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3105 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
90e7678c 3106 ""
7c209481
GJL
3107 {
3108 return ashlsi3_out (insn, operands, NULL);
3109 }
a3cf5992 3110 [(set_attr "length" "8,0,4,4,8,10,12")
8a6a05ce 3111 (set_attr "adjust_len" "ashlsi")
a3cf5992 3112 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
90e7678c 3113
afee2a52
MM
3114;; Optimize if a scratch register from LD_REGS happens to be available.
3115
d3dd4dbd
AS
3116(define_peephole2 ; ashlqi3_l_const4
3117 [(set (match_operand:QI 0 "l_register_operand" "")
3118 (ashift:QI (match_dup 0)
3119 (const_int 4)))
3120 (match_scratch:QI 1 "d")]
3121 ""
15fe850f 3122 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3123 (set (match_dup 1) (const_int -16))
3124 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3125 "")
3126
3127(define_peephole2 ; ashlqi3_l_const5
3128 [(set (match_operand:QI 0 "l_register_operand" "")
3129 (ashift:QI (match_dup 0)
3130 (const_int 5)))
3131 (match_scratch:QI 1 "d")]
3132 ""
15fe850f 3133 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3134 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3135 (set (match_dup 1) (const_int -32))
3136 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3137 "")
3138
3139(define_peephole2 ; ashlqi3_l_const6
3140 [(set (match_operand:QI 0 "l_register_operand" "")
3141 (ashift:QI (match_dup 0)
3142 (const_int 6)))
3143 (match_scratch:QI 1 "d")]
3144 ""
15fe850f 3145 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3146 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3147 (set (match_dup 1) (const_int -64))
3148 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3149 "")
3150
afee2a52
MM
3151(define_peephole2
3152 [(match_scratch:QI 3 "d")
3153 (set (match_operand:HI 0 "register_operand" "")
3154 (ashift:HI (match_operand:HI 1 "register_operand" "")
3155 (match_operand:QI 2 "const_int_operand" "")))]
3156 ""
3157 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3158 (clobber (match_dup 3))])]
1cf0a7f1 3159 "")
afee2a52
MM
3160
3161(define_insn "*ashlhi3_const"
a3cf5992 3162 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
7c209481
GJL
3163 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3164 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3165 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
afee2a52 3166 "reload_completed"
7c209481
GJL
3167 {
3168 return ashlhi3_out (insn, operands, NULL);
3169 }
a3cf5992 3170 [(set_attr "length" "0,2,2,4,10")
8a6a05ce 3171 (set_attr "adjust_len" "ashlhi")
a3cf5992 3172 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
afee2a52
MM
3173
3174(define_peephole2
3175 [(match_scratch:QI 3 "d")
3176 (set (match_operand:SI 0 "register_operand" "")
3177 (ashift:SI (match_operand:SI 1 "register_operand" "")
3178 (match_operand:QI 2 "const_int_operand" "")))]
3179 ""
3180 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3181 (clobber (match_dup 3))])]
1cf0a7f1 3182 "")
afee2a52
MM
3183
3184(define_insn "*ashlsi3_const"
a3cf5992 3185 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7c209481
GJL
3186 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3187 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3188 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
afee2a52 3189 "reload_completed"
7c209481
GJL
3190 {
3191 return ashlsi3_out (insn, operands, NULL);
3192 }
a3cf5992 3193 [(set_attr "length" "0,4,4,10")
8a6a05ce 3194 (set_attr "adjust_len" "ashlsi")
a3cf5992 3195 (set_attr "cc" "none,set_n,clobber,clobber")])
afee2a52 3196
e4fe948a
GJL
3197(define_insn "ashlpsi3"
3198 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3199 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3200 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3201 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3202 ""
3203 {
3204 return avr_out_ashlpsi3 (insn, operands, NULL);
3205 }
3206 [(set_attr "adjust_len" "ashlpsi")
3207 (set_attr "cc" "clobber")])
3208
90e7678c
DC
3209;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3210;; arithmetic shift right
3211
28e801e2 3212(define_insn "ashrqi3"
7c209481
GJL
3213 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3214 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3215 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
90e7678c 3216 ""
7c209481
GJL
3217 {
3218 return ashrqi3_out (insn, operands, NULL);
3219 }
1cd12949 3220 [(set_attr "length" "5,0,1,2,5,4,9")
8a6a05ce 3221 (set_attr "adjust_len" "ashrqi")
1cd12949 3222 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
90e7678c 3223
28e801e2 3224(define_insn "ashrhi3"
7c209481
GJL
3225 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3226 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3227 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
90e7678c 3228 ""
7c209481
GJL
3229 {
3230 return ashrhi3_out (insn, operands, NULL);
3231 }
a3cf5992 3232 [(set_attr "length" "6,0,2,4,4,10,10")
8a6a05ce 3233 (set_attr "adjust_len" "ashrhi")
a3cf5992 3234 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
90e7678c 3235
e4fe948a
GJL
3236(define_insn "ashrpsi3"
3237 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3238 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3239 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3240 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3241 ""
3242 {
3243 return avr_out_ashrpsi3 (insn, operands, NULL);
3244 }
3245 [(set_attr "adjust_len" "ashrpsi")
3246 (set_attr "cc" "clobber")])
3247
28e801e2 3248(define_insn "ashrsi3"
7c209481
GJL
3249 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3250 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3251 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
90e7678c 3252 ""
7c209481
GJL
3253 {
3254 return ashrsi3_out (insn, operands, NULL);
3255 }
a3cf5992 3256 [(set_attr "length" "8,0,4,6,8,10,12")
8a6a05ce 3257 (set_attr "adjust_len" "ashrsi")
a3cf5992 3258 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
afee2a52
MM
3259
3260;; Optimize if a scratch register from LD_REGS happens to be available.
3261
3262(define_peephole2
3263 [(match_scratch:QI 3 "d")
3264 (set (match_operand:HI 0 "register_operand" "")
3265 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3266 (match_operand:QI 2 "const_int_operand" "")))]
3267 ""
3268 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3269 (clobber (match_dup 3))])]
1cf0a7f1 3270 "")
afee2a52
MM
3271
3272(define_insn "*ashrhi3_const"
a3cf5992 3273 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
7c209481
GJL
3274 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3275 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3276 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
afee2a52 3277 "reload_completed"
7c209481
GJL
3278 {
3279 return ashrhi3_out (insn, operands, NULL);
3280 }
a3cf5992 3281 [(set_attr "length" "0,2,4,4,10")
8a6a05ce 3282 (set_attr "adjust_len" "ashrhi")
a3cf5992 3283 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
afee2a52
MM
3284
3285(define_peephole2
3286 [(match_scratch:QI 3 "d")
3287 (set (match_operand:SI 0 "register_operand" "")
3288 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3289 (match_operand:QI 2 "const_int_operand" "")))]
3290 ""
3291 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3292 (clobber (match_dup 3))])]
1cf0a7f1 3293 "")
afee2a52
MM
3294
3295(define_insn "*ashrsi3_const"
a3cf5992 3296 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7c209481
GJL
3297 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3298 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3299 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
afee2a52 3300 "reload_completed"
7c209481
GJL
3301 {
3302 return ashrsi3_out (insn, operands, NULL);
3303 }
a3cf5992 3304 [(set_attr "length" "0,4,4,10")
8a6a05ce 3305 (set_attr "adjust_len" "ashrsi")
a3cf5992 3306 (set_attr "cc" "none,clobber,set_n,clobber")])
90e7678c
DC
3307
3308;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3309;; logical shift right
3310
d3dd4dbd 3311(define_expand "lshrqi3"
7c209481
GJL
3312 [(set (match_operand:QI 0 "register_operand" "")
3313 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3314 (match_operand:QI 2 "nop_general_operand" "")))])
d3dd4dbd
AS
3315
3316(define_split ; lshrqi3_const4
3317 [(set (match_operand:QI 0 "d_register_operand" "")
3318 (lshiftrt:QI (match_dup 0)
3319 (const_int 4)))]
3320 ""
15fe850f 3321 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3322 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3323 "")
3324
3325(define_split ; lshrqi3_const5
3326 [(set (match_operand:QI 0 "d_register_operand" "")
3327 (lshiftrt:QI (match_dup 0)
3328 (const_int 5)))]
3329 ""
15fe850f 3330 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3331 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3332 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3333 "")
3334
3335(define_split ; lshrqi3_const6
3336 [(set (match_operand:QI 0 "d_register_operand" "")
3337 (lshiftrt:QI (match_dup 0)
3338 (const_int 6)))]
3339 ""
15fe850f 3340 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3341 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3342 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3343 "")
3344
3345(define_insn "*lshrqi3"
7c209481
GJL
3346 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3347 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3348 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
90e7678c 3349 ""
7c209481
GJL
3350 {
3351 return lshrqi3_out (insn, operands, NULL);
3352 }
a3cf5992 3353 [(set_attr "length" "5,0,1,2,4,6,9")
8a6a05ce 3354 (set_attr "adjust_len" "lshrqi")
a3cf5992 3355 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
90e7678c 3356
28e801e2 3357(define_insn "lshrhi3"
7c209481
GJL
3358 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3359 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3360 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
90e7678c 3361 ""
7c209481
GJL
3362 {
3363 return lshrhi3_out (insn, operands, NULL);
3364 }
a3cf5992 3365 [(set_attr "length" "6,0,2,2,4,10,10")
8a6a05ce 3366 (set_attr "adjust_len" "lshrhi")
a3cf5992 3367 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
90e7678c 3368
e4fe948a
GJL
3369(define_insn "lshrpsi3"
3370 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3371 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3372 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3373 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3374 ""
3375 {
3376 return avr_out_lshrpsi3 (insn, operands, NULL);
3377 }
3378 [(set_attr "adjust_len" "lshrpsi")
3379 (set_attr "cc" "clobber")])
3380
28e801e2 3381(define_insn "lshrsi3"
7c209481
GJL
3382 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3383 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3384 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
adcd8f77 3385 ""
7c209481
GJL
3386 {
3387 return lshrsi3_out (insn, operands, NULL);
3388 }
a3cf5992 3389 [(set_attr "length" "8,0,4,4,8,10,12")
8a6a05ce 3390 (set_attr "adjust_len" "lshrsi")
a3cf5992 3391 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
90e7678c 3392
afee2a52
MM
3393;; Optimize if a scratch register from LD_REGS happens to be available.
3394
d3dd4dbd
AS
3395(define_peephole2 ; lshrqi3_l_const4
3396 [(set (match_operand:QI 0 "l_register_operand" "")
3397 (lshiftrt:QI (match_dup 0)
3398 (const_int 4)))
3399 (match_scratch:QI 1 "d")]
3400 ""
15fe850f 3401 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3402 (set (match_dup 1) (const_int 15))
3403 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3404 "")
3405
3406(define_peephole2 ; lshrqi3_l_const5
3407 [(set (match_operand:QI 0 "l_register_operand" "")
3408 (lshiftrt:QI (match_dup 0)
3409 (const_int 5)))
3410 (match_scratch:QI 1 "d")]
3411 ""
15fe850f 3412 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3413 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3414 (set (match_dup 1) (const_int 7))
3415 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3416 "")
3417
3418(define_peephole2 ; lshrqi3_l_const6
3419 [(set (match_operand:QI 0 "l_register_operand" "")
3420 (lshiftrt:QI (match_dup 0)
3421 (const_int 6)))
3422 (match_scratch:QI 1 "d")]
3423 ""
15fe850f 3424 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
d3dd4dbd
AS
3425 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3426 (set (match_dup 1) (const_int 3))
3427 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3428 "")
3429
afee2a52
MM
3430(define_peephole2
3431 [(match_scratch:QI 3 "d")
3432 (set (match_operand:HI 0 "register_operand" "")
3433 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3434 (match_operand:QI 2 "const_int_operand" "")))]
3435 ""
3436 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3437 (clobber (match_dup 3))])]
1cf0a7f1 3438 "")
afee2a52
MM
3439
3440(define_insn "*lshrhi3_const"
a3cf5992 3441 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
7c209481
GJL
3442 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3443 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3444 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
afee2a52 3445 "reload_completed"
7c209481
GJL
3446 {
3447 return lshrhi3_out (insn, operands, NULL);
3448 }
a3cf5992 3449 [(set_attr "length" "0,2,2,4,10")
8a6a05ce 3450 (set_attr "adjust_len" "lshrhi")
a3cf5992 3451 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
afee2a52
MM
3452
3453(define_peephole2
3454 [(match_scratch:QI 3 "d")
3455 (set (match_operand:SI 0 "register_operand" "")
3456 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3457 (match_operand:QI 2 "const_int_operand" "")))]
3458 ""
3459 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3460 (clobber (match_dup 3))])]
1cf0a7f1 3461 "")
afee2a52
MM
3462
3463(define_insn "*lshrsi3_const"
a3cf5992 3464 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7c209481
GJL
3465 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3466 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3467 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
afee2a52 3468 "reload_completed"
7c209481
GJL
3469 {
3470 return lshrsi3_out (insn, operands, NULL);
3471 }
a3cf5992 3472 [(set_attr "length" "0,4,4,10")
8a6a05ce 3473 (set_attr "adjust_len" "lshrsi")
a3cf5992 3474 (set_attr "cc" "none,clobber,clobber,clobber")])
afee2a52 3475
90e7678c
DC
3476;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3477;; abs
3478
3479(define_insn "absqi2"
3480 [(set (match_operand:QI 0 "register_operand" "=r")
3481 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3482 ""
1ca04dc8
DC
3483 "sbrc %0,7
3484 neg %0"
90e7678c
DC
3485 [(set_attr "length" "2")
3486 (set_attr "cc" "clobber")])
3487
3488
3489(define_insn "abssf2"
3490 [(set (match_operand:SF 0 "register_operand" "=d,r")
3491 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3492 ""
3493 "@
3494 andi %D0,0x7f
3495 clt\;bld %D0,7"
3496 [(set_attr "length" "1,2")
80b8585d 3497 (set_attr "cc" "set_n,clobber")])
90e7678c
DC
3498
3499;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3500;; neg
3501
3502(define_insn "negqi2"
3503 [(set (match_operand:QI 0 "register_operand" "=r")
3504 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3505 ""
3506 "neg %0"
3507 [(set_attr "length" "1")
3508 (set_attr "cc" "set_zn")])
3509
8b42d3de
GJL
3510(define_insn "*negqihi2"
3511 [(set (match_operand:HI 0 "register_operand" "=r")
3512 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3513 ""
3514 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3515 [(set_attr "length" "4")
3516 (set_attr "cc" "set_n")])
3517
90e7678c 3518(define_insn "neghi2"
155b14a8
DC
3519 [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
3520 (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
90e7678c
DC
3521 ""
3522 "@
3523 com %B0\;neg %A0\;sbci %B0,lo8(-1)
155b14a8
DC
3524 com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
3525 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3526 [(set_attr "length" "3,4,4")
3527 (set_attr "cc" "set_czn,set_n,set_czn")])
90e7678c 3528
e4fe948a
GJL
3529(define_insn "negpsi2"
3530 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3531 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3532 ""
3533 "@
3534 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3535 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3536 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3537 [(set_attr "length" "5,6,6")
3538 (set_attr "cc" "set_czn,set_n,set_czn")])
3539
155b14a8 3540(define_insn "negsi2"
7c3297ce
GJL
3541 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3542 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
90e7678c
DC
3543 ""
3544 "@
3545 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
bad3869a 3546 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
7c3297ce
GJL
3547 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3548 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3549 [(set_attr "length" "7,8,8,7")
3550 (set_attr "isa" "*,*,mov,movw")
3551 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
6bec29c9
DC
3552
3553(define_insn "negsf2"
3554 [(set (match_operand:SF 0 "register_operand" "=d,r")
3555 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3556 ""
3557 "@
3558 subi %D0,0x80
3559 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3560 [(set_attr "length" "1,4")
3561 (set_attr "cc" "set_n,set_n")])
90e7678c
DC
3562
3563;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3564;; not
3565
3566(define_insn "one_cmplqi2"
3567 [(set (match_operand:QI 0 "register_operand" "=r")
3568 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3569 ""
3570 "com %0"
3571 [(set_attr "length" "1")
3572 (set_attr "cc" "set_czn")])
3573
3574(define_insn "one_cmplhi2"
3575 [(set (match_operand:HI 0 "register_operand" "=r")
3576 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3577 ""
1ca04dc8
DC
3578 "com %0
3579 com %B0"
90e7678c
DC
3580 [(set_attr "length" "2")
3581 (set_attr "cc" "set_n")])
3582
e4fe948a
GJL
3583(define_insn "one_cmplpsi2"
3584 [(set (match_operand:PSI 0 "register_operand" "=r")
3585 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3586 ""
3587 "com %0\;com %B0\;com %C0"
3588 [(set_attr "length" "3")
3589 (set_attr "cc" "set_n")])
3590
90e7678c
DC
3591(define_insn "one_cmplsi2"
3592 [(set (match_operand:SI 0 "register_operand" "=r")
3593 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3594 ""
1ca04dc8
DC
3595 "com %0
3596 com %B0
3597 com %C0
3598 com %D0"
90e7678c
DC
3599 [(set_attr "length" "4")
3600 (set_attr "cc" "set_n")])
3601
3602;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3603;; sign extend
3604
296799ba
GJL
3605;; We keep combiner from inserting hard registers into the input of sign- and
3606;; zero-extends. A hard register in the input operand is not wanted because
3607;; 32-bit multiply patterns clobber some hard registers and extends with a
3608;; hard register that overlaps these clobbers won't be combined to a widening
3609;; multiplication. There is no need for combine to propagate hard registers,
3610;; register allocation can do it just as well.
3611
90e7678c
DC
3612(define_insn "extendqihi2"
3613 [(set (match_operand:HI 0 "register_operand" "=r,r")
296799ba 3614 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
90e7678c
DC
3615 ""
3616 "@
3617 clr %B0\;sbrc %0,7\;com %B0
3618 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3619 [(set_attr "length" "3,4")
3620 (set_attr "cc" "set_n,set_n")])
3621
e4fe948a
GJL
3622(define_insn "extendqipsi2"
3623 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3624 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3625 ""
3626 "@
3627 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3628 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3629 [(set_attr "length" "4,5")
3630 (set_attr "cc" "set_n,set_n")])
3631
90e7678c
DC
3632(define_insn "extendqisi2"
3633 [(set (match_operand:SI 0 "register_operand" "=r,r")
296799ba 3634 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
90e7678c
DC
3635 ""
3636 "@
3637 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3638 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3639 [(set_attr "length" "5,6")
80b8585d 3640 (set_attr "cc" "set_n,set_n")])
90e7678c 3641
e4fe948a
GJL
3642(define_insn "extendhipsi2"
3643 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3644 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3645 ""
3646 "@
3647 clr %C0\;sbrc %B0,7\;com %C0
3648 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
3649 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
3650 [(set_attr "length" "3,5,4")
3651 (set_attr "isa" "*,mov,movw")
3652 (set_attr "cc" "set_n")])
3653
90e7678c 3654(define_insn "extendhisi2"
7c3297ce
GJL
3655 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3656 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
90e7678c
DC
3657 ""
3658 "@
3659 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
7c3297ce
GJL
3660 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3661 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3662 [(set_attr "length" "4,6,5")
3663 (set_attr "isa" "*,mov,movw")
3664 (set_attr "cc" "set_n")])
90e7678c 3665
e4fe948a
GJL
3666(define_insn "extendpsisi2"
3667 [(set (match_operand:SI 0 "register_operand" "=r")
3668 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
3669 ""
3670 "clr %D0\;sbrc %C0,7\;com %D0"
3671 [(set_attr "length" "3")
3672 (set_attr "cc" "set_n")])
3673
90e7678c
DC
3674;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3675;; zero extend
3676
2d0c44e6
AS
3677(define_insn_and_split "zero_extendqihi2"
3678 [(set (match_operand:HI 0 "register_operand" "=r")
296799ba 3679 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
90e7678c 3680 ""
2d0c44e6
AS
3681 "#"
3682 "reload_completed"
3683 [(set (match_dup 2) (match_dup 1))
3684 (set (match_dup 3) (const_int 0))]
3f02a5f3
JR
3685{
3686 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
3687 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
3688
3689 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
3690 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
3691})
90e7678c 3692
e4fe948a
GJL
3693(define_insn_and_split "zero_extendqipsi2"
3694 [(set (match_operand:PSI 0 "register_operand" "=r")
3695 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3696 ""
3697 "#"
3698 "reload_completed"
3699 [(set (match_dup 2) (match_dup 1))
3700 (set (match_dup 3) (const_int 0))
3701 (set (match_dup 4) (const_int 0))]
3702 {
3703 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
3704 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
3705 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
3706 })
3707
2d0c44e6
AS
3708(define_insn_and_split "zero_extendqisi2"
3709 [(set (match_operand:SI 0 "register_operand" "=r")
296799ba 3710 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
90e7678c 3711 ""
2d0c44e6
AS
3712 "#"
3713 "reload_completed"
3714 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
3715 (set (match_dup 3) (const_int 0))]
3f02a5f3
JR
3716{
3717 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3718 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3719
3720 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3721 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3722})
90e7678c 3723
e4fe948a
GJL
3724(define_insn_and_split "zero_extendhipsi2"
3725 [(set (match_operand:PSI 0 "register_operand" "=r")
3726 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
3727 ""
3728 "#"
3729 "reload_completed"
3730 [(set (match_dup 2) (match_dup 1))
3731 (set (match_dup 3) (const_int 0))]
3732 {
3733 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
3734 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
3735 })
3736
7c209481
GJL
3737(define_insn_and_split "n_extendhipsi2"
3738 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
3739 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
3740 (match_operand:HI 2 "register_operand" "r,r,r,r")))
3741 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3742 ""
3743 "#"
3744 "reload_completed"
3745 [(set (match_dup 4) (match_dup 2))
3746 (set (match_dup 3) (match_dup 6))
3747 ; no-op move in the case where no scratch is needed
3748 (set (match_dup 5) (match_dup 3))]
3749 {
3750 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
3751 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
3752 operands[6] = operands[1];
3753
3754 if (GET_CODE (operands[3]) == SCRATCH)
3755 operands[3] = operands[5];
3756 })
3757
2d0c44e6 3758(define_insn_and_split "zero_extendhisi2"
296799ba
GJL
3759 [(set (match_operand:SI 0 "register_operand" "=r")
3760 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
90e7678c 3761 ""
2d0c44e6
AS
3762 "#"
3763 "reload_completed"
3764 [(set (match_dup 2) (match_dup 1))
3765 (set (match_dup 3) (const_int 0))]
3f02a5f3
JR
3766{
3767 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
3768 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
3769
3770 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
3771 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
3772})
2d0c44e6 3773
e4fe948a
GJL
3774(define_insn_and_split "zero_extendpsisi2"
3775 [(set (match_operand:SI 0 "register_operand" "=r")
3776 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
3777 ""
3778 "#"
3779 "reload_completed"
3780 [(set (match_dup 2) (match_dup 1))
3781 (set (match_dup 3) (const_int 0))]
3782 {
3783 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
3784 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
3785 })
3786
2d0c44e6
AS
3787(define_insn_and_split "zero_extendqidi2"
3788 [(set (match_operand:DI 0 "register_operand" "=r")
3789 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3790 ""
3791 "#"
3792 "reload_completed"
3793 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3794 (set (match_dup 3) (const_int 0))]
3f02a5f3
JR
3795{
3796 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3797 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3798
3799 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3800 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3801})
2d0c44e6
AS
3802
3803(define_insn_and_split "zero_extendhidi2"
3804 [(set (match_operand:DI 0 "register_operand" "=r")
3805 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3806 ""
3807 "#"
3808 "reload_completed"
3809 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
3810 (set (match_dup 3) (const_int 0))]
3f02a5f3
JR
3811{
3812 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3813 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3814
3815 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3816 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3817})
2d0c44e6
AS
3818
3819(define_insn_and_split "zero_extendsidi2"
3820 [(set (match_operand:DI 0 "register_operand" "=r")
3821 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3822 ""
3823 "#"
3824 "reload_completed"
3825 [(set (match_dup 2) (match_dup 1))
3826 (set (match_dup 3) (const_int 0))]
3f02a5f3
JR
3827{
3828 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
3829 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
3830
3831 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
3832 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
3833})
90e7678c
DC
3834
3835;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
3836;; compare
3837
f90b7a5a
PB
3838; Optimize negated tests into reverse compare if overflow is undefined.
3839(define_insn "*negated_tstqi"
90e7678c 3840 [(set (cc0)
f90b7a5a
PB
3841 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
3842 (const_int 0)))]
3843 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3844 "cp __zero_reg__,%0"
90e7678c
DC
3845 [(set_attr "cc" "compare")
3846 (set_attr "length" "1")])
3847
3d709466 3848(define_insn "*reversed_tstqi"
90e7678c 3849 [(set (cc0)
f90b7a5a 3850 (compare (const_int 0)
3d709466 3851 (match_operand:QI 0 "register_operand" "r")))]
90e7678c
DC
3852 ""
3853 "cp __zero_reg__,%0"
f90b7a5a
PB
3854[(set_attr "cc" "compare")
3855 (set_attr "length" "2")])
90e7678c 3856
f90b7a5a 3857(define_insn "*negated_tsthi"
90e7678c 3858 [(set (cc0)
f90b7a5a
PB
3859 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
3860 (const_int 0)))]
3861 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3862 "cp __zero_reg__,%A0
3863 cpc __zero_reg__,%B0"
3864[(set_attr "cc" "compare")
3865 (set_attr "length" "2")])
90e7678c 3866
f90b7a5a
PB
3867;; Leave here the clobber used by the cmphi pattern for simplicity, even
3868;; though it is unused, because this pattern is synthesized by avr_reorg.
3d709466 3869(define_insn "*reversed_tsthi"
90e7678c 3870 [(set (cc0)
3d709466 3871 (compare (const_int 0)
f90b7a5a
PB
3872 (match_operand:HI 0 "register_operand" "r")))
3873 (clobber (match_scratch:QI 1 "=X"))]
90e7678c
DC
3874 ""
3875 "cp __zero_reg__,%A0
3876 cpc __zero_reg__,%B0"
3877[(set_attr "cc" "compare")
3878 (set_attr "length" "2")])
3879
e4fe948a
GJL
3880(define_insn "*negated_tstpsi"
3881 [(set (cc0)
3882 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
3883 (const_int 0)))]
3884 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
3885 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
3886 [(set_attr "cc" "compare")
3887 (set_attr "length" "3")])
3888
3889(define_insn "*reversed_tstpsi"
3890 [(set (cc0)
3891 (compare (const_int 0)
3892 (match_operand:PSI 0 "register_operand" "r")))
3893 (clobber (match_scratch:QI 1 "=X"))]
3894 ""
3895 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
3896 [(set_attr "cc" "compare")
3897 (set_attr "length" "3")])
3898
f90b7a5a 3899(define_insn "*negated_tstsi"
90e7678c 3900 [(set (cc0)
f90b7a5a
PB
3901 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
3902 (const_int 0)))]
3903 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
3904 "cp __zero_reg__,%A0
3905 cpc __zero_reg__,%B0
3906 cpc __zero_reg__,%C0
3907 cpc __zero_reg__,%D0"
90e7678c
DC
3908 [(set_attr "cc" "compare")
3909 (set_attr "length" "4")])
3910
3d709466 3911(define_insn "*reversed_tstsi"
90e7678c 3912 [(set (cc0)
f90b7a5a
PB
3913 (compare (const_int 0)
3914 (match_operand:SI 0 "register_operand" "r")))
3915 (clobber (match_scratch:QI 1 "=X"))]
90e7678c
DC
3916 ""
3917 "cp __zero_reg__,%A0
3918 cpc __zero_reg__,%B0
3919 cpc __zero_reg__,%C0
3920 cpc __zero_reg__,%D0"
3921 [(set_attr "cc" "compare")
3922 (set_attr "length" "4")])
3923
3924
f90b7a5a 3925(define_insn "*cmpqi"
90e7678c 3926 [(set (cc0)
f90b7a5a
PB
3927 (compare (match_operand:QI 0 "register_operand" "r,r,d")
3928 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
90e7678c
DC
3929 ""
3930 "@
f90b7a5a 3931 tst %0
90e7678c
DC
3932 cp %0,%1
3933 cpi %0,lo8(%1)"
f90b7a5a
PB
3934 [(set_attr "cc" "compare,compare,compare")
3935 (set_attr "length" "1,1,1")])
90e7678c
DC
3936
3937(define_insn "*cmpqi_sign_extend"
3938 [(set (cc0)
a7c0acd0
GJL
3939 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
3940 (match_operand:HI 1 "s8_operand" "n")))]
3941 ""
90e7678c
DC
3942 "cpi %0,lo8(%1)"
3943 [(set_attr "cc" "compare")
3944 (set_attr "length" "1")])
3945
f90b7a5a 3946(define_insn "*cmphi"
90e7678c 3947 [(set (cc0)
a7c0acd0
GJL
3948 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
3949 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
3950 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
90e7678c 3951 ""
a7c0acd0
GJL
3952 {
3953 switch (which_alternative)
3954 {
3955 case 0:
3956 case 1:
3957 return avr_out_tsthi (insn, operands, NULL);
3958
3959 case 2:
3960 return "cp %A0,%A1\;cpc %B0,%B1";
3961
3962 case 3:
3963 return reg_unused_after (insn, operands[0])
3964 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
3965 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
3966
3967 case 4:
3968 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
3969 }
3970
3971 return avr_out_compare (insn, operands, NULL);
3972 }
3973 [(set_attr "cc" "compare")
3974 (set_attr "length" "1,2,2,3,4,2,4")
8a6a05ce 3975 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
90e7678c 3976
e4fe948a
GJL
3977(define_insn "*cmppsi"
3978 [(set (cc0)
3979 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
3980 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
3981 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
3982 ""
3983 {
3984 switch (which_alternative)
3985 {
3986 case 0:
3987 return avr_out_tstpsi (insn, operands, NULL);
3988
3989 case 1:
3990 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
3991
3992 case 2:
3993 return reg_unused_after (insn, operands[0])
3994 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
3995 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
3996
3997 case 3:
3998 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
3999 }
4000
4001 return avr_out_compare (insn, operands, NULL);
4002 }
4003 [(set_attr "cc" "compare")
4004 (set_attr "length" "3,3,5,6,3,7")
4005 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
90e7678c 4006
f90b7a5a 4007(define_insn "*cmpsi"
90e7678c 4008 [(set (cc0)
a7c0acd0
GJL
4009 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
4010 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
4011 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
90e7678c 4012 ""
a7c0acd0
GJL
4013 {
4014 if (0 == which_alternative)
4015 return avr_out_tstsi (insn, operands, NULL);
4016 else if (1 == which_alternative)
4017 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4018
4019 return avr_out_compare (insn, operands, NULL);
4020 }
4021 [(set_attr "cc" "compare")
4022 (set_attr "length" "4,4,4,5,8")
8a6a05ce 4023 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
3d709466 4024
3d709466 4025
90e7678c
DC
4026;; ----------------------------------------------------------------------
4027;; JUMP INSTRUCTIONS
4028;; ----------------------------------------------------------------------
4029;; Conditional jump instructions
4030
f90b7a5a
PB
4031(define_expand "cbranchsi4"
4032 [(parallel [(set (cc0)
4033 (compare (match_operand:SI 1 "register_operand" "")
4034 (match_operand:SI 2 "nonmemory_operand" "")))
4035 (clobber (match_scratch:QI 4 ""))])
4036 (set (pc)
4037 (if_then_else
4038 (match_operator 0 "ordered_comparison_operator" [(cc0)
4039 (const_int 0)])
4040 (label_ref (match_operand 3 "" ""))
4041 (pc)))]
4042 "")
4043
e4fe948a
GJL
4044(define_expand "cbranchpsi4"
4045 [(parallel [(set (cc0)
4046 (compare (match_operand:PSI 1 "register_operand" "")
4047 (match_operand:PSI 2 "nonmemory_operand" "")))
4048 (clobber (match_scratch:QI 4 ""))])
4049 (set (pc)
4050 (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0)
4051 (const_int 0)])
4052 (label_ref (match_operand 3 "" ""))
4053 (pc)))]
4054 "")
4055
f90b7a5a
PB
4056(define_expand "cbranchhi4"
4057 [(parallel [(set (cc0)
4058 (compare (match_operand:HI 1 "register_operand" "")
4059 (match_operand:HI 2 "nonmemory_operand" "")))
4060 (clobber (match_scratch:QI 4 ""))])
4061 (set (pc)
4062 (if_then_else
4063 (match_operator 0 "ordered_comparison_operator" [(cc0)
4064 (const_int 0)])
4065 (label_ref (match_operand 3 "" ""))
4066 (pc)))]
4067 "")
90e7678c 4068
f90b7a5a
PB
4069(define_expand "cbranchqi4"
4070 [(set (cc0)
4071 (compare (match_operand:QI 1 "register_operand" "")
4072 (match_operand:QI 2 "nonmemory_operand" "")))
4073 (set (pc)
4074 (if_then_else
4075 (match_operator 0 "ordered_comparison_operator" [(cc0)
4076 (const_int 0)])
4077 (label_ref (match_operand 3 "" ""))
4078 (pc)))]
4079 "")
90e7678c 4080
90e7678c 4081
331ca350 4082;; Test a single bit in a QI/HI/SImode register.
ed1f5d71
AH
4083;; Combine will create zero extract patterns for single bit tests.
4084;; permit any mode in source pattern by using VOIDmode.
4085
4086(define_insn "*sbrx_branch<mode>"
90e7678c
DC
4087 [(set (pc)
4088 (if_then_else
413fc59a 4089 (match_operator 0 "eqne_operator"
ed1f5d71
AH
4090 [(zero_extract:QIDI
4091 (match_operand:VOID 1 "register_operand" "r")
90e7678c 4092 (const_int 1)
331ca350 4093 (match_operand 2 "const_int_operand" "n"))
90e7678c
DC
4094 (const_int 0)])
4095 (label_ref (match_operand 3 "" ""))
4096 (pc)))]
413fc59a 4097 ""
331ca350 4098 "* return avr_out_sbxx_branch (insn, operands);"
7e3bd81e
DC
4099 [(set (attr "length")
4100 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4101 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4102 (const_int 2)
7c3297ce 4103 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7e3bd81e
DC
4104 (const_int 2)
4105 (const_int 4))))
90e7678c
DC
4106 (set_attr "cc" "clobber")])
4107
ed1f5d71
AH
4108;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
4109;; or for old peepholes.
4110;; Fixme - bitwise Mask will not work for DImode
90e7678c 4111
ed1f5d71 4112(define_insn "*sbrx_and_branch<mode>"
90e7678c
DC
4113 [(set (pc)
4114 (if_then_else
413fc59a 4115 (match_operator 0 "eqne_operator"
ed1f5d71
AH
4116 [(and:QISI
4117 (match_operand:QISI 1 "register_operand" "r")
4118 (match_operand:QISI 2 "single_one_operand" "n"))
90e7678c
DC
4119 (const_int 0)])
4120 (label_ref (match_operand 3 "" ""))
4121 (pc)))]
413fc59a 4122 ""
ed1f5d71
AH
4123{
4124 HOST_WIDE_INT bitnumber;
4125 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4126 operands[2] = GEN_INT (bitnumber);
4127 return avr_out_sbxx_branch (insn, operands);
4128}
7e3bd81e
DC
4129 [(set (attr "length")
4130 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4131 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4132 (const_int 2)
7c3297ce 4133 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7e3bd81e
DC
4134 (const_int 2)
4135 (const_int 4))))
90e7678c
DC
4136 (set_attr "cc" "clobber")])
4137
331ca350
MM
4138;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4139(define_peephole2
f90b7a5a
PB
4140 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4141 (const_int 0)))
331ca350
MM
4142 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4143 (label_ref (match_operand 1 "" ""))
4144 (pc)))]
4145 ""
38ce04d9 4146 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
cf2758e3
PB
4147 (const_int 1)
4148 (const_int 7))
331ca350
MM
4149 (const_int 0))
4150 (label_ref (match_dup 1))
4151 (pc)))]
4152 "")
4153
4154(define_peephole2
f90b7a5a
PB
4155 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4156 (const_int 0)))
331ca350
MM
4157 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4158 (label_ref (match_operand 1 "" ""))
4159 (pc)))]
4160 ""
38ce04d9 4161 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
cf2758e3
PB
4162 (const_int 1)
4163 (const_int 7))
331ca350
MM
4164 (const_int 0))
4165 (label_ref (match_dup 1))
4166 (pc)))]
4167 "")
4168
4169(define_peephole2
f90b7a5a
PB
4170 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4171 (const_int 0)))
4172 (clobber (match_operand:HI 2 ""))])
331ca350
MM
4173 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4174 (label_ref (match_operand 1 "" ""))
4175 (pc)))]
4176 ""
4177 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4178 (const_int 0))
4179 (label_ref (match_dup 1))
4180 (pc)))]
4181 "")
4182
4183(define_peephole2
f90b7a5a
PB
4184 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4185 (const_int 0)))
4186 (clobber (match_operand:HI 2 ""))])
331ca350
MM
4187 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4188 (label_ref (match_operand 1 "" ""))
4189 (pc)))]
4190 ""
4191 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4192 (const_int 0))
4193 (label_ref (match_dup 1))
4194 (pc)))]
4195 "")
4196
4197(define_peephole2
f90b7a5a
PB
4198 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4199 (const_int 0)))
4200 (clobber (match_operand:SI 2 ""))])
331ca350
MM
4201 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4202 (label_ref (match_operand 1 "" ""))
4203 (pc)))]
4204 ""
4205 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4206 (const_int 0))
4207 (label_ref (match_dup 1))
4208 (pc)))]
126dbce0 4209 "operands[2] = GEN_INT (-2147483647 - 1);")
331ca350
MM
4210
4211(define_peephole2
f90b7a5a
PB
4212 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4213 (const_int 0)))
4214 (clobber (match_operand:SI 2 ""))])
331ca350
MM
4215 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4216 (label_ref (match_operand 1 "" ""))
4217 (pc)))]
4218 ""
4219 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4220 (const_int 0))
4221 (label_ref (match_dup 1))
4222 (pc)))]
126dbce0 4223 "operands[2] = GEN_INT (-2147483647 - 1);")
331ca350 4224
90e7678c
DC
4225;; ************************************************************************
4226;; Implementation of conditional jumps here.
4227;; Compare with 0 (test) jumps
4228;; ************************************************************************
4229
4230(define_insn "branch"
4231 [(set (pc)
413fc59a 4232 (if_then_else (match_operator 1 "simple_comparison_operator"
f3713778
GJL
4233 [(cc0)
4234 (const_int 0)])
90e7678c
DC
4235 (label_ref (match_operand 0 "" ""))
4236 (pc)))]
413fc59a 4237 ""
f3713778
GJL
4238 {
4239 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4240 }
90e7678c
DC
4241 [(set_attr "type" "branch")
4242 (set_attr "cc" "clobber")])
4243
f3713778
GJL
4244
4245;; Same as above but wrap SET_SRC so that this branch won't be transformed
4246;; or optimized in the remainder.
4247
4248(define_insn "branch_unspec"
4249 [(set (pc)
4250 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4251 [(cc0)
4252 (const_int 0)])
4253 (label_ref (match_operand 0 "" ""))
4254 (pc))
4255 ] UNSPEC_IDENTITY))]
4256 ""
4257 {
4258 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4259 }
4260 [(set_attr "type" "branch")
4261 (set_attr "cc" "none")])
4262
f90b7a5a
PB
4263;; ****************************************************************
4264;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4265;; Convert them all to proper jumps.
4266;; ****************************************************************/
4267
90e7678c
DC
4268(define_insn "difficult_branch"
4269 [(set (pc)
413fc59a 4270 (if_then_else (match_operator 1 "difficult_comparison_operator"
90e7678c
DC
4271 [(cc0)
4272 (const_int 0)])
4273 (label_ref (match_operand 0 "" ""))
4274 (pc)))]
413fc59a 4275 ""
90e7678c 4276 "*
56b871c1 4277 return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
90e7678c
DC
4278 [(set_attr "type" "branch1")
4279 (set_attr "cc" "clobber")])
4280
4281;; revers branch
4282
4283(define_insn "rvbranch"
4284 [(set (pc)
413fc59a
AS
4285 (if_then_else (match_operator 1 "simple_comparison_operator"
4286 [(cc0)
4287 (const_int 0)])
90e7678c
DC
4288 (pc)
4289 (label_ref (match_operand 0 "" ""))))]
413fc59a 4290 ""
90e7678c 4291 "*
56b871c1 4292 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
90e7678c
DC
4293 [(set_attr "type" "branch1")
4294 (set_attr "cc" "clobber")])
4295
4296(define_insn "difficult_rvbranch"
4297 [(set (pc)
413fc59a
AS
4298 (if_then_else (match_operator 1 "difficult_comparison_operator"
4299 [(cc0)
4300 (const_int 0)])
90e7678c
DC
4301 (pc)
4302 (label_ref (match_operand 0 "" ""))))]
413fc59a 4303 ""
90e7678c 4304 "*
56b871c1 4305 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
90e7678c
DC
4306 [(set_attr "type" "branch")
4307 (set_attr "cc" "clobber")])
4308
4309;; **************************************************************************
4310;; Unconditional and other jump instructions.
4311
4312(define_insn "jump"
4313 [(set (pc)
4314 (label_ref (match_operand 0 "" "")))]
4315 ""
7c3297ce
GJL
4316 {
4317 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4318 ? "jmp %x0"
4319 : "rjmp %x0";
4320 }
7e3bd81e 4321 [(set (attr "length")
4fc2b4ff 4322 (if_then_else (match_operand 0 "symbol_ref_operand" "")
7c3297ce
GJL
4323 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4324 (const_int 1)
4325 (const_int 2))
2f47b8d3
GJL
4326 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4327 (le (minus (pc) (match_dup 0)) (const_int 2047)))
7c3297ce
GJL
4328 (const_int 1)
4329 (const_int 2))))
90e7678c
DC
4330 (set_attr "cc" "none")])
4331
4332;; call
4333
4334(define_expand "call"
980a0ff4
GJL
4335 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4336 (match_operand:HI 1 "general_operand" ""))
4337 (use (const_int 0))])]
90e7678c 4338 ;; Operand 1 not used on the AVR.
980a0ff4
GJL
4339 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4340 ""
4341 "")
4342
4343(define_expand "sibcall"
4344 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4345 (match_operand:HI 1 "general_operand" ""))
4346 (use (const_int 1))])]
4347 ;; Operand 1 not used on the AVR.
4348 ;; Operand 2 is 1 for tail-call, 0 otherwise.
90e7678c
DC
4349 ""
4350 "")
4351
4352;; call value
4353
4354(define_expand "call_value"
980a0ff4
GJL
4355 [(parallel[(set (match_operand 0 "register_operand" "")
4356 (call (match_operand:HI 1 "call_insn_operand" "")
4357 (match_operand:HI 2 "general_operand" "")))
4358 (use (const_int 0))])]
4359 ;; Operand 2 not used on the AVR.
4360 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4361 ""
4362 "")
4363
4364(define_expand "sibcall_value"
4365 [(parallel[(set (match_operand 0 "register_operand" "")
4366 (call (match_operand:HI 1 "call_insn_operand" "")
4367 (match_operand:HI 2 "general_operand" "")))
4368 (use (const_int 1))])]
90e7678c 4369 ;; Operand 2 not used on the AVR.
980a0ff4 4370 ;; Operand 3 is 1 for tail-call, 0 otherwise.
90e7678c
DC
4371 ""
4372 "")
4373
9bc9ee67 4374(define_insn "call_insn"
980a0ff4
GJL
4375 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4376 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4377 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
90e7678c 4378 ;; Operand 1 not used on the AVR.
980a0ff4
GJL
4379 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4380 ""
4381 "@
4382 %!icall
4383 %~call %x0
4384 %!ijmp
4385 %~jmp %x0"
4386 [(set_attr "cc" "clobber")
7c3297ce
GJL
4387 (set_attr "length" "1,*,1,*")
4388 (set_attr "adjust_len" "*,call,*,call")])
980a0ff4 4389
9bc9ee67 4390(define_insn "call_value_insn"
980a0ff4
GJL
4391 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4392 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4393 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4394 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
90e7678c 4395 ;; Operand 2 not used on the AVR.
980a0ff4
GJL
4396 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4397 ""
4398 "@
4399 %!icall
4400 %~call %x1
4401 %!ijmp
4402 %~jmp %x1"
4403 [(set_attr "cc" "clobber")
7c3297ce
GJL
4404 (set_attr "length" "1,*,1,*")
4405 (set_attr "adjust_len" "*,call,*,call")])
90e7678c
DC
4406
4407(define_insn "nop"
4408 [(const_int 0)]
4409 ""
4410 "nop"
4411 [(set_attr "cc" "none")
4412 (set_attr "length" "1")])
4413
4414; indirect jump
846428f1
AH
4415
4416(define_expand "indirect_jump"
7c3297ce
GJL
4417 [(set (pc)
4418 (match_operand:HI 0 "nonmemory_operand" ""))]
846428f1 4419 ""
7c3297ce
GJL
4420 {
4421 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4422 {
4423 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4424 }
4425 })
846428f1
AH
4426
4427; indirect jump
7c3297ce
GJL
4428(define_insn "*indirect_jump"
4429 [(set (pc)
4430 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
846428f1 4431 ""
90e7678c 4432 "@
7c3297ce
GJL
4433 rjmp %x0
4434 jmp %x0
90e7678c 4435 ijmp
7c3297ce
GJL
4436 push %A0\;push %B0\;ret
4437 eijmp"
4438 [(set_attr "length" "1,2,1,3,1")
4439 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
693092fb
BH
4440 (set_attr "cc" "none")])
4441
90e7678c 4442;; table jump
917e14f3 4443;; For entries in jump table see avr_output_addr_vec_elt.
90e7678c 4444
7c3297ce
GJL
4445;; Table made from
4446;; "rjmp .L<n>" instructions for <= 8K devices
4447;; ".word gs(.L<n>)" addresses for > 8K devices
4448(define_insn "*tablejump"
917e14f3 4449 [(set (pc)
7c3297ce 4450 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
917e14f3 4451 UNSPEC_INDEX_JMP))
84e6f1ba
MM
4452 (use (label_ref (match_operand 1 "" "")))
4453 (clobber (match_dup 0))]
7c3297ce 4454 ""
84e6f1ba
MM
4455 "@
4456 ijmp
7c3297ce
GJL
4457 push %A0\;push %B0\;ret
4458 jmp __tablejump2__"
4459 [(set_attr "length" "1,3,2")
4460 (set_attr "isa" "rjmp,rjmp,jmp")
4461 (set_attr "cc" "none,none,clobber")])
5fecfd8d 4462
90e7678c
DC
4463
4464(define_expand "casesi"
4465 [(set (match_dup 6)
4466 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4467 (match_operand:HI 1 "register_operand" "")))
4468 (parallel [(set (cc0)
4469 (compare (match_dup 6)
4470 (match_operand:HI 2 "register_operand" "")))
4471 (clobber (match_scratch:QI 9 ""))])
4472
4473 (set (pc)
4474 (if_then_else (gtu (cc0)
4475 (const_int 0))
4476 (label_ref (match_operand 4 "" ""))
4477 (pc)))
84e6f1ba
MM
4478
4479 (set (match_dup 6)
4480 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4481
2d67effa 4482 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
84e6f1ba
MM
4483 (use (label_ref (match_dup 3)))
4484 (clobber (match_dup 6))])]
1268b05f 4485 ""
90e7678c
DC
4486 "
4487{
4488 operands[6] = gen_reg_rtx (HImode);
4489}")
4490
4491
4492;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9a9f7594 4493;; This instruction sets Z flag
90e7678c
DC
4494
4495(define_insn "sez"
4496 [(set (cc0) (const_int 0))]
4497 ""
4498 "sez"
4499 [(set_attr "length" "1")
4500 (set_attr "cc" "compare")])
4501
1a499b92
MM
4502;; Clear/set/test a single bit in I/O address space.
4503
4504(define_insn "*cbi"
413fc59a 4505 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
1a499b92 4506 (and:QI (mem:QI (match_dup 0))
413fc59a
AS
4507 (match_operand:QI 1 "single_zero_operand" "n")))]
4508 "(optimize > 0)"
1a499b92
MM
4509{
4510 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
846428f1 4511 return AS2 (cbi,%m0-0x20,%2);
1a499b92
MM
4512}
4513 [(set_attr "length" "1")
4514 (set_attr "cc" "none")])
4515
4516(define_insn "*sbi"
413fc59a 4517 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
1a499b92 4518 (ior:QI (mem:QI (match_dup 0))
413fc59a
AS
4519 (match_operand:QI 1 "single_one_operand" "n")))]
4520 "(optimize > 0)"
1a499b92
MM
4521{
4522 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
846428f1 4523 return AS2 (sbi,%m0-0x20,%2);
1a499b92
MM
4524}
4525 [(set_attr "length" "1")
4526 (set_attr "cc" "none")])
4527
331ca350 4528;; Lower half of the I/O space - use sbic/sbis directly.
1a499b92
MM
4529(define_insn "*sbix_branch"
4530 [(set (pc)
4531 (if_then_else
413fc59a 4532 (match_operator 0 "eqne_operator"
38ce04d9 4533 [(zero_extract:HI
413fc59a 4534 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
1a499b92
MM
4535 (const_int 1)
4536 (match_operand 2 "const_int_operand" "n"))
4537 (const_int 0)])
4538 (label_ref (match_operand 3 "" ""))
4539 (pc)))]
413fc59a 4540 "(optimize > 0)"
331ca350 4541 "* return avr_out_sbxx_branch (insn, operands);"
1a499b92
MM
4542 [(set (attr "length")
4543 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
7c3297ce
GJL
4544 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4545 (const_int 2)
4546 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4547 (const_int 2)
4548 (const_int 4))))
1a499b92
MM
4549 (set_attr "cc" "clobber")])
4550
4551;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4552(define_insn "*sbix_branch_bit7"
4553 [(set (pc)
4554 (if_then_else
413fc59a
AS
4555 (match_operator 0 "gelt_operator"
4556 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
1a499b92
MM
4557 (const_int 0)])
4558 (label_ref (match_operand 2 "" ""))
4559 (pc)))]
413fc59a 4560 "(optimize > 0)"
1a499b92 4561{
331ca350
MM
4562 operands[3] = operands[2];
4563 operands[2] = GEN_INT (7);
4564 return avr_out_sbxx_branch (insn, operands);
1a499b92
MM
4565}
4566 [(set (attr "length")
4567 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
7c3297ce
GJL
4568 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4569 (const_int 2)
4570 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4571 (const_int 2)
4572 (const_int 4))))
1a499b92 4573 (set_attr "cc" "clobber")])
90e7678c 4574
331ca350
MM
4575;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4576(define_insn "*sbix_branch_tmp"
4577 [(set (pc)
4578 (if_then_else
413fc59a 4579 (match_operator 0 "eqne_operator"
38ce04d9 4580 [(zero_extract:HI
d8a1f0fb 4581 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
331ca350
MM
4582 (const_int 1)
4583 (match_operand 2 "const_int_operand" "n"))
4584 (const_int 0)])
4585 (label_ref (match_operand 3 "" ""))
4586 (pc)))]
413fc59a 4587 "(optimize > 0)"
331ca350
MM
4588 "* return avr_out_sbxx_branch (insn, operands);"
4589 [(set (attr "length")
4590 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
7c3297ce
GJL
4591 (le (minus (pc) (match_dup 3)) (const_int 2045)))
4592 (const_int 3)
4593 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4594 (const_int 3)
4595 (const_int 5))))
331ca350
MM
4596 (set_attr "cc" "clobber")])
4597
4598(define_insn "*sbix_branch_tmp_bit7"
4599 [(set (pc)
4600 (if_then_else
413fc59a 4601 (match_operator 0 "gelt_operator"
d8a1f0fb 4602 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
331ca350
MM
4603 (const_int 0)])
4604 (label_ref (match_operand 2 "" ""))
4605 (pc)))]
413fc59a 4606 "(optimize > 0)"
331ca350
MM
4607{
4608 operands[3] = operands[2];
4609 operands[2] = GEN_INT (7);
4610 return avr_out_sbxx_branch (insn, operands);
4611}
4612 [(set (attr "length")
4613 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4614 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4615 (const_int 3)
7c3297ce 4616 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
331ca350
MM
4617 (const_int 3)
4618 (const_int 5))))
4619 (set_attr "cc" "clobber")])
4620
90e7678c
DC
4621;; ************************* Peepholes ********************************
4622
4623(define_peephole
59024515
GJL
4624 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
4625 (plus:SI (match_dup 0)
4626 (const_int -1)))
4627 (clobber (scratch:QI))])
4628 (parallel [(set (cc0)
4629 (compare (match_dup 0)
4630 (const_int -1)))
4631 (clobber (match_operand:QI 1 "d_register_operand" ""))])
90e7678c 4632 (set (pc)
59024515
GJL
4633 (if_then_else (ne (cc0)
4634 (const_int 0))
4635 (label_ref (match_operand 2 "" ""))
4636 (pc)))]
413fc59a 4637 ""
90e7678c 4638 {
59024515
GJL
4639 CC_STATUS_INIT;
4640 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4641 output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
4642 AS2 (sbc,%C0,__zero_reg__) CR_TAB
4643 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
4644 else
4645 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
4646 AS2 (sbc,%B0,__zero_reg__) CR_TAB
4647 AS2 (sbc,%C0,__zero_reg__) CR_TAB
4648 AS2 (sbc,%D0,__zero_reg__) "\n", operands);
4649
4650 switch (avr_jump_mode (operands[2], insn))
4651 {
4652 case 1:
4653 return AS1 (brcc,%2);
4654 case 2:
4655 return (AS1 (brcs,.+2) CR_TAB
4656 AS1 (rjmp,%2));
4657 }
4658
4659 return (AS1 (brcs,.+4) CR_TAB
4660 AS1 (jmp,%2));
4661 })
90e7678c
DC
4662
4663(define_peephole
413fc59a 4664 [(set (match_operand:HI 0 "d_register_operand" "")
90e7678c
DC
4665 (plus:HI (match_dup 0)
4666 (const_int -1)))
4667 (parallel
4668 [(set (cc0)
4669 (compare (match_dup 0)
31fd727b 4670 (const_int -1)))
413fc59a 4671 (clobber (match_operand:QI 1 "d_register_operand" ""))])
90e7678c
DC
4672 (set (pc)
4673 (if_then_else (ne (cc0) (const_int 0))
4674 (label_ref (match_operand 2 "" ""))
4675 (pc)))]
413fc59a 4676 ""
90e7678c
DC
4677 "*
4678{
db62867b 4679 CC_STATUS_INIT;
5fecfd8d 4680 if (test_hard_reg_class (ADDW_REGS, operands[0]))
90e7678c
DC
4681 output_asm_insn (AS2 (sbiw,%0,1), operands);
4682 else
4683 output_asm_insn (AS2 (subi,%A0,1) CR_TAB
4684 AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
4685 switch (avr_jump_mode (operands[2],insn))
4686 {
4687 case 1:
4688 return AS1 (brcc,%2);
4689 case 2:
13e8651c 4690 return (AS1 (brcs,.+2) CR_TAB
90e7678c
DC
4691 AS1 (rjmp,%2));
4692 }
13e8651c 4693 return (AS1 (brcs,.+4) CR_TAB
90e7678c
DC
4694 AS1 (jmp,%2));
4695}")
4696
4697(define_peephole
413fc59a 4698 [(set (match_operand:QI 0 "d_register_operand" "")
90e7678c
DC
4699 (plus:QI (match_dup 0)
4700 (const_int -1)))
4701 (set (cc0)
4702 (compare (match_dup 0)
4703 (const_int -1)))
4704 (set (pc)
4705 (if_then_else (ne (cc0) (const_int 0))
4706 (label_ref (match_operand 1 "" ""))
4707 (pc)))]
413fc59a 4708 ""
90e7678c
DC
4709 "*
4710{
db62867b
DC
4711 CC_STATUS_INIT;
4712 cc_status.value1 = operands[0];
4713 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
90e7678c
DC
4714 output_asm_insn (AS2 (subi,%A0,1), operands);
4715 switch (avr_jump_mode (operands[1],insn))
4716 {
4717 case 1:
4718 return AS1 (brcc,%1);
4719 case 2:
13e8651c 4720 return (AS1 (brcs,.+2) CR_TAB
90e7678c
DC
4721 AS1 (rjmp,%1));
4722 }
13e8651c 4723 return (AS1 (brcs,.+4) CR_TAB
90e7678c
DC
4724 AS1 (jmp,%1));
4725}")
6bec29c9
DC
4726
4727(define_peephole
f90b7a5a
PB
4728 [(set (cc0)
4729 (compare (match_operand:QI 0 "register_operand" "")
4730 (const_int 0)))
6bec29c9
DC
4731 (set (pc)
4732 (if_then_else (eq (cc0) (const_int 0))
4733 (label_ref (match_operand 1 "" ""))
4734 (pc)))]
4735 "jump_over_one_insn_p (insn, operands[1])"
4736 "cpse %0,__zero_reg__")
4737
4738(define_peephole
4739 [(set (cc0)
4740 (compare (match_operand:QI 0 "register_operand" "")
4741 (match_operand:QI 1 "register_operand" "")))
4742 (set (pc)
4743 (if_then_else (eq (cc0) (const_int 0))
4744 (label_ref (match_operand 2 "" ""))
4745 (pc)))]
4746 "jump_over_one_insn_p (insn, operands[2])"
4747 "cpse %0,%1")
4fc2b4ff
AH
4748
4749;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
4750;;prologue/epilogue support instructions
4751
4752(define_insn "popqi"
4753 [(set (match_operand:QI 0 "register_operand" "=r")
bdfe906f 4754 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
4fc2b4ff
AH
4755 ""
4756 "pop %0"
4757 [(set_attr "cc" "none")
4758 (set_attr "length" "1")])
4759
4fc2b4ff
AH
4760;; Enable Interrupts
4761(define_insn "enable_interrupt"
43ea6502 4762 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
4fc2b4ff
AH
4763 ""
4764 "sei"
4765 [(set_attr "length" "1")
43ea6502 4766 (set_attr "cc" "none")])
4fc2b4ff
AH
4767
4768;; Disable Interrupts
4769(define_insn "disable_interrupt"
43ea6502 4770 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
4fc2b4ff
AH
4771 ""
4772 "cli"
4773 [(set_attr "length" "1")
43ea6502 4774 (set_attr "cc" "none")])
4fc2b4ff
AH
4775
4776;; Library prologue saves
4777(define_insn "call_prologue_saves"
4778 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
7c3297ce
GJL
4779 (match_operand:HI 0 "immediate_operand" "i,i")
4780 (set (reg:HI REG_SP)
4781 (minus:HI (reg:HI REG_SP)
4782 (match_operand:HI 1 "immediate_operand" "i,i")))
4e63b362 4783 (use (reg:HI REG_X))
4fc2b4ff
AH
4784 (clobber (reg:HI REG_Z))]
4785 ""
4d492420
TG
4786 "ldi r30,lo8(gs(1f))
4787 ldi r31,hi8(gs(1f))
4e63b362 4788 %~jmp __prologue_saves__+((18 - %0) * 2)
4fc2b4ff 47891:"
7c3297ce
GJL
4790 [(set_attr "length" "5,6")
4791 (set_attr "cc" "clobber")
4792 (set_attr "isa" "rjmp,jmp")])
4fc2b4ff
AH
4793
4794; epilogue restores using library
4795(define_insn "epilogue_restores"
4796 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
7c3297ce
GJL
4797 (set (reg:HI REG_Y)
4798 (plus:HI (reg:HI REG_Y)
4799 (match_operand:HI 0 "immediate_operand" "i,i")))
4800 (set (reg:HI REG_SP)
4801 (plus:HI (reg:HI REG_Y)
4802 (match_dup 0)))
4803 (clobber (reg:QI REG_Z))]
4fc2b4ff
AH
4804 ""
4805 "ldi r30, lo8(%0)
4806 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
7c3297ce
GJL
4807 [(set_attr "length" "2,3")
4808 (set_attr "cc" "clobber")
4809 (set_attr "isa" "rjmp,jmp")])
4fc2b4ff
AH
4810
4811; return
4812(define_insn "return"
4813 [(return)]
4814 "reload_completed && avr_simple_epilogue ()"
4815 "ret"
4816 [(set_attr "cc" "none")
4817 (set_attr "length" "1")])
4818
4819(define_insn "return_from_epilogue"
4820 [(return)]
4821 "(reload_completed
4822 && cfun->machine
4fc2b4ff
AH
4823 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
4824 && !cfun->machine->is_naked)"
4825 "ret"
4826 [(set_attr "cc" "none")
4827 (set_attr "length" "1")])
4828
4fc2b4ff
AH
4829(define_insn "return_from_interrupt_epilogue"
4830 [(return)]
4831 "(reload_completed
4832 && cfun->machine
4fc2b4ff
AH
4833 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
4834 && !cfun->machine->is_naked)"
4835 "reti"
4836 [(set_attr "cc" "none")
4837 (set_attr "length" "1")])
4838
4839(define_insn "return_from_naked_epilogue"
4840 [(return)]
4841 "(reload_completed
4842 && cfun->machine
4843 && cfun->machine->is_naked)"
4844 ""
4845 [(set_attr "cc" "none")
4846 (set_attr "length" "0")])
4847
4848(define_expand "prologue"
4849 [(const_int 0)]
4850 ""
4fc2b4ff
AH
4851 {
4852 expand_prologue ();
4853 DONE;
7c3297ce 4854 })
4fc2b4ff
AH
4855
4856(define_expand "epilogue"
4857 [(const_int 0)]
4858 ""
4fc2b4ff 4859 {
980a0ff4 4860 expand_epilogue (false /* sibcall_p */);
4fc2b4ff 4861 DONE;
980a0ff4
GJL
4862 })
4863
4864(define_expand "sibcall_epilogue"
4865 [(const_int 0)]
4866 ""
4867 {
4868 expand_epilogue (true /* sibcall_p */);
4869 DONE;
4870 })
43ea6502
AS
4871
4872;; Some instructions resp. instruction sequences available
4873;; via builtins.
4874
4875(define_insn "delay_cycles_1"
4876 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
4877 (const_int 1)]
4878 UNSPECV_DELAY_CYCLES)
4879 (clobber (match_scratch:QI 1 "=&d"))]
4880 ""
4881 "ldi %1,lo8(%0)
4882 1: dec %1
4883 brne 1b"
4884 [(set_attr "length" "3")
4885 (set_attr "cc" "clobber")])
4886
4887(define_insn "delay_cycles_2"
4888 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
4889 (const_int 2)]
4890 UNSPECV_DELAY_CYCLES)
4891 (clobber (match_scratch:HI 1 "=&w"))]
4892 ""
4893 "ldi %A1,lo8(%0)
4894 ldi %B1,hi8(%0)
4895 1: sbiw %A1,1
4896 brne 1b"
4897 [(set_attr "length" "4")
4898 (set_attr "cc" "clobber")])
4899
4900(define_insn "delay_cycles_3"
4901 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4902 (const_int 3)]
4903 UNSPECV_DELAY_CYCLES)
4904 (clobber (match_scratch:QI 1 "=&d"))
4905 (clobber (match_scratch:QI 2 "=&d"))
4906 (clobber (match_scratch:QI 3 "=&d"))]
4907 ""
4908 "ldi %1,lo8(%0)
4909 ldi %2,hi8(%0)
4910 ldi %3,hlo8(%0)
4911 1: subi %1,1
4912 sbci %2,0
4913 sbci %3,0
4914 brne 1b"
4915 [(set_attr "length" "7")
4916 (set_attr "cc" "clobber")])
4917
4918(define_insn "delay_cycles_4"
4919 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
4920 (const_int 4)]
4921 UNSPECV_DELAY_CYCLES)
4922 (clobber (match_scratch:QI 1 "=&d"))
4923 (clobber (match_scratch:QI 2 "=&d"))
4924 (clobber (match_scratch:QI 3 "=&d"))
4925 (clobber (match_scratch:QI 4 "=&d"))]
4926 ""
4927 "ldi %1,lo8(%0)
4928 ldi %2,hi8(%0)
4929 ldi %3,hlo8(%0)
4930 ldi %4,hhi8(%0)
4931 1: subi %1,1
4932 sbci %2,0
4933 sbci %3,0
4934 sbci %4,0
4935 brne 1b"
4936 [(set_attr "length" "9")
4937 (set_attr "cc" "clobber")])
4938
6130646b
GJL
4939
4940;; Parity
4941
f89d6e77
GJL
4942;; Postpone expansion of 16-bit parity to libgcc call until after combine for
4943;; better 8-bit parity recognition.
4944
6130646b 4945(define_expand "parityhi2"
f89d6e77
GJL
4946 [(parallel [(set (match_operand:HI 0 "register_operand" "")
4947 (parity:HI (match_operand:HI 1 "register_operand" "")))
4948 (clobber (reg:HI 24))])])
4949
4950(define_insn_and_split "*parityhi2"
4951 [(set (match_operand:HI 0 "register_operand" "=r")
4952 (parity:HI (match_operand:HI 1 "register_operand" "r")))
4953 (clobber (reg:HI 24))]
4954 "!reload_completed"
4955 { gcc_unreachable(); }
4956 "&& 1"
6130646b 4957 [(set (reg:HI 24)
f89d6e77 4958 (match_dup 1))
6130646b
GJL
4959 (set (reg:HI 24)
4960 (parity:HI (reg:HI 24)))
f89d6e77
GJL
4961 (set (match_dup 0)
4962 (reg:HI 24))])
4963
4964(define_insn_and_split "*parityqihi2"
4965 [(set (match_operand:HI 0 "register_operand" "=r")
4966 (parity:HI (match_operand:QI 1 "register_operand" "r")))
4967 (clobber (reg:HI 24))]
4968 "!reload_completed"
4969 { gcc_unreachable(); }
4970 "&& 1"
4971 [(set (reg:QI 24)
4972 (match_dup 1))
4973 (set (reg:HI 24)
4974 (zero_extend:HI (parity:QI (reg:QI 24))))
4975 (set (match_dup 0)
4976 (reg:HI 24))])
6130646b
GJL
4977
4978(define_expand "paritysi2"
4979 [(set (reg:SI 22)
4980 (match_operand:SI 1 "register_operand" ""))
4981 (set (reg:HI 24)
07f10472 4982 (truncate:HI (parity:SI (reg:SI 22))))
6130646b
GJL
4983 (set (match_dup 2)
4984 (reg:HI 24))
4985 (set (match_operand:SI 0 "register_operand" "")
4986 (zero_extend:SI (match_dup 2)))]
4987 ""
4988 {
4989 operands[2] = gen_reg_rtx (HImode);
4990 })
4991
4992(define_insn "*parityhi2.libgcc"
4993 [(set (reg:HI 24)
4994 (parity:HI (reg:HI 24)))]
4995 ""
4996 "%~call __parityhi2"
4997 [(set_attr "type" "xcall")
4998 (set_attr "cc" "clobber")])
4999
5000(define_insn "*parityqihi2.libgcc"
5001 [(set (reg:HI 24)
07f10472 5002 (zero_extend:HI (parity:QI (reg:QI 24))))]
6130646b
GJL
5003 ""
5004 "%~call __parityqi2"
5005 [(set_attr "type" "xcall")
5006 (set_attr "cc" "clobber")])
5007
5008(define_insn "*paritysihi2.libgcc"
5009 [(set (reg:HI 24)
07f10472 5010 (truncate:HI (parity:SI (reg:SI 22))))]
6130646b
GJL
5011 ""
5012 "%~call __paritysi2"
5013 [(set_attr "type" "xcall")
5014 (set_attr "cc" "clobber")])
5015
5016
5017;; Popcount
5018
5019(define_expand "popcounthi2"
5020 [(set (reg:HI 24)
5021 (match_operand:HI 1 "register_operand" ""))
5022 (set (reg:HI 24)
5023 (popcount:HI (reg:HI 24)))
5024 (set (match_operand:HI 0 "register_operand" "")
5025 (reg:HI 24))]
5026 ""
5027 "")
5028
5029(define_expand "popcountsi2"
5030 [(set (reg:SI 22)
5031 (match_operand:SI 1 "register_operand" ""))
5032 (set (reg:HI 24)
07f10472 5033 (truncate:HI (popcount:SI (reg:SI 22))))
6130646b
GJL
5034 (set (match_dup 2)
5035 (reg:HI 24))
5036 (set (match_operand:SI 0 "register_operand" "")
5037 (zero_extend:SI (match_dup 2)))]
5038 ""
5039 {
5040 operands[2] = gen_reg_rtx (HImode);
5041 })
5042
5043(define_insn "*popcounthi2.libgcc"
5044 [(set (reg:HI 24)
5045 (popcount:HI (reg:HI 24)))]
5046 ""
5047 "%~call __popcounthi2"
5048 [(set_attr "type" "xcall")
5049 (set_attr "cc" "clobber")])
5050
5051(define_insn "*popcountsi2.libgcc"
5052 [(set (reg:HI 24)
07f10472 5053 (truncate:HI (popcount:SI (reg:SI 22))))]
6130646b
GJL
5054 ""
5055 "%~call __popcountsi2"
5056 [(set_attr "type" "xcall")
5057 (set_attr "cc" "clobber")])
5058
5059(define_insn "*popcountqi2.libgcc"
5060 [(set (reg:QI 24)
5061 (popcount:QI (reg:QI 24)))]
5062 ""
5063 "%~call __popcountqi2"
5064 [(set_attr "type" "xcall")
5065 (set_attr "cc" "clobber")])
5066
5067(define_insn_and_split "*popcountqihi2.libgcc"
5068 [(set (reg:HI 24)
07f10472 5069 (zero_extend:HI (popcount:QI (reg:QI 24))))]
6130646b
GJL
5070 ""
5071 "#"
5072 ""
5073 [(set (reg:QI 24)
5074 (popcount:QI (reg:QI 24)))
5075 (set (reg:QI 25)
5076 (const_int 0))]
5077 "")
5078
5079;; Count Leading Zeros
5080
5081(define_expand "clzhi2"
5082 [(set (reg:HI 24)
5083 (match_operand:HI 1 "register_operand" ""))
5084 (parallel [(set (reg:HI 24)
5085 (clz:HI (reg:HI 24)))
5086 (clobber (reg:QI 26))])
5087 (set (match_operand:HI 0 "register_operand" "")
5088 (reg:HI 24))]
5089 ""
5090 "")
5091
5092(define_expand "clzsi2"
5093 [(set (reg:SI 22)
5094 (match_operand:SI 1 "register_operand" ""))
5095 (parallel [(set (reg:HI 24)
07f10472 5096 (truncate:HI (clz:SI (reg:SI 22))))
6130646b
GJL
5097 (clobber (reg:QI 26))])
5098 (set (match_dup 2)
5099 (reg:HI 24))
5100 (set (match_operand:SI 0 "register_operand" "")
5101 (zero_extend:SI (match_dup 2)))]
5102 ""
5103 {
5104 operands[2] = gen_reg_rtx (HImode);
5105 })
5106
5107(define_insn "*clzhi2.libgcc"
5108 [(set (reg:HI 24)
5109 (clz:HI (reg:HI 24)))
5110 (clobber (reg:QI 26))]
5111 ""
5112 "%~call __clzhi2"
5113 [(set_attr "type" "xcall")
5114 (set_attr "cc" "clobber")])
5115
5116(define_insn "*clzsihi2.libgcc"
5117 [(set (reg:HI 24)
07f10472 5118 (truncate:HI (clz:SI (reg:SI 22))))
6130646b
GJL
5119 (clobber (reg:QI 26))]
5120 ""
5121 "%~call __clzsi2"
5122 [(set_attr "type" "xcall")
5123 (set_attr "cc" "clobber")])
5124
5125;; Count Trailing Zeros
5126
5127(define_expand "ctzhi2"
5128 [(set (reg:HI 24)
5129 (match_operand:HI 1 "register_operand" ""))
5130 (parallel [(set (reg:HI 24)
5131 (ctz:HI (reg:HI 24)))
5132 (clobber (reg:QI 26))])
5133 (set (match_operand:HI 0 "register_operand" "")
5134 (reg:HI 24))]
5135 ""
5136 "")
5137
5138(define_expand "ctzsi2"
5139 [(set (reg:SI 22)
5140 (match_operand:SI 1 "register_operand" ""))
5141 (parallel [(set (reg:HI 24)
07f10472 5142 (truncate:HI (ctz:SI (reg:SI 22))))
6130646b
GJL
5143 (clobber (reg:QI 22))
5144 (clobber (reg:QI 26))])
5145 (set (match_dup 2)
5146 (reg:HI 24))
5147 (set (match_operand:SI 0 "register_operand" "")
5148 (zero_extend:SI (match_dup 2)))]
5149 ""
5150 {
5151 operands[2] = gen_reg_rtx (HImode);
5152 })
5153
5154(define_insn "*ctzhi2.libgcc"
5155 [(set (reg:HI 24)
5156 (ctz:HI (reg:HI 24)))
5157 (clobber (reg:QI 26))]
5158 ""
5159 "%~call __ctzhi2"
5160 [(set_attr "type" "xcall")
5161 (set_attr "cc" "clobber")])
5162
5163(define_insn "*ctzsihi2.libgcc"
5164 [(set (reg:HI 24)
07f10472 5165 (truncate:HI (ctz:SI (reg:SI 22))))
6130646b
GJL
5166 (clobber (reg:QI 22))
5167 (clobber (reg:QI 26))]
5168 ""
5169 "%~call __ctzsi2"
5170 [(set_attr "type" "xcall")
5171 (set_attr "cc" "clobber")])
5172
5173;; Find First Set
5174
5175(define_expand "ffshi2"
5176 [(set (reg:HI 24)
5177 (match_operand:HI 1 "register_operand" ""))
5178 (parallel [(set (reg:HI 24)
5179 (ffs:HI (reg:HI 24)))
5180 (clobber (reg:QI 26))])
5181 (set (match_operand:HI 0 "register_operand" "")
5182 (reg:HI 24))]
5183 ""
5184 "")
5185
5186(define_expand "ffssi2"
5187 [(set (reg:SI 22)
5188 (match_operand:SI 1 "register_operand" ""))
5189 (parallel [(set (reg:HI 24)
07f10472 5190 (truncate:HI (ffs:SI (reg:SI 22))))
6130646b
GJL
5191 (clobber (reg:QI 22))
5192 (clobber (reg:QI 26))])
5193 (set (match_dup 2)
5194 (reg:HI 24))
5195 (set (match_operand:SI 0 "register_operand" "")
5196 (zero_extend:SI (match_dup 2)))]
5197 ""
5198 {
5199 operands[2] = gen_reg_rtx (HImode);
5200 })
5201
5202(define_insn "*ffshi2.libgcc"
5203 [(set (reg:HI 24)
5204 (ffs:HI (reg:HI 24)))
5205 (clobber (reg:QI 26))]
5206 ""
5207 "%~call __ffshi2"
5208 [(set_attr "type" "xcall")
5209 (set_attr "cc" "clobber")])
5210
5211(define_insn "*ffssihi2.libgcc"
5212 [(set (reg:HI 24)
07f10472 5213 (truncate:HI (ffs:SI (reg:SI 22))))
6130646b
GJL
5214 (clobber (reg:QI 22))
5215 (clobber (reg:QI 26))]
5216 ""
5217 "%~call __ffssi2"
5218 [(set_attr "type" "xcall")
5219 (set_attr "cc" "clobber")])
5220
5221;; Copysign
5222
5223(define_insn "copysignsf3"
5224 [(set (match_operand:SF 0 "register_operand" "=r")
5225 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5226 (match_operand:SF 2 "register_operand" "r")]
5227 UNSPEC_COPYSIGN))]
5228 ""
5229 "bst %D2,7\;bld %D0,7"
5230 [(set_attr "length" "2")
5231 (set_attr "cc" "none")])
5232
5233;; Swap Bytes (change byte-endianess)
5234
5235(define_expand "bswapsi2"
5236 [(set (reg:SI 22)
5237 (match_operand:SI 1 "register_operand" ""))
5238 (set (reg:SI 22)
5239 (bswap:SI (reg:SI 22)))
5240 (set (match_operand:SI 0 "register_operand" "")
5241 (reg:SI 22))]
5242 ""
5243 "")
5244
5245(define_insn "*bswapsi2.libgcc"
5246 [(set (reg:SI 22)
5247 (bswap:SI (reg:SI 22)))]
5248 ""
5249 "%~call __bswapsi2"
5250 [(set_attr "type" "xcall")
5251 (set_attr "cc" "clobber")])
5252
5253
43ea6502
AS
5254;; CPU instructions
5255
5256;; NOP taking 1 or 2 Ticks
5257(define_insn "nopv"
5258 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5259 UNSPECV_NOP)]
5260 ""
5261 "@
5262 nop
5263 rjmp ."
5264 [(set_attr "length" "1")
5265 (set_attr "cc" "none")])
5266
5267;; SLEEP
5268(define_insn "sleep"
5269 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
5270 ""
5271 "sleep"
5272 [(set_attr "length" "1")
5273 (set_attr "cc" "none")])
5274
5275;; WDR
5276(define_insn "wdr"
5277 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
5278 ""
5279 "wdr"
5280 [(set_attr "length" "1")
5281 (set_attr "cc" "none")])
5282
5283;; FMUL
f451d14d
GJL
5284(define_expand "fmul"
5285 [(set (reg:QI 24)
5286 (match_operand:QI 1 "register_operand" ""))
5287 (set (reg:QI 25)
5288 (match_operand:QI 2 "register_operand" ""))
5289 (parallel [(set (reg:HI 22)
5290 (unspec:HI [(reg:QI 24)
5291 (reg:QI 25)] UNSPEC_FMUL))
5292 (clobber (reg:HI 24))])
5293 (set (match_operand:HI 0 "register_operand" "")
5294 (reg:HI 22))]
5295 ""
5296 {
5297 if (AVR_HAVE_MUL)
5298 {
5299 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
5300 DONE;
5301 }
5302 })
5303
5304(define_insn "fmul_insn"
43ea6502
AS
5305 [(set (match_operand:HI 0 "register_operand" "=r")
5306 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5307 (match_operand:QI 2 "register_operand" "a")]
5308 UNSPEC_FMUL))]
5309 "AVR_HAVE_MUL"
5310 "fmul %1,%2
5311 movw %0,r0
5312 clr __zero_reg__"
5313 [(set_attr "length" "3")
5314 (set_attr "cc" "clobber")])
5315
f451d14d
GJL
5316(define_insn "*fmul.call"
5317 [(set (reg:HI 22)
5318 (unspec:HI [(reg:QI 24)
5319 (reg:QI 25)] UNSPEC_FMUL))
5320 (clobber (reg:HI 24))]
5321 "!AVR_HAVE_MUL"
5322 "%~call __fmul"
5323 [(set_attr "type" "xcall")
5324 (set_attr "cc" "clobber")])
5325
43ea6502 5326;; FMULS
f451d14d
GJL
5327(define_expand "fmuls"
5328 [(set (reg:QI 24)
5329 (match_operand:QI 1 "register_operand" ""))
5330 (set (reg:QI 25)
5331 (match_operand:QI 2 "register_operand" ""))
5332 (parallel [(set (reg:HI 22)
5333 (unspec:HI [(reg:QI 24)
5334 (reg:QI 25)] UNSPEC_FMULS))
5335 (clobber (reg:HI 24))])
5336 (set (match_operand:HI 0 "register_operand" "")
5337 (reg:HI 22))]
5338 ""
5339 {
5340 if (AVR_HAVE_MUL)
5341 {
5342 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
5343 DONE;
5344 }
5345 })
5346
5347(define_insn "fmuls_insn"
43ea6502
AS
5348 [(set (match_operand:HI 0 "register_operand" "=r")
5349 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5350 (match_operand:QI 2 "register_operand" "a")]
5351 UNSPEC_FMULS))]
5352 "AVR_HAVE_MUL"
5353 "fmuls %1,%2
5354 movw %0,r0
5355 clr __zero_reg__"
5356 [(set_attr "length" "3")
5357 (set_attr "cc" "clobber")])
5358
f451d14d
GJL
5359(define_insn "*fmuls.call"
5360 [(set (reg:HI 22)
5361 (unspec:HI [(reg:QI 24)
5362 (reg:QI 25)] UNSPEC_FMULS))
5363 (clobber (reg:HI 24))]
5364 "!AVR_HAVE_MUL"
5365 "%~call __fmuls"
5366 [(set_attr "type" "xcall")
5367 (set_attr "cc" "clobber")])
5368
43ea6502 5369;; FMULSU
f451d14d
GJL
5370(define_expand "fmulsu"
5371 [(set (reg:QI 24)
5372 (match_operand:QI 1 "register_operand" ""))
5373 (set (reg:QI 25)
5374 (match_operand:QI 2 "register_operand" ""))
5375 (parallel [(set (reg:HI 22)
5376 (unspec:HI [(reg:QI 24)
5377 (reg:QI 25)] UNSPEC_FMULSU))
5378 (clobber (reg:HI 24))])
5379 (set (match_operand:HI 0 "register_operand" "")
5380 (reg:HI 22))]
5381 ""
5382 {
5383 if (AVR_HAVE_MUL)
5384 {
5385 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
5386 DONE;
5387 }
5388 })
5389
5390(define_insn "fmulsu_insn"
43ea6502
AS
5391 [(set (match_operand:HI 0 "register_operand" "=r")
5392 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5393 (match_operand:QI 2 "register_operand" "a")]
5394 UNSPEC_FMULSU))]
5395 "AVR_HAVE_MUL"
5396 "fmulsu %1,%2
5397 movw %0,r0
5398 clr __zero_reg__"
5399 [(set_attr "length" "3")
5400 (set_attr "cc" "clobber")])
687027a4 5401
f451d14d
GJL
5402(define_insn "*fmulsu.call"
5403 [(set (reg:HI 22)
5404 (unspec:HI [(reg:QI 24)
5405 (reg:QI 25)] UNSPEC_FMULSU))
5406 (clobber (reg:HI 24))]
5407 "!AVR_HAVE_MUL"
5408 "%~call __fmulsu"
5409 [(set_attr "type" "xcall")
5410 (set_attr "cc" "clobber")])
5411
48f9d59a
RH
5412\f
5413;; Some combiner patterns dealing with bits.
5414;; See PR42210
5415
5416;; Move bit $3.0 into bit $0.$4
5417(define_insn "*movbitqi.1-6.a"
5418 [(set (match_operand:QI 0 "register_operand" "=r")
5419 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5420 (match_operand:QI 2 "single_zero_operand" "n"))
5421 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
5422 (match_operand:QI 4 "const_0_to_7_operand" "n"))
5423 (match_operand:QI 5 "single_one_operand" "n"))))]
5424 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
5425 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
5426 "bst %3,0\;bld %0,%4"
5427 [(set_attr "length" "2")
5428 (set_attr "cc" "none")])
5429
5430;; Move bit $3.0 into bit $0.$4
5431;; Variation of above. Unfortunately, there is no canonicalized representation
5432;; of moving around bits. So what we see here depends on how user writes down
5433;; bit manipulations.
5434(define_insn "*movbitqi.1-6.b"
5435 [(set (match_operand:QI 0 "register_operand" "=r")
5436 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5437 (match_operand:QI 2 "single_zero_operand" "n"))
5438 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
5439 (const_int 1))
5440 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
5441 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5442 "bst %3,0\;bld %0,%4"
5443 [(set_attr "length" "2")
5444 (set_attr "cc" "none")])
5445
5446;; Move bit $3.0 into bit $0.0.
5447;; For bit 0, combiner generates slightly different pattern.
5448(define_insn "*movbitqi.0"
5449 [(set (match_operand:QI 0 "register_operand" "=r")
5450 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5451 (match_operand:QI 2 "single_zero_operand" "n"))
5452 (and:QI (match_operand:QI 3 "register_operand" "r")
5453 (const_int 1))))]
5454 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5455 "bst %3,0\;bld %0,0"
5456 [(set_attr "length" "2")
5457 (set_attr "cc" "none")])
5458
5459;; Move bit $2.0 into bit $0.7.
5460;; For bit 7, combiner generates slightly different pattern
5461(define_insn "*movbitqi.7"
5462 [(set (match_operand:QI 0 "register_operand" "=r")
5463 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5464 (const_int 127))
5465 (ashift:QI (match_operand:QI 2 "register_operand" "r")
5466 (const_int 7))))]
5467 ""
5468 "bst %2,0\;bld %0,7"
5469 [(set_attr "length" "2")
5470 (set_attr "cc" "none")])
5471
5472;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
5473;; and input/output match. We provide a special pattern for this, because
5474;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
5475;; operation on I/O is atomic.
5476(define_insn "*insv.io"
5477 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
5478 (const_int 1)
5479 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
5480 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
5481 ""
5482 "@
5483 cbi %m0-0x20,%1
5484 sbi %m0-0x20,%1
5485 sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
5486 [(set_attr "length" "1,1,4")
5487 (set_attr "cc" "none")])
5488
5489(define_insn "*insv.not.io"
5490 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5491 (const_int 1)
5492 (match_operand:QI 1 "const_0_to_7_operand" "n"))
5493 (not:QI (match_operand:QI 2 "register_operand" "r")))]
5494 ""
5495 "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
5496 [(set_attr "length" "4")
5497 (set_attr "cc" "none")])
5498
5499;; The insv expander.
5500;; We only support 1-bit inserts
5501(define_expand "insv"
5502 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
5503 (match_operand:QI 1 "const1_operand" "") ; width
5504 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
5505 (match_operand:QI 3 "nonmemory_operand" ""))]
5506 "optimize"
5507 "")
5508
5509;; Insert bit $2.0 into $0.$1
5510(define_insn "*insv.reg"
5511 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
5512 (const_int 1)
5513 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
5514 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
5515 ""
5516 "@
5517 bst %2,0\;bld %0,%1
5518 andi %0,lo8(~(1<<%1))
5519 ori %0,lo8(1<<%1)
5520 clt\;bld %0,%1
5521 set\;bld %0,%1"
5522 [(set_attr "length" "2,1,1,2,2")
5523 (set_attr "cc" "none,set_zn,set_zn,none,none")])
5524
687027a4
GJL
5525\f
5526;; Some combine patterns that try to fix bad code when a value is composed
5527;; from byte parts like in PR27663.
5528;; The patterns give some release but the code still is not optimal,
5529;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
5530;; That switch obfuscates things here and in many other places.
5531
5532(define_insn_and_split "*ior<mode>qi.byte0"
5533 [(set (match_operand:HISI 0 "register_operand" "=r")
5534 (ior:HISI
5535 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5536 (match_operand:HISI 2 "register_operand" "0")))]
5537 ""
5538 "#"
5539 "reload_completed"
5540 [(set (match_dup 3)
5541 (ior:QI (match_dup 3)
5542 (match_dup 1)))]
5543 {
5544 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
5545 })
5546
5547(define_insn_and_split "*ior<mode>qi.byte1-3"
5548 [(set (match_operand:HISI 0 "register_operand" "=r")
5549 (ior:HISI
5550 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5551 (match_operand:QI 2 "const_8_16_24_operand" "n"))
5552 (match_operand:HISI 3 "register_operand" "0")))]
5553 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5554 "#"
5555 "&& reload_completed"
5556 [(set (match_dup 4)
5557 (ior:QI (match_dup 4)
5558 (match_dup 1)))]
5559 {
5560 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
5561 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
5562 })
663827d3
GJL
5563
5564(define_expand "extzv"
5565 [(set (match_operand:QI 0 "register_operand" "")
5566 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
5567 (match_operand:QI 2 "const1_operand" "")
5568 (match_operand:QI 3 "const_0_to_7_operand" "")))]
5569 ""
5570 "")
5571
5572(define_insn "*extzv"
5573 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
5574 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
5575 (const_int 1)
5576 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
5577 ""
5578 "@
5579 andi %0,1
5580 mov %0,%1\;andi %0,1
5581 lsr %0\;andi %0,1
fddb8924 5582 swap %0\;andi %0,1
663827d3
GJL
5583 bst %1,%2\;clr %0\;bld %0,0"
5584 [(set_attr "length" "1,2,2,2,3")
5585 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
5586
5587(define_insn_and_split "*extzv.qihi1"
5588 [(set (match_operand:HI 0 "register_operand" "=r")
5589 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
5590 (const_int 1)
5591 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
5592 ""
5593 "#"
5594 ""
5595 [(set (match_dup 3)
5596 (zero_extract:QI (match_dup 1)
5597 (const_int 1)
5598 (match_dup 2)))
5599 (set (match_dup 4)
5600 (const_int 0))]
5601 {
5602 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5603 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5604 })
5605
5606(define_insn_and_split "*extzv.qihi2"
5607 [(set (match_operand:HI 0 "register_operand" "=r")
5608 (zero_extend:HI
5609 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
5610 (const_int 1)
5611 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
5612 ""
5613 "#"
5614 ""
5615 [(set (match_dup 3)
5616 (zero_extract:QI (match_dup 1)
5617 (const_int 1)
5618 (match_dup 2)))
5619 (set (match_dup 4)
5620 (const_int 0))]
5621 {
5622 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5623 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5624 })