OSDN Git Service

* config/avr/avr.c (avr_option_override): Set
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
3    2009, 2010, 2011 Free Software Foundation, Inc.
4    Contributed by Denis Chertykov (chertykov@gmail.com)
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 3, 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 COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-attr.h"
32 #include "insn-codes.h"
33 #include "flags.h"
34 #include "reload.h"
35 #include "tree.h"
36 #include "output.h"
37 #include "expr.h"
38 #include "diagnostic-core.h"
39 #include "obstack.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "optabs.h"
43 #include "ggc.h"
44 #include "langhooks.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "target-def.h"
48 #include "params.h"
49 #include "df.h"
50
51 /* Maximal allowed offset for an address in the LD command */
52 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
53
54 /* Return true if STR starts with PREFIX and false, otherwise.  */
55 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
56
57 #define AVR_SECTION_PROGMEM (SECTION_MACH_DEP << 0)
58
59 static void avr_option_override (void);
60 static int avr_naked_function_p (tree);
61 static int interrupt_function_p (tree);
62 static int signal_function_p (tree);
63 static int avr_OS_task_function_p (tree);
64 static int avr_OS_main_function_p (tree);
65 static int avr_regs_to_save (HARD_REG_SET *);
66 static int get_sequence_length (rtx insns);
67 static int sequent_regs_live (void);
68 static const char *ptrreg_to_str (int);
69 static const char *cond_string (enum rtx_code);
70 static int avr_num_arg_regs (enum machine_mode, const_tree);
71
72 static rtx avr_legitimize_address (rtx, rtx, enum machine_mode);
73 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
74 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
75 static tree avr_handle_fntype_attribute (tree *, tree, tree, int, bool *);
76 static bool avr_assemble_integer (rtx, unsigned int, int);
77 static void avr_file_start (void);
78 static void avr_file_end (void);
79 static bool avr_legitimate_address_p (enum machine_mode, rtx, bool);
80 static void avr_asm_function_end_prologue (FILE *);
81 static void avr_asm_function_begin_epilogue (FILE *);
82 static bool avr_cannot_modify_jumps_p (void);
83 static rtx avr_function_value (const_tree, const_tree, bool);
84 static rtx avr_libcall_value (enum machine_mode, const_rtx);
85 static bool avr_function_value_regno_p (const unsigned int);
86 static void avr_insert_attributes (tree, tree *);
87 static void avr_asm_init_sections (void);
88 static unsigned int avr_section_type_flags (tree, const char *, int);
89
90 static void avr_reorg (void);
91 static void avr_asm_out_ctor (rtx, int);
92 static void avr_asm_out_dtor (rtx, int);
93 static int avr_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
94 static int avr_memory_move_cost (enum machine_mode, reg_class_t, bool);
95 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
96                                  int, bool);
97 static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
98 static int avr_address_cost (rtx, bool);
99 static bool avr_return_in_memory (const_tree, const_tree);
100 static struct machine_function * avr_init_machine_status (void);
101 static void avr_init_builtins (void);
102 static rtx avr_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
103 static rtx avr_builtin_setjmp_frame_value (void);
104 static bool avr_hard_regno_scratch_ok (unsigned int);
105 static unsigned int avr_case_values_threshold (void);
106 static bool avr_frame_pointer_required_p (void);
107 static bool avr_can_eliminate (const int, const int);
108 static bool avr_class_likely_spilled_p (reg_class_t c);
109 static rtx avr_function_arg (cumulative_args_t , enum machine_mode,
110                              const_tree, bool);
111 static void avr_function_arg_advance (cumulative_args_t, enum machine_mode,
112                                       const_tree, bool);
113 static bool avr_function_ok_for_sibcall (tree, tree);
114 static void avr_asm_named_section (const char *name, unsigned int flags, tree decl);
115 static void avr_encode_section_info (tree, rtx, int);
116 static section* avr_asm_function_rodata_section (tree);
117 static section* avr_asm_select_section (tree, int, unsigned HOST_WIDE_INT);
118
119 /* Allocate registers from r25 to r8 for parameters for function calls.  */
120 #define FIRST_CUM_REG 26
121
122 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
123 static GTY(()) rtx tmp_reg_rtx;
124
125 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
126 static GTY(()) rtx zero_reg_rtx;
127
128 /* AVR register names {"r0", "r1", ..., "r31"} */
129 static const char *const avr_regnames[] = REGISTER_NAMES;
130
131 /* Preprocessor macros to define depending on MCU type.  */
132 const char *avr_extra_arch_macro;
133
134 /* Current architecture.  */
135 const struct base_arch_s *avr_current_arch;
136
137 /* Current device.  */
138 const struct mcu_type_s *avr_current_device;
139
140 /* Section to put switch tables in.  */
141 static GTY(()) section *progmem_swtable_section;
142
143 /* Unnamed section associated to __attribute__((progmem)) aka. PROGMEM.  */
144 static GTY(()) section *progmem_section;
145
146 /* To track if code will use .bss and/or .data.  */
147 bool avr_need_clear_bss_p = false;
148 bool avr_need_copy_data_p = false;
149
150 /* AVR attributes.  */
151 static const struct attribute_spec avr_attribute_table[] =
152 {
153   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
154        affects_type_identity } */
155   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute,
156     false },
157   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute,
158     false },
159   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
160     false },
161   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
162     false },
163   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
164     false },
165   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
166     false },
167   { NULL,        0, 0, false, false, false, NULL, false }
168 };
169 \f
170 /* Initialize the GCC target structure.  */
171 #undef TARGET_ASM_ALIGNED_HI_OP
172 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
173 #undef TARGET_ASM_ALIGNED_SI_OP
174 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
175 #undef TARGET_ASM_UNALIGNED_HI_OP
176 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
177 #undef TARGET_ASM_UNALIGNED_SI_OP
178 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
179 #undef TARGET_ASM_INTEGER
180 #define TARGET_ASM_INTEGER avr_assemble_integer
181 #undef TARGET_ASM_FILE_START
182 #define TARGET_ASM_FILE_START avr_file_start
183 #undef TARGET_ASM_FILE_END
184 #define TARGET_ASM_FILE_END avr_file_end
185
186 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
187 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
188 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
189 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
190
191 #undef TARGET_FUNCTION_VALUE
192 #define TARGET_FUNCTION_VALUE avr_function_value
193 #undef TARGET_LIBCALL_VALUE
194 #define TARGET_LIBCALL_VALUE avr_libcall_value
195 #undef TARGET_FUNCTION_VALUE_REGNO_P
196 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
197
198 #undef TARGET_ATTRIBUTE_TABLE
199 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
200 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
201 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
202 #undef TARGET_INSERT_ATTRIBUTES
203 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
204 #undef TARGET_SECTION_TYPE_FLAGS
205 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
206
207 #undef TARGET_ASM_NAMED_SECTION
208 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
209 #undef TARGET_ASM_INIT_SECTIONS
210 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
211 #undef TARGET_ENCODE_SECTION_INFO
212 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
213 #undef TARGET_ASM_SELECT_SECTION
214 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
215
216 #undef TARGET_REGISTER_MOVE_COST
217 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
218 #undef TARGET_MEMORY_MOVE_COST
219 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
220 #undef TARGET_RTX_COSTS
221 #define TARGET_RTX_COSTS avr_rtx_costs
222 #undef TARGET_ADDRESS_COST
223 #define TARGET_ADDRESS_COST avr_address_cost
224 #undef TARGET_MACHINE_DEPENDENT_REORG
225 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
226 #undef TARGET_FUNCTION_ARG
227 #define TARGET_FUNCTION_ARG avr_function_arg
228 #undef TARGET_FUNCTION_ARG_ADVANCE
229 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
230
231 #undef TARGET_LEGITIMIZE_ADDRESS
232 #define TARGET_LEGITIMIZE_ADDRESS avr_legitimize_address
233
234 #undef TARGET_RETURN_IN_MEMORY
235 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
236
237 #undef TARGET_STRICT_ARGUMENT_NAMING
238 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
239
240 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
241 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
242
243 #undef TARGET_HARD_REGNO_SCRATCH_OK
244 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
245 #undef TARGET_CASE_VALUES_THRESHOLD
246 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
247
248 #undef TARGET_LEGITIMATE_ADDRESS_P
249 #define TARGET_LEGITIMATE_ADDRESS_P avr_legitimate_address_p
250
251 #undef TARGET_FRAME_POINTER_REQUIRED
252 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
253 #undef TARGET_CAN_ELIMINATE
254 #define TARGET_CAN_ELIMINATE avr_can_eliminate
255
256 #undef TARGET_CLASS_LIKELY_SPILLED_P
257 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
258
259 #undef TARGET_OPTION_OVERRIDE
260 #define TARGET_OPTION_OVERRIDE avr_option_override
261
262 #undef TARGET_CANNOT_MODIFY_JUMPS_P
263 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
264
265 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
266 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
267
268 #undef TARGET_INIT_BUILTINS
269 #define TARGET_INIT_BUILTINS avr_init_builtins
270
271 #undef TARGET_EXPAND_BUILTIN
272 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
273
274 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
275 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
276
277 struct gcc_target targetm = TARGET_INITIALIZER;
278 \f
279
280 /* Custom function to replace string prefix.
281
282    Return a ggc-allocated string with strlen (OLD_PREFIX) characters removed
283    from the start of OLD_STR and then prepended with NEW_PREFIX.  */
284
285 static inline const char*
286 avr_replace_prefix (const char *old_str,
287                     const char *old_prefix, const char *new_prefix)
288 {
289   char *new_str;
290   size_t len = strlen (old_str) + strlen (new_prefix) - strlen (old_prefix);
291
292   gcc_assert (strlen (old_prefix) <= strlen (old_str));
293
294   /* Unfortunately, ggc_alloc_string returns a const char* and thus cannot be
295      used here.  */
296      
297   new_str = (char*) ggc_alloc_atomic (1 + len);
298
299   strcat (stpcpy (new_str, new_prefix), old_str + strlen (old_prefix));
300   
301   return (const char*) new_str;
302 }
303
304
305 /* Custom function to count number of set bits.  */
306
307 static inline int
308 avr_popcount (unsigned int val)
309 {
310   int pop = 0;
311
312   while (val)
313     {
314       val &= val-1;
315       pop++;
316     }
317
318   return pop;
319 }
320
321
322 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
323    Return true if the least significant N_BYTES bytes of XVAL all have a
324    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
325    of integers which contains an integer N iff bit N of POP_MASK is set.  */
326    
327 bool
328 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
329 {
330   int i;
331
332   enum machine_mode mode = GET_MODE (xval);
333
334   if (VOIDmode == mode)
335     mode = SImode;
336
337   for (i = 0; i < n_bytes; i++)
338     {
339       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
340       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
341
342       if (0 == (pop_mask & (1 << avr_popcount (val8))))
343         return false;
344     }
345
346   return true;
347 }
348
349 static void
350 avr_option_override (void)
351 {
352   flag_delete_null_pointer_checks = 0;
353
354   /* Unwind tables currently require a frame pointer for correctness,
355      see toplev.c:process_options().  */
356
357   if ((flag_unwind_tables
358        || flag_non_call_exceptions
359        || flag_asynchronous_unwind_tables)
360       && !ACCUMULATE_OUTGOING_ARGS)
361     {
362       flag_omit_frame_pointer = 0;
363     }
364   else
365     {
366       flag_omit_frame_pointer = (optimize >= 1);
367     }
368
369   avr_current_device = &avr_mcu_types[avr_mcu_index];
370   avr_current_arch = &avr_arch_types[avr_current_device->arch];
371   avr_extra_arch_macro = avr_current_device->macro;
372
373   tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
374   zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
375
376   init_machine_status = avr_init_machine_status;
377
378   avr_log_set_avr_log();
379 }
380
381 /* Function to set up the backend function structure.  */
382
383 static struct machine_function *
384 avr_init_machine_status (void)
385 {
386   return ggc_alloc_cleared_machine_function ();
387 }
388
389 /* Return register class for register R.  */
390
391 enum reg_class
392 avr_regno_reg_class (int r)
393 {
394   static const enum reg_class reg_class_tab[] =
395     {
396       R0_REG,
397       /* r1 - r15 */
398       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
399       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
400       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
401       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
402       /* r16 - r23 */
403       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
404       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
405       /* r24, r25 */
406       ADDW_REGS, ADDW_REGS,
407       /* X: r26, 27 */
408       POINTER_X_REGS, POINTER_X_REGS,
409       /* Y: r28, r29 */
410       POINTER_Y_REGS, POINTER_Y_REGS,
411       /* Z: r30, r31 */
412       POINTER_Z_REGS, POINTER_Z_REGS,
413       /* SP: SPL, SPH */
414       STACK_REG, STACK_REG
415     };
416
417   if (r <= 33)
418     return reg_class_tab[r];
419   
420   return ALL_REGS;
421 }
422
423 /* A helper for the subsequent function attribute used to dig for
424    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
425
426 static inline int
427 avr_lookup_function_attribute1 (const_tree func, const char *name)
428 {
429   if (FUNCTION_DECL == TREE_CODE (func))
430     {
431       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
432         {
433           return true;
434         }
435       
436       func = TREE_TYPE (func);
437     }
438
439   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
440               || TREE_CODE (func) == METHOD_TYPE);
441   
442   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
443 }
444
445 /* Return nonzero if FUNC is a naked function.  */
446
447 static int
448 avr_naked_function_p (tree func)
449 {
450   return avr_lookup_function_attribute1 (func, "naked");
451 }
452
453 /* Return nonzero if FUNC is an interrupt function as specified
454    by the "interrupt" attribute.  */
455
456 static int
457 interrupt_function_p (tree func)
458 {
459   return avr_lookup_function_attribute1 (func, "interrupt");
460 }
461
462 /* Return nonzero if FUNC is a signal function as specified
463    by the "signal" attribute.  */
464
465 static int
466 signal_function_p (tree func)
467 {
468   return avr_lookup_function_attribute1 (func, "signal");
469 }
470
471 /* Return nonzero if FUNC is an OS_task function.  */
472
473 static int
474 avr_OS_task_function_p (tree func)
475 {
476   return avr_lookup_function_attribute1 (func, "OS_task");
477 }
478
479 /* Return nonzero if FUNC is an OS_main function.  */
480
481 static int
482 avr_OS_main_function_p (tree func)
483 {
484   return avr_lookup_function_attribute1 (func, "OS_main");
485 }
486
487 /* Return the number of hard registers to push/pop in the prologue/epilogue
488    of the current function, and optionally store these registers in SET.  */
489
490 static int
491 avr_regs_to_save (HARD_REG_SET *set)
492 {
493   int reg, count;
494   int int_or_sig_p = (interrupt_function_p (current_function_decl)
495                       || signal_function_p (current_function_decl));
496
497   if (set)
498     CLEAR_HARD_REG_SET (*set);
499   count = 0;
500
501   /* No need to save any registers if the function never returns or 
502      has the "OS_task" or "OS_main" attribute.  */
503   if (TREE_THIS_VOLATILE (current_function_decl)
504       || cfun->machine->is_OS_task
505       || cfun->machine->is_OS_main)
506     return 0;
507
508   for (reg = 0; reg < 32; reg++)
509     {
510       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
511          any global register variables.  */
512       if (fixed_regs[reg])
513         continue;
514
515       if ((int_or_sig_p && !current_function_is_leaf && call_used_regs[reg])
516           || (df_regs_ever_live_p (reg)
517               && (int_or_sig_p || !call_used_regs[reg])
518               && !(frame_pointer_needed
519                    && (reg == REG_Y || reg == (REG_Y+1)))))
520         {
521           if (set)
522             SET_HARD_REG_BIT (*set, reg);
523           count++;
524         }
525     }
526   return count;
527 }
528
529 /* Return true if register FROM can be eliminated via register TO.  */
530
531 bool
532 avr_can_eliminate (const int from, const int to)
533 {
534   return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
535           || ((from == FRAME_POINTER_REGNUM 
536                || from == FRAME_POINTER_REGNUM + 1)
537               && !frame_pointer_needed));
538 }
539
540 /* Compute offset between arg_pointer and frame_pointer.  */
541
542 int
543 avr_initial_elimination_offset (int from, int to)
544 {
545   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
546     return 0;
547   else
548     {
549       int offset = frame_pointer_needed ? 2 : 0;
550       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
551
552       offset += avr_regs_to_save (NULL);
553       return get_frame_size () + (avr_pc_size) + 1 + offset;
554     }
555 }
556
557 /* Actual start of frame is virtual_stack_vars_rtx this is offset from 
558    frame pointer by +STARTING_FRAME_OFFSET.
559    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
560    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
561
562 rtx avr_builtin_setjmp_frame_value (void)
563 {
564   return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx, 
565                          gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
566 }
567
568 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3 byte PC).
569    This is return address of function.  */
570 rtx 
571 avr_return_addr_rtx (int count, rtx tem)
572 {
573   rtx r;
574     
575   /* Can only return this function's return address. Others not supported.  */
576   if (count)
577      return NULL;
578
579   if (AVR_3_BYTE_PC)
580     {
581       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
582       warning (0, "'builtin_return_address' contains only 2 bytes of address");
583     }
584   else
585     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
586
587   r = gen_rtx_PLUS (Pmode, tem, r);
588   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
589   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
590   return  r;
591 }
592
593 /* Return 1 if the function epilogue is just a single "ret".  */
594
595 int
596 avr_simple_epilogue (void)
597 {
598   return (! frame_pointer_needed
599           && get_frame_size () == 0
600           && avr_regs_to_save (NULL) == 0
601           && ! interrupt_function_p (current_function_decl)
602           && ! signal_function_p (current_function_decl)
603           && ! avr_naked_function_p (current_function_decl)
604           && ! TREE_THIS_VOLATILE (current_function_decl));
605 }
606
607 /* This function checks sequence of live registers.  */
608
609 static int
610 sequent_regs_live (void)
611 {
612   int reg;
613   int live_seq=0;
614   int cur_seq=0;
615
616   for (reg = 0; reg < 18; ++reg)
617     {
618       if (fixed_regs[reg])
619         {
620           /* Don't recognize sequences that contain global register
621              variables.  */
622       
623           if (live_seq != 0)
624             return 0;
625           else
626             continue;
627         }
628       
629       if (!call_used_regs[reg])
630         {
631           if (df_regs_ever_live_p (reg))
632             {
633               ++live_seq;
634               ++cur_seq;
635             }
636           else
637             cur_seq = 0;
638         }
639     }
640
641   if (!frame_pointer_needed)
642     {
643       if (df_regs_ever_live_p (REG_Y))
644         {
645           ++live_seq;
646           ++cur_seq;
647         }
648       else
649         cur_seq = 0;
650
651       if (df_regs_ever_live_p (REG_Y+1))
652         {
653           ++live_seq;
654           ++cur_seq;
655         }
656       else
657         cur_seq = 0;
658     }
659   else
660     {
661       cur_seq += 2;
662       live_seq += 2;
663     }
664   return (cur_seq == live_seq) ? live_seq : 0;
665 }
666
667 /* Obtain the length sequence of insns.  */
668
669 int
670 get_sequence_length (rtx insns)
671 {
672   rtx insn;
673   int length;
674   
675   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
676     length += get_attr_length (insn);
677                 
678   return length;
679 }
680
681 /*  Implement INCOMING_RETURN_ADDR_RTX.  */
682
683 rtx
684 avr_incoming_return_addr_rtx (void)
685 {
686   /* The return address is at the top of the stack.  Note that the push
687      was via post-decrement, which means the actual address is off by one.  */
688   return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
689 }
690
691 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
692
693 static void
694 emit_push_byte (unsigned regno, bool frame_related_p)
695 {
696   rtx mem, reg, insn;
697
698   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
699   mem = gen_frame_mem (QImode, mem);
700   reg = gen_rtx_REG (QImode, regno);
701
702   insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
703   if (frame_related_p)
704     RTX_FRAME_RELATED_P (insn) = 1;
705
706   cfun->machine->stack_usage++;
707 }
708
709
710 /*  Output function prologue.  */
711
712 void
713 expand_prologue (void)
714 {
715   int live_seq;
716   HARD_REG_SET set;
717   int minimize;
718   HOST_WIDE_INT size = get_frame_size();
719   rtx insn;
720   
721   /* Init cfun->machine.  */
722   cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
723   cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
724   cfun->machine->is_signal = signal_function_p (current_function_decl);
725   cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
726   cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
727   cfun->machine->stack_usage = 0;
728   
729   /* Prologue: naked.  */
730   if (cfun->machine->is_naked)
731     {
732       return;
733     }
734
735   avr_regs_to_save (&set);
736   live_seq = sequent_regs_live ();
737   minimize = (TARGET_CALL_PROLOGUES
738               && !cfun->machine->is_interrupt
739               && !cfun->machine->is_signal
740               && !cfun->machine->is_OS_task
741               && !cfun->machine->is_OS_main
742               && live_seq);
743
744   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
745     {
746       /* Enable interrupts.  */
747       if (cfun->machine->is_interrupt)
748         emit_insn (gen_enable_interrupt ());
749         
750       /* Push zero reg.  */
751       emit_push_byte (ZERO_REGNO, true);
752
753       /* Push tmp reg.  */
754       emit_push_byte (TMP_REGNO, true);
755
756       /* Push SREG.  */
757       /* ??? There's no dwarf2 column reserved for SREG.  */
758       emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
759       emit_push_byte (TMP_REGNO, false);
760
761       /* Push RAMPZ.  */
762       /* ??? There's no dwarf2 column reserved for RAMPZ.  */
763       if (AVR_HAVE_RAMPZ 
764           && TEST_HARD_REG_BIT (set, REG_Z)
765           && TEST_HARD_REG_BIT (set, REG_Z + 1))
766         {
767           emit_move_insn (tmp_reg_rtx,
768                           gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
769           emit_push_byte (TMP_REGNO, false);
770         }
771         
772       /* Clear zero reg.  */
773       emit_move_insn (zero_reg_rtx, const0_rtx);
774
775       /* Prevent any attempt to delete the setting of ZERO_REG!  */
776       emit_use (zero_reg_rtx);
777     }
778   if (minimize && (frame_pointer_needed 
779                    || (AVR_2_BYTE_PC && live_seq > 6)
780                    || live_seq > 7)) 
781     {
782       int first_reg, reg, offset;
783
784       emit_move_insn (gen_rtx_REG (HImode, REG_X), 
785                       gen_int_mode (size, HImode));
786
787       insn = emit_insn (gen_call_prologue_saves
788                         (gen_int_mode (live_seq, HImode),
789                          gen_int_mode (size + live_seq, HImode)));
790       RTX_FRAME_RELATED_P (insn) = 1;
791
792       /* Describe the effect of the unspec_volatile call to prologue_saves.
793          Note that this formulation assumes that add_reg_note pushes the
794          notes to the front.  Thus we build them in the reverse order of
795          how we want dwarf2out to process them.  */
796
797       /* The function does always set frame_pointer_rtx, but whether that
798          is going to be permanent in the function is frame_pointer_needed.  */
799       add_reg_note (insn, REG_CFA_ADJUST_CFA,
800                     gen_rtx_SET (VOIDmode,
801                                  (frame_pointer_needed
802                                   ? frame_pointer_rtx : stack_pointer_rtx),
803                                  plus_constant (stack_pointer_rtx,
804                                                 -(size + live_seq))));
805
806       /* Note that live_seq always contains r28+r29, but the other
807          registers to be saved are all below 18.  */
808       first_reg = 18 - (live_seq - 2);
809
810       for (reg = 29, offset = -live_seq + 1;
811            reg >= first_reg;
812            reg = (reg == 28 ? 17 : reg - 1), ++offset)
813         {
814           rtx m, r;
815
816           m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
817           r = gen_rtx_REG (QImode, reg);
818           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
819         }
820
821       cfun->machine->stack_usage += size + live_seq;
822     }
823   else
824     {
825       int reg;
826       for (reg = 0; reg < 32; ++reg)
827         if (TEST_HARD_REG_BIT (set, reg))
828           emit_push_byte (reg, true);
829
830       if (frame_pointer_needed)
831         {
832           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
833             {
834               /* Push frame pointer.  Always be consistent about the
835                  ordering of pushes -- epilogue_restores expects the
836                  register pair to be pushed low byte first.  */
837               emit_push_byte (REG_Y, true);
838               emit_push_byte (REG_Y + 1, true);
839             }
840
841           if (!size)
842             {
843               insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
844               RTX_FRAME_RELATED_P (insn) = 1;
845             }
846           else
847             {
848               /*  Creating a frame can be done by direct manipulation of the
849                   stack or via the frame pointer. These two methods are:
850                     fp=sp
851                     fp-=size
852                     sp=fp
853                   OR
854                     sp-=size
855                     fp=sp
856               the optimum method depends on function type, stack and frame size.
857               To avoid a complex logic, both methods are tested and shortest
858               is selected.  */
859               rtx myfp;
860               rtx fp_plus_insns; 
861
862               if (AVR_HAVE_8BIT_SP)
863                 {
864                   /* The high byte (r29) doesn't change.  Prefer 'subi'
865                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
866                   myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
867                 }
868               else 
869                 {
870                   /*  Normal sized addition.  */
871                   myfp = frame_pointer_rtx;
872                 }
873
874               /* Method 1-Adjust frame pointer.  */
875               start_sequence ();
876
877               /* Normally the dwarf2out frame-related-expr interpreter does
878                  not expect to have the CFA change once the frame pointer is
879                  set up.  Thus we avoid marking the move insn below and
880                  instead indicate that the entire operation is complete after
881                  the frame pointer subtraction is done.  */
882
883               emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
884
885               insn = emit_move_insn (myfp, plus_constant (myfp, -size));
886               RTX_FRAME_RELATED_P (insn) = 1;
887               add_reg_note (insn, REG_CFA_ADJUST_CFA,
888                             gen_rtx_SET (VOIDmode, frame_pointer_rtx,
889                                          plus_constant (stack_pointer_rtx,
890                                                         -size)));
891
892               /* Copy to stack pointer.  Note that since we've already
893                  changed the CFA to the frame pointer this operation
894                  need not be annotated at all.  */
895               if (AVR_HAVE_8BIT_SP)
896                 {
897                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
898                 }
899               else if (TARGET_NO_INTERRUPTS 
900                        || cfun->machine->is_signal
901                        || cfun->machine->is_OS_main)
902                 {
903                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
904                                                      frame_pointer_rtx));
905                 }
906               else if (cfun->machine->is_interrupt)
907                 {
908                   emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
909                                                     frame_pointer_rtx));
910                 }
911               else
912                 {
913                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
914                 }
915
916               fp_plus_insns = get_insns ();
917               end_sequence ();
918
919               /* Method 2-Adjust Stack pointer.  */
920               if (size <= 6)
921                 {
922                   rtx sp_plus_insns;
923
924                   start_sequence ();
925
926                   insn = plus_constant (stack_pointer_rtx, -size);
927                   insn = emit_move_insn (stack_pointer_rtx, insn);
928                   RTX_FRAME_RELATED_P (insn) = 1;
929                   
930                   insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
931                   RTX_FRAME_RELATED_P (insn) = 1;
932
933                   sp_plus_insns = get_insns ();
934                   end_sequence ();
935
936                   /* Use shortest method.  */
937                   if (get_sequence_length (sp_plus_insns) 
938                       < get_sequence_length (fp_plus_insns))
939                     emit_insn (sp_plus_insns);
940                   else
941                     emit_insn (fp_plus_insns);
942                 }
943               else
944                 emit_insn (fp_plus_insns);
945
946               cfun->machine->stack_usage += size;
947             }
948         }
949     }
950
951   if (flag_stack_usage_info)
952     current_function_static_stack_size = cfun->machine->stack_usage;
953 }
954
955 /* Output summary at end of function prologue.  */
956
957 static void
958 avr_asm_function_end_prologue (FILE *file)
959 {
960   if (cfun->machine->is_naked)
961     {
962       fputs ("/* prologue: naked */\n", file);
963     }
964   else
965     {
966       if (cfun->machine->is_interrupt)
967         {
968           fputs ("/* prologue: Interrupt */\n", file);
969         }
970       else if (cfun->machine->is_signal)
971         {
972           fputs ("/* prologue: Signal */\n", file);
973         }
974       else
975         fputs ("/* prologue: function */\n", file);
976     }
977   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
978                  get_frame_size());
979   fprintf (file, "/* stack size = %d */\n",
980                  cfun->machine->stack_usage);
981   /* Create symbol stack offset here so all functions have it. Add 1 to stack
982      usage for offset so that SP + .L__stack_offset = return address.  */
983   fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
984 }
985
986
987 /* Implement EPILOGUE_USES.  */
988
989 int
990 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
991 {
992   if (reload_completed 
993       && cfun->machine
994       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
995     return 1;
996   return 0;
997 }
998
999 /*  Helper for expand_epilogue.  Emit a pop of a byte register.  */
1000
1001 static void
1002 emit_pop_byte (unsigned regno)
1003 {
1004   rtx mem, reg;
1005
1006   mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1007   mem = gen_frame_mem (QImode, mem);
1008   reg = gen_rtx_REG (QImode, regno);
1009
1010   emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
1011 }
1012
1013 /*  Output RTL epilogue.  */
1014
1015 void
1016 expand_epilogue (bool sibcall_p)
1017 {
1018   int reg;
1019   int live_seq;
1020   HARD_REG_SET set;      
1021   int minimize;
1022   HOST_WIDE_INT size = get_frame_size();
1023   
1024   /* epilogue: naked  */
1025   if (cfun->machine->is_naked)
1026     {
1027       gcc_assert (!sibcall_p);
1028       
1029       emit_jump_insn (gen_return ());
1030       return;
1031     }
1032
1033   avr_regs_to_save (&set);
1034   live_seq = sequent_regs_live ();
1035   minimize = (TARGET_CALL_PROLOGUES
1036               && !cfun->machine->is_interrupt
1037               && !cfun->machine->is_signal
1038               && !cfun->machine->is_OS_task
1039               && !cfun->machine->is_OS_main
1040               && live_seq);
1041   
1042   if (minimize && (frame_pointer_needed || live_seq > 4))
1043     {
1044       if (frame_pointer_needed)
1045         {
1046           /*  Get rid of frame.  */
1047           emit_move_insn(frame_pointer_rtx,
1048                          gen_rtx_PLUS (HImode, frame_pointer_rtx,
1049                                        gen_int_mode (size, HImode)));
1050         }
1051       else
1052         {
1053           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1054         }
1055         
1056       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1057     }
1058   else
1059     {
1060       if (frame_pointer_needed)
1061         {
1062           if (size)
1063             {
1064               /* Try two methods to adjust stack and select shortest.  */
1065               rtx myfp;
1066               rtx fp_plus_insns;
1067
1068               if (AVR_HAVE_8BIT_SP)
1069                 {
1070                   /* The high byte (r29) doesn't change - prefer 'subi' 
1071                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
1072                   myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
1073                 }
1074               else 
1075                 {
1076                   /* Normal sized addition.  */
1077                   myfp = frame_pointer_rtx;
1078                 }
1079               
1080               /* Method 1-Adjust frame pointer.  */
1081               start_sequence ();
1082
1083               emit_move_insn (myfp, plus_constant (myfp, size));
1084
1085               /* Copy to stack pointer.  */
1086               if (AVR_HAVE_8BIT_SP)
1087                 {
1088                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1089                 }
1090               else if (TARGET_NO_INTERRUPTS 
1091                        || cfun->machine->is_signal)
1092                 {
1093                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
1094                                                      frame_pointer_rtx));
1095                 }
1096               else if (cfun->machine->is_interrupt)
1097                 {
1098                   emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
1099                                                     frame_pointer_rtx));
1100                 }
1101               else
1102                 {
1103                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1104                 }
1105
1106               fp_plus_insns = get_insns ();
1107               end_sequence ();        
1108
1109               /* Method 2-Adjust Stack pointer.  */
1110               if (size <= 5)
1111                 {
1112                   rtx sp_plus_insns;
1113
1114                   start_sequence ();
1115
1116                   emit_move_insn (stack_pointer_rtx,
1117                                   plus_constant (stack_pointer_rtx, size));
1118
1119                   sp_plus_insns = get_insns ();
1120                   end_sequence ();
1121
1122                   /* Use shortest method.  */
1123                   if (get_sequence_length (sp_plus_insns) 
1124                       < get_sequence_length (fp_plus_insns))
1125                     emit_insn (sp_plus_insns);
1126                   else
1127                     emit_insn (fp_plus_insns);
1128                 }
1129               else
1130                 emit_insn (fp_plus_insns);
1131             }
1132           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1133             {
1134               /* Restore previous frame_pointer.  See expand_prologue for
1135                  rationale for not using pophi.  */
1136               emit_pop_byte (REG_Y + 1);
1137               emit_pop_byte (REG_Y);
1138             }
1139         }
1140
1141       /* Restore used registers.  */
1142       for (reg = 31; reg >= 0; --reg)
1143         if (TEST_HARD_REG_BIT (set, reg))
1144           emit_pop_byte (reg);
1145
1146       if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1147         {
1148           /* Restore RAMPZ using tmp reg as scratch.  */
1149           if (AVR_HAVE_RAMPZ 
1150               && TEST_HARD_REG_BIT (set, REG_Z)
1151               && TEST_HARD_REG_BIT (set, REG_Z + 1))
1152             {
1153               emit_pop_byte (TMP_REGNO);
1154               emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)), 
1155                               tmp_reg_rtx);
1156             }
1157
1158           /* Restore SREG using tmp reg as scratch.  */
1159           emit_pop_byte (TMP_REGNO);
1160       
1161           emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)), 
1162                           tmp_reg_rtx);
1163
1164           /* Restore tmp REG.  */
1165           emit_pop_byte (TMP_REGNO);
1166
1167           /* Restore zero REG.  */
1168           emit_pop_byte (ZERO_REGNO);
1169         }
1170
1171       if (!sibcall_p)
1172         emit_jump_insn (gen_return ());
1173     }
1174 }
1175
1176 /* Output summary messages at beginning of function epilogue.  */
1177
1178 static void
1179 avr_asm_function_begin_epilogue (FILE *file)
1180 {
1181   fprintf (file, "/* epilogue start */\n");
1182 }
1183
1184
1185 /* Implement TARGET_CANNOT_MODITY_JUMPS_P */
1186
1187 static bool
1188 avr_cannot_modify_jumps_p (void)
1189 {
1190
1191   /* Naked Functions must not have any instructions after
1192      their epilogue, see PR42240 */
1193      
1194   if (reload_completed
1195       && cfun->machine
1196       && cfun->machine->is_naked)
1197     {
1198       return true;
1199     }
1200
1201   return false;
1202 }
1203
1204
1205 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1206    machine for a memory operand of mode MODE.  */
1207
1208 bool
1209 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1210 {
1211   reg_class_t r = NO_REGS;
1212   
1213   if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
1214                     : REG_OK_FOR_BASE_NOSTRICT_P (x)))
1215     r = POINTER_REGS;
1216   else if (CONSTANT_ADDRESS_P (x))
1217     r = ALL_REGS;
1218   else if (GET_CODE (x) == PLUS
1219            && REG_P (XEXP (x, 0))
1220            && GET_CODE (XEXP (x, 1)) == CONST_INT
1221            && INTVAL (XEXP (x, 1)) >= 0)
1222     {
1223       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1224       if (fit)
1225         {
1226           if (! strict
1227               || REGNO (XEXP (x,0)) == REG_X
1228               || REGNO (XEXP (x,0)) == REG_Y
1229               || REGNO (XEXP (x,0)) == REG_Z)
1230             r = BASE_POINTER_REGS;
1231           if (XEXP (x,0) == frame_pointer_rtx
1232               || XEXP (x,0) == arg_pointer_rtx)
1233             r = BASE_POINTER_REGS;
1234         }
1235       else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
1236         r = POINTER_Y_REGS;
1237     }
1238   else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
1239            && REG_P (XEXP (x, 0))
1240            && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
1241                : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
1242     {
1243       r = POINTER_REGS;
1244     }
1245
1246   if (avr_log.legitimate_address_p)
1247     {
1248       avr_edump ("\n%?: ret=%d=%R, mode=%m strict=%d "
1249                  "reload_completed=%d reload_in_progress=%d %s:",
1250                  !!r, r, mode, strict, reload_completed, reload_in_progress,
1251                  reg_renumber ? "(reg_renumber)" : "");
1252       
1253       if (GET_CODE (x) == PLUS
1254           && REG_P (XEXP (x, 0))
1255           && CONST_INT_P (XEXP (x, 1))
1256           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1257           && reg_renumber)
1258         {
1259           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1260                      true_regnum (XEXP (x, 0)));
1261         }
1262       
1263       avr_edump ("\n%r\n", x);
1264     }
1265   
1266   return r == NO_REGS ? 0 : (int)r;
1267 }
1268
1269 /* Attempts to replace X with a valid
1270    memory address for an operand of mode MODE  */
1271
1272 rtx
1273 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1274 {
1275   bool big_offset_p = false;
1276   
1277   x = oldx;
1278   
1279   if (GET_CODE (oldx) == PLUS
1280       && REG_P (XEXP (oldx, 0)))
1281     {
1282       if (REG_P (XEXP (oldx, 1)))
1283         x = force_reg (GET_MODE (oldx), oldx);
1284       else if (CONST_INT_P (XEXP (oldx, 1)))
1285         {
1286           int offs = INTVAL (XEXP (oldx, 1));
1287           if (frame_pointer_rtx != XEXP (oldx, 0)
1288               && offs > MAX_LD_OFFSET (mode))
1289             {
1290               big_offset_p = true;
1291               x = force_reg (GET_MODE (oldx), oldx);
1292             }
1293         }
1294     }
1295   
1296   if (avr_log.legitimize_address)
1297     {
1298       avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1299
1300       if (x != oldx)
1301         avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1302     }
1303
1304   return x;
1305 }
1306
1307
1308 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'.  */
1309 /* This will allow register R26/27 to be used where it is no worse than normal
1310    base pointers R28/29 or R30/31.  For example, if base offset is greater
1311    than 63 bytes or for R++ or --R addressing.  */
1312
1313 rtx
1314 avr_legitimize_reload_address (rtx x, enum machine_mode mode,
1315                                int opnum, int type, int addr_type,
1316                                int ind_levels ATTRIBUTE_UNUSED,
1317                                rtx (*mk_memloc)(rtx,int))
1318 {
1319   if (avr_log.legitimize_reload_address)
1320     avr_edump ("\n%?:%m %r\n", mode, x);
1321   
1322   if (1 && (GET_CODE (x) == POST_INC
1323             || GET_CODE (x) == PRE_DEC))
1324     {
1325       push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1326                    POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1327                    opnum, RELOAD_OTHER);
1328       
1329       if (avr_log.legitimize_reload_address)
1330         avr_edump (" RCLASS = %R\n IN = %r\n OUT = %r\n",
1331                    POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1332       
1333       return x;
1334     }
1335   
1336   if (GET_CODE (x) == PLUS
1337       && REG_P (XEXP (x, 0))
1338       && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1339       && CONST_INT_P (XEXP (x, 1))
1340       && INTVAL (XEXP (x, 1)) >= 1)
1341     {
1342       bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1343       
1344       if (fit)
1345         {
1346           if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1347             {
1348               int regno = REGNO (XEXP (x, 0));
1349               rtx mem = mk_memloc (x, regno);
1350               
1351               push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
1352                            POINTER_REGS, Pmode, VOIDmode, 0, 0,
1353                            1, addr_type);
1354               
1355               if (avr_log.legitimize_reload_address)
1356                 avr_edump (" RCLASS = %R\n IN = %r\n OUT = %r\n",
1357                            POINTER_REGS, XEXP (mem, 0), NULL_RTX);
1358               
1359               push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
1360                            BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1361                            opnum, type);
1362               
1363               if (avr_log.legitimize_reload_address)
1364                 avr_edump (" RCLASS = %R\n IN = %r\n OUT = %r\n",
1365                            BASE_POINTER_REGS, mem, NULL_RTX);
1366               
1367               return x;
1368             }
1369         }
1370       else if (! (frame_pointer_needed
1371                   && XEXP (x, 0) == frame_pointer_rtx))
1372         {
1373           push_reload (x, NULL_RTX, &x, NULL,
1374                        POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1375                        opnum, type);
1376           
1377           if (avr_log.legitimize_reload_address)
1378             avr_edump (" RCLASS = %R\n IN = %r\n OUT = %r\n",
1379                        POINTER_REGS, x, NULL_RTX);
1380           
1381           return x;
1382         }
1383     }
1384   
1385   return NULL_RTX;
1386 }
1387
1388
1389 /* Helper function to print assembler resp. track instruction
1390    sequence lengths.
1391    
1392    If PLEN == NULL:
1393        Output assembler code from template TPL with operands supplied
1394        by OPERANDS.  This is just forwarding to output_asm_insn.
1395    
1396    If PLEN != NULL:
1397        If N_WORDS >= 0  Add N_WORDS to *PLEN.
1398        If N_WORDS < 0   Set *PLEN to -N_WORDS.
1399        Don't output anything.
1400 */
1401
1402 static void
1403 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
1404 {
1405   if (NULL == plen)
1406     {
1407       output_asm_insn (tpl, operands);
1408     }
1409   else
1410     {
1411       if (n_words < 0)
1412         *plen = -n_words;
1413       else
1414         *plen += n_words;
1415     }
1416 }
1417
1418
1419 /* Return a pointer register name as a string.  */
1420
1421 static const char *
1422 ptrreg_to_str (int regno)
1423 {
1424   switch (regno)
1425     {
1426     case REG_X: return "X";
1427     case REG_Y: return "Y";
1428     case REG_Z: return "Z";
1429     default:
1430       output_operand_lossage ("address operand requires constraint for X, Y, or Z register");
1431     }
1432   return NULL;
1433 }
1434
1435 /* Return the condition name as a string.
1436    Used in conditional jump constructing  */
1437
1438 static const char *
1439 cond_string (enum rtx_code code)
1440 {
1441   switch (code)
1442     {
1443     case NE:
1444       return "ne";
1445     case EQ:
1446       return "eq";
1447     case GE:
1448       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1449         return "pl";
1450       else
1451         return "ge";
1452     case LT:
1453       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1454         return "mi";
1455       else
1456         return "lt";
1457     case GEU:
1458       return "sh";
1459     case LTU:
1460       return "lo";
1461     default:
1462       gcc_unreachable ();
1463     }
1464 }
1465
1466 /* Output ADDR to FILE as address.  */
1467
1468 void
1469 print_operand_address (FILE *file, rtx addr)
1470 {
1471   switch (GET_CODE (addr))
1472     {
1473     case REG:
1474       fprintf (file, ptrreg_to_str (REGNO (addr)));
1475       break;
1476
1477     case PRE_DEC:
1478       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1479       break;
1480
1481     case POST_INC:
1482       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1483       break;
1484
1485     default:
1486       if (CONSTANT_ADDRESS_P (addr)
1487           && text_segment_operand (addr, VOIDmode))
1488         {
1489           rtx x = addr;
1490           if (GET_CODE (x) == CONST)
1491             x = XEXP (x, 0);
1492           if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
1493             {
1494               /* Assembler gs() will implant word address. Make offset 
1495                  a byte offset inside gs() for assembler. This is 
1496                  needed because the more logical (constant+gs(sym)) is not 
1497                  accepted by gas. For 128K and lower devices this is ok. For
1498                  large devices it will create a Trampoline to offset from symbol 
1499                  which may not be what the user really wanted.  */
1500               fprintf (file, "gs(");
1501               output_addr_const (file, XEXP (x,0));
1502               fprintf (file,"+" HOST_WIDE_INT_PRINT_DEC ")", 2 * INTVAL (XEXP (x,1)));
1503               if (AVR_3_BYTE_PC)
1504                 if (warning (0, "pointer offset from symbol maybe incorrect"))
1505                   {
1506                     output_addr_const (stderr, addr);
1507                     fprintf(stderr,"\n");
1508                   }
1509             }
1510           else
1511             {
1512               fprintf (file, "gs(");
1513               output_addr_const (file, addr);
1514               fprintf (file, ")");
1515             }
1516         }
1517       else
1518         output_addr_const (file, addr);
1519     }
1520 }
1521
1522
1523 /* Output X as assembler operand to file FILE.  */
1524      
1525 void
1526 print_operand (FILE *file, rtx x, int code)
1527 {
1528   int abcd = 0;
1529
1530   if (code >= 'A' && code <= 'D')
1531     abcd = code - 'A';
1532
1533   if (code == '~')
1534     {
1535       if (!AVR_HAVE_JMP_CALL)
1536         fputc ('r', file);
1537     }
1538   else if (code == '!')
1539     {
1540       if (AVR_HAVE_EIJMP_EICALL)
1541         fputc ('e', file);
1542     }
1543   else if (REG_P (x))
1544     {
1545       if (x == zero_reg_rtx)
1546         fprintf (file, "__zero_reg__");
1547       else
1548         fprintf (file, reg_names[true_regnum (x) + abcd]);
1549     }
1550   else if (GET_CODE (x) == CONST_INT)
1551     fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1552   else if (GET_CODE (x) == MEM)
1553     {
1554       rtx addr = XEXP (x,0);
1555       if (code == 'm')
1556         {
1557            if (!CONSTANT_P (addr))
1558             fatal_insn ("bad address, not a constant):", addr);
1559           /* Assembler template with m-code is data - not progmem section */
1560           if (text_segment_operand (addr, VOIDmode))
1561             if (warning ( 0, "accessing data memory with program memory address"))
1562               {
1563                 output_addr_const (stderr, addr);
1564                 fprintf(stderr,"\n");
1565               }
1566           output_addr_const (file, addr);
1567         }
1568       else if (code == 'o')
1569         {
1570           if (GET_CODE (addr) != PLUS)
1571             fatal_insn ("bad address, not (reg+disp):", addr);
1572
1573           print_operand (file, XEXP (addr, 1), 0);
1574         }
1575       else if (code == 'p' || code == 'r')
1576         {
1577           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1578             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1579           
1580           if (code == 'p')
1581             print_operand_address (file, XEXP (addr, 0));  /* X, Y, Z */
1582           else
1583             print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
1584         }
1585       else if (GET_CODE (addr) == PLUS)
1586         {
1587           print_operand_address (file, XEXP (addr,0));
1588           if (REGNO (XEXP (addr, 0)) == REG_X)
1589             fatal_insn ("internal compiler error.  Bad address:"
1590                         ,addr);
1591           fputc ('+', file);
1592           print_operand (file, XEXP (addr,1), code);
1593         }
1594       else
1595         print_operand_address (file, addr);
1596     }
1597   else if (code == 'x')
1598     {
1599       /* Constant progmem address - like used in jmp or call */
1600       if (0 == text_segment_operand (x, VOIDmode))
1601             if (warning ( 0, "accessing program  memory with data memory address"))
1602           {
1603             output_addr_const (stderr, x);
1604             fprintf(stderr,"\n");
1605           }
1606       /* Use normal symbol for direct address no linker trampoline needed */
1607       output_addr_const (file, x);
1608     }
1609   else if (GET_CODE (x) == CONST_DOUBLE)
1610     {
1611       long val;
1612       REAL_VALUE_TYPE rv;
1613       if (GET_MODE (x) != SFmode)
1614         fatal_insn ("internal compiler error.  Unknown mode:", x);
1615       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1616       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1617       fprintf (file, "0x%lx", val);
1618     }
1619   else if (code == 'j')
1620     fputs (cond_string (GET_CODE (x)), file);
1621   else if (code == 'k')
1622     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1623   else
1624     print_operand_address (file, x);
1625 }
1626
1627 /* Update the condition code in the INSN.  */
1628
1629 void
1630 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1631 {
1632   rtx set;
1633   
1634   switch (get_attr_cc (insn))
1635     {
1636     case CC_NONE:
1637       /* Insn does not affect CC at all.  */
1638       break;
1639
1640     case CC_SET_N:
1641       CC_STATUS_INIT;
1642       break;
1643
1644     case CC_SET_ZN:
1645       set = single_set (insn);
1646       CC_STATUS_INIT;
1647       if (set)
1648         {
1649           cc_status.flags |= CC_NO_OVERFLOW;
1650           cc_status.value1 = SET_DEST (set);
1651         }
1652       break;
1653
1654     case CC_SET_CZN:
1655       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1656          The V flag may or may not be known but that's ok because
1657          alter_cond will change tests to use EQ/NE.  */
1658       set = single_set (insn);
1659       CC_STATUS_INIT;
1660       if (set)
1661         {
1662           cc_status.value1 = SET_DEST (set);
1663           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1664         }
1665       break;
1666
1667     case CC_COMPARE:
1668       set = single_set (insn);
1669       CC_STATUS_INIT;
1670       if (set)
1671         cc_status.value1 = SET_SRC (set);
1672       break;
1673       
1674     case CC_CLOBBER:
1675       /* Insn doesn't leave CC in a usable state.  */
1676       CC_STATUS_INIT;
1677       break;
1678     }
1679 }
1680
1681 /* Choose mode for jump insn:
1682    1 - relative jump in range -63 <= x <= 62 ;
1683    2 - relative jump in range -2046 <= x <= 2045 ;
1684    3 - absolute jump (only for ATmega[16]03).  */
1685
1686 int
1687 avr_jump_mode (rtx x, rtx insn)
1688 {
1689   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
1690                                             ? XEXP (x, 0) : x));
1691   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1692   int jump_distance = cur_addr - dest_addr;
1693   
1694   if (-63 <= jump_distance && jump_distance <= 62)
1695     return 1;
1696   else if (-2046 <= jump_distance && jump_distance <= 2045)
1697     return 2;
1698   else if (AVR_HAVE_JMP_CALL)
1699     return 3;
1700   
1701   return 2;
1702 }
1703
1704 /* return an AVR condition jump commands.
1705    X is a comparison RTX.
1706    LEN is a number returned by avr_jump_mode function.
1707    if REVERSE nonzero then condition code in X must be reversed.  */
1708
1709 const char *
1710 ret_cond_branch (rtx x, int len, int reverse)
1711 {
1712   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1713   
1714   switch (cond)
1715     {
1716     case GT:
1717       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1718         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1719                             AS1 (brpl,%0)) :
1720                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1721                             AS1 (brmi,.+2) CR_TAB
1722                             AS1 (rjmp,%0)) :
1723                 (AS1 (breq,.+6) CR_TAB
1724                  AS1 (brmi,.+4) CR_TAB
1725                  AS1 (jmp,%0)));
1726           
1727       else
1728         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1729                             AS1 (brge,%0)) :
1730                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1731                             AS1 (brlt,.+2) CR_TAB
1732                             AS1 (rjmp,%0)) :
1733                 (AS1 (breq,.+6) CR_TAB
1734                  AS1 (brlt,.+4) CR_TAB
1735                  AS1 (jmp,%0)));
1736     case GTU:
1737       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1738                           AS1 (brsh,%0)) :
1739               len == 2 ? (AS1 (breq,.+4) CR_TAB
1740                           AS1 (brlo,.+2) CR_TAB
1741                           AS1 (rjmp,%0)) :
1742               (AS1 (breq,.+6) CR_TAB
1743                AS1 (brlo,.+4) CR_TAB
1744                AS1 (jmp,%0)));
1745     case LE:
1746       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1747         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1748                             AS1 (brmi,%0)) :
1749                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1750                             AS1 (brpl,.+2) CR_TAB
1751                             AS1 (rjmp,%0)) :
1752                 (AS1 (breq,.+2) CR_TAB
1753                  AS1 (brpl,.+4) CR_TAB
1754                  AS1 (jmp,%0)));
1755       else
1756         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1757                             AS1 (brlt,%0)) :
1758                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1759                             AS1 (brge,.+2) CR_TAB
1760                             AS1 (rjmp,%0)) :
1761                 (AS1 (breq,.+2) CR_TAB
1762                  AS1 (brge,.+4) CR_TAB
1763                  AS1 (jmp,%0)));
1764     case LEU:
1765       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1766                           AS1 (brlo,%0)) :
1767               len == 2 ? (AS1 (breq,.+2) CR_TAB
1768                           AS1 (brsh,.+2) CR_TAB
1769                           AS1 (rjmp,%0)) :
1770               (AS1 (breq,.+2) CR_TAB
1771                AS1 (brsh,.+4) CR_TAB
1772                AS1 (jmp,%0)));
1773     default:
1774       if (reverse)
1775         {
1776           switch (len)
1777             {
1778             case 1:
1779               return AS1 (br%k1,%0);
1780             case 2:
1781               return (AS1 (br%j1,.+2) CR_TAB
1782                       AS1 (rjmp,%0));
1783             default:
1784               return (AS1 (br%j1,.+4) CR_TAB
1785                       AS1 (jmp,%0));
1786             }
1787         }
1788         else
1789           {
1790             switch (len)
1791               {
1792               case 1:
1793                 return AS1 (br%j1,%0);
1794               case 2:
1795                 return (AS1 (br%k1,.+2) CR_TAB
1796                         AS1 (rjmp,%0));
1797               default:
1798                 return (AS1 (br%k1,.+4) CR_TAB
1799                         AS1 (jmp,%0));
1800               }
1801           }
1802     }
1803   return "";
1804 }
1805
1806 /* Output insn cost for next insn.  */
1807
1808 void
1809 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1810                     int num_operands ATTRIBUTE_UNUSED)
1811 {
1812   if (avr_log.rtx_costs)
1813     {
1814       rtx set = single_set (insn);
1815
1816       if (set)
1817         fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
1818                  set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
1819       else
1820         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
1821                  rtx_cost (PATTERN (insn), INSN, 0,
1822                            optimize_insn_for_speed_p()));
1823     }
1824 }
1825
1826 /* Return 0 if undefined, 1 if always true or always false.  */
1827
1828 int
1829 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
1830 {
1831   unsigned int max = (mode == QImode ? 0xff :
1832                       mode == HImode ? 0xffff :
1833                       mode == SImode ? 0xffffffff : 0);
1834   if (max && op && GET_CODE (x) == CONST_INT)
1835     {
1836       if (unsigned_condition (op) != op)
1837         max >>= 1;
1838
1839       if (max != (INTVAL (x) & max)
1840           && INTVAL (x) != 0xff)
1841         return 1;
1842     }
1843   return 0;
1844 }
1845
1846
1847 /* Returns nonzero if REGNO is the number of a hard
1848    register in which function arguments are sometimes passed.  */
1849
1850 int
1851 function_arg_regno_p(int r)
1852 {
1853   return (r >= 8 && r <= 25);
1854 }
1855
1856 /* Initializing the variable cum for the state at the beginning
1857    of the argument list.  */
1858
1859 void
1860 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1861                       tree fndecl ATTRIBUTE_UNUSED)
1862 {
1863   cum->nregs = 18;
1864   cum->regno = FIRST_CUM_REG;
1865   if (!libname && stdarg_p (fntype))
1866     cum->nregs = 0;
1867
1868   /* Assume the calle may be tail called */
1869   
1870   cfun->machine->sibcall_fails = 0;
1871 }
1872
1873 /* Returns the number of registers to allocate for a function argument.  */
1874
1875 static int
1876 avr_num_arg_regs (enum machine_mode mode, const_tree type)
1877 {
1878   int size;
1879
1880   if (mode == BLKmode)
1881     size = int_size_in_bytes (type);
1882   else
1883     size = GET_MODE_SIZE (mode);
1884
1885   /* Align all function arguments to start in even-numbered registers.
1886      Odd-sized arguments leave holes above them.  */
1887
1888   return (size + 1) & ~1;
1889 }
1890
1891 /* Controls whether a function argument is passed
1892    in a register, and which register.  */
1893
1894 static rtx
1895 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
1896                   const_tree type, bool named ATTRIBUTE_UNUSED)
1897 {
1898   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1899   int bytes = avr_num_arg_regs (mode, type);
1900
1901   if (cum->nregs && bytes <= cum->nregs)
1902     return gen_rtx_REG (mode, cum->regno - bytes);
1903
1904   return NULL_RTX;
1905 }
1906
1907 /* Update the summarizer variable CUM to advance past an argument
1908    in the argument list.  */
1909    
1910 static void
1911 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1912                           const_tree type, bool named ATTRIBUTE_UNUSED)
1913 {
1914   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1915   int bytes = avr_num_arg_regs (mode, type);
1916
1917   cum->nregs -= bytes;
1918   cum->regno -= bytes;
1919
1920   /* A parameter is being passed in a call-saved register. As the original
1921      contents of these regs has to be restored before leaving the function,
1922      a function must not pass arguments in call-saved regs in order to get
1923      tail-called. */
1924   
1925   if (cum->regno >= 8
1926       && cum->nregs >= 0
1927       && !call_used_regs[cum->regno])
1928     {
1929       /* FIXME: We ship info on failing tail-call in struct machine_function.
1930          This uses internals of calls.c:expand_call() and the way args_so_far
1931          is used. targetm.function_ok_for_sibcall() needs to be extended to
1932          pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
1933          dependent so that such an extension is not wanted. */
1934       
1935       cfun->machine->sibcall_fails = 1;
1936     }
1937
1938   /* Test if all registers needed by the ABI are actually available.  If the
1939      user has fixed a GPR needed to pass an argument, an (implicit) function
1940      call will clobber that fixed register.  See PR45099 for an example.  */
1941   
1942   if (cum->regno >= 8
1943       && cum->nregs >= 0)
1944     {
1945       int regno;
1946
1947       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
1948         if (fixed_regs[regno])
1949           warning (0, "fixed register %s used to pass parameter to function",
1950                    reg_names[regno]);
1951     }
1952       
1953   if (cum->nregs <= 0)
1954     {
1955       cum->nregs = 0;
1956       cum->regno = FIRST_CUM_REG;
1957     }
1958 }
1959
1960 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
1961 /* Decide whether we can make a sibling call to a function.  DECL is the
1962    declaration of the function being targeted by the call and EXP is the
1963    CALL_EXPR representing the call. */
1964
1965 static bool
1966 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
1967 {
1968   tree fntype_callee;
1969
1970   /* Tail-calling must fail if callee-saved regs are used to pass
1971      function args.  We must not tail-call when `epilogue_restores'
1972      is used.  Unfortunately, we cannot tell at this point if that
1973      actually will happen or not, and we cannot step back from
1974      tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
1975   
1976   if (cfun->machine->sibcall_fails
1977       || TARGET_CALL_PROLOGUES)
1978     {
1979       return false;
1980     }
1981   
1982   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
1983
1984   if (decl_callee)
1985     {
1986       decl_callee = TREE_TYPE (decl_callee);
1987     }
1988   else
1989     {
1990       decl_callee = fntype_callee;
1991       
1992       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
1993              && METHOD_TYPE != TREE_CODE (decl_callee))
1994         {
1995           decl_callee = TREE_TYPE (decl_callee);
1996         }
1997     }
1998
1999   /* Ensure that caller and callee have compatible epilogues */
2000   
2001   if (interrupt_function_p (current_function_decl)
2002       || signal_function_p (current_function_decl)
2003       || avr_naked_function_p (decl_callee)
2004       || avr_naked_function_p (current_function_decl)
2005       /* FIXME: For OS_task and OS_main, we are over-conservative.
2006          This is due to missing documentation of these attributes
2007          and what they actually should do and should not do. */
2008       || (avr_OS_task_function_p (decl_callee)
2009           != avr_OS_task_function_p (current_function_decl))
2010       || (avr_OS_main_function_p (decl_callee)
2011           != avr_OS_main_function_p (current_function_decl)))
2012     {
2013       return false;
2014     }
2015  
2016   return true;
2017 }
2018
2019 /***********************************************************************
2020   Functions for outputting various mov's for a various modes
2021 ************************************************************************/
2022 const char *
2023 output_movqi (rtx insn, rtx operands[], int *l)
2024 {
2025   int dummy;
2026   rtx dest = operands[0];
2027   rtx src = operands[1];
2028   int *real_l = l;
2029   
2030   if (!l)
2031     l = &dummy;
2032
2033   *l = 1;
2034   
2035   if (register_operand (dest, QImode))
2036     {
2037       if (register_operand (src, QImode)) /* mov r,r */
2038         {
2039           if (test_hard_reg_class (STACK_REG, dest))
2040             return AS2 (out,%0,%1);
2041           else if (test_hard_reg_class (STACK_REG, src))
2042             return AS2 (in,%0,%1);
2043           
2044           return AS2 (mov,%0,%1);
2045         }
2046       else if (CONSTANT_P (src))
2047         {
2048           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2049             return AS2 (ldi,%0,lo8(%1));
2050           
2051           if (GET_CODE (src) == CONST_INT)
2052             {
2053               if (src == const0_rtx) /* mov r,L */
2054                 return AS1 (clr,%0);
2055               else if (src == const1_rtx)
2056                 {
2057                   *l = 2;
2058                   return (AS1 (clr,%0) CR_TAB
2059                           AS1 (inc,%0));
2060                 }
2061               else if (src == constm1_rtx)
2062                 {
2063                   /* Immediate constants -1 to any register */
2064                   *l = 2;
2065                   return (AS1 (clr,%0) CR_TAB
2066                           AS1 (dec,%0));
2067                 }
2068               else
2069                 {
2070                   int bit_nr = exact_log2 (INTVAL (src));
2071
2072                   if (bit_nr >= 0)
2073                     {
2074                       *l = 3;
2075                       if (!real_l)
2076                         output_asm_insn ((AS1 (clr,%0) CR_TAB
2077                                           "set"), operands);
2078                       if (!real_l)
2079                         avr_output_bld (operands, bit_nr);
2080
2081                       return "";
2082                     }
2083                 }
2084             }
2085           
2086           /* Last resort, larger than loading from memory.  */
2087           *l = 4;
2088           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2089                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2090                   AS2 (mov,%0,r31)          CR_TAB
2091                   AS2 (mov,r31,__tmp_reg__));
2092         }
2093       else if (GET_CODE (src) == MEM)
2094         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
2095     }
2096   else if (GET_CODE (dest) == MEM)
2097     {
2098       const char *templ;
2099
2100       if (src == const0_rtx)
2101         operands[1] = zero_reg_rtx;
2102
2103       templ = out_movqi_mr_r (insn, operands, real_l);
2104
2105       if (!real_l)
2106         output_asm_insn (templ, operands);
2107
2108       operands[1] = src;
2109     }
2110   return "";
2111 }
2112
2113
2114 const char *
2115 output_movhi (rtx insn, rtx operands[], int *l)
2116 {
2117   int dummy;
2118   rtx dest = operands[0];
2119   rtx src = operands[1];
2120   int *real_l = l;
2121   
2122   if (!l)
2123     l = &dummy;
2124   
2125   if (register_operand (dest, HImode))
2126     {
2127       if (register_operand (src, HImode)) /* mov r,r */
2128         {
2129           if (test_hard_reg_class (STACK_REG, dest))
2130             {
2131               if (AVR_HAVE_8BIT_SP)
2132                 return *l = 1, AS2 (out,__SP_L__,%A1);
2133               /* Use simple load of stack pointer if no interrupts are 
2134                  used.  */
2135               else if (TARGET_NO_INTERRUPTS)
2136                 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
2137                                 AS2 (out,__SP_L__,%A1));
2138               *l = 5;
2139               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
2140                       "cli"                          CR_TAB
2141                       AS2 (out,__SP_H__,%B1)         CR_TAB
2142                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
2143                       AS2 (out,__SP_L__,%A1));
2144             }
2145           else if (test_hard_reg_class (STACK_REG, src))
2146             {
2147               *l = 2;   
2148               return (AS2 (in,%A0,__SP_L__) CR_TAB
2149                       AS2 (in,%B0,__SP_H__));
2150             }
2151
2152           if (AVR_HAVE_MOVW)
2153             {
2154               *l = 1;
2155               return (AS2 (movw,%0,%1));
2156             }
2157           else
2158             {
2159               *l = 2;
2160               return (AS2 (mov,%A0,%A1) CR_TAB
2161                       AS2 (mov,%B0,%B1));
2162             }
2163         }
2164       else if (CONSTANT_P (src))
2165         {
2166           return output_reload_inhi (operands, NULL, real_l);
2167         }
2168       else if (GET_CODE (src) == MEM)
2169         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
2170     }
2171   else if (GET_CODE (dest) == MEM)
2172     {
2173       const char *templ;
2174
2175       if (src == const0_rtx)
2176         operands[1] = zero_reg_rtx;
2177
2178       templ = out_movhi_mr_r (insn, operands, real_l);
2179
2180       if (!real_l)
2181         output_asm_insn (templ, operands);
2182
2183       operands[1] = src;
2184       return "";
2185     }
2186   fatal_insn ("invalid insn:", insn);
2187   return "";
2188 }
2189
2190 const char *
2191 out_movqi_r_mr (rtx insn, rtx op[], int *l)
2192 {
2193   rtx dest = op[0];
2194   rtx src = op[1];
2195   rtx x = XEXP (src, 0);
2196   int dummy;
2197   
2198   if (!l)
2199     l = &dummy;
2200   
2201   if (CONSTANT_ADDRESS_P (x))
2202     {
2203       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2204         {
2205           *l = 1;
2206           return AS2 (in,%0,__SREG__);
2207         }
2208       if (optimize > 0 && io_address_operand (x, QImode))
2209         {
2210           *l = 1;
2211           return AS2 (in,%0,%m1-0x20);
2212         }
2213       *l = 2;
2214       return AS2 (lds,%0,%m1);
2215     }
2216   /* memory access by reg+disp */
2217   else if (GET_CODE (x) == PLUS
2218       && REG_P (XEXP (x,0))
2219       && GET_CODE (XEXP (x,1)) == CONST_INT)
2220     {
2221       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
2222         {
2223           int disp = INTVAL (XEXP (x,1));
2224           if (REGNO (XEXP (x,0)) != REG_Y)
2225             fatal_insn ("incorrect insn:",insn);
2226
2227           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2228             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
2229                             AS2 (ldd,%0,Y+63)     CR_TAB
2230                             AS2 (sbiw,r28,%o1-63));
2231
2232           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2233                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2234                           AS2 (ld,%0,Y)            CR_TAB
2235                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2236                           AS2 (sbci,r29,hi8(%o1)));
2237         }
2238       else if (REGNO (XEXP (x,0)) == REG_X)
2239         {
2240           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2241              it but I have this situation with extremal optimizing options.  */
2242           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
2243               || reg_unused_after (insn, XEXP (x,0)))
2244             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
2245                             AS2 (ld,%0,X));
2246
2247           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
2248                           AS2 (ld,%0,X)      CR_TAB
2249                           AS2 (sbiw,r26,%o1));
2250         }
2251       *l = 1;
2252       return AS2 (ldd,%0,%1);
2253     }
2254   *l = 1;
2255   return AS2 (ld,%0,%1);
2256 }
2257
2258 const char *
2259 out_movhi_r_mr (rtx insn, rtx op[], int *l)
2260 {
2261   rtx dest = op[0];
2262   rtx src = op[1];
2263   rtx base = XEXP (src, 0);
2264   int reg_dest = true_regnum (dest);
2265   int reg_base = true_regnum (base);
2266   /* "volatile" forces reading low byte first, even if less efficient,
2267      for correct operation with 16-bit I/O registers.  */
2268   int mem_volatile_p = MEM_VOLATILE_P (src);
2269   int tmp;
2270
2271   if (!l)
2272     l = &tmp;
2273
2274   if (reg_base > 0)
2275     {
2276       if (reg_dest == reg_base)         /* R = (R) */
2277         {
2278           *l = 3;
2279           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
2280                   AS2 (ld,%B0,%1) CR_TAB
2281                   AS2 (mov,%A0,__tmp_reg__));
2282         }
2283       else if (reg_base == REG_X)        /* (R26) */
2284         {
2285           if (reg_unused_after (insn, base))
2286             {
2287               *l = 2;
2288               return (AS2 (ld,%A0,X+) CR_TAB
2289                       AS2 (ld,%B0,X));
2290             }
2291           *l  = 3;
2292           return (AS2 (ld,%A0,X+) CR_TAB
2293                   AS2 (ld,%B0,X) CR_TAB
2294                   AS2 (sbiw,r26,1));
2295         }
2296       else                      /* (R)  */
2297         {
2298           *l = 2;
2299           return (AS2 (ld,%A0,%1)    CR_TAB
2300                   AS2 (ldd,%B0,%1+1));
2301         }
2302     }
2303   else if (GET_CODE (base) == PLUS) /* (R + i) */
2304     {
2305       int disp = INTVAL (XEXP (base, 1));
2306       int reg_base = true_regnum (XEXP (base, 0));
2307       
2308       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2309         {
2310           if (REGNO (XEXP (base, 0)) != REG_Y)
2311             fatal_insn ("incorrect insn:",insn);
2312           
2313           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2314             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
2315                             AS2 (ldd,%A0,Y+62)    CR_TAB
2316                             AS2 (ldd,%B0,Y+63)    CR_TAB
2317                             AS2 (sbiw,r28,%o1-62));
2318
2319           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2320                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2321                           AS2 (ld,%A0,Y)           CR_TAB
2322                           AS2 (ldd,%B0,Y+1)        CR_TAB
2323                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2324                           AS2 (sbci,r29,hi8(%o1)));
2325         }
2326       if (reg_base == REG_X)
2327         {
2328           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
2329              it but I have this situation with extremal
2330              optimization options.  */
2331           
2332           *l = 4;
2333           if (reg_base == reg_dest)
2334             return (AS2 (adiw,r26,%o1)      CR_TAB
2335                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2336                     AS2 (ld,%B0,X)          CR_TAB
2337                     AS2 (mov,%A0,__tmp_reg__));
2338
2339           return (AS2 (adiw,r26,%o1) CR_TAB
2340                   AS2 (ld,%A0,X+)    CR_TAB
2341                   AS2 (ld,%B0,X)     CR_TAB
2342                   AS2 (sbiw,r26,%o1+1));
2343         }
2344
2345       if (reg_base == reg_dest)
2346         {
2347           *l = 3;
2348           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2349                   AS2 (ldd,%B0,%B1)         CR_TAB
2350                   AS2 (mov,%A0,__tmp_reg__));
2351         }
2352       
2353       *l = 2;
2354       return (AS2 (ldd,%A0,%A1) CR_TAB
2355               AS2 (ldd,%B0,%B1));
2356     }
2357   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2358     {
2359       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2360         fatal_insn ("incorrect insn:", insn);
2361
2362       if (mem_volatile_p)
2363         {
2364           if (REGNO (XEXP (base, 0)) == REG_X)
2365             {
2366               *l = 4;
2367               return (AS2 (sbiw,r26,2)  CR_TAB
2368                       AS2 (ld,%A0,X+)   CR_TAB
2369                       AS2 (ld,%B0,X)    CR_TAB
2370                       AS2 (sbiw,r26,1));
2371             }
2372           else
2373             {
2374               *l = 3;
2375               return (AS2 (sbiw,%r1,2)   CR_TAB
2376                       AS2 (ld,%A0,%p1)  CR_TAB
2377                       AS2 (ldd,%B0,%p1+1));
2378             }
2379         }
2380
2381       *l = 2;
2382       return (AS2 (ld,%B0,%1) CR_TAB
2383               AS2 (ld,%A0,%1));
2384     }
2385   else if (GET_CODE (base) == POST_INC) /* (R++) */
2386     {
2387       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2388         fatal_insn ("incorrect insn:", insn);
2389
2390       *l = 2;
2391       return (AS2 (ld,%A0,%1)  CR_TAB
2392               AS2 (ld,%B0,%1));
2393     }
2394   else if (CONSTANT_ADDRESS_P (base))
2395     {
2396       if (optimize > 0 && io_address_operand (base, HImode))
2397         {
2398           *l = 2;
2399           return (AS2 (in,%A0,%m1-0x20) CR_TAB
2400                   AS2 (in,%B0,%m1+1-0x20));
2401         }
2402       *l = 4;
2403       return (AS2 (lds,%A0,%m1) CR_TAB
2404               AS2 (lds,%B0,%m1+1));
2405     }
2406   
2407   fatal_insn ("unknown move insn:",insn);
2408   return "";
2409 }
2410
2411 const char *
2412 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2413 {
2414   rtx dest = op[0];
2415   rtx src = op[1];
2416   rtx base = XEXP (src, 0);
2417   int reg_dest = true_regnum (dest);
2418   int reg_base = true_regnum (base);
2419   int tmp;
2420
2421   if (!l)
2422     l = &tmp;
2423   
2424   if (reg_base > 0)
2425     {
2426       if (reg_base == REG_X)        /* (R26) */
2427         {
2428           if (reg_dest == REG_X)
2429             /* "ld r26,-X" is undefined */
2430             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
2431                           AS2 (ld,r29,X)          CR_TAB
2432                           AS2 (ld,r28,-X)         CR_TAB
2433                           AS2 (ld,__tmp_reg__,-X) CR_TAB
2434                           AS2 (sbiw,r26,1)        CR_TAB
2435                           AS2 (ld,r26,X)          CR_TAB
2436                           AS2 (mov,r27,__tmp_reg__));
2437           else if (reg_dest == REG_X - 2)
2438             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2439                           AS2 (ld,%B0,X+) CR_TAB
2440                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
2441                           AS2 (ld,%D0,X)  CR_TAB
2442                           AS2 (mov,%C0,__tmp_reg__));
2443           else if (reg_unused_after (insn, base))
2444             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
2445                            AS2 (ld,%B0,X+) CR_TAB
2446                            AS2 (ld,%C0,X+) CR_TAB
2447                            AS2 (ld,%D0,X));
2448           else
2449             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2450                            AS2 (ld,%B0,X+) CR_TAB
2451                            AS2 (ld,%C0,X+) CR_TAB
2452                            AS2 (ld,%D0,X)  CR_TAB
2453                            AS2 (sbiw,r26,3));
2454         }
2455       else
2456         {
2457           if (reg_dest == reg_base)
2458             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2459                           AS2 (ldd,%C0,%1+2) CR_TAB
2460                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
2461                           AS2 (ld,%A0,%1)  CR_TAB
2462                           AS2 (mov,%B0,__tmp_reg__));
2463           else if (reg_base == reg_dest + 2)
2464             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2465                           AS2 (ldd,%B0,%1+1) CR_TAB
2466                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2467                           AS2 (ldd,%D0,%1+3) CR_TAB
2468                           AS2 (mov,%C0,__tmp_reg__));
2469           else
2470             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2471                           AS2 (ldd,%B0,%1+1) CR_TAB
2472                           AS2 (ldd,%C0,%1+2) CR_TAB
2473                           AS2 (ldd,%D0,%1+3));
2474         }
2475     }
2476   else if (GET_CODE (base) == PLUS) /* (R + i) */
2477     {
2478       int disp = INTVAL (XEXP (base, 1));
2479       
2480       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2481         {
2482           if (REGNO (XEXP (base, 0)) != REG_Y)
2483             fatal_insn ("incorrect insn:",insn);
2484
2485           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2486             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2487                             AS2 (ldd,%A0,Y+60)    CR_TAB
2488                             AS2 (ldd,%B0,Y+61)    CR_TAB
2489                             AS2 (ldd,%C0,Y+62)    CR_TAB
2490                             AS2 (ldd,%D0,Y+63)    CR_TAB
2491                             AS2 (sbiw,r28,%o1-60));
2492
2493           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2494                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2495                           AS2 (ld,%A0,Y)           CR_TAB
2496                           AS2 (ldd,%B0,Y+1)        CR_TAB
2497                           AS2 (ldd,%C0,Y+2)        CR_TAB
2498                           AS2 (ldd,%D0,Y+3)        CR_TAB
2499                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2500                           AS2 (sbci,r29,hi8(%o1)));
2501         }
2502
2503       reg_base = true_regnum (XEXP (base, 0));
2504       if (reg_base == REG_X)
2505         {
2506           /* R = (X + d) */
2507           if (reg_dest == REG_X)
2508             {
2509               *l = 7;
2510               /* "ld r26,-X" is undefined */
2511               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2512                       AS2 (ld,r29,X)          CR_TAB
2513                       AS2 (ld,r28,-X)         CR_TAB
2514                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2515                       AS2 (sbiw,r26,1)        CR_TAB
2516                       AS2 (ld,r26,X)          CR_TAB
2517                       AS2 (mov,r27,__tmp_reg__));
2518             }
2519           *l = 6;
2520           if (reg_dest == REG_X - 2)
2521             return (AS2 (adiw,r26,%o1)      CR_TAB
2522                     AS2 (ld,r24,X+)         CR_TAB
2523                     AS2 (ld,r25,X+)         CR_TAB
2524                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2525                     AS2 (ld,r27,X)          CR_TAB
2526                     AS2 (mov,r26,__tmp_reg__));
2527
2528           return (AS2 (adiw,r26,%o1) CR_TAB
2529                   AS2 (ld,%A0,X+)    CR_TAB
2530                   AS2 (ld,%B0,X+)    CR_TAB
2531                   AS2 (ld,%C0,X+)    CR_TAB
2532                   AS2 (ld,%D0,X)     CR_TAB
2533                   AS2 (sbiw,r26,%o1+3));
2534         }
2535       if (reg_dest == reg_base)
2536         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2537                       AS2 (ldd,%C0,%C1) CR_TAB
2538                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2539                       AS2 (ldd,%A0,%A1) CR_TAB
2540                       AS2 (mov,%B0,__tmp_reg__));
2541       else if (reg_dest == reg_base - 2)
2542         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2543                       AS2 (ldd,%B0,%B1) CR_TAB
2544                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2545                       AS2 (ldd,%D0,%D1) CR_TAB
2546                       AS2 (mov,%C0,__tmp_reg__));
2547       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2548                     AS2 (ldd,%B0,%B1) CR_TAB
2549                     AS2 (ldd,%C0,%C1) CR_TAB
2550                     AS2 (ldd,%D0,%D1));
2551     }
2552   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2553     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2554                   AS2 (ld,%C0,%1) CR_TAB
2555                   AS2 (ld,%B0,%1) CR_TAB
2556                   AS2 (ld,%A0,%1));
2557   else if (GET_CODE (base) == POST_INC) /* (R++) */
2558     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2559                   AS2 (ld,%B0,%1) CR_TAB
2560                   AS2 (ld,%C0,%1) CR_TAB
2561                   AS2 (ld,%D0,%1));
2562   else if (CONSTANT_ADDRESS_P (base))
2563       return *l=8, (AS2 (lds,%A0,%m1) CR_TAB
2564                     AS2 (lds,%B0,%m1+1) CR_TAB
2565                     AS2 (lds,%C0,%m1+2) CR_TAB
2566                     AS2 (lds,%D0,%m1+3));
2567     
2568   fatal_insn ("unknown move insn:",insn);
2569   return "";
2570 }
2571
2572 const char *
2573 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2574 {
2575   rtx dest = op[0];
2576   rtx src = op[1];
2577   rtx base = XEXP (dest, 0);
2578   int reg_base = true_regnum (base);
2579   int reg_src = true_regnum (src);
2580   int tmp;
2581   
2582   if (!l)
2583     l = &tmp;
2584   
2585   if (CONSTANT_ADDRESS_P (base))
2586     return *l=8,(AS2 (sts,%m0,%A1) CR_TAB
2587                  AS2 (sts,%m0+1,%B1) CR_TAB
2588                  AS2 (sts,%m0+2,%C1) CR_TAB
2589                  AS2 (sts,%m0+3,%D1));
2590   if (reg_base > 0)                 /* (r) */
2591     {
2592       if (reg_base == REG_X)                /* (R26) */
2593         {
2594           if (reg_src == REG_X)
2595             {
2596               /* "st X+,r26" is undefined */
2597               if (reg_unused_after (insn, base))
2598                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2599                               AS2 (st,X,r26)            CR_TAB
2600                               AS2 (adiw,r26,1)          CR_TAB
2601                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2602                               AS2 (st,X+,r28)           CR_TAB
2603                               AS2 (st,X,r29));
2604               else
2605                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2606                               AS2 (st,X,r26)            CR_TAB
2607                               AS2 (adiw,r26,1)          CR_TAB
2608                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2609                               AS2 (st,X+,r28)           CR_TAB
2610                               AS2 (st,X,r29)            CR_TAB
2611                               AS2 (sbiw,r26,3));
2612             }
2613           else if (reg_base == reg_src + 2)
2614             {
2615               if (reg_unused_after (insn, base))
2616                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2617                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2618                               AS2 (st,%0+,%A1) CR_TAB
2619                               AS2 (st,%0+,%B1) CR_TAB
2620                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2621                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2622                               AS1 (clr,__zero_reg__));
2623               else
2624                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2625                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2626                               AS2 (st,%0+,%A1) CR_TAB
2627                               AS2 (st,%0+,%B1) CR_TAB
2628                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2629                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2630                               AS1 (clr,__zero_reg__)     CR_TAB
2631                               AS2 (sbiw,r26,3));
2632             }
2633           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2634                         AS2 (st,%0+,%B1) CR_TAB
2635                         AS2 (st,%0+,%C1) CR_TAB
2636                         AS2 (st,%0,%D1)  CR_TAB
2637                         AS2 (sbiw,r26,3));
2638         }
2639       else
2640         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2641                       AS2 (std,%0+1,%B1) CR_TAB
2642                       AS2 (std,%0+2,%C1) CR_TAB
2643                       AS2 (std,%0+3,%D1));
2644     }
2645   else if (GET_CODE (base) == PLUS) /* (R + i) */
2646     {
2647       int disp = INTVAL (XEXP (base, 1));
2648       reg_base = REGNO (XEXP (base, 0));
2649       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2650         {
2651           if (reg_base != REG_Y)
2652             fatal_insn ("incorrect insn:",insn);
2653
2654           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2655             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2656                             AS2 (std,Y+60,%A1)    CR_TAB
2657                             AS2 (std,Y+61,%B1)    CR_TAB
2658                             AS2 (std,Y+62,%C1)    CR_TAB
2659                             AS2 (std,Y+63,%D1)    CR_TAB
2660                             AS2 (sbiw,r28,%o0-60));
2661
2662           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2663                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2664                           AS2 (st,Y,%A1)           CR_TAB
2665                           AS2 (std,Y+1,%B1)        CR_TAB
2666                           AS2 (std,Y+2,%C1)        CR_TAB
2667                           AS2 (std,Y+3,%D1)        CR_TAB
2668                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2669                           AS2 (sbci,r29,hi8(%o0)));
2670         }
2671       if (reg_base == REG_X)
2672         {
2673           /* (X + d) = R */
2674           if (reg_src == REG_X)
2675             {
2676               *l = 9;
2677               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2678                       AS2 (mov,__zero_reg__,r27) CR_TAB
2679                       AS2 (adiw,r26,%o0)         CR_TAB
2680                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2681                       AS2 (st,X+,__zero_reg__)   CR_TAB
2682                       AS2 (st,X+,r28)            CR_TAB
2683                       AS2 (st,X,r29)             CR_TAB
2684                       AS1 (clr,__zero_reg__)     CR_TAB
2685                       AS2 (sbiw,r26,%o0+3));
2686             }
2687           else if (reg_src == REG_X - 2)
2688             {
2689               *l = 9;
2690               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2691                       AS2 (mov,__zero_reg__,r27) CR_TAB
2692                       AS2 (adiw,r26,%o0)         CR_TAB
2693                       AS2 (st,X+,r24)            CR_TAB
2694                       AS2 (st,X+,r25)            CR_TAB
2695                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2696                       AS2 (st,X,__zero_reg__)    CR_TAB
2697                       AS1 (clr,__zero_reg__)     CR_TAB
2698                       AS2 (sbiw,r26,%o0+3));
2699             }
2700           *l = 6;
2701           return (AS2 (adiw,r26,%o0) CR_TAB
2702                   AS2 (st,X+,%A1)    CR_TAB
2703                   AS2 (st,X+,%B1)    CR_TAB
2704                   AS2 (st,X+,%C1)    CR_TAB
2705                   AS2 (st,X,%D1)     CR_TAB
2706                   AS2 (sbiw,r26,%o0+3));
2707         }
2708       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2709                     AS2 (std,%B0,%B1) CR_TAB
2710                     AS2 (std,%C0,%C1) CR_TAB
2711                     AS2 (std,%D0,%D1));
2712     }
2713   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2714     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2715                   AS2 (st,%0,%C1) CR_TAB
2716                   AS2 (st,%0,%B1) CR_TAB
2717                   AS2 (st,%0,%A1));
2718   else if (GET_CODE (base) == POST_INC) /* (R++) */
2719     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2720                   AS2 (st,%0,%B1) CR_TAB
2721                   AS2 (st,%0,%C1) CR_TAB
2722                   AS2 (st,%0,%D1));
2723   fatal_insn ("unknown move insn:",insn);
2724   return "";
2725 }
2726
2727 const char *
2728 output_movsisf (rtx insn, rtx operands[], int *l)
2729 {
2730   int dummy;
2731   rtx dest = operands[0];
2732   rtx src = operands[1];
2733   int *real_l = l;
2734   
2735   if (!l)
2736     l = &dummy;
2737   
2738   if (register_operand (dest, VOIDmode))
2739     {
2740       if (register_operand (src, VOIDmode)) /* mov r,r */
2741         {
2742           if (true_regnum (dest) > true_regnum (src))
2743             {
2744               if (AVR_HAVE_MOVW)
2745                 {
2746                   *l = 2;
2747                   return (AS2 (movw,%C0,%C1) CR_TAB
2748                           AS2 (movw,%A0,%A1));
2749                 }
2750               *l = 4;
2751               return (AS2 (mov,%D0,%D1) CR_TAB
2752                       AS2 (mov,%C0,%C1) CR_TAB
2753                       AS2 (mov,%B0,%B1) CR_TAB
2754                       AS2 (mov,%A0,%A1));
2755             }
2756           else
2757             {
2758               if (AVR_HAVE_MOVW)
2759                 {
2760                   *l = 2;
2761                   return (AS2 (movw,%A0,%A1) CR_TAB
2762                           AS2 (movw,%C0,%C1));
2763                 }
2764               *l = 4;
2765               return (AS2 (mov,%A0,%A1) CR_TAB
2766                       AS2 (mov,%B0,%B1) CR_TAB
2767                       AS2 (mov,%C0,%C1) CR_TAB
2768                       AS2 (mov,%D0,%D1));
2769             }
2770         }
2771       else if (CONST_INT_P (src)
2772                || CONST_DOUBLE_P (src))
2773         {
2774           return output_reload_insisf (operands, NULL_RTX, real_l);
2775         }
2776       else if (CONSTANT_P (src))
2777         {
2778           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2779             {
2780               *l = 4;
2781               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2782                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2783                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2784                       AS2 (ldi,%D0,hhi8(%1)));
2785             }
2786           /* Last resort, better than loading from memory.  */
2787           *l = 10;
2788           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2789                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2790                   AS2 (mov,%A0,r31)         CR_TAB
2791                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2792                   AS2 (mov,%B0,r31)         CR_TAB
2793                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2794                   AS2 (mov,%C0,r31)         CR_TAB
2795                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2796                   AS2 (mov,%D0,r31)         CR_TAB
2797                   AS2 (mov,r31,__tmp_reg__));
2798         }
2799       else if (GET_CODE (src) == MEM)
2800         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2801     }
2802   else if (GET_CODE (dest) == MEM)
2803     {
2804       const char *templ;
2805
2806       if (src == CONST0_RTX (GET_MODE (dest)))
2807           operands[1] = zero_reg_rtx;
2808
2809       templ = out_movsi_mr_r (insn, operands, real_l);
2810
2811       if (!real_l)
2812         output_asm_insn (templ, operands);
2813
2814       operands[1] = src;
2815       return "";
2816     }
2817   fatal_insn ("invalid insn:", insn);
2818   return "";
2819 }
2820
2821 const char *
2822 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2823 {
2824   rtx dest = op[0];
2825   rtx src = op[1];
2826   rtx x = XEXP (dest, 0);
2827   int dummy;
2828
2829   if (!l)
2830     l = &dummy;
2831   
2832   if (CONSTANT_ADDRESS_P (x))
2833     {
2834       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2835         {
2836           *l = 1;
2837           return AS2 (out,__SREG__,%1);
2838         }
2839       if (optimize > 0 && io_address_operand (x, QImode))
2840         {
2841           *l = 1;
2842           return AS2 (out,%m0-0x20,%1);
2843         }
2844       *l = 2;
2845       return AS2 (sts,%m0,%1);
2846     }
2847   /* memory access by reg+disp */
2848   else if (GET_CODE (x) == PLUS 
2849       && REG_P (XEXP (x,0))
2850       && GET_CODE (XEXP (x,1)) == CONST_INT)
2851     {
2852       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2853         {
2854           int disp = INTVAL (XEXP (x,1));
2855           if (REGNO (XEXP (x,0)) != REG_Y)
2856             fatal_insn ("incorrect insn:",insn);
2857
2858           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2859             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2860                             AS2 (std,Y+63,%1)     CR_TAB
2861                             AS2 (sbiw,r28,%o0-63));
2862
2863           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2864                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2865                           AS2 (st,Y,%1)            CR_TAB
2866                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2867                           AS2 (sbci,r29,hi8(%o0)));
2868         }
2869       else if (REGNO (XEXP (x,0)) == REG_X)
2870         {
2871           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2872             {
2873               if (reg_unused_after (insn, XEXP (x,0)))
2874                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2875                                 AS2 (adiw,r26,%o0)       CR_TAB
2876                                 AS2 (st,X,__tmp_reg__));
2877
2878               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2879                               AS2 (adiw,r26,%o0)       CR_TAB
2880                               AS2 (st,X,__tmp_reg__)   CR_TAB
2881                               AS2 (sbiw,r26,%o0));
2882             }
2883           else
2884             {
2885               if (reg_unused_after (insn, XEXP (x,0)))
2886                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2887                                 AS2 (st,X,%1));
2888
2889               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2890                               AS2 (st,X,%1)      CR_TAB
2891                               AS2 (sbiw,r26,%o0));
2892             }
2893         }
2894       *l = 1;
2895       return AS2 (std,%0,%1);
2896     }
2897   *l = 1;
2898   return AS2 (st,%0,%1);
2899 }
2900
2901 const char *
2902 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2903 {
2904   rtx dest = op[0];
2905   rtx src = op[1];
2906   rtx base = XEXP (dest, 0);
2907   int reg_base = true_regnum (base);
2908   int reg_src = true_regnum (src);
2909   /* "volatile" forces writing high byte first, even if less efficient,
2910      for correct operation with 16-bit I/O registers.  */
2911   int mem_volatile_p = MEM_VOLATILE_P (dest);
2912   int tmp;
2913
2914   if (!l)
2915     l = &tmp;
2916   if (CONSTANT_ADDRESS_P (base))
2917     {
2918       if (optimize > 0 && io_address_operand (base, HImode))
2919         {
2920           *l = 2;
2921           return (AS2 (out,%m0+1-0x20,%B1) CR_TAB
2922                   AS2 (out,%m0-0x20,%A1));
2923         }
2924       return *l = 4, (AS2 (sts,%m0+1,%B1) CR_TAB
2925                       AS2 (sts,%m0,%A1));
2926     }
2927   if (reg_base > 0)
2928     {
2929       if (reg_base == REG_X)
2930         {
2931           if (reg_src == REG_X)
2932             {
2933               /* "st X+,r26" and "st -X,r26" are undefined.  */
2934               if (!mem_volatile_p && reg_unused_after (insn, src))
2935                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2936                               AS2 (st,X,r26)            CR_TAB
2937                               AS2 (adiw,r26,1)          CR_TAB
2938                               AS2 (st,X,__tmp_reg__));
2939               else
2940                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2941                               AS2 (adiw,r26,1)          CR_TAB
2942                               AS2 (st,X,__tmp_reg__)    CR_TAB
2943                               AS2 (sbiw,r26,1)          CR_TAB
2944                               AS2 (st,X,r26));
2945             }
2946           else
2947             {
2948               if (!mem_volatile_p && reg_unused_after (insn, base))
2949                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2950                               AS2 (st,X,%B1));
2951               else
2952                 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2953                               AS2 (st,X,%B1)   CR_TAB
2954                               AS2 (st,-X,%A1));
2955             }
2956         }
2957       else
2958         return  *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2959                        AS2 (st,%0,%A1));
2960     }
2961   else if (GET_CODE (base) == PLUS)
2962     {
2963       int disp = INTVAL (XEXP (base, 1));
2964       reg_base = REGNO (XEXP (base, 0));
2965       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2966         {
2967           if (reg_base != REG_Y)
2968             fatal_insn ("incorrect insn:",insn);
2969
2970           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2971             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2972                             AS2 (std,Y+63,%B1)    CR_TAB
2973                             AS2 (std,Y+62,%A1)    CR_TAB
2974                             AS2 (sbiw,r28,%o0-62));
2975
2976           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2977                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2978                           AS2 (std,Y+1,%B1)        CR_TAB
2979                           AS2 (st,Y,%A1)           CR_TAB
2980                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2981                           AS2 (sbci,r29,hi8(%o0)));
2982         }
2983       if (reg_base == REG_X)
2984         {
2985           /* (X + d) = R */
2986           if (reg_src == REG_X)
2987             {
2988               *l = 7;
2989               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2990                       AS2 (mov,__zero_reg__,r27) CR_TAB
2991                       AS2 (adiw,r26,%o0+1)       CR_TAB
2992                       AS2 (st,X,__zero_reg__)    CR_TAB
2993                       AS2 (st,-X,__tmp_reg__)    CR_TAB
2994                       AS1 (clr,__zero_reg__)     CR_TAB
2995                       AS2 (sbiw,r26,%o0));
2996             }
2997           *l = 4;
2998           return (AS2 (adiw,r26,%o0+1) CR_TAB
2999                   AS2 (st,X,%B1)       CR_TAB
3000                   AS2 (st,-X,%A1)      CR_TAB
3001                   AS2 (sbiw,r26,%o0));
3002         }
3003       return *l=2, (AS2 (std,%B0,%B1)    CR_TAB
3004                     AS2 (std,%A0,%A1));
3005     }
3006   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3007     return *l=2, (AS2 (st,%0,%B1) CR_TAB
3008                   AS2 (st,%0,%A1));
3009   else if (GET_CODE (base) == POST_INC) /* (R++) */
3010     {
3011       if (mem_volatile_p)
3012         {
3013           if (REGNO (XEXP (base, 0)) == REG_X)
3014             {
3015               *l = 4;
3016               return (AS2 (adiw,r26,1)  CR_TAB
3017                       AS2 (st,X,%B1)    CR_TAB
3018                       AS2 (st,-X,%A1)   CR_TAB
3019                       AS2 (adiw,r26,2));
3020             }
3021           else
3022             {
3023               *l = 3;
3024               return (AS2 (std,%p0+1,%B1) CR_TAB
3025                       AS2 (st,%p0,%A1)    CR_TAB
3026                       AS2 (adiw,%r0,2));
3027             }
3028         }
3029
3030       *l = 2;
3031       return (AS2 (st,%0,%A1)  CR_TAB
3032             AS2 (st,%0,%B1));
3033     }
3034   fatal_insn ("unknown move insn:",insn);
3035   return "";
3036 }
3037
3038 /* Return 1 if frame pointer for current function required.  */
3039
3040 bool
3041 avr_frame_pointer_required_p (void)
3042 {
3043   return (cfun->calls_alloca
3044           || crtl->args.info.nregs == 0
3045           || get_frame_size () > 0);
3046 }
3047
3048 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
3049
3050 static RTX_CODE
3051 compare_condition (rtx insn)
3052 {
3053   rtx next = next_real_insn (insn);
3054
3055   if (next && JUMP_P (next))
3056     {
3057       rtx pat = PATTERN (next);
3058       rtx src = SET_SRC (pat);
3059       
3060       if (IF_THEN_ELSE == GET_CODE (src))
3061         return GET_CODE (XEXP (src, 0));
3062     }
3063   
3064   return UNKNOWN;
3065 }
3066
3067
3068 /* Returns true iff INSN is a tst insn that only tests the sign.  */
3069
3070 static bool
3071 compare_sign_p (rtx insn)
3072 {
3073   RTX_CODE cond = compare_condition (insn);
3074   return (cond == GE || cond == LT);
3075 }
3076
3077
3078 /* Returns true iff the next insn is a JUMP_INSN with a condition
3079    that needs to be swapped (GT, GTU, LE, LEU).  */
3080
3081 static bool
3082 compare_diff_p (rtx insn)
3083 {
3084   RTX_CODE cond = compare_condition (insn);
3085   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
3086 }
3087
3088 /* Returns true iff INSN is a compare insn with the EQ or NE condition.  */
3089
3090 static bool
3091 compare_eq_p (rtx insn)
3092 {
3093   RTX_CODE cond = compare_condition (insn);
3094   return (cond == EQ || cond == NE);
3095 }
3096
3097
3098 /* Output compare instruction
3099
3100       compare (XOP[0], XOP[1])
3101
3102    for an HI/SI register XOP[0] and an integer XOP[1].  Return "".
3103    XOP[2] is an 8-bit scratch register as needed.
3104
3105    PLEN == NULL:  Output instructions.
3106    PLEN != NULL:  Set *PLEN to the length (in words) of the sequence.
3107                   Don't output anything.  */
3108
3109 const char*
3110 avr_out_compare (rtx insn, rtx *xop, int *plen)
3111 {
3112   /* Register to compare and value to compare against. */
3113   rtx xreg = xop[0];
3114   rtx xval = xop[1];
3115   
3116   /* MODE of the comparison.  */
3117   enum machine_mode mode = GET_MODE (xreg);
3118
3119   /* Number of bytes to operate on.  */
3120   int i, n_bytes = GET_MODE_SIZE (mode);
3121
3122   /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown.  */
3123   int clobber_val = -1;
3124
3125   gcc_assert (REG_P (xreg)
3126               && CONST_INT_P (xval));
3127   
3128   if (plen)
3129     *plen = 0;
3130
3131   /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
3132      against 0 by ORing the bytes.  This is one instruction shorter.  */
3133
3134   if (!test_hard_reg_class (LD_REGS, xreg)
3135       && compare_eq_p (insn)
3136       && reg_unused_after (insn, xreg))
3137     {
3138       if (xval == const1_rtx)
3139         {
3140           avr_asm_len ("dec %A0" CR_TAB
3141                        "or %A0,%B0", xop, plen, 2);
3142           
3143           if (n_bytes == 4)
3144             avr_asm_len ("or %A0,%C0" CR_TAB
3145                          "or %A0,%D0", xop, plen, 2);
3146
3147           return "";
3148         }
3149       else if (xval == constm1_rtx)
3150         {
3151           if (n_bytes == 4)
3152             avr_asm_len ("and %A0,%D0" CR_TAB
3153                          "and %A0,%C0", xop, plen, 2);
3154           
3155           avr_asm_len ("and %A0,%B0" CR_TAB
3156                        "com %A0", xop, plen, 2);
3157           
3158           return "";
3159         }
3160     }
3161
3162   for (i = 0; i < n_bytes; i++)
3163     {
3164       /* We compare byte-wise.  */
3165       rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
3166       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
3167
3168       /* 8-bit value to compare with this byte.  */
3169       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
3170
3171       /* Registers R16..R31 can operate with immediate.  */
3172       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
3173
3174       xop[0] = reg8;
3175       xop[1] = gen_int_mode (val8, QImode);
3176
3177       /* Word registers >= R24 can use SBIW/ADIW with 0..63.  */
3178
3179       if (i == 0
3180           && test_hard_reg_class (ADDW_REGS, reg8))
3181         {
3182           int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
3183           
3184           if (IN_RANGE (val16, 0, 63)
3185               && (val8 == 0
3186                   || reg_unused_after (insn, xreg)))
3187             {
3188               avr_asm_len ("sbiw %0,%1", xop, plen, 1);
3189               i++;
3190               continue;
3191             }
3192
3193           if (n_bytes == 2
3194               && IN_RANGE (val16, -63, -1)
3195               && compare_eq_p (insn)
3196               && reg_unused_after (insn, xreg))
3197             {
3198               avr_asm_len ("adiw %0,%n1", xop, plen, 1);
3199               break;
3200             }
3201         }
3202
3203       /* Comparing against 0 is easy.  */
3204       
3205       if (val8 == 0)
3206         {
3207           avr_asm_len (i == 0
3208                        ? "cp %0,__zero_reg__"
3209                        : "cpc %0,__zero_reg__", xop, plen, 1);
3210           continue;
3211         }
3212
3213       /* Upper registers can compare and subtract-with-carry immediates.
3214          Notice that compare instructions do the same as respective subtract
3215          instruction; the only difference is that comparisons don't write
3216          the result back to the target register.  */
3217
3218       if (ld_reg_p)
3219         {
3220           if (i == 0)
3221             {
3222               avr_asm_len ("cpi %0,%1", xop, plen, 1);
3223               continue;
3224             }
3225           else if (reg_unused_after (insn, xreg))
3226             {
3227               avr_asm_len ("sbci %0,%1", xop, plen, 1);
3228               continue;
3229             }
3230         }
3231
3232       /* Must load the value into the scratch register.  */
3233
3234       gcc_assert (REG_P (xop[2]));
3235               
3236       if (clobber_val != (int) val8)
3237         avr_asm_len ("ldi %2,%1", xop, plen, 1);
3238       clobber_val = (int) val8;
3239               
3240       avr_asm_len (i == 0
3241                    ? "cp %0,%2"
3242                    : "cpc %0,%2", xop, plen, 1);
3243     }
3244
3245   return "";
3246 }
3247
3248
3249 /* Output test instruction for HImode.  */
3250
3251 const char*
3252 avr_out_tsthi (rtx insn, rtx *op, int *plen)
3253 {
3254   if (compare_sign_p (insn))
3255     {
3256       avr_asm_len ("tst %B0", op, plen, -1);
3257     }
3258   else if (reg_unused_after (insn, op[0])
3259            && compare_eq_p (insn))
3260     {
3261       /* Faster than sbiw if we can clobber the operand.  */
3262       avr_asm_len ("or %A0,%B0", op, plen, -1);
3263     }
3264   else
3265     {
3266       avr_out_compare (insn, op, plen);
3267     }
3268
3269   return "";
3270 }
3271
3272
3273 /* Output test instruction for SImode.  */
3274
3275 const char*
3276 avr_out_tstsi (rtx insn, rtx *op, int *plen)
3277 {
3278   if (compare_sign_p (insn))
3279     {
3280       avr_asm_len ("tst %D0", op, plen, -1);
3281     }
3282   else if (reg_unused_after (insn, op[0])
3283            && compare_eq_p (insn))
3284     {
3285       /* Faster than sbiw if we can clobber the operand.  */
3286       avr_asm_len ("or %A0,%B0" CR_TAB
3287                    "or %A0,%C0" CR_TAB
3288                    "or %A0,%D0", op, plen, -3);
3289     }
3290   else
3291     {
3292       avr_out_compare (insn, op, plen);
3293     }
3294
3295   return "";
3296 }
3297
3298
3299 /* Generate asm equivalent for various shifts.
3300    Shift count is a CONST_INT, MEM or REG.
3301    This only handles cases that are not already
3302    carefully hand-optimized in ?sh??i3_out.  */
3303
3304 void
3305 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
3306                     int *len, int t_len)
3307 {
3308   rtx op[10];
3309   char str[500];
3310   int second_label = 1;
3311   int saved_in_tmp = 0;
3312   int use_zero_reg = 0;
3313
3314   op[0] = operands[0];
3315   op[1] = operands[1];
3316   op[2] = operands[2];
3317   op[3] = operands[3];
3318   str[0] = 0;
3319
3320   if (len)
3321     *len = 1;
3322
3323   if (GET_CODE (operands[2]) == CONST_INT)
3324     {
3325       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3326       int count = INTVAL (operands[2]);
3327       int max_len = 10;  /* If larger than this, always use a loop.  */
3328
3329       if (count <= 0)
3330         {
3331           if (len)
3332             *len = 0;
3333           return;
3334         }
3335
3336       if (count < 8 && !scratch)
3337         use_zero_reg = 1;
3338
3339       if (optimize_size)
3340         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
3341
3342       if (t_len * count <= max_len)
3343         {
3344           /* Output shifts inline with no loop - faster.  */
3345           if (len)
3346             *len = t_len * count;
3347           else
3348             {
3349               while (count-- > 0)
3350                 output_asm_insn (templ, op);
3351             }
3352
3353           return;
3354         }
3355
3356       if (scratch)
3357         {
3358           if (!len)
3359             strcat (str, AS2 (ldi,%3,%2));
3360         }
3361       else if (use_zero_reg)
3362         {
3363           /* Hack to save one word: use __zero_reg__ as loop counter.
3364              Set one bit, then shift in a loop until it is 0 again.  */
3365
3366           op[3] = zero_reg_rtx;
3367           if (len)
3368             *len = 2;
3369           else
3370             strcat (str, ("set" CR_TAB
3371                           AS2 (bld,%3,%2-1)));
3372         }
3373       else
3374         {
3375           /* No scratch register available, use one from LD_REGS (saved in
3376              __tmp_reg__) that doesn't overlap with registers to shift.  */
3377
3378           op[3] = gen_rtx_REG (QImode,
3379                            ((true_regnum (operands[0]) - 1) & 15) + 16);
3380           op[4] = tmp_reg_rtx;
3381           saved_in_tmp = 1;
3382
3383           if (len)
3384             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
3385           else
3386             strcat (str, (AS2 (mov,%4,%3) CR_TAB
3387                           AS2 (ldi,%3,%2)));
3388         }
3389
3390       second_label = 0;
3391     }
3392   else if (GET_CODE (operands[2]) == MEM)
3393     {
3394       rtx op_mov[10];
3395       
3396       op[3] = op_mov[0] = tmp_reg_rtx;
3397       op_mov[1] = op[2];
3398
3399       if (len)
3400         out_movqi_r_mr (insn, op_mov, len);
3401       else
3402         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
3403     }
3404   else if (register_operand (operands[2], QImode))
3405     {
3406       if (reg_unused_after (insn, operands[2])
3407           && !reg_overlap_mentioned_p (operands[0], operands[2]))
3408         {
3409           op[3] = op[2];
3410         }
3411       else
3412         {
3413           op[3] = tmp_reg_rtx;
3414           if (!len)
3415             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
3416         }
3417     }
3418   else
3419     fatal_insn ("bad shift insn:", insn);
3420
3421   if (second_label)
3422     {
3423       if (len)
3424         ++*len;
3425       else
3426         strcat (str, AS1 (rjmp,2f));
3427     }
3428
3429   if (len)
3430     *len += t_len + 2;  /* template + dec + brXX */
3431   else
3432     {
3433       strcat (str, "\n1:\t");
3434       strcat (str, templ);
3435       strcat (str, second_label ? "\n2:\t" : "\n\t");
3436       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3437       strcat (str, CR_TAB);
3438       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3439       if (saved_in_tmp)
3440         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3441       output_asm_insn (str, op);
3442     }
3443 }
3444
3445
3446 /* 8bit shift left ((char)x << i)   */
3447
3448 const char *
3449 ashlqi3_out (rtx insn, rtx operands[], int *len)
3450 {
3451   if (GET_CODE (operands[2]) == CONST_INT)
3452     {
3453       int k;
3454
3455       if (!len)
3456         len = &k;
3457
3458       switch (INTVAL (operands[2]))
3459         {
3460         default:
3461           if (INTVAL (operands[2]) < 8)
3462             break;
3463
3464           *len = 1;
3465           return AS1 (clr,%0);
3466           
3467         case 1:
3468           *len = 1;
3469           return AS1 (lsl,%0);
3470           
3471         case 2:
3472           *len = 2;
3473           return (AS1 (lsl,%0) CR_TAB
3474                   AS1 (lsl,%0));
3475
3476         case 3:
3477           *len = 3;
3478           return (AS1 (lsl,%0) CR_TAB
3479                   AS1 (lsl,%0) CR_TAB
3480                   AS1 (lsl,%0));
3481
3482         case 4:
3483           if (test_hard_reg_class (LD_REGS, operands[0]))
3484             {
3485               *len = 2;
3486               return (AS1 (swap,%0) CR_TAB
3487                       AS2 (andi,%0,0xf0));
3488             }
3489           *len = 4;
3490           return (AS1 (lsl,%0) CR_TAB
3491                   AS1 (lsl,%0) CR_TAB
3492                   AS1 (lsl,%0) CR_TAB
3493                   AS1 (lsl,%0));
3494
3495         case 5:
3496           if (test_hard_reg_class (LD_REGS, operands[0]))
3497             {
3498               *len = 3;
3499               return (AS1 (swap,%0) CR_TAB
3500                       AS1 (lsl,%0)  CR_TAB
3501                       AS2 (andi,%0,0xe0));
3502             }
3503           *len = 5;
3504           return (AS1 (lsl,%0) CR_TAB
3505                   AS1 (lsl,%0) CR_TAB
3506                   AS1 (lsl,%0) CR_TAB
3507                   AS1 (lsl,%0) CR_TAB
3508                   AS1 (lsl,%0));
3509
3510         case 6:
3511           if (test_hard_reg_class (LD_REGS, operands[0]))
3512             {
3513               *len = 4;
3514               return (AS1 (swap,%0) CR_TAB
3515                       AS1 (lsl,%0)  CR_TAB
3516                       AS1 (lsl,%0)  CR_TAB
3517                       AS2 (andi,%0,0xc0));
3518             }
3519           *len = 6;
3520           return (AS1 (lsl,%0) CR_TAB
3521                   AS1 (lsl,%0) CR_TAB
3522                   AS1 (lsl,%0) CR_TAB
3523                   AS1 (lsl,%0) CR_TAB
3524                   AS1 (lsl,%0) CR_TAB
3525                   AS1 (lsl,%0));
3526
3527         case 7:
3528           *len = 3;
3529           return (AS1 (ror,%0) CR_TAB
3530                   AS1 (clr,%0) CR_TAB
3531                   AS1 (ror,%0));
3532         }
3533     }
3534   else if (CONSTANT_P (operands[2]))
3535     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3536
3537   out_shift_with_cnt (AS1 (lsl,%0),
3538                       insn, operands, len, 1);
3539   return "";
3540 }
3541
3542
3543 /* 16bit shift left ((short)x << i)   */
3544
3545 const char *
3546 ashlhi3_out (rtx insn, rtx operands[], int *len)
3547 {
3548   if (GET_CODE (operands[2]) == CONST_INT)
3549     {
3550       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3551       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3552       int k;
3553       int *t = len;
3554
3555       if (!len)
3556         len = &k;
3557       
3558       switch (INTVAL (operands[2]))
3559         {
3560         default:
3561           if (INTVAL (operands[2]) < 16)
3562             break;
3563
3564           *len = 2;
3565           return (AS1 (clr,%B0) CR_TAB
3566                   AS1 (clr,%A0));
3567
3568         case 4:
3569           if (optimize_size && scratch)
3570             break;  /* 5 */
3571           if (ldi_ok)
3572             {
3573               *len = 6;
3574               return (AS1 (swap,%A0)      CR_TAB
3575                       AS1 (swap,%B0)      CR_TAB
3576                       AS2 (andi,%B0,0xf0) CR_TAB
3577                       AS2 (eor,%B0,%A0)   CR_TAB
3578                       AS2 (andi,%A0,0xf0) CR_TAB
3579                       AS2 (eor,%B0,%A0));
3580             }
3581           if (scratch)
3582             {
3583               *len = 7;
3584               return (AS1 (swap,%A0)    CR_TAB
3585                       AS1 (swap,%B0)    CR_TAB
3586                       AS2 (ldi,%3,0xf0) CR_TAB
3587                       "and %B0,%3"      CR_TAB
3588                       AS2 (eor,%B0,%A0) CR_TAB
3589                       "and %A0,%3"      CR_TAB
3590                       AS2 (eor,%B0,%A0));
3591             }
3592           break;  /* optimize_size ? 6 : 8 */
3593
3594         case 5:
3595           if (optimize_size)
3596             break;  /* scratch ? 5 : 6 */
3597           if (ldi_ok)
3598             {
3599               *len = 8;
3600               return (AS1 (lsl,%A0)       CR_TAB
3601                       AS1 (rol,%B0)       CR_TAB
3602                       AS1 (swap,%A0)      CR_TAB
3603                       AS1 (swap,%B0)      CR_TAB
3604                       AS2 (andi,%B0,0xf0) CR_TAB
3605                       AS2 (eor,%B0,%A0)   CR_TAB
3606                       AS2 (andi,%A0,0xf0) CR_TAB
3607                       AS2 (eor,%B0,%A0));
3608             }
3609           if (scratch)
3610             {
3611               *len = 9;
3612               return (AS1 (lsl,%A0)     CR_TAB
3613                       AS1 (rol,%B0)     CR_TAB
3614                       AS1 (swap,%A0)    CR_TAB
3615                       AS1 (swap,%B0)    CR_TAB
3616                       AS2 (ldi,%3,0xf0) CR_TAB
3617                       "and %B0,%3"      CR_TAB
3618                       AS2 (eor,%B0,%A0) CR_TAB
3619                       "and %A0,%3"      CR_TAB
3620                       AS2 (eor,%B0,%A0));
3621             }
3622           break;  /* 10 */
3623
3624         case 6:
3625           if (optimize_size)
3626             break;  /* scratch ? 5 : 6 */
3627           *len = 9;
3628           return (AS1 (clr,__tmp_reg__) CR_TAB
3629                   AS1 (lsr,%B0)         CR_TAB
3630                   AS1 (ror,%A0)         CR_TAB
3631                   AS1 (ror,__tmp_reg__) CR_TAB
3632                   AS1 (lsr,%B0)         CR_TAB
3633                   AS1 (ror,%A0)         CR_TAB
3634                   AS1 (ror,__tmp_reg__) CR_TAB
3635                   AS2 (mov,%B0,%A0)     CR_TAB
3636                   AS2 (mov,%A0,__tmp_reg__));
3637
3638         case 7:
3639           *len = 5;
3640           return (AS1 (lsr,%B0)     CR_TAB
3641                   AS2 (mov,%B0,%A0) CR_TAB
3642                   AS1 (clr,%A0)     CR_TAB
3643                   AS1 (ror,%B0)     CR_TAB
3644                   AS1 (ror,%A0));
3645
3646         case 8:
3647           return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3648                             AS1 (clr,%A0));
3649
3650         case 9:
3651           *len = 3;
3652           return (AS2 (mov,%B0,%A0) CR_TAB
3653                   AS1 (clr,%A0)     CR_TAB
3654                   AS1 (lsl,%B0));
3655
3656         case 10:
3657           *len = 4;
3658           return (AS2 (mov,%B0,%A0) CR_TAB
3659                   AS1 (clr,%A0)     CR_TAB
3660                   AS1 (lsl,%B0)     CR_TAB
3661                   AS1 (lsl,%B0));
3662
3663         case 11:
3664           *len = 5;
3665           return (AS2 (mov,%B0,%A0) CR_TAB
3666                   AS1 (clr,%A0)     CR_TAB
3667                   AS1 (lsl,%B0)     CR_TAB
3668                   AS1 (lsl,%B0)     CR_TAB
3669                   AS1 (lsl,%B0));
3670
3671         case 12:
3672           if (ldi_ok)
3673             {
3674               *len = 4;
3675               return (AS2 (mov,%B0,%A0) CR_TAB
3676                       AS1 (clr,%A0)     CR_TAB
3677                       AS1 (swap,%B0)    CR_TAB
3678                       AS2 (andi,%B0,0xf0));
3679             }
3680           if (scratch)
3681             {
3682               *len = 5;
3683               return (AS2 (mov,%B0,%A0) CR_TAB
3684                       AS1 (clr,%A0)     CR_TAB
3685                       AS1 (swap,%B0)    CR_TAB
3686                       AS2 (ldi,%3,0xf0) CR_TAB
3687                       "and %B0,%3");
3688             }
3689           *len = 6;
3690           return (AS2 (mov,%B0,%A0) CR_TAB
3691                   AS1 (clr,%A0)     CR_TAB
3692                   AS1 (lsl,%B0)     CR_TAB
3693                   AS1 (lsl,%B0)     CR_TAB
3694                   AS1 (lsl,%B0)     CR_TAB
3695                   AS1 (lsl,%B0));
3696
3697         case 13:
3698           if (ldi_ok)
3699             {
3700               *len = 5;
3701               return (AS2 (mov,%B0,%A0) CR_TAB
3702                       AS1 (clr,%A0)     CR_TAB
3703                       AS1 (swap,%B0)    CR_TAB
3704                       AS1 (lsl,%B0)     CR_TAB
3705                       AS2 (andi,%B0,0xe0));
3706             }
3707           if (AVR_HAVE_MUL && scratch)
3708             {
3709               *len = 5;
3710               return (AS2 (ldi,%3,0x20) CR_TAB
3711                       AS2 (mul,%A0,%3)  CR_TAB
3712                       AS2 (mov,%B0,r0)  CR_TAB
3713                       AS1 (clr,%A0)     CR_TAB
3714                       AS1 (clr,__zero_reg__));
3715             }
3716           if (optimize_size && scratch)
3717             break;  /* 5 */
3718           if (scratch)
3719             {
3720               *len = 6;
3721               return (AS2 (mov,%B0,%A0) CR_TAB
3722                       AS1 (clr,%A0)     CR_TAB
3723                       AS1 (swap,%B0)    CR_TAB
3724                       AS1 (lsl,%B0)     CR_TAB
3725                       AS2 (ldi,%3,0xe0) CR_TAB
3726                       "and %B0,%3");
3727             }
3728           if (AVR_HAVE_MUL)
3729             {
3730               *len = 6;
3731               return ("set"            CR_TAB
3732                       AS2 (bld,r1,5)   CR_TAB
3733                       AS2 (mul,%A0,r1) CR_TAB
3734                       AS2 (mov,%B0,r0) CR_TAB
3735                       AS1 (clr,%A0)    CR_TAB
3736                       AS1 (clr,__zero_reg__));
3737             }
3738           *len = 7;
3739           return (AS2 (mov,%B0,%A0) CR_TAB
3740                   AS1 (clr,%A0)     CR_TAB
3741                   AS1 (lsl,%B0)     CR_TAB
3742                   AS1 (lsl,%B0)     CR_TAB
3743                   AS1 (lsl,%B0)     CR_TAB
3744                   AS1 (lsl,%B0)     CR_TAB
3745                   AS1 (lsl,%B0));
3746
3747         case 14:
3748           if (AVR_HAVE_MUL && ldi_ok)
3749             {
3750               *len = 5;
3751               return (AS2 (ldi,%B0,0x40) CR_TAB
3752                       AS2 (mul,%A0,%B0)  CR_TAB
3753                       AS2 (mov,%B0,r0)   CR_TAB
3754                       AS1 (clr,%A0)      CR_TAB
3755                       AS1 (clr,__zero_reg__));
3756             }
3757           if (AVR_HAVE_MUL && scratch)
3758             {
3759               *len = 5;
3760               return (AS2 (ldi,%3,0x40) CR_TAB
3761                       AS2 (mul,%A0,%3)  CR_TAB
3762                       AS2 (mov,%B0,r0)  CR_TAB
3763                       AS1 (clr,%A0)     CR_TAB
3764                       AS1 (clr,__zero_reg__));
3765             }
3766           if (optimize_size && ldi_ok)
3767             {
3768               *len = 5;
3769               return (AS2 (mov,%B0,%A0) CR_TAB
3770                       AS2 (ldi,%A0,6) "\n1:\t"
3771                       AS1 (lsl,%B0)     CR_TAB
3772                       AS1 (dec,%A0)     CR_TAB
3773                       AS1 (brne,1b));
3774             }
3775           if (optimize_size && scratch)
3776             break;  /* 5 */
3777           *len = 6;
3778           return (AS1 (clr,%B0) CR_TAB
3779                   AS1 (lsr,%A0) CR_TAB
3780                   AS1 (ror,%B0) CR_TAB
3781                   AS1 (lsr,%A0) CR_TAB
3782                   AS1 (ror,%B0) CR_TAB
3783                   AS1 (clr,%A0));
3784
3785         case 15:
3786           *len = 4;
3787           return (AS1 (clr,%B0) CR_TAB
3788                   AS1 (lsr,%A0) CR_TAB
3789                   AS1 (ror,%B0) CR_TAB
3790                   AS1 (clr,%A0));
3791         }
3792       len = t;
3793     }
3794   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3795                        AS1 (rol,%B0)),
3796                        insn, operands, len, 2);
3797   return "";
3798 }
3799
3800
3801 /* 32bit shift left ((long)x << i)   */
3802
3803 const char *
3804 ashlsi3_out (rtx insn, rtx operands[], int *len)
3805 {
3806   if (GET_CODE (operands[2]) == CONST_INT)
3807     {
3808       int k;
3809       int *t = len;
3810       
3811       if (!len)
3812         len = &k;
3813       
3814       switch (INTVAL (operands[2]))
3815         {
3816         default:
3817           if (INTVAL (operands[2]) < 32)
3818             break;
3819
3820           if (AVR_HAVE_MOVW)
3821             return *len = 3, (AS1 (clr,%D0) CR_TAB
3822                               AS1 (clr,%C0) CR_TAB
3823                               AS2 (movw,%A0,%C0));
3824           *len = 4;
3825           return (AS1 (clr,%D0) CR_TAB
3826                   AS1 (clr,%C0) CR_TAB
3827                   AS1 (clr,%B0) CR_TAB
3828                   AS1 (clr,%A0));
3829
3830         case 8:
3831           {
3832             int reg0 = true_regnum (operands[0]);
3833             int reg1 = true_regnum (operands[1]);
3834             *len = 4;
3835             if (reg0 >= reg1)
3836               return (AS2 (mov,%D0,%C1)  CR_TAB
3837                       AS2 (mov,%C0,%B1)  CR_TAB
3838                       AS2 (mov,%B0,%A1)  CR_TAB
3839                       AS1 (clr,%A0));
3840             else
3841               return (AS1 (clr,%A0)      CR_TAB
3842                       AS2 (mov,%B0,%A1)  CR_TAB
3843                       AS2 (mov,%C0,%B1)  CR_TAB
3844                       AS2 (mov,%D0,%C1));
3845           }
3846
3847         case 16:
3848           {
3849             int reg0 = true_regnum (operands[0]);
3850             int reg1 = true_regnum (operands[1]);
3851             if (reg0 + 2 == reg1)
3852               return *len = 2, (AS1 (clr,%B0)      CR_TAB
3853                                 AS1 (clr,%A0));
3854             if (AVR_HAVE_MOVW)
3855               return *len = 3, (AS2 (movw,%C0,%A1) CR_TAB
3856                                 AS1 (clr,%B0)      CR_TAB
3857                                 AS1 (clr,%A0));
3858             else
3859               return *len = 4, (AS2 (mov,%C0,%A1)  CR_TAB
3860                                 AS2 (mov,%D0,%B1)  CR_TAB
3861                                 AS1 (clr,%B0)      CR_TAB
3862                                 AS1 (clr,%A0));
3863           }
3864
3865         case 24:
3866           *len = 4;
3867           return (AS2 (mov,%D0,%A1)  CR_TAB
3868                   AS1 (clr,%C0)      CR_TAB
3869                   AS1 (clr,%B0)      CR_TAB
3870                   AS1 (clr,%A0));
3871
3872         case 31:
3873           *len = 6;
3874           return (AS1 (clr,%D0) CR_TAB
3875                   AS1 (lsr,%A0) CR_TAB
3876                   AS1 (ror,%D0) CR_TAB
3877                   AS1 (clr,%C0) CR_TAB
3878                   AS1 (clr,%B0) CR_TAB
3879                   AS1 (clr,%A0));
3880         }
3881       len = t;
3882     }
3883   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3884                        AS1 (rol,%B0) CR_TAB
3885                        AS1 (rol,%C0) CR_TAB
3886                        AS1 (rol,%D0)),
3887                        insn, operands, len, 4);
3888   return "";
3889 }
3890
3891 /* 8bit arithmetic shift right  ((signed char)x >> i) */
3892
3893 const char *
3894 ashrqi3_out (rtx insn, rtx operands[], int *len)
3895 {
3896   if (GET_CODE (operands[2]) == CONST_INT)
3897     {
3898       int k;
3899
3900       if (!len)
3901         len = &k;
3902
3903       switch (INTVAL (operands[2]))
3904         {
3905         case 1:
3906           *len = 1;
3907           return AS1 (asr,%0);
3908
3909         case 2:
3910           *len = 2;
3911           return (AS1 (asr,%0) CR_TAB
3912                   AS1 (asr,%0));
3913
3914         case 3:
3915           *len = 3;
3916           return (AS1 (asr,%0) CR_TAB
3917                   AS1 (asr,%0) CR_TAB
3918                   AS1 (asr,%0));
3919
3920         case 4:
3921           *len = 4;
3922           return (AS1 (asr,%0) CR_TAB
3923                   AS1 (asr,%0) CR_TAB
3924                   AS1 (asr,%0) CR_TAB
3925                   AS1 (asr,%0));
3926
3927         case 5:
3928           *len = 5;
3929           return (AS1 (asr,%0) CR_TAB
3930                   AS1 (asr,%0) CR_TAB
3931                   AS1 (asr,%0) CR_TAB
3932                   AS1 (asr,%0) CR_TAB
3933                   AS1 (asr,%0));
3934
3935         case 6:
3936           *len = 4;
3937           return (AS2 (bst,%0,6)  CR_TAB
3938                   AS1 (lsl,%0)    CR_TAB
3939                   AS2 (sbc,%0,%0) CR_TAB
3940                   AS2 (bld,%0,0));
3941
3942         default:
3943           if (INTVAL (operands[2]) < 8)
3944             break;
3945
3946           /* fall through */
3947
3948         case 7:
3949           *len = 2;
3950           return (AS1 (lsl,%0) CR_TAB
3951                   AS2 (sbc,%0,%0));
3952         }
3953     }
3954   else if (CONSTANT_P (operands[2]))
3955     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3956
3957   out_shift_with_cnt (AS1 (asr,%0),
3958                       insn, operands, len, 1);
3959   return "";
3960 }
3961
3962
3963 /* 16bit arithmetic shift right  ((signed short)x >> i) */
3964
3965 const char *
3966 ashrhi3_out (rtx insn, rtx operands[], int *len)
3967 {
3968   if (GET_CODE (operands[2]) == CONST_INT)
3969     {
3970       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3971       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3972       int k;
3973       int *t = len;
3974       
3975       if (!len)
3976         len = &k;
3977
3978       switch (INTVAL (operands[2]))
3979         {
3980         case 4:
3981         case 5:
3982           /* XXX try to optimize this too? */
3983           break;
3984
3985         case 6:
3986           if (optimize_size)
3987             break;  /* scratch ? 5 : 6 */
3988           *len = 8;
3989           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3990                   AS2 (mov,%A0,%B0)         CR_TAB
3991                   AS1 (lsl,__tmp_reg__)     CR_TAB
3992                   AS1 (rol,%A0)             CR_TAB
3993                   AS2 (sbc,%B0,%B0)         CR_TAB
3994                   AS1 (lsl,__tmp_reg__)     CR_TAB
3995                   AS1 (rol,%A0)             CR_TAB
3996                   AS1 (rol,%B0));
3997
3998         case 7:
3999           *len = 4;
4000           return (AS1 (lsl,%A0)     CR_TAB
4001                   AS2 (mov,%A0,%B0) CR_TAB
4002                   AS1 (rol,%A0)     CR_TAB
4003                   AS2 (sbc,%B0,%B0));
4004
4005         case 8:
4006           {
4007             int reg0 = true_regnum (operands[0]);
4008             int reg1 = true_regnum (operands[1]);
4009
4010             if (reg0 == reg1)
4011               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
4012                                 AS1 (lsl,%B0)     CR_TAB
4013                                 AS2 (sbc,%B0,%B0));
4014             else 
4015               return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
4016                                 AS1 (clr,%B0)     CR_TAB
4017                                 AS2 (sbrc,%A0,7)  CR_TAB
4018                                 AS1 (dec,%B0));
4019           }
4020
4021         case 9:
4022           *len = 4;
4023           return (AS2 (mov,%A0,%B0) CR_TAB
4024                   AS1 (lsl,%B0)      CR_TAB
4025                   AS2 (sbc,%B0,%B0) CR_TAB
4026                   AS1 (asr,%A0));
4027
4028         case 10:
4029           *len = 5;
4030           return (AS2 (mov,%A0,%B0) CR_TAB
4031                   AS1 (lsl,%B0)     CR_TAB
4032                   AS2 (sbc,%B0,%B0) CR_TAB
4033                   AS1 (asr,%A0)     CR_TAB
4034                   AS1 (asr,%A0));
4035
4036         case 11:
4037           if (AVR_HAVE_MUL && ldi_ok)
4038             {
4039               *len = 5;
4040               return (AS2 (ldi,%A0,0x20) CR_TAB
4041                       AS2 (muls,%B0,%A0) CR_TAB
4042                       AS2 (mov,%A0,r1)   CR_TAB
4043                       AS2 (sbc,%B0,%B0)  CR_TAB
4044                       AS1 (clr,__zero_reg__));
4045             }
4046           if (optimize_size && scratch)
4047             break;  /* 5 */
4048           *len = 6;
4049           return (AS2 (mov,%A0,%B0) CR_TAB
4050                   AS1 (lsl,%B0)     CR_TAB
4051                   AS2 (sbc,%B0,%B0) CR_TAB
4052                   AS1 (asr,%A0)     CR_TAB
4053                   AS1 (asr,%A0)     CR_TAB
4054                   AS1 (asr,%A0));
4055
4056         case 12:
4057           if (AVR_HAVE_MUL && ldi_ok)
4058             {
4059               *len = 5;
4060               return (AS2 (ldi,%A0,0x10) CR_TAB
4061                       AS2 (muls,%B0,%A0) CR_TAB
4062                       AS2 (mov,%A0,r1)   CR_TAB
4063                       AS2 (sbc,%B0,%B0)  CR_TAB
4064                       AS1 (clr,__zero_reg__));
4065             }
4066           if (optimize_size && scratch)
4067             break;  /* 5 */
4068           *len = 7;
4069           return (AS2 (mov,%A0,%B0) CR_TAB
4070                   AS1 (lsl,%B0)     CR_TAB
4071                   AS2 (sbc,%B0,%B0) CR_TAB
4072                   AS1 (asr,%A0)     CR_TAB
4073                   AS1 (asr,%A0)     CR_TAB
4074                   AS1 (asr,%A0)     CR_TAB
4075                   AS1 (asr,%A0));
4076
4077         case 13:
4078           if (AVR_HAVE_MUL && ldi_ok)
4079             {
4080               *len = 5;
4081               return (AS2 (ldi,%A0,0x08) CR_TAB
4082                       AS2 (muls,%B0,%A0) CR_TAB
4083                       AS2 (mov,%A0,r1)   CR_TAB
4084                       AS2 (sbc,%B0,%B0)  CR_TAB
4085                       AS1 (clr,__zero_reg__));
4086             }
4087           if (optimize_size)
4088             break;  /* scratch ? 5 : 7 */
4089           *len = 8;
4090           return (AS2 (mov,%A0,%B0) CR_TAB
4091                   AS1 (lsl,%B0)     CR_TAB
4092                   AS2 (sbc,%B0,%B0) CR_TAB
4093                   AS1 (asr,%A0)     CR_TAB
4094                   AS1 (asr,%A0)     CR_TAB
4095                   AS1 (asr,%A0)     CR_TAB
4096                   AS1 (asr,%A0)     CR_TAB
4097                   AS1 (asr,%A0));
4098
4099         case 14:
4100           *len = 5;
4101           return (AS1 (lsl,%B0)     CR_TAB
4102                   AS2 (sbc,%A0,%A0) CR_TAB
4103                   AS1 (lsl,%B0)     CR_TAB
4104                   AS2 (mov,%B0,%A0) CR_TAB
4105                   AS1 (rol,%A0));
4106
4107         default:
4108           if (INTVAL (operands[2]) < 16)
4109             break;
4110
4111           /* fall through */
4112
4113         case 15:
4114           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
4115                             AS2 (sbc,%A0,%A0) CR_TAB
4116                             AS2 (mov,%B0,%A0));
4117         }
4118       len = t;
4119     }
4120   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
4121                        AS1 (ror,%A0)),
4122                        insn, operands, len, 2);
4123   return "";
4124 }
4125
4126
4127 /* 32bit arithmetic shift right  ((signed long)x >> i) */
4128
4129 const char *
4130 ashrsi3_out (rtx insn, rtx operands[], int *len)
4131 {
4132   if (GET_CODE (operands[2]) == CONST_INT)
4133     {
4134       int k;
4135       int *t = len;
4136       
4137       if (!len)
4138         len = &k;
4139       
4140       switch (INTVAL (operands[2]))
4141         {
4142         case 8:
4143           {
4144             int reg0 = true_regnum (operands[0]);
4145             int reg1 = true_regnum (operands[1]);
4146             *len=6;
4147             if (reg0 <= reg1)
4148               return (AS2 (mov,%A0,%B1) CR_TAB
4149                       AS2 (mov,%B0,%C1) CR_TAB
4150                       AS2 (mov,%C0,%D1) CR_TAB
4151                       AS1 (clr,%D0)     CR_TAB
4152                       AS2 (sbrc,%C0,7)  CR_TAB
4153                       AS1 (dec,%D0));
4154             else
4155               return (AS1 (clr,%D0)     CR_TAB
4156                       AS2 (sbrc,%D1,7)  CR_TAB
4157                       AS1 (dec,%D0)     CR_TAB
4158                       AS2 (mov,%C0,%D1) CR_TAB
4159                       AS2 (mov,%B0,%C1) CR_TAB
4160                       AS2 (mov,%A0,%B1));
4161           }
4162           
4163         case 16:
4164           {
4165             int reg0 = true_regnum (operands[0]);
4166             int reg1 = true_regnum (operands[1]);
4167             
4168             if (reg0 == reg1 + 2)
4169               return *len = 4, (AS1 (clr,%D0)     CR_TAB
4170                                 AS2 (sbrc,%B0,7)  CR_TAB
4171                                 AS1 (com,%D0)     CR_TAB
4172                                 AS2 (mov,%C0,%D0));
4173             if (AVR_HAVE_MOVW)
4174               return *len = 5, (AS2 (movw,%A0,%C1) CR_TAB
4175                                 AS1 (clr,%D0)      CR_TAB
4176                                 AS2 (sbrc,%B0,7)   CR_TAB
4177                                 AS1 (com,%D0)      CR_TAB
4178                                 AS2 (mov,%C0,%D0));
4179             else 
4180               return *len = 6, (AS2 (mov,%B0,%D1) CR_TAB
4181                                 AS2 (mov,%A0,%C1) CR_TAB
4182                                 AS1 (clr,%D0)     CR_TAB
4183                                 AS2 (sbrc,%B0,7)  CR_TAB
4184                                 AS1 (com,%D0)     CR_TAB
4185                                 AS2 (mov,%C0,%D0));
4186           }
4187
4188         case 24:
4189           return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
4190                             AS1 (clr,%D0)     CR_TAB
4191                             AS2 (sbrc,%A0,7)  CR_TAB
4192                             AS1 (com,%D0)     CR_TAB
4193                             AS2 (mov,%B0,%D0) CR_TAB
4194                             AS2 (mov,%C0,%D0));
4195
4196         default:
4197           if (INTVAL (operands[2]) < 32)
4198             break;
4199
4200           /* fall through */
4201
4202         case 31:
4203           if (AVR_HAVE_MOVW)
4204             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
4205                               AS2 (sbc,%A0,%A0) CR_TAB
4206                               AS2 (mov,%B0,%A0) CR_TAB
4207                               AS2 (movw,%C0,%A0));
4208           else
4209             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
4210                               AS2 (sbc,%A0,%A0) CR_TAB
4211                               AS2 (mov,%B0,%A0) CR_TAB
4212                               AS2 (mov,%C0,%A0) CR_TAB
4213                               AS2 (mov,%D0,%A0));
4214         }
4215       len = t;
4216     }
4217   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
4218                        AS1 (ror,%C0) CR_TAB
4219                        AS1 (ror,%B0) CR_TAB
4220                        AS1 (ror,%A0)),
4221                        insn, operands, len, 4);
4222   return "";
4223 }
4224
4225 /* 8bit logic shift right ((unsigned char)x >> i) */
4226
4227 const char *
4228 lshrqi3_out (rtx insn, rtx operands[], int *len)
4229 {
4230   if (GET_CODE (operands[2]) == CONST_INT)
4231     {
4232       int k;
4233
4234       if (!len)
4235         len = &k;
4236       
4237       switch (INTVAL (operands[2]))
4238         {
4239         default:
4240           if (INTVAL (operands[2]) < 8)
4241             break;
4242
4243           *len = 1;
4244           return AS1 (clr,%0);
4245
4246         case 1:
4247           *len = 1;
4248           return AS1 (lsr,%0);
4249
4250         case 2:
4251           *len = 2;
4252           return (AS1 (lsr,%0) CR_TAB
4253                   AS1 (lsr,%0));
4254         case 3:
4255           *len = 3;
4256           return (AS1 (lsr,%0) CR_TAB
4257                   AS1 (lsr,%0) CR_TAB
4258                   AS1 (lsr,%0));
4259           
4260         case 4:
4261           if (test_hard_reg_class (LD_REGS, operands[0]))
4262             {
4263               *len=2;
4264               return (AS1 (swap,%0) CR_TAB
4265                       AS2 (andi,%0,0x0f));
4266             }
4267           *len = 4;
4268           return (AS1 (lsr,%0) CR_TAB
4269                   AS1 (lsr,%0) CR_TAB
4270                   AS1 (lsr,%0) CR_TAB
4271                   AS1 (lsr,%0));
4272           
4273         case 5:
4274           if (test_hard_reg_class (LD_REGS, operands[0]))
4275             {
4276               *len = 3;
4277               return (AS1 (swap,%0) CR_TAB
4278                       AS1 (lsr,%0)  CR_TAB
4279                       AS2 (andi,%0,0x7));
4280             }
4281           *len = 5;
4282           return (AS1 (lsr,%0) CR_TAB
4283                   AS1 (lsr,%0) CR_TAB
4284                   AS1 (lsr,%0) CR_TAB
4285                   AS1 (lsr,%0) CR_TAB
4286                   AS1 (lsr,%0));
4287           
4288         case 6:
4289           if (test_hard_reg_class (LD_REGS, operands[0]))
4290             {
4291               *len = 4;
4292               return (AS1 (swap,%0) CR_TAB
4293                       AS1 (lsr,%0)  CR_TAB
4294                       AS1 (lsr,%0)  CR_TAB
4295                       AS2 (andi,%0,0x3));
4296             }
4297           *len = 6;
4298           return (AS1 (lsr,%0) CR_TAB
4299                   AS1 (lsr,%0) CR_TAB
4300                   AS1 (lsr,%0) CR_TAB
4301                   AS1 (lsr,%0) CR_TAB
4302                   AS1 (lsr,%0) CR_TAB
4303                   AS1 (lsr,%0));
4304           
4305         case 7:
4306           *len = 3;
4307           return (AS1 (rol,%0) CR_TAB
4308                   AS1 (clr,%0) CR_TAB
4309                   AS1 (rol,%0));
4310         }
4311     }
4312   else if (CONSTANT_P (operands[2]))
4313     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
4314   
4315   out_shift_with_cnt (AS1 (lsr,%0),
4316                       insn, operands, len, 1);
4317   return "";
4318 }
4319
4320 /* 16bit logic shift right ((unsigned short)x >> i) */
4321
4322 const char *
4323 lshrhi3_out (rtx insn, rtx operands[], int *len)
4324 {
4325   if (GET_CODE (operands[2]) == CONST_INT)
4326     {
4327       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4328       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4329       int k;
4330       int *t = len;
4331
4332       if (!len)
4333         len = &k;
4334       
4335       switch (INTVAL (operands[2]))
4336         {
4337         default:
4338           if (INTVAL (operands[2]) < 16)
4339             break;
4340
4341           *len = 2;
4342           return (AS1 (clr,%B0) CR_TAB
4343                   AS1 (clr,%A0));
4344
4345         case 4:
4346           if (optimize_size && scratch)
4347             break;  /* 5 */
4348           if (ldi_ok)
4349             {
4350               *len = 6;
4351               return (AS1 (swap,%B0)      CR_TAB
4352                       AS1 (swap,%A0)      CR_TAB
4353                       AS2 (andi,%A0,0x0f) CR_TAB
4354                       AS2 (eor,%A0,%B0)   CR_TAB
4355                       AS2 (andi,%B0,0x0f) CR_TAB
4356                       AS2 (eor,%A0,%B0));
4357             }
4358           if (scratch)
4359             {
4360               *len = 7;
4361               return (AS1 (swap,%B0)    CR_TAB
4362                       AS1 (swap,%A0)    CR_TAB
4363                       AS2 (ldi,%3,0x0f) CR_TAB
4364                       "and %A0,%3"      CR_TAB
4365                       AS2 (eor,%A0,%B0) CR_TAB
4366                       "and %B0,%3"      CR_TAB
4367                       AS2 (eor,%A0,%B0));
4368             }
4369           break;  /* optimize_size ? 6 : 8 */
4370
4371         case 5:
4372           if (optimize_size)
4373             break;  /* scratch ? 5 : 6 */
4374           if (ldi_ok)
4375             {
4376               *len = 8;
4377               return (AS1 (lsr,%B0)       CR_TAB
4378                       AS1 (ror,%A0)       CR_TAB
4379                       AS1 (swap,%B0)      CR_TAB
4380                       AS1 (swap,%A0)      CR_TAB
4381                       AS2 (andi,%A0,0x0f) CR_TAB
4382                       AS2 (eor,%A0,%B0)   CR_TAB
4383                       AS2 (andi,%B0,0x0f) CR_TAB
4384                       AS2 (eor,%A0,%B0));
4385             }
4386           if (scratch)
4387             {
4388               *len = 9;
4389               return (AS1 (lsr,%B0)     CR_TAB
4390                       AS1 (ror,%A0)     CR_TAB
4391                       AS1 (swap,%B0)    CR_TAB
4392                       AS1 (swap,%A0)    CR_TAB
4393                       AS2 (ldi,%3,0x0f) CR_TAB
4394                       "and %A0,%3"      CR_TAB
4395                       AS2 (eor,%A0,%B0) CR_TAB
4396                       "and %B0,%3"      CR_TAB
4397                       AS2 (eor,%A0,%B0));
4398             }
4399           break;  /* 10 */
4400
4401         case 6:
4402           if (optimize_size)
4403             break;  /* scratch ? 5 : 6 */
4404           *len = 9;
4405           return (AS1 (clr,__tmp_reg__) CR_TAB
4406                   AS1 (lsl,%A0)         CR_TAB
4407                   AS1 (rol,%B0)         CR_TAB
4408                   AS1 (rol,__tmp_reg__) CR_TAB
4409                   AS1 (lsl,%A0)         CR_TAB
4410                   AS1 (rol,%B0)         CR_TAB
4411                   AS1 (rol,__tmp_reg__) CR_TAB
4412                   AS2 (mov,%A0,%B0)     CR_TAB
4413                   AS2 (mov,%B0,__tmp_reg__));
4414
4415         case 7:
4416           *len = 5;
4417           return (AS1 (lsl,%A0)     CR_TAB
4418                   AS2 (mov,%A0,%B0) CR_TAB
4419                   AS1 (rol,%A0)     CR_TAB
4420                   AS2 (sbc,%B0,%B0) CR_TAB
4421                   AS1 (neg,%B0));
4422
4423         case 8:
4424           return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
4425                             AS1 (clr,%B0));
4426
4427         case 9:
4428           *len = 3;
4429           return (AS2 (mov,%A0,%B0) CR_TAB
4430                   AS1 (clr,%B0)     CR_TAB
4431                   AS1 (lsr,%A0));
4432
4433         case 10:
4434           *len = 4;
4435           return (AS2 (mov,%A0,%B0) CR_TAB
4436                   AS1 (clr,%B0)     CR_TAB
4437                   AS1 (lsr,%A0)     CR_TAB
4438                   AS1 (lsr,%A0));
4439
4440         case 11:
4441           *len = 5;
4442           return (AS2 (mov,%A0,%B0) CR_TAB
4443                   AS1 (clr,%B0)     CR_TAB
4444                   AS1 (lsr,%A0)     CR_TAB
4445                   AS1 (lsr,%A0)     CR_TAB
4446                   AS1 (lsr,%A0));
4447
4448         case 12:
4449           if (ldi_ok)
4450             {
4451               *len = 4;
4452               return (AS2 (mov,%A0,%B0) CR_TAB
4453                       AS1 (clr,%B0)     CR_TAB
4454                       AS1 (swap,%A0)    CR_TAB
4455                       AS2 (andi,%A0,0x0f));
4456             }
4457           if (scratch)
4458             {
4459               *len = 5;
4460               return (AS2 (mov,%A0,%B0) CR_TAB
4461                       AS1 (clr,%B0)     CR_TAB
4462                       AS1 (swap,%A0)    CR_TAB
4463                       AS2 (ldi,%3,0x0f) CR_TAB
4464                       "and %A0,%3");
4465             }
4466           *len = 6;
4467           return (AS2 (mov,%A0,%B0) CR_TAB
4468                   AS1 (clr,%B0)     CR_TAB
4469                   AS1 (lsr,%A0)     CR_TAB
4470                   AS1 (lsr,%A0)     CR_TAB
4471                   AS1 (lsr,%A0)     CR_TAB
4472                   AS1 (lsr,%A0));
4473
4474         case 13:
4475           if (ldi_ok)
4476             {
4477               *len = 5;
4478               return (AS2 (mov,%A0,%B0) CR_TAB
4479                       AS1 (clr,%B0)     CR_TAB
4480                       AS1 (swap,%A0)    CR_TAB
4481                       AS1 (lsr,%A0)     CR_TAB
4482                       AS2 (andi,%A0,0x07));
4483             }
4484           if (AVR_HAVE_MUL && scratch)
4485             {
4486               *len = 5;
4487               return (AS2 (ldi,%3,0x08) CR_TAB
4488                       AS2 (mul,%B0,%3)  CR_TAB
4489                       AS2 (mov,%A0,r1)  CR_TAB
4490                       AS1 (clr,%B0)     CR_TAB
4491                       AS1 (clr,__zero_reg__));
4492             }
4493           if (optimize_size && scratch)
4494             break;  /* 5 */
4495           if (scratch)
4496             {
4497               *len = 6;
4498               return (AS2 (mov,%A0,%B0) CR_TAB
4499                       AS1 (clr,%B0)     CR_TAB
4500                       AS1 (swap,%A0)    CR_TAB
4501                       AS1 (lsr,%A0)     CR_TAB
4502                       AS2 (ldi,%3,0x07) CR_TAB
4503                       "and %A0,%3");
4504             }
4505           if (AVR_HAVE_MUL)
4506             {
4507               *len = 6;
4508               return ("set"            CR_TAB
4509                       AS2 (bld,r1,3)   CR_TAB
4510                       AS2 (mul,%B0,r1) CR_TAB
4511                       AS2 (mov,%A0,r1) CR_TAB
4512                       AS1 (clr,%B0)    CR_TAB
4513                       AS1 (clr,__zero_reg__));
4514             }
4515           *len = 7;
4516           return (AS2 (mov,%A0,%B0) CR_TAB
4517                   AS1 (clr,%B0)     CR_TAB
4518                   AS1 (lsr,%A0)     CR_TAB
4519                   AS1 (lsr,%A0)     CR_TAB
4520                   AS1 (lsr,%A0)     CR_TAB
4521                   AS1 (lsr,%A0)     CR_TAB
4522                   AS1 (lsr,%A0));
4523
4524         case 14:
4525           if (AVR_HAVE_MUL && ldi_ok)
4526             {
4527               *len = 5;
4528               return (AS2 (ldi,%A0,0x04) CR_TAB
4529                       AS2 (mul,%B0,%A0)  CR_TAB
4530                       AS2 (mov,%A0,r1)   CR_TAB
4531                       AS1 (clr,%B0)      CR_TAB
4532                       AS1 (clr,__zero_reg__));
4533             }
4534           if (AVR_HAVE_MUL && scratch)
4535             {
4536               *len = 5;
4537               return (AS2 (ldi,%3,0x04) CR_TAB
4538                       AS2 (mul,%B0,%3)  CR_TAB
4539                       AS2 (mov,%A0,r1)  CR_TAB
4540                       AS1 (clr,%B0)     CR_TAB
4541                       AS1 (clr,__zero_reg__));
4542             }
4543           if (optimize_size && ldi_ok)
4544             {
4545               *len = 5;
4546               return (AS2 (mov,%A0,%B0) CR_TAB
4547                       AS2 (ldi,%B0,6) "\n1:\t"
4548                       AS1 (lsr,%A0)     CR_TAB
4549                       AS1 (dec,%B0)     CR_TAB
4550                       AS1 (brne,1b));
4551             }
4552           if (optimize_size && scratch)
4553             break;  /* 5 */
4554           *len = 6;
4555           return (AS1 (clr,%A0) CR_TAB
4556                   AS1 (lsl,%B0) CR_TAB
4557                   AS1 (rol,%A0) CR_TAB
4558                   AS1 (lsl,%B0) CR_TAB
4559                   AS1 (rol,%A0) CR_TAB
4560                   AS1 (clr,%B0));
4561
4562         case 15:
4563           *len = 4;
4564           return (AS1 (clr,%A0) CR_TAB
4565                   AS1 (lsl,%B0) CR_TAB
4566                   AS1 (rol,%A0) CR_TAB
4567                   AS1 (clr,%B0));
4568         }
4569       len = t;
4570     }
4571   out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4572                        AS1 (ror,%A0)),
4573                        insn, operands, len, 2);
4574   return "";
4575 }
4576
4577 /* 32bit logic shift right ((unsigned int)x >> i) */
4578
4579 const char *
4580 lshrsi3_out (rtx insn, rtx operands[], int *len)
4581 {
4582   if (GET_CODE (operands[2]) == CONST_INT)
4583     {
4584       int k;
4585       int *t = len;
4586       
4587       if (!len)
4588         len = &k;
4589       
4590       switch (INTVAL (operands[2]))
4591         {
4592         default:
4593           if (INTVAL (operands[2]) < 32)
4594             break;
4595
4596           if (AVR_HAVE_MOVW)
4597             return *len = 3, (AS1 (clr,%D0) CR_TAB
4598                               AS1 (clr,%C0) CR_TAB
4599                               AS2 (movw,%A0,%C0));
4600           *len = 4;
4601           return (AS1 (clr,%D0) CR_TAB
4602                   AS1 (clr,%C0) CR_TAB
4603                   AS1 (clr,%B0) CR_TAB
4604                   AS1 (clr,%A0));
4605
4606         case 8:
4607           {
4608             int reg0 = true_regnum (operands[0]);
4609             int reg1 = true_regnum (operands[1]);
4610             *len = 4;
4611             if (reg0 <= reg1)
4612               return (AS2 (mov,%A0,%B1) CR_TAB
4613                       AS2 (mov,%B0,%C1) CR_TAB
4614                       AS2 (mov,%C0,%D1) CR_TAB
4615                       AS1 (clr,%D0));
4616             else
4617               return (AS1 (clr,%D0)     CR_TAB
4618                       AS2 (mov,%C0,%D1) CR_TAB
4619                       AS2 (mov,%B0,%C1) CR_TAB
4620                       AS2 (mov,%A0,%B1)); 
4621           }
4622           
4623         case 16:
4624           {
4625             int reg0 = true_regnum (operands[0]);
4626             int reg1 = true_regnum (operands[1]);
4627
4628             if (reg0 == reg1 + 2)
4629               return *len = 2, (AS1 (clr,%C0)     CR_TAB
4630                                 AS1 (clr,%D0));
4631             if (AVR_HAVE_MOVW)
4632               return *len = 3, (AS2 (movw,%A0,%C1) CR_TAB
4633                                 AS1 (clr,%C0)      CR_TAB
4634                                 AS1 (clr,%D0));
4635             else
4636               return *len = 4, (AS2 (mov,%B0,%D1) CR_TAB
4637                                 AS2 (mov,%A0,%C1) CR_TAB
4638                                 AS1 (clr,%C0)     CR_TAB
4639                                 AS1 (clr,%D0));
4640           }
4641           
4642         case 24:
4643           return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4644                             AS1 (clr,%B0)     CR_TAB
4645                             AS1 (clr,%C0)     CR_TAB
4646                             AS1 (clr,%D0));
4647
4648         case 31:
4649           *len = 6;
4650           return (AS1 (clr,%A0)    CR_TAB
4651                   AS2 (sbrc,%D0,7) CR_TAB
4652                   AS1 (inc,%A0)    CR_TAB
4653                   AS1 (clr,%B0)    CR_TAB
4654                   AS1 (clr,%C0)    CR_TAB
4655                   AS1 (clr,%D0));
4656         }
4657       len = t;
4658     }
4659   out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4660                        AS1 (ror,%C0) CR_TAB
4661                        AS1 (ror,%B0) CR_TAB
4662                        AS1 (ror,%A0)),
4663                       insn, operands, len, 4);
4664   return "";
4665 }
4666
4667
4668 /* Output addition of register XOP[0] and compile time constant XOP[2]:
4669
4670       XOP[0] = XOP[0] + XOP[2]
4671
4672    and return "".  If PLEN == NULL, print assembler instructions to perform the
4673    addition; otherwise, set *PLEN to the length of the instruction sequence (in
4674    words) printed with PLEN == NULL.  XOP[3] is an 8-bit scratch register.
4675    CODE == PLUS:  perform addition by using ADD instructions.
4676    CODE == MINUS: perform addition by using SUB instructions.  */
4677
4678 static void
4679 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code)
4680 {
4681   /* MODE of the operation.  */
4682   enum machine_mode mode = GET_MODE (xop[0]);
4683
4684   /* Number of bytes to operate on.  */
4685   int i, n_bytes = GET_MODE_SIZE (mode);
4686
4687   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
4688   int clobber_val = -1;
4689
4690   /* op[0]: 8-bit destination register
4691      op[1]: 8-bit const int
4692      op[2]: 8-bit scratch register */
4693   rtx op[3];
4694
4695   /* Started the operation?  Before starting the operation we may skip
4696      adding 0.  This is no more true after the operation started because
4697      carry must be taken into account.  */
4698   bool started = false;
4699
4700   /* Value to add.  There are two ways to add VAL: R += VAL and R -= -VAL.  */
4701   rtx xval = xop[2];
4702
4703   if (MINUS == code)
4704     xval = gen_int_mode (-UINTVAL (xval), mode);
4705
4706   op[2] = xop[3];
4707
4708   if (plen)
4709     *plen = 0;
4710
4711   for (i = 0; i < n_bytes; i++)
4712     {
4713       /* We operate byte-wise on the destination.  */
4714       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
4715       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
4716
4717       /* 8-bit value to operate with this byte. */
4718       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
4719
4720       /* Registers R16..R31 can operate with immediate.  */
4721       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
4722
4723       op[0] = reg8;
4724       op[1] = GEN_INT (val8);
4725       
4726       if (!started && i % 2 == 0
4727           && test_hard_reg_class (ADDW_REGS, reg8))
4728         {
4729           rtx xval16 = simplify_gen_subreg (HImode, xval, mode, i);
4730           unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
4731
4732           /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
4733              i.e. operate word-wise.  */
4734
4735           if (val16 < 64)
4736             {
4737               if (val16 != 0)
4738                 {
4739                   started = true;
4740                   avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
4741                                op, plen, 1);
4742                 }
4743
4744               i++;
4745               continue;
4746             }
4747         }
4748
4749       if (val8 == 0)
4750         {
4751           if (started)
4752             avr_asm_len (code == PLUS
4753                          ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
4754                          op, plen, 1);
4755           continue;
4756         }
4757
4758       switch (code)
4759         {
4760         case PLUS:
4761
4762           gcc_assert (plen != NULL || REG_P (op[2]));
4763
4764           if (clobber_val != (int) val8)
4765             avr_asm_len ("ldi %2,%1", op, plen, 1);
4766           clobber_val = (int) val8;
4767               
4768           avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
4769
4770           break; /* PLUS */
4771
4772         case MINUS:
4773
4774           if (ld_reg_p)
4775             avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
4776           else
4777             {
4778               gcc_assert (plen != NULL || REG_P (op[2]));
4779
4780               if (clobber_val != (int) val8)
4781                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4782               clobber_val = (int) val8;
4783               
4784               avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
4785             }
4786
4787           break; /* MINUS */
4788           
4789         default:
4790           /* Unknown code */
4791           gcc_unreachable();
4792         }
4793
4794       started = true;
4795
4796     } /* for all sub-bytes */
4797 }
4798
4799
4800 /* Output addition of register XOP[0] and compile time constant XOP[2]:
4801
4802       XOP[0] = XOP[0] + XOP[2]
4803
4804    and return "".  If PLEN == NULL, print assembler instructions to perform the
4805    addition; otherwise, set *PLEN to the length of the instruction sequence (in
4806    words) printed with PLEN == NULL.  */
4807
4808 const char*
4809 avr_out_plus (rtx *xop, int *plen)
4810 {
4811   int len_plus, len_minus;
4812
4813   /* Work out if  XOP[0] += XOP[2]  is better or  XOP[0] -= -XOP[2].  */
4814   
4815   avr_out_plus_1 (xop, &len_plus, PLUS);
4816   avr_out_plus_1 (xop, &len_minus, MINUS);
4817
4818   if (plen)
4819     *plen = (len_minus <= len_plus) ? len_minus : len_plus;
4820   else if (len_minus <= len_plus)
4821     avr_out_plus_1 (xop, NULL, MINUS);
4822   else
4823     avr_out_plus_1 (xop, NULL, PLUS);
4824
4825   return "";
4826 }
4827
4828
4829 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
4830    time constant XOP[2]:
4831
4832       XOP[0] = XOP[0] <op> XOP[2]
4833
4834    and return "".  If PLEN == NULL, print assembler instructions to perform the
4835    operation; otherwise, set *PLEN to the length of the instruction sequence
4836    (in words) printed with PLEN == NULL.  XOP[3] is either an 8-bit clobber
4837    register or SCRATCH if no clobber register is needed for the operation.  */
4838
4839 const char*
4840 avr_out_bitop (rtx insn, rtx *xop, int *plen)
4841 {
4842   /* CODE and MODE of the operation.  */
4843   enum rtx_code code = GET_CODE (SET_SRC (single_set (insn)));
4844   enum machine_mode mode = GET_MODE (xop[0]);
4845
4846   /* Number of bytes to operate on.  */
4847   int i, n_bytes = GET_MODE_SIZE (mode);
4848
4849   /* Value of T-flag (0 or 1) or -1 if unknow.  */
4850   int set_t = -1;
4851
4852   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
4853   int clobber_val = -1;
4854
4855   /* op[0]: 8-bit destination register
4856      op[1]: 8-bit const int
4857      op[2]: 8-bit clobber register or SCRATCH
4858      op[3]: 8-bit register containing 0xff or NULL_RTX  */
4859   rtx op[4];
4860
4861   op[2] = xop[3];
4862   op[3] = NULL_RTX;
4863
4864   if (plen)
4865     *plen = 0;
4866
4867   for (i = 0; i < n_bytes; i++)
4868     {
4869       /* We operate byte-wise on the destination.  */
4870       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
4871       rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
4872
4873       /* 8-bit value to operate with this byte. */
4874       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
4875
4876       /* Number of bits set in the current byte of the constant.  */
4877       int pop8 = avr_popcount (val8);
4878
4879       /* Registers R16..R31 can operate with immediate.  */
4880       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
4881
4882       op[0] = reg8;
4883       op[1] = GEN_INT (val8);
4884     
4885       switch (code)
4886         {
4887         case IOR:
4888
4889           if (0 == pop8)
4890             continue;
4891           else if (ld_reg_p)
4892             avr_asm_len ("ori %0,%1", op, plen, 1);
4893           else if (1 == pop8)
4894             {
4895               if (set_t != 1)
4896                 avr_asm_len ("set", op, plen, 1);
4897               set_t = 1;
4898               
4899               op[1] = GEN_INT (exact_log2 (val8));
4900               avr_asm_len ("bld %0,%1", op, plen, 1);
4901             }
4902           else if (8 == pop8)
4903             {
4904               if (op[3] != NULL_RTX)
4905                 avr_asm_len ("mov %0,%3", op, plen, 1);
4906               else
4907                 avr_asm_len ("clr %0" CR_TAB
4908                              "dec %0", op, plen, 2);
4909
4910               op[3] = op[0];
4911             }
4912           else
4913             {
4914               if (clobber_val != (int) val8)
4915                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4916               clobber_val = (int) val8;
4917               
4918               avr_asm_len ("or %0,%2", op, plen, 1);
4919             }
4920
4921           continue; /* IOR */
4922
4923         case AND:
4924
4925           if (8 == pop8)
4926             continue;
4927           else if (0 == pop8)
4928             avr_asm_len ("clr %0", op, plen, 1);
4929           else if (ld_reg_p)
4930             avr_asm_len ("andi %0,%1", op, plen, 1);
4931           else if (7 == pop8)
4932             {
4933               if (set_t != 0)
4934                 avr_asm_len ("clt", op, plen, 1);
4935               set_t = 0;
4936               
4937               op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
4938               avr_asm_len ("bld %0,%1", op, plen, 1);
4939             }
4940           else
4941             {
4942               if (clobber_val != (int) val8)
4943                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4944               clobber_val = (int) val8;
4945               
4946               avr_asm_len ("and %0,%2", op, plen, 1);
4947             }
4948
4949           continue; /* AND */
4950           
4951         case XOR:
4952
4953           if (0 == pop8)
4954             continue;
4955           else if (8 == pop8)
4956             avr_asm_len ("com %0", op, plen, 1);
4957           else if (ld_reg_p && val8 == (1 << 7))
4958             avr_asm_len ("subi %0,%1", op, plen, 1);
4959           else
4960             {
4961               if (clobber_val != (int) val8)
4962                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4963               clobber_val = (int) val8;
4964               
4965               avr_asm_len ("eor %0,%2", op, plen, 1);
4966             }
4967
4968           continue; /* XOR */
4969           
4970         default:
4971           /* Unknown rtx_code */
4972           gcc_unreachable();
4973         }
4974     } /* for all sub-bytes */
4975
4976   return "";
4977 }
4978
4979
4980 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
4981    PLEN != NULL: Set *PLEN to the length of that sequence.
4982    Return "".  */
4983
4984 const char*
4985 avr_out_addto_sp (rtx *op, int *plen)
4986 {
4987   int pc_len = AVR_2_BYTE_PC ? 2 : 3;
4988   int addend = INTVAL (op[0]);
4989
4990   if (plen)
4991     *plen = 0;
4992
4993   if (addend < 0)
4994     {
4995       if (flag_verbose_asm || flag_print_asm_name)
4996         avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
4997   
4998       while (addend <= -pc_len)
4999         {
5000           addend += pc_len;
5001           avr_asm_len ("rcall .", op, plen, 1);
5002         }
5003
5004       while (addend++ < 0)
5005         avr_asm_len ("push __zero_reg__", op, plen, 1);
5006     }
5007   else if (addend > 0)
5008     {
5009       if (flag_verbose_asm || flag_print_asm_name)
5010         avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
5011
5012       while (addend-- > 0)
5013         avr_asm_len ("pop __tmp_reg__", op, plen, 1);
5014     }
5015
5016   return "";
5017 }
5018
5019
5020 /* Create RTL split patterns for byte sized rotate expressions.  This
5021   produces a series of move instructions and considers overlap situations.
5022   Overlapping non-HImode operands need a scratch register.  */
5023
5024 bool
5025 avr_rotate_bytes (rtx operands[])
5026 {
5027     int i, j;
5028     enum machine_mode mode = GET_MODE (operands[0]);
5029     bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
5030     bool same_reg = rtx_equal_p (operands[0], operands[1]);
5031     int num = INTVAL (operands[2]);
5032     rtx scratch = operands[3];
5033     /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
5034        Word move if no scratch is needed, otherwise use size of scratch.  */
5035     enum machine_mode move_mode = QImode;
5036     int move_size, offset, size;
5037
5038     if (num & 0xf)
5039       move_mode = QImode;
5040     else if ((mode == SImode && !same_reg) || !overlapped)
5041       move_mode = HImode;
5042     else
5043       move_mode = GET_MODE (scratch);
5044
5045     /* Force DI rotate to use QI moves since other DI moves are currently split
5046        into QI moves so forward propagation works better.  */
5047     if (mode == DImode)
5048       move_mode = QImode;
5049     /* Make scratch smaller if needed.  */
5050     if (SCRATCH != GET_CODE (scratch)
5051         && HImode == GET_MODE (scratch)
5052         && QImode == move_mode)
5053       scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0); 
5054
5055     move_size = GET_MODE_SIZE (move_mode);
5056     /* Number of bytes/words to rotate.  */
5057     offset = (num  >> 3) / move_size;
5058     /* Number of moves needed.  */
5059     size = GET_MODE_SIZE (mode) / move_size;
5060     /* Himode byte swap is special case to avoid a scratch register.  */
5061     if (mode == HImode && same_reg)
5062       {
5063         /* HImode byte swap, using xor.  This is as quick as using scratch.  */
5064         rtx src, dst;
5065         src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
5066         dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
5067         if (!rtx_equal_p (dst, src))
5068           {
5069              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
5070              emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
5071              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
5072           }
5073       }    
5074     else  
5075       {
5076 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode)  */
5077         /* Create linked list of moves to determine move order.  */
5078         struct {
5079           rtx src, dst;
5080           int links;
5081         } move[MAX_SIZE + 8];
5082         int blocked, moves;
5083
5084         gcc_assert (size <= MAX_SIZE);
5085         /* Generate list of subreg moves.  */
5086         for (i = 0; i < size; i++)
5087           {
5088             int from = i;
5089             int to = (from + offset) % size;          
5090             move[i].src = simplify_gen_subreg (move_mode, operands[1],
5091                                                 mode, from * move_size);
5092             move[i].dst = simplify_gen_subreg (move_mode, operands[0],
5093                                                 mode, to   * move_size);
5094             move[i].links = -1;
5095            }
5096         /* Mark dependence where a dst of one move is the src of another move.
5097            The first move is a conflict as it must wait until second is
5098            performed.  We ignore moves to self - we catch this later.  */
5099         if (overlapped)
5100           for (i = 0; i < size; i++)
5101             if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
5102               for (j = 0; j < size; j++)
5103                 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
5104                   {
5105                     /* The dst of move i is the src of move j.  */
5106                     move[i].links = j;
5107                     break;
5108                   }
5109
5110         blocked = -1;
5111         moves = 0;
5112         /* Go through move list and perform non-conflicting moves.  As each
5113            non-overlapping move is made, it may remove other conflicts
5114            so the process is repeated until no conflicts remain.  */
5115         do
5116           {
5117             blocked = -1;
5118             moves = 0;
5119             /* Emit move where dst is not also a src or we have used that
5120                src already.  */
5121             for (i = 0; i < size; i++)
5122               if (move[i].src != NULL_RTX)
5123                 {
5124                   if (move[i].links == -1
5125                       || move[move[i].links].src == NULL_RTX)
5126                     {
5127                       moves++;
5128                       /* Ignore NOP moves to self.  */
5129                       if (!rtx_equal_p (move[i].dst, move[i].src))
5130                         emit_move_insn (move[i].dst, move[i].src);
5131
5132                       /* Remove  conflict from list.  */
5133                       move[i].src = NULL_RTX;
5134                     }
5135                   else
5136                     blocked = i;
5137                 }
5138
5139             /* Check for deadlock. This is when no moves occurred and we have
5140                at least one blocked move.  */
5141             if (moves == 0 && blocked != -1)
5142               {
5143                 /* Need to use scratch register to break deadlock.
5144                    Add move to put dst of blocked move into scratch.
5145                    When this move occurs, it will break chain deadlock.
5146                    The scratch register is substituted for real move.  */
5147
5148                 gcc_assert (SCRATCH != GET_CODE (scratch));
5149
5150                 move[size].src = move[blocked].dst;
5151                 move[size].dst =  scratch;
5152                 /* Scratch move is never blocked.  */
5153                 move[size].links = -1; 
5154                 /* Make sure we have valid link.  */
5155                 gcc_assert (move[blocked].links != -1);
5156                 /* Replace src of  blocking move with scratch reg.  */
5157                 move[move[blocked].links].src = scratch;
5158                 /* Make dependent on scratch move occuring.  */
5159                 move[blocked].links = size; 
5160                 size=size+1;
5161               }
5162           }
5163         while (blocked != -1);
5164       }
5165     return true;
5166 }
5167
5168 /* Modifies the length assigned to instruction INSN
5169    LEN is the initially computed length of the insn.  */
5170
5171 int
5172 adjust_insn_length (rtx insn, int len)
5173 {
5174   rtx *op = recog_data.operand;
5175   enum attr_adjust_len adjust_len;
5176
5177   /* Some complex insns don't need length adjustment and therefore
5178      the length need not/must not be adjusted for these insns.
5179      It is easier to state this in an insn attribute "adjust_len" than
5180      to clutter up code here...  */
5181   
5182   if (-1 == recog_memoized (insn))
5183     {
5184       return len;
5185     }
5186
5187   /* Read from insn attribute "adjust_len" if/how length is to be adjusted.  */
5188
5189   adjust_len = get_attr_adjust_len (insn);
5190
5191   if (adjust_len == ADJUST_LEN_NO)
5192     {
5193       /* Nothing to adjust: The length from attribute "length" is fine.
5194          This is the default.  */
5195       
5196       return len;
5197     }
5198   
5199   /* Extract insn's operands.  */
5200   
5201   extract_constrain_insn_cached (insn);
5202   
5203   /* Dispatch to right function.  */
5204   
5205   switch (adjust_len)
5206     {
5207     case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
5208     case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
5209       
5210     case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
5211       
5212     case ADJUST_LEN_OUT_PLUS: avr_out_plus (op, &len); break;
5213
5214     case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
5215       
5216     case ADJUST_LEN_MOV8:  output_movqi (insn, op, &len); break;
5217     case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
5218     case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
5219       
5220     case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
5221     case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
5222     case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
5223
5224     case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
5225     case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
5226     case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
5227
5228     case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
5229     case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
5230     case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
5231
5232     case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
5233     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
5234     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
5235       
5236     default:
5237       gcc_unreachable();
5238     }
5239   
5240   return len;
5241 }
5242
5243 /* Return nonzero if register REG dead after INSN.  */
5244
5245 int
5246 reg_unused_after (rtx insn, rtx reg)
5247 {
5248   return (dead_or_set_p (insn, reg)
5249           || (REG_P(reg) && _reg_unused_after (insn, reg)));
5250 }
5251
5252 /* Return nonzero if REG is not used after INSN.
5253    We assume REG is a reload reg, and therefore does
5254    not live past labels.  It may live past calls or jumps though.  */
5255
5256 int
5257 _reg_unused_after (rtx insn, rtx reg)
5258 {
5259   enum rtx_code code;
5260   rtx set;
5261
5262   /* If the reg is set by this instruction, then it is safe for our
5263      case.  Disregard the case where this is a store to memory, since
5264      we are checking a register used in the store address.  */
5265   set = single_set (insn);
5266   if (set && GET_CODE (SET_DEST (set)) != MEM
5267       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
5268     return 1;
5269
5270   while ((insn = NEXT_INSN (insn)))
5271     {
5272       rtx set;
5273       code = GET_CODE (insn);
5274
5275 #if 0
5276       /* If this is a label that existed before reload, then the register
5277          if dead here.  However, if this is a label added by reorg, then
5278          the register may still be live here.  We can't tell the difference,
5279          so we just ignore labels completely.  */
5280       if (code == CODE_LABEL)
5281         return 1;
5282       /* else */
5283 #endif
5284
5285       if (!INSN_P (insn))
5286         continue;
5287
5288       if (code == JUMP_INSN)
5289         return 0;
5290
5291       /* If this is a sequence, we must handle them all at once.
5292          We could have for instance a call that sets the target register,
5293          and an insn in a delay slot that uses the register.  In this case,
5294          we must return 0.  */
5295       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
5296         {
5297           int i;
5298           int retval = 0;
5299
5300           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
5301             {
5302               rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
5303               rtx set = single_set (this_insn);
5304
5305               if (GET_CODE (this_insn) == CALL_INSN)
5306                 code = CALL_INSN;
5307               else if (GET_CODE (this_insn) == JUMP_INSN)
5308                 {
5309                   if (INSN_ANNULLED_BRANCH_P (this_insn))
5310                     return 0;
5311                   code = JUMP_INSN;
5312                 }
5313
5314               if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
5315                 return 0;
5316               if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
5317                 {
5318                   if (GET_CODE (SET_DEST (set)) != MEM)
5319                     retval = 1;
5320                   else
5321                     return 0;
5322                 }
5323               if (set == 0
5324                   && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
5325                 return 0;
5326             }
5327           if (retval == 1)
5328             return 1;
5329           else if (code == JUMP_INSN)
5330             return 0;
5331         }
5332
5333       if (code == CALL_INSN)
5334         {
5335           rtx tem;
5336           for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
5337             if (GET_CODE (XEXP (tem, 0)) == USE
5338                 && REG_P (XEXP (XEXP (tem, 0), 0))
5339                 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
5340               return 0;
5341           if (call_used_regs[REGNO (reg)]) 
5342             return 1;
5343         }
5344
5345       set = single_set (insn);
5346
5347       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
5348         return 0;
5349       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
5350         return GET_CODE (SET_DEST (set)) != MEM;
5351       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
5352         return 0;
5353     }
5354   return 1;
5355 }
5356
5357 /* Target hook for assembling integer objects.  The AVR version needs
5358    special handling for references to certain labels.  */
5359
5360 static bool
5361 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
5362 {
5363   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
5364       && text_segment_operand (x, VOIDmode) )
5365     {
5366       fputs ("\t.word\tgs(", asm_out_file);
5367       output_addr_const (asm_out_file, x);
5368       fputs (")\n", asm_out_file);
5369       return true;
5370     }
5371   return default_assemble_integer (x, size, aligned_p);
5372 }
5373
5374 /* Worker function for ASM_DECLARE_FUNCTION_NAME.  */
5375
5376 void
5377 avr_asm_declare_function_name (FILE *file, const char *name, tree decl)
5378 {
5379
5380   /* If the function has the 'signal' or 'interrupt' attribute, test to
5381      make sure that the name of the function is "__vector_NN" so as to
5382      catch when the user misspells the interrupt vector name.  */
5383
5384   if (cfun->machine->is_interrupt)
5385     {
5386       if (!STR_PREFIX_P (name, "__vector"))
5387         {
5388           warning_at (DECL_SOURCE_LOCATION (decl), 0,
5389                       "%qs appears to be a misspelled interrupt handler",
5390                       name);
5391         }
5392     }
5393   else if (cfun->machine->is_signal)
5394     {
5395       if (!STR_PREFIX_P (name, "__vector"))
5396         {
5397            warning_at (DECL_SOURCE_LOCATION (decl), 0,
5398                        "%qs appears to be a misspelled signal handler",
5399                        name);
5400         }
5401     }
5402
5403   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
5404   ASM_OUTPUT_LABEL (file, name);
5405 }
5406
5407
5408 /* Return value is nonzero if pseudos that have been
5409    assigned to registers of class CLASS would likely be spilled
5410    because registers of CLASS are needed for spill registers.  */
5411
5412 static bool
5413 avr_class_likely_spilled_p (reg_class_t c)
5414 {
5415   return (c != ALL_REGS && c != ADDW_REGS);
5416 }
5417
5418 /* Valid attributes:
5419    progmem - put data to program memory;
5420    signal - make a function to be hardware interrupt. After function
5421    prologue interrupts are disabled;
5422    interrupt - make a function to be hardware interrupt. After function
5423    prologue interrupts are enabled;
5424    naked     - don't generate function prologue/epilogue and `ret' command.
5425
5426    Only `progmem' attribute valid for type.  */
5427
5428 /* Handle a "progmem" attribute; arguments as in
5429    struct attribute_spec.handler.  */
5430 static tree
5431 avr_handle_progmem_attribute (tree *node, tree name,
5432                               tree args ATTRIBUTE_UNUSED,
5433                               int flags ATTRIBUTE_UNUSED,
5434                               bool *no_add_attrs)
5435 {
5436   if (DECL_P (*node))
5437     {
5438       if (TREE_CODE (*node) == TYPE_DECL)
5439         {
5440           /* This is really a decl attribute, not a type attribute,
5441              but try to handle it for GCC 3.0 backwards compatibility.  */
5442
5443           tree type = TREE_TYPE (*node);
5444           tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
5445           tree newtype = build_type_attribute_variant (type, attr);
5446
5447           TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
5448           TREE_TYPE (*node) = newtype;
5449           *no_add_attrs = true;
5450         }
5451       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
5452         {
5453           *no_add_attrs = false;
5454         }
5455       else
5456         {
5457           warning (OPT_Wattributes, "%qE attribute ignored",
5458                    name);
5459           *no_add_attrs = true;
5460         }
5461     }
5462
5463   return NULL_TREE;
5464 }
5465
5466 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
5467    struct attribute_spec.handler.  */
5468
5469 static tree
5470 avr_handle_fndecl_attribute (tree *node, tree name,
5471                              tree args ATTRIBUTE_UNUSED,
5472                              int flags ATTRIBUTE_UNUSED,
5473                              bool *no_add_attrs)
5474 {
5475   if (TREE_CODE (*node) != FUNCTION_DECL)
5476     {
5477       warning (OPT_Wattributes, "%qE attribute only applies to functions",
5478                name);
5479       *no_add_attrs = true;
5480     }
5481
5482   return NULL_TREE;
5483 }
5484
5485 static tree
5486 avr_handle_fntype_attribute (tree *node, tree name,
5487                              tree args ATTRIBUTE_UNUSED,
5488                              int flags ATTRIBUTE_UNUSED,
5489                              bool *no_add_attrs)
5490 {
5491   if (TREE_CODE (*node) != FUNCTION_TYPE)
5492     {
5493       warning (OPT_Wattributes, "%qE attribute only applies to functions",
5494                name);
5495       *no_add_attrs = true;
5496     }
5497
5498   return NULL_TREE;
5499 }
5500
5501 /* Look for attribute `progmem' in DECL
5502    if found return 1, otherwise 0.  */
5503
5504 int
5505 avr_progmem_p (tree decl, tree attributes)
5506 {
5507   tree a;
5508
5509   if (TREE_CODE (decl) != VAR_DECL)
5510     return 0;
5511
5512   if (NULL_TREE
5513       != lookup_attribute ("progmem", attributes))
5514     return 1;
5515
5516   a=decl;
5517   do
5518     a = TREE_TYPE(a);
5519   while (TREE_CODE (a) == ARRAY_TYPE);
5520
5521   if (a == error_mark_node)
5522     return 0;
5523
5524   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
5525     return 1;
5526   
5527   return 0;
5528 }
5529
5530 /* Add the section attribute if the variable is in progmem.  */
5531
5532 static void
5533 avr_insert_attributes (tree node, tree *attributes)
5534 {
5535   if (TREE_CODE (node) == VAR_DECL
5536       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
5537       && avr_progmem_p (node, *attributes))
5538     {
5539       tree node0 = node;
5540
5541       /* For C++, we have to peel arrays in order to get correct
5542          determination of readonlyness.  */
5543       
5544       do
5545         node0 = TREE_TYPE (node0);
5546       while (TREE_CODE (node0) == ARRAY_TYPE);
5547
5548       if (error_mark_node == node0)
5549         return;
5550       
5551       if (!TYPE_READONLY (node0))
5552         {
5553           error ("variable %q+D must be const in order to be put into"
5554                  " read-only section by means of %<__attribute__((progmem))%>",
5555                  node);
5556         }
5557     }
5558 }
5559
5560
5561 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
5562 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
5563 /* Track need of __do_clear_bss.  */
5564
5565 void
5566 avr_asm_output_aligned_decl_common (FILE * stream, const_tree decl ATTRIBUTE_UNUSED,
5567                                     const char *name, unsigned HOST_WIDE_INT size,
5568                                     unsigned int align, bool local_p)
5569 {
5570   avr_need_clear_bss_p = true;
5571
5572   if (local_p)
5573     ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
5574   else
5575     ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
5576 }
5577
5578
5579 /* Unnamed section callback for data_section
5580    to track need of __do_copy_data.  */
5581
5582 static void
5583 avr_output_data_section_asm_op (const void *data)
5584 {
5585   avr_need_copy_data_p = true;
5586   
5587   /* Dispatch to default.  */
5588   output_section_asm_op (data);
5589 }
5590
5591
5592 /* Unnamed section callback for bss_section
5593    to track need of __do_clear_bss.  */
5594
5595 static void
5596 avr_output_bss_section_asm_op (const void *data)
5597 {
5598   avr_need_clear_bss_p = true;
5599   
5600   /* Dispatch to default.  */
5601   output_section_asm_op (data);
5602 }
5603
5604
5605 /* Implement `TARGET_ASM_INIT_SECTIONS'.  */
5606
5607 static void
5608 avr_asm_init_sections (void)
5609 {
5610   /* Set up a section for jump tables.  Alignment is handled by
5611      ASM_OUTPUT_BEFORE_CASE_LABEL.  */
5612   
5613   if (AVR_HAVE_JMP_CALL)
5614     {
5615       progmem_swtable_section
5616         = get_unnamed_section (0, output_section_asm_op,
5617                                "\t.section\t.progmem.gcc_sw_table"
5618                                ",\"a\",@progbits");
5619     }
5620   else
5621     {
5622       progmem_swtable_section
5623         = get_unnamed_section (SECTION_CODE, output_section_asm_op,
5624                                "\t.section\t.progmem.gcc_sw_table"
5625                                ",\"ax\",@progbits");
5626     }
5627
5628   progmem_section
5629     = get_unnamed_section (0, output_section_asm_op,
5630                            "\t.section\t.progmem.data,\"a\",@progbits");
5631   
5632   /* Override section callbacks to keep track of `avr_need_clear_bss_p'
5633      resp. `avr_need_copy_data_p'.  */
5634   
5635   readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
5636   data_section->unnamed.callback = avr_output_data_section_asm_op;
5637   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
5638 }
5639
5640
5641 /* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'.  */
5642
5643 static section*
5644 avr_asm_function_rodata_section (tree decl)
5645 {
5646   /* If a function is unused and optimized out by -ffunction-sections
5647      and --gc-sections, ensure that the same will happen for its jump
5648      tables by putting them into individual sections.  */
5649
5650   unsigned int flags;
5651   section * frodata;
5652
5653   /* Get the frodata section from the default function in varasm.c
5654      but treat function-associated data-like jump tables as code
5655      rather than as user defined data.  AVR has no constant pools.  */
5656   {
5657     int fdata = flag_data_sections;
5658
5659     flag_data_sections = flag_function_sections;
5660     frodata = default_function_rodata_section (decl);
5661     flag_data_sections = fdata;
5662     flags = frodata->common.flags;
5663   }
5664
5665   if (frodata != readonly_data_section
5666       && flags & SECTION_NAMED)
5667     {
5668       /* Adjust section flags and replace section name prefix.  */
5669
5670       unsigned int i;
5671
5672       static const char* const prefix[] =
5673         {
5674           ".rodata",          ".progmem.gcc_sw_table",
5675           ".gnu.linkonce.r.", ".gnu.linkonce.t."
5676         };
5677
5678       for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2)
5679         {
5680           const char * old_prefix = prefix[i];
5681           const char * new_prefix = prefix[i+1];
5682           const char * name = frodata->named.name;
5683
5684           if (STR_PREFIX_P (name, old_prefix))
5685             {
5686               const char *rname = avr_replace_prefix (name, old_prefix, new_prefix);
5687
5688               flags &= ~SECTION_CODE;
5689               flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
5690               
5691               return get_section (rname, flags, frodata->named.decl);
5692             }
5693         }
5694     }
5695         
5696   return progmem_swtable_section;
5697 }
5698
5699
5700 /* Implement `TARGET_ASM_NAMED_SECTION'.  */
5701 /* Track need of __do_clear_bss, __do_copy_data for named sections.  */
5702
5703 static void
5704 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
5705 {
5706   if (flags & AVR_SECTION_PROGMEM)
5707     {
5708       const char *old_prefix = ".rodata";
5709       const char *new_prefix = ".progmem.data";
5710       const char *sname = new_prefix;
5711       
5712       if (STR_PREFIX_P (name, old_prefix))
5713         {
5714           sname = avr_replace_prefix (name, old_prefix, new_prefix);
5715         }
5716
5717       default_elf_asm_named_section (sname, flags, decl);
5718
5719       return;
5720     }
5721   
5722   if (!avr_need_copy_data_p)
5723     avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
5724                             || STR_PREFIX_P (name, ".rodata")
5725                             || STR_PREFIX_P (name, ".gnu.linkonce.d"));
5726   
5727   if (!avr_need_clear_bss_p)
5728     avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
5729   
5730   default_elf_asm_named_section (name, flags, decl);
5731 }
5732
5733 static unsigned int
5734 avr_section_type_flags (tree decl, const char *name, int reloc)
5735 {
5736   unsigned int flags = default_section_type_flags (decl, name, reloc);
5737
5738   if (STR_PREFIX_P (name, ".noinit"))
5739     {
5740       if (decl && TREE_CODE (decl) == VAR_DECL
5741           && DECL_INITIAL (decl) == NULL_TREE)
5742         flags |= SECTION_BSS;  /* @nobits */
5743       else
5744         warning (0, "only uninitialized variables can be placed in the "
5745                  ".noinit section");
5746     }
5747
5748   if (decl && DECL_P (decl)
5749       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
5750     {
5751       flags &= ~SECTION_WRITE;
5752       flags |= AVR_SECTION_PROGMEM;
5753     }
5754   
5755   return flags;
5756 }
5757
5758
5759 /* Implement `TARGET_ENCODE_SECTION_INFO'.  */
5760
5761 static void
5762 avr_encode_section_info (tree decl, rtx rtl,
5763                          int new_decl_p)
5764 {
5765   /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
5766      readily available, see PR34734.  So we postpone the warning
5767      about uninitialized data in program memory section until here.  */
5768    
5769   if (new_decl_p
5770       && decl && DECL_P (decl)
5771       && NULL_TREE == DECL_INITIAL (decl)
5772       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
5773     {
5774       warning (OPT_Wuninitialized,
5775                "uninitialized variable %q+D put into "
5776                "program memory area", decl);
5777     }
5778
5779   default_encode_section_info (decl, rtl, new_decl_p);
5780 }
5781
5782
5783 /* Implement `TARGET_ASM_SELECT_SECTION' */
5784
5785 static section *
5786 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
5787 {
5788   section * sect = default_elf_select_section (decl, reloc, align);
5789   
5790   if (decl && DECL_P (decl)
5791       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
5792     {
5793       if (sect->common.flags & SECTION_NAMED)
5794         {
5795           const char * name = sect->named.name;
5796           const char * old_prefix = ".rodata";
5797           const char * new_prefix = ".progmem.data";
5798
5799           if (STR_PREFIX_P (name, old_prefix))
5800             {
5801               const char *sname = avr_replace_prefix (name, old_prefix, new_prefix);
5802
5803               return get_section (sname, sect->common.flags, sect->named.decl);
5804             }
5805         }
5806           
5807       return progmem_section;
5808     }
5809
5810   return sect;
5811 }
5812
5813 /* Implement `TARGET_ASM_FILE_START'.  */
5814 /* Outputs some appropriate text to go at the start of an assembler
5815    file.  */
5816
5817 static void
5818 avr_file_start (void)
5819 {
5820   if (avr_current_arch->asm_only)
5821     error ("MCU %qs supported for assembler only", avr_current_device->name);
5822
5823   default_file_start ();
5824
5825 /*  fprintf (asm_out_file, "\t.arch %s\n", avr_current_device->name);*/
5826   fputs ("__SREG__ = 0x3f\n"
5827          "__SP_H__ = 0x3e\n"
5828          "__SP_L__ = 0x3d\n", asm_out_file);
5829   
5830   fputs ("__tmp_reg__ = 0\n" 
5831          "__zero_reg__ = 1\n", asm_out_file);
5832 }
5833
5834
5835 /* Implement `TARGET_ASM_FILE_END'.  */
5836 /* Outputs to the stdio stream FILE some
5837    appropriate text to go at the end of an assembler file.  */
5838
5839 static void
5840 avr_file_end (void)
5841 {
5842   /* Output these only if there is anything in the
5843      .data* / .rodata* / .gnu.linkonce.* resp. .bss*
5844      input section(s) - some code size can be saved by not
5845      linking in the initialization code from libgcc if resp.
5846      sections are empty.  */
5847
5848   if (avr_need_copy_data_p)
5849     fputs (".global __do_copy_data\n", asm_out_file);
5850
5851   if (avr_need_clear_bss_p)
5852     fputs (".global __do_clear_bss\n", asm_out_file);
5853 }
5854
5855 /* Choose the order in which to allocate hard registers for
5856    pseudo-registers local to a basic block.
5857
5858    Store the desired register order in the array `reg_alloc_order'.
5859    Element 0 should be the register to allocate first; element 1, the
5860    next register; and so on.  */
5861
5862 void
5863 order_regs_for_local_alloc (void)
5864 {
5865   unsigned int i;
5866   static const int order_0[] = {
5867     24,25,
5868     18,19,
5869     20,21,
5870     22,23,
5871     30,31,
5872     26,27,
5873     28,29,
5874     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5875     0,1,
5876     32,33,34,35
5877   };
5878   static const int order_1[] = {
5879     18,19,
5880     20,21,
5881     22,23,
5882     24,25,
5883     30,31,
5884     26,27,
5885     28,29,
5886     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5887     0,1,
5888     32,33,34,35
5889   };
5890   static const int order_2[] = {
5891     25,24,
5892     23,22,
5893     21,20,
5894     19,18,
5895     30,31,
5896     26,27,
5897     28,29,
5898     17,16,
5899     15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5900     1,0,
5901     32,33,34,35
5902   };
5903   
5904   const int *order = (TARGET_ORDER_1 ? order_1 :
5905                       TARGET_ORDER_2 ? order_2 :
5906                       order_0);
5907   for (i=0; i < ARRAY_SIZE (order_0); ++i)
5908       reg_alloc_order[i] = order[i];
5909 }
5910
5911
5912 /* Implement `TARGET_REGISTER_MOVE_COST' */
5913
5914 static int
5915 avr_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
5916                         reg_class_t from, reg_class_t to)
5917 {
5918   return (from == STACK_REG ? 6
5919           : to == STACK_REG ? 12
5920           : 2);
5921 }
5922
5923
5924 /* Implement `TARGET_MEMORY_MOVE_COST' */
5925
5926 static int
5927 avr_memory_move_cost (enum machine_mode mode, reg_class_t rclass ATTRIBUTE_UNUSED,
5928                       bool in ATTRIBUTE_UNUSED)
5929 {
5930   return (mode == QImode ? 2
5931           : mode == HImode ? 4
5932           : mode == SImode ? 8
5933           : mode == SFmode ? 8
5934           : 16);
5935 }
5936
5937
5938 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
5939    cost of an RTX operand given its context.  X is the rtx of the
5940    operand, MODE is its mode, and OUTER is the rtx_code of this
5941    operand's parent operator.  */
5942
5943 static int
5944 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
5945                       int opno, bool speed)
5946 {
5947   enum rtx_code code = GET_CODE (x);
5948   int total;
5949
5950   switch (code)
5951     {
5952     case REG:
5953     case SUBREG:
5954       return 0;
5955
5956     case CONST_INT:
5957     case CONST_DOUBLE:
5958       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
5959
5960     default:
5961       break;
5962     }
5963
5964   total = 0;
5965   avr_rtx_costs (x, code, outer, opno, &total, speed);
5966   return total;
5967 }
5968
5969 /* Worker function for AVR backend's rtx_cost function.
5970    X is rtx expression whose cost is to be calculated.
5971    Return true if the complete cost has been computed.
5972    Return false if subexpressions should be scanned.
5973    In either case, *TOTAL contains the cost result.  */
5974
5975 static bool
5976 avr_rtx_costs_1 (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
5977                  int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5978 {
5979   enum rtx_code code = (enum rtx_code) codearg;
5980   enum machine_mode mode = GET_MODE (x);
5981   HOST_WIDE_INT val;
5982
5983   switch (code)
5984     {
5985     case CONST_INT:
5986     case CONST_DOUBLE:
5987     case SYMBOL_REF:
5988     case CONST:
5989     case LABEL_REF:
5990       /* Immediate constants are as cheap as registers.  */
5991       *total = 0;
5992       return true;
5993
5994     case MEM:
5995       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5996       return true;
5997
5998     case NEG:
5999       switch (mode)
6000         {
6001         case QImode:
6002         case SFmode:
6003           *total = COSTS_N_INSNS (1);
6004           break;
6005
6006         case HImode:
6007           *total = COSTS_N_INSNS (3);
6008           break;
6009
6010         case SImode:
6011           *total = COSTS_N_INSNS (7);
6012           break;
6013
6014         default:
6015           return false;
6016         }
6017       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6018       return true;
6019
6020     case ABS:
6021       switch (mode)
6022         {
6023         case QImode:
6024         case SFmode:
6025           *total = COSTS_N_INSNS (1);
6026           break;
6027
6028         default:
6029           return false;
6030         }
6031       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6032       return true;
6033
6034     case NOT:
6035       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
6036       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6037       return true;
6038
6039     case ZERO_EXTEND:
6040       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
6041                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
6042       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6043       return true;
6044
6045     case SIGN_EXTEND:
6046       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
6047                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
6048       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6049       return true;
6050
6051     case PLUS:
6052       switch (mode)
6053         {
6054         case QImode:
6055           if (AVR_HAVE_MUL
6056               && MULT == GET_CODE (XEXP (x, 0))
6057               && register_operand (XEXP (x, 1), QImode))
6058             {
6059               /* multiply-add */
6060               *total = COSTS_N_INSNS (speed ? 4 : 3);
6061               /* multiply-add with constant: will be split and load constant. */
6062               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
6063                 *total = COSTS_N_INSNS (1) + *total;
6064               return true;
6065             }
6066           *total = COSTS_N_INSNS (1);
6067           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6068             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6069           break;
6070
6071         case HImode:
6072           if (AVR_HAVE_MUL
6073               && (MULT == GET_CODE (XEXP (x, 0))
6074                   || ASHIFT == GET_CODE (XEXP (x, 0)))
6075               && register_operand (XEXP (x, 1), HImode)
6076               && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
6077                   || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
6078             {
6079               /* multiply-add */
6080               *total = COSTS_N_INSNS (speed ? 5 : 4);
6081               /* multiply-add with constant: will be split and load constant. */
6082               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
6083                 *total = COSTS_N_INSNS (1) + *total;
6084               return true;
6085             }
6086           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6087             {
6088               *total = COSTS_N_INSNS (2);
6089               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6090                                               speed);
6091             }
6092           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
6093             *total = COSTS_N_INSNS (1);
6094           else
6095             *total = COSTS_N_INSNS (2);
6096           break;
6097
6098         case SImode:
6099           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6100             {
6101               *total = COSTS_N_INSNS (4);
6102               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6103                                               speed);
6104             }
6105           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
6106             *total = COSTS_N_INSNS (1);
6107           else
6108             *total = COSTS_N_INSNS (4);
6109           break;
6110
6111         default:
6112           return false;
6113         }
6114       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6115       return true;
6116
6117     case MINUS:
6118       if (AVR_HAVE_MUL
6119           && QImode == mode
6120           && register_operand (XEXP (x, 0), QImode)
6121           && MULT == GET_CODE (XEXP (x, 1)))
6122         {
6123           /* multiply-sub */
6124           *total = COSTS_N_INSNS (speed ? 4 : 3);
6125           /* multiply-sub with constant: will be split and load constant. */
6126           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
6127             *total = COSTS_N_INSNS (1) + *total;
6128           return true;
6129         }
6130       if (AVR_HAVE_MUL
6131           && HImode == mode
6132           && register_operand (XEXP (x, 0), HImode)
6133           && (MULT == GET_CODE (XEXP (x, 1))
6134               || ASHIFT == GET_CODE (XEXP (x, 1)))
6135           && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
6136               || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
6137         {
6138           /* multiply-sub */
6139           *total = COSTS_N_INSNS (speed ? 5 : 4);
6140           /* multiply-sub with constant: will be split and load constant. */
6141           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
6142             *total = COSTS_N_INSNS (1) + *total;
6143           return true;
6144         }
6145     case AND:
6146     case IOR:
6147       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
6148       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6149       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6150         *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6151       return true;
6152
6153     case XOR:
6154       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
6155       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6156       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6157       return true;
6158
6159     case MULT:
6160       switch (mode)
6161         {
6162         case QImode:
6163           if (AVR_HAVE_MUL)
6164             *total = COSTS_N_INSNS (!speed ? 3 : 4);
6165           else if (!speed)
6166             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
6167           else
6168             return false;
6169           break;
6170
6171         case HImode:
6172           if (AVR_HAVE_MUL)
6173             {
6174               rtx op0 = XEXP (x, 0);
6175               rtx op1 = XEXP (x, 1);
6176               enum rtx_code code0 = GET_CODE (op0);
6177               enum rtx_code code1 = GET_CODE (op1);
6178               bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
6179               bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
6180
6181               if (ex0
6182                   && (u8_operand (op1, HImode)
6183                       || s8_operand (op1, HImode)))
6184                 {
6185                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
6186                   return true;
6187                 }
6188               if (ex0
6189                   && register_operand (op1, HImode))
6190                 {
6191                   *total = COSTS_N_INSNS (!speed ? 5 : 8);
6192                   return true;
6193                 }
6194               else if (ex0 || ex1)
6195                 {
6196                   *total = COSTS_N_INSNS (!speed ? 3 : 5);
6197                   return true;
6198                 }
6199               else if (register_operand (op0, HImode)
6200                        && (u8_operand (op1, HImode)
6201                            || s8_operand (op1, HImode)))
6202                 {
6203                   *total = COSTS_N_INSNS (!speed ? 6 : 9);
6204                   return true;
6205                 }
6206               else
6207                 *total = COSTS_N_INSNS (!speed ? 7 : 10);
6208             }
6209           else if (!speed)
6210             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
6211           else
6212             return false;
6213           break;
6214
6215         case SImode:
6216           if (AVR_HAVE_MUL)
6217             {
6218               if (!speed)
6219                 {
6220                   /* Add some additional costs besides CALL like moves etc.  */
6221
6222                   *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
6223                 }
6224               else
6225                 {
6226                   /* Just a rough estimate.  Even with -O2 we don't want bulky
6227                      code expanded inline.  */
6228
6229                   *total = COSTS_N_INSNS (25);
6230                 }
6231             }
6232           else
6233             {
6234               if (speed)
6235                 *total = COSTS_N_INSNS (300);
6236               else
6237                 /* Add some additional costs besides CALL like moves etc.  */
6238                 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
6239             }
6240           
6241           return true;
6242           
6243         default:
6244           return false;
6245         }
6246       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6247       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6248       return true;
6249
6250     case DIV:
6251     case MOD:
6252     case UDIV:
6253     case UMOD:
6254       if (!speed)
6255         *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
6256       else
6257         return false;
6258       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6259       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6260       return true;
6261
6262     case ROTATE:
6263       switch (mode)
6264         {
6265         case QImode:
6266           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
6267             *total = COSTS_N_INSNS (1);
6268
6269           break;
6270
6271         case HImode:
6272           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
6273             *total = COSTS_N_INSNS (3);
6274
6275           break;
6276
6277         case SImode:
6278           if (CONST_INT_P (XEXP (x, 1)))
6279             switch (INTVAL (XEXP (x, 1)))
6280               {
6281               case 8:
6282               case 24:
6283                 *total = COSTS_N_INSNS (5);
6284                 break;
6285               case 16:
6286                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
6287                 break;
6288               }
6289           break;
6290
6291         default:
6292           return false;
6293         }
6294       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6295       return true;    
6296
6297     case ASHIFT:
6298       switch (mode)
6299         {
6300         case QImode:
6301           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6302             {
6303               *total = COSTS_N_INSNS (!speed ? 4 : 17);
6304               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6305                                               speed);
6306             }
6307           else
6308             {
6309               val = INTVAL (XEXP (x, 1));
6310               if (val == 7)
6311                 *total = COSTS_N_INSNS (3);
6312               else if (val >= 0 && val <= 7)
6313                 *total = COSTS_N_INSNS (val);
6314               else
6315                 *total = COSTS_N_INSNS (1);
6316             }
6317           break;
6318
6319         case HImode:
6320           if (AVR_HAVE_MUL)
6321             {
6322               if (const_2_to_7_operand (XEXP (x, 1), HImode)
6323                   && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
6324                       || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
6325                 {
6326                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
6327                   return true;
6328                 }
6329             }
6330           
6331           if (const1_rtx == (XEXP (x, 1))
6332               && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
6333             {
6334               *total = COSTS_N_INSNS (2);
6335               return true;
6336             }
6337           
6338           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6339             {
6340               *total = COSTS_N_INSNS (!speed ? 5 : 41);
6341               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6342                                               speed);
6343             }
6344           else
6345             switch (INTVAL (XEXP (x, 1)))
6346               {
6347               case 0:
6348                 *total = 0;
6349                 break;
6350               case 1:
6351               case 8:
6352                 *total = COSTS_N_INSNS (2);
6353                 break;
6354               case 9:
6355                 *total = COSTS_N_INSNS (3);
6356                 break;
6357               case 2:
6358               case 3:
6359               case 10:
6360               case 15:
6361                 *total = COSTS_N_INSNS (4);
6362                 break;
6363               case 7:
6364               case 11:
6365               case 12:
6366                 *total = COSTS_N_INSNS (5);
6367                 break;
6368               case 4:
6369                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
6370                 break;
6371               case 6:
6372                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
6373                 break;
6374               case 5:
6375                 *total = COSTS_N_INSNS (!speed ? 5 : 10);
6376                 break;
6377               default:
6378                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
6379                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6380                                                 speed);
6381               }
6382           break;
6383
6384         case SImode:
6385           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6386             {
6387               *total = COSTS_N_INSNS (!speed ? 7 : 113);
6388               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6389                                               speed);
6390             }
6391           else
6392             switch (INTVAL (XEXP (x, 1)))
6393               {
6394               case 0:
6395                 *total = 0;
6396                 break;
6397               case 24:
6398                 *total = COSTS_N_INSNS (3);
6399                 break;
6400               case 1:
6401               case 8:
6402               case 16:
6403                 *total = COSTS_N_INSNS (4);
6404                 break;
6405               case 31:
6406                 *total = COSTS_N_INSNS (6);
6407                 break;
6408               case 2:
6409                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
6410                 break;
6411               default:
6412                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
6413                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6414                                                 speed);
6415               }
6416           break;
6417
6418         default:
6419           return false;
6420         }
6421       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6422       return true;
6423
6424     case ASHIFTRT:
6425       switch (mode)
6426         {
6427         case QImode:
6428           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6429             {
6430               *total = COSTS_N_INSNS (!speed ? 4 : 17);
6431               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6432                                               speed);
6433             }
6434           else
6435             {
6436               val = INTVAL (XEXP (x, 1));
6437               if (val == 6)
6438                 *total = COSTS_N_INSNS (4);
6439               else if (val == 7)
6440                 *total = COSTS_N_INSNS (2);
6441               else if (val >= 0 && val <= 7)
6442                 *total = COSTS_N_INSNS (val);
6443               else
6444                 *total = COSTS_N_INSNS (1);
6445             }
6446           break;
6447
6448         case HImode:
6449           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6450             {
6451               *total = COSTS_N_INSNS (!speed ? 5 : 41);
6452               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6453                                               speed);
6454             }
6455           else
6456             switch (INTVAL (XEXP (x, 1)))
6457               {
6458               case 0:
6459                 *total = 0;
6460                 break;
6461               case 1:
6462                 *total = COSTS_N_INSNS (2);
6463                 break;
6464               case 15:
6465                 *total = COSTS_N_INSNS (3);
6466                 break;
6467               case 2:
6468               case 7:
6469               case 8:
6470               case 9:
6471                 *total = COSTS_N_INSNS (4);
6472                 break;
6473               case 10:
6474               case 14:
6475                 *total = COSTS_N_INSNS (5);
6476                 break;
6477               case 11:
6478                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
6479                 break;
6480               case 12:
6481                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
6482                 break;
6483               case 6:
6484               case 13:
6485                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
6486                 break;
6487               default:
6488                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
6489                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6490                                                 speed);
6491               }
6492           break;
6493
6494         case SImode:
6495           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6496             {
6497               *total = COSTS_N_INSNS (!speed ? 7 : 113);
6498               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6499                                               speed);
6500             }
6501           else
6502             switch (INTVAL (XEXP (x, 1)))
6503               {
6504               case 0:
6505                 *total = 0;
6506                 break;
6507               case 1:
6508                 *total = COSTS_N_INSNS (4);
6509                 break;
6510               case 8:
6511               case 16:
6512               case 24:
6513                 *total = COSTS_N_INSNS (6);
6514                 break;
6515               case 2:
6516                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
6517                 break;
6518               case 31:
6519                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
6520                 break;
6521               default:
6522                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
6523                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6524                                                 speed);
6525               }
6526           break;
6527
6528         default:
6529           return false;
6530         }
6531       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6532       return true;
6533
6534     case LSHIFTRT:
6535       switch (mode)
6536         {
6537         case QImode:
6538           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6539             {
6540               *total = COSTS_N_INSNS (!speed ? 4 : 17);
6541               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6542                                               speed);
6543             }
6544           else
6545             {
6546               val = INTVAL (XEXP (x, 1));
6547               if (val == 7)
6548                 *total = COSTS_N_INSNS (3);
6549               else if (val >= 0 && val <= 7)
6550                 *total = COSTS_N_INSNS (val);
6551               else
6552                 *total = COSTS_N_INSNS (1);
6553             }
6554           break;
6555
6556         case HImode:
6557           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6558             {
6559               *total = COSTS_N_INSNS (!speed ? 5 : 41);
6560               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6561                                               speed);
6562             }
6563           else
6564             switch (INTVAL (XEXP (x, 1)))
6565               {
6566               case 0:
6567                 *total = 0;
6568                 break;
6569               case 1:
6570               case 8:
6571                 *total = COSTS_N_INSNS (2);
6572                 break;
6573               case 9:
6574                 *total = COSTS_N_INSNS (3);
6575                 break;
6576               case 2:
6577               case 10:
6578               case 15:
6579                 *total = COSTS_N_INSNS (4);
6580                 break;
6581               case 7:
6582               case 11:
6583                 *total = COSTS_N_INSNS (5);
6584                 break;
6585               case 3:
6586               case 12:
6587               case 13:
6588               case 14:
6589                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
6590                 break;
6591               case 4:
6592                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
6593                 break;
6594               case 5:
6595               case 6:
6596                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
6597                 break;
6598               default:
6599                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
6600                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6601                                                 speed);
6602               }
6603           break;
6604
6605         case SImode:
6606           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6607             {
6608               *total = COSTS_N_INSNS (!speed ? 7 : 113);
6609               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6610                                               speed);
6611             }
6612           else
6613             switch (INTVAL (XEXP (x, 1)))
6614               {
6615               case 0:
6616                 *total = 0;
6617                 break;
6618               case 1:
6619                 *total = COSTS_N_INSNS (4);
6620                 break;
6621               case 2:
6622                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
6623                 break;
6624               case 8:
6625               case 16:
6626               case 24:
6627                 *total = COSTS_N_INSNS (4);
6628                 break;
6629               case 31:
6630                 *total = COSTS_N_INSNS (6);
6631                 break;
6632               default:
6633                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
6634                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6635                                                 speed);
6636               }
6637           break;
6638
6639         default:
6640           return false;
6641         }
6642       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6643       return true;
6644
6645     case COMPARE:
6646       switch (GET_MODE (XEXP (x, 0)))
6647         {
6648         case QImode:
6649           *total = COSTS_N_INSNS (1);
6650           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6651             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6652           break;
6653
6654         case HImode:
6655           *total = COSTS_N_INSNS (2);
6656           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6657             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6658           else if (INTVAL (XEXP (x, 1)) != 0)
6659             *total += COSTS_N_INSNS (1);
6660           break;
6661
6662         case SImode:
6663           *total = COSTS_N_INSNS (4);
6664           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6665             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6666           else if (INTVAL (XEXP (x, 1)) != 0)
6667             *total += COSTS_N_INSNS (3);
6668           break;
6669
6670         default:
6671           return false;
6672         }
6673       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6674       return true;
6675
6676     case TRUNCATE:
6677       if (AVR_HAVE_MUL
6678           && LSHIFTRT == GET_CODE (XEXP (x, 0))
6679           && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
6680           && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
6681         {
6682           if (QImode == mode || HImode == mode)
6683             {
6684               *total = COSTS_N_INSNS (2);
6685               return true;
6686             }
6687         }
6688       break;
6689
6690     default:
6691       break;
6692     }
6693   return false;
6694 }
6695
6696
6697 /* Implement `TARGET_RTX_COSTS'.  */
6698
6699 static bool
6700 avr_rtx_costs (rtx x, int codearg, int outer_code,
6701                int opno, int *total, bool speed)
6702 {
6703   bool done = avr_rtx_costs_1 (x, codearg, outer_code,
6704                                opno, total, speed);
6705
6706   if (avr_log.rtx_costs)
6707     {
6708       avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
6709                  done, speed ? "speed" : "size", *total, outer_code, x);
6710     }
6711
6712   return done;
6713 }
6714
6715
6716 /* Implement `TARGET_ADDRESS_COST'.  */
6717
6718 static int
6719 avr_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
6720 {
6721   int cost = 4;
6722   
6723   if (GET_CODE (x) == PLUS
6724       && CONST_INT_P (XEXP (x, 1))
6725       && (REG_P (XEXP (x, 0))
6726           || GET_CODE (XEXP (x, 0)) == SUBREG))
6727     {
6728       if (INTVAL (XEXP (x, 1)) >= 61)
6729         cost = 18;
6730     }
6731   else if (CONSTANT_ADDRESS_P (x))
6732     {
6733       if (optimize > 0
6734           && io_address_operand (x, QImode))
6735         cost = 2;
6736     }
6737
6738   if (avr_log.address_cost)
6739     avr_edump ("\n%?: %d = %r\n", cost, x);
6740   
6741   return cost;
6742 }
6743
6744 /* Test for extra memory constraint 'Q'.
6745    It's a memory address based on Y or Z pointer with valid displacement.  */
6746
6747 int
6748 extra_constraint_Q (rtx x)
6749 {
6750   int ok = 0;
6751   
6752   if (GET_CODE (XEXP (x,0)) == PLUS
6753       && REG_P (XEXP (XEXP (x,0), 0))
6754       && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
6755       && (INTVAL (XEXP (XEXP (x,0), 1))
6756           <= MAX_LD_OFFSET (GET_MODE (x))))
6757     {
6758       rtx xx = XEXP (XEXP (x,0), 0);
6759       int regno = REGNO (xx);
6760       
6761       ok = (/* allocate pseudos */
6762             regno >= FIRST_PSEUDO_REGISTER
6763             /* strictly check */
6764             || regno == REG_Z || regno == REG_Y
6765             /* XXX frame & arg pointer checks */
6766             || xx == frame_pointer_rtx
6767             || xx == arg_pointer_rtx);
6768       
6769       if (avr_log.constraints)
6770         avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
6771                    ok, reload_completed, reload_in_progress, x);
6772     }
6773
6774   return ok;
6775 }
6776
6777 /* Convert condition code CONDITION to the valid AVR condition code.  */
6778
6779 RTX_CODE
6780 avr_normalize_condition (RTX_CODE condition)
6781 {
6782   switch (condition)
6783     {
6784     case GT:
6785       return GE;
6786     case GTU:
6787       return GEU;
6788     case LE:
6789       return LT;
6790     case LEU:
6791       return LTU;
6792     default:
6793       gcc_unreachable ();
6794     }
6795 }
6796
6797 /* Helper function for `avr_reorg'.  */
6798
6799 static rtx
6800 avr_compare_pattern (rtx insn)
6801 {
6802   rtx pattern = single_set (insn);
6803
6804   if (pattern
6805       && NONJUMP_INSN_P (insn)
6806       && SET_DEST (pattern) == cc0_rtx
6807       && GET_CODE (SET_SRC (pattern)) == COMPARE)
6808     {
6809       return pattern;
6810     }
6811
6812   return NULL_RTX;
6813 }
6814
6815 /* Helper function for `avr_reorg'.  */
6816
6817 /* Expansion of switch/case decision trees leads to code like
6818
6819        cc0 = compare (Reg, Num)
6820        if (cc0 == 0)
6821          goto L1
6822          
6823        cc0 = compare (Reg, Num)
6824        if (cc0 > 0)
6825          goto L2
6826
6827    The second comparison is superfluous and can be deleted.
6828    The second jump condition can be transformed from a
6829    "difficult" one to a "simple" one because "cc0 > 0" and
6830    "cc0 >= 0" will have the same effect here.
6831
6832    This function relies on the way switch/case is being expaned
6833    as binary decision tree.  For example code see PR 49903.
6834          
6835    Return TRUE if optimization performed.
6836    Return FALSE if nothing changed.
6837
6838    INSN1 is a comparison, i.e. avr_compare_pattern != 0.
6839
6840    We don't want to do this in text peephole because it is
6841    tedious to work out jump offsets there and the second comparison
6842    might have been transormed by `avr_reorg'.
6843
6844    RTL peephole won't do because peephole2 does not scan across
6845    basic blocks.  */                
6846                         
6847 static bool
6848 avr_reorg_remove_redundant_compare (rtx insn1)
6849 {
6850   rtx comp1, ifelse1, xcond1, branch1;
6851   rtx comp2, ifelse2, xcond2, branch2, insn2;
6852   enum rtx_code code;
6853   rtx jump, target, cond;
6854   
6855   /* Look out for:  compare1 - branch1 - compare2 - branch2  */
6856
6857   branch1 = next_nonnote_nondebug_insn (insn1);
6858   if (!branch1 || !JUMP_P (branch1))
6859     return false;
6860
6861   insn2 = next_nonnote_nondebug_insn (branch1);
6862   if (!insn2 || !avr_compare_pattern (insn2))
6863     return false;
6864
6865   branch2 = next_nonnote_nondebug_insn (insn2);
6866   if (!branch2 || !JUMP_P (branch2))
6867     return false;
6868
6869   comp1 = avr_compare_pattern (insn1);
6870   comp2 = avr_compare_pattern (insn2);
6871   xcond1 = single_set (branch1);
6872   xcond2 = single_set (branch2);
6873   
6874   if (!comp1 || !comp2
6875       || !rtx_equal_p (comp1, comp2)
6876       || !xcond1 || SET_DEST (xcond1) != pc_rtx
6877       || !xcond2 || SET_DEST (xcond2) != pc_rtx
6878       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
6879       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
6880     {
6881       return false;
6882     }
6883
6884   comp1 = SET_SRC (comp1);
6885   ifelse1 = SET_SRC (xcond1);
6886   ifelse2 = SET_SRC (xcond2);
6887
6888   /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE.  */
6889
6890   if (EQ != GET_CODE (XEXP (ifelse1, 0))
6891       || !REG_P (XEXP (comp1, 0))
6892       || !CONST_INT_P (XEXP (comp1, 1))
6893       || XEXP (ifelse1, 2) != pc_rtx
6894       || XEXP (ifelse2, 2) != pc_rtx
6895       || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
6896       || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
6897       || !COMPARISON_P (XEXP (ifelse2, 0))
6898       || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
6899       || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
6900       || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
6901       || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
6902     {
6903       return false;
6904     }
6905
6906   /* We filtered the insn sequence to look like
6907
6908         (set (cc0)
6909              (compare (reg:M N)
6910                       (const_int VAL)))
6911         (set (pc)
6912              (if_then_else (eq (cc0)
6913                                (const_int 0))
6914                            (label_ref L1)
6915                            (pc)))
6916                            
6917         (set (cc0)
6918              (compare (reg:M N)
6919                       (const_int VAL)))
6920         (set (pc)
6921              (if_then_else (CODE (cc0)
6922                                  (const_int 0))
6923                            (label_ref L2)
6924                            (pc)))
6925   */
6926
6927   code = GET_CODE (XEXP (ifelse2, 0));
6928
6929   /* Map GT/GTU to GE/GEU which is easier for AVR.
6930      The first two instructions compare/branch on EQ
6931      so we may replace the difficult
6932         
6933         if (x == VAL)   goto L1;
6934         if (x > VAL)    goto L2;
6935
6936      with easy
6937          
6938          if (x == VAL)   goto L1;
6939          if (x >= VAL)   goto L2;
6940
6941      Similarly, replace LE/LEU by LT/LTU.  */
6942   
6943   switch (code)
6944     {
6945     case EQ:
6946     case LT:  case LTU:
6947     case GE:  case GEU:
6948       break;
6949
6950     case LE:  case LEU:
6951     case GT:  case GTU:
6952       code = avr_normalize_condition (code);
6953       break;
6954       
6955     default:
6956       return false;
6957     }
6958
6959   /* Wrap the branches into UNSPECs so they won't be changed or
6960      optimized in the remainder.  */
6961
6962   target = XEXP (XEXP (ifelse1, 1), 0);
6963   cond = XEXP (ifelse1, 0);
6964   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
6965
6966   JUMP_LABEL (jump) = JUMP_LABEL (branch1);
6967
6968   target = XEXP (XEXP (ifelse2, 1), 0);
6969   cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
6970   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
6971
6972   JUMP_LABEL (jump) = JUMP_LABEL (branch2);
6973
6974   /* The comparisons in insn1 and insn2 are exactly the same;
6975      insn2 is superfluous so delete it.  */
6976      
6977   delete_insn (insn2);
6978   delete_insn (branch1);
6979   delete_insn (branch2);
6980
6981   return true;
6982 }
6983
6984
6985 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'.  */
6986 /* Optimize conditional jumps.  */
6987
6988 static void
6989 avr_reorg (void)
6990 {
6991   rtx insn = get_insns();
6992   
6993   for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
6994     {
6995       rtx pattern = avr_compare_pattern (insn);
6996       
6997       if (!pattern)
6998         continue;
6999
7000       if (optimize
7001           && avr_reorg_remove_redundant_compare (insn))
7002         {
7003           continue;
7004         }
7005
7006       if (compare_diff_p (insn))
7007         {
7008           /* Now we work under compare insn with difficult branch.  */
7009           
7010           rtx next = next_real_insn (insn);
7011           rtx pat = PATTERN (next);
7012
7013           pattern = SET_SRC (pattern);
7014           
7015           if (true_regnum (XEXP (pattern, 0)) >= 0
7016               && true_regnum (XEXP (pattern, 1)) >= 0)
7017             {
7018               rtx x = XEXP (pattern, 0);
7019               rtx src = SET_SRC (pat);
7020               rtx t = XEXP (src,0);
7021               PUT_CODE (t, swap_condition (GET_CODE (t)));
7022               XEXP (pattern, 0) = XEXP (pattern, 1);
7023               XEXP (pattern, 1) = x;
7024               INSN_CODE (next) = -1;
7025             }
7026           else if (true_regnum (XEXP (pattern, 0)) >= 0
7027                    && XEXP (pattern, 1) == const0_rtx)
7028             {
7029               /* This is a tst insn, we can reverse it.  */
7030               rtx src = SET_SRC (pat);
7031               rtx t = XEXP (src,0);
7032     
7033               PUT_CODE (t, swap_condition (GET_CODE (t)));
7034               XEXP (pattern, 1) = XEXP (pattern, 0);
7035               XEXP (pattern, 0) = const0_rtx;
7036               INSN_CODE (next) = -1;
7037               INSN_CODE (insn) = -1;
7038             }
7039           else if (true_regnum (XEXP (pattern, 0)) >= 0
7040                    && CONST_INT_P (XEXP (pattern, 1)))
7041             {
7042               rtx x = XEXP (pattern, 1);
7043               rtx src = SET_SRC (pat);
7044               rtx t = XEXP (src,0);
7045               enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
7046               
7047               if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
7048                 {
7049                   XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
7050                   PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
7051                   INSN_CODE (next) = -1;
7052                   INSN_CODE (insn) = -1;
7053                 }
7054             }
7055         }
7056     }
7057 }
7058
7059 /* Returns register number for function return value.*/
7060
7061 static inline unsigned int
7062 avr_ret_register (void)
7063 {
7064   return 24;
7065 }
7066
7067 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
7068
7069 static bool
7070 avr_function_value_regno_p (const unsigned int regno)
7071 {
7072   return (regno == avr_ret_register ());
7073 }
7074
7075 /* Create an RTX representing the place where a
7076    library function returns a value of mode MODE.  */
7077
7078 static rtx
7079 avr_libcall_value (enum machine_mode mode,
7080                    const_rtx func ATTRIBUTE_UNUSED)
7081 {
7082   int offs = GET_MODE_SIZE (mode);
7083   if (offs < 2)
7084     offs = 2;
7085   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
7086 }
7087
7088 /* Create an RTX representing the place where a
7089    function returns a value of data type VALTYPE.  */
7090
7091 static rtx
7092 avr_function_value (const_tree type,
7093                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
7094                     bool outgoing ATTRIBUTE_UNUSED)
7095 {
7096   unsigned int offs;
7097
7098   if (TYPE_MODE (type) != BLKmode)
7099     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
7100   
7101   offs = int_size_in_bytes (type);
7102   if (offs < 2)
7103     offs = 2;
7104   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
7105     offs = GET_MODE_SIZE (SImode);
7106   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
7107     offs = GET_MODE_SIZE (DImode);
7108   
7109   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
7110 }
7111
7112 int
7113 test_hard_reg_class (enum reg_class rclass, rtx x)
7114 {
7115   int regno = true_regnum (x);
7116   if (regno < 0)
7117     return 0;
7118
7119   if (TEST_HARD_REG_CLASS (rclass, regno))
7120     return 1;
7121
7122   return 0;
7123 }
7124
7125
7126 int
7127 jump_over_one_insn_p (rtx insn, rtx dest)
7128 {
7129   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
7130                       ? XEXP (dest, 0)
7131                       : dest);
7132   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
7133   int dest_addr = INSN_ADDRESSES (uid);
7134   return dest_addr - jump_addr == get_attr_length (insn) + 1;
7135 }
7136
7137 /* Returns 1 if a value of mode MODE can be stored starting with hard
7138    register number REGNO.  On the enhanced core, anything larger than
7139    1 byte must start in even numbered register for "movw" to work
7140    (this way we don't have to check for odd registers everywhere).  */
7141
7142 int
7143 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
7144 {
7145   /* NOTE: 8-bit values must not be disallowed for R28 or R29.
7146         Disallowing QI et al. in these regs might lead to code like
7147             (set (subreg:QI (reg:HI 28) n) ...)
7148         which will result in wrong code because reload does not
7149         handle SUBREGs of hard regsisters like this.
7150         This could be fixed in reload.  However, it appears
7151         that fixing reload is not wanted by reload people.  */
7152   
7153   /* Any GENERAL_REGS register can hold 8-bit values.  */
7154   
7155   if (GET_MODE_SIZE (mode) == 1)
7156     return 1;
7157
7158   /* FIXME: Ideally, the following test is not needed.
7159         However, it turned out that it can reduce the number
7160         of spill fails.  AVR and it's poor endowment with
7161         address registers is extreme stress test for reload.  */
7162   
7163   if (GET_MODE_SIZE (mode) >= 4
7164       && regno >= REG_X)
7165     return 0;
7166
7167   /* All modes larger than 8 bits should start in an even register.  */
7168   
7169   return !(regno & 1);
7170 }
7171
7172
7173 /* A helper for `output_reload_insisf' and `output_reload_inhi'.  */
7174 /* Set 32-bit register OP[0] to compile-time constant OP[1].
7175    CLOBBER_REG is a QI clobber register or NULL_RTX.
7176    LEN == NULL: output instructions.
7177    LEN != NULL: set *LEN to the length of the instruction sequence
7178                 (in words) printed with LEN = NULL.
7179    If CLEAR_P is true, OP[0] had been cleard to Zero already.
7180    If CLEAR_P is false, nothing is known about OP[0].  */
7181
7182 static void
7183 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
7184 {
7185   rtx src = op[1];
7186   rtx dest = op[0];
7187   rtx xval, xdest[4];
7188   int ival[4];
7189   int clobber_val = 1234;
7190   bool cooked_clobber_p = false;
7191   bool set_p = false;
7192   unsigned int n;
7193   enum machine_mode mode = GET_MODE (dest);
7194   
7195   gcc_assert (REG_P (dest));
7196
7197   if (len)
7198     *len = 0;
7199   
7200   /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
7201      but has some subregs that are in LD_REGS.  Use the MSB (REG:QI 17).  */
7202   
7203   if (14 == REGNO (dest)
7204       && 4 == GET_MODE_SIZE (mode))
7205     {
7206       clobber_reg = gen_rtx_REG (QImode, 17);
7207     }
7208
7209   /* We might need a clobber reg but don't have one.  Look at the value
7210      to be loaded more closely.  A clobber is only needed if it contains
7211      a byte that is neither 0, -1 or a power of 2.  */
7212   
7213   if (NULL_RTX == clobber_reg
7214       && !test_hard_reg_class (LD_REGS, dest)
7215       && !avr_popcount_each_byte (src, GET_MODE_SIZE (mode),
7216                                   (1 << 0) | (1 << 1) | (1 << 8)))
7217     {
7218       /* We have no clobber register but need one.  Cook one up.
7219          That's cheaper than loading from constant pool.  */
7220       
7221       cooked_clobber_p = true;
7222       clobber_reg = gen_rtx_REG (QImode, REG_Z + 1);
7223       avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
7224     }
7225
7226   /* Now start filling DEST from LSB to MSB.  */
7227   
7228   for (n = 0; n < GET_MODE_SIZE (mode); n++)
7229     {
7230       bool done_byte = false;
7231       unsigned int j;
7232       rtx xop[3];
7233
7234       /* Crop the n-th sub-byte.  */
7235       
7236       xval = simplify_gen_subreg (QImode, src, mode, n);
7237       xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
7238       ival[n] = INTVAL (xval);
7239
7240       /* Look if we can reuse the low word by means of MOVW.  */
7241       
7242       if (n == 2
7243           && AVR_HAVE_MOVW)
7244         {
7245           rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
7246           rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
7247
7248           if (INTVAL (lo16) == INTVAL (hi16))
7249             {
7250               if (0 != INTVAL (lo16)
7251                   || !clear_p)
7252                 {
7253                   avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
7254                 }
7255               
7256               break;
7257             }
7258         }
7259
7260       /* Use CLR to zero a value so that cc0 is set as expected
7261          for zero.  */
7262       
7263       if (ival[n] == 0)
7264         {
7265           if (!clear_p)
7266             avr_asm_len ("clr %0", &xdest[n], len, 1);
7267           
7268           continue;
7269         }
7270
7271       if (clobber_val == ival[n]
7272           && REGNO (clobber_reg) == REGNO (xdest[n]))
7273         {
7274           continue;
7275         }
7276
7277       /* LD_REGS can use LDI to move a constant value */
7278       
7279       if (test_hard_reg_class (LD_REGS, xdest[n]))
7280         {
7281           xop[0] = xdest[n];
7282           xop[1] = xval;
7283           avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
7284           continue;
7285         }
7286
7287       /* Try to reuse value already loaded in some lower byte. */
7288       
7289       for (j = 0; j < n; j++)
7290         if (ival[j] == ival[n])
7291           {
7292             xop[0] = xdest[n];
7293             xop[1] = xdest[j];
7294             
7295             avr_asm_len ("mov %0,%1", xop, len, 1);
7296             done_byte = true;
7297             break;
7298           }
7299
7300       if (done_byte)
7301         continue;
7302
7303       /* Need no clobber reg for -1: Use CLR/DEC */
7304       
7305       if (-1 == ival[n])
7306         {
7307           if (!clear_p)
7308             avr_asm_len ("clr %0", &xdest[n], len, 1);
7309           
7310           avr_asm_len ("dec %0", &xdest[n], len, 1);
7311           continue;
7312         }
7313       else if (1 == ival[n])
7314         {
7315           if (!clear_p)
7316             avr_asm_len ("clr %0", &xdest[n], len, 1);
7317           
7318           avr_asm_len ("inc %0", &xdest[n], len, 1);
7319           continue;
7320         }
7321
7322       /* Use T flag or INC to manage powers of 2 if we have
7323          no clobber reg.  */
7324
7325       if (NULL_RTX == clobber_reg
7326           && single_one_operand (xval, QImode))
7327         {
7328           xop[0] = xdest[n];
7329           xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
7330
7331           gcc_assert (constm1_rtx != xop[1]);
7332
7333           if (!set_p)
7334             {
7335               set_p = true;
7336               avr_asm_len ("set", xop, len, 1);
7337             }
7338
7339           if (!clear_p)
7340             avr_asm_len ("clr %0", xop, len, 1);
7341           
7342           avr_asm_len ("bld %0,%1", xop, len, 1);
7343           continue;
7344         }
7345
7346       /* We actually need the LD_REGS clobber reg.  */
7347
7348       gcc_assert (NULL_RTX != clobber_reg);
7349         
7350       xop[0] = xdest[n];
7351       xop[1] = xval;
7352       xop[2] = clobber_reg;
7353       clobber_val = ival[n];
7354         
7355       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
7356                    "mov %0,%2", xop, len, 2);
7357     }
7358   
7359   /* If we cooked up a clobber reg above, restore it.  */
7360   
7361   if (cooked_clobber_p)
7362     {
7363       avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
7364     }
7365 }
7366
7367
7368 /* Reload the constant OP[1] into the HI register OP[0].
7369    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
7370    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
7371    need a clobber reg or have to cook one up.
7372
7373    PLEN == NULL: Output instructions.
7374    PLEN != NULL: Output nothing.  Set *PLEN to number of words occupied
7375                  by the insns printed.
7376
7377    Return "".  */
7378
7379 const char*
7380 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
7381 {
7382   if (CONST_INT_P (op[1]))
7383     {
7384       output_reload_in_const (op, clobber_reg, plen, false);
7385     }
7386   else if (test_hard_reg_class (LD_REGS, op[0]))
7387     {
7388       avr_asm_len ("ldi %A0,lo8(%1)" CR_TAB
7389                    "ldi %B0,hi8(%1)", op, plen, -2);
7390     }
7391   else
7392     {
7393       rtx xop[3];
7394
7395       xop[0] = op[0];
7396       xop[1] = op[1];
7397       xop[2] = clobber_reg;
7398       
7399       if (plen)
7400         *plen = 0;
7401       
7402       if (clobber_reg == NULL_RTX)
7403         {
7404           /* No scratch register provided: cook une up.  */
7405           
7406           xop[2] = gen_rtx_REG (QImode, REG_Z + 1);
7407           avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
7408         }
7409       
7410       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
7411                    "mov %A0,%2"     CR_TAB
7412                    "ldi %2,hi8(%1)" CR_TAB
7413                    "mov %B0,%2", xop, plen, 4);
7414
7415       if (clobber_reg == NULL_RTX)
7416         {
7417           avr_asm_len ("mov %2,__tmp_reg__", xop, plen, 1);
7418         }
7419     }
7420
7421   return "";
7422 }
7423
7424
7425 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
7426    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
7427    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
7428    need a clobber reg or have to cook one up.
7429
7430    LEN == NULL: Output instructions.
7431    
7432    LEN != NULL: Output nothing.  Set *LEN to number of words occupied
7433                 by the insns printed.
7434
7435    Return "".  */
7436
7437 const char *
7438 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
7439 {
7440   gcc_assert (REG_P (op[0])
7441               && CONSTANT_P (op[1]));
7442
7443   if (AVR_HAVE_MOVW
7444       && !test_hard_reg_class (LD_REGS, op[0]))
7445     {
7446       int len_clr, len_noclr;
7447       
7448       /* In some cases it is better to clear the destination beforehand, e.g.
7449
7450              CLR R2   CLR R3   MOVW R4,R2   INC R2
7451
7452          is shorther than
7453
7454              CLR R2   INC R2   CLR  R3      CLR R4   CLR R5
7455
7456          We find it too tedious to work that out in the print function.
7457          Instead, we call the print function twice to get the lengths of
7458          both methods and use the shortest one.  */
7459          
7460       output_reload_in_const (op, clobber_reg, &len_clr, true);
7461       output_reload_in_const (op, clobber_reg, &len_noclr, false);
7462       
7463       if (len_noclr - len_clr == 4)
7464         {
7465           /* Default needs 4 CLR instructions: clear register beforehand.  */
7466           
7467           avr_asm_len ("clr %A0" CR_TAB
7468                        "clr %B0" CR_TAB
7469                        "movw %C0,%A0", &op[0], len, 3);
7470           
7471           output_reload_in_const (op, clobber_reg, len, true);
7472           
7473           if (len)
7474             *len += 3;
7475
7476           return "";
7477         }
7478     }
7479
7480   /* Default: destination not pre-cleared.  */
7481
7482   output_reload_in_const (op, clobber_reg, len, false);
7483   return "";
7484 }
7485
7486 void
7487 avr_output_bld (rtx operands[], int bit_nr)
7488 {
7489   static char s[] = "bld %A0,0";
7490
7491   s[5] = 'A' + (bit_nr >> 3);
7492   s[8] = '0' + (bit_nr & 7);
7493   output_asm_insn (s, operands);
7494 }
7495
7496 void
7497 avr_output_addr_vec_elt (FILE *stream, int value)
7498 {
7499   if (AVR_HAVE_JMP_CALL)
7500     fprintf (stream, "\t.word gs(.L%d)\n", value);
7501   else
7502     fprintf (stream, "\trjmp .L%d\n", value);
7503 }
7504
7505 /* Returns true if SCRATCH are safe to be allocated as a scratch
7506    registers (for a define_peephole2) in the current function.  */
7507
7508 bool
7509 avr_hard_regno_scratch_ok (unsigned int regno)
7510 {
7511   /* Interrupt functions can only use registers that have already been saved
7512      by the prologue, even if they would normally be call-clobbered.  */
7513
7514   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
7515       && !df_regs_ever_live_p (regno))
7516     return false;
7517
7518   /* Don't allow hard registers that might be part of the frame pointer.
7519      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
7520      and don't care for a frame pointer that spans more than one register.  */
7521
7522   if ((!reload_completed || frame_pointer_needed)
7523       && (regno == REG_Y || regno == REG_Y + 1))
7524     {
7525       return false;
7526     }
7527
7528   return true;
7529 }
7530
7531 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
7532
7533 int
7534 avr_hard_regno_rename_ok (unsigned int old_reg,
7535                           unsigned int new_reg)
7536 {
7537   /* Interrupt functions can only use registers that have already been
7538      saved by the prologue, even if they would normally be
7539      call-clobbered.  */
7540
7541   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
7542       && !df_regs_ever_live_p (new_reg))
7543     return 0;
7544
7545   /* Don't allow hard registers that might be part of the frame pointer.
7546      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
7547      and don't care for a frame pointer that spans more than one register.  */
7548
7549   if ((!reload_completed || frame_pointer_needed)
7550       && (old_reg == REG_Y || old_reg == REG_Y + 1
7551           || new_reg == REG_Y || new_reg == REG_Y + 1))
7552     {
7553       return 0;
7554     }
7555   
7556   return 1;
7557 }
7558
7559 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
7560    or memory location in the I/O space (QImode only).
7561
7562    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
7563    Operand 1: register operand to test, or CONST_INT memory address.
7564    Operand 2: bit number.
7565    Operand 3: label to jump to if the test is true.  */
7566
7567 const char *
7568 avr_out_sbxx_branch (rtx insn, rtx operands[])
7569 {
7570   enum rtx_code comp = GET_CODE (operands[0]);
7571   int long_jump = (get_attr_length (insn) >= 4);
7572   int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
7573
7574   if (comp == GE)
7575     comp = EQ;
7576   else if (comp == LT)
7577     comp = NE;
7578
7579   if (reverse)
7580     comp = reverse_condition (comp);
7581
7582   if (GET_CODE (operands[1]) == CONST_INT)
7583     {
7584       if (INTVAL (operands[1]) < 0x40)
7585         {
7586           if (comp == EQ)
7587             output_asm_insn (AS2 (sbis,%m1-0x20,%2), operands);
7588           else
7589             output_asm_insn (AS2 (sbic,%m1-0x20,%2), operands);
7590         }
7591       else
7592         {
7593           output_asm_insn (AS2 (in,__tmp_reg__,%m1-0x20), operands);
7594           if (comp == EQ)
7595             output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
7596           else
7597             output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
7598         }
7599     }
7600   else  /* GET_CODE (operands[1]) == REG */
7601     {
7602       if (GET_MODE (operands[1]) == QImode)
7603         {
7604           if (comp == EQ)
7605             output_asm_insn (AS2 (sbrs,%1,%2), operands);
7606           else
7607             output_asm_insn (AS2 (sbrc,%1,%2), operands);
7608         }
7609       else  /* HImode or SImode */
7610         {
7611           static char buf[] = "sbrc %A1,0";
7612           int bit_nr = INTVAL (operands[2]);
7613           buf[3] = (comp == EQ) ? 's' : 'c';
7614           buf[6] = 'A' + (bit_nr >> 3);
7615           buf[9] = '0' + (bit_nr & 7);
7616           output_asm_insn (buf, operands);
7617         }
7618     }
7619
7620   if (long_jump)
7621     return (AS1 (rjmp,.+4) CR_TAB
7622             AS1 (jmp,%x3));
7623   if (!reverse)
7624     return AS1 (rjmp,%x3);
7625   return "";
7626 }
7627
7628 /* Worker function for TARGET_ASM_CONSTRUCTOR.  */
7629
7630 static void
7631 avr_asm_out_ctor (rtx symbol, int priority)
7632 {
7633   fputs ("\t.global __do_global_ctors\n", asm_out_file);
7634   default_ctor_section_asm_out_constructor (symbol, priority);
7635 }
7636
7637 /* Worker function for TARGET_ASM_DESTRUCTOR.  */
7638
7639 static void
7640 avr_asm_out_dtor (rtx symbol, int priority)
7641 {
7642   fputs ("\t.global __do_global_dtors\n", asm_out_file);
7643   default_dtor_section_asm_out_destructor (symbol, priority);
7644 }
7645
7646 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
7647
7648 static bool
7649 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7650 {
7651   if (TYPE_MODE (type) == BLKmode)
7652     {
7653       HOST_WIDE_INT size = int_size_in_bytes (type);
7654       return (size == -1 || size > 8);
7655     }
7656   else
7657     return false;
7658 }
7659
7660 /* Worker function for CASE_VALUES_THRESHOLD.  */
7661
7662 unsigned int avr_case_values_threshold (void)
7663 {
7664   return (!AVR_HAVE_JMP_CALL || TARGET_CALL_PROLOGUES) ? 8 : 17;
7665 }
7666
7667 /* Helper for __builtin_avr_delay_cycles */
7668
7669 static void
7670 avr_expand_delay_cycles (rtx operands0)
7671 {
7672   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0);
7673   unsigned HOST_WIDE_INT cycles_used;
7674   unsigned HOST_WIDE_INT loop_count;
7675   
7676   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
7677     {
7678       loop_count = ((cycles - 9) / 6) + 1;
7679       cycles_used = ((loop_count - 1) * 6) + 9;
7680       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode)));
7681       cycles -= cycles_used;
7682     }
7683   
7684   if (IN_RANGE (cycles, 262145, 83886081))
7685     {
7686       loop_count = ((cycles - 7) / 5) + 1;
7687       if (loop_count > 0xFFFFFF)
7688         loop_count = 0xFFFFFF;
7689       cycles_used = ((loop_count - 1) * 5) + 7;
7690       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode)));
7691       cycles -= cycles_used;
7692     }
7693   
7694   if (IN_RANGE (cycles, 768, 262144))
7695     {
7696       loop_count = ((cycles - 5) / 4) + 1;
7697       if (loop_count > 0xFFFF)
7698         loop_count = 0xFFFF;
7699       cycles_used = ((loop_count - 1) * 4) + 5;
7700       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode)));
7701       cycles -= cycles_used;
7702     }
7703   
7704   if (IN_RANGE (cycles, 6, 767))
7705     {
7706       loop_count = cycles / 3;
7707       if (loop_count > 255) 
7708         loop_count = 255;
7709       cycles_used = loop_count * 3;
7710       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode)));
7711       cycles -= cycles_used;
7712       }
7713   
7714   while (cycles >= 2)
7715     {
7716       emit_insn (gen_nopv (GEN_INT(2)));
7717       cycles -= 2;
7718     }
7719
7720   if (cycles == 1)
7721     {
7722       emit_insn (gen_nopv (GEN_INT(1)));
7723       cycles--;
7724     }
7725 }
7726
7727 /* IDs for all the AVR builtins.  */
7728
7729 enum avr_builtin_id
7730   {
7731     AVR_BUILTIN_NOP,
7732     AVR_BUILTIN_SEI,
7733     AVR_BUILTIN_CLI,
7734     AVR_BUILTIN_WDR,
7735     AVR_BUILTIN_SLEEP,
7736     AVR_BUILTIN_SWAP,
7737     AVR_BUILTIN_FMUL,
7738     AVR_BUILTIN_FMULS,
7739     AVR_BUILTIN_FMULSU,
7740     AVR_BUILTIN_DELAY_CYCLES
7741   };
7742
7743 #define DEF_BUILTIN(NAME, TYPE, CODE)                                   \
7744   do                                                                    \
7745     {                                                                   \
7746       add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,        \
7747                             NULL, NULL_TREE);                           \
7748     } while (0)
7749
7750
7751 /* Implement `TARGET_INIT_BUILTINS' */
7752 /* Set up all builtin functions for this target.  */
7753
7754 static void
7755 avr_init_builtins (void)
7756 {
7757   tree void_ftype_void
7758     = build_function_type_list (void_type_node, NULL_TREE);
7759   tree uchar_ftype_uchar
7760     = build_function_type_list (unsigned_char_type_node, 
7761                                 unsigned_char_type_node,
7762                                 NULL_TREE);
7763   tree uint_ftype_uchar_uchar
7764     = build_function_type_list (unsigned_type_node, 
7765                                 unsigned_char_type_node,
7766                                 unsigned_char_type_node, 
7767                                 NULL_TREE);
7768   tree int_ftype_char_char
7769     = build_function_type_list (integer_type_node, 
7770                                 char_type_node,
7771                                 char_type_node, 
7772                                 NULL_TREE);
7773   tree int_ftype_char_uchar
7774     = build_function_type_list (integer_type_node, 
7775                                 char_type_node,
7776                                 unsigned_char_type_node, 
7777                                 NULL_TREE);
7778   tree void_ftype_ulong
7779     = build_function_type_list (void_type_node, 
7780                                 long_unsigned_type_node,
7781                                 NULL_TREE);
7782
7783   DEF_BUILTIN ("__builtin_avr_nop", void_ftype_void, AVR_BUILTIN_NOP);
7784   DEF_BUILTIN ("__builtin_avr_sei", void_ftype_void, AVR_BUILTIN_SEI);
7785   DEF_BUILTIN ("__builtin_avr_cli", void_ftype_void, AVR_BUILTIN_CLI);
7786   DEF_BUILTIN ("__builtin_avr_wdr", void_ftype_void, AVR_BUILTIN_WDR);
7787   DEF_BUILTIN ("__builtin_avr_sleep", void_ftype_void, AVR_BUILTIN_SLEEP);
7788   DEF_BUILTIN ("__builtin_avr_swap", uchar_ftype_uchar, AVR_BUILTIN_SWAP);
7789   DEF_BUILTIN ("__builtin_avr_delay_cycles", void_ftype_ulong, 
7790                AVR_BUILTIN_DELAY_CYCLES);
7791
7792   DEF_BUILTIN ("__builtin_avr_fmul", uint_ftype_uchar_uchar, 
7793                AVR_BUILTIN_FMUL);
7794   DEF_BUILTIN ("__builtin_avr_fmuls", int_ftype_char_char, 
7795                AVR_BUILTIN_FMULS);
7796   DEF_BUILTIN ("__builtin_avr_fmulsu", int_ftype_char_uchar, 
7797                AVR_BUILTIN_FMULSU);
7798 }
7799
7800 #undef DEF_BUILTIN
7801
7802 struct avr_builtin_description
7803 {
7804   const enum insn_code icode;
7805   const char *const name;
7806   const enum avr_builtin_id id;
7807 };
7808
7809 static const struct avr_builtin_description
7810 bdesc_1arg[] =
7811   {
7812     { CODE_FOR_rotlqi3_4, "__builtin_avr_swap", AVR_BUILTIN_SWAP }
7813   };
7814
7815 static const struct avr_builtin_description
7816 bdesc_2arg[] =
7817   {
7818     { CODE_FOR_fmul, "__builtin_avr_fmul", AVR_BUILTIN_FMUL },
7819     { CODE_FOR_fmuls, "__builtin_avr_fmuls", AVR_BUILTIN_FMULS },
7820     { CODE_FOR_fmulsu, "__builtin_avr_fmulsu", AVR_BUILTIN_FMULSU }
7821   };
7822
7823 /* Subroutine of avr_expand_builtin to take care of unop insns.  */
7824
7825 static rtx
7826 avr_expand_unop_builtin (enum insn_code icode, tree exp,
7827                          rtx target)
7828 {
7829   rtx pat;
7830   tree arg0 = CALL_EXPR_ARG (exp, 0);
7831   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7832   enum machine_mode op0mode = GET_MODE (op0);
7833   enum machine_mode tmode = insn_data[icode].operand[0].mode;
7834   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7835
7836   if (! target
7837       || GET_MODE (target) != tmode
7838       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7839     {
7840       target = gen_reg_rtx (tmode);
7841     }
7842
7843   if (op0mode == SImode && mode0 == HImode)
7844     {
7845       op0mode = HImode;
7846       op0 = gen_lowpart (HImode, op0);
7847     }
7848   
7849   gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
7850
7851   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7852     op0 = copy_to_mode_reg (mode0, op0);
7853
7854   pat = GEN_FCN (icode) (target, op0);
7855   if (! pat)
7856     return 0;
7857   
7858   emit_insn (pat);
7859   
7860   return target;
7861 }
7862
7863
7864 /* Subroutine of avr_expand_builtin to take care of binop insns.  */
7865
7866 static rtx
7867 avr_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
7868 {
7869   rtx pat;
7870   tree arg0 = CALL_EXPR_ARG (exp, 0);
7871   tree arg1 = CALL_EXPR_ARG (exp, 1);
7872   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7873   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7874   enum machine_mode op0mode = GET_MODE (op0);
7875   enum machine_mode op1mode = GET_MODE (op1);
7876   enum machine_mode tmode = insn_data[icode].operand[0].mode;
7877   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7878   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7879
7880   if (! target
7881       || GET_MODE (target) != tmode
7882       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7883     {
7884       target = gen_reg_rtx (tmode);
7885     }
7886
7887   if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
7888     {
7889       op0mode = HImode;
7890       op0 = gen_lowpart (HImode, op0);
7891     }
7892   
7893   if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
7894     {
7895       op1mode = HImode;
7896       op1 = gen_lowpart (HImode, op1);
7897     }
7898   
7899   /* In case the insn wants input operands in modes different from
7900      the result, abort.  */
7901   
7902   gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
7903               && (op1mode == mode1 || op1mode == VOIDmode));
7904
7905   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7906     op0 = copy_to_mode_reg (mode0, op0);
7907   
7908   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7909     op1 = copy_to_mode_reg (mode1, op1);
7910
7911   pat = GEN_FCN (icode) (target, op0, op1);
7912   
7913   if (! pat)
7914     return 0;
7915
7916   emit_insn (pat);
7917   return target;
7918 }
7919
7920
7921 /* Expand an expression EXP that calls a built-in function,
7922    with result going to TARGET if that's convenient
7923    (and in mode MODE if that's convenient).
7924    SUBTARGET may be used as the target for computing one of EXP's operands.
7925    IGNORE is nonzero if the value is to be ignored.  */
7926
7927 static rtx
7928 avr_expand_builtin (tree exp, rtx target,
7929                     rtx subtarget ATTRIBUTE_UNUSED,
7930                     enum machine_mode mode ATTRIBUTE_UNUSED,
7931                     int ignore ATTRIBUTE_UNUSED)
7932 {
7933   size_t i;
7934   const struct avr_builtin_description *d;
7935   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7936   unsigned int id = DECL_FUNCTION_CODE (fndecl);
7937   tree arg0;
7938   rtx op0;
7939
7940   switch (id)
7941     {
7942     case AVR_BUILTIN_NOP:
7943       emit_insn (gen_nopv (GEN_INT(1)));
7944       return 0;
7945       
7946     case AVR_BUILTIN_SEI:
7947       emit_insn (gen_enable_interrupt ());
7948       return 0;
7949       
7950     case AVR_BUILTIN_CLI:
7951       emit_insn (gen_disable_interrupt ());
7952       return 0;
7953       
7954     case AVR_BUILTIN_WDR:
7955       emit_insn (gen_wdr ());
7956       return 0;
7957       
7958     case AVR_BUILTIN_SLEEP:
7959       emit_insn (gen_sleep ());
7960       return 0;
7961       
7962     case AVR_BUILTIN_DELAY_CYCLES:
7963       {
7964         arg0 = CALL_EXPR_ARG (exp, 0);
7965         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7966
7967         if (! CONST_INT_P (op0))
7968           error ("__builtin_avr_delay_cycles expects a compile time integer constant.");
7969
7970         avr_expand_delay_cycles (op0);
7971         return 0;
7972       }
7973     }
7974
7975   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
7976     if (d->id == id)
7977       return avr_expand_unop_builtin (d->icode, exp, target);
7978
7979   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
7980     if (d->id == id)
7981       return avr_expand_binop_builtin (d->icode, exp, target);
7982
7983   gcc_unreachable ();
7984 }
7985
7986
7987 #include "gt-avr.h"