OSDN Git Service

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