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