OSDN Git Service

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