OSDN Git Service

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