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