OSDN Git Service

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