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