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