OSDN Git Service

* target.h (gcc_target): Add asm_out.named_section,
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2    Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3    Contributed by Denis Chertykov (denisc@overta.ru)
4
5    This file is part of GNU CC.
6
7    GNU CC is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11    
12    GNU CC is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with GNU CC; see the file COPYING.  If not, write to
19    the Free Software Foundation, 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "regs.h"
26 #include "hard-reg-set.h"
27 #include "real.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "output.h"
31 #include "insn-attr.h"
32 #include "flags.h"
33 #include "reload.h"
34 #include "tree.h"
35 #include "expr.h"
36 #include "toplev.h"
37 #include "obstack.h"
38 #include "function.h"
39 #include "recog.h"
40 #include "tm_p.h"
41 #include "target.h"
42 #include "target-def.h"
43
44 /* Maximal allowed offset for an address in the LD command */
45 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
46
47 static int    avr_naked_function_p PARAMS ((tree));
48 static int    interrupt_function_p PARAMS ((tree));
49 static int    signal_function_p    PARAMS ((tree));
50 static int    sequent_regs_live    PARAMS ((void));
51 static const char * ptrreg_to_str  PARAMS ((int));
52 static const char * cond_string    PARAMS ((enum rtx_code));
53 static int    avr_num_arg_regs     PARAMS ((enum machine_mode, tree));
54 static int    out_adj_frame_ptr    PARAMS ((FILE *, int));
55 static int    out_set_stack_ptr    PARAMS ((FILE *, int, int));
56 static RTX_CODE compare_condition  PARAMS ((rtx insn));
57 static int    compare_sign_p       PARAMS ((rtx insn));
58 static int    reg_was_0            PARAMS ((rtx insn, rtx op));
59 static int    io_address_p         PARAMS ((rtx x, int size));
60 void          debug_hard_reg_set   PARAMS ((HARD_REG_SET set));
61 static int    avr_valid_type_attribute PARAMS ((tree, tree, tree, tree));
62 static int    avr_valid_decl_attribute PARAMS ((tree, tree, tree, tree));
63 static void   avr_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
64 static void   avr_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
65
66 /* Allocate registers from r25 to r8 for parameters for function calls */
67 #define FIRST_CUM_REG 26
68
69 /* Temporary register RTX (gen_rtx (REG,QImode,TMP_REGNO)) */
70 rtx tmp_reg_rtx;
71
72 /* Zeroed register RTX (gen_rtx (REG,QImode,ZERO_REGNO)) */
73 rtx zero_reg_rtx;
74
75 /* RTX for register which will be used for loading immediate values to
76    r0-r15 registers.  */
77 rtx ldi_reg_rtx;
78
79 /* AVR register names {"r0", "r1", ..., "r31"} */
80 const char * avr_regnames[] = REGISTER_NAMES;
81
82 /* This holds the last insn address.  */
83 static int last_insn_address = 0;
84
85 /* Commands count in the compiled file */
86 static int commands_in_file;
87
88 /* Commands in the functions prologues in the compiled file */
89 static int commands_in_prologues;
90
91 /* Commands in the functions epilogues in the compiled file */
92 static int commands_in_epilogues;
93
94 /* Prologue/Epilogue size in words */
95 static int prologue_size;
96 static int epilogue_size;
97
98 /* Size of all jump tables in the current function, in words.  */
99 static int jump_tables_size;
100
101 /* Initial stack value specified by the `-minit-stack=' option */
102 const char *avr_init_stack = "__stack";
103
104 /* Default MCU name */
105 const char *avr_mcu_name = "avr2";
106
107 /* More than 8K of program memory: use "call" and "jmp".  */
108 int avr_mega_p = 0;
109
110 /* Enhanced core: use "movw", "mul", ...  */
111 int avr_enhanced_p = 0;
112
113 enum avr_arch {
114   AVR1 = 1,
115   AVR2,
116   AVR3,
117   AVR4,
118   AVR5
119 };
120
121 struct mcu_type_s {
122   const char *name;
123   enum avr_arch arch;
124 };
125
126 /* List of all known AVR MCU types - if updated, it has to be kept
127    in sync in several places (FIXME: is there a better way?):
128     - here
129     - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
130     - t-avr (MULTILIB_MATCHES)
131     - gas/config/tc-avr.c
132     - avr-libc  */
133
134 static const struct mcu_type_s avr_mcu_types[] = {
135     /* Classic, <= 8K.  */
136   { "avr2",      AVR2 },
137   { "at90s2313", AVR2 },
138   { "at90s2323", AVR2 },
139   { "attiny22",  AVR2 },
140   { "at90s2333", AVR2 },
141   { "at90s2343", AVR2 },
142   { "at90s4414", AVR2 },
143   { "at90s4433", AVR2 },
144   { "at90s4434", AVR2 },
145   { "at90s8515", AVR2 },
146   { "at90c8534", AVR2 },
147   { "at90s8535", AVR2 },
148     /* Classic, > 8K.  */
149   { "avr3",      AVR3 },
150   { "atmega103", AVR3 },
151   { "atmega603", AVR3 },
152     /* Enhanced, <= 8K.  */
153   { "avr4",      AVR4 },
154   { "atmega83",  AVR4 },
155   { "atmega85",  AVR4 },
156     /* Enhanced, > 8K.  */
157   { "avr5",      AVR5 },
158   { "atmega161", AVR5 },
159   { "atmega163", AVR5 },
160   { "atmega32",  AVR5 },
161   { "at94k",     AVR5 },
162     /* Assembler only.  */
163   { "avr1",      AVR1 },
164   { "at90s1200", AVR1 },
165   { "attiny10",  AVR1 },
166   { "attiny11",  AVR1 },
167   { "attiny12",  AVR1 },
168   { "attiny15",  AVR1 },
169   { "attiny28",  AVR1 },
170   { NULL, 0 }
171 };
172
173 int avr_case_values_threshold = 30000;
174 \f
175 /* Initialize the GCC target structure.  */
176 #undef TARGET_ASM_FUNCTION_PROLOGUE
177 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
178 #undef TARGET_ASM_FUNCTION_EPILOGUE
179 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
180 #undef TARGET_VALID_DECL_ATTRIBUTE
181 #define TARGET_VALID_DECL_ATTRIBUTE avr_valid_decl_attribute
182
183 #undef TARGET_VALID_TYPE_ATTRIBUTE
184 #define TARGET_VALID_TYPE_ATTRIBUTE avr_valid_type_attribute
185
186 struct gcc_target targetm = TARGET_INITIALIZER;
187 \f
188 void
189 avr_override_options ()
190 {
191   const struct mcu_type_s *t;
192
193   for (t = avr_mcu_types; t->name; t++)
194     if (strcmp (t->name, avr_mcu_name) == 0)
195       break;
196
197   if (!t->name)
198     {
199       fprintf (stderr, "Unknown MCU `%s' specified\nKnown MCU names:\n",
200                avr_mcu_name);
201       for (t = avr_mcu_types; t->name; t++)
202         fprintf (stderr,"   %s\n", t->name);
203     }
204
205   switch (t->arch)
206     {
207     case AVR1:
208     default:
209       error ("MCU `%s' not supported", avr_mcu_name);
210       /* ... fall through ... */
211     case AVR2: avr_enhanced_p = 0; avr_mega_p = 0; break;
212     case AVR3: avr_enhanced_p = 0; avr_mega_p = 1; break;
213     case AVR4: avr_enhanced_p = 1; avr_mega_p = 0; break;
214     case AVR5: avr_enhanced_p = 1; avr_mega_p = 1; break;
215     }
216
217   if (optimize && !TARGET_NO_TABLEJUMP)
218     avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
219 }
220
221
222 /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
223 void
224 avr_init_once ()
225 {
226   tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
227   memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
228   PUT_CODE (tmp_reg_rtx, REG);
229   PUT_MODE (tmp_reg_rtx, QImode);
230   XINT (tmp_reg_rtx, 0) = TMP_REGNO;
231
232   zero_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
233   memset (zero_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
234   PUT_CODE (zero_reg_rtx, REG);
235   PUT_MODE (zero_reg_rtx, QImode);
236   XINT (zero_reg_rtx, 0) = ZERO_REGNO;
237
238   ldi_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
239   memset (ldi_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
240   PUT_CODE (ldi_reg_rtx, REG);
241   PUT_MODE (ldi_reg_rtx, QImode);
242   XINT (ldi_reg_rtx, 0) = LDI_REG_REGNO;
243 }
244
245 /*  return register class from register number */
246
247 static int reg_class_tab[]={
248   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
249   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
250   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
251   GENERAL_REGS, /* r0 - r15 */
252   LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
253   LD_REGS,                      /* r16 - 23 */
254   ADDW_REGS,ADDW_REGS,          /* r24,r25 */
255   POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
256   POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
257   POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
258   STACK_REG,STACK_REG           /* SPL,SPH */
259 };
260
261 /* Return register class for register R */
262
263 enum reg_class
264 avr_regno_reg_class (r)
265      int r;
266 {
267   if (r <= 33)
268     return reg_class_tab[r];
269   return ALL_REGS;
270 }
271
272
273 /* A C expression which defines the machine-dependent operand
274    constraint letters for register classes.  If C is such a
275    letter, the value should be the register class corresponding to
276    it.  Otherwise, the value should be `NO_REGS'.  The register
277    letter `r', corresponding to class `GENERAL_REGS', will not be
278    passed to this macro; you do not need to handle it.  */
279
280 enum reg_class
281 avr_reg_class_from_letter  (c)
282      int c;
283 {
284   switch (c)
285     {
286     case 't' : return R0_REG;
287     case 'b' : return BASE_POINTER_REGS;
288     case 'e' : return POINTER_REGS;
289     case 'w' : return ADDW_REGS;
290     case 'd' : return LD_REGS;
291     case 'l' : return NO_LD_REGS;
292     case 'a' : return SIMPLE_LD_REGS;
293     case 'x' : return POINTER_X_REGS;
294     case 'y' : return POINTER_Y_REGS;
295     case 'z' : return POINTER_Z_REGS;
296     case 'q' : return STACK_REG;
297     default: break;
298     }
299   return NO_REGS;
300 }
301
302 /* Return non-zero if FUNC is a naked function.  */
303
304 static int
305 avr_naked_function_p (func)
306      tree func;
307 {
308   tree a;
309
310   if (TREE_CODE (func) != FUNCTION_DECL)
311     abort ();
312   
313   a = lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func));
314   return a != NULL_TREE;
315 }
316
317 /* Return nonzero if FUNC is an interrupt function as specified
318    by the "interrupt" attribute.  */
319
320 static int
321 interrupt_function_p (func)
322      tree func;
323 {
324   tree a;
325
326   if (TREE_CODE (func) != FUNCTION_DECL)
327     return 0;
328
329   a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
330   return a != NULL_TREE;
331 }
332
333 /* Return nonzero if FUNC is a signal function as specified
334    by the "signal" attribute.  */
335
336 static int
337 signal_function_p (func)
338      tree func;
339 {
340   tree a;
341
342   if (TREE_CODE (func) != FUNCTION_DECL)
343     return 0;
344
345   a = lookup_attribute ("signal", DECL_MACHINE_ATTRIBUTES (func));
346   return a != NULL_TREE;
347 }
348
349 /* Compute offset between arg_pointer and frame_pointer */
350
351 int
352 initial_elimination_offset (from, to)
353      int from;
354      int to;
355 {
356   int reg;
357   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
358     return 0;
359   else
360     {
361       int interrupt_func_p = interrupt_function_p (current_function_decl);
362       int signal_func_p = signal_function_p (current_function_decl);
363       int leaf_func_p = leaf_function_p ();
364       int offset= frame_pointer_needed ? 2 : 0;
365
366       for (reg = 0; reg < 32; ++reg)
367         {
368           if ((!leaf_func_p && (call_used_regs[reg]
369                                 && (interrupt_func_p || signal_func_p)))
370               || (regs_ever_live[reg]
371                   && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
372                   && ! (frame_pointer_needed
373                         && (reg == REG_Y || reg == (REG_Y+1)))))
374             {
375               ++offset;
376             }
377         }
378       return get_frame_size () + 2 + 1 + offset;
379     }
380   return 0;
381 }
382
383 /* This function checks sequence of live registers */
384
385 static int
386 sequent_regs_live ()
387 {
388   int reg;
389   int live_seq=0;
390   int cur_seq=0;
391
392   for (reg = 0; reg < 18; ++reg)
393     {
394       if (!call_used_regs[reg])
395         {
396           if (regs_ever_live[reg])
397             {
398               ++live_seq;
399               ++cur_seq;
400             }
401           else
402             cur_seq = 0;
403         }
404     }
405
406   if (!frame_pointer_needed)
407     {
408       if (regs_ever_live[REG_Y])
409         {
410           ++live_seq;
411           ++cur_seq;
412         }
413       else
414         cur_seq = 0;
415
416       if (regs_ever_live[REG_Y+1])
417         {
418           ++live_seq;
419           ++cur_seq;
420         }
421       else
422         cur_seq = 0;
423     }
424   else
425     {
426       cur_seq += 2;
427       live_seq += 2;
428     }
429   return (cur_seq == live_seq) ? live_seq : 0;
430 }
431
432
433 /* Output to FILE the asm instructions to adjust the frame pointer by
434    ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
435    (epilogue).  Returns the number of instructions generated.  */
436
437 static int
438 out_adj_frame_ptr (file, adj)
439      FILE *file;
440      int adj;
441 {
442   int size = 0;
443
444   if (adj)
445     {
446       if (TARGET_TINY_STACK)
447         {
448           if (adj < -63 || adj > 63)
449             warning ("large frame pointer change (%d) with -mtiny-stack", adj);
450
451           /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
452              over "sbiw" (2 cycles, same size).  */
453
454           fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
455           size++;
456         }
457       else if (adj < -63 || adj > 63)
458         {
459           fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
460                           AS2 (sbci, r29, hi8(%d)) CR_TAB),
461                    adj, adj);
462           size += 2;
463         }
464       else if (adj < 0)
465         {
466           fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
467           size++;
468         }
469       else
470         {
471           fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
472           size++;
473         }
474     }
475   return size;
476 }
477
478
479 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
480    handling various cases of interrupt enable flag state BEFORE and AFTER
481    (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
482    Returns the number of instructions generated.  */
483
484 static int
485 out_set_stack_ptr (file, before, after)
486      FILE *file;
487      int before;
488      int after;
489 {
490   int do_sph, do_cli, do_save, do_sei, lock_sph, size;
491
492   /* The logic here is so that -mno-interrupts actually means
493      "it is safe to write SPH in one instruction, then SPL in the
494      next instruction, without disabling interrupts first".
495      The after != -1 case (interrupt/signal) is not affected.  */
496
497   do_sph = !TARGET_TINY_STACK;
498   lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
499   do_cli = (before != 0 && (after == 0 || lock_sph));
500   do_save = (do_cli && before == -1 && after == -1);
501   do_sei = ((do_cli || before != 1) && after == 1);
502   size = 1;
503
504   if (do_save)
505     {
506       fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
507       size++;
508     }
509
510   if (do_cli)
511     {
512       fprintf (file, "cli" CR_TAB);
513       size++;
514     }
515
516   /* Do SPH first - maybe this will disable interrupts for one instruction
517      someday (a suggestion has been sent to avr@atmel.com for consideration
518      in future devices - that would make -mno-interrupts always safe).  */
519   if (do_sph)
520     {
521       fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
522       size++;
523     }
524
525   /* Set/restore the I flag now - interrupts will be really enabled only
526      after the next instruction.  This is not clearly documented, but
527      believed to be true for all AVR devices.  */
528   if (do_save)
529     {
530       fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
531       size++;
532     }
533   else if (do_sei)
534     {
535       fprintf (file, "sei" CR_TAB);
536       size++;
537     }
538
539   fprintf (file, AS2 (out, __SP_L__, r28) "\n");
540
541   return size;
542 }
543
544
545 /* Output function prologue */
546
547 static void
548 avr_output_function_prologue (file, size)
549      FILE *file;
550      HOST_WIDE_INT size;
551 {
552   int reg;
553   int interrupt_func_p;
554   int signal_func_p;
555   int leaf_func_p;
556   int main_p;
557   int live_seq;
558   int minimize;
559   
560   if (avr_naked_function_p (current_function_decl))
561     {
562       fprintf (file, "/* prologue: naked */\n");
563       return;
564     }
565
566   interrupt_func_p = interrupt_function_p (current_function_decl);
567   signal_func_p = signal_function_p (current_function_decl);
568   leaf_func_p = leaf_function_p ();
569   main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
570   live_seq = sequent_regs_live ();
571   minimize = (TARGET_CALL_PROLOGUES
572               && !interrupt_func_p && !signal_func_p && live_seq);
573
574   last_insn_address = 0;
575   jump_tables_size = 0;
576   prologue_size = 0;
577   fprintf (file, "/* prologue: frame size=%d */\n", size);
578   
579   if (interrupt_func_p)
580     {
581       fprintf (file,"\tsei\n");
582       ++prologue_size;
583     }
584   if (interrupt_func_p | signal_func_p)
585     {
586       fprintf (file, "\t"
587                AS1 (push,__zero_reg__)   CR_TAB
588                AS1 (push,__tmp_reg__)    CR_TAB
589                AS2 (in,__tmp_reg__,__SREG__) CR_TAB
590                AS1 (push,__tmp_reg__)    CR_TAB
591                AS1 (clr,__zero_reg__)    "\n");
592       prologue_size += 5;
593     }
594   if (main_p)
595     {
596       fprintf (file, ("\t" 
597                       AS2 (ldi,r28,lo8(%s - %d)) CR_TAB
598                       AS2 (ldi,r29,hi8(%s - %d)) CR_TAB
599                       AS2 (out,__SP_H__,r29)     CR_TAB
600                       AS2 (out,__SP_L__,r28) "\n"),
601                avr_init_stack, size, avr_init_stack, size);
602       
603       prologue_size += 4;
604     }
605   else if (minimize && (frame_pointer_needed || live_seq > 6)) 
606     {
607       fprintf (file, ("\t"
608                       AS2 (ldi, r26, lo8(%d)) CR_TAB
609                       AS2 (ldi, r27, hi8(%d)) CR_TAB), size, size);
610
611       fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
612                       AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB)
613                ,current_function_name, current_function_name);
614       
615       prologue_size += 4;
616       
617       if (AVR_MEGA)
618         {
619           fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
620                    (18 - live_seq) * 2);
621           prologue_size += 2;
622         }
623       else
624         {
625           fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
626                    (18 - live_seq) * 2);
627           ++prologue_size;
628         }
629       fprintf (file, ".L_%s_body:\n", current_function_name);
630     }
631   else
632     {
633       for (reg = 0; reg < 32; ++reg)
634         {
635           if ((!leaf_func_p
636                && (call_used_regs[reg]
637                    && (interrupt_func_p || signal_func_p)
638                    && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
639               || (regs_ever_live[reg]
640                   && (!call_used_regs[reg]
641                       || interrupt_func_p || signal_func_p)
642                   && ! (frame_pointer_needed
643                         && (reg == REG_Y || reg == (REG_Y+1)))))
644             {
645               fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
646               ++prologue_size;
647             }
648         }
649       if (frame_pointer_needed)
650         {
651           {
652             fprintf (file, "\t"
653                      AS1 (push,r28) CR_TAB
654                      AS1 (push,r29) CR_TAB
655                      AS2 (in,r28,__SP_L__) CR_TAB
656                      AS2 (in,r29,__SP_H__) "\n");
657             prologue_size += 4;
658             if (size)
659               {
660                 fputs ("\t", file);
661                 prologue_size += out_adj_frame_ptr (file, size);
662
663                 if (interrupt_func_p)
664                   {
665                     prologue_size += out_set_stack_ptr (file, 1, 1);
666                   }
667                 else if (signal_func_p)
668                   {
669                     prologue_size += out_set_stack_ptr (file, 0, 0);
670                   }
671                 else
672                   {
673                     prologue_size += out_set_stack_ptr (file, -1, -1);
674                   }
675               }
676           }
677         }
678     }
679   fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
680 }
681
682 /* Output function epilogue */
683
684 static void
685 avr_output_function_epilogue (file, size)
686      FILE *file;
687      HOST_WIDE_INT size;
688 {
689   int reg;
690   int interrupt_func_p;
691   int signal_func_p;
692   int leaf_func_p;
693   int main_p;
694   int function_size;
695   int live_seq;
696   int minimize;
697
698   if (avr_naked_function_p (current_function_decl))
699     {
700       fprintf (file, "/* epilogue: naked */\n");
701       return;
702     }
703
704   interrupt_func_p = interrupt_function_p (current_function_decl);
705   signal_func_p = signal_function_p (current_function_decl);
706   leaf_func_p = leaf_function_p ();
707   main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
708   function_size = (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
709                    - INSN_ADDRESSES (INSN_UID (get_insns ())));
710   function_size += jump_tables_size;
711   live_seq = sequent_regs_live ();
712   minimize = (TARGET_CALL_PROLOGUES
713               && !interrupt_func_p && !signal_func_p && live_seq);
714   
715   epilogue_size = 0;
716   fprintf (file, "/* epilogue: frame size=%d */\n", size);
717   if (main_p)
718     {
719       fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
720       ++epilogue_size;
721     }
722   else if (minimize && (frame_pointer_needed || live_seq > 4))
723     {
724       fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
725       ++epilogue_size;
726       if (frame_pointer_needed)
727         {
728           epilogue_size += out_adj_frame_ptr (file, -size);
729         }
730       else
731         {
732           fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
733                           AS2 (in , r29, __SP_H__) CR_TAB));
734           epilogue_size += 2;
735         }
736       
737       if (AVR_MEGA)
738         {
739           fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
740                    (18 - live_seq) * 2);
741           epilogue_size += 2;
742         }
743       else
744         {
745           fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
746                    (18 - live_seq) * 2);
747           ++epilogue_size;
748         }
749     }
750   else
751     {
752       if (frame_pointer_needed)
753         {
754           if (size)
755             {
756               fputs ("\t", file);
757               epilogue_size += out_adj_frame_ptr (file, -size);
758
759               if (interrupt_func_p | signal_func_p)
760                 {
761                   epilogue_size += out_set_stack_ptr (file, -1, 0);
762                 }
763               else
764                 {
765                   epilogue_size += out_set_stack_ptr (file, -1, -1);
766                 }
767             }
768           fprintf (file, "\t"
769                    AS1 (pop,r29) CR_TAB
770                    AS1 (pop,r28) "\n");
771           epilogue_size += 2;
772         }
773
774       for (reg = 31; reg >= 0; --reg)
775         {
776           if ((!leaf_func_p
777                && (call_used_regs[reg]
778                    && (interrupt_func_p || signal_func_p)
779                    && !(reg == TMP_REGNO || reg == ZERO_REGNO)))
780               || (regs_ever_live[reg]
781                   && (!call_used_regs[reg]
782                       || interrupt_func_p || signal_func_p)
783                   && ! (frame_pointer_needed
784                         && (reg == REG_Y || reg == (REG_Y+1)))))
785             {
786               fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
787               ++epilogue_size;
788             }
789         }
790       
791       if (interrupt_func_p | signal_func_p)
792         {
793           fprintf (file, "\t"
794                    AS1 (pop,__tmp_reg__)      CR_TAB
795                    AS2 (out,__SREG__,__tmp_reg__) CR_TAB
796                    AS1 (pop,__tmp_reg__)      CR_TAB
797                    AS1 (pop,__zero_reg__)     "\n");
798           epilogue_size += 4;
799           fprintf (file, "\treti\n");
800         }
801       else
802         fprintf (file, "\tret\n");
803       ++epilogue_size;
804     }
805   
806   fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
807   fprintf (file, "/* function %s size %d (%d) */\n", current_function_name,
808            prologue_size + function_size + epilogue_size, function_size);
809   commands_in_file += prologue_size + function_size + epilogue_size;
810   commands_in_prologues += prologue_size;
811   commands_in_epilogues += epilogue_size;
812 }
813
814
815 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
816    machine for a memory operand of mode MODE.  */
817
818 int
819 int
820 legitimate_address_p (mode, x, strict)
821      enum machine_mode mode;
822      rtx x;
823      int strict;
824 {
825   enum reg_class r = NO_REGS;
826   
827   if (TARGET_ALL_DEBUG)
828     {
829       fprintf (stderr, "mode: (%s) %s %s %s %s:",
830                GET_MODE_NAME(mode),
831                strict ? "(strict)": "",
832                reload_completed ? "(reload_completed)": "",
833                reload_in_progress ? "(reload_in_progress)": "",
834                reg_renumber ? "(reg_renumber)" : "");
835       if (GET_CODE (x) == PLUS
836           && REG_P (XEXP (x, 0))
837           && GET_CODE (XEXP (x, 1)) == CONST_INT
838           && INTVAL (XEXP (x, 1)) >= 0
839           && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
840           && reg_renumber
841           )
842         fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
843                  true_regnum (XEXP (x, 0)));
844       debug_rtx (x);
845     }
846   if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
847                     : REG_OK_FOR_BASE_NOSTRICT_P (x)))
848     r = POINTER_REGS;
849   else if (CONSTANT_ADDRESS_P (x))
850     r = ALL_REGS;
851   else if (GET_CODE (x) == PLUS
852            && REG_P (XEXP (x, 0))
853            && GET_CODE (XEXP (x, 1)) == CONST_INT
854            && INTVAL (XEXP (x, 1)) >= 0)
855     {
856       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
857       if (fit)
858         {
859           if (! strict
860               || REGNO (XEXP (x,0)) == REG_Y
861               || REGNO (XEXP (x,0)) == REG_Z)
862             r = BASE_POINTER_REGS;
863           if (XEXP (x,0) == frame_pointer_rtx
864               || XEXP (x,0) == arg_pointer_rtx)
865             r = BASE_POINTER_REGS;
866         }
867       else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
868         r = POINTER_Y_REGS;
869     }
870   else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
871            && REG_P (XEXP (x, 0))
872            && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
873                : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
874     {
875       r = POINTER_REGS;
876     }
877   if (TARGET_ALL_DEBUG)
878     {
879       fprintf (stderr, "   ret = %c\n", r);
880     }
881   return r == NO_REGS ? 0 : (int)r;
882 }
883
884 /* Attempts to replace X with a valid
885    memory address for an operand of mode MODE  */
886
887 rtx
888 legitimize_address (x, oldx, mode)
889      rtx x;
890      rtx oldx;
891      enum machine_mode mode;
892 {
893   x = oldx;
894   if (TARGET_ALL_DEBUG)
895     {
896       fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
897       debug_rtx (oldx);
898     }
899   
900   if (GET_CODE (oldx) == PLUS
901       && REG_P (XEXP (oldx,0)))
902     {
903       if (REG_P (XEXP (oldx,1)))
904         x = force_reg (GET_MODE (oldx), oldx);
905       else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
906         {
907           int offs = INTVAL (XEXP (oldx,1));
908           if (frame_pointer_rtx != XEXP (oldx,0))
909             if (offs > MAX_LD_OFFSET (mode))
910               {
911                 if (TARGET_ALL_DEBUG)
912                   fprintf (stderr, "force_reg (big offset)\n");
913                 x = force_reg (GET_MODE (oldx), oldx);
914               }
915         }
916     }
917   return x;
918 }
919
920
921 /* Return a pointer register name as a string */
922
923 static const char *
924 ptrreg_to_str (regno)
925      int regno;
926 {
927   switch (regno)
928     {
929     case REG_X: return "X";
930     case REG_Y: return "Y";
931     case REG_Z: return "Z";
932     default:
933       abort ();
934     }
935   return NULL;
936 }
937
938 /* Return the condition name as a string.
939    Used in conditional jump constructing  */
940
941 static const char *
942 cond_string (code)
943      enum rtx_code code;
944 {
945   switch (code)
946     {
947     case NE:
948       return "ne";
949     case EQ:
950       return "eq";
951     case GE:
952       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
953         return "pl";
954       else
955         return "ge";
956     case LT:
957       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
958         return "mi";
959       else
960         return "lt";
961     case GEU:
962       return "sh";
963     case LTU:
964       return "lo";
965     default:
966       abort ();
967     }
968 }
969
970 /* Output ADDR to FILE as address */
971
972 void
973 print_operand_address (file, addr)
974      FILE *file;
975      rtx addr;
976 {
977   switch (GET_CODE (addr))
978     {
979     case REG:
980       fprintf (file, ptrreg_to_str (REGNO (addr)));
981       break;
982
983     case PRE_DEC:
984       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
985       break;
986
987     case POST_INC:
988       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
989       break;
990
991     default:
992       if (CONSTANT_ADDRESS_P (addr)
993           && (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
994         {
995           fprintf (file, "pm(");
996           output_addr_const (file,addr);
997           fprintf (file ,")");
998         }
999       else
1000         output_addr_const (file, addr);
1001     }
1002 }
1003
1004
1005 /* Output X as assembler operand to file FILE */
1006      
1007 void
1008 print_operand (file, x, code)
1009      FILE *file;
1010      rtx x;
1011      int code;
1012 {
1013   int abcd = 0;
1014
1015   if (code >= 'A' && code <= 'D')
1016     abcd = code - 'A';
1017
1018   if (code == '~')
1019     {
1020       if (!AVR_MEGA)
1021         fputc ('r', file);
1022     }
1023   else if (REG_P (x))
1024     {
1025       if (x == zero_reg_rtx)
1026         fprintf (file, "__zero_reg__");
1027       else
1028         fprintf (file, reg_names[true_regnum (x) + abcd]);
1029     }
1030   else if (GET_CODE (x) == CONST_INT)
1031     fprintf (file, "%d", INTVAL (x) + abcd);
1032   else if (GET_CODE (x) == MEM)
1033     {
1034       rtx addr = XEXP (x,0);
1035
1036       if (CONSTANT_P (addr) && abcd)
1037         {
1038           fputc ('(', file);
1039           output_address (addr);
1040           fprintf (file, ")+%d", abcd);
1041         }
1042       else if (code == 'o')
1043         {
1044           if (GET_CODE (addr) != PLUS)
1045             fatal_insn ("Bad address, not (reg+disp):", addr);
1046
1047           print_operand (file, XEXP (addr, 1), 0);
1048         }
1049       else if (GET_CODE (addr) == PLUS)
1050         {
1051           print_operand_address (file, XEXP (addr,0));
1052           if (REGNO (XEXP (addr, 0)) == REG_X)
1053             fatal_insn ("Internal compiler bug.\nBad address:"
1054                         ,addr);
1055           fputc ('+', file);
1056           print_operand (file, XEXP (addr,1), code);
1057         }
1058       else
1059         print_operand_address (file, addr);
1060     }
1061   else if (GET_CODE (x) == CONST_DOUBLE)
1062     {
1063       long val;
1064       REAL_VALUE_TYPE rv;
1065       if (GET_MODE (x) != SFmode)
1066         fatal_insn ("Internal compiler bug. Unknown mode:", x);
1067       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1068       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1069       asm_fprintf (file, "0x%lx", val);
1070     }
1071   else if (code == 'j')
1072     asm_fprintf (file, cond_string (GET_CODE (x)));
1073   else if (code == 'k')
1074     asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1075   else
1076     print_operand_address (file, x);
1077 }
1078
1079 /* Recognize operand OP of mode MODE used in call instructions */
1080
1081 int
1082 call_insn_operand (op, mode)
1083      rtx op;
1084      enum machine_mode mode ATTRIBUTE_UNUSED;
1085 {
1086   if (GET_CODE (op) == MEM)
1087     {
1088       rtx inside = XEXP (op, 0);
1089       if (register_operand (inside, Pmode))
1090         return 1;
1091       if (CONSTANT_ADDRESS_P (inside))
1092         return 1;
1093     }
1094   return 0;
1095 }
1096
1097 /* Update the condition code in the INSN.  */
1098
1099 void
1100 notice_update_cc (body, insn)
1101      rtx body ATTRIBUTE_UNUSED;
1102      rtx insn;
1103 {
1104   rtx set;
1105   
1106   switch (get_attr_cc (insn))
1107     {
1108     case CC_NONE:
1109       /* Insn does not affect CC at all.  */
1110       break;
1111
1112     case CC_SET_N:
1113       CC_STATUS_INIT;
1114       break;
1115
1116     case CC_SET_ZN:
1117       set = single_set (insn);
1118       CC_STATUS_INIT;
1119       if (set)
1120         {
1121           cc_status.flags |= CC_NO_OVERFLOW;
1122           cc_status.value1 = SET_DEST (set);
1123         }
1124       break;
1125
1126     case CC_SET_CZN:
1127       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1128          The V flag may or may not be known but that's ok because
1129          alter_cond will change tests to use EQ/NE.  */
1130       set = single_set (insn);
1131       CC_STATUS_INIT;
1132       if (set)
1133         {
1134           cc_status.value1 = SET_DEST (set);
1135           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1136         }
1137       break;
1138
1139     case CC_COMPARE:
1140       set = single_set (insn);
1141       CC_STATUS_INIT;
1142       if (set)
1143         cc_status.value1 = SET_SRC (set);
1144       break;
1145       
1146     case CC_CLOBBER:
1147       /* Insn doesn't leave CC in a usable state.  */
1148       CC_STATUS_INIT;
1149
1150       /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1151       set = single_set (insn);
1152       if (set)
1153         {
1154           rtx src = SET_SRC (set);
1155           
1156           if (GET_CODE (src) == ASHIFTRT
1157               && GET_MODE (src) == QImode)
1158             {
1159               rtx x = XEXP (src, 1);
1160
1161               if (GET_CODE (x) == CONST_INT
1162                   && INTVAL (x) != 6)
1163                 {
1164                   cc_status.value1 = SET_DEST (set);
1165                   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1166                 }
1167             }
1168         }
1169       break;
1170     }
1171 }
1172
1173 /* Return maximum number of consecutive registers of
1174    class CLASS needed to hold a value of mode MODE.  */
1175
1176 int
1177 class_max_nregs (class, mode)
1178      enum reg_class class ATTRIBUTE_UNUSED;
1179      enum machine_mode mode;
1180 {
1181   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1182 }
1183
1184 /* Choose mode for jump insn:
1185    1 - relative jump in range -63 <= x <= 62 ;
1186    2 - relative jump in range -2046 <= x <= 2045 ;
1187    3 - absolute jump (only for ATmega[16]03).  */
1188
1189 int
1190 avr_jump_mode (x, insn)
1191      rtx x;                     /* jump operand */
1192      rtx insn;                  /* jump insn */
1193 {
1194   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1195                                             ? XEXP (x, 0) : x));
1196   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1197   int jump_distance = cur_addr - dest_addr;
1198   
1199   if (-63 <= jump_distance && jump_distance <= 62)
1200     return 1;
1201   else if (-2046 <= jump_distance && jump_distance <= 2045)
1202     return 2;
1203   else if (AVR_MEGA)
1204     return 3;
1205   
1206   return 2;
1207 }
1208
1209 /* return an AVR condition jump commands.
1210    X is a comparison RTX.
1211    LEN is a number returned by avr_jump_mode function.
1212    if REVERSE nonzero then condition code in X must be reversed.  */
1213
1214 const char *
1215 ret_cond_branch (x, len, reverse)
1216      rtx x;
1217      int len;
1218      int reverse;
1219 {
1220   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1221   
1222   switch (cond)
1223     {
1224     case GT:
1225       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1226         return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1227                             AS1 (brpl,%0)) :
1228                 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1229                             AS1 (brmi,_PC_+2) CR_TAB
1230                             AS1 (rjmp,%0)) :
1231                 (AS1 (breq,_PC_+6) CR_TAB
1232                  AS1 (brmi,_PC_+4) CR_TAB
1233                  AS1 (jmp,%0)));
1234           
1235       else
1236         return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1237                             AS1 (brge,%0)) :
1238                 len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1239                             AS1 (brlt,_PC_+2) CR_TAB
1240                             AS1 (rjmp,%0)) :
1241                 (AS1 (breq,_PC_+6) CR_TAB
1242                  AS1 (brlt,_PC_+4) CR_TAB
1243                  AS1 (jmp,%0)));
1244     case GTU:
1245       return (len == 1 ? (AS1 (breq,_PC_+2) CR_TAB
1246                           AS1 (brsh,%0)) :
1247               len == 2 ? (AS1 (breq,_PC_+4) CR_TAB
1248                           AS1 (brlo,_PC_+2) CR_TAB
1249                           AS1 (rjmp,%0)) :
1250               (AS1 (breq,_PC_+6) CR_TAB
1251                AS1 (brlo,_PC_+4) CR_TAB
1252                AS1 (jmp,%0)));
1253     case LE:
1254       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1255         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1256                             AS1 (brmi,%0)) :
1257                 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1258                             AS1 (brpl,_PC_+2) CR_TAB
1259                             AS1 (rjmp,%0)) :
1260                 (AS1 (breq,_PC_+2) CR_TAB
1261                  AS1 (brpl,_PC_+4) CR_TAB
1262                  AS1 (jmp,%0)));
1263       else
1264         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1265                             AS1 (brlt,%0)) :
1266                 len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1267                             AS1 (brge,_PC_+2) CR_TAB
1268                             AS1 (rjmp,%0)) :
1269                 (AS1 (breq,_PC_+2) CR_TAB
1270                  AS1 (brge,_PC_+4) CR_TAB
1271                  AS1 (jmp,%0)));
1272     case LEU:
1273       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1274                           AS1 (brlo,%0)) :
1275               len == 2 ? (AS1 (breq,_PC_+2) CR_TAB
1276                           AS1 (brsh,_PC_+2) CR_TAB
1277                           AS1 (rjmp,%0)) :
1278               (AS1 (breq,_PC_+2) CR_TAB
1279                AS1 (brsh,_PC_+4) CR_TAB
1280                AS1 (jmp,%0)));
1281     default:
1282       if (reverse)
1283         {
1284           switch (len)
1285             {
1286             case 1:
1287               return AS1 (br%k1,%0);
1288             case 2:
1289               return (AS1 (br%j1,_PC_+2) CR_TAB
1290                       AS1 (rjmp,%0));
1291             default:
1292               return (AS1 (br%j1,_PC_+4) CR_TAB
1293                       AS1 (jmp,%0));
1294             }
1295         }
1296         else
1297           {
1298             switch (len)
1299               {
1300               case 1:
1301                 return AS1 (br%j1,%0);
1302               case 2:
1303                 return (AS1 (br%k1,_PC_+2) CR_TAB
1304                         AS1 (rjmp,%0));
1305               default:
1306                 return (AS1 (br%k1,_PC_+4) CR_TAB
1307                         AS1 (jmp,%0));
1308               }
1309           }
1310     }
1311   return "";
1312 }
1313
1314 /* Predicate function for immediate operand which fits to byte (8bit) */
1315
1316 int
1317 byte_immediate_operand (op, mode)
1318      register rtx op;
1319      enum machine_mode mode ATTRIBUTE_UNUSED;
1320 {
1321   return (GET_CODE (op) == CONST_INT
1322           && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1323 }
1324
1325 /* Output all insn addresses and their sizes into the assembly language
1326    output file.  This is helpful for debugging whether the length attributes
1327    in the md file are correct.
1328    Output insn cost for next insn.  */
1329
1330 void
1331 final_prescan_insn (insn, operand, num_operands)
1332      rtx insn, *operand ATTRIBUTE_UNUSED;
1333      int num_operands ATTRIBUTE_UNUSED;
1334 {
1335   int uid = INSN_UID (insn);
1336
1337   if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1338     {
1339       fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1340                INSN_ADDRESSES (uid),
1341                INSN_ADDRESSES (uid) - last_insn_address,
1342                rtx_cost (PATTERN (insn), INSN));
1343     }
1344   last_insn_address = INSN_ADDRESSES (uid);
1345
1346   if (TARGET_RTL_DUMP)
1347     {
1348       fprintf (asm_out_file, "/*****************\n");
1349       print_rtl_single (asm_out_file, insn);
1350       fprintf (asm_out_file, "*****************/\n");
1351     }
1352 }
1353
1354 /* Return 0 if undefined, 1 if always true or always false.  */
1355
1356 int
1357 avr_simplify_comparision_p (mode, operator, x)
1358      enum machine_mode mode;
1359      RTX_CODE operator;
1360      rtx x;
1361 {
1362   unsigned int max = (mode == QImode ? 0xff :
1363                       mode == HImode ? 0xffff :
1364                       mode == SImode ? 0xffffffffU : 0);
1365   if (max && operator && GET_CODE (x) == CONST_INT)
1366     {
1367       if (unsigned_condition (operator) != operator)
1368         max >>= 1;
1369
1370       if (max != (INTVAL (x) & max)
1371           && INTVAL (x) != 0xff)
1372         return 1;
1373     }
1374   return 0;
1375 }
1376
1377
1378 /* Returns nonzero if REGNO is the number of a hard
1379    register in which function arguments are sometimes passed.  */
1380
1381 int
1382 function_arg_regno_p(r)
1383      int r;
1384 {
1385   return (r >= 8 && r <= 25);
1386 }
1387
1388 /* Initializing the variable cum for the state at the beginning
1389    of the argument list.  */
1390
1391 void
1392 init_cumulative_args (cum, fntype, libname, indirect)
1393      CUMULATIVE_ARGS *cum;
1394      tree fntype;
1395      rtx libname;
1396      int indirect ATTRIBUTE_UNUSED;
1397 {
1398   cum->nregs = 18;
1399   cum->regno = FIRST_CUM_REG;
1400   if (!libname)
1401     {
1402       int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1403                     && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1404                         != void_type_node));
1405       if (stdarg)
1406         cum->nregs = 0;
1407     }
1408 }
1409
1410 /* Returns the number of registers to allocate for a function argument.  */
1411
1412 static int
1413 avr_num_arg_regs (mode, type)
1414      enum machine_mode mode;
1415      tree type;
1416 {
1417   int size;
1418
1419   if (mode == BLKmode)
1420     size = int_size_in_bytes (type);
1421   else
1422     size = GET_MODE_SIZE (mode);
1423
1424   /* Align all function arguments to start in even-numbered registers.
1425      Odd-sized arguments leave holes above them.  */
1426
1427   return (size + 1) & ~1;
1428 }
1429
1430 /* Controls whether a function argument is passed
1431    in a register, and which register. */
1432
1433 rtx
1434 function_arg (cum, mode, type, named)
1435      CUMULATIVE_ARGS *cum;
1436      enum machine_mode mode;
1437      tree type;
1438      int named ATTRIBUTE_UNUSED;
1439 {
1440   int bytes = avr_num_arg_regs (mode, type);
1441
1442   if (cum->nregs && bytes <= cum->nregs)
1443     return gen_rtx (REG, mode, cum->regno - bytes);
1444
1445   return NULL_RTX;
1446 }
1447
1448 /* Update the summarizer variable CUM to advance past an argument
1449    in the argument list.  */
1450    
1451 void
1452 function_arg_advance (cum, mode, type, named)
1453      CUMULATIVE_ARGS *cum;      /* current arg information */
1454      enum machine_mode mode;    /* current arg mode */
1455      tree type;                 /* type of the argument or 0 if lib support */
1456      int named ATTRIBUTE_UNUSED; /* whether or not the argument was named */
1457 {
1458   int bytes = avr_num_arg_regs (mode, type);
1459
1460   cum->nregs -= bytes;
1461   cum->regno -= bytes;
1462
1463   if (cum->nregs <= 0)
1464     {
1465       cum->nregs = 0;
1466       cum->regno = FIRST_CUM_REG;
1467     }
1468 }
1469
1470 /***********************************************************************
1471   Functions for outputting various mov's for a various modes
1472 ************************************************************************/
1473 const char *
1474 output_movqi (insn, operands, l)
1475      rtx insn;
1476      rtx operands[];
1477      int *l;
1478 {
1479   int dummy;
1480   rtx dest = operands[0];
1481   rtx src = operands[1];
1482   int *real_l = l;
1483   
1484   if (!l)
1485     l = &dummy;
1486
1487   *l = 1;
1488   
1489   if (register_operand (dest, QImode))
1490     {
1491       if (register_operand (src, QImode)) /* mov r,r */
1492         {
1493           if (test_hard_reg_class (STACK_REG, dest))
1494             return AS2 (out,%0,%1);
1495           else if (test_hard_reg_class (STACK_REG, src))
1496             return AS2 (in,%0,%1);
1497           
1498           return AS2 (mov,%0,%1);
1499         }
1500       else if (CONSTANT_P (src))
1501         {
1502           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1503             return AS2 (ldi,%0,lo8(%1));
1504           
1505           if (GET_CODE (src) == CONST_INT)
1506             {
1507               if (src == const0_rtx) /* mov r,L */
1508                 return AS1 (clr,%0);
1509               else if (src == const1_rtx)
1510                 {
1511                   if (reg_was_0 (insn, dest))
1512                     return AS1 (inc,%0 ; reg_was_0);
1513
1514                   *l = 2;
1515                   return (AS1 (clr,%0) CR_TAB
1516                           AS1 (inc,%0));
1517                 }
1518               else if (src == constm1_rtx)
1519                 {
1520                   /* Immediate constants -1 to any register */
1521                   if (reg_was_0 (insn, dest))
1522                     return AS1 (dec,%0 ; reg_was_0);
1523
1524                   *l = 2;
1525                   return (AS1 (clr,%0) CR_TAB
1526                           AS1 (dec,%0));
1527                 }
1528               else
1529                 {
1530                   int bit_nr = exact_log2 (INTVAL (src));
1531
1532                   if (bit_nr >= 0)
1533                     {
1534                       if (reg_was_0 (insn, dest))
1535                         {
1536                           *l = 2;
1537                           if (!real_l)
1538                             output_asm_insn ("set ; reg_was_0", operands);
1539                         }
1540                       else
1541                         {
1542                           *l = 3;
1543                           if (!real_l)
1544                             output_asm_insn ((AS1 (clr,%0) CR_TAB
1545                                               "set"), operands);
1546                         }
1547                       if (!real_l)
1548                         avr_output_bld (operands, bit_nr);
1549
1550                       return "";
1551                     }
1552                 }
1553             }
1554           
1555           /* Last resort, larger than loading from memory.  */
1556           *l = 4;
1557           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1558                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1559                   AS2 (mov,%0,r31)          CR_TAB
1560                   AS2 (mov,r31,__tmp_reg__));
1561         }
1562       else if (GET_CODE (src) == MEM)
1563         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1564     }
1565   else if (GET_CODE (dest) == MEM)
1566     {
1567       const char *template;
1568
1569       if (src == const0_rtx)
1570         operands[1] = zero_reg_rtx;
1571
1572       template = out_movqi_mr_r (insn, operands, real_l);
1573
1574       if (!real_l)
1575         output_asm_insn (template, operands);
1576
1577       operands[1] = src;
1578     }
1579   return "";
1580 }
1581
1582
1583 const char *
1584 output_movhi (insn, operands, l)
1585      rtx insn;
1586      rtx operands[];
1587      int *l;
1588 {
1589   int dummy;
1590   rtx dest = operands[0];
1591   rtx src = operands[1];
1592   int *real_l = l;
1593   
1594   if (!l)
1595     l = &dummy;
1596   
1597   if (register_operand (dest, HImode))
1598     {
1599       if (register_operand (src, HImode)) /* mov r,r */
1600         {
1601           if (test_hard_reg_class (STACK_REG, dest))
1602             {
1603               if (TARGET_TINY_STACK)
1604                 {
1605                   *l = 1;
1606                   return AS2 (out,__SP_L__,%A1);
1607                 }
1608               else if (TARGET_NO_INTERRUPTS)
1609                 {
1610                   *l = 2;
1611                   return (AS2 (out,__SP_H__,%B1) CR_TAB
1612                           AS2 (out,__SP_L__,%A1));
1613                 }
1614
1615               *l = 5;
1616               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
1617                       "cli"                          CR_TAB
1618                       AS2 (out,__SP_H__,%B1)         CR_TAB
1619                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1620                       AS2 (out,__SP_L__,%A1));
1621             }
1622           else if (test_hard_reg_class (STACK_REG, src))
1623             {
1624               *l = 2;   
1625               return (AS2 (in,%A0,__SP_L__) CR_TAB
1626                       AS2 (in,%B0,__SP_H__));
1627             }
1628
1629           if (AVR_ENHANCED)
1630             {
1631               *l = 1;
1632               return (AS2 (movw,%0,%1));
1633             }
1634
1635           if (true_regnum (dest) > true_regnum (src))
1636             {
1637               *l = 2;
1638               return (AS2 (mov,%B0,%B1) CR_TAB
1639                       AS2 (mov,%A0,%A1));
1640             }
1641           else
1642             {
1643               *l = 2;
1644               return (AS2 (mov,%A0,%A1) CR_TAB
1645                       AS2 (mov,%B0,%B1));
1646             }
1647         }
1648       else if (CONSTANT_P (src))
1649         {
1650           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1651             {
1652               if (byte_immediate_operand (src, HImode)
1653                   && reg_was_0 (insn, dest))
1654                 {
1655                   *l = 1;
1656                   return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
1657                 }
1658
1659               *l = 2;
1660               return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1661                       AS2 (ldi,%B0,hi8(%1)));
1662             }
1663           
1664           if (GET_CODE (src) == CONST_INT)
1665             {
1666               if (src == const0_rtx) /* mov r,L */
1667                 {
1668                   *l = 2;
1669                   return (AS1 (clr,%A0) CR_TAB
1670                           AS1 (clr,%B0));
1671                 }
1672               else if (src == const1_rtx)
1673                 {
1674                   if (reg_was_0 (insn, dest))
1675                     {
1676                       *l = 1;
1677                       return AS1 (inc,%0 ; reg_was_0);
1678                     }
1679
1680                   *l = 3;
1681                   return (AS1 (clr,%A0) CR_TAB
1682                           AS1 (clr,%B0) CR_TAB
1683                           AS1 (inc,%A0));
1684                 }
1685               else if (src == constm1_rtx)
1686                 {
1687                   /* Immediate constants -1 to any register */
1688                   if (reg_was_0 (insn, dest))
1689                     {
1690                       *l = 2;
1691                       return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
1692                               AS1 (dec,%B0));
1693                     }
1694
1695                   *l = 3;
1696                   return (AS1 (clr,%0)  CR_TAB
1697                           AS1 (dec,%A0) CR_TAB
1698                           AS2 (mov,%B0,%A0));
1699                 }
1700               else
1701                 {
1702                   int bit_nr = exact_log2 (INTVAL (src));
1703
1704                   if (bit_nr >= 0)
1705                     {
1706                       if (reg_was_0 (insn, dest))
1707                         {
1708                           *l = 2;
1709                           if (!real_l)
1710                             output_asm_insn ("set ; reg_was_0", operands);
1711                         }
1712                       else
1713                         {
1714                           *l = 4;
1715                           if (!real_l)
1716                             output_asm_insn ((AS1 (clr,%A0) CR_TAB
1717                                               AS1 (clr,%B0) CR_TAB
1718                                               "set"), operands);
1719                         }
1720                       if (!real_l)
1721                         avr_output_bld (operands, bit_nr);
1722
1723                       return "";
1724                     }
1725                 }
1726
1727               if ((INTVAL (src) & 0xff) == 0)
1728                 {
1729                   *l = 5;
1730                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1731                           AS1 (clr,%A0)             CR_TAB
1732                           AS2 (ldi,r31,hi8(%1))     CR_TAB
1733                           AS2 (mov,%B0,r31)         CR_TAB
1734                           AS2 (mov,r31,__tmp_reg__));
1735                 }
1736               else if ((INTVAL (src) & 0xff00) == 0)
1737                 {
1738                   *l = 5;
1739                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1740                           AS2 (ldi,r31,lo8(%1))     CR_TAB
1741                           AS2 (mov,%A0,r31)         CR_TAB
1742                           AS1 (clr,%B0)             CR_TAB
1743                           AS2 (mov,r31,__tmp_reg__));
1744                 }
1745             }
1746           
1747           /* Last resort, equal to loading from memory.  */
1748           *l = 6;
1749           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1750                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1751                   AS2 (mov,%A0,r31)         CR_TAB
1752                   AS2 (ldi,r31,hi8(%1))     CR_TAB
1753                   AS2 (mov,%B0,r31)         CR_TAB
1754                   AS2 (mov,r31,__tmp_reg__));
1755         }
1756       else if (GET_CODE (src) == MEM)
1757         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1758     }
1759   else if (GET_CODE (dest) == MEM)
1760     {
1761       const char *template;
1762
1763       if (src == const0_rtx)
1764         operands[1] = zero_reg_rtx;
1765
1766       template = out_movhi_mr_r (insn, operands, real_l);
1767
1768       if (!real_l)
1769         output_asm_insn (template, operands);
1770
1771       operands[1] = src;
1772       return "";
1773     }
1774   fatal_insn ("Invalid insn:", insn);
1775   return "";
1776 }
1777
1778 const char *
1779 out_movqi_r_mr (insn, op, l)
1780      rtx insn;
1781      rtx op[];
1782      int *l; /* instruction length */
1783 {
1784   rtx dest = op[0];
1785   rtx src = op[1];
1786   rtx x = XEXP (src, 0);
1787   int dummy;
1788   
1789   if (!l)
1790     l = &dummy;
1791   
1792   if (CONSTANT_ADDRESS_P (x))
1793     {
1794       if (io_address_p (x, 1))
1795         {
1796           *l = 1;
1797           return AS2 (in,%0,%1-0x20);
1798         }
1799       *l = 2;
1800       return AS2 (lds,%0,%1);
1801     }
1802   /* memory access by reg+disp */
1803   else if (GET_CODE (x) == PLUS
1804       && REG_P (XEXP (x,0))
1805       && GET_CODE (XEXP (x,1)) == CONST_INT)
1806     {
1807       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1808         {
1809           int disp = INTVAL (XEXP (x,1));
1810           if (REGNO (XEXP (x,0)) != REG_Y)
1811             fatal_insn ("Incorrect insn:",insn);
1812
1813           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1814             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1815                             AS2 (ldd,%0,Y+63)     CR_TAB
1816                             AS2 (sbiw,r28,%o1-63));
1817
1818           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1819                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1820                           AS2 (ld,%0,Y)            CR_TAB
1821                           AS2 (subi,r28,lo8(%o1))  CR_TAB
1822                           AS2 (sbci,r29,hi8(%o1)));
1823         }
1824       else if (REGNO (XEXP (x,0)) == REG_X)
1825         {
1826           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1827              it but I have this situation with extremal optimizing options.  */
1828           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1829               || reg_unused_after (insn, XEXP (x,0)))
1830             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1831                             AS2 (ld,%0,X));
1832
1833           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1834                           AS2 (ld,%0,X)      CR_TAB
1835                           AS2 (sbiw,r26,%o1));
1836         }
1837       *l = 1;
1838       return AS2 (ldd,%0,%1);
1839     }
1840   *l = 1;
1841   return AS2 (ld,%0,%1);
1842 }
1843
1844 const char *
1845 out_movhi_r_mr (insn, op, l)
1846      rtx insn;
1847      rtx op[];
1848      int *l; /* instruction length */
1849 {
1850   rtx dest = op[0];
1851   rtx src = op[1];
1852   rtx base = XEXP (src, 0);
1853   int reg_dest = true_regnum (dest);
1854   int reg_base = true_regnum (base);
1855   int tmp;
1856
1857   if (!l)
1858     l = &tmp;
1859
1860   if (reg_base > 0)
1861     {
1862       if (reg_dest == reg_base)         /* R = (R) */
1863         {
1864           *l = 3;
1865           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1866                   AS2 (ld,%B0,%1) CR_TAB
1867                   AS2 (mov,%A0,__tmp_reg__));
1868         }
1869       else if (reg_base == REG_X)        /* (R26) */
1870         {
1871           if (reg_unused_after (insn, base))
1872             {
1873               *l = 2;
1874               return (AS2 (ld,%A0,X+) CR_TAB
1875                       AS2 (ld,%B0,X));
1876             }
1877           *l  = 3;
1878           return (AS2 (ld,%A0,X+) CR_TAB
1879                   AS2 (ld,%B0,X) CR_TAB
1880                   AS2 (sbiw,r26,1));
1881         }
1882       else                      /* (R)  */
1883         {
1884           *l = 2;
1885           return (AS2 (ld,%A0,%1)    CR_TAB
1886                   AS2 (ldd,%B0,%1+1));
1887         }
1888     }
1889   else if (GET_CODE (base) == PLUS) /* (R + i) */
1890     {
1891       int disp = INTVAL (XEXP (base, 1));
1892       int reg_base = true_regnum (XEXP (base, 0));
1893       
1894       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1895         {
1896           if (REGNO (XEXP (base, 0)) != REG_Y)
1897             fatal_insn ("Incorrect insn:",insn);
1898           
1899           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1900             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1901                             AS2 (ldd,%A0,Y+62)    CR_TAB
1902                             AS2 (ldd,%B0,Y+63)    CR_TAB
1903                             AS2 (sbiw,r28,%o1-62));
1904
1905           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1906                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1907                           AS2 (ld,%A0,Y)           CR_TAB
1908                           AS2 (ldd,%B0,Y+1)        CR_TAB
1909                           AS2 (subi,r28,lo8(%o1))  CR_TAB
1910                           AS2 (sbci,r29,hi8(%o1)));
1911         }
1912       if (reg_base == REG_X)
1913         {
1914           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1915              it but I have this situation with extremal
1916              optimization options.  */
1917           
1918           *l = 4;
1919           if (reg_base == reg_dest)
1920             return (AS2 (adiw,r26,%o1)      CR_TAB
1921                     AS2 (ld,__tmp_reg__,X+) CR_TAB
1922                     AS2 (ld,%B0,X)          CR_TAB
1923                     AS2 (mov,%A0,__tmp_reg__));
1924
1925           return (AS2 (adiw,r26,%o1) CR_TAB
1926                   AS2 (ld,%A0,X+)    CR_TAB
1927                   AS2 (ld,%B0,X)     CR_TAB
1928                   AS2 (sbiw,r26,%o1+1));
1929         }
1930
1931       if (reg_base == reg_dest)
1932         {
1933           *l = 3;
1934           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1935                   AS2 (ldd,%B0,%B1)         CR_TAB
1936                   AS2 (mov,%A0,__tmp_reg__));
1937         }
1938       
1939       *l = 2;
1940       return (AS2 (ldd,%A0,%A1) CR_TAB
1941               AS2 (ldd,%B0,%B1));
1942     }
1943   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1944     {
1945       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1946         fatal_insn ("Incorrect insn:", insn);
1947
1948       *l = 2;
1949       return (AS2 (ld,%B0,%1) CR_TAB
1950               AS2 (ld,%A0,%1));
1951     }
1952   else if (GET_CODE (base) == POST_INC) /* (R++) */
1953     {
1954       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1955         fatal_insn ("Incorrect insn:", insn);
1956
1957       *l = 2;
1958       return (AS2 (ld,%A0,%1)  CR_TAB
1959               AS2 (ld,%B0,%1));
1960     }
1961   else if (CONSTANT_ADDRESS_P (base))
1962     {
1963       if (io_address_p (base, 2))
1964         {
1965           *l = 2;
1966           return (AS2 (in,%A0,%A1-0x20) CR_TAB
1967                   AS2 (in,%B0,%B1-0x20));
1968         }
1969       *l = 4;
1970       return (AS2 (lds,%A0,%A1) CR_TAB
1971               AS2 (lds,%B0,%B1));
1972     }
1973   
1974   fatal_insn ("Unknown move insn:",insn);
1975   return "";
1976 }
1977
1978 const char *
1979 out_movsi_r_mr (insn, op, l)
1980      rtx insn;
1981      rtx op[];
1982      int *l; /* instruction length */
1983 {
1984   rtx dest = op[0];
1985   rtx src = op[1];
1986   rtx base = XEXP (src, 0);
1987   int reg_dest = true_regnum (dest);
1988   int reg_base = true_regnum (base);
1989   int tmp;
1990
1991   if (!l)
1992     l = &tmp;
1993   
1994   if (reg_base > 0)
1995     {
1996       if (reg_base == REG_X)        /* (R26) */
1997         {
1998           if (reg_dest == REG_X)
1999             /* "ld r26,-X" is undefined */
2000             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
2001                           AS2 (ld,r29,X)          CR_TAB
2002                           AS2 (ld,r28,-X)         CR_TAB
2003                           AS2 (ld,__tmp_reg__,-X) CR_TAB
2004                           AS2 (sbiw,r26,1)        CR_TAB
2005                           AS2 (ld,r26,X)          CR_TAB
2006                           AS2 (mov,r27,__tmp_reg__));
2007           else if (reg_dest == REG_X - 2)
2008             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2009                           AS2 (ld,%B0,X+) CR_TAB
2010                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
2011                           AS2 (ld,%D0,X)  CR_TAB
2012                           AS2 (mov,%C0,__tmp_reg__));
2013           else if (reg_unused_after (insn, base))
2014             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
2015                            AS2 (ld,%B0,X+) CR_TAB
2016                            AS2 (ld,%C0,X+) CR_TAB
2017                            AS2 (ld,%D0,X));
2018           else
2019             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2020                            AS2 (ld,%B0,X+) CR_TAB
2021                            AS2 (ld,%C0,X+) CR_TAB
2022                            AS2 (ld,%D0,X)  CR_TAB
2023                            AS2 (sbiw,r26,3));
2024         }
2025       else
2026         {
2027           if (reg_dest == reg_base)
2028             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2029                           AS2 (ldd,%C0,%1+2) CR_TAB
2030                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
2031                           AS2 (ld,%A0,%1)  CR_TAB
2032                           AS2 (mov,%B0,__tmp_reg__));
2033           else if (reg_base == reg_dest + 2)
2034             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2035                           AS2 (ldd,%B0,%1+1) CR_TAB
2036                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2037                           AS2 (ldd,%D0,%1+3) CR_TAB
2038                           AS2 (mov,%C0,__tmp_reg__));
2039           else
2040             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2041                           AS2 (ldd,%B0,%1+1) CR_TAB
2042                           AS2 (ldd,%C0,%1+2) CR_TAB
2043                           AS2 (ldd,%D0,%1+3));
2044         }
2045     }
2046   else if (GET_CODE (base) == PLUS) /* (R + i) */
2047     {
2048       int disp = INTVAL (XEXP (base, 1));
2049       
2050       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2051         {
2052           if (REGNO (XEXP (base, 0)) != REG_Y)
2053             fatal_insn ("Incorrect insn:",insn);
2054
2055           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2056             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2057                             AS2 (ldd,%A0,Y+60)    CR_TAB
2058                             AS2 (ldd,%B0,Y+61)    CR_TAB
2059                             AS2 (ldd,%C0,Y+62)    CR_TAB
2060                             AS2 (ldd,%D0,Y+63)    CR_TAB
2061                             AS2 (sbiw,r28,%o1-60));
2062
2063           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2064                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2065                           AS2 (ld,%A0,Y)           CR_TAB
2066                           AS2 (ldd,%B0,Y+1)        CR_TAB
2067                           AS2 (ldd,%C0,Y+2)        CR_TAB
2068                           AS2 (ldd,%D0,Y+3)        CR_TAB
2069                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2070                           AS2 (sbci,r29,hi8(%o1)));
2071         }
2072
2073       reg_base = true_regnum (XEXP (base, 0));
2074       if (reg_base == REG_X)
2075         {
2076           /* R = (X + d) */
2077           if (reg_dest == REG_X)
2078             {
2079               *l = 7;
2080               /* "ld r26,-X" is undefined */
2081               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2082                       AS2 (ld,r29,X)          CR_TAB
2083                       AS2 (ld,r28,-X)         CR_TAB
2084                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2085                       AS2 (sbiw,r26,1)        CR_TAB
2086                       AS2 (ld,r26,X)          CR_TAB
2087                       AS2 (mov,r27,__tmp_reg__));
2088             }
2089           *l = 6;
2090           if (reg_dest == REG_X - 2)
2091             return (AS2 (adiw,r26,%o1)      CR_TAB
2092                     AS2 (ld,r24,X+)         CR_TAB
2093                     AS2 (ld,r25,X+)         CR_TAB
2094                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2095                     AS2 (ld,r27,X)          CR_TAB
2096                     AS2 (mov,r26,__tmp_reg__));
2097
2098           return (AS2 (adiw,r26,%o1) CR_TAB
2099                   AS2 (ld,%A0,X+)    CR_TAB
2100                   AS2 (ld,%B0,X+)    CR_TAB
2101                   AS2 (ld,%C0,X+)    CR_TAB
2102                   AS2 (ld,%D0,X)     CR_TAB
2103                   AS2 (sbiw,r26,%o1+3));
2104         }
2105       if (reg_dest == reg_base)
2106         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2107                       AS2 (ldd,%C0,%C1) CR_TAB
2108                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2109                       AS2 (ldd,%A0,%A1) CR_TAB
2110                       AS2 (mov,%B0,__tmp_reg__));
2111       else if (reg_dest == reg_base - 2)
2112         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2113                       AS2 (ldd,%B0,%B1) CR_TAB
2114                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2115                       AS2 (ldd,%D0,%D1) CR_TAB
2116                       AS2 (mov,%C0,__tmp_reg__));
2117       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2118                     AS2 (ldd,%B0,%B1) CR_TAB
2119                     AS2 (ldd,%C0,%C1) CR_TAB
2120                     AS2 (ldd,%D0,%D1));
2121     }
2122   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2123     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2124                   AS2 (ld,%C0,%1) CR_TAB
2125                   AS2 (ld,%B0,%1) CR_TAB
2126                   AS2 (ld,%A0,%1));
2127   else if (GET_CODE (base) == POST_INC) /* (R++) */
2128     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2129                   AS2 (ld,%B0,%1) CR_TAB
2130                   AS2 (ld,%C0,%1) CR_TAB
2131                   AS2 (ld,%D0,%1));
2132   else if (CONSTANT_ADDRESS_P (base))
2133       return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2134                     AS2 (lds,%B0,%B1) CR_TAB
2135                     AS2 (lds,%C0,%C1) CR_TAB
2136                     AS2 (lds,%D0,%D1));
2137     
2138   fatal_insn ("Unknown move insn:",insn);
2139   return "";
2140 }
2141
2142 const char *
2143 out_movsi_mr_r (insn, op, l)
2144      rtx insn;
2145      rtx op[];
2146      int *l;
2147 {
2148   rtx dest = op[0];
2149   rtx src = op[1];
2150   rtx base = XEXP (dest, 0);
2151   int reg_base = true_regnum (base);
2152   int reg_src = true_regnum (src);
2153   int tmp;
2154   
2155   if (!l)
2156     l = &tmp;
2157   
2158   if (CONSTANT_ADDRESS_P (base))
2159     return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2160                  AS2 (sts,%B0,%B1) CR_TAB
2161                  AS2 (sts,%C0,%C1) CR_TAB
2162                  AS2 (sts,%D0,%D1));
2163   if (reg_base > 0)                 /* (r) */
2164     {
2165       if (reg_base == REG_X)                /* (R26) */
2166         {
2167           if (reg_src == REG_X)
2168             {
2169               /* "st X+,r26" is undefined */
2170               if (reg_unused_after (insn, base))
2171                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2172                               AS2 (st,X,r26)            CR_TAB
2173                               AS2 (adiw,r26,1)          CR_TAB
2174                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2175                               AS2 (st,X+,r28)           CR_TAB
2176                               AS2 (st,X,r29));
2177               else
2178                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2179                               AS2 (st,X,r26)            CR_TAB
2180                               AS2 (adiw,r26,1)          CR_TAB
2181                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2182                               AS2 (st,X+,r28)           CR_TAB
2183                               AS2 (st,X,r29)            CR_TAB
2184                               AS2 (sbiw,r26,3));
2185             }
2186           else if (reg_base == reg_src + 2)
2187             {
2188               if (reg_unused_after (insn, base))
2189                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2190                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2191                               AS2 (st,%0+,%A1) CR_TAB
2192                               AS2 (st,%0+,%B1) CR_TAB
2193                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2194                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2195                               AS1 (clr,__zero_reg__));
2196               else
2197                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2198                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2199                               AS2 (st,%0+,%A1) CR_TAB
2200                               AS2 (st,%0+,%B1) CR_TAB
2201                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2202                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2203                               AS1 (clr,__zero_reg__)     CR_TAB
2204                               AS2 (sbiw,r26,3));
2205             }
2206           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2207                         AS2 (st,%0+,%B1) CR_TAB
2208                         AS2 (st,%0+,%C1) CR_TAB
2209                         AS2 (st,%0,%D1)  CR_TAB
2210                         AS2 (sbiw,r26,3));
2211         }
2212       else
2213         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2214                       AS2 (std,%0+1,%B1) CR_TAB
2215                       AS2 (std,%0+2,%C1) CR_TAB
2216                       AS2 (std,%0+3,%D1));
2217     }
2218   else if (GET_CODE (base) == PLUS) /* (R + i) */
2219     {
2220       int disp = INTVAL (XEXP (base, 1));
2221       reg_base = REGNO (XEXP (base, 0));
2222       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2223         {
2224           if (reg_base != REG_Y)
2225             fatal_insn ("Incorrect insn:",insn);
2226
2227           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2228             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2229                             AS2 (std,Y+60,%A1)    CR_TAB
2230                             AS2 (std,Y+61,%B1)    CR_TAB
2231                             AS2 (std,Y+62,%C1)    CR_TAB
2232                             AS2 (std,Y+63,%D1)    CR_TAB
2233                             AS2 (sbiw,r28,%o0-60));
2234
2235           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2236                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2237                           AS2 (st,Y,%A1)           CR_TAB
2238                           AS2 (std,Y+1,%B1)        CR_TAB
2239                           AS2 (std,Y+2,%C1)        CR_TAB
2240                           AS2 (std,Y+3,%D1)        CR_TAB
2241                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2242                           AS2 (sbci,r29,hi8(%o0)));
2243         }
2244       if (reg_base == REG_X)
2245         {
2246           /* (X + d) = R */
2247           if (reg_src == REG_X)
2248             {
2249               *l = 9;
2250               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2251                       AS2 (mov,__zero_reg__,r27) CR_TAB
2252                       AS2 (adiw,r26,%o0)         CR_TAB
2253                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2254                       AS2 (st,X+,__zero_reg__)   CR_TAB
2255                       AS2 (st,X+,r28)            CR_TAB
2256                       AS2 (st,X,r29)             CR_TAB
2257                       AS1 (clr,__zero_reg__)     CR_TAB
2258                       AS2 (sbiw,r26,%o0+3));
2259             }
2260           else if (reg_src == REG_X - 2)
2261             {
2262               *l = 9;
2263               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2264                       AS2 (mov,__zero_reg__,r27) CR_TAB
2265                       AS2 (adiw,r26,%o0)         CR_TAB
2266                       AS2 (st,X+,r24)            CR_TAB
2267                       AS2 (st,X+,r25)            CR_TAB
2268                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2269                       AS2 (st,X,__zero_reg__)    CR_TAB
2270                       AS1 (clr,__zero_reg__)     CR_TAB
2271                       AS2 (sbiw,r26,%o0+3));
2272             }
2273           *l = 6;
2274           return (AS2 (adiw,r26,%o0) CR_TAB
2275                   AS2 (st,X+,%A1)    CR_TAB
2276                   AS2 (st,X+,%B1)    CR_TAB
2277                   AS2 (st,X+,%C1)    CR_TAB
2278                   AS2 (st,X,%D1)     CR_TAB
2279                   AS2 (sbiw,r26,%o0+3));
2280         }
2281       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2282                     AS2 (std,%B0,%B1) CR_TAB
2283                     AS2 (std,%C0,%C1) CR_TAB
2284                     AS2 (std,%D0,%D1));
2285     }
2286   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2287     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2288                   AS2 (st,%0,%C1) CR_TAB
2289                   AS2 (st,%0,%B1) CR_TAB
2290                   AS2 (st,%0,%A1));
2291   else if (GET_CODE (base) == POST_INC) /* (R++) */
2292     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2293                   AS2 (st,%0,%B1) CR_TAB
2294                   AS2 (st,%0,%C1) CR_TAB
2295                   AS2 (st,%0,%D1));
2296   fatal_insn ("Unknown move insn:",insn);
2297   return "";
2298 }
2299
2300 const char *
2301 output_movsisf(insn, operands, l)
2302      rtx insn;
2303      rtx operands[];
2304      int *l;
2305 {
2306   int dummy;
2307   rtx dest = operands[0];
2308   rtx src = operands[1];
2309   int *real_l = l;
2310   
2311   if (!l)
2312     l = &dummy;
2313   
2314   if (register_operand (dest, VOIDmode))
2315     {
2316       if (register_operand (src, VOIDmode)) /* mov r,r */
2317         {
2318           if (true_regnum (dest) > true_regnum (src))
2319             {
2320               if (AVR_ENHANCED)
2321                 {
2322                   *l = 2;
2323                   return (AS2 (movw,%C0,%C1) CR_TAB
2324                           AS2 (movw,%A0,%A1));
2325                 }
2326               *l = 4;
2327               return (AS2 (mov,%D0,%D1) CR_TAB
2328                       AS2 (mov,%C0,%C1) CR_TAB
2329                       AS2 (mov,%B0,%B1) CR_TAB
2330                       AS2 (mov,%A0,%A1));
2331             }
2332           else
2333             {
2334               if (AVR_ENHANCED)
2335                 {
2336                   *l = 2;
2337                   return (AS2 (movw,%A0,%A1) CR_TAB
2338                           AS2 (movw,%C0,%C1));
2339                 }
2340               *l = 4;
2341               return (AS2 (mov,%A0,%A1) CR_TAB
2342                       AS2 (mov,%B0,%B1) CR_TAB
2343                       AS2 (mov,%C0,%C1) CR_TAB
2344                       AS2 (mov,%D0,%D1));
2345             }
2346         }
2347       else if (CONSTANT_P (src))
2348         {
2349           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2350             {
2351               if (byte_immediate_operand (src, SImode)
2352                   && reg_was_0 (insn, dest))
2353                 {
2354                   *l = 1;
2355                   return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
2356                 }
2357
2358               *l = 4;
2359               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2360                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2361                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2362                       AS2 (ldi,%D0,hhi8(%1)));
2363             }
2364           
2365           if (GET_CODE (src) == CONST_INT)
2366             {
2367               const char *clr_op0 =
2368                 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2369                                 AS1 (clr,%B0) CR_TAB
2370                                 AS2 (movw,%C0,%A0))
2371                              : (AS1 (clr,%A0) CR_TAB
2372                                 AS1 (clr,%B0) CR_TAB
2373                                 AS1 (clr,%C0) CR_TAB
2374                                 AS1 (clr,%D0));
2375
2376               if (src == const0_rtx) /* mov r,L */
2377                 {
2378                   *l = AVR_ENHANCED ? 3 : 4;
2379                   return clr_op0;
2380                 }
2381               else if (src == const1_rtx)
2382                 {
2383                   if (reg_was_0 (insn, dest))
2384                     {
2385                       *l = 1;
2386                       return AS1 (inc,%A0 ; reg_was_0);
2387                     }
2388                   if (!real_l)
2389                     output_asm_insn (clr_op0, operands);
2390                   *l = AVR_ENHANCED ? 4 : 5;
2391                   return AS1 (inc,%A0);
2392                 }
2393               else if (src == constm1_rtx)
2394                 {
2395                   /* Immediate constants -1 to any register */
2396                   if (reg_was_0 (insn, dest))
2397                     {
2398                       if (AVR_ENHANCED)
2399                         {
2400                           *l = 3;
2401                           return (AS1 (dec,%A0) CR_TAB
2402                                   AS1 (dec,%B0) CR_TAB
2403                                   AS2 (movw,%C0,%A0));
2404                         }
2405                       *l = 4;
2406                       return (AS1 (dec,%D0 ; reg_was_0) CR_TAB
2407                               AS1 (dec,%C0)             CR_TAB
2408                               AS1 (dec,%B0)             CR_TAB
2409                               AS1 (dec,%A0));
2410                     }
2411                   if (AVR_ENHANCED)
2412                     {
2413                       *l = 4;
2414                       return (AS1 (clr,%A0)     CR_TAB
2415                               AS1 (dec,%A0)     CR_TAB
2416                               AS2 (mov,%B0,%A0) CR_TAB
2417                               AS2 (movw,%C0,%A0));
2418                     }
2419                   *l = 5;
2420                   return (AS1 (clr,%A0)     CR_TAB
2421                           AS1 (dec,%A0)     CR_TAB
2422                           AS2 (mov,%B0,%A0) CR_TAB
2423                           AS2 (mov,%C0,%A0) CR_TAB
2424                           AS2 (mov,%D0,%A0));
2425                 }
2426               else
2427                 {
2428                   int bit_nr = exact_log2 (INTVAL (src));
2429
2430                   if (bit_nr >= 0)
2431                     {
2432                       if (reg_was_0 (insn, dest))
2433                         {
2434                           *l = 2;
2435                           if (!real_l)
2436                             output_asm_insn ("set ; reg_was_0", operands);
2437                         }
2438                       else
2439                         {
2440                           *l = AVR_ENHANCED ? 5 : 6;
2441                           if (!real_l)
2442                             {
2443                               output_asm_insn (clr_op0, operands);
2444                               output_asm_insn ("set", operands);
2445                             }
2446                         }
2447                       if (!real_l)
2448                         avr_output_bld (operands, bit_nr);
2449
2450                       return "";
2451                     }
2452                 }
2453             }
2454           
2455           /* Last resort, better than loading from memory.  */
2456           *l = 10;
2457           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2458                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2459                   AS2 (mov,%A0,r31)         CR_TAB
2460                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2461                   AS2 (mov,%B0,r31)         CR_TAB
2462                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2463                   AS2 (mov,%C0,r31)         CR_TAB
2464                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2465                   AS2 (mov,%D0,r31)         CR_TAB
2466                   AS2 (mov,r31,__tmp_reg__));
2467         }
2468       else if (GET_CODE (src) == MEM)
2469         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2470     }
2471   else if (GET_CODE (dest) == MEM)
2472     {
2473       const char *template;
2474
2475       if (src == const0_rtx)
2476           operands[1] = zero_reg_rtx;
2477
2478       template = out_movsi_mr_r (insn, operands, real_l);
2479
2480       if (!real_l)
2481         output_asm_insn (template, operands);
2482
2483       operands[1] = src;
2484       return "";
2485     }
2486   fatal_insn ("Invalid insn:", insn);
2487   return "";
2488 }
2489
2490 const char *
2491 out_movqi_mr_r (insn, op, l)
2492      rtx insn;
2493      rtx op[];
2494      int *l; /* instruction length */
2495 {
2496   rtx dest = op[0];
2497   rtx src = op[1];
2498   rtx x = XEXP (dest, 0);
2499   int dummy;
2500
2501   if (!l)
2502     l = &dummy;
2503   
2504   if (CONSTANT_ADDRESS_P (x))
2505     {
2506       if (io_address_p (x, 1))
2507         {
2508           *l = 1;
2509           return AS2 (out,%0-0x20,%1);
2510         }
2511       *l = 2;
2512       return AS2 (sts,%0,%1);
2513     }
2514   /* memory access by reg+disp */
2515   else if (GET_CODE (x) == PLUS 
2516       && REG_P (XEXP (x,0))
2517       && GET_CODE (XEXP (x,1)) == CONST_INT)
2518     {
2519       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2520         {
2521           int disp = INTVAL (XEXP (x,1));
2522           if (REGNO (XEXP (x,0)) != REG_Y)
2523             fatal_insn ("Incorrect insn:",insn);
2524
2525           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2526             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2527                             AS2 (std,Y+63,%1)     CR_TAB
2528                             AS2 (sbiw,r28,%o0-63));
2529
2530           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2531                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2532                           AS2 (st,Y,%1)            CR_TAB
2533                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2534                           AS2 (sbci,r29,hi8(%o0)));
2535         }
2536       else if (REGNO (XEXP (x,0)) == REG_X)
2537         {
2538           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2539             {
2540               if (reg_unused_after (insn, XEXP (x,0)))
2541                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2542                                 AS2 (adiw,r26,%o0)       CR_TAB
2543                                 AS2 (st,X,__tmp_reg__));
2544
2545               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2546                               AS2 (adiw,r26,%o0)       CR_TAB
2547                               AS2 (st,X,__tmp_reg__)   CR_TAB
2548                               AS2 (sbiw,r26,%o0));
2549             }
2550           else
2551             {
2552               if (reg_unused_after (insn, XEXP (x,0)))
2553                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2554                                 AS2 (st,X,%1));
2555
2556               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2557                               AS2 (st,X,%1)      CR_TAB
2558                               AS2 (sbiw,r26,%o0));
2559             }
2560         }
2561       *l = 1;
2562       return AS2 (std,%0,%1);
2563     }
2564   *l = 1;
2565   return AS2 (st,%0,%1);
2566 }
2567
2568 const char *
2569 out_movhi_mr_r (insn, op, l)
2570      rtx insn;
2571      rtx op[];
2572      int *l;
2573 {
2574   rtx dest = op[0];
2575   rtx src = op[1];
2576   rtx base = XEXP (dest, 0);
2577   int reg_base = true_regnum (base);
2578   int reg_src = true_regnum (src);
2579   int tmp;
2580   if (!l)
2581     l = &tmp;
2582   if (CONSTANT_ADDRESS_P (base))
2583     {
2584       if (io_address_p (base, 2))
2585         {
2586           *l = 2;
2587           return (AS2 (out,%B0-0x20,%B1) CR_TAB
2588                   AS2 (out,%A0-0x20,%A1));
2589         }
2590       return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2591                       AS2 (sts,%A0,%A1));
2592     }
2593   if (reg_base > 0)
2594     {
2595       if (reg_base == REG_X)
2596         {
2597           if (reg_src == REG_X)
2598             {
2599               /* "st X+,r26" is undefined */
2600               if (reg_unused_after (insn, src))
2601                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2602                               AS2 (st,X,r26)            CR_TAB
2603                               AS2 (adiw,r26,1)          CR_TAB
2604                               AS2 (st,X,__tmp_reg__));
2605               else
2606                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2607                               AS2 (st,X,r26)            CR_TAB
2608                               AS2 (adiw,r26,1)          CR_TAB
2609                               AS2 (st,X,__tmp_reg__)    CR_TAB
2610                               AS2 (sbiw,r26,1));
2611             }
2612           else
2613             {
2614               if (reg_unused_after (insn, base))
2615                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2616                               AS2 (st,X,%B1));
2617               else
2618                 return *l=3, (AS2 (st  ,X+,%A1) CR_TAB
2619                               AS2 (st  ,X,%B1) CR_TAB
2620                               AS2 (sbiw,r26,1));
2621             }
2622         }
2623       else
2624         return  *l=2, (AS2 (st ,%0,%A1)    CR_TAB
2625                        AS2 (std,%0+1,%B1));
2626     }
2627   else if (GET_CODE (base) == PLUS)
2628     {
2629       int disp = INTVAL (XEXP (base, 1));
2630       reg_base = REGNO (XEXP (base, 0));
2631       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2632         {
2633           if (reg_base != REG_Y)
2634             fatal_insn ("Incorrect insn:",insn);
2635
2636           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2637             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2638                             AS2 (std,Y+62,%A1)    CR_TAB
2639                             AS2 (std,Y+63,%B1)    CR_TAB
2640                             AS2 (sbiw,r28,%o0-62));
2641
2642           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2643                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2644                           AS2 (st,Y,%A1)           CR_TAB
2645                           AS2 (std,Y+1,%B1)        CR_TAB
2646                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2647                           AS2 (sbci,r29,hi8(%o0)));
2648         }
2649       if (reg_base == REG_X)
2650         {
2651           /* (X + d) = R */
2652           if (reg_src == REG_X)
2653             {
2654               *l = 7;
2655               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2656                       AS2 (mov,__zero_reg__,r27) CR_TAB
2657                       AS2 (adiw,r26,%o0)         CR_TAB
2658                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2659                       AS2 (st,X,__zero_reg__)    CR_TAB
2660                       AS1 (clr,__zero_reg__)     CR_TAB
2661                       AS2 (sbiw,r26,%o0+1));
2662             }
2663           *l = 4;
2664           return (AS2 (adiw,r26,%o0) CR_TAB
2665                   AS2 (st,X+,%A1)    CR_TAB
2666                   AS2 (st,X,%B1)     CR_TAB
2667                   AS2 (sbiw,r26,%o0+1));
2668         }
2669       return *l=2, (AS2 (std,%A0,%A1)    CR_TAB
2670                     AS2 (std,%B0,%B1));
2671     }
2672   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2673     return *l=2, (AS2 (st,%0,%B1) CR_TAB
2674                   AS2 (st,%0,%A1));
2675   else if (GET_CODE (base) == POST_INC) /* (R++) */
2676     return *l=2, (AS2 (st,%0,%A1)  CR_TAB
2677                   AS2 (st,%0,%B1));
2678   fatal_insn ("Unknown move insn:",insn);
2679   return "";
2680 }
2681
2682 /* Return 1 if frame pointer for current function required */
2683
2684 int
2685 frame_pointer_required_p ()
2686 {
2687   return (current_function_calls_alloca
2688           || current_function_args_info.nregs == 0
2689           || current_function_varargs
2690           || get_frame_size () > 0);
2691 }
2692
2693 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
2694
2695 static RTX_CODE
2696 compare_condition (insn)
2697      rtx insn;
2698 {
2699   rtx next = next_real_insn (insn);
2700   RTX_CODE cond = UNKNOWN;
2701   if (next && GET_CODE (next) == JUMP_INSN)
2702     {
2703       rtx pat = PATTERN (next);
2704       rtx src = SET_SRC (pat);
2705       rtx t = XEXP (src, 0);
2706       cond = GET_CODE (t);
2707     }
2708   return cond;
2709 }
2710
2711 /* Returns nonzero if INSN is a tst insn that only tests the sign.  */
2712
2713 static int
2714 compare_sign_p (insn)
2715      rtx insn;
2716 {
2717   RTX_CODE cond = compare_condition (insn);
2718   return (cond == GE || cond == LT);
2719 }
2720
2721 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2722    that needs to be swapped (GT, GTU, LE, LEU).  */
2723
2724 int
2725 compare_diff_p (insn)
2726      rtx insn;
2727 {
2728   RTX_CODE cond = compare_condition (insn);
2729   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2730 }
2731
2732 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition.  */
2733
2734 int
2735 compare_eq_p (insn)
2736      rtx insn;
2737 {
2738   RTX_CODE cond = compare_condition (insn);
2739   return (cond == EQ || cond == NE);
2740 }
2741
2742
2743 /* Output test instruction for HImode */
2744
2745 const char *
2746 out_tsthi (insn, l)
2747      rtx insn;
2748      int *l;
2749 {
2750   if (compare_sign_p (insn))
2751     {
2752       if (l) *l = 1;
2753       return AS1 (tst,%B0);
2754     }
2755   if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2756       && compare_eq_p (insn))
2757     {
2758       /* faster than sbiw if we can clobber the operand */
2759       if (l) *l = 1;
2760       return AS2 (or,%A0,%B0);
2761     }
2762   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2763     {
2764       if (l) *l = 1;
2765       return AS2 (sbiw,%0,0);
2766     }
2767   if (l) *l = 2;
2768   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2769           AS2 (cpc,%B0,__zero_reg__));
2770 }
2771
2772
2773 /* Output test instruction for SImode */
2774
2775 const char *
2776 out_tstsi (insn, l)
2777      rtx insn;
2778      int *l;
2779 {
2780   if (compare_sign_p (insn))
2781     {
2782       if (l) *l = 1;
2783       return AS1 (tst,%D0);
2784     }
2785   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2786     {
2787       if (l) *l = 3;
2788       return (AS2 (sbiw,%A0,0) CR_TAB
2789               AS2 (cpc,%C0,__zero_reg__) CR_TAB
2790               AS2 (cpc,%D0,__zero_reg__));
2791     }
2792   if (l) *l = 4;
2793   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2794           AS2 (cpc,%B0,__zero_reg__) CR_TAB
2795           AS2 (cpc,%C0,__zero_reg__) CR_TAB
2796           AS2 (cpc,%D0,__zero_reg__));
2797 }
2798
2799
2800 /* Generate asm equivalent for various shifts.
2801    Shift count is a CONST_INT, MEM or REG.
2802    This only handles cases that are not already
2803    carefully hand-optimized in ?sh??i3_out.  */
2804
2805 void
2806 out_shift_with_cnt (template, insn, operands, len, t_len)
2807      const char *template;
2808      rtx insn;
2809      rtx operands[];
2810      int *len;
2811      int t_len;  /* Length of template.  */
2812 {
2813   rtx op[10];
2814   char str[500];
2815   int second_label = 1;
2816   int saved_in_tmp = 0;
2817   int use_zero_reg = 0;
2818
2819   op[0] = operands[0];
2820   op[1] = operands[1];
2821   op[2] = operands[2];
2822   op[3] = operands[3];
2823   str[0] = 0;
2824
2825   if (len)
2826     *len = 1;
2827
2828   if (GET_CODE (operands[2]) == CONST_INT)
2829     {
2830       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2831       int count = INTVAL (operands[2]);
2832       int max_len = 10;  /* If larger than this, always use a loop.  */
2833
2834       if (count < 8 && !scratch)
2835         use_zero_reg = 1;
2836
2837       if (optimize_size)
2838         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2839
2840       if (t_len * count <= max_len)
2841         {
2842           /* Output shifts inline with no loop - faster.  */
2843           if (len)
2844             *len = t_len * count;
2845           else
2846             {
2847               while (count-- > 0)
2848                 output_asm_insn (template, op);
2849             }
2850
2851           return;
2852         }
2853
2854       if (scratch)
2855         {
2856           if (!len)
2857             strcat (str, AS2 (ldi,%3,%2));
2858         }
2859       else if (use_zero_reg)
2860         {
2861           /* Hack to save one word: use __zero_reg__ as loop counter.
2862              Set one bit, then shift in a loop until it is 0 again.  */
2863
2864           op[3] = zero_reg_rtx;
2865           if (len)
2866             *len = 2;
2867           else
2868             strcat (str, ("set" CR_TAB
2869                           AS2 (bld,%3,%2-1)));
2870         }
2871       else
2872         {
2873           /* No scratch register available, use one from LD_REGS (saved in
2874              __tmp_reg__) that doesn't overlap with registers to shift.  */
2875
2876           op[3] = gen_rtx (REG, QImode,
2877                            ((true_regnum (operands[0]) - 1) & 15) + 16);
2878           op[4] = tmp_reg_rtx;
2879           saved_in_tmp = 1;
2880
2881           if (len)
2882             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
2883           else
2884             strcat (str, (AS2 (mov,%4,%3) CR_TAB
2885                           AS2 (ldi,%3,%2)));
2886         }
2887
2888       second_label = 0;
2889     }
2890   else if (GET_CODE (operands[2]) == MEM)
2891     {
2892       rtx op_mov[10];
2893       
2894       op[3] = op_mov[0] = tmp_reg_rtx;
2895       op_mov[1] = op[2];
2896
2897       if (len)
2898         out_movqi_r_mr (insn, op_mov, len);
2899       else
2900         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2901     }
2902   else if (register_operand (operands[2], QImode))
2903     {
2904       if (reg_unused_after (insn, operands[2]))
2905         op[3] = op[2];
2906       else
2907         {
2908           op[3] = tmp_reg_rtx;
2909           if (!len)
2910             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2911         }
2912     }
2913   else
2914     fatal_insn ("Bad shift insn:", insn);
2915
2916   if (second_label)
2917     {
2918       if (len)
2919         ++*len;
2920       else
2921         strcat (str, AS1 (rjmp,2f));
2922     }
2923
2924   if (len)
2925     *len += t_len + 2;  /* template + dec + brXX */
2926   else
2927     {
2928       strcat (str, "\n1:\t");
2929       strcat (str, template);
2930       strcat (str, second_label ? "\n2:\t" : "\n\t");
2931       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2932       strcat (str, CR_TAB);
2933       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2934       if (saved_in_tmp)
2935         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2936       output_asm_insn (str, op);
2937     }
2938 }
2939
2940
2941 /* 8bit shift left ((char)x << i)   */
2942
2943 const char *
2944 ashlqi3_out (insn, operands, len)
2945      rtx insn;
2946      rtx operands[];
2947      int *len;                  /* insn length (may be NULL) */
2948 {
2949   if (GET_CODE (operands[2]) == CONST_INT)
2950     {
2951       int k;
2952
2953       if (!len)
2954         len = &k;
2955
2956       switch (INTVAL (operands[2]))
2957         {
2958         default:
2959           *len = 1;
2960           return AS1 (clr,%0);
2961           
2962         case 1:
2963           *len = 1;
2964           return AS1 (lsl,%0);
2965           
2966         case 2:
2967           *len = 2;
2968           return (AS1 (lsl,%0) CR_TAB
2969                   AS1 (lsl,%0));
2970
2971         case 3:
2972           *len = 3;
2973           return (AS1 (lsl,%0) CR_TAB
2974                   AS1 (lsl,%0) CR_TAB
2975                   AS1 (lsl,%0));
2976
2977         case 4:
2978           if (test_hard_reg_class (LD_REGS, operands[0]))
2979             {
2980               *len = 2;
2981               return (AS1 (swap,%0) CR_TAB
2982                       AS2 (andi,%0,0xf0));
2983             }
2984           *len = 4;
2985           return (AS1 (lsl,%0) CR_TAB
2986                   AS1 (lsl,%0) CR_TAB
2987                   AS1 (lsl,%0) CR_TAB
2988                   AS1 (lsl,%0));
2989
2990         case 5:
2991           if (test_hard_reg_class (LD_REGS, operands[0]))
2992             {
2993               *len = 3;
2994               return (AS1 (swap,%0) CR_TAB
2995                       AS1 (lsl,%0)  CR_TAB
2996                       AS2 (andi,%0,0xe0));
2997             }
2998           *len = 5;
2999           return (AS1 (lsl,%0) CR_TAB
3000                   AS1 (lsl,%0) CR_TAB
3001                   AS1 (lsl,%0) CR_TAB
3002                   AS1 (lsl,%0) CR_TAB
3003                   AS1 (lsl,%0));
3004
3005         case 6:
3006           if (test_hard_reg_class (LD_REGS, operands[0]))
3007             {
3008               *len = 4;
3009               return (AS1 (swap,%0) CR_TAB
3010                       AS1 (lsl,%0)  CR_TAB
3011                       AS1 (lsl,%0)  CR_TAB
3012                       AS2 (andi,%0,0xc0));
3013             }
3014           *len = 6;
3015           return (AS1 (lsl,%0) CR_TAB
3016                   AS1 (lsl,%0) CR_TAB
3017                   AS1 (lsl,%0) CR_TAB
3018                   AS1 (lsl,%0) CR_TAB
3019                   AS1 (lsl,%0) CR_TAB
3020                   AS1 (lsl,%0));
3021
3022         case 7:
3023           *len = 3;
3024           return (AS1 (ror,%0) CR_TAB
3025                   AS1 (clr,%0) CR_TAB
3026                   AS1 (ror,%0));
3027         }
3028     }
3029   else if (CONSTANT_P (operands[2]))
3030     fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3031
3032   out_shift_with_cnt (AS1 (lsl,%0),
3033                       insn, operands, len, 1);
3034   return "";
3035 }
3036
3037
3038 /* 16bit shift left ((short)x << i)   */
3039
3040 const char *
3041 ashlhi3_out (insn, operands, len)
3042      rtx insn;
3043      rtx operands[];
3044      int *len;
3045 {
3046   if (GET_CODE (operands[2]) == CONST_INT)
3047     {
3048       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3049       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3050       int k;
3051       int *t = len;
3052
3053       if (!len)
3054         len = &k;
3055       
3056       switch (INTVAL (operands[2]))
3057         {
3058         case 4:
3059           if (optimize_size && scratch)
3060             break;  /* 5 */
3061           if (ldi_ok)
3062             {
3063               *len = 6;
3064               return (AS1 (swap,%A0)      CR_TAB
3065                       AS1 (swap,%B0)      CR_TAB
3066                       AS2 (andi,%B0,0xf0) CR_TAB
3067                       AS2 (eor,%B0,%A0)   CR_TAB
3068                       AS2 (andi,%A0,0xf0) CR_TAB
3069                       AS2 (eor,%B0,%A0));
3070             }
3071           if (scratch)
3072             {
3073               *len = 7;
3074               return (AS1 (swap,%A0)    CR_TAB
3075                       AS1 (swap,%B0)    CR_TAB
3076                       AS2 (ldi,%3,0xf0) CR_TAB
3077                       AS2 (and,%B0,%3)  CR_TAB
3078                       AS2 (eor,%B0,%A0) CR_TAB
3079                       AS2 (and,%A0,%3)  CR_TAB
3080                       AS2 (eor,%B0,%A0));
3081             }
3082           break;  /* optimize_size ? 6 : 8 */
3083
3084         case 5:
3085           if (optimize_size)
3086             break;  /* scratch ? 5 : 6 */
3087           if (ldi_ok)
3088             {
3089               *len = 8;
3090               return (AS1 (lsl,%A0)       CR_TAB
3091                       AS1 (rol,%B0)       CR_TAB
3092                       AS1 (swap,%A0)      CR_TAB
3093                       AS1 (swap,%B0)      CR_TAB
3094                       AS2 (andi,%B0,0xf0) CR_TAB
3095                       AS2 (eor,%B0,%A0)   CR_TAB
3096                       AS2 (andi,%A0,0xf0) CR_TAB
3097                       AS2 (eor,%B0,%A0));
3098             }
3099           if (scratch)
3100             {
3101               *len = 9;
3102               return (AS1 (lsl,%A0)     CR_TAB
3103                       AS1 (rol,%B0)     CR_TAB
3104                       AS1 (swap,%A0)    CR_TAB
3105                       AS1 (swap,%B0)    CR_TAB
3106                       AS2 (ldi,%3,0xf0) CR_TAB
3107                       AS2 (and,%B0,%3)  CR_TAB
3108                       AS2 (eor,%B0,%A0) CR_TAB
3109                       AS2 (and,%A0,%3)  CR_TAB
3110                       AS2 (eor,%B0,%A0));
3111             }
3112           break;  /* 10 */
3113
3114         case 6:
3115           if (optimize_size)
3116             break;  /* scratch ? 5 : 6 */
3117           *len = 9;
3118           return (AS1 (clr,__tmp_reg__) CR_TAB
3119                   AS1 (lsr,%B0)         CR_TAB
3120                   AS1 (ror,%A0)         CR_TAB
3121                   AS1 (ror,__tmp_reg__) CR_TAB
3122                   AS1 (lsr,%B0)         CR_TAB
3123                   AS1 (ror,%A0)         CR_TAB
3124                   AS1 (ror,__tmp_reg__) CR_TAB
3125                   AS2 (mov,%B0,%A0)     CR_TAB
3126                   AS2 (mov,%A0,__tmp_reg__));
3127
3128         case 7:
3129           *len = 5;
3130           return (AS1 (lsr,%B0)     CR_TAB
3131                   AS2 (mov,%B0,%A0) CR_TAB
3132                   AS1 (clr,%A0)     CR_TAB
3133                   AS1 (ror,%B0)     CR_TAB
3134                   AS1 (ror,%A0));
3135
3136         case 8:
3137           if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3138             return *len = 1, AS1 (clr,%A0);
3139           else
3140             return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3141                               AS1 (clr,%A0));
3142
3143         case 9:
3144           *len = 3;
3145           return (AS2 (mov,%B0,%A0) CR_TAB
3146                   AS1 (clr,%A0)     CR_TAB
3147                   AS1 (lsl,%B0));
3148
3149         case 10:
3150           *len = 4;
3151           return (AS2 (mov,%B0,%A0) CR_TAB
3152                   AS1 (clr,%A0)     CR_TAB
3153                   AS1 (lsl,%B0)     CR_TAB
3154                   AS1 (lsl,%B0));
3155
3156         case 11:
3157           *len = 5;
3158           return (AS2 (mov,%B0,%A0) CR_TAB
3159                   AS1 (clr,%A0)     CR_TAB
3160                   AS1 (lsl,%B0)     CR_TAB
3161                   AS1 (lsl,%B0)     CR_TAB
3162                   AS1 (lsl,%B0));
3163
3164         case 12:
3165           if (ldi_ok)
3166             {
3167               *len = 4;
3168               return (AS2 (mov,%B0,%A0) CR_TAB
3169                       AS1 (clr,%A0)     CR_TAB
3170                       AS1 (swap,%B0)    CR_TAB
3171                       AS2 (andi,%B0,0xf0));
3172             }
3173           if (scratch)
3174             {
3175               *len = 5;
3176               return (AS2 (mov,%B0,%A0) CR_TAB
3177                       AS1 (clr,%A0)     CR_TAB
3178                       AS1 (swap,%B0)    CR_TAB
3179                       AS2 (ldi,%3,0xf0) CR_TAB
3180                       AS2 (and,%B0,%3));
3181             }
3182           *len = 6;
3183           return (AS2 (mov,%B0,%A0) CR_TAB
3184                   AS1 (clr,%A0)     CR_TAB
3185                   AS1 (lsl,%B0)     CR_TAB
3186                   AS1 (lsl,%B0)     CR_TAB
3187                   AS1 (lsl,%B0)     CR_TAB
3188                   AS1 (lsl,%B0));
3189
3190         case 13:
3191           if (ldi_ok)
3192             {
3193               *len = 5;
3194               return (AS2 (mov,%B0,%A0) CR_TAB
3195                       AS1 (clr,%A0)     CR_TAB
3196                       AS1 (swap,%B0)    CR_TAB
3197                       AS1 (lsl,%B0)     CR_TAB
3198                       AS2 (andi,%B0,0xe0));
3199             }
3200           if (AVR_ENHANCED && scratch)
3201             {
3202               *len = 5;
3203               return (AS2 (ldi,%3,0x20) CR_TAB
3204                       AS2 (mul,%A0,%3)  CR_TAB
3205                       AS2 (mov,%B0,r0)  CR_TAB
3206                       AS1 (clr,%A0)     CR_TAB
3207                       AS1 (clr,__zero_reg__));
3208             }
3209           if (optimize_size && scratch)
3210             break;  /* 5 */
3211           if (scratch)
3212             {
3213               *len = 6;
3214               return (AS2 (mov,%B0,%A0) CR_TAB
3215                       AS1 (clr,%A0)     CR_TAB
3216                       AS1 (swap,%B0)    CR_TAB
3217                       AS1 (lsl,%B0)     CR_TAB
3218                       AS2 (ldi,%3,0xe0) CR_TAB
3219                       AS2 (and,%B0,%3));
3220             }
3221           if (AVR_ENHANCED)
3222             {
3223               *len = 6;
3224               return ("set"            CR_TAB
3225                       AS2 (bld,r1,5)   CR_TAB
3226                       AS2 (mul,%A0,r1) CR_TAB
3227                       AS2 (mov,%B0,r0) CR_TAB
3228                       AS1 (clr,%A0)    CR_TAB
3229                       AS1 (clr,__zero_reg__));
3230             }
3231           *len = 7;
3232           return (AS2 (mov,%B0,%A0) CR_TAB
3233                   AS1 (clr,%A0)     CR_TAB
3234                   AS1 (lsl,%B0)     CR_TAB
3235                   AS1 (lsl,%B0)     CR_TAB
3236                   AS1 (lsl,%B0)     CR_TAB
3237                   AS1 (lsl,%B0)     CR_TAB
3238                   AS1 (lsl,%B0));
3239
3240         case 14:
3241           if (AVR_ENHANCED && ldi_ok)
3242             {
3243               *len = 5;
3244               return (AS2 (ldi,%B0,0x40) CR_TAB
3245                       AS2 (mul,%A0,%B0)  CR_TAB
3246                       AS2 (mov,%B0,r0)   CR_TAB
3247                       AS1 (clr,%A0)      CR_TAB
3248                       AS1 (clr,__zero_reg__));
3249             }
3250           if (AVR_ENHANCED && scratch)
3251             {
3252               *len = 5;
3253               return (AS2 (ldi,%3,0x40) CR_TAB
3254                       AS2 (mul,%A0,%3)  CR_TAB
3255                       AS2 (mov,%B0,r0)  CR_TAB
3256                       AS1 (clr,%A0)     CR_TAB
3257                       AS1 (clr,__zero_reg__));
3258             }
3259           if (optimize_size && ldi_ok)
3260             {
3261               *len = 5;
3262               return (AS2 (mov,%B0,%A0) CR_TAB
3263                       AS2 (ldi,%A0,6) "\n1:\t"
3264                       AS1 (lsl,%B0)     CR_TAB
3265                       AS1 (dec,%A0)     CR_TAB
3266                       AS1 (brne,1b));
3267             }
3268           if (optimize_size && scratch)
3269             break;  /* 5 */
3270           *len = 6;
3271           return (AS1 (clr,%B0) CR_TAB
3272                   AS1 (lsr,%A0) CR_TAB
3273                   AS1 (ror,%B0) CR_TAB
3274                   AS1 (lsr,%A0) CR_TAB
3275                   AS1 (ror,%B0) CR_TAB
3276                   AS1 (clr,%A0));
3277
3278         case 15:
3279           *len = 4;
3280           return (AS1 (clr,%B0) CR_TAB
3281                   AS1 (lsr,%A0) CR_TAB
3282                   AS1 (ror,%B0) CR_TAB
3283                   AS1 (clr,%A0));
3284         }
3285       len = t;
3286     }
3287   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3288                        AS1 (rol,%B0)),
3289                        insn, operands, len, 2);
3290   return "";
3291 }
3292
3293
3294 /* 32bit shift left ((long)x << i)   */
3295
3296 const char *
3297 ashlsi3_out (insn, operands, len)
3298      rtx insn;
3299      rtx operands[];
3300      int *len;
3301 {
3302   if (GET_CODE (operands[2]) == CONST_INT)
3303     {
3304       int k;
3305       int *t = len;
3306       
3307       if (!len)
3308         len = &k;
3309       
3310       switch (INTVAL (operands[2]))
3311         {
3312         case 8:
3313           {
3314             int reg0 = true_regnum (operands[0]);
3315             int reg1 = true_regnum (operands[1]);
3316             *len = 4;
3317             if (reg0 >= reg1)
3318               return (AS2 (mov,%D0,%C1)  CR_TAB
3319                       AS2 (mov,%C0,%B1)  CR_TAB
3320                       AS2 (mov,%B0,%A1)  CR_TAB
3321                       AS1 (clr,%A0));
3322             else if (reg0 + 1 == reg1)
3323               {
3324                 *len = 1;
3325                 return AS1 (clr,%A0);
3326               }
3327             else
3328               return (AS1 (clr,%A0)      CR_TAB
3329                       AS2 (mov,%B0,%A1)  CR_TAB
3330                       AS2 (mov,%C0,%B1)  CR_TAB
3331                       AS2 (mov,%D0,%C1));
3332           }
3333
3334         case 16:
3335           {
3336             int reg0 = true_regnum (operands[0]);
3337             int reg1 = true_regnum (operands[1]);
3338             *len = 4;
3339             if (AVR_ENHANCED && (reg0 + 2 != reg1))
3340               {
3341                 *len = 3;
3342                 return (AS2 (movw,%C0,%A1) CR_TAB
3343                         AS1 (clr,%B0)      CR_TAB
3344                         AS1 (clr,%A0));
3345               }
3346             if (reg0 + 1 >= reg1)
3347               return (AS2 (mov,%D0,%B1)  CR_TAB
3348                       AS2 (mov,%C0,%A1)  CR_TAB
3349                       AS1 (clr,%B0)      CR_TAB
3350                       AS1 (clr,%A0));
3351             if (reg0 + 2 == reg1)
3352               {
3353                 *len = 2;
3354                 return (AS1 (clr,%B0)      CR_TAB
3355                         AS1 (clr,%A0));
3356               }
3357             else
3358               return (AS2 (mov,%C0,%A1)  CR_TAB
3359                       AS2 (mov,%D0,%B1)  CR_TAB
3360                       AS1 (clr,%B0)      CR_TAB
3361                       AS1 (clr,%A0));
3362           }
3363
3364         case 24:
3365           *len = 4;
3366           if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3367             return (AS2 (mov,%D0,%A1)  CR_TAB
3368                     AS1 (clr,%C0)      CR_TAB
3369                     AS1 (clr,%B0)      CR_TAB
3370                     AS1 (clr,%A0));
3371           else
3372             {
3373               *len = 3;
3374               return (AS1 (clr,%C0)      CR_TAB
3375                       AS1 (clr,%B0)      CR_TAB
3376                       AS1 (clr,%A0));
3377             }
3378
3379         case 31:
3380           *len = 6;
3381           return (AS1 (clr,%D0) CR_TAB
3382                   AS1 (lsr,%A0) CR_TAB
3383                   AS1 (ror,%D0) CR_TAB
3384                   AS1 (clr,%C0) CR_TAB
3385                   AS1 (clr,%B0) CR_TAB
3386                   AS1 (clr,%A0));
3387         }
3388       len = t;
3389     }
3390   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3391                        AS1 (rol,%B0) CR_TAB
3392                        AS1 (rol,%C0) CR_TAB
3393                        AS1 (rol,%D0)),
3394                        insn, operands, len, 4);
3395   return "";
3396 }
3397
3398 /* 8bit arithmetic shift right  ((signed char)x >> i) */
3399
3400 const char *
3401 ashrqi3_out (insn, operands, len)
3402      rtx insn;
3403      rtx operands[];
3404      int *len; /* insn length */
3405 {
3406   if (GET_CODE (operands[2]) == CONST_INT)
3407     {
3408       int k;
3409
3410       if (!len)
3411         len = &k;
3412
3413       switch (INTVAL (operands[2]))
3414         {
3415         case 1:
3416           *len = 1;
3417           return AS1 (asr,%0);
3418
3419         case 2:
3420           *len = 2;
3421           return (AS1 (asr,%0) CR_TAB
3422                   AS1 (asr,%0));
3423
3424         case 3:
3425           *len = 3;
3426           return (AS1 (asr,%0) CR_TAB
3427                   AS1 (asr,%0) CR_TAB
3428                   AS1 (asr,%0));
3429
3430         case 4:
3431           *len = 4;
3432           return (AS1 (asr,%0) CR_TAB
3433                   AS1 (asr,%0) CR_TAB
3434                   AS1 (asr,%0) CR_TAB
3435                   AS1 (asr,%0));
3436
3437         case 5:
3438           *len = 5;
3439           return (AS1 (asr,%0) CR_TAB
3440                   AS1 (asr,%0) CR_TAB
3441                   AS1 (asr,%0) CR_TAB
3442                   AS1 (asr,%0) CR_TAB
3443                   AS1 (asr,%0));
3444
3445         case 6:
3446           *len = 4;
3447           return (AS2 (bst,%0,6)  CR_TAB
3448                   AS1 (lsl,%0)    CR_TAB
3449                   AS2 (sbc,%0,%0) CR_TAB
3450                   AS2 (bld,%0,0));
3451
3452         default:
3453         case 7:
3454           *len = 2;
3455           return (AS1 (lsl,%0) CR_TAB
3456                   AS2 (sbc,%0,%0));
3457         }
3458     }
3459   else if (CONSTANT_P (operands[2]))
3460     fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3461
3462   out_shift_with_cnt (AS1 (asr,%0),
3463                       insn, operands, len, 1);
3464   return "";
3465 }
3466
3467
3468 /* 16bit arithmetic shift right  ((signed short)x >> i) */
3469
3470 const char *
3471 ashrhi3_out (insn, operands, len)
3472      rtx insn;
3473      rtx operands[];
3474      int *len;
3475 {
3476   if (GET_CODE (operands[2]) == CONST_INT)
3477     {
3478       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3479       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3480       int k;
3481       int *t = len;
3482       
3483       if (!len)
3484         len = &k;
3485
3486       switch (INTVAL (operands[2]))
3487         {
3488         case 4:
3489         case 5:
3490           /* XXX try to optimize this too? */
3491           break;
3492
3493         case 6:
3494           if (optimize_size)
3495             break;  /* scratch ? 5 : 6 */
3496           *len = 8;
3497           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3498                   AS2 (mov,%A0,%B0)         CR_TAB
3499                   AS1 (lsl,__tmp_reg__)     CR_TAB
3500                   AS1 (rol,%A0)             CR_TAB
3501                   AS2 (sbc,%B0,%B0)         CR_TAB
3502                   AS1 (lsl,__tmp_reg__)     CR_TAB
3503                   AS1 (rol,%A0)             CR_TAB
3504                   AS1 (rol,%B0));
3505
3506         case 7:
3507           *len = 4;
3508           return (AS1 (lsl,%A0)     CR_TAB
3509                   AS2 (mov,%A0,%B0) CR_TAB
3510                   AS1 (rol,%A0)     CR_TAB
3511                   AS2 (sbc,%B0,%B0));
3512
3513         case 8:
3514           {
3515             int reg0 = true_regnum (operands[0]);
3516             int reg1 = true_regnum (operands[1]);
3517
3518             if (reg0 == reg1)
3519               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3520                                 AS1 (lsl,%B0)     CR_TAB
3521                                 AS2 (sbc,%B0,%B0));
3522             else if (reg0 == reg1 + 1)
3523               return *len = 3, (AS1 (clr,%B0)    CR_TAB
3524                                 AS2 (sbrc,%A0,7) CR_TAB
3525                                 AS1 (dec,%B0));
3526
3527             return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3528                               AS1 (clr,%B0)     CR_TAB
3529                               AS2 (sbrc,%A0,7)  CR_TAB
3530                               AS1 (dec,%B0));
3531           }
3532
3533         case 9:
3534           *len = 4;
3535           return (AS2 (mov,%A0,%B0) CR_TAB
3536                   AS1 (lsl,%B0)      CR_TAB
3537                   AS2 (sbc,%B0,%B0) CR_TAB
3538                   AS1 (asr,%A0));
3539
3540         case 10:
3541           *len = 5;
3542           return (AS2 (mov,%A0,%B0) CR_TAB
3543                   AS1 (lsl,%B0)     CR_TAB
3544                   AS2 (sbc,%B0,%B0) CR_TAB
3545                   AS1 (asr,%A0)     CR_TAB
3546                   AS1 (asr,%A0));
3547
3548         case 11:
3549           if (AVR_ENHANCED && ldi_ok)
3550             {
3551               *len = 5;
3552               return (AS2 (ldi,%A0,0x20) CR_TAB
3553                       AS2 (muls,%B0,%A0) CR_TAB
3554                       AS2 (mov,%A0,r1)   CR_TAB
3555                       AS2 (sbc,%B0,%B0)  CR_TAB
3556                       AS1 (clr,__zero_reg__));
3557             }
3558           if (optimize_size && scratch)
3559             break;  /* 5 */
3560           *len = 6;
3561           return (AS2 (mov,%A0,%B0) CR_TAB
3562                   AS1 (lsl,%B0)     CR_TAB
3563                   AS2 (sbc,%B0,%B0) CR_TAB
3564                   AS1 (asr,%A0)     CR_TAB
3565                   AS1 (asr,%A0)     CR_TAB
3566                   AS1 (asr,%A0));
3567
3568         case 12:
3569           if (AVR_ENHANCED && ldi_ok)
3570             {
3571               *len = 5;
3572               return (AS2 (ldi,%A0,0x10) CR_TAB
3573                       AS2 (muls,%B0,%A0) CR_TAB
3574                       AS2 (mov,%A0,r1)   CR_TAB
3575                       AS2 (sbc,%B0,%B0)  CR_TAB
3576                       AS1 (clr,__zero_reg__));
3577             }
3578           if (optimize_size && scratch)
3579             break;  /* 5 */
3580           *len = 7;
3581           return (AS2 (mov,%A0,%B0) CR_TAB
3582                   AS1 (lsl,%B0)     CR_TAB
3583                   AS2 (sbc,%B0,%B0) CR_TAB
3584                   AS1 (asr,%A0)     CR_TAB
3585                   AS1 (asr,%A0)     CR_TAB
3586                   AS1 (asr,%A0)     CR_TAB
3587                   AS1 (asr,%A0));
3588
3589         case 13:
3590           if (AVR_ENHANCED && ldi_ok)
3591             {
3592               *len = 5;
3593               return (AS2 (ldi,%A0,0x08) CR_TAB
3594                       AS2 (muls,%B0,%A0) CR_TAB
3595                       AS2 (mov,%A0,r1)   CR_TAB
3596                       AS2 (sbc,%B0,%B0)  CR_TAB
3597                       AS1 (clr,__zero_reg__));
3598             }
3599           if (optimize_size)
3600             break;  /* scratch ? 5 : 7 */
3601           *len = 8;
3602           return (AS2 (mov,%A0,%B0) CR_TAB
3603                   AS1 (lsl,%B0)     CR_TAB
3604                   AS2 (sbc,%B0,%B0) CR_TAB
3605                   AS1 (asr,%A0)     CR_TAB
3606                   AS1 (asr,%A0)     CR_TAB
3607                   AS1 (asr,%A0)     CR_TAB
3608                   AS1 (asr,%A0)     CR_TAB
3609                   AS1 (asr,%A0));
3610
3611         case 14:
3612           *len = 5;
3613           return (AS1 (lsl,%B0)     CR_TAB
3614                   AS2 (sbc,%A0,%A0) CR_TAB
3615                   AS1 (lsl,%B0)     CR_TAB
3616                   AS2 (mov,%B0,%A0) CR_TAB
3617                   AS1 (rol,%A0));
3618
3619         case 15:
3620           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
3621                             AS2 (sbc,%A0,%A0) CR_TAB
3622                             AS2 (mov,%B0,%A0));
3623         }
3624       len = t;
3625     }
3626   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3627                        AS1 (ror,%A0)),
3628                        insn, operands, len, 2);
3629   return "";
3630 }
3631
3632
3633 /* 32bit arithmetic shift right  ((signed long)x >> i) */
3634
3635 const char *
3636 ashrsi3_out (insn, operands, len)
3637      rtx insn;
3638      rtx operands[];
3639      int *len;
3640 {
3641   if (GET_CODE (operands[2]) == CONST_INT)
3642     {
3643       int k;
3644       int *t = len;
3645       
3646       if (!len)
3647         len = &k;
3648       
3649       switch (INTVAL (operands[2]))
3650         {
3651         case 8:
3652           {
3653             int reg0 = true_regnum (operands[0]);
3654             int reg1 = true_regnum (operands[1]);
3655             *len=6;
3656             if (reg0 <= reg1)
3657               return (AS2 (mov,%A0,%B1) CR_TAB
3658                       AS2 (mov,%B0,%C1) CR_TAB
3659                       AS2 (mov,%C0,%D1) CR_TAB
3660                       AS1 (clr,%D0)     CR_TAB
3661                       AS2 (sbrc,%C0,7)  CR_TAB
3662                       AS1 (dec,%D0));
3663             else if (reg0 == reg1 + 1)
3664               {
3665                 *len = 3;
3666                 return (AS1 (clr,%D0)     CR_TAB
3667                         AS2 (sbrc,%C0,7)  CR_TAB
3668                         AS1 (dec,%D0));
3669               }
3670             else
3671               return (AS1 (clr,%D0)     CR_TAB
3672                       AS2 (sbrc,%D1,7)  CR_TAB
3673                       AS1 (dec,%D0)     CR_TAB
3674                       AS2 (mov,%C0,%D1) CR_TAB
3675                       AS2 (mov,%B0,%C1) CR_TAB
3676                       AS2 (mov,%A0,%B1));
3677           }
3678           
3679         case 16:
3680           {
3681             int reg0 = true_regnum (operands[0]);
3682             int reg1 = true_regnum (operands[1]);
3683             *len=6;
3684             if (AVR_ENHANCED && (reg0 != reg1 + 2))
3685               {
3686                 *len = 5;
3687                 return (AS2 (movw,%A0,%C1) CR_TAB
3688                         AS1 (clr,%D0)      CR_TAB
3689                         AS2 (sbrc,%B0,7)   CR_TAB
3690                         AS1 (com,%D0)      CR_TAB
3691                         AS2 (mov,%C0,%D0));
3692               }
3693             if (reg0 <= reg1 + 1)
3694               return (AS2 (mov,%A0,%C1) CR_TAB
3695                       AS2 (mov,%B0,%D1) CR_TAB
3696                       AS1 (clr,%D0)     CR_TAB
3697                       AS2 (sbrc,%B0,7)  CR_TAB
3698                       AS1 (com,%D0)     CR_TAB
3699                       AS2 (mov,%C0,%D0));
3700             else if (reg0 == reg1 + 2)
3701               return *len = 4, (AS1 (clr,%D0)     CR_TAB
3702                                 AS2 (sbrc,%B0,7)  CR_TAB
3703                                 AS1 (com,%D0)     CR_TAB
3704                                 AS2 (mov,%C0,%D0));
3705             else
3706               return (AS2 (mov,%B0,%D1) CR_TAB
3707                       AS2 (mov,%A0,%C1) CR_TAB
3708                       AS1 (clr,%D0)     CR_TAB
3709                       AS2 (sbrc,%B0,7)  CR_TAB
3710                       AS1 (com,%D0)     CR_TAB
3711                       AS2 (mov,%C0,%D0));
3712           }
3713
3714         case 24:
3715           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3716             return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3717                               AS1 (clr,%D0)     CR_TAB
3718                               AS2 (sbrc,%A0,7)  CR_TAB
3719                               AS1 (com,%D0)     CR_TAB
3720                               AS2 (mov,%B0,%D0) CR_TAB
3721                               AS2 (mov,%C0,%D0));
3722           else
3723             return *len = 5, (AS1 (clr,%D0)     CR_TAB
3724                               AS2 (sbrc,%A0,7)  CR_TAB
3725                               AS1 (com,%D0)     CR_TAB
3726                               AS2 (mov,%B0,%D0) CR_TAB
3727                               AS2 (mov,%C0,%D0));
3728
3729         case 31:
3730           if (AVR_ENHANCED)
3731             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
3732                               AS2 (sbc,%A0,%A0) CR_TAB
3733                               AS2 (mov,%B0,%A0) CR_TAB
3734                               AS2 (movw,%C0,%A0));
3735           else
3736             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
3737                               AS2 (sbc,%A0,%A0) CR_TAB
3738                               AS2 (mov,%B0,%A0) CR_TAB
3739                               AS2 (mov,%C0,%A0) CR_TAB
3740                               AS2 (mov,%D0,%A0));
3741         }
3742       len = t;
3743     }
3744   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3745                        AS1 (ror,%C0) CR_TAB
3746                        AS1 (ror,%B0) CR_TAB
3747                        AS1 (ror,%A0)),
3748                        insn, operands, len, 4);
3749   return "";
3750 }
3751
3752 /* 8bit logic shift right ((unsigned char)x >> i) */
3753
3754 const char *
3755 lshrqi3_out (insn, operands, len)
3756      rtx insn;
3757      rtx operands[];
3758      int *len;
3759 {
3760   if (GET_CODE (operands[2]) == CONST_INT)
3761     {
3762       int k;
3763
3764       if (!len)
3765         len = &k;
3766       
3767       switch (INTVAL (operands[2]))
3768         {
3769         default:
3770           *len = 1;
3771           return AS1 (clr,%0);
3772
3773         case 1:
3774           *len = 1;
3775           return AS1 (lsr,%0);
3776
3777         case 2:
3778           *len = 2;
3779           return (AS1 (lsr,%0) CR_TAB
3780                   AS1 (lsr,%0));
3781         case 3:
3782           *len = 3;
3783           return (AS1 (lsr,%0) CR_TAB
3784                   AS1 (lsr,%0) CR_TAB
3785                   AS1 (lsr,%0));
3786           
3787         case 4:
3788           if (test_hard_reg_class (LD_REGS, operands[0]))
3789             {
3790               *len=2;
3791               return (AS1 (swap,%0) CR_TAB
3792                       AS2 (andi,%0,0x0f));
3793             }
3794           *len = 4;
3795           return (AS1 (lsr,%0) CR_TAB
3796                   AS1 (lsr,%0) CR_TAB
3797                   AS1 (lsr,%0) CR_TAB
3798                   AS1 (lsr,%0));
3799           
3800         case 5:
3801           if (test_hard_reg_class (LD_REGS, operands[0]))
3802             {
3803               *len = 3;
3804               return (AS1 (swap,%0) CR_TAB
3805                       AS1 (lsr,%0)  CR_TAB
3806                       AS2 (andi,%0,0x7));
3807             }
3808           *len = 5;
3809           return (AS1 (lsr,%0) CR_TAB
3810                   AS1 (lsr,%0) CR_TAB
3811                   AS1 (lsr,%0) CR_TAB
3812                   AS1 (lsr,%0) CR_TAB
3813                   AS1 (lsr,%0));
3814           
3815         case 6:
3816           if (test_hard_reg_class (LD_REGS, operands[0]))
3817             {
3818               *len = 4;
3819               return (AS1 (swap,%0) CR_TAB
3820                       AS1 (lsr,%0)  CR_TAB
3821                       AS1 (lsr,%0)  CR_TAB
3822                       AS2 (andi,%0,0x3));
3823             }
3824           *len = 6;
3825           return (AS1 (lsr,%0) CR_TAB
3826                   AS1 (lsr,%0) CR_TAB
3827                   AS1 (lsr,%0) CR_TAB
3828                   AS1 (lsr,%0) CR_TAB
3829                   AS1 (lsr,%0) CR_TAB
3830                   AS1 (lsr,%0));
3831           
3832         case 7:
3833           *len = 3;
3834           return (AS1 (rol,%0) CR_TAB
3835                   AS1 (clr,%0) CR_TAB
3836                   AS1 (rol,%0));
3837         }
3838     }
3839   else if (CONSTANT_P (operands[2]))
3840     fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
3841   
3842   out_shift_with_cnt (AS1 (lsr,%0),
3843                       insn, operands, len, 1);
3844   return "";
3845 }
3846
3847 /* 16bit logic shift right ((unsigned short)x >> i) */
3848
3849 const char *
3850 lshrhi3_out (insn, operands, len)
3851      rtx insn;
3852      rtx operands[];
3853      int *len;
3854 {
3855   if (GET_CODE (operands[2]) == CONST_INT)
3856     {
3857       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3858       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3859       int k;
3860       int *t = len;
3861
3862       if (!len)
3863         len = &k;
3864       
3865       switch (INTVAL (operands[2]))
3866         {
3867         case 4:
3868           if (optimize_size && scratch)
3869             break;  /* 5 */
3870           if (ldi_ok)
3871             {
3872               *len = 6;
3873               return (AS1 (swap,%B0)      CR_TAB
3874                       AS1 (swap,%A0)      CR_TAB
3875                       AS2 (andi,%A0,0x0f) CR_TAB
3876                       AS2 (eor,%A0,%B0)   CR_TAB
3877                       AS2 (andi,%B0,0x0f) CR_TAB
3878                       AS2 (eor,%A0,%B0));
3879             }
3880           if (scratch)
3881             {
3882               *len = 7;
3883               return (AS1 (swap,%B0)    CR_TAB
3884                       AS1 (swap,%A0)    CR_TAB
3885                       AS2 (ldi,%3,0x0f) CR_TAB
3886                       AS2 (and,%A0,%3)  CR_TAB
3887                       AS2 (eor,%A0,%B0) CR_TAB
3888                       AS2 (and,%B0,%3)  CR_TAB
3889                       AS2 (eor,%A0,%B0));
3890             }
3891           break;  /* optimize_size ? 6 : 8 */
3892
3893         case 5:
3894           if (optimize_size)
3895             break;  /* scratch ? 5 : 6 */
3896           if (ldi_ok)
3897             {
3898               *len = 8;
3899               return (AS1 (lsr,%B0)       CR_TAB
3900                       AS1 (ror,%A0)       CR_TAB
3901                       AS1 (swap,%B0)      CR_TAB
3902                       AS1 (swap,%A0)      CR_TAB
3903                       AS2 (andi,%A0,0x0f) CR_TAB
3904                       AS2 (eor,%A0,%B0)   CR_TAB
3905                       AS2 (andi,%B0,0x0f) CR_TAB
3906                       AS2 (eor,%A0,%B0));
3907             }
3908           if (scratch)
3909             {
3910               *len = 9;
3911               return (AS1 (lsr,%B0)     CR_TAB
3912                       AS1 (ror,%A0)     CR_TAB
3913                       AS1 (swap,%B0)    CR_TAB
3914                       AS1 (swap,%A0)    CR_TAB
3915                       AS2 (ldi,%3,0x0f) CR_TAB
3916                       AS2 (and,%A0,%3)  CR_TAB
3917                       AS2 (eor,%A0,%B0) CR_TAB
3918                       AS2 (and,%B0,%3)  CR_TAB
3919                       AS2 (eor,%A0,%B0));
3920             }
3921           break;  /* 10 */
3922
3923         case 6:
3924           if (optimize_size)
3925             break;  /* scratch ? 5 : 6 */
3926           *len = 9;
3927           return (AS1 (clr,__tmp_reg__) CR_TAB
3928                   AS1 (lsl,%A0)         CR_TAB
3929                   AS1 (rol,%B0)         CR_TAB
3930                   AS1 (rol,__tmp_reg__) CR_TAB
3931                   AS1 (lsl,%A0)         CR_TAB
3932                   AS1 (rol,%B0)         CR_TAB
3933                   AS1 (rol,__tmp_reg__) CR_TAB
3934                   AS2 (mov,%A0,%B0)     CR_TAB
3935                   AS2 (mov,%B0,__tmp_reg__));
3936
3937         case 7:
3938           *len = 5;
3939           return (AS1 (lsl,%A0)     CR_TAB
3940                   AS2 (mov,%A0,%B0) CR_TAB
3941                   AS1 (rol,%A0)     CR_TAB
3942                   AS2 (sbc,%B0,%B0) CR_TAB
3943                   AS1 (neg,%B0));
3944
3945         case 8:
3946           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3947             return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3948                               AS1 (clr,%B0));
3949           else
3950             return *len = 1, AS1 (clr,%B0);
3951
3952         case 9:
3953           *len = 3;
3954           return (AS2 (mov,%A0,%B0) CR_TAB
3955                   AS1 (clr,%B0)     CR_TAB
3956                   AS1 (lsr,%A0));
3957
3958         case 10:
3959           *len = 4;
3960           return (AS2 (mov,%A0,%B0) CR_TAB
3961                   AS1 (clr,%B0)     CR_TAB
3962                   AS1 (lsr,%A0)     CR_TAB
3963                   AS1 (lsr,%A0));
3964
3965         case 11:
3966           *len = 5;
3967           return (AS2 (mov,%A0,%B0) CR_TAB
3968                   AS1 (clr,%B0)     CR_TAB
3969                   AS1 (lsr,%A0)     CR_TAB
3970                   AS1 (lsr,%A0)     CR_TAB
3971                   AS1 (lsr,%A0));
3972
3973         case 12:
3974           if (ldi_ok)
3975             {
3976               *len = 4;
3977               return (AS2 (mov,%A0,%B0) CR_TAB
3978                       AS1 (clr,%B0)     CR_TAB
3979                       AS1 (swap,%A0)    CR_TAB
3980                       AS2 (andi,%A0,0x0f));
3981             }
3982           if (scratch)
3983             {
3984               *len = 5;
3985               return (AS2 (mov,%A0,%B0) CR_TAB
3986                       AS1 (clr,%B0)     CR_TAB
3987                       AS1 (swap,%A0)    CR_TAB
3988                       AS2 (ldi,%3,0x0f) CR_TAB
3989                       AS2 (and,%A0,%3));
3990             }
3991           *len = 6;
3992           return (AS2 (mov,%A0,%B0) CR_TAB
3993                   AS1 (clr,%B0)     CR_TAB
3994                   AS1 (lsr,%A0)     CR_TAB
3995                   AS1 (lsr,%A0)     CR_TAB
3996                   AS1 (lsr,%A0)     CR_TAB
3997                   AS1 (lsr,%A0));
3998
3999         case 13:
4000           if (ldi_ok)
4001             {
4002               *len = 5;
4003               return (AS2 (mov,%A0,%B0) CR_TAB
4004                       AS1 (clr,%B0)     CR_TAB
4005                       AS1 (swap,%A0)    CR_TAB
4006                       AS1 (lsr,%A0)     CR_TAB
4007                       AS2 (andi,%A0,0x07));
4008             }
4009           if (AVR_ENHANCED && scratch)
4010             {
4011               *len = 5;
4012               return (AS2 (ldi,%3,0x08) CR_TAB
4013                       AS2 (mul,%B0,%3)  CR_TAB
4014                       AS2 (mov,%A0,r1)  CR_TAB
4015                       AS1 (clr,%B0)     CR_TAB
4016                       AS1 (clr,__zero_reg__));
4017             }
4018           if (optimize_size && scratch)
4019             break;  /* 5 */
4020           if (scratch)
4021             {
4022               *len = 6;
4023               return (AS2 (mov,%A0,%B0) CR_TAB
4024                       AS1 (clr,%B0)     CR_TAB
4025                       AS1 (swap,%A0)    CR_TAB
4026                       AS1 (lsr,%A0)     CR_TAB
4027                       AS2 (ldi,%3,0x07) CR_TAB
4028                       AS2 (and,%A0,%3));
4029             }
4030           if (AVR_ENHANCED)
4031             {
4032               *len = 6;
4033               return ("set"            CR_TAB
4034                       AS2 (bld,r1,3)   CR_TAB
4035                       AS2 (mul,%B0,r1) CR_TAB
4036                       AS2 (mov,%A0,r1) CR_TAB
4037                       AS1 (clr,%B0)    CR_TAB
4038                       AS1 (clr,__zero_reg__));
4039             }
4040           *len = 7;
4041           return (AS2 (mov,%A0,%B0) CR_TAB
4042                   AS1 (clr,%B0)     CR_TAB
4043                   AS1 (lsr,%A0)     CR_TAB
4044                   AS1 (lsr,%A0)     CR_TAB
4045                   AS1 (lsr,%A0)     CR_TAB
4046                   AS1 (lsr,%A0)     CR_TAB
4047                   AS1 (lsr,%A0));
4048
4049         case 14:
4050           if (AVR_ENHANCED && ldi_ok)
4051             {
4052               *len = 5;
4053               return (AS2 (ldi,%A0,0x04) CR_TAB
4054                       AS2 (mul,%B0,%A0)  CR_TAB
4055                       AS2 (mov,%A0,r1)   CR_TAB
4056                       AS1 (clr,%B0)      CR_TAB
4057                       AS1 (clr,__zero_reg__));
4058             }
4059           if (AVR_ENHANCED && scratch)
4060             {
4061               *len = 5;
4062               return (AS2 (ldi,%3,0x04) CR_TAB
4063                       AS2 (mul,%B0,%3)  CR_TAB
4064                       AS2 (mov,%A0,r1)  CR_TAB
4065                       AS1 (clr,%B0)     CR_TAB
4066                       AS1 (clr,__zero_reg__));
4067             }
4068           if (optimize_size && ldi_ok)
4069             {
4070               *len = 5;
4071               return (AS2 (mov,%A0,%B0) CR_TAB
4072                       AS2 (ldi,%B0,6) "\n1:\t"
4073                       AS1 (lsr,%A0)     CR_TAB
4074                       AS1 (dec,%B0)     CR_TAB
4075                       AS1 (brne,1b));
4076             }
4077           if (optimize_size && scratch)
4078             break;  /* 5 */
4079           *len = 6;
4080           return (AS1 (clr,%A0) CR_TAB
4081                   AS1 (lsl,%B0) CR_TAB
4082                   AS1 (rol,%A0) CR_TAB
4083                   AS1 (lsl,%B0) CR_TAB
4084                   AS1 (rol,%A0) CR_TAB
4085                   AS1 (clr,%B0));
4086
4087         case 15:
4088           *len = 4;
4089           return (AS1 (clr,%A0) CR_TAB
4090                   AS1 (lsl,%B0) CR_TAB
4091                   AS1 (rol,%A0) CR_TAB
4092                   AS1 (clr,%B0));
4093         }
4094       len = t;
4095     }
4096   out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4097                        AS1 (ror,%A0)),
4098                        insn, operands, len, 2);
4099   return "";
4100 }
4101
4102 /* 32bit logic shift right ((unsigned int)x >> i) */
4103
4104 const char *
4105 lshrsi3_out (insn, operands, len)
4106      rtx insn;
4107      rtx operands[];
4108      int *len;
4109 {
4110   if (GET_CODE (operands[2]) == CONST_INT)
4111     {
4112       int k;
4113       int *t = len;
4114       
4115       if (!len)
4116         len = &k;
4117       
4118       switch (INTVAL (operands[2]))
4119         {
4120         case 8:
4121           {
4122             int reg0 = true_regnum (operands[0]);
4123             int reg1 = true_regnum (operands[1]);
4124             *len = 4;
4125             if (reg0 <= reg1)
4126               return (AS2 (mov,%A0,%B1) CR_TAB
4127                       AS2 (mov,%B0,%C1) CR_TAB
4128                       AS2 (mov,%C0,%D1) CR_TAB
4129                       AS1 (clr,%D0));
4130             else if (reg0 == reg1 + 1)
4131               return *len = 1, AS1 (clr,%D0);
4132             else
4133               return (AS1 (clr,%D0)     CR_TAB
4134                       AS2 (mov,%C0,%D1) CR_TAB
4135                       AS2 (mov,%B0,%C1) CR_TAB
4136                       AS2 (mov,%A0,%B1)); 
4137           }
4138           
4139         case 16:
4140           {
4141             int reg0 = true_regnum (operands[0]);
4142             int reg1 = true_regnum (operands[1]);
4143             *len = 4;
4144             if (AVR_ENHANCED && (reg0 != reg1 + 2))
4145               {
4146                 *len = 3;
4147                 return (AS2 (movw,%A0,%C1) CR_TAB
4148                         AS1 (clr,%C0)      CR_TAB
4149                         AS1 (clr,%D0));
4150               }
4151             if (reg0 <= reg1 + 1)
4152               return (AS2 (mov,%A0,%C1) CR_TAB
4153                       AS2 (mov,%B0,%D1) CR_TAB
4154                       AS1 (clr,%C0)     CR_TAB
4155                       AS1 (clr,%D0));
4156             else if (reg0 == reg1 + 2)
4157               return *len = 2, (AS1 (clr,%C0)     CR_TAB
4158                                 AS1 (clr,%D0));
4159             else
4160               return (AS2 (mov,%B0,%D1) CR_TAB
4161                       AS2 (mov,%A0,%C1) CR_TAB
4162                       AS1 (clr,%C0)     CR_TAB
4163                       AS1 (clr,%D0));
4164           }
4165           
4166         case 24:
4167           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4168             return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4169                               AS1 (clr,%B0)     CR_TAB
4170                               AS1 (clr,%C0)     CR_TAB
4171                               AS1 (clr,%D0));
4172           else
4173             return *len = 3, (AS1 (clr,%B0)     CR_TAB
4174                               AS1 (clr,%C0)     CR_TAB
4175                               AS1 (clr,%D0));
4176
4177         case 31:
4178           *len = 6;
4179           return (AS1 (clr,%A0)    CR_TAB
4180                   AS2 (sbrc,%D0,7) CR_TAB
4181                   AS1 (inc,%A0)    CR_TAB
4182                   AS1 (clr,%B0)    CR_TAB
4183                   AS1 (clr,%C0)    CR_TAB
4184                   AS1 (clr,%D0));
4185         }
4186       len = t;
4187     }
4188   out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4189                        AS1 (ror,%C0) CR_TAB
4190                        AS1 (ror,%B0) CR_TAB
4191                        AS1 (ror,%A0)),
4192                       insn, operands, len, 4);
4193   return "";
4194 }
4195
4196 /* Modifies the length assigned to instruction INSN
4197  LEN is the initially computed length of the insn.  */
4198
4199 int
4200 adjust_insn_length (insn, len)
4201      rtx insn;
4202      int len;
4203 {
4204   rtx patt = PATTERN (insn);
4205   rtx set;
4206
4207   if (GET_CODE (patt) == SET)
4208     {
4209       rtx op[10];
4210       op[1] = SET_SRC (patt);
4211       op[0] = SET_DEST (patt);
4212       if (general_operand (op[1], VOIDmode)
4213           && general_operand (op[0], VOIDmode))
4214         {
4215           switch (GET_MODE (op[0]))
4216             {
4217             case QImode:
4218               output_movqi (insn, op, &len);
4219               break;
4220             case HImode:
4221               output_movhi (insn, op, &len);
4222               break;
4223             case SImode:
4224             case SFmode:
4225               output_movsisf (insn, op, &len);
4226               break;
4227             default:
4228               break;
4229             }
4230         }
4231       else if (op[0] == cc0_rtx && REG_P (op[1]))
4232         {
4233           switch (GET_MODE (op[1]))
4234             {
4235             case HImode: out_tsthi (insn,&len); break;
4236             case SImode: out_tstsi (insn,&len); break;
4237             default: break;
4238             }
4239         }
4240       else if (GET_CODE (op[1]) == AND)
4241         {
4242           if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4243             {
4244               HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4245               if (GET_MODE (op[1]) == SImode)
4246                 len = (((mask & 0xff) != 0xff)
4247                        + ((mask & 0xff00) != 0xff00)
4248                        + ((mask & 0xff0000UL) != 0xff0000UL)
4249                        + ((mask & 0xff000000UL) != 0xff000000UL));
4250               else if (GET_MODE (op[1]) == HImode)
4251                 len = (((mask & 0xff) != 0xff)
4252                        + ((mask & 0xff00) != 0xff00));
4253             }
4254         }
4255       else if (GET_CODE (op[1]) == IOR)
4256         {
4257           if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4258             {
4259               HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4260               if (GET_MODE (op[1]) == SImode)
4261                 len = (((mask & 0xff) != 0)
4262                        + ((mask & 0xff00) != 0)
4263                        + ((mask & 0xff0000UL) != 0)
4264                        + ((mask & 0xff000000UL) != 0));
4265               else if (GET_MODE (op[1]) == HImode)
4266                 len = (((mask & 0xff) != 0)
4267                        + ((mask & 0xff00) != 0));
4268             }
4269         }
4270     }
4271   set = single_set (insn);
4272   if (set)
4273     {
4274       rtx op[10];
4275
4276       op[1] = SET_SRC (set);
4277       op[0] = SET_DEST (set);
4278
4279       if (GET_CODE (patt) == PARALLEL
4280           && general_operand (op[1], VOIDmode)
4281           && general_operand (op[0], VOIDmode))
4282         {
4283           if (XVECLEN (patt, 0) == 2)
4284             op[2] = XVECEXP (patt, 0, 1);
4285
4286           switch (GET_MODE (op[0]))
4287             {
4288             case QImode:
4289               len = 2;
4290               break;
4291             case HImode:
4292               output_reload_inhi (insn, op, &len);
4293               break;
4294             case SImode:
4295             case SFmode:
4296               output_reload_insisf (insn, op, &len);
4297               break;
4298             default:
4299               break;
4300             }
4301         }
4302       else if (GET_CODE (op[1]) == ASHIFT
4303           || GET_CODE (op[1]) == ASHIFTRT
4304           || GET_CODE (op[1]) == LSHIFTRT)
4305         {
4306           rtx ops[10];
4307           ops[0] = op[0];
4308           ops[1] = XEXP (op[1],0);
4309           ops[2] = XEXP (op[1],1);
4310           switch (GET_CODE (op[1]))
4311             {
4312             case ASHIFT:
4313               switch (GET_MODE (op[0]))
4314                 {
4315                 case QImode: ashlqi3_out (insn,ops,&len); break;
4316                 case HImode: ashlhi3_out (insn,ops,&len); break;
4317                 case SImode: ashlsi3_out (insn,ops,&len); break;
4318                 default: break;
4319                 }
4320               break;
4321             case ASHIFTRT:
4322               switch (GET_MODE (op[0]))
4323                 {
4324                 case QImode: ashrqi3_out (insn,ops,&len); break;
4325                 case HImode: ashrhi3_out (insn,ops,&len); break;
4326                 case SImode: ashrsi3_out (insn,ops,&len); break;
4327                 default: break;
4328                 }
4329               break;
4330             case LSHIFTRT:
4331               switch (GET_MODE (op[0]))
4332                 {
4333                 case QImode: lshrqi3_out (insn,ops,&len); break;
4334                 case HImode: lshrhi3_out (insn,ops,&len); break;
4335                 case SImode: lshrsi3_out (insn,ops,&len); break;
4336                 default: break;
4337                 }
4338               break;
4339             default:
4340               break;
4341             }
4342         }
4343     }
4344   return len;
4345 }
4346
4347 /* Return non-zero if register REG dead after INSN */
4348
4349 int
4350 reg_unused_after (insn, reg)
4351      rtx insn;
4352      rtx reg;
4353 {
4354   return (dead_or_set_p (insn, reg)
4355           || (REG_P(reg) && _reg_unused_after (insn, reg)));
4356 }
4357
4358 /* Return non-zero if REG is not used after INSN.
4359    We assume REG is a reload reg, and therefore does
4360    not live past labels.  It may live past calls or jumps though.  */
4361
4362 int
4363 _reg_unused_after (insn, reg)
4364      rtx insn;
4365      rtx reg;
4366 {
4367   enum rtx_code code;
4368   rtx set;
4369
4370   /* If the reg is set by this instruction, then it is safe for our
4371      case.  Disregard the case where this is a store to memory, since
4372      we are checking a register used in the store address.  */
4373   set = single_set (insn);
4374   if (set && GET_CODE (SET_DEST (set)) != MEM
4375       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4376     return 1;
4377
4378   while ((insn = NEXT_INSN (insn)))
4379     {
4380       code = GET_CODE (insn);
4381
4382 #if 0
4383       /* If this is a label that existed before reload, then the register
4384          if dead here.  However, if this is a label added by reorg, then
4385          the register may still be live here.  We can't tell the difference,
4386          so we just ignore labels completely.  */
4387       if (code == CODE_LABEL)
4388         return 1;
4389       /* else */
4390 #endif
4391
4392       if (code == JUMP_INSN)
4393         return 0;
4394
4395       /* If this is a sequence, we must handle them all at once.
4396          We could have for instance a call that sets the target register,
4397          and a insn in a delay slot that uses the register.  In this case,
4398          we must return 0.  */
4399       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4400         {
4401           int i;
4402           int retval = 0;
4403
4404           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4405             {
4406               rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4407               rtx set = single_set (this_insn);
4408
4409               if (GET_CODE (this_insn) == CALL_INSN)
4410                 code = CALL_INSN;
4411               else if (GET_CODE (this_insn) == JUMP_INSN)
4412                 {
4413                   if (INSN_ANNULLED_BRANCH_P (this_insn))
4414                     return 0;
4415                   code = JUMP_INSN;
4416                 }
4417
4418               if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4419                 return 0;
4420               if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4421                 {
4422                   if (GET_CODE (SET_DEST (set)) != MEM)
4423                     retval = 1;
4424                   else
4425                     return 0;
4426                 }
4427               if (set == 0
4428                   && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4429                 return 0;
4430             }
4431           if (retval == 1)
4432             return 1;
4433           else if (code == JUMP_INSN)
4434             return 0;
4435         }
4436
4437       if (code == CALL_INSN)
4438         {
4439           rtx tem;
4440           for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4441             if (GET_CODE (XEXP (tem, 0)) == USE
4442                 && REG_P (XEXP (XEXP (tem, 0), 0))
4443                 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4444               return 0;
4445           if (call_used_regs[REGNO (reg)]) 
4446             return 1;
4447         }
4448
4449       if (GET_RTX_CLASS (code) == 'i')
4450         {
4451           rtx set = single_set (insn);
4452
4453           if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4454             return 0;
4455           if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4456             return GET_CODE (SET_DEST (set)) != MEM;
4457           if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4458             return 0;
4459         }
4460     }
4461   return 1;
4462 }
4463
4464 /* Output rtx VALUE as .byte to file FILE */
4465
4466 void
4467 asm_output_char (file, value)
4468      FILE *file;
4469      rtx value;
4470 {
4471   fprintf (file, "\t.byte ");
4472   output_addr_const (file, value);
4473   fprintf (file, "\n");
4474 }
4475
4476
4477 /* Output VALUE as .byte to file FILE */
4478
4479 void
4480 asm_output_byte (file, value)
4481      FILE *file;
4482      int value;
4483 {
4484   fprintf (file, "\t.byte 0x%x\n", value & 0xff);
4485 }
4486
4487
4488 /* Output rtx VALUE as .word to file FILE */
4489
4490 void
4491 asm_output_short (file, value)
4492      FILE *file;
4493      rtx value;
4494 {
4495   if (SYMBOL_REF_FLAG (value) || GET_CODE (value) == LABEL_REF)
4496     {
4497       fprintf (file, "\t.word pm(");
4498       output_addr_const (file, (value));
4499       fprintf (file, ")\n");
4500     }
4501   else
4502     {
4503       fprintf (file, "\t.word ");
4504       output_addr_const (file, (value));
4505       fprintf (file, "\n");
4506     }
4507 }
4508
4509
4510 /* Output real N to file FILE */
4511
4512 void
4513 asm_output_float (file, n)
4514      FILE *file;
4515      REAL_VALUE_TYPE n;
4516 {
4517   long val;
4518   char dstr[100];
4519   
4520   REAL_VALUE_TO_TARGET_SINGLE (n, val);
4521   REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
4522   fprintf (file, "\t.long 0x%08lx\t/* %s */\n", val, dstr);
4523 }
4524
4525 /* Sets section name for declaration DECL */
4526   
4527 void
4528 unique_section (decl, reloc)
4529      tree decl;
4530      int reloc ATTRIBUTE_UNUSED;
4531 {
4532   int len;
4533   const char *name, *prefix;
4534   char *string;
4535   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4536   /* Strip off any encoding in name.  */
4537   STRIP_NAME_ENCODING (name, name);
4538
4539   if (TREE_CODE (decl) == FUNCTION_DECL)
4540     {
4541       if (flag_function_sections)
4542         prefix = ".text.";
4543       else
4544         prefix = ".text";
4545     }
4546   else 
4547     abort ();
4548
4549   if (flag_function_sections)
4550     {
4551       len = strlen (name) + strlen (prefix);
4552       string = alloca (len + 1);
4553       sprintf (string, "%s%s", prefix, name);
4554       DECL_SECTION_NAME (decl) = build_string (len, string);
4555     }
4556 }
4557
4558
4559 /* The routine used to output NUL terminated strings.  We use a special
4560    version of this for most svr4 targets because doing so makes the
4561    generated assembly code more compact (and thus faster to assemble)
4562    as well as more readable, especially for targets like the i386
4563    (where the only alternative is to output character sequences as
4564    comma separated lists of numbers).   */
4565
4566 void
4567 gas_output_limited_string(file, str)
4568      FILE *file;
4569      const char * str;
4570 {
4571   const unsigned char *_limited_str = (unsigned char *) str;
4572   unsigned ch;
4573   fprintf (file, "%s\"", STRING_ASM_OP);
4574   for (; (ch = *_limited_str); _limited_str++)
4575     {
4576       int escape;
4577       switch (escape = ESCAPES[ch])
4578         {
4579         case 0:
4580           putc (ch, file);
4581           break;
4582         case 1:
4583           fprintf (file, "\\%03o", ch);
4584           break;
4585         default:
4586           putc ('\\', file);
4587           putc (escape, file);
4588           break;
4589         }
4590     }
4591   fprintf (file, "\"\n");
4592 }
4593
4594 /* The routine used to output sequences of byte values.  We use a special
4595    version of this for most svr4 targets because doing so makes the
4596    generated assembly code more compact (and thus faster to assemble)
4597    as well as more readable.  Note that if we find subparts of the
4598    character sequence which end with NUL (and which are shorter than
4599    STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
4600
4601 void
4602 gas_output_ascii(file, str, length)
4603      FILE * file;
4604      const char * str;
4605      size_t length;
4606 {
4607   const unsigned char *_ascii_bytes = (const unsigned char *) str;
4608   const unsigned char *limit = _ascii_bytes + length;
4609   unsigned bytes_in_chunk = 0;
4610   for (; _ascii_bytes < limit; _ascii_bytes++)
4611     {
4612       const unsigned char *p;
4613       if (bytes_in_chunk >= 60)
4614         {
4615           fprintf (file, "\"\n");
4616           bytes_in_chunk = 0;
4617         }
4618       for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4619         continue;
4620       if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4621         {
4622           if (bytes_in_chunk > 0)
4623             {
4624               fprintf (file, "\"\n");
4625               bytes_in_chunk = 0;
4626             }
4627           gas_output_limited_string (file, (char*)_ascii_bytes);
4628           _ascii_bytes = p;
4629         }
4630       else
4631         {
4632           int escape;
4633           unsigned ch;
4634           if (bytes_in_chunk == 0)
4635             fprintf (file, "\t.ascii\t\"");
4636           switch (escape = ESCAPES[ch = *_ascii_bytes])
4637             {
4638             case 0:
4639               putc (ch, file);
4640               bytes_in_chunk++;
4641               break;
4642             case 1:
4643               fprintf (file, "\\%03o", ch);
4644               bytes_in_chunk += 4;
4645               break;
4646             default:
4647               putc ('\\', file);
4648               putc (escape, file);
4649               bytes_in_chunk += 2;
4650               break;
4651             }
4652         }
4653     }
4654   if (bytes_in_chunk > 0)
4655     fprintf (file, "\"\n");
4656 }
4657
4658 /* Return value is nonzero if pseudos that have been
4659    assigned to registers of class CLASS would likely be spilled
4660    because registers of CLASS are needed for spill registers.  */
4661
4662 enum reg_class
4663 class_likely_spilled_p (c)
4664      int c;
4665 {
4666   return (c != ALL_REGS && c != ADDW_REGS);
4667 }
4668
4669 /* Only `progmem' attribute valid for type.  */
4670
4671 static int
4672 avr_valid_type_attribute (type, attributes, identifier, args)
4673      tree type ATTRIBUTE_UNUSED;
4674      tree attributes ATTRIBUTE_UNUSED;
4675      tree identifier;
4676      tree args ATTRIBUTE_UNUSED;
4677 {
4678   return is_attribute_p ("progmem", identifier);
4679 }
4680
4681 /* If IDENTIFIER with arguments ARGS is a valid machine specific
4682    attribute for DECL return 1.
4683    Valid attributes:
4684    progmem - put data to program memory;
4685    signal - make a function to be hardware interrupt. After function
4686    prologue interrupts are disabled;
4687    interrupt - make a function to be hardware interrupt. After function
4688    prologue interrupts are enabled;
4689    naked     - don't generate function prologue/epilogue and `ret' command.  */
4690
4691 static int
4692 avr_valid_decl_attribute (decl, attributes, attr, args)
4693      tree decl;
4694      tree attributes ATTRIBUTE_UNUSED;
4695      tree attr;
4696      tree args ATTRIBUTE_UNUSED;
4697 {
4698   if (is_attribute_p ("interrupt", attr)
4699       || is_attribute_p ("signal", attr)
4700       || is_attribute_p ("naked", attr))
4701     return TREE_CODE (decl) == FUNCTION_DECL;
4702
4703   if (is_attribute_p ("progmem", attr)
4704       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
4705     {
4706       if (DECL_INITIAL (decl) == NULL_TREE && !DECL_EXTERNAL (decl))
4707         {
4708           warning ("Only initialized variables can be placed into "
4709                    "program memory area.");
4710           return 0;
4711         }
4712       return 1;
4713     }
4714   return 0;
4715 }
4716
4717
4718 /* Look for attribute `progmem' in DECL
4719    if found return 1, otherwise 0.  */
4720
4721 int
4722 avr_progmem_p (decl)
4723      tree decl;
4724 {
4725   tree a;
4726
4727   if (TREE_CODE (decl) != VAR_DECL)
4728     return 0;
4729
4730   if (NULL_TREE
4731       != lookup_attribute ("progmem", DECL_MACHINE_ATTRIBUTES (decl)))
4732     return 1;
4733
4734   a=decl;
4735   do
4736     a = TREE_TYPE(a);
4737   while (TREE_CODE (a) == ARRAY_TYPE);
4738
4739   if (a == error_mark_node)
4740     return 0;
4741
4742   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4743     return 1;
4744   
4745   return 0;
4746 }
4747
4748 /* Encode section information about tree DECL */
4749   
4750 void
4751 encode_section_info (decl)
4752      tree decl;
4753 {
4754   if (TREE_CODE (decl) == FUNCTION_DECL)
4755     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
4756   else if ((TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4757            && TREE_CODE (decl) == VAR_DECL
4758            && avr_progmem_p (decl))
4759     {
4760       const char *dsec = ".progmem.data";
4761       DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
4762       TREE_READONLY (decl) = 1;
4763     }
4764 }   
4765
4766 /* Outputs to the stdio stream FILE some
4767    appropriate text to go at the start of an assembler file.  */
4768
4769 void
4770 asm_file_start (file)
4771      FILE *file;
4772 {
4773   output_file_directive (file, main_input_filename);
4774   fprintf (file, "\t.arch %s\n", avr_mcu_name);
4775   fputs ("__SREG__ = 0x3f\n"
4776          "__SP_H__ = 0x3e\n"
4777          "__SP_L__ = 0x3d\n", file);
4778   
4779   fputs ("__tmp_reg__ = 0\n" 
4780          "__zero_reg__ = 1\n"
4781          "_PC_ = 2\n", file);
4782   
4783   commands_in_file = 0;
4784   commands_in_prologues = 0;
4785   commands_in_epilogues = 0;
4786 }
4787
4788 /* Outputs to the stdio stream FILE some
4789    appropriate text to go at the end of an assembler file.  */
4790
4791 void
4792 asm_file_end (file)
4793      FILE *file;
4794 {
4795   fprintf (file,
4796            "/* File %s: code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4797            main_input_filename,
4798            commands_in_file,
4799            commands_in_file,
4800            commands_in_file - commands_in_prologues - commands_in_epilogues,
4801            commands_in_prologues, commands_in_epilogues);
4802 }
4803
4804 /* Choose the order in which to allocate hard registers for
4805    pseudo-registers local to a basic block.
4806
4807    Store the desired register order in the array `reg_alloc_order'.
4808    Element 0 should be the register to allocate first; element 1, the
4809    next register; and so on.  */
4810
4811 void
4812 order_regs_for_local_alloc ()
4813 {
4814   unsigned int i;
4815   int order_0[] = {
4816     24,25,
4817     18,19,
4818     20,21,
4819     22,23,
4820     30,31,
4821     26,27,
4822     28,29,
4823     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4824     0,1,
4825     32,33,34,35
4826   };
4827   int order_1[] = {
4828     18,19,
4829     20,21,
4830     22,23,
4831     24,25,
4832     30,31,
4833     26,27,
4834     28,29,
4835     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4836     0,1,
4837     32,33,34,35
4838   };
4839   int order_2[] = {
4840     25,24,
4841     23,22,
4842     21,20,
4843     19,18,
4844     30,31,
4845     26,27,
4846     28,29,
4847     17,16,
4848     15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4849     1,0,
4850     32,33,34,35
4851   };
4852   
4853   int *order = (TARGET_ORDER_1 ? order_1 :
4854                 TARGET_ORDER_2 ? order_2 :
4855                 order_0);
4856   for (i=0; i < ARRAY_SIZE (order_0); ++i)
4857       reg_alloc_order[i] = order[i];
4858 }
4859
4860 /* Calculate the cost of X code of the expression in which it is contained,
4861    found in OUTER_CODE */
4862
4863 int
4864 default_rtx_costs (X, code, outer_code)
4865      rtx X;
4866      enum rtx_code code;
4867      enum rtx_code outer_code;
4868 {
4869   int cost=0;
4870   switch (code)
4871     {
4872     case SYMBOL_REF:
4873     case LABEL_REF:
4874       cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4875       break;
4876     case MEM:
4877       if (outer_code != SET)
4878         cost = 1;
4879       if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4880         cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4881       else
4882         cost += GET_MODE_SIZE (GET_MODE (X));
4883       break;
4884     case CONST_INT:
4885       cost = 0;
4886       break;
4887     case SIGN_EXTEND:
4888       if (outer_code == SET)
4889         cost = GET_MODE_SIZE (GET_MODE (X));
4890       else
4891         cost = -GET_MODE_SIZE (GET_MODE (X));
4892       break;
4893     case ZERO_EXTEND:
4894       if (outer_code == SET)
4895         cost = GET_MODE_SIZE (GET_MODE (X));
4896       else
4897         cost = -1;
4898       break;
4899     case PLUS:
4900     case MINUS:
4901       if (outer_code == SET)
4902         {
4903           if (X == stack_pointer_rtx)
4904             cost = -10;
4905           else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4906             cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4907                      GET_MODE_SIZE (GET_MODE (X)));
4908           else
4909             cost = GET_MODE_SIZE (GET_MODE (X));
4910         }
4911       break;
4912     case COMPARE:
4913       if (GET_CODE (XEXP (X,1)) == CONST_INT)
4914         cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4915       break;
4916     default:
4917       break;
4918     }
4919   return cost;
4920 }
4921
4922 /* Calculate the cost of a memory address */
4923
4924 int
4925 avr_address_cost (x)
4926      rtx x;
4927 {
4928   if (GET_CODE (x) == PLUS
4929       && GET_CODE (XEXP (x,1)) == CONST_INT
4930       && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4931       && INTVAL (XEXP (x,1)) >= 61)
4932     return 18;
4933   if (CONSTANT_ADDRESS_P (x))
4934     {
4935       if (io_address_p (x, 1))
4936         return 2;
4937       return 4;
4938     }
4939   return 4;
4940 }
4941
4942 /*  EXTRA_CONSTRAINT helper */
4943
4944 int
4945 extra_constraint (x, c)
4946      rtx x;
4947      int c;
4948 {
4949   if (c == 'Q'
4950       && GET_CODE (x) == MEM
4951       && GET_CODE (XEXP (x,0)) == PLUS)
4952     {
4953           if (TARGET_ALL_DEBUG)
4954             {
4955               fprintf (stderr, ("extra_constraint:\n"
4956                                 "reload_completed: %d\n"
4957                                 "reload_in_progress: %d\n"),
4958                        reload_completed, reload_in_progress);
4959               debug_rtx (x);
4960             }
4961       if (GET_CODE (x) == MEM
4962           && GET_CODE (XEXP (x,0)) == PLUS
4963           && REG_P (XEXP (XEXP (x,0), 0))
4964           && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4965           && (INTVAL (XEXP (XEXP (x,0), 1))
4966               <= MAX_LD_OFFSET (GET_MODE (x))))
4967         {
4968           rtx xx = XEXP (XEXP (x,0), 0);
4969           int regno = REGNO (xx);
4970           if (TARGET_ALL_DEBUG)
4971             {
4972               fprintf (stderr, ("extra_constraint:\n"
4973                                 "reload_completed: %d\n"
4974                                 "reload_in_progress: %d\n"),
4975                        reload_completed, reload_in_progress);
4976               debug_rtx (x);
4977             }
4978           if (regno >= FIRST_PSEUDO_REGISTER)
4979             return 1;           /* allocate pseudos */
4980           else if (regno == REG_Z || regno == REG_Y)
4981             return 1;           /* strictly check */
4982           else if (xx == frame_pointer_rtx
4983                    || xx == arg_pointer_rtx)
4984             return 1;           /* XXX frame & arg pointer checks */
4985         }
4986     }
4987   return 0;
4988 }
4989
4990 /* Convert condition code CONDITION to the valid AVR condition code */
4991
4992 RTX_CODE
4993 avr_normalize_condition (condition)
4994      RTX_CODE condition;
4995 {
4996   switch (condition)
4997     {
4998     case GT:
4999       return GE;
5000     case GTU:
5001       return GEU;
5002     case LE:
5003       return LT;
5004     case LEU:
5005       return LTU;
5006     default:
5007       abort ();
5008     }
5009 }
5010
5011 /* This fnction optimizes conditional jumps */
5012
5013 void
5014 machine_dependent_reorg (first_insn)
5015      rtx first_insn;
5016 {
5017   rtx insn, pattern;
5018   
5019   for (insn = first_insn; insn; insn = NEXT_INSN (insn))
5020     {
5021       if (! (GET_CODE (insn) == INSN
5022              || GET_CODE (insn) == CALL_INSN
5023              || GET_CODE (insn) == JUMP_INSN)
5024           || !single_set (insn))
5025         continue;
5026
5027       pattern = PATTERN (insn);
5028
5029       if (GET_CODE (pattern) == PARALLEL)
5030         pattern = XVECEXP (pattern, 0, 0);
5031       if (GET_CODE (pattern) == SET
5032           && SET_DEST (pattern) == cc0_rtx
5033           && compare_diff_p (insn))
5034         {
5035           if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5036             {
5037               /* Now we work under compare insn */
5038               
5039               pattern = SET_SRC (pattern);
5040               if (true_regnum (XEXP (pattern,0)) >= 0
5041                   && true_regnum (XEXP (pattern,1)) >= 0 )
5042                 {
5043                   rtx x = XEXP (pattern,0);
5044                   rtx next = next_real_insn (insn);
5045                   rtx pat = PATTERN (next);
5046                   rtx src = SET_SRC (pat);
5047                   rtx t = XEXP (src,0);
5048                   PUT_CODE (t, swap_condition (GET_CODE (t)));
5049                   XEXP (pattern,0) = XEXP (pattern,1);
5050                   XEXP (pattern,1) = x;
5051                   INSN_CODE (next) = -1;
5052                 }
5053               else if (true_regnum (XEXP (pattern,0)) >= 0
5054                        && GET_CODE (XEXP (pattern,1)) == CONST_INT)
5055                 {
5056                   rtx x = XEXP (pattern,1);
5057                   rtx next = next_real_insn (insn);
5058                   rtx pat = PATTERN (next);
5059                   rtx src = SET_SRC (pat);
5060                   rtx t = XEXP (src,0);
5061
5062                   if (avr_simplify_comparision_p (GET_MODE (XEXP (pattern,0)),
5063                                                   GET_CODE (t), x))
5064                     {
5065                       XEXP (pattern,1) = GEN_INT (INTVAL (x)+1);
5066                       PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
5067                       INSN_CODE (next) = -1;
5068                       INSN_CODE (insn) = -1;
5069                     }
5070                 }
5071             }
5072           else if (true_regnum (SET_SRC (pattern)) >= 0)
5073             {
5074               /* This is a tst insn */
5075               rtx next = next_real_insn (insn);
5076               rtx pat = PATTERN (next);
5077               rtx src = SET_SRC (pat);
5078               rtx t = XEXP (src,0);
5079
5080               PUT_CODE (t, swap_condition (GET_CODE (t)));
5081               SET_SRC (pattern) = gen_rtx (NEG,
5082                                            GET_MODE (SET_SRC (pattern)),
5083                                            SET_SRC (pattern));
5084               INSN_CODE (next) = -1;
5085               INSN_CODE (insn) = -1;
5086             }
5087         }
5088     }
5089 }
5090
5091 /* Returns register number for function return value.*/
5092
5093 int
5094 avr_ret_register ()
5095 {
5096   return 24;
5097 }
5098
5099 /* Ceate an RTX representing the place where a
5100    library function returns a value of mode MODE.  */
5101
5102 rtx
5103 avr_libcall_value (mode)
5104      enum machine_mode mode;
5105 {
5106   int offs = GET_MODE_SIZE (mode);
5107   if (offs < 2)
5108     offs = 2;
5109   return gen_rtx (REG, mode, RET_REGISTER + 2 - offs);
5110 }
5111
5112 /* Create an RTX representing the place where a
5113    function returns a value of data type VALTYPE.  */
5114
5115 rtx
5116 avr_function_value (type, func)
5117      tree type;
5118      tree func ATTRIBUTE_UNUSED;
5119 {
5120   unsigned int offs;
5121   
5122   if (TYPE_MODE (type) != BLKmode)
5123     return avr_libcall_value (TYPE_MODE (type));
5124   
5125   offs = int_size_in_bytes (type);
5126   if (offs < 2)
5127     offs = 2;
5128   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5129     offs = GET_MODE_SIZE (SImode);
5130   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5131     offs = GET_MODE_SIZE (DImode);
5132   
5133   return gen_rtx (REG, BLKmode, RET_REGISTER + 2 - offs);
5134 }
5135
5136 /* Returns non-zero if the number MASK has only one bit set.  */
5137
5138 int
5139 mask_one_bit_p (mask)
5140      HOST_WIDE_INT mask;
5141 {
5142   int i;
5143   unsigned HOST_WIDE_INT n=mask;
5144   for (i = 0; i < 32; ++i)
5145     {
5146       if (n & 0x80000000UL)
5147         {
5148           if (n & 0x7fffffffUL)
5149             return 0;
5150           else
5151             return 32-i;
5152         }
5153       n<<=1;
5154     }
5155   return 0; 
5156 }
5157
5158
5159 /* Places additional restrictions on the register class to
5160    use when it is necessary to copy value X into a register
5161    in class CLASS.  */
5162
5163 enum reg_class
5164 preferred_reload_class (x, class)
5165      rtx x ATTRIBUTE_UNUSED;
5166      enum reg_class class;
5167 {
5168   return class;
5169 }
5170
5171 int
5172 test_hard_reg_class (class, x)
5173      enum reg_class class;
5174      rtx x;
5175 {
5176   int regno = true_regnum (x);
5177   if (regno < 0)
5178     return 0;
5179   return TEST_HARD_REG_CLASS (class, regno);
5180 }
5181
5182 void
5183 debug_hard_reg_set (set)
5184      HARD_REG_SET set;
5185 {
5186   int i;
5187   for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
5188     {
5189       if (TEST_HARD_REG_BIT (set, i))
5190         {
5191           fprintf (stderr, "r%-2d ", i);
5192         }
5193     }
5194   fprintf (stderr, "\n");
5195 }
5196
5197 int
5198 jump_over_one_insn_p (insn, dest)
5199      rtx insn;
5200      rtx dest;
5201 {
5202   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5203                       ? XEXP (dest, 0)
5204                       : dest);
5205   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5206   int dest_addr = INSN_ADDRESSES (uid);
5207   return dest_addr - jump_addr == 2;
5208 }
5209
5210 /* Returns 1 if a value of mode MODE can be stored starting with hard
5211    register number REGNO.  On the enhanced core, anything larger than
5212    1 byte must start in even numbered register for "movw" to work
5213    (this way we don't have to check for odd registers everywhere).  */
5214
5215 int
5216 avr_hard_regno_mode_ok (regno, mode)
5217      int regno;
5218      enum machine_mode mode;
5219 {
5220   if (mode == QImode)
5221     return 1;
5222   /*  if (regno < 24 && !AVR_ENHANCED)
5223       return 1;*/
5224   return !(regno & 1);
5225 }
5226
5227 /* Returns 1 if we know register operand OP was 0 before INSN.  */
5228
5229 static int
5230 reg_was_0 (insn, op)
5231      rtx insn;
5232      rtx op;
5233 {
5234   rtx link;
5235   return (optimize > 0 && insn && op && REG_P (op)
5236           && (link = find_reg_note (insn, REG_WAS_0, 0))
5237           /* Make sure the insn that stored the 0 is still present.  */
5238           && ! INSN_DELETED_P (XEXP (link, 0))
5239           && GET_CODE (XEXP (link, 0)) != NOTE
5240           /* Make sure cross jumping didn't happen here.  */
5241           && no_labels_between_p (XEXP (link, 0), insn)
5242           /* Make sure the reg hasn't been clobbered.  */
5243           && ! reg_set_between_p (op, XEXP (link, 0), insn));
5244 }
5245
5246 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5247    (1 or 2).  Used for lds/sts -> in/out optimization.  */
5248
5249 static int
5250 io_address_p (x, size)
5251      rtx x;
5252      int size;
5253 {
5254   return (optimize > 0 && GET_CODE (x) == CONST_INT
5255           && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5256 }
5257
5258 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2.  */
5259
5260 int
5261 const_int_pow2_p (x)
5262      rtx x;
5263 {
5264   if (GET_CODE (x) == CONST_INT)
5265     {
5266       HOST_WIDE_INT d = INTVAL (x);
5267       HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5268       return exact_log2 (abs_d) + 1;
5269     }
5270   return 0;
5271 }
5272
5273 const char *
5274 output_reload_inhi (insn, operands, len)
5275      rtx insn ATTRIBUTE_UNUSED;
5276      rtx *operands;
5277      int *len;
5278 {
5279   int tmp;
5280   if (!len)
5281     len = &tmp;
5282       
5283   if (GET_CODE (operands[1]) == CONST_INT)
5284     {
5285       int val = INTVAL (operands[1]);
5286       if ((val & 0xff) == 0)
5287         {
5288           *len = 3;
5289           return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5290                   AS2 (ldi,%2,hi8(%1))       CR_TAB
5291                   AS2 (mov,%B0,%2));
5292         }
5293       else if ((val & 0xff00) == 0)
5294         {
5295           *len = 3;
5296           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5297                   AS2 (mov,%A0,%2)     CR_TAB
5298                   AS2 (mov,%B0,__zero_reg__));
5299         }
5300       else if ((val & 0xff) == ((val & 0xff00) >> 8))
5301         {
5302           *len = 3;
5303           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5304                   AS2 (mov,%A0,%2)     CR_TAB
5305                   AS2 (mov,%B0,%2));
5306         }
5307     }
5308   *len = 4;
5309   return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5310           AS2 (mov,%A0,%2)     CR_TAB
5311           AS2 (ldi,%2,hi8(%1)) CR_TAB
5312           AS2 (mov,%B0,%2));
5313 }
5314
5315
5316 const char *
5317 output_reload_insisf (insn, operands, len)
5318      rtx insn ATTRIBUTE_UNUSED;
5319      rtx *operands;
5320      int *len;
5321 {
5322   rtx src = operands[1];
5323   int cnst = (GET_CODE (src) == CONST_INT);
5324
5325   if (len)
5326     {
5327       if (cnst)
5328         *len = 4 + ((INTVAL (src) & 0xff) != 0)
5329                 + ((INTVAL (src) & 0xff00) != 0)
5330                 + ((INTVAL (src) & 0xff0000) != 0)
5331                 + ((INTVAL (src) & 0xff000000U) != 0);
5332       else
5333         *len = 8;
5334
5335       return "";
5336     }
5337
5338   if (cnst && ((INTVAL (src) & 0xff) == 0))
5339     output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5340   else
5341     {
5342       output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5343       output_asm_insn (AS2 (mov, %A0, %2), operands);
5344     }
5345   if (cnst && ((INTVAL (src) & 0xff00) == 0))
5346     output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5347   else
5348     {
5349       output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5350       output_asm_insn (AS2 (mov, %B0, %2), operands);
5351     }
5352   if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5353     output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5354   else
5355     {
5356       output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5357       output_asm_insn (AS2 (mov, %C0, %2), operands);
5358     }
5359   if (cnst && ((INTVAL (src) & 0xff000000U) == 0))
5360     output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5361   else
5362     {
5363       output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5364       output_asm_insn (AS2 (mov, %D0, %2), operands);
5365     }
5366   return "";
5367 }
5368
5369 void
5370 avr_output_bld (operands, bit_nr)
5371      rtx operands[];
5372      int bit_nr;
5373 {
5374   static char s[] = "bld %A0,0";
5375
5376   s[5] = 'A' + (bit_nr >> 3);
5377   s[8] = '0' + (bit_nr & 7);
5378   output_asm_insn (s, operands);
5379 }
5380
5381 void
5382 avr_output_addr_vec_elt (stream, value)
5383      FILE *stream;
5384      int value;
5385 {
5386   if (AVR_MEGA)
5387     fprintf (stream, "\t.word pm(.L%d)\n", value);
5388   else
5389     fprintf (stream, "\trjmp .L%d\n", value);
5390
5391   jump_tables_size++;
5392 }
5393
5394 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5395    registers (for a define_peephole2) in the current function.  */
5396
5397 int
5398 avr_peep2_scratch_safe (scratch)
5399      rtx scratch;
5400 {
5401   if ((interrupt_function_p (current_function_decl)
5402        || signal_function_p (current_function_decl))
5403       && leaf_function_p ())
5404     {
5405       int first_reg = true_regnum (scratch);
5406       int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5407       int reg;
5408
5409       for (reg = first_reg; reg <= last_reg; reg++)
5410         {
5411           if (!regs_ever_live[reg])
5412             return 0;
5413         }
5414     }
5415   return 1;
5416 }