OSDN Git Service

* config/avr/avr.c (output_reload_in_const): Loading a byte with 0
[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 "c-family/c-common.h"
39 #include "diagnostic-core.h"
40 #include "obstack.h"
41 #include "function.h"
42 #include "recog.h"
43 #include "optabs.h"
44 #include "ggc.h"
45 #include "langhooks.h"
46 #include "tm_p.h"
47 #include "target.h"
48 #include "target-def.h"
49 #include "params.h"
50 #include "df.h"
51
52 /* Maximal allowed offset for an address in the LD command */
53 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
54
55 /* Return true if STR starts with PREFIX and false, otherwise.  */
56 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
57
58 /* The 4 bits starting at SECTION_MACH_DEP are reverved to store
59    1 + flash segment where progmem data is to be located.
60    For example, data with __pgm2 is stored as (1+2) * SECTION_MACH_DEP.  */
61 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
62
63
64 /* Prototypes for local helper functions.  */
65
66 static const char* out_movqi_r_mr (rtx, rtx[], int*);
67 static const char* out_movhi_r_mr (rtx, rtx[], int*);
68 static const char* out_movsi_r_mr (rtx, rtx[], int*);
69 static const char* out_movqi_mr_r (rtx, rtx[], int*);
70 static const char* out_movhi_mr_r (rtx, rtx[], int*);
71 static const char* out_movsi_mr_r (rtx, rtx[], int*);
72
73 static int avr_naked_function_p (tree);
74 static int interrupt_function_p (tree);
75 static int signal_function_p (tree);
76 static int avr_OS_task_function_p (tree);
77 static int avr_OS_main_function_p (tree);
78 static int avr_regs_to_save (HARD_REG_SET *);
79 static int get_sequence_length (rtx insns);
80 static int sequent_regs_live (void);
81 static const char *ptrreg_to_str (int);
82 static const char *cond_string (enum rtx_code);
83 static int avr_num_arg_regs (enum machine_mode, const_tree);
84 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
85                                  int, bool);
86 static void output_reload_in_const (rtx*, rtx, int*, bool);
87 static struct machine_function * avr_init_machine_status (void);
88
89
90 /* Prototypes for hook implementors if needed before their implementation.  */
91
92 static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
93
94
95 /* Allocate registers from r25 to r8 for parameters for function calls.  */
96 #define FIRST_CUM_REG 26
97
98 /* Implicit target register of LPM instruction (R0) */
99 static GTY(()) rtx lpm_reg_rtx;
100
101 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
102 static GTY(()) rtx lpm_addr_reg_rtx;
103
104 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
105 static GTY(()) rtx tmp_reg_rtx;
106
107 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
108 static GTY(()) rtx zero_reg_rtx;
109
110 /* RAMPZ special function register */
111 static GTY(()) rtx rampz_rtx;
112
113 /* RTX containing the strings "" and "e", respectively */
114 static GTY(()) rtx xstring_empty;
115 static GTY(()) rtx xstring_e;
116
117 /* RTXs for all general purpose registers as QImode */
118 static GTY(()) rtx all_regs_rtx[32];
119
120 /* AVR register names {"r0", "r1", ..., "r31"} */
121 static const char *const avr_regnames[] = REGISTER_NAMES;
122
123 /* Preprocessor macros to define depending on MCU type.  */
124 const char *avr_extra_arch_macro;
125
126 /* Current architecture.  */
127 const struct base_arch_s *avr_current_arch;
128
129 /* Current device.  */
130 const struct mcu_type_s *avr_current_device;
131
132 /* Section to put switch tables in.  */
133 static GTY(()) section *progmem_swtable_section;
134
135 /* Unnamed section associated to __attribute__((progmem)) aka. PROGMEM.  */
136 static GTY(()) section *progmem_section[6];
137
138 static const char * const progmem_section_prefix[6] =
139   {
140     ".progmem.data",
141     ".progmem1.data",
142     ".progmem2.data",
143     ".progmem3.data",
144     ".progmem4.data",
145     ".progmem5.data"
146   };
147
148 /* To track if code will use .bss and/or .data.  */
149 bool avr_need_clear_bss_p = false;
150 bool avr_need_copy_data_p = false;
151
152 \f
153 /* Initialize the GCC target structure.  */
154 #undef TARGET_ASM_ALIGNED_HI_OP
155 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
156 #undef TARGET_ASM_ALIGNED_SI_OP
157 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
158 #undef TARGET_ASM_UNALIGNED_HI_OP
159 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
160 #undef TARGET_ASM_UNALIGNED_SI_OP
161 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
162 #undef TARGET_ASM_INTEGER
163 #define TARGET_ASM_INTEGER avr_assemble_integer
164 #undef TARGET_ASM_FILE_START
165 #define TARGET_ASM_FILE_START avr_file_start
166 #undef TARGET_ASM_FILE_END
167 #define TARGET_ASM_FILE_END avr_file_end
168
169 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
170 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
171 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
172 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
173
174 #undef TARGET_FUNCTION_VALUE
175 #define TARGET_FUNCTION_VALUE avr_function_value
176 #undef TARGET_LIBCALL_VALUE
177 #define TARGET_LIBCALL_VALUE avr_libcall_value
178 #undef TARGET_FUNCTION_VALUE_REGNO_P
179 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
180
181 #undef TARGET_ATTRIBUTE_TABLE
182 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
183 #undef TARGET_INSERT_ATTRIBUTES
184 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
185 #undef TARGET_SECTION_TYPE_FLAGS
186 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
187
188 #undef TARGET_ASM_NAMED_SECTION
189 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
190 #undef TARGET_ASM_INIT_SECTIONS
191 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
192 #undef TARGET_ENCODE_SECTION_INFO
193 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
194 #undef TARGET_ASM_SELECT_SECTION
195 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
196
197 #undef TARGET_REGISTER_MOVE_COST
198 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
199 #undef TARGET_MEMORY_MOVE_COST
200 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
201 #undef TARGET_RTX_COSTS
202 #define TARGET_RTX_COSTS avr_rtx_costs
203 #undef TARGET_ADDRESS_COST
204 #define TARGET_ADDRESS_COST avr_address_cost
205 #undef TARGET_MACHINE_DEPENDENT_REORG
206 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
207 #undef TARGET_FUNCTION_ARG
208 #define TARGET_FUNCTION_ARG avr_function_arg
209 #undef TARGET_FUNCTION_ARG_ADVANCE
210 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
211
212 #undef TARGET_RETURN_IN_MEMORY
213 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
214
215 #undef TARGET_STRICT_ARGUMENT_NAMING
216 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
217
218 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
219 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
220
221 #undef TARGET_HARD_REGNO_SCRATCH_OK
222 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
223 #undef TARGET_CASE_VALUES_THRESHOLD
224 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
225
226 #undef TARGET_FRAME_POINTER_REQUIRED
227 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
228 #undef TARGET_CAN_ELIMINATE
229 #define TARGET_CAN_ELIMINATE avr_can_eliminate
230
231 #undef TARGET_CLASS_LIKELY_SPILLED_P
232 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
233
234 #undef TARGET_OPTION_OVERRIDE
235 #define TARGET_OPTION_OVERRIDE avr_option_override
236
237 #undef TARGET_CANNOT_MODIFY_JUMPS_P
238 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
239
240 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
241 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
242
243 #undef TARGET_INIT_BUILTINS
244 #define TARGET_INIT_BUILTINS avr_init_builtins
245
246 #undef TARGET_EXPAND_BUILTIN
247 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
248
249 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
250 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
251
252 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
253 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
254
255 #undef  TARGET_ADDR_SPACE_SUBSET_P
256 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
257
258 #undef  TARGET_ADDR_SPACE_CONVERT
259 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
260
261 #undef  TARGET_ADDR_SPACE_ADDRESS_MODE
262 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
263
264 #undef  TARGET_ADDR_SPACE_POINTER_MODE
265 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
266
267 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
268 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P avr_addr_space_legitimate_address_p
269
270 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
271 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
272
273 \f
274
275 /* Custom function to replace string prefix.
276
277    Return a ggc-allocated string with strlen (OLD_PREFIX) characters removed
278    from the start of OLD_STR and then prepended with NEW_PREFIX.  */
279
280 static inline const char*
281 avr_replace_prefix (const char *old_str,
282                     const char *old_prefix, const char *new_prefix)
283 {
284   char *new_str;
285   size_t len = strlen (old_str) + strlen (new_prefix) - strlen (old_prefix);
286
287   gcc_assert (strlen (old_prefix) <= strlen (old_str));
288
289   /* Unfortunately, ggc_alloc_string returns a const char* and thus cannot be
290      used here.  */
291      
292   new_str = (char*) ggc_alloc_atomic (1 + len);
293
294   strcat (stpcpy (new_str, new_prefix), old_str + strlen (old_prefix));
295   
296   return (const char*) new_str;
297 }
298
299
300 /* Custom function to count number of set bits.  */
301
302 static inline int
303 avr_popcount (unsigned int val)
304 {
305   int pop = 0;
306
307   while (val)
308     {
309       val &= val-1;
310       pop++;
311     }
312
313   return pop;
314 }
315
316
317 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
318    Return true if the least significant N_BYTES bytes of XVAL all have a
319    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
320    of integers which contains an integer N iff bit N of POP_MASK is set.  */
321    
322 bool
323 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
324 {
325   int i;
326
327   enum machine_mode mode = GET_MODE (xval);
328
329   if (VOIDmode == mode)
330     mode = SImode;
331
332   for (i = 0; i < n_bytes; i++)
333     {
334       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
335       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
336
337       if (0 == (pop_mask & (1 << avr_popcount (val8))))
338         return false;
339     }
340
341   return true;
342 }
343
344 static void
345 avr_option_override (void)
346 {
347   flag_delete_null_pointer_checks = 0;
348
349   /* caller-save.c looks for call-clobbered hard registers that are assigned
350      to pseudos that cross calls and tries so save-restore them around calls
351      in order to reduce the number of stack slots needed.
352
353      This might leads to situations where reload is no more able to cope
354      with the challenge of AVR's very few address registers and fails to
355      perform the requested spills.  */
356   
357   if (avr_strict_X)
358     flag_caller_saves = 0;
359
360   /* Unwind tables currently require a frame pointer for correctness,
361      see toplev.c:process_options().  */
362
363   if ((flag_unwind_tables
364        || flag_non_call_exceptions
365        || flag_asynchronous_unwind_tables)
366       && !ACCUMULATE_OUTGOING_ARGS)
367     {
368       flag_omit_frame_pointer = 0;
369     }
370
371   avr_current_device = &avr_mcu_types[avr_mcu_index];
372   avr_current_arch = &avr_arch_types[avr_current_device->arch];
373   avr_extra_arch_macro = avr_current_device->macro;
374
375   init_machine_status = avr_init_machine_status;
376
377   avr_log_set_avr_log();
378 }
379
380 /* Function to set up the backend function structure.  */
381
382 static struct machine_function *
383 avr_init_machine_status (void)
384 {
385   return ggc_alloc_cleared_machine_function ();
386 }
387
388
389 /* Implement `INIT_EXPANDERS'.  */
390 /* The function works like a singleton.  */
391
392 void
393 avr_init_expanders (void)
394 {
395   int regno;
396
397   static bool done = false;
398
399   if (done)
400     return;
401   else
402     done = true;
403
404   for (regno = 0; regno < 32; regno ++)
405     all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
406
407   lpm_reg_rtx  = all_regs_rtx[LPM_REGNO];
408   tmp_reg_rtx  = all_regs_rtx[TMP_REGNO];
409   zero_reg_rtx = all_regs_rtx[ZERO_REGNO];
410
411   lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
412
413   rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR));
414
415   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
416   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
417 }
418
419
420 /* Return register class for register R.  */
421
422 enum reg_class
423 avr_regno_reg_class (int r)
424 {
425   static const enum reg_class reg_class_tab[] =
426     {
427       R0_REG,
428       /* r1 - r15 */
429       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
430       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
431       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
432       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
433       /* r16 - r23 */
434       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
435       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
436       /* r24, r25 */
437       ADDW_REGS, ADDW_REGS,
438       /* X: r26, 27 */
439       POINTER_X_REGS, POINTER_X_REGS,
440       /* Y: r28, r29 */
441       POINTER_Y_REGS, POINTER_Y_REGS,
442       /* Z: r30, r31 */
443       POINTER_Z_REGS, POINTER_Z_REGS,
444       /* SP: SPL, SPH */
445       STACK_REG, STACK_REG
446     };
447
448   if (r <= 33)
449     return reg_class_tab[r];
450   
451   return ALL_REGS;
452 }
453
454
455 static bool
456 avr_scalar_mode_supported_p (enum machine_mode mode)
457 {
458   if (PSImode == mode)
459     return true;
460
461   return default_scalar_mode_supported_p (mode);
462 }
463
464
465 /* Return the segment number of pgm address space AS, i.e.
466    the 64k block it lives in.
467    Return -1 if unknown, i.e. 24-bit AS in flash.
468    Return -2 for anything else.  */
469
470 static int
471 avr_pgm_segment (addr_space_t as)
472 {
473   switch (as)
474     {
475     default: return -2;
476
477     case ADDR_SPACE_PGMX:  return -1;
478     case ADDR_SPACE_PGM:   return 0;
479     case ADDR_SPACE_PGM1:  return 1;
480     case ADDR_SPACE_PGM2:  return 2;
481     case ADDR_SPACE_PGM3:  return 3;
482     case ADDR_SPACE_PGM4:  return 4;
483     case ADDR_SPACE_PGM5:  return 5;
484     }
485 }
486
487
488 /* Return TRUE if DECL is a VAR_DECL located in Flash and FALSE, otherwise.  */
489
490 static bool
491 avr_decl_pgm_p (tree decl)
492 {
493   if (TREE_CODE (decl) != VAR_DECL
494       || TREE_TYPE (decl) == error_mark_node)
495     {
496       return false;
497     }
498
499   return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
500 }
501
502
503 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit Flash
504    address space and FALSE, otherwise.  */
505  
506 static bool
507 avr_decl_pgmx_p (tree decl)
508 {
509   if (TREE_CODE (decl) != VAR_DECL
510       || TREE_TYPE (decl) == error_mark_node)
511     {
512       return false;
513     }
514
515   return (ADDR_SPACE_PGMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
516 }
517
518
519 /* Return TRUE if X is a MEM rtx located in Flash and FALSE, otherwise.  */
520
521 bool
522 avr_mem_pgm_p (rtx x)
523 {
524   return (MEM_P (x)
525           && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
526 }
527
528
529 /* Return TRUE if X is a MEM rtx located in the 24-bit Flash
530    address space and FALSE, otherwise.  */
531
532 bool
533 avr_mem_pgmx_p (rtx x)
534 {
535   return (MEM_P (x)
536           && ADDR_SPACE_PGMX == MEM_ADDR_SPACE (x));
537 }
538
539
540 /* A helper for the subsequent function attribute used to dig for
541    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
542
543 static inline int
544 avr_lookup_function_attribute1 (const_tree func, const char *name)
545 {
546   if (FUNCTION_DECL == TREE_CODE (func))
547     {
548       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
549         {
550           return true;
551         }
552       
553       func = TREE_TYPE (func);
554     }
555
556   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
557               || TREE_CODE (func) == METHOD_TYPE);
558   
559   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
560 }
561
562 /* Return nonzero if FUNC is a naked function.  */
563
564 static int
565 avr_naked_function_p (tree func)
566 {
567   return avr_lookup_function_attribute1 (func, "naked");
568 }
569
570 /* Return nonzero if FUNC is an interrupt function as specified
571    by the "interrupt" attribute.  */
572
573 static int
574 interrupt_function_p (tree func)
575 {
576   return avr_lookup_function_attribute1 (func, "interrupt");
577 }
578
579 /* Return nonzero if FUNC is a signal function as specified
580    by the "signal" attribute.  */
581
582 static int
583 signal_function_p (tree func)
584 {
585   return avr_lookup_function_attribute1 (func, "signal");
586 }
587
588 /* Return nonzero if FUNC is an OS_task function.  */
589
590 static int
591 avr_OS_task_function_p (tree func)
592 {
593   return avr_lookup_function_attribute1 (func, "OS_task");
594 }
595
596 /* Return nonzero if FUNC is an OS_main function.  */
597
598 static int
599 avr_OS_main_function_p (tree func)
600 {
601   return avr_lookup_function_attribute1 (func, "OS_main");
602 }
603
604
605 /* Implement `ACCUMULATE_OUTGOING_ARGS'.  */
606 bool
607 avr_accumulate_outgoing_args (void)
608 {
609   if (!cfun)
610     return TARGET_ACCUMULATE_OUTGOING_ARGS;
611
612   /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
613         what offset is correct.  In some cases it is relative to
614         virtual_outgoing_args_rtx and in others it is relative to
615         virtual_stack_vars_rtx.  For example code see
616             gcc.c-torture/execute/built-in-setjmp.c
617             gcc.c-torture/execute/builtins/sprintf-chk.c   */
618   
619   return (TARGET_ACCUMULATE_OUTGOING_ARGS
620           && !(cfun->calls_setjmp
621                || cfun->has_nonlocal_label));
622 }
623
624
625 /* Report contribution of accumulated outgoing arguments to stack size.  */
626
627 static inline int
628 avr_outgoing_args_size (void)
629 {
630   return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
631 }
632
633
634 /* Implement `STARTING_FRAME_OFFSET'.  */
635 /* This is the offset from the frame pointer register to the first stack slot
636    that contains a variable living in the frame.  */
637
638 int
639 avr_starting_frame_offset (void)
640 {
641   return 1 + avr_outgoing_args_size ();
642 }
643
644
645 /* Return the number of hard registers to push/pop in the prologue/epilogue
646    of the current function, and optionally store these registers in SET.  */
647
648 static int
649 avr_regs_to_save (HARD_REG_SET *set)
650 {
651   int reg, count;
652   int int_or_sig_p = (interrupt_function_p (current_function_decl)
653                       || signal_function_p (current_function_decl));
654
655   if (set)
656     CLEAR_HARD_REG_SET (*set);
657   count = 0;
658
659   /* No need to save any registers if the function never returns or 
660      has the "OS_task" or "OS_main" attribute.  */
661   if (TREE_THIS_VOLATILE (current_function_decl)
662       || cfun->machine->is_OS_task
663       || cfun->machine->is_OS_main)
664     return 0;
665
666   for (reg = 0; reg < 32; reg++)
667     {
668       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
669          any global register variables.  */
670       if (fixed_regs[reg])
671         continue;
672
673       if ((int_or_sig_p && !current_function_is_leaf && call_used_regs[reg])
674           || (df_regs_ever_live_p (reg)
675               && (int_or_sig_p || !call_used_regs[reg])
676               /* Don't record frame pointer registers here.  They are treated
677                  indivitually in prologue.  */
678               && !(frame_pointer_needed
679                    && (reg == REG_Y || reg == (REG_Y+1)))))
680         {
681           if (set)
682             SET_HARD_REG_BIT (*set, reg);
683           count++;
684         }
685     }
686   return count;
687 }
688
689 /* Return true if register FROM can be eliminated via register TO.  */
690
691 static bool
692 avr_can_eliminate (const int from, const int to)
693 {
694   return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
695           || (frame_pointer_needed && to == FRAME_POINTER_REGNUM)
696           || ((from == FRAME_POINTER_REGNUM 
697                || from == FRAME_POINTER_REGNUM + 1)
698               && !frame_pointer_needed));
699 }
700
701 /* Compute offset between arg_pointer and frame_pointer.  */
702
703 int
704 avr_initial_elimination_offset (int from, int to)
705 {
706   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
707     return 0;
708   else
709     {
710       int offset = frame_pointer_needed ? 2 : 0;
711       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
712       
713       offset += avr_regs_to_save (NULL);
714       return (get_frame_size () + avr_outgoing_args_size()
715               + avr_pc_size + 1 + offset);
716     }
717 }
718
719 /* Actual start of frame is virtual_stack_vars_rtx this is offset from 
720    frame pointer by +STARTING_FRAME_OFFSET.
721    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
722    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
723
724 static rtx
725 avr_builtin_setjmp_frame_value (void)
726 {
727   return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx, 
728                         gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
729 }
730
731 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3 byte PC).
732    This is return address of function.  */
733 rtx 
734 avr_return_addr_rtx (int count, rtx tem)
735 {
736   rtx r;
737     
738   /* Can only return this function's return address. Others not supported.  */
739   if (count)
740      return NULL;
741
742   if (AVR_3_BYTE_PC)
743     {
744       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
745       warning (0, "'builtin_return_address' contains only 2 bytes of address");
746     }
747   else
748     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
749
750   r = gen_rtx_PLUS (Pmode, tem, r);
751   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
752   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
753   return  r;
754 }
755
756 /* Return 1 if the function epilogue is just a single "ret".  */
757
758 int
759 avr_simple_epilogue (void)
760 {
761   return (! frame_pointer_needed
762           && get_frame_size () == 0
763           && avr_outgoing_args_size() == 0
764           && avr_regs_to_save (NULL) == 0
765           && ! interrupt_function_p (current_function_decl)
766           && ! signal_function_p (current_function_decl)
767           && ! avr_naked_function_p (current_function_decl)
768           && ! TREE_THIS_VOLATILE (current_function_decl));
769 }
770
771 /* This function checks sequence of live registers.  */
772
773 static int
774 sequent_regs_live (void)
775 {
776   int reg;
777   int live_seq=0;
778   int cur_seq=0;
779
780   for (reg = 0; reg < 18; ++reg)
781     {
782       if (fixed_regs[reg])
783         {
784           /* Don't recognize sequences that contain global register
785              variables.  */
786       
787           if (live_seq != 0)
788             return 0;
789           else
790             continue;
791         }
792       
793       if (!call_used_regs[reg])
794         {
795           if (df_regs_ever_live_p (reg))
796             {
797               ++live_seq;
798               ++cur_seq;
799             }
800           else
801             cur_seq = 0;
802         }
803     }
804
805   if (!frame_pointer_needed)
806     {
807       if (df_regs_ever_live_p (REG_Y))
808         {
809           ++live_seq;
810           ++cur_seq;
811         }
812       else
813         cur_seq = 0;
814
815       if (df_regs_ever_live_p (REG_Y+1))
816         {
817           ++live_seq;
818           ++cur_seq;
819         }
820       else
821         cur_seq = 0;
822     }
823   else
824     {
825       cur_seq += 2;
826       live_seq += 2;
827     }
828   return (cur_seq == live_seq) ? live_seq : 0;
829 }
830
831 /* Obtain the length sequence of insns.  */
832
833 int
834 get_sequence_length (rtx insns)
835 {
836   rtx insn;
837   int length;
838   
839   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
840     length += get_attr_length (insn);
841                 
842   return length;
843 }
844
845 /*  Implement INCOMING_RETURN_ADDR_RTX.  */
846
847 rtx
848 avr_incoming_return_addr_rtx (void)
849 {
850   /* The return address is at the top of the stack.  Note that the push
851      was via post-decrement, which means the actual address is off by one.  */
852   return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
853 }
854
855 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
856
857 static void
858 emit_push_byte (unsigned regno, bool frame_related_p)
859 {
860   rtx mem, reg, insn;
861
862   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
863   mem = gen_frame_mem (QImode, mem);
864   reg = gen_rtx_REG (QImode, regno);
865
866   insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
867   if (frame_related_p)
868     RTX_FRAME_RELATED_P (insn) = 1;
869
870   cfun->machine->stack_usage++;
871 }
872
873 static void
874 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
875 {
876   rtx insn;
877   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
878   int live_seq = sequent_regs_live ();
879
880   bool minimize = (TARGET_CALL_PROLOGUES
881                    && live_seq
882                    && !isr_p
883                    && !cfun->machine->is_OS_task
884                    && !cfun->machine->is_OS_main);
885   
886   if (minimize
887       && (frame_pointer_needed
888           || avr_outgoing_args_size() > 8
889           || (AVR_2_BYTE_PC && live_seq > 6)
890           || live_seq > 7)) 
891     {
892       rtx pattern;
893       int first_reg, reg, offset;
894
895       emit_move_insn (gen_rtx_REG (HImode, REG_X), 
896                       gen_int_mode (size, HImode));
897
898       pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
899                                          gen_int_mode (live_seq+size, HImode));
900       insn = emit_insn (pattern);
901       RTX_FRAME_RELATED_P (insn) = 1;
902
903       /* Describe the effect of the unspec_volatile call to prologue_saves.
904          Note that this formulation assumes that add_reg_note pushes the
905          notes to the front.  Thus we build them in the reverse order of
906          how we want dwarf2out to process them.  */
907
908       /* The function does always set frame_pointer_rtx, but whether that
909          is going to be permanent in the function is frame_pointer_needed.  */
910
911       add_reg_note (insn, REG_CFA_ADJUST_CFA,
912                     gen_rtx_SET (VOIDmode, (frame_pointer_needed
913                                             ? frame_pointer_rtx
914                                             : stack_pointer_rtx),
915                                  plus_constant (stack_pointer_rtx,
916                                                 -(size + live_seq))));
917
918       /* Note that live_seq always contains r28+r29, but the other
919          registers to be saved are all below 18.  */
920
921       first_reg = 18 - (live_seq - 2);
922
923       for (reg = 29, offset = -live_seq + 1;
924            reg >= first_reg;
925            reg = (reg == 28 ? 17 : reg - 1), ++offset)
926         {
927           rtx m, r;
928
929           m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
930           r = gen_rtx_REG (QImode, reg);
931           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
932         }
933
934       cfun->machine->stack_usage += size + live_seq;
935     }
936   else /* !minimize */
937     {
938       int reg;
939       
940       for (reg = 0; reg < 32; ++reg)
941         if (TEST_HARD_REG_BIT (set, reg))
942           emit_push_byte (reg, true);
943
944       if (frame_pointer_needed
945           && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
946         {
947           /* Push frame pointer.  Always be consistent about the
948              ordering of pushes -- epilogue_restores expects the
949              register pair to be pushed low byte first.  */
950           
951           emit_push_byte (REG_Y, true);
952           emit_push_byte (REG_Y + 1, true);
953         }
954           
955       if (frame_pointer_needed
956           && size == 0)
957         {
958           insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
959           RTX_FRAME_RELATED_P (insn) = 1;
960         }
961       
962       if (size != 0)
963         {
964           /*  Creating a frame can be done by direct manipulation of the
965               stack or via the frame pointer. These two methods are:
966                   fp =  sp
967                   fp -= size
968                   sp =  fp
969               or
970                   sp -= size
971                   fp =  sp    (*)
972               the optimum method depends on function type, stack and
973               frame size.  To avoid a complex logic, both methods are
974               tested and shortest is selected.
975
976               There is also the case where SIZE != 0 and no frame pointer is
977               needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
978               In that case, insn (*) is not needed in that case.
979               We use the X register as scratch. This is save because in X
980               is call-clobbered.
981                  In an interrupt routine, the case of SIZE != 0 together with
982               !frame_pointer_needed can only occur if the function is not a
983               leaf function and thus X has already been saved.  */
984               
985           rtx fp_plus_insns, fp, my_fp;
986           rtx sp_minus_size = plus_constant (stack_pointer_rtx, -size);
987
988           gcc_assert (frame_pointer_needed
989                       || !isr_p
990                       || !current_function_is_leaf);
991           
992           fp = my_fp = (frame_pointer_needed
993                         ? frame_pointer_rtx
994                         : gen_rtx_REG (Pmode, REG_X));
995           
996           if (AVR_HAVE_8BIT_SP)
997             {
998               /* The high byte (r29) does not change:
999                  Prefer SUBI (1 cycle) over ABIW (2 cycles, same size).  */
1000
1001               my_fp = simplify_gen_subreg (QImode, fp, Pmode, 0);
1002             }
1003
1004           /************  Method 1: Adjust frame pointer  ************/
1005           
1006           start_sequence ();
1007
1008           /* Normally, the dwarf2out frame-related-expr interpreter does
1009              not expect to have the CFA change once the frame pointer is
1010              set up.  Thus, we avoid marking the move insn below and
1011              instead indicate that the entire operation is complete after
1012              the frame pointer subtraction is done.  */
1013           
1014           insn = emit_move_insn (fp, stack_pointer_rtx);
1015           if (!frame_pointer_needed)
1016             RTX_FRAME_RELATED_P (insn) = 1;
1017
1018           insn = emit_move_insn (my_fp, plus_constant (my_fp, -size));
1019           RTX_FRAME_RELATED_P (insn) = 1;
1020           
1021           if (frame_pointer_needed)
1022             {
1023               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1024                             gen_rtx_SET (VOIDmode, fp, sp_minus_size));
1025             }
1026           
1027           /* Copy to stack pointer.  Note that since we've already
1028              changed the CFA to the frame pointer this operation
1029              need not be annotated if frame pointer is needed.  */
1030               
1031           if (AVR_HAVE_8BIT_SP)
1032             {
1033               insn = emit_move_insn (stack_pointer_rtx, fp);
1034             }
1035           else if (TARGET_NO_INTERRUPTS 
1036                    || isr_p
1037                    || cfun->machine->is_OS_main)
1038             {
1039               rtx irqs_are_on = GEN_INT (!!cfun->machine->is_interrupt);
1040               
1041               insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1042                                                 fp, irqs_are_on));
1043             }
1044           else
1045             {
1046               insn = emit_move_insn (stack_pointer_rtx, fp);
1047             }
1048
1049           if (!frame_pointer_needed)
1050             RTX_FRAME_RELATED_P (insn) = 1;
1051
1052           fp_plus_insns = get_insns ();
1053           end_sequence ();
1054           
1055           /************  Method 2: Adjust Stack pointer  ************/
1056
1057           /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1058              can only handle specific offsets.  */
1059           
1060           if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1061             {
1062               rtx sp_plus_insns;
1063               
1064               start_sequence ();
1065
1066               insn = emit_move_insn (stack_pointer_rtx, sp_minus_size);
1067               RTX_FRAME_RELATED_P (insn) = 1;
1068
1069               if (frame_pointer_needed)
1070                 {
1071                   insn = emit_move_insn (fp, stack_pointer_rtx);
1072                   RTX_FRAME_RELATED_P (insn) = 1;
1073                 }
1074
1075               sp_plus_insns = get_insns ();
1076               end_sequence ();
1077
1078               /************ Use shortest method  ************/
1079                   
1080               emit_insn (get_sequence_length (sp_plus_insns)
1081                          < get_sequence_length (fp_plus_insns)
1082                          ? sp_plus_insns
1083                          : fp_plus_insns);
1084             }
1085           else
1086             {
1087               emit_insn (fp_plus_insns);
1088             }
1089
1090           cfun->machine->stack_usage += size;
1091         } /* !minimize && size != 0 */
1092     } /* !minimize */
1093 }
1094
1095
1096 /*  Output function prologue.  */
1097
1098 void
1099 expand_prologue (void)
1100 {
1101   HARD_REG_SET set;
1102   HOST_WIDE_INT size;
1103
1104   size = get_frame_size() + avr_outgoing_args_size();
1105   
1106   /* Init cfun->machine.  */
1107   cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
1108   cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
1109   cfun->machine->is_signal = signal_function_p (current_function_decl);
1110   cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
1111   cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
1112   cfun->machine->stack_usage = 0;
1113   
1114   /* Prologue: naked.  */
1115   if (cfun->machine->is_naked)
1116     {
1117       return;
1118     }
1119
1120   avr_regs_to_save (&set);
1121
1122   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1123     {
1124       /* Enable interrupts.  */
1125       if (cfun->machine->is_interrupt)
1126         emit_insn (gen_enable_interrupt ());
1127         
1128       /* Push zero reg.  */
1129       emit_push_byte (ZERO_REGNO, true);
1130
1131       /* Push tmp reg.  */
1132       emit_push_byte (TMP_REGNO, true);
1133
1134       /* Push SREG.  */
1135       /* ??? There's no dwarf2 column reserved for SREG.  */
1136       emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
1137       emit_push_byte (TMP_REGNO, false);
1138
1139       /* Push RAMPZ.  */
1140       /* ??? There's no dwarf2 column reserved for RAMPZ.  */
1141       if (AVR_HAVE_RAMPZ 
1142           && TEST_HARD_REG_BIT (set, REG_Z)
1143           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1144         {
1145           emit_move_insn (tmp_reg_rtx, rampz_rtx);
1146           emit_push_byte (TMP_REGNO, false);
1147         }
1148         
1149       /* Clear zero reg.  */
1150       emit_move_insn (zero_reg_rtx, const0_rtx);
1151
1152       /* Prevent any attempt to delete the setting of ZERO_REG!  */
1153       emit_use (zero_reg_rtx);
1154     }
1155
1156   avr_prologue_setup_frame (size, set);
1157   
1158   if (flag_stack_usage_info)
1159     current_function_static_stack_size = cfun->machine->stack_usage;
1160 }
1161
1162 /* Output summary at end of function prologue.  */
1163
1164 static void
1165 avr_asm_function_end_prologue (FILE *file)
1166 {
1167   if (cfun->machine->is_naked)
1168     {
1169       fputs ("/* prologue: naked */\n", file);
1170     }
1171   else
1172     {
1173       if (cfun->machine->is_interrupt)
1174         {
1175           fputs ("/* prologue: Interrupt */\n", file);
1176         }
1177       else if (cfun->machine->is_signal)
1178         {
1179           fputs ("/* prologue: Signal */\n", file);
1180         }
1181       else
1182         fputs ("/* prologue: function */\n", file);
1183     }
1184
1185   if (ACCUMULATE_OUTGOING_ARGS)
1186     fprintf (file, "/* outgoing args size = %d */\n",
1187              avr_outgoing_args_size());
1188
1189   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1190                  get_frame_size());
1191   fprintf (file, "/* stack size = %d */\n",
1192                  cfun->machine->stack_usage);
1193   /* Create symbol stack offset here so all functions have it. Add 1 to stack
1194      usage for offset so that SP + .L__stack_offset = return address.  */
1195   fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1196 }
1197
1198
1199 /* Implement EPILOGUE_USES.  */
1200
1201 int
1202 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1203 {
1204   if (reload_completed 
1205       && cfun->machine
1206       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1207     return 1;
1208   return 0;
1209 }
1210
1211 /*  Helper for expand_epilogue.  Emit a pop of a byte register.  */
1212
1213 static void
1214 emit_pop_byte (unsigned regno)
1215 {
1216   rtx mem, reg;
1217
1218   mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1219   mem = gen_frame_mem (QImode, mem);
1220   reg = gen_rtx_REG (QImode, regno);
1221
1222   emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
1223 }
1224
1225 /*  Output RTL epilogue.  */
1226
1227 void
1228 expand_epilogue (bool sibcall_p)
1229 {
1230   int reg;
1231   int live_seq;
1232   HARD_REG_SET set;      
1233   int minimize;
1234   HOST_WIDE_INT size;
1235   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1236
1237   size = get_frame_size() + avr_outgoing_args_size();
1238   
1239   /* epilogue: naked  */
1240   if (cfun->machine->is_naked)
1241     {
1242       gcc_assert (!sibcall_p);
1243       
1244       emit_jump_insn (gen_return ());
1245       return;
1246     }
1247
1248   avr_regs_to_save (&set);
1249   live_seq = sequent_regs_live ();
1250   
1251   minimize = (TARGET_CALL_PROLOGUES
1252               && live_seq
1253               && !isr_p
1254               && !cfun->machine->is_OS_task
1255               && !cfun->machine->is_OS_main);
1256   
1257   if (minimize
1258       && (live_seq > 4
1259           || frame_pointer_needed
1260           || size))
1261     {
1262       /*  Get rid of frame.  */
1263       
1264       if (!frame_pointer_needed)
1265         {
1266           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1267         }
1268
1269       if (size)
1270         {
1271           emit_move_insn (frame_pointer_rtx,
1272                           plus_constant (frame_pointer_rtx, size));
1273         }
1274         
1275       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1276       return;
1277     }
1278       
1279   if (size)
1280     {
1281       /* Try two methods to adjust stack and select shortest.  */
1282           
1283       rtx fp, my_fp;
1284       rtx fp_plus_insns;
1285
1286       gcc_assert (frame_pointer_needed
1287                   || !isr_p
1288                   || !current_function_is_leaf);
1289       
1290       fp = my_fp = (frame_pointer_needed
1291                     ? frame_pointer_rtx
1292                     : gen_rtx_REG (Pmode, REG_X));
1293
1294       if (AVR_HAVE_8BIT_SP)
1295         {
1296           /* The high byte (r29) does not change:
1297              Prefer SUBI (1 cycle) over SBIW (2 cycles).  */
1298                   
1299           my_fp = simplify_gen_subreg (QImode, fp, Pmode, 0);
1300         }
1301               
1302       /********** Method 1: Adjust fp register  **********/
1303               
1304       start_sequence ();
1305
1306       if (!frame_pointer_needed)
1307         emit_move_insn (fp, stack_pointer_rtx);
1308
1309       emit_move_insn (my_fp, plus_constant (my_fp, size));
1310
1311       /* Copy to stack pointer.  */
1312               
1313       if (AVR_HAVE_8BIT_SP)
1314         {
1315           emit_move_insn (stack_pointer_rtx, fp);
1316         }
1317       else if (TARGET_NO_INTERRUPTS 
1318                || isr_p
1319                || cfun->machine->is_OS_main)
1320         {
1321           rtx irqs_are_on = GEN_INT (!!cfun->machine->is_interrupt);
1322           
1323           emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp, irqs_are_on));
1324         }
1325       else
1326         {
1327           emit_move_insn (stack_pointer_rtx, fp);
1328         }
1329
1330       fp_plus_insns = get_insns ();
1331       end_sequence ();        
1332
1333       /********** Method 2: Adjust Stack pointer  **********/
1334       
1335       if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1336         {
1337           rtx sp_plus_insns;
1338
1339           start_sequence ();
1340
1341           emit_move_insn (stack_pointer_rtx,
1342                           plus_constant (stack_pointer_rtx, size));
1343
1344           sp_plus_insns = get_insns ();
1345           end_sequence ();
1346
1347           /************ Use shortest method  ************/
1348           
1349           emit_insn (get_sequence_length (sp_plus_insns)
1350                      < get_sequence_length (fp_plus_insns)
1351                      ? sp_plus_insns
1352                      : fp_plus_insns);
1353         }
1354       else
1355         emit_insn (fp_plus_insns);
1356     } /* size != 0 */
1357           
1358   if (frame_pointer_needed
1359       && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1360     {
1361       /* Restore previous frame_pointer.  See expand_prologue for
1362          rationale for not using pophi.  */
1363               
1364       emit_pop_byte (REG_Y + 1);
1365       emit_pop_byte (REG_Y);
1366     }
1367
1368   /* Restore used registers.  */
1369   
1370   for (reg = 31; reg >= 0; --reg)
1371     if (TEST_HARD_REG_BIT (set, reg))
1372       emit_pop_byte (reg);
1373
1374   if (isr_p)
1375     {
1376       /* Restore RAMPZ using tmp reg as scratch.  */
1377       
1378       if (AVR_HAVE_RAMPZ 
1379           && TEST_HARD_REG_BIT (set, REG_Z)
1380           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1381         {
1382           emit_pop_byte (TMP_REGNO);
1383           emit_move_insn (rampz_rtx, tmp_reg_rtx);
1384         }
1385
1386       /* Restore SREG using tmp reg as scratch.  */
1387       
1388       emit_pop_byte (TMP_REGNO);
1389       emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)), 
1390                       tmp_reg_rtx);
1391
1392       /* Restore tmp REG.  */
1393       emit_pop_byte (TMP_REGNO);
1394
1395       /* Restore zero REG.  */
1396       emit_pop_byte (ZERO_REGNO);
1397     }
1398
1399   if (!sibcall_p)
1400     emit_jump_insn (gen_return ());
1401 }
1402
1403 /* Output summary messages at beginning of function epilogue.  */
1404
1405 static void
1406 avr_asm_function_begin_epilogue (FILE *file)
1407 {
1408   fprintf (file, "/* epilogue start */\n");
1409 }
1410
1411
1412 /* Implement TARGET_CANNOT_MODITY_JUMPS_P */
1413
1414 static bool
1415 avr_cannot_modify_jumps_p (void)
1416 {
1417
1418   /* Naked Functions must not have any instructions after
1419      their epilogue, see PR42240 */
1420      
1421   if (reload_completed
1422       && cfun->machine
1423       && cfun->machine->is_naked)
1424     {
1425       return true;
1426     }
1427
1428   return false;
1429 }
1430
1431
1432 /* Helper function for `avr_legitimate_address_p'.  */
1433
1434 static inline bool
1435 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1436                        RTX_CODE outer_code, bool strict)
1437 {
1438   return (REG_P (reg)
1439           && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1440                                                  as, outer_code, UNKNOWN)
1441               || (!strict
1442                   && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1443 }
1444
1445
1446 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1447    machine for a memory operand of mode MODE.  */
1448
1449 static bool
1450 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1451 {
1452   bool ok = CONSTANT_ADDRESS_P (x);
1453   
1454   switch (GET_CODE (x))
1455     {
1456     case REG:
1457       ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1458                                   MEM, strict);
1459
1460       if (strict
1461           && DImode == mode
1462           && REG_X == REGNO (x))
1463         {
1464           ok = false;
1465         }
1466       break;
1467
1468     case POST_INC:
1469     case PRE_DEC:
1470       ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1471                                   GET_CODE (x), strict);
1472       break;
1473
1474     case PLUS:
1475       {
1476         rtx reg = XEXP (x, 0);
1477         rtx op1 = XEXP (x, 1);
1478         
1479         if (REG_P (reg)
1480             && CONST_INT_P (op1)
1481             && INTVAL (op1) >= 0)
1482           {
1483             bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1484
1485             if (fit)
1486               {
1487                 ok = (! strict
1488                       || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1489                                                 PLUS, strict));
1490           
1491                 if (reg == frame_pointer_rtx
1492                     || reg == arg_pointer_rtx)
1493                   {
1494                     ok = true;
1495                   }
1496               }
1497             else if (frame_pointer_needed
1498                      && reg == frame_pointer_rtx)
1499               {
1500                 ok = true;
1501               }
1502           }
1503       }
1504       break;
1505       
1506     default:
1507       break;
1508     }
1509   
1510   if (avr_log.legitimate_address_p)
1511     {
1512       avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1513                  "reload_completed=%d reload_in_progress=%d %s:",
1514                  ok, mode, strict, reload_completed, reload_in_progress,
1515                  reg_renumber ? "(reg_renumber)" : "");
1516       
1517       if (GET_CODE (x) == PLUS
1518           && REG_P (XEXP (x, 0))
1519           && CONST_INT_P (XEXP (x, 1))
1520           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1521           && reg_renumber)
1522         {
1523           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1524                      true_regnum (XEXP (x, 0)));
1525         }
1526       
1527       avr_edump ("\n%r\n", x);
1528     }
1529   
1530   return ok;
1531 }
1532
1533
1534 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1535    now only a helper for avr_addr_space_legitimize_address.  */
1536 /* Attempts to replace X with a valid
1537    memory address for an operand of mode MODE  */
1538
1539 static rtx
1540 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1541 {
1542   bool big_offset_p = false;
1543   
1544   x = oldx;
1545   
1546   if (GET_CODE (oldx) == PLUS
1547       && REG_P (XEXP (oldx, 0)))
1548     {
1549       if (REG_P (XEXP (oldx, 1)))
1550         x = force_reg (GET_MODE (oldx), oldx);
1551       else if (CONST_INT_P (XEXP (oldx, 1)))
1552         {
1553           int offs = INTVAL (XEXP (oldx, 1));
1554           if (frame_pointer_rtx != XEXP (oldx, 0)
1555               && offs > MAX_LD_OFFSET (mode))
1556             {
1557               big_offset_p = true;
1558               x = force_reg (GET_MODE (oldx), oldx);
1559             }
1560         }
1561     }
1562   
1563   if (avr_log.legitimize_address)
1564     {
1565       avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1566
1567       if (x != oldx)
1568         avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1569     }
1570
1571   return x;
1572 }
1573
1574
1575 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'.  */
1576 /* This will allow register R26/27 to be used where it is no worse than normal
1577    base pointers R28/29 or R30/31.  For example, if base offset is greater
1578    than 63 bytes or for R++ or --R addressing.  */
1579
1580 rtx
1581 avr_legitimize_reload_address (rtx *px, enum machine_mode mode,
1582                                int opnum, int type, int addr_type,
1583                                int ind_levels ATTRIBUTE_UNUSED,
1584                                rtx (*mk_memloc)(rtx,int))
1585 {
1586   rtx x = *px;
1587   
1588   if (avr_log.legitimize_reload_address)
1589     avr_edump ("\n%?:%m %r\n", mode, x);
1590   
1591   if (1 && (GET_CODE (x) == POST_INC
1592             || GET_CODE (x) == PRE_DEC))
1593     {
1594       push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1595                    POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1596                    opnum, RELOAD_OTHER);
1597       
1598       if (avr_log.legitimize_reload_address)
1599         avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1600                    POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1601       
1602       return x;
1603     }
1604   
1605   if (GET_CODE (x) == PLUS
1606       && REG_P (XEXP (x, 0))
1607       && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1608       && CONST_INT_P (XEXP (x, 1))
1609       && INTVAL (XEXP (x, 1)) >= 1)
1610     {
1611       bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1612       
1613       if (fit)
1614         {
1615           if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1616             {
1617               int regno = REGNO (XEXP (x, 0));
1618               rtx mem = mk_memloc (x, regno);
1619               
1620               push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
1621                            POINTER_REGS, Pmode, VOIDmode, 0, 0,
1622                            1, addr_type);
1623               
1624               if (avr_log.legitimize_reload_address)
1625                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1626                            POINTER_REGS, XEXP (mem, 0), NULL_RTX);
1627               
1628               push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
1629                            BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1630                            opnum, type);
1631               
1632               if (avr_log.legitimize_reload_address)
1633                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1634                            BASE_POINTER_REGS, mem, NULL_RTX);
1635               
1636               return x;
1637             }
1638         }
1639       else if (! (frame_pointer_needed
1640                   && XEXP (x, 0) == frame_pointer_rtx))
1641         {
1642           push_reload (x, NULL_RTX, px, NULL,
1643                        POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1644                        opnum, type);
1645           
1646           if (avr_log.legitimize_reload_address)
1647             avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
1648                        POINTER_REGS, x, NULL_RTX);
1649           
1650           return x;
1651         }
1652     }
1653   
1654   return NULL_RTX;
1655 }
1656
1657
1658 /* Helper function to print assembler resp. track instruction
1659    sequence lengths.  Always return "".
1660    
1661    If PLEN == NULL:
1662        Output assembler code from template TPL with operands supplied
1663        by OPERANDS.  This is just forwarding to output_asm_insn.
1664    
1665    If PLEN != NULL:
1666        If N_WORDS >= 0  Add N_WORDS to *PLEN.
1667        If N_WORDS < 0   Set *PLEN to -N_WORDS.
1668        Don't output anything.
1669 */
1670
1671 static const char*
1672 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
1673 {
1674   if (NULL == plen)
1675     {
1676       output_asm_insn (tpl, operands);
1677     }
1678   else
1679     {
1680       if (n_words < 0)
1681         *plen = -n_words;
1682       else
1683         *plen += n_words;
1684     }
1685
1686   return "";
1687 }
1688
1689
1690 /* Return a pointer register name as a string.  */
1691
1692 static const char *
1693 ptrreg_to_str (int regno)
1694 {
1695   switch (regno)
1696     {
1697     case REG_X: return "X";
1698     case REG_Y: return "Y";
1699     case REG_Z: return "Z";
1700     default:
1701       output_operand_lossage ("address operand requires constraint for"
1702                               " X, Y, or Z register");
1703     }
1704   return NULL;
1705 }
1706
1707 /* Return the condition name as a string.
1708    Used in conditional jump constructing  */
1709
1710 static const char *
1711 cond_string (enum rtx_code code)
1712 {
1713   switch (code)
1714     {
1715     case NE:
1716       return "ne";
1717     case EQ:
1718       return "eq";
1719     case GE:
1720       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1721         return "pl";
1722       else
1723         return "ge";
1724     case LT:
1725       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1726         return "mi";
1727       else
1728         return "lt";
1729     case GEU:
1730       return "sh";
1731     case LTU:
1732       return "lo";
1733     default:
1734       gcc_unreachable ();
1735     }
1736
1737   return "";
1738 }
1739
1740 /* Output ADDR to FILE as address.  */
1741
1742 void
1743 print_operand_address (FILE *file, rtx addr)
1744 {
1745   switch (GET_CODE (addr))
1746     {
1747     case REG:
1748       fprintf (file, ptrreg_to_str (REGNO (addr)));
1749       break;
1750
1751     case PRE_DEC:
1752       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1753       break;
1754
1755     case POST_INC:
1756       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1757       break;
1758
1759     default:
1760       if (CONSTANT_ADDRESS_P (addr)
1761           && text_segment_operand (addr, VOIDmode))
1762         {
1763           rtx x = addr;
1764           if (GET_CODE (x) == CONST)
1765             x = XEXP (x, 0);
1766           if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
1767             {
1768               /* Assembler gs() will implant word address. Make offset 
1769                  a byte offset inside gs() for assembler. This is 
1770                  needed because the more logical (constant+gs(sym)) is not 
1771                  accepted by gas. For 128K and lower devices this is ok.
1772                  For large devices it will create a Trampoline to offset
1773                  from symbol which may not be what the user really wanted.  */
1774               fprintf (file, "gs(");
1775               output_addr_const (file, XEXP (x,0));
1776               fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
1777                        2 * INTVAL (XEXP (x, 1)));
1778               if (AVR_3_BYTE_PC)
1779                 if (warning (0, "pointer offset from symbol maybe incorrect"))
1780                   {
1781                     output_addr_const (stderr, addr);
1782                     fprintf(stderr,"\n");
1783                   }
1784             }
1785           else
1786             {
1787               fprintf (file, "gs(");
1788               output_addr_const (file, addr);
1789               fprintf (file, ")");
1790             }
1791         }
1792       else
1793         output_addr_const (file, addr);
1794     }
1795 }
1796
1797
1798 /* Output X as assembler operand to file FILE.  */
1799      
1800 void
1801 print_operand (FILE *file, rtx x, int code)
1802 {
1803   int abcd = 0;
1804
1805   if (code >= 'A' && code <= 'D')
1806     abcd = code - 'A';
1807
1808   if (code == '~')
1809     {
1810       if (!AVR_HAVE_JMP_CALL)
1811         fputc ('r', file);
1812     }
1813   else if (code == '!')
1814     {
1815       if (AVR_HAVE_EIJMP_EICALL)
1816         fputc ('e', file);
1817     }
1818   else if (REG_P (x))
1819     {
1820       if (x == zero_reg_rtx)
1821         fprintf (file, "__zero_reg__");
1822       else
1823         fprintf (file, reg_names[true_regnum (x) + abcd]);
1824     }
1825   else if (GET_CODE (x) == CONST_INT)
1826     fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1827   else if (GET_CODE (x) == MEM)
1828     {
1829       rtx addr = XEXP (x, 0);
1830       
1831       if (code == 'm')
1832         {
1833           if (!CONSTANT_P (addr))
1834             fatal_insn ("bad address, not a constant:", addr);
1835           /* Assembler template with m-code is data - not progmem section */
1836           if (text_segment_operand (addr, VOIDmode))
1837             if (warning (0, "accessing data memory with"
1838                          " program memory address"))
1839               {
1840                 output_addr_const (stderr, addr);
1841                 fprintf(stderr,"\n");
1842               }
1843           output_addr_const (file, addr);
1844         }
1845       else if (code == 'i')
1846         {
1847           if (!io_address_operand (addr, GET_MODE (x)))
1848             fatal_insn ("bad address, not an I/O address:", addr);
1849           
1850           switch (INTVAL (addr))
1851             {
1852             case RAMPZ_ADDR: fprintf (file, "__RAMPZ__"); break;
1853             case SREG_ADDR: fprintf (file, "__SREG__"); break;
1854             case SP_ADDR:   fprintf (file, "__SP_L__"); break;
1855             case SP_ADDR+1: fprintf (file, "__SP_H__"); break;
1856               
1857             default:
1858               fprintf (file, HOST_WIDE_INT_PRINT_HEX,
1859                        UINTVAL (addr) - avr_current_arch->sfr_offset);
1860               break;
1861             }
1862         }
1863       else if (code == 'o')
1864         {
1865           if (GET_CODE (addr) != PLUS)
1866             fatal_insn ("bad address, not (reg+disp):", addr);
1867
1868           print_operand (file, XEXP (addr, 1), 0);
1869         }
1870       else if (code == 'p' || code == 'r')
1871         {
1872           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1873             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1874           
1875           if (code == 'p')
1876             print_operand_address (file, XEXP (addr, 0));  /* X, Y, Z */
1877           else
1878             print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
1879         }
1880       else if (GET_CODE (addr) == PLUS)
1881         {
1882           print_operand_address (file, XEXP (addr,0));
1883           if (REGNO (XEXP (addr, 0)) == REG_X)
1884             fatal_insn ("internal compiler error.  Bad address:"
1885                         ,addr);
1886           fputc ('+', file);
1887           print_operand (file, XEXP (addr,1), code);
1888         }
1889       else
1890         print_operand_address (file, addr);
1891     }
1892   else if (code == 'x')
1893     {
1894       /* Constant progmem address - like used in jmp or call */
1895       if (0 == text_segment_operand (x, VOIDmode))
1896         if (warning (0, "accessing program memory"
1897                      " with data memory address"))
1898           {
1899             output_addr_const (stderr, x);
1900             fprintf(stderr,"\n");
1901           }
1902       /* Use normal symbol for direct address no linker trampoline needed */
1903       output_addr_const (file, x);
1904     }
1905   else if (GET_CODE (x) == CONST_DOUBLE)
1906     {
1907       long val;
1908       REAL_VALUE_TYPE rv;
1909       if (GET_MODE (x) != SFmode)
1910         fatal_insn ("internal compiler error.  Unknown mode:", x);
1911       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1912       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1913       fprintf (file, "0x%lx", val);
1914     }
1915   else if (GET_CODE (x) == CONST_STRING)
1916     fputs (XSTR (x, 0), file);
1917   else if (code == 'j')
1918     fputs (cond_string (GET_CODE (x)), file);
1919   else if (code == 'k')
1920     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1921   else
1922     print_operand_address (file, x);
1923 }
1924
1925 /* Update the condition code in the INSN.  */
1926
1927 void
1928 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1929 {
1930   rtx set;
1931   enum attr_cc cc = get_attr_cc (insn);
1932   
1933   switch (cc)
1934     {
1935     default:
1936       break;
1937
1938     case CC_OUT_PLUS:
1939     case CC_OUT_PLUS_NOCLOBBER:
1940       {
1941         rtx *op = recog_data.operand;
1942         int len_dummy, icc;
1943         
1944         /* Extract insn's operands.  */
1945         extract_constrain_insn_cached (insn);
1946
1947         if (CC_OUT_PLUS == cc)
1948           avr_out_plus (op, &len_dummy, &icc);
1949         else
1950           avr_out_plus_noclobber (op, &len_dummy, &icc);
1951         
1952         cc = (enum attr_cc) icc;
1953         
1954         break;
1955       }
1956     }
1957
1958   switch (cc)
1959     {
1960     default:
1961       /* Special values like CC_OUT_PLUS from above have been
1962          mapped to "standard" CC_* values so we never come here.  */
1963       
1964       gcc_unreachable();
1965       break;
1966       
1967     case CC_NONE:
1968       /* Insn does not affect CC at all.  */
1969       break;
1970
1971     case CC_SET_N:
1972       CC_STATUS_INIT;
1973       break;
1974
1975     case CC_SET_ZN:
1976       set = single_set (insn);
1977       CC_STATUS_INIT;
1978       if (set)
1979         {
1980           cc_status.flags |= CC_NO_OVERFLOW;
1981           cc_status.value1 = SET_DEST (set);
1982         }
1983       break;
1984
1985     case CC_SET_CZN:
1986       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1987          The V flag may or may not be known but that's ok because
1988          alter_cond will change tests to use EQ/NE.  */
1989       set = single_set (insn);
1990       CC_STATUS_INIT;
1991       if (set)
1992         {
1993           cc_status.value1 = SET_DEST (set);
1994           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1995         }
1996       break;
1997
1998     case CC_COMPARE:
1999       set = single_set (insn);
2000       CC_STATUS_INIT;
2001       if (set)
2002         cc_status.value1 = SET_SRC (set);
2003       break;
2004       
2005     case CC_CLOBBER:
2006       /* Insn doesn't leave CC in a usable state.  */
2007       CC_STATUS_INIT;
2008       break;
2009     }
2010 }
2011
2012 /* Choose mode for jump insn:
2013    1 - relative jump in range -63 <= x <= 62 ;
2014    2 - relative jump in range -2046 <= x <= 2045 ;
2015    3 - absolute jump (only for ATmega[16]03).  */
2016
2017 int
2018 avr_jump_mode (rtx x, rtx insn)
2019 {
2020   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2021                                             ? XEXP (x, 0) : x));
2022   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2023   int jump_distance = cur_addr - dest_addr;
2024   
2025   if (-63 <= jump_distance && jump_distance <= 62)
2026     return 1;
2027   else if (-2046 <= jump_distance && jump_distance <= 2045)
2028     return 2;
2029   else if (AVR_HAVE_JMP_CALL)
2030     return 3;
2031   
2032   return 2;
2033 }
2034
2035 /* return an AVR condition jump commands.
2036    X is a comparison RTX.
2037    LEN is a number returned by avr_jump_mode function.
2038    if REVERSE nonzero then condition code in X must be reversed.  */
2039
2040 const char *
2041 ret_cond_branch (rtx x, int len, int reverse)
2042 {
2043   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2044   
2045   switch (cond)
2046     {
2047     case GT:
2048       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2049         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
2050                             AS1 (brpl,%0)) :
2051                 len == 2 ? (AS1 (breq,.+4) CR_TAB
2052                             AS1 (brmi,.+2) CR_TAB
2053                             AS1 (rjmp,%0)) :
2054                 (AS1 (breq,.+6) CR_TAB
2055                  AS1 (brmi,.+4) CR_TAB
2056                  AS1 (jmp,%0)));
2057           
2058       else
2059         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
2060                             AS1 (brge,%0)) :
2061                 len == 2 ? (AS1 (breq,.+4) CR_TAB
2062                             AS1 (brlt,.+2) CR_TAB
2063                             AS1 (rjmp,%0)) :
2064                 (AS1 (breq,.+6) CR_TAB
2065                  AS1 (brlt,.+4) CR_TAB
2066                  AS1 (jmp,%0)));
2067     case GTU:
2068       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
2069                           AS1 (brsh,%0)) :
2070               len == 2 ? (AS1 (breq,.+4) CR_TAB
2071                           AS1 (brlo,.+2) CR_TAB
2072                           AS1 (rjmp,%0)) :
2073               (AS1 (breq,.+6) CR_TAB
2074                AS1 (brlo,.+4) CR_TAB
2075                AS1 (jmp,%0)));
2076     case LE:
2077       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2078         return (len == 1 ? (AS1 (breq,%0) CR_TAB
2079                             AS1 (brmi,%0)) :
2080                 len == 2 ? (AS1 (breq,.+2) CR_TAB
2081                             AS1 (brpl,.+2) CR_TAB
2082                             AS1 (rjmp,%0)) :
2083                 (AS1 (breq,.+2) CR_TAB
2084                  AS1 (brpl,.+4) CR_TAB
2085                  AS1 (jmp,%0)));
2086       else
2087         return (len == 1 ? (AS1 (breq,%0) CR_TAB
2088                             AS1 (brlt,%0)) :
2089                 len == 2 ? (AS1 (breq,.+2) CR_TAB
2090                             AS1 (brge,.+2) CR_TAB
2091                             AS1 (rjmp,%0)) :
2092                 (AS1 (breq,.+2) CR_TAB
2093                  AS1 (brge,.+4) CR_TAB
2094                  AS1 (jmp,%0)));
2095     case LEU:
2096       return (len == 1 ? (AS1 (breq,%0) CR_TAB
2097                           AS1 (brlo,%0)) :
2098               len == 2 ? (AS1 (breq,.+2) CR_TAB
2099                           AS1 (brsh,.+2) CR_TAB
2100                           AS1 (rjmp,%0)) :
2101               (AS1 (breq,.+2) CR_TAB
2102                AS1 (brsh,.+4) CR_TAB
2103                AS1 (jmp,%0)));
2104     default:
2105       if (reverse)
2106         {
2107           switch (len)
2108             {
2109             case 1:
2110               return AS1 (br%k1,%0);
2111             case 2:
2112               return (AS1 (br%j1,.+2) CR_TAB
2113                       AS1 (rjmp,%0));
2114             default:
2115               return (AS1 (br%j1,.+4) CR_TAB
2116                       AS1 (jmp,%0));
2117             }
2118         }
2119         else
2120           {
2121             switch (len)
2122               {
2123               case 1:
2124                 return AS1 (br%j1,%0);
2125               case 2:
2126                 return (AS1 (br%k1,.+2) CR_TAB
2127                         AS1 (rjmp,%0));
2128               default:
2129                 return (AS1 (br%k1,.+4) CR_TAB
2130                         AS1 (jmp,%0));
2131               }
2132           }
2133     }
2134   return "";
2135 }
2136
2137 /* Output insn cost for next insn.  */
2138
2139 void
2140 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
2141                     int num_operands ATTRIBUTE_UNUSED)
2142 {
2143   if (avr_log.rtx_costs)
2144     {
2145       rtx set = single_set (insn);
2146
2147       if (set)
2148         fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
2149                  set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
2150       else
2151         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
2152                  rtx_cost (PATTERN (insn), INSN, 0,
2153                            optimize_insn_for_speed_p()));
2154     }
2155 }
2156
2157 /* Return 0 if undefined, 1 if always true or always false.  */
2158
2159 int
2160 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
2161 {
2162   unsigned int max = (mode == QImode ? 0xff :
2163                       mode == HImode ? 0xffff :
2164                       mode == PSImode ? 0xffffff :
2165                       mode == SImode ? 0xffffffff : 0);
2166   if (max && op && GET_CODE (x) == CONST_INT)
2167     {
2168       if (unsigned_condition (op) != op)
2169         max >>= 1;
2170
2171       if (max != (INTVAL (x) & max)
2172           && INTVAL (x) != 0xff)
2173         return 1;
2174     }
2175   return 0;
2176 }
2177
2178
2179 /* Returns nonzero if REGNO is the number of a hard
2180    register in which function arguments are sometimes passed.  */
2181
2182 int
2183 function_arg_regno_p(int r)
2184 {
2185   return (r >= 8 && r <= 25);
2186 }
2187
2188 /* Initializing the variable cum for the state at the beginning
2189    of the argument list.  */
2190
2191 void
2192 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2193                       tree fndecl ATTRIBUTE_UNUSED)
2194 {
2195   cum->nregs = 18;
2196   cum->regno = FIRST_CUM_REG;
2197   if (!libname && stdarg_p (fntype))
2198     cum->nregs = 0;
2199
2200   /* Assume the calle may be tail called */
2201   
2202   cfun->machine->sibcall_fails = 0;
2203 }
2204
2205 /* Returns the number of registers to allocate for a function argument.  */
2206
2207 static int
2208 avr_num_arg_regs (enum machine_mode mode, const_tree type)
2209 {
2210   int size;
2211
2212   if (mode == BLKmode)
2213     size = int_size_in_bytes (type);
2214   else
2215     size = GET_MODE_SIZE (mode);
2216
2217   /* Align all function arguments to start in even-numbered registers.
2218      Odd-sized arguments leave holes above them.  */
2219
2220   return (size + 1) & ~1;
2221 }
2222
2223 /* Controls whether a function argument is passed
2224    in a register, and which register.  */
2225
2226 static rtx
2227 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
2228                   const_tree type, bool named ATTRIBUTE_UNUSED)
2229 {
2230   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2231   int bytes = avr_num_arg_regs (mode, type);
2232
2233   if (cum->nregs && bytes <= cum->nregs)
2234     return gen_rtx_REG (mode, cum->regno - bytes);
2235
2236   return NULL_RTX;
2237 }
2238
2239 /* Update the summarizer variable CUM to advance past an argument
2240    in the argument list.  */
2241    
2242 static void
2243 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
2244                           const_tree type, bool named ATTRIBUTE_UNUSED)
2245 {
2246   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2247   int bytes = avr_num_arg_regs (mode, type);
2248
2249   cum->nregs -= bytes;
2250   cum->regno -= bytes;
2251
2252   /* A parameter is being passed in a call-saved register. As the original
2253      contents of these regs has to be restored before leaving the function,
2254      a function must not pass arguments in call-saved regs in order to get
2255      tail-called. */
2256   
2257   if (cum->regno >= 8
2258       && cum->nregs >= 0
2259       && !call_used_regs[cum->regno])
2260     {
2261       /* FIXME: We ship info on failing tail-call in struct machine_function.
2262          This uses internals of calls.c:expand_call() and the way args_so_far
2263          is used. targetm.function_ok_for_sibcall() needs to be extended to
2264          pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2265          dependent so that such an extension is not wanted. */
2266       
2267       cfun->machine->sibcall_fails = 1;
2268     }
2269
2270   /* Test if all registers needed by the ABI are actually available.  If the
2271      user has fixed a GPR needed to pass an argument, an (implicit) function
2272      call will clobber that fixed register.  See PR45099 for an example.  */
2273   
2274   if (cum->regno >= 8
2275       && cum->nregs >= 0)
2276     {
2277       int regno;
2278
2279       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2280         if (fixed_regs[regno])
2281           warning (0, "fixed register %s used to pass parameter to function",
2282                    reg_names[regno]);
2283     }
2284       
2285   if (cum->nregs <= 0)
2286     {
2287       cum->nregs = 0;
2288       cum->regno = FIRST_CUM_REG;
2289     }
2290 }
2291
2292 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2293 /* Decide whether we can make a sibling call to a function.  DECL is the
2294    declaration of the function being targeted by the call and EXP is the
2295    CALL_EXPR representing the call. */
2296
2297 static bool
2298 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2299 {
2300   tree fntype_callee;
2301
2302   /* Tail-calling must fail if callee-saved regs are used to pass
2303      function args.  We must not tail-call when `epilogue_restores'
2304      is used.  Unfortunately, we cannot tell at this point if that
2305      actually will happen or not, and we cannot step back from
2306      tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2307   
2308   if (cfun->machine->sibcall_fails
2309       || TARGET_CALL_PROLOGUES)
2310     {
2311       return false;
2312     }
2313   
2314   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2315
2316   if (decl_callee)
2317     {
2318       decl_callee = TREE_TYPE (decl_callee);
2319     }
2320   else
2321     {
2322       decl_callee = fntype_callee;
2323       
2324       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2325              && METHOD_TYPE != TREE_CODE (decl_callee))
2326         {
2327           decl_callee = TREE_TYPE (decl_callee);
2328         }
2329     }
2330
2331   /* Ensure that caller and callee have compatible epilogues */
2332   
2333   if (interrupt_function_p (current_function_decl)
2334       || signal_function_p (current_function_decl)
2335       || avr_naked_function_p (decl_callee)
2336       || avr_naked_function_p (current_function_decl)
2337       /* FIXME: For OS_task and OS_main, we are over-conservative.
2338          This is due to missing documentation of these attributes
2339          and what they actually should do and should not do. */
2340       || (avr_OS_task_function_p (decl_callee)
2341           != avr_OS_task_function_p (current_function_decl))
2342       || (avr_OS_main_function_p (decl_callee)
2343           != avr_OS_main_function_p (current_function_decl)))
2344     {
2345       return false;
2346     }
2347  
2348   return true;
2349 }
2350
2351 /***********************************************************************
2352   Functions for outputting various mov's for a various modes
2353 ************************************************************************/
2354
2355 /* Return true if a value of mode MODE is read from flash by
2356    __load_* function from libgcc.  */
2357
2358 bool
2359 avr_load_libgcc_p (rtx op)
2360 {
2361   enum machine_mode mode = GET_MODE (op);
2362   int n_bytes = GET_MODE_SIZE (mode);
2363         
2364   return (n_bytes > 2
2365           && !AVR_HAVE_LPMX
2366           && avr_mem_pgm_p (op));
2367 }
2368
2369 /* Return true if a value of mode MODE is read by __xload_* function.  */
2370
2371 bool
2372 avr_xload_libgcc_p (enum machine_mode mode)
2373 {
2374   int n_bytes = GET_MODE_SIZE (mode);
2375   
2376   return (n_bytes > 1
2377           && avr_current_arch->n_segments > 1
2378           && !AVR_HAVE_ELPMX);
2379 }
2380
2381
2382 /* Find an unused d-register to be used as scratch in INSN.
2383    EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2384    is a register, skip all possible return values that overlap EXCLUDE.
2385    The policy for the returned register is similar to that of
2386    `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2387    of INSN.
2388
2389    Return a QImode d-register or NULL_RTX if nothing found.  */
2390
2391 static rtx
2392 avr_find_unused_d_reg (rtx insn, rtx exclude)
2393 {
2394   int regno;
2395   bool isr_p = (interrupt_function_p (current_function_decl)
2396                 || signal_function_p (current_function_decl));
2397
2398   for (regno = 16; regno < 32; regno++)
2399     {
2400       rtx reg = all_regs_rtx[regno];
2401       
2402       if ((exclude
2403            && reg_overlap_mentioned_p (exclude, reg))
2404           || fixed_regs[regno])
2405         {
2406           continue;
2407         }
2408
2409       /* Try non-live register */
2410
2411       if (!df_regs_ever_live_p (regno)
2412           && (TREE_THIS_VOLATILE (current_function_decl)
2413               || cfun->machine->is_OS_task
2414               || cfun->machine->is_OS_main
2415               || (!isr_p && call_used_regs[regno])))
2416         {
2417           return reg;
2418         }
2419
2420       /* Any live register can be used if it is unused after.
2421          Prologue/epilogue will care for it as needed.  */
2422       
2423       if (df_regs_ever_live_p (regno)
2424           && reg_unused_after (insn, reg))
2425         {
2426           return reg;
2427         }
2428     }
2429
2430   return NULL_RTX;
2431 }
2432
2433
2434 /* Helper function for the next function in the case where only restricted
2435    version of LPM instruction is available.  */
2436
2437 static const char*
2438 avr_out_lpm_no_lpmx (rtx insn, rtx *xop, int *plen)
2439 {
2440   rtx dest = xop[0];
2441   rtx addr = xop[1];
2442   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2443   int regno_dest;
2444
2445   regno_dest = REGNO (dest);
2446
2447   /* The implicit target register of LPM.  */
2448   xop[3] = lpm_reg_rtx;
2449
2450   switch (GET_CODE (addr))
2451     {
2452     default:
2453       gcc_unreachable();
2454
2455     case REG:
2456
2457       gcc_assert (REG_Z == REGNO (addr));
2458
2459       switch (n_bytes)
2460         {
2461         default:
2462           gcc_unreachable();
2463
2464         case 1:
2465           avr_asm_len ("%4lpm", xop, plen, 1);
2466
2467           if (regno_dest != LPM_REGNO)
2468             avr_asm_len ("mov %0,%3", xop, plen, 1);
2469
2470           return "";
2471
2472         case 2:
2473           if (REGNO (dest) == REG_Z)
2474             return avr_asm_len ("%4lpm"      CR_TAB
2475                                 "push %3"    CR_TAB
2476                                 "adiw %2,1"  CR_TAB
2477                                 "%4lpm"      CR_TAB
2478                                 "mov %B0,%3" CR_TAB
2479                                 "pop %A0", xop, plen, 6);
2480           
2481           avr_asm_len ("%4lpm"      CR_TAB
2482                        "mov %A0,%3" CR_TAB
2483                        "adiw %2,1"  CR_TAB
2484                        "%4lpm"      CR_TAB
2485                        "mov %B0,%3", xop, plen, 5);
2486                 
2487           if (!reg_unused_after (insn, addr))
2488             avr_asm_len ("sbiw %2,1", xop, plen, 1);
2489           
2490           break; /* 2 */
2491         }
2492       
2493       break; /* REG */
2494
2495     case POST_INC:
2496
2497       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
2498                   && n_bytes <= 4);
2499
2500       if (regno_dest == LPM_REGNO)
2501         avr_asm_len ("%4lpm"      CR_TAB
2502                      "adiw %2,1", xop, plen, 2);
2503       else
2504         avr_asm_len ("%4lpm"      CR_TAB
2505                      "mov %A0,%3" CR_TAB
2506                      "adiw %2,1", xop, plen, 3);
2507
2508       if (n_bytes >= 2)
2509         avr_asm_len ("%4lpm"      CR_TAB
2510                      "mov %B0,%3" CR_TAB
2511                      "adiw %2,1", xop, plen, 3);
2512
2513       if (n_bytes >= 3)
2514         avr_asm_len ("%4lpm"      CR_TAB
2515                      "mov %C0,%3" CR_TAB
2516                      "adiw %2,1", xop, plen, 3);
2517
2518       if (n_bytes >= 4)
2519         avr_asm_len ("%4lpm"      CR_TAB
2520                      "mov %D0,%3" CR_TAB
2521                      "adiw %2,1", xop, plen, 3);
2522
2523       break; /* POST_INC */
2524       
2525     } /* switch CODE (addr) */
2526       
2527   return "";
2528 }
2529
2530
2531 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
2532    OP[1] in AS1 to register OP[0].
2533    If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
2534    Return "".  */
2535
2536 static const char*
2537 avr_out_lpm (rtx insn, rtx *op, int *plen)
2538 {
2539   rtx xop[6];
2540   rtx dest = op[0];
2541   rtx src = SET_SRC (single_set (insn));
2542   rtx addr;
2543   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2544   int regno_dest;
2545   int segment;
2546
2547   if (plen)
2548     *plen = 0;
2549   
2550   if (MEM_P (dest))
2551     {
2552       warning (0, "writing to address space %qs not supported",
2553                c_addr_space_name (MEM_ADDR_SPACE (dest)));
2554       
2555       return "";
2556     }
2557
2558   addr = XEXP (src, 0);
2559
2560   segment = avr_pgm_segment (MEM_ADDR_SPACE (src));
2561
2562   gcc_assert (REG_P (dest)
2563               && ((segment >= 0
2564                    && (REG_P (addr) || POST_INC == GET_CODE (addr)))
2565                   || (GET_CODE (addr) == LO_SUM && segment == -1)));
2566
2567   if (segment == -1)
2568     {
2569       /* We are called from avr_out_xload because someone wrote
2570          __pgmx on a device with just one flash segment.  */
2571
2572       addr = XEXP (addr, 1);
2573     }
2574
2575   xop[0] = dest;
2576   xop[1] = addr;
2577   xop[2] = lpm_addr_reg_rtx;
2578   xop[4] = xstring_empty;
2579   xop[5] = tmp_reg_rtx;
2580
2581   regno_dest = REGNO (dest);
2582
2583   /* Cut down segment number to a number the device actually
2584      supports.  We do this late to preserve the address space's
2585      name for diagnostics.  */
2586
2587   segment %= avr_current_arch->n_segments;
2588
2589   /* Set RAMPZ as needed.  */
2590
2591   if (segment)
2592     {
2593       xop[4] = GEN_INT (segment);
2594       
2595       if (xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx),
2596           xop[3])
2597         {
2598           avr_asm_len ("ldi %3,%4" CR_TAB
2599                        "out __RAMPZ__,%3", xop, plen, 2);
2600         }
2601       else if (segment == 1)
2602         {
2603           avr_asm_len ("clr %5" CR_TAB
2604                        "inc %5" CR_TAB
2605                        "out __RAMPZ__,%5", xop, plen, 3);
2606         }
2607       else
2608         {
2609           avr_asm_len ("mov %5,%2"         CR_TAB
2610                        "ldi %2,%4"         CR_TAB
2611                        "out __RAMPZ__,%2"  CR_TAB
2612                        "mov %2,%5", xop, plen, 4);
2613         }
2614       
2615       xop[4] = xstring_e;
2616     }
2617
2618   if ((segment == 0 && !AVR_HAVE_LPMX)
2619       || (segment != 0 && !AVR_HAVE_ELPMX))
2620     {
2621       return avr_out_lpm_no_lpmx (insn, xop, plen);
2622     }
2623
2624   switch (GET_CODE (addr))
2625     {
2626     default:
2627       gcc_unreachable();
2628
2629     case REG:
2630
2631       gcc_assert (REG_Z == REGNO (addr));
2632
2633       switch (n_bytes)
2634         {
2635         default:
2636           gcc_unreachable();
2637
2638         case 1:
2639           return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
2640
2641         case 2:
2642           if (REGNO (dest) == REG_Z)
2643             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
2644                                 "%4lpm %B0,%a2" CR_TAB
2645                                 "mov %A0,%5", xop, plen, 3);
2646           else
2647             {
2648               avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
2649                            "%4lpm %B0,%a2", xop, plen, 2);
2650                 
2651               if (!reg_unused_after (insn, addr))
2652                 avr_asm_len ("sbiw %2,1", xop, plen, 1);
2653             }
2654           
2655           break; /* 2 */
2656
2657         case 3:
2658
2659           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
2660                        "%4lpm %B0,%a2+" CR_TAB
2661                        "%4lpm %C0,%a2", xop, plen, 3);
2662                 
2663           if (!reg_unused_after (insn, addr))
2664             avr_asm_len ("sbiw %2,2", xop, plen, 1);
2665
2666           break; /* 3 */
2667       
2668         case 4:
2669
2670           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
2671                        "%4lpm %B0,%a2+", xop, plen, 2);
2672           
2673           if (REGNO (dest) == REG_Z - 2)
2674             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
2675                                 "%4lpm %C0,%a2"          CR_TAB
2676                                 "mov %D0,%5", xop, plen, 3);
2677           else
2678             {
2679               avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
2680                            "%4lpm %D0,%a2", xop, plen, 2);
2681                 
2682               if (!reg_unused_after (insn, addr))
2683                 avr_asm_len ("sbiw %2,3", xop, plen, 1);
2684             }
2685
2686           break; /* 4 */
2687         } /* n_bytes */
2688       
2689       break; /* REG */
2690
2691     case POST_INC:
2692
2693       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
2694                   && n_bytes <= 4);
2695
2696       avr_asm_len                    ("%4lpm %A0,%a2+", xop, plen, 1);
2697       if (n_bytes >= 2)  avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
2698       if (n_bytes >= 3)  avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
2699       if (n_bytes >= 4)  avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
2700
2701       break; /* POST_INC */
2702
2703     } /* switch CODE (addr) */
2704       
2705   return "";
2706 }
2707
2708
2709 /* Worker function for xload_<mode> and xload_8 insns.  */
2710
2711 const char*
2712 avr_out_xload (rtx insn, rtx *op, int *plen)
2713 {
2714   rtx xop[5];
2715   rtx reg = op[0];
2716   int n_bytes = GET_MODE_SIZE (GET_MODE (reg));
2717   unsigned int regno = REGNO (reg);
2718
2719   if (avr_current_arch->n_segments == 1)
2720     return avr_out_lpm (insn, op, plen);
2721
2722   xop[0] = reg;
2723   xop[1] = op[1];
2724   xop[2] = lpm_addr_reg_rtx;
2725   xop[3] = lpm_reg_rtx;
2726   xop[4] = tmp_reg_rtx;
2727   
2728   avr_asm_len ("out __RAMPZ__,%1", xop, plen, -1);
2729   
2730   if (1 == n_bytes)
2731     {
2732       if (AVR_HAVE_ELPMX)
2733         return avr_asm_len ("elpm %0,%a2", xop, plen, 1);
2734       else
2735         return avr_asm_len ("elpm" CR_TAB
2736                             "mov %0,%3", xop, plen, 2);
2737     }
2738
2739   gcc_assert (AVR_HAVE_ELPMX);
2740   
2741   if (!reg_overlap_mentioned_p (reg, lpm_addr_reg_rtx))
2742     {
2743       /* Insn clobbers the Z-register so we can use post-increment.  */
2744       
2745       avr_asm_len                    ("elpm %A0,%a2+", xop, plen, 1);
2746       if (n_bytes >= 2)  avr_asm_len ("elpm %B0,%a2+", xop, plen, 1);
2747       if (n_bytes >= 3)  avr_asm_len ("elpm %C0,%a2+", xop, plen, 1);
2748       if (n_bytes >= 4)  avr_asm_len ("elpm %D0,%a2+", xop, plen, 1);
2749
2750       return "";
2751     }
2752
2753   switch (n_bytes)
2754     {
2755     default:
2756       gcc_unreachable();
2757       
2758     case 2:
2759       gcc_assert (regno == REGNO (lpm_addr_reg_rtx));
2760
2761       return avr_asm_len ("elpm %4,%a2+" CR_TAB
2762                           "elpm %B0,%a2" CR_TAB
2763                           "mov %A0,%4", xop, plen, 3);
2764
2765     case 3:
2766     case 4:
2767       gcc_assert (regno + 2 == REGNO (lpm_addr_reg_rtx));
2768       
2769       avr_asm_len ("elpm %A0,%a2+" CR_TAB
2770                    "elpm %B0,%a2+", xop, plen, 2);
2771
2772       if (n_bytes == 3)
2773         return avr_asm_len ("elpm %C0,%a2", xop, plen, 1);
2774       else
2775         return avr_asm_len ("elpm %4,%a2+" CR_TAB
2776                             "elpm %D0,%a2" CR_TAB
2777                             "mov %C0,%4", xop, plen, 3);
2778     }
2779   
2780   return "";
2781 }
2782
2783
2784 const char *
2785 output_movqi (rtx insn, rtx operands[], int *l)
2786 {
2787   int dummy;
2788   rtx dest = operands[0];
2789   rtx src = operands[1];
2790   int *real_l = l;
2791   
2792   if (avr_mem_pgm_p (src)
2793       || avr_mem_pgm_p (dest))
2794     {
2795       return avr_out_lpm (insn, operands, real_l);
2796     }
2797
2798   if (!l)
2799     l = &dummy;
2800
2801   *l = 1;
2802   
2803   if (register_operand (dest, QImode))
2804     {
2805       if (register_operand (src, QImode)) /* mov r,r */
2806         {
2807           if (test_hard_reg_class (STACK_REG, dest))
2808             return AS2 (out,%0,%1);
2809           else if (test_hard_reg_class (STACK_REG, src))
2810             return AS2 (in,%0,%1);
2811           
2812           return AS2 (mov,%0,%1);
2813         }
2814       else if (CONSTANT_P (src))
2815         {
2816           output_reload_in_const (operands, NULL_RTX, real_l, false);
2817           return "";
2818         }
2819       else if (GET_CODE (src) == MEM)
2820         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
2821     }
2822   else if (GET_CODE (dest) == MEM)
2823     {
2824       rtx xop[2];
2825
2826       xop[0] = dest;
2827       xop[1] = src == const0_rtx ? zero_reg_rtx : src;
2828
2829       return out_movqi_mr_r (insn, xop, real_l);
2830     }
2831   return "";
2832 }
2833
2834
2835 const char *
2836 output_movhi (rtx insn, rtx operands[], int *l)
2837 {
2838   int dummy;
2839   rtx dest = operands[0];
2840   rtx src = operands[1];
2841   int *real_l = l;
2842   
2843   if (avr_mem_pgm_p (src)
2844       || avr_mem_pgm_p (dest))
2845     {
2846       return avr_out_lpm (insn, operands, real_l);
2847     }
2848
2849   if (!l)
2850     l = &dummy;
2851   
2852   if (register_operand (dest, HImode))
2853     {
2854       if (register_operand (src, HImode)) /* mov r,r */
2855         {
2856           if (test_hard_reg_class (STACK_REG, dest))
2857             {
2858               if (AVR_HAVE_8BIT_SP)
2859                 return *l = 1, AS2 (out,__SP_L__,%A1);
2860               /* Use simple load of stack pointer if no interrupts are 
2861                  used.  */
2862               else if (TARGET_NO_INTERRUPTS)
2863                 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
2864                                 AS2 (out,__SP_L__,%A1));
2865               *l = 5;
2866               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
2867                       "cli"                          CR_TAB
2868                       AS2 (out,__SP_H__,%B1)         CR_TAB
2869                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
2870                       AS2 (out,__SP_L__,%A1));
2871             }
2872           else if (test_hard_reg_class (STACK_REG, src))
2873             {
2874               *l = 2;   
2875               return (AS2 (in,%A0,__SP_L__) CR_TAB
2876                       AS2 (in,%B0,__SP_H__));
2877             }
2878
2879           if (AVR_HAVE_MOVW)
2880             {
2881               *l = 1;
2882               return (AS2 (movw,%0,%1));
2883             }
2884           else
2885             {
2886               *l = 2;
2887               return (AS2 (mov,%A0,%A1) CR_TAB
2888                       AS2 (mov,%B0,%B1));
2889             }
2890         }
2891       else if (CONSTANT_P (src))
2892         {
2893           return output_reload_inhi (operands, NULL, real_l);
2894         }
2895       else if (GET_CODE (src) == MEM)
2896         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
2897     }
2898   else if (GET_CODE (dest) == MEM)
2899     {
2900       rtx xop[2];
2901
2902       xop[0] = dest;
2903       xop[1] = src == const0_rtx ? zero_reg_rtx : src;
2904
2905       return out_movhi_mr_r (insn, xop, real_l);
2906     }
2907   fatal_insn ("invalid insn:", insn);
2908   return "";
2909 }
2910
2911 static const char*
2912 out_movqi_r_mr (rtx insn, rtx op[], int *plen)
2913 {
2914   rtx dest = op[0];
2915   rtx src = op[1];
2916   rtx x = XEXP (src, 0);
2917   
2918   if (CONSTANT_ADDRESS_P (x))
2919     {
2920       return optimize > 0 && io_address_operand (x, QImode)
2921         ? avr_asm_len ("in %0,%i1", op, plen, -1)
2922         : avr_asm_len ("lds %0,%m1", op, plen, -2);
2923     }
2924   else if (GET_CODE (x) == PLUS
2925            && REG_P (XEXP (x, 0))
2926            && CONST_INT_P (XEXP (x, 1)))
2927     {
2928       /* memory access by reg+disp */
2929
2930       int disp = INTVAL (XEXP (x, 1));
2931       
2932       if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
2933         {
2934           if (REGNO (XEXP (x, 0)) != REG_Y)
2935             fatal_insn ("incorrect insn:",insn);
2936
2937           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2938             return avr_asm_len ("adiw r28,%o1-63" CR_TAB
2939                                 "ldd %0,Y+63"     CR_TAB
2940                                 "sbiw r28,%o1-63", op, plen, -3);
2941
2942           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
2943                               "sbci r29,hi8(-%o1)" CR_TAB
2944                               "ld %0,Y"            CR_TAB
2945                               "subi r28,lo8(%o1)"  CR_TAB
2946                               "sbci r29,hi8(%o1)", op, plen, -5);
2947         }
2948       else if (REGNO (XEXP (x, 0)) == REG_X)
2949         {
2950           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2951              it but I have this situation with extremal optimizing options.  */
2952           
2953           avr_asm_len ("adiw r26,%o1" CR_TAB
2954                        "ld %0,X", op, plen, -2);
2955           
2956           if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
2957               && !reg_unused_after (insn, XEXP (x,0)))
2958             {
2959               avr_asm_len ("sbiw r26,%o1", op, plen, 1);
2960             }
2961
2962           return "";
2963         }
2964
2965       return avr_asm_len ("ldd %0,%1", op, plen, -1);
2966     }
2967   
2968   return avr_asm_len ("ld %0,%1", op, plen, -1);
2969 }
2970
2971 static const char*
2972 out_movhi_r_mr (rtx insn, rtx op[], int *plen)
2973 {
2974   rtx dest = op[0];
2975   rtx src = op[1];
2976   rtx base = XEXP (src, 0);
2977   int reg_dest = true_regnum (dest);
2978   int reg_base = true_regnum (base);
2979   /* "volatile" forces reading low byte first, even if less efficient,
2980      for correct operation with 16-bit I/O registers.  */
2981   int mem_volatile_p = MEM_VOLATILE_P (src);
2982
2983   if (reg_base > 0)
2984     {
2985       if (reg_dest == reg_base)         /* R = (R) */
2986         return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
2987                             "ld %B0,%1"          CR_TAB
2988                             "mov %A0,__tmp_reg__", op, plen, -3);
2989
2990       if (reg_base != REG_X)
2991         return avr_asm_len ("ld %A0,%1" CR_TAB
2992                             "ldd %B0,%1+1", op, plen, -2);
2993       
2994       avr_asm_len ("ld %A0,X+" CR_TAB
2995                    "ld %B0,X", op, plen, -2);
2996           
2997       if (!reg_unused_after (insn, base))
2998         avr_asm_len ("sbiw r26,1", op, plen, 1);
2999
3000       return "";
3001     }
3002   else if (GET_CODE (base) == PLUS) /* (R + i) */
3003     {
3004       int disp = INTVAL (XEXP (base, 1));
3005       int reg_base = true_regnum (XEXP (base, 0));
3006       
3007       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3008         {
3009           if (REGNO (XEXP (base, 0)) != REG_Y)
3010             fatal_insn ("incorrect insn:",insn);
3011           
3012           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3013             ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3014                            "ldd %A0,Y+62"    CR_TAB
3015                            "ldd %B0,Y+63"    CR_TAB
3016                            "sbiw r28,%o1-62", op, plen, -4)
3017
3018             : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3019                            "sbci r29,hi8(-%o1)" CR_TAB
3020                            "ld %A0,Y"           CR_TAB
3021                            "ldd %B0,Y+1"        CR_TAB
3022                            "subi r28,lo8(%o1)"  CR_TAB
3023                            "sbci r29,hi8(%o1)", op, plen, -6);
3024         }
3025
3026       /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3027          it but I have this situation with extremal
3028          optimization options.  */
3029
3030       if (reg_base == REG_X)
3031         return reg_base == reg_dest
3032           ? avr_asm_len ("adiw r26,%o1"      CR_TAB
3033                          "ld __tmp_reg__,X+" CR_TAB
3034                          "ld %B0,X"          CR_TAB
3035                          "mov %A0,__tmp_reg__", op, plen, -4)
3036
3037           : avr_asm_len ("adiw r26,%o1" CR_TAB
3038                          "ld %A0,X+"    CR_TAB
3039                          "ld %B0,X"     CR_TAB
3040                          "sbiw r26,%o1+1", op, plen, -4);
3041
3042       return reg_base == reg_dest
3043         ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3044                        "ldd %B0,%B1"         CR_TAB
3045                        "mov %A0,__tmp_reg__", op, plen, -3)
3046
3047         : avr_asm_len ("ldd %A0,%A1" CR_TAB
3048                        "ldd %B0,%B1", op, plen, -2);
3049     }
3050   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3051     {
3052       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3053         fatal_insn ("incorrect insn:", insn);
3054
3055       if (!mem_volatile_p)
3056         return avr_asm_len ("ld %B0,%1" CR_TAB
3057                             "ld %A0,%1", op, plen, -2);
3058       
3059       return REGNO (XEXP (base, 0)) == REG_X
3060         ? avr_asm_len ("sbiw r26,2"  CR_TAB
3061                        "ld %A0,X+"   CR_TAB
3062                        "ld %B0,X"    CR_TAB
3063                        "sbiw r26,1", op, plen, -4)
3064         
3065         : avr_asm_len ("sbiw %r1,2"  CR_TAB
3066                        "ld %A0,%p1"  CR_TAB
3067                        "ldd %B0,%p1+1", op, plen, -3);
3068     }
3069   else if (GET_CODE (base) == POST_INC) /* (R++) */
3070     {
3071       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3072         fatal_insn ("incorrect insn:", insn);
3073
3074       return avr_asm_len ("ld %A0,%1"  CR_TAB
3075                           "ld %B0,%1", op, plen, -2);
3076     }
3077   else if (CONSTANT_ADDRESS_P (base))
3078     {
3079       return optimize > 0 && io_address_operand (base, HImode)
3080         ? avr_asm_len ("in %A0,%i1" CR_TAB
3081                        "in %B0,%i1+1", op, plen, -2)
3082
3083         : avr_asm_len ("lds %A0,%m1" CR_TAB
3084                        "lds %B0,%m1+1", op, plen, -4);
3085     }
3086   
3087   fatal_insn ("unknown move insn:",insn);
3088   return "";
3089 }
3090
3091 static const char*
3092 out_movsi_r_mr (rtx insn, rtx op[], int *l)
3093 {
3094   rtx dest = op[0];
3095   rtx src = op[1];
3096   rtx base = XEXP (src, 0);
3097   int reg_dest = true_regnum (dest);
3098   int reg_base = true_regnum (base);
3099   int tmp;
3100
3101   if (!l)
3102     l = &tmp;
3103   
3104   if (reg_base > 0)
3105     {
3106       if (reg_base == REG_X)        /* (R26) */
3107         {
3108           if (reg_dest == REG_X)
3109             /* "ld r26,-X" is undefined */
3110             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
3111                           AS2 (ld,r29,X)          CR_TAB
3112                           AS2 (ld,r28,-X)         CR_TAB
3113                           AS2 (ld,__tmp_reg__,-X) CR_TAB
3114                           AS2 (sbiw,r26,1)        CR_TAB
3115                           AS2 (ld,r26,X)          CR_TAB
3116                           AS2 (mov,r27,__tmp_reg__));
3117           else if (reg_dest == REG_X - 2)
3118             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
3119                           AS2 (ld,%B0,X+) CR_TAB
3120                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
3121                           AS2 (ld,%D0,X)  CR_TAB
3122                           AS2 (mov,%C0,__tmp_reg__));
3123           else if (reg_unused_after (insn, base))
3124             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
3125                            AS2 (ld,%B0,X+) CR_TAB
3126                            AS2 (ld,%C0,X+) CR_TAB
3127                            AS2 (ld,%D0,X));
3128           else
3129             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
3130                            AS2 (ld,%B0,X+) CR_TAB
3131                            AS2 (ld,%C0,X+) CR_TAB
3132                            AS2 (ld,%D0,X)  CR_TAB
3133                            AS2 (sbiw,r26,3));
3134         }
3135       else
3136         {
3137           if (reg_dest == reg_base)
3138             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
3139                           AS2 (ldd,%C0,%1+2) CR_TAB
3140                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
3141                           AS2 (ld,%A0,%1)  CR_TAB
3142                           AS2 (mov,%B0,__tmp_reg__));
3143           else if (reg_base == reg_dest + 2)
3144             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
3145                           AS2 (ldd,%B0,%1+1) CR_TAB
3146                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
3147                           AS2 (ldd,%D0,%1+3) CR_TAB
3148                           AS2 (mov,%C0,__tmp_reg__));
3149           else
3150             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
3151                           AS2 (ldd,%B0,%1+1) CR_TAB
3152                           AS2 (ldd,%C0,%1+2) CR_TAB
3153                           AS2 (ldd,%D0,%1+3));
3154         }
3155     }
3156   else if (GET_CODE (base) == PLUS) /* (R + i) */
3157     {
3158       int disp = INTVAL (XEXP (base, 1));
3159       
3160       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3161         {
3162           if (REGNO (XEXP (base, 0)) != REG_Y)
3163             fatal_insn ("incorrect insn:",insn);
3164
3165           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3166             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
3167                             AS2 (ldd,%A0,Y+60)    CR_TAB
3168                             AS2 (ldd,%B0,Y+61)    CR_TAB
3169                             AS2 (ldd,%C0,Y+62)    CR_TAB
3170                             AS2 (ldd,%D0,Y+63)    CR_TAB
3171                             AS2 (sbiw,r28,%o1-60));
3172
3173           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
3174                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
3175                           AS2 (ld,%A0,Y)           CR_TAB
3176                           AS2 (ldd,%B0,Y+1)        CR_TAB
3177                           AS2 (ldd,%C0,Y+2)        CR_TAB
3178                           AS2 (ldd,%D0,Y+3)        CR_TAB
3179                           AS2 (subi,r28,lo8(%o1))  CR_TAB
3180                           AS2 (sbci,r29,hi8(%o1)));
3181         }
3182
3183       reg_base = true_regnum (XEXP (base, 0));
3184       if (reg_base == REG_X)
3185         {
3186           /* R = (X + d) */
3187           if (reg_dest == REG_X)
3188             {
3189               *l = 7;
3190               /* "ld r26,-X" is undefined */
3191               return (AS2 (adiw,r26,%o1+3)    CR_TAB
3192                       AS2 (ld,r29,X)          CR_TAB
3193                       AS2 (ld,r28,-X)         CR_TAB
3194                       AS2 (ld,__tmp_reg__,-X) CR_TAB
3195                       AS2 (sbiw,r26,1)        CR_TAB
3196                       AS2 (ld,r26,X)          CR_TAB
3197                       AS2 (mov,r27,__tmp_reg__));
3198             }
3199           *l = 6;
3200           if (reg_dest == REG_X - 2)
3201             return (AS2 (adiw,r26,%o1)      CR_TAB
3202                     AS2 (ld,r24,X+)         CR_TAB
3203                     AS2 (ld,r25,X+)         CR_TAB
3204                     AS2 (ld,__tmp_reg__,X+) CR_TAB
3205                     AS2 (ld,r27,X)          CR_TAB
3206                     AS2 (mov,r26,__tmp_reg__));
3207
3208           return (AS2 (adiw,r26,%o1) CR_TAB
3209                   AS2 (ld,%A0,X+)    CR_TAB
3210                   AS2 (ld,%B0,X+)    CR_TAB
3211                   AS2 (ld,%C0,X+)    CR_TAB
3212                   AS2 (ld,%D0,X)     CR_TAB
3213                   AS2 (sbiw,r26,%o1+3));
3214         }
3215       if (reg_dest == reg_base)
3216         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
3217                       AS2 (ldd,%C0,%C1) CR_TAB
3218                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
3219                       AS2 (ldd,%A0,%A1) CR_TAB
3220                       AS2 (mov,%B0,__tmp_reg__));
3221       else if (reg_dest == reg_base - 2)
3222         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
3223                       AS2 (ldd,%B0,%B1) CR_TAB
3224                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
3225                       AS2 (ldd,%D0,%D1) CR_TAB
3226                       AS2 (mov,%C0,__tmp_reg__));
3227       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
3228                     AS2 (ldd,%B0,%B1) CR_TAB
3229                     AS2 (ldd,%C0,%C1) CR_TAB
3230                     AS2 (ldd,%D0,%D1));
3231     }
3232   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3233     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
3234                   AS2 (ld,%C0,%1) CR_TAB
3235                   AS2 (ld,%B0,%1) CR_TAB
3236                   AS2 (ld,%A0,%1));
3237   else if (GET_CODE (base) == POST_INC) /* (R++) */
3238     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
3239                   AS2 (ld,%B0,%1) CR_TAB
3240                   AS2 (ld,%C0,%1) CR_TAB
3241                   AS2 (ld,%D0,%1));
3242   else if (CONSTANT_ADDRESS_P (base))
3243       return *l=8, (AS2 (lds,%A0,%m1) CR_TAB
3244                     AS2 (lds,%B0,%m1+1) CR_TAB
3245                     AS2 (lds,%C0,%m1+2) CR_TAB
3246                     AS2 (lds,%D0,%m1+3));
3247     
3248   fatal_insn ("unknown move insn:",insn);
3249   return "";
3250 }
3251
3252 static const char*
3253 out_movsi_mr_r (rtx insn, rtx op[], int *l)
3254 {
3255   rtx dest = op[0];
3256   rtx src = op[1];
3257   rtx base = XEXP (dest, 0);
3258   int reg_base = true_regnum (base);
3259   int reg_src = true_regnum (src);
3260   int tmp;
3261   
3262   if (!l)
3263     l = &tmp;
3264   
3265   if (CONSTANT_ADDRESS_P (base))
3266     return *l=8,(AS2 (sts,%m0,%A1) CR_TAB
3267                  AS2 (sts,%m0+1,%B1) CR_TAB
3268                  AS2 (sts,%m0+2,%C1) CR_TAB
3269                  AS2 (sts,%m0+3,%D1));
3270   if (reg_base > 0)                 /* (r) */
3271     {
3272       if (reg_base == REG_X)                /* (R26) */
3273         {
3274           if (reg_src == REG_X)
3275             {
3276               /* "st X+,r26" is undefined */
3277               if (reg_unused_after (insn, base))
3278                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
3279                               AS2 (st,X,r26)            CR_TAB
3280                               AS2 (adiw,r26,1)          CR_TAB
3281                               AS2 (st,X+,__tmp_reg__)   CR_TAB
3282                               AS2 (st,X+,r28)           CR_TAB
3283                               AS2 (st,X,r29));
3284               else
3285                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
3286                               AS2 (st,X,r26)            CR_TAB
3287                               AS2 (adiw,r26,1)          CR_TAB
3288                               AS2 (st,X+,__tmp_reg__)   CR_TAB
3289                               AS2 (st,X+,r28)           CR_TAB
3290                               AS2 (st,X,r29)            CR_TAB
3291                               AS2 (sbiw,r26,3));
3292             }
3293           else if (reg_base == reg_src + 2)
3294             {
3295               if (reg_unused_after (insn, base))
3296                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
3297                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
3298                               AS2 (st,%0+,%A1) CR_TAB
3299                               AS2 (st,%0+,%B1) CR_TAB
3300                               AS2 (st,%0+,__zero_reg__)  CR_TAB
3301                               AS2 (st,%0,__tmp_reg__)   CR_TAB
3302                               AS1 (clr,__zero_reg__));
3303               else
3304                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
3305                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
3306                               AS2 (st,%0+,%A1) CR_TAB
3307                               AS2 (st,%0+,%B1) CR_TAB
3308                               AS2 (st,%0+,__zero_reg__)  CR_TAB
3309                               AS2 (st,%0,__tmp_reg__)   CR_TAB
3310                               AS1 (clr,__zero_reg__)     CR_TAB
3311                               AS2 (sbiw,r26,3));
3312             }
3313           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
3314                         AS2 (st,%0+,%B1) CR_TAB
3315                         AS2 (st,%0+,%C1) CR_TAB
3316                         AS2 (st,%0,%D1)  CR_TAB
3317                         AS2 (sbiw,r26,3));
3318         }
3319       else
3320         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
3321                       AS2 (std,%0+1,%B1) CR_TAB
3322                       AS2 (std,%0+2,%C1) CR_TAB
3323                       AS2 (std,%0+3,%D1));
3324     }
3325   else if (GET_CODE (base) == PLUS) /* (R + i) */
3326     {
3327       int disp = INTVAL (XEXP (base, 1));
3328       reg_base = REGNO (XEXP (base, 0));
3329       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3330         {
3331           if (reg_base != REG_Y)
3332             fatal_insn ("incorrect insn:",insn);
3333
3334           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3335             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
3336                             AS2 (std,Y+60,%A1)    CR_TAB
3337                             AS2 (std,Y+61,%B1)    CR_TAB
3338                             AS2 (std,Y+62,%C1)    CR_TAB
3339                             AS2 (std,Y+63,%D1)    CR_TAB
3340                             AS2 (sbiw,r28,%o0-60));
3341
3342           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
3343                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
3344                           AS2 (st,Y,%A1)           CR_TAB
3345                           AS2 (std,Y+1,%B1)        CR_TAB
3346                           AS2 (std,Y+2,%C1)        CR_TAB
3347                           AS2 (std,Y+3,%D1)        CR_TAB
3348                           AS2 (subi,r28,lo8(%o0))  CR_TAB
3349                           AS2 (sbci,r29,hi8(%o0)));
3350         }
3351       if (reg_base == REG_X)
3352         {
3353           /* (X + d) = R */
3354           if (reg_src == REG_X)
3355             {
3356               *l = 9;
3357               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
3358                       AS2 (mov,__zero_reg__,r27) CR_TAB
3359                       AS2 (adiw,r26,%o0)         CR_TAB
3360                       AS2 (st,X+,__tmp_reg__)    CR_TAB
3361                       AS2 (st,X+,__zero_reg__)   CR_TAB
3362                       AS2 (st,X+,r28)            CR_TAB
3363                       AS2 (st,X,r29)             CR_TAB
3364                       AS1 (clr,__zero_reg__)     CR_TAB
3365                       AS2 (sbiw,r26,%o0+3));
3366             }
3367           else if (reg_src == REG_X - 2)
3368             {
3369               *l = 9;
3370               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
3371                       AS2 (mov,__zero_reg__,r27) CR_TAB
3372                       AS2 (adiw,r26,%o0)         CR_TAB
3373                       AS2 (st,X+,r24)            CR_TAB
3374                       AS2 (st,X+,r25)            CR_TAB
3375                       AS2 (st,X+,__tmp_reg__)    CR_TAB
3376                       AS2 (st,X,__zero_reg__)    CR_TAB
3377                       AS1 (clr,__zero_reg__)     CR_TAB
3378                       AS2 (sbiw,r26,%o0+3));
3379             }
3380           *l = 6;
3381           return (AS2 (adiw,r26,%o0) CR_TAB
3382                   AS2 (st,X+,%A1)    CR_TAB
3383                   AS2 (st,X+,%B1)    CR_TAB
3384                   AS2 (st,X+,%C1)    CR_TAB
3385                   AS2 (st,X,%D1)     CR_TAB
3386                   AS2 (sbiw,r26,%o0+3));
3387         }
3388       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
3389                     AS2 (std,%B0,%B1) CR_TAB
3390                     AS2 (std,%C0,%C1) CR_TAB
3391                     AS2 (std,%D0,%D1));
3392     }
3393   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3394     return *l=4, (AS2 (st,%0,%D1) CR_TAB
3395                   AS2 (st,%0,%C1) CR_TAB
3396                   AS2 (st,%0,%B1) CR_TAB
3397                   AS2 (st,%0,%A1));
3398   else if (GET_CODE (base) == POST_INC) /* (R++) */
3399     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
3400                   AS2 (st,%0,%B1) CR_TAB
3401                   AS2 (st,%0,%C1) CR_TAB
3402                   AS2 (st,%0,%D1));
3403   fatal_insn ("unknown move insn:",insn);
3404   return "";
3405 }
3406
3407 const char *
3408 output_movsisf (rtx insn, rtx operands[], int *l)
3409 {
3410   int dummy;
3411   rtx dest = operands[0];
3412   rtx src = operands[1];
3413   int *real_l = l;
3414   
3415   if (avr_mem_pgm_p (src)
3416       || avr_mem_pgm_p (dest))
3417     {
3418       return avr_out_lpm (insn, operands, real_l);
3419     }
3420
3421   if (!l)
3422     l = &dummy;
3423   
3424   if (register_operand (dest, VOIDmode))
3425     {
3426       if (register_operand (src, VOIDmode)) /* mov r,r */
3427         {
3428           if (true_regnum (dest) > true_regnum (src))
3429             {
3430               if (AVR_HAVE_MOVW)
3431                 {
3432                   *l = 2;
3433                   return (AS2 (movw,%C0,%C1) CR_TAB
3434                           AS2 (movw,%A0,%A1));
3435                 }
3436               *l = 4;
3437               return (AS2 (mov,%D0,%D1) CR_TAB
3438                       AS2 (mov,%C0,%C1) CR_TAB
3439                       AS2 (mov,%B0,%B1) CR_TAB
3440                       AS2 (mov,%A0,%A1));
3441             }
3442           else
3443             {
3444               if (AVR_HAVE_MOVW)
3445                 {
3446                   *l = 2;
3447                   return (AS2 (movw,%A0,%A1) CR_TAB
3448                           AS2 (movw,%C0,%C1));
3449                 }
3450               *l = 4;
3451               return (AS2 (mov,%A0,%A1) CR_TAB
3452                       AS2 (mov,%B0,%B1) CR_TAB
3453                       AS2 (mov,%C0,%C1) CR_TAB
3454                       AS2 (mov,%D0,%D1));
3455             }
3456         }
3457       else if (CONSTANT_P (src))
3458         {
3459           return output_reload_insisf (operands, NULL_RTX, real_l);
3460         }
3461       else if (GET_CODE (src) == MEM)
3462         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
3463     }
3464   else if (GET_CODE (dest) == MEM)
3465     {
3466       const char *templ;
3467
3468       if (src == CONST0_RTX (GET_MODE (dest)))
3469           operands[1] = zero_reg_rtx;
3470
3471       templ = out_movsi_mr_r (insn, operands, real_l);
3472
3473       if (!real_l)
3474         output_asm_insn (templ, operands);
3475
3476       operands[1] = src;
3477       return "";
3478     }
3479   fatal_insn ("invalid insn:", insn);
3480   return "";
3481 }
3482
3483
3484 /* Handle loads of 24-bit types from memory to register.  */
3485
3486 static const char*
3487 avr_out_load_psi (rtx insn, rtx *op, int *plen)
3488 {
3489   rtx dest = op[0];
3490   rtx src = op[1];
3491   rtx base = XEXP (src, 0);
3492   int reg_dest = true_regnum (dest);
3493   int reg_base = true_regnum (base);
3494   
3495   if (reg_base > 0)
3496     {
3497       if (reg_base == REG_X)        /* (R26) */
3498         {
3499           if (reg_dest == REG_X)
3500             /* "ld r26,-X" is undefined */
3501             return avr_asm_len ("adiw r26,2"        CR_TAB
3502                                 "ld r28,X"          CR_TAB
3503                                 "ld __tmp_reg__,-X" CR_TAB
3504                                 "sbiw r26,1"        CR_TAB
3505                                 "ld r26,X"          CR_TAB
3506                                 "mov r27,__tmp_reg__", op, plen, -6);
3507           else
3508             {
3509               avr_asm_len ("ld %A0,X+" CR_TAB
3510                            "ld %B0,X+" CR_TAB
3511                            "ld %C0,X", op, plen, -3);
3512
3513               if (reg_dest != REG_X - 2
3514                   && !reg_unused_after (insn, base))
3515                 {
3516                   avr_asm_len ("sbiw r26,2", op, plen, 1);
3517                 }
3518
3519               return "";
3520             }
3521         }
3522       else /* reg_base != REG_X */
3523         {
3524           if (reg_dest == reg_base)
3525             return avr_asm_len ("ldd %C0,%1+2"          CR_TAB
3526                                 "ldd __tmp_reg__,%1+1"  CR_TAB
3527                                 "ld  %A0,%1"            CR_TAB
3528                                 "mov %B0,__tmp_reg__", op, plen, -4);
3529           else
3530             return avr_asm_len ("ld  %A0,%1"    CR_TAB
3531                                 "ldd %B0,%1+1"  CR_TAB
3532                                 "ldd %C0,%1+2", op, plen, -3);
3533         }
3534     }
3535   else if (GET_CODE (base) == PLUS) /* (R + i) */
3536     {
3537       int disp = INTVAL (XEXP (base, 1));
3538       
3539       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3540         {
3541           if (REGNO (XEXP (base, 0)) != REG_Y)
3542             fatal_insn ("incorrect insn:",insn);
3543
3544           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3545             return avr_asm_len ("adiw r28,%o1-61" CR_TAB
3546                                 "ldd %A0,Y+61"    CR_TAB
3547                                 "ldd %B0,Y+62"    CR_TAB
3548                                 "ldd %C0,Y+63"    CR_TAB
3549                                 "sbiw r28,%o1-61", op, plen, -5);
3550
3551           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3552                               "sbci r29,hi8(-%o1)" CR_TAB
3553                               "ld  %A0,Y"           CR_TAB
3554                               "ldd %B0,Y+1"        CR_TAB
3555                               "ldd %C0,Y+2"        CR_TAB
3556                               "subi r28,lo8(%o1)"  CR_TAB
3557                               "sbci r29,hi8(%o1)", op, plen, -7);
3558         }
3559
3560       reg_base = true_regnum (XEXP (base, 0));
3561       if (reg_base == REG_X)
3562         {
3563           /* R = (X + d) */
3564           if (reg_dest == REG_X)
3565             {
3566               /* "ld r26,-X" is undefined */
3567               return avr_asm_len ("adiw r26,%o1+2"     CR_TAB
3568                                   "ld  r28,X"          CR_TAB
3569                                   "ld  __tmp_reg__,-X" CR_TAB
3570                                   "sbiw r26,1"         CR_TAB
3571                                   "ld  r26,X"          CR_TAB
3572                                   "mov r27,__tmp_reg__", op, plen, -6);
3573             }
3574           
3575             avr_asm_len ("adiw r26,%o1"      CR_TAB
3576                          "ld r24,X+"         CR_TAB
3577                          "ld r25,X+"         CR_TAB
3578                          "ld r26,X", op, plen, -4);
3579
3580             if (reg_dest != REG_X - 2)
3581               avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
3582
3583             return "";
3584         }
3585       
3586       if (reg_dest == reg_base)
3587         return avr_asm_len ("ldd %C0,%C1" CR_TAB
3588                             "ldd __tmp_reg__,%B1"  CR_TAB
3589                             "ldd %A0,%A1" CR_TAB
3590                             "mov %B0,__tmp_reg__", op, plen, -4);
3591
3592         return avr_asm_len ("ldd %A0,%A1" CR_TAB
3593                             "ldd %B0,%B1" CR_TAB
3594                             "ldd %C0,%C1", op, plen, -3);
3595     }
3596   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3597     return avr_asm_len ("ld %C0,%1" CR_TAB
3598                         "ld %B0,%1" CR_TAB
3599                         "ld %A0,%1", op, plen, -3);
3600   else if (GET_CODE (base) == POST_INC) /* (R++) */
3601     return avr_asm_len ("ld %A0,%1" CR_TAB
3602                         "ld %B0,%1" CR_TAB
3603                         "ld %C0,%1", op, plen, -3);
3604
3605   else if (CONSTANT_ADDRESS_P (base))
3606     return avr_asm_len ("lds %A0,%m1" CR_TAB
3607                         "lds %B0,%m1+1" CR_TAB
3608                         "lds %C0,%m1+2", op, plen , -6);
3609   
3610   fatal_insn ("unknown move insn:",insn);
3611   return "";
3612 }
3613
3614 /* Handle store of 24-bit type from register or zero to memory.  */
3615
3616 static const char*
3617 avr_out_store_psi (rtx insn, rtx *op, int *plen)
3618 {
3619   rtx dest = op[0];
3620   rtx src = op[1];
3621   rtx base = XEXP (dest, 0);
3622   int reg_base = true_regnum (base);
3623   
3624   if (CONSTANT_ADDRESS_P (base))
3625     return avr_asm_len ("sts %m0,%A1"   CR_TAB
3626                         "sts %m0+1,%B1" CR_TAB
3627                         "sts %m0+2,%C1", op, plen, -6);
3628   
3629   if (reg_base > 0)                 /* (r) */
3630     {
3631       if (reg_base == REG_X)        /* (R26) */
3632         {
3633           gcc_assert (!reg_overlap_mentioned_p (base, src));
3634           
3635           avr_asm_len ("st %0+,%A1"  CR_TAB
3636                        "st %0+,%B1" CR_TAB
3637                        "st %0,%C1", op, plen, -3);
3638
3639           if (!reg_unused_after (insn, base))
3640             avr_asm_len ("sbiw r26,2", op, plen, 1);
3641
3642           return "";
3643         }
3644       else
3645         return avr_asm_len ("st %0,%A1"    CR_TAB
3646                             "std %0+1,%B1" CR_TAB
3647                             "std %0+2,%C1", op, plen, -3);
3648     }
3649   else if (GET_CODE (base) == PLUS) /* (R + i) */
3650     {
3651       int disp = INTVAL (XEXP (base, 1));
3652       reg_base = REGNO (XEXP (base, 0));
3653
3654       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3655         {
3656           if (reg_base != REG_Y)
3657             fatal_insn ("incorrect insn:",insn);
3658
3659           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3660             return avr_asm_len ("adiw r28,%o0-61" CR_TAB
3661                                 "std Y+61,%A1"    CR_TAB
3662                                 "std Y+62,%B1"    CR_TAB
3663                                 "std Y+63,%C1"    CR_TAB
3664                                 "sbiw r28,%o0-60", op, plen, -5);
3665
3666           return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
3667                               "sbci r29,hi8(-%o0)" CR_TAB
3668                               "st Y,%A1"           CR_TAB
3669                               "std Y+1,%B1"        CR_TAB
3670                               "std Y+2,%C1"        CR_TAB
3671                               "subi r28,lo8(%o0)"  CR_TAB
3672                               "sbci r29,hi8(%o0)", op, plen, -7);
3673         }
3674       if (reg_base == REG_X)
3675         {
3676           /* (X + d) = R */
3677           gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
3678           
3679           avr_asm_len ("adiw r26,%o0" CR_TAB
3680                        "st X+,%A1"    CR_TAB
3681                        "st X+,%B1"    CR_TAB
3682                        "st X,%C1", op, plen, -4);
3683
3684           if (!reg_unused_after (insn, XEXP (base, 0)))
3685             avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
3686
3687           return "";
3688         }
3689       
3690       return avr_asm_len ("std %A0,%A1" CR_TAB
3691                           "std %B0,%B1" CR_TAB
3692                           "std %C0,%C1", op, plen, -3);
3693     }
3694   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3695     return avr_asm_len ("st %0,%C1" CR_TAB
3696                         "st %0,%B1" CR_TAB
3697                         "st %0,%A1", op, plen, -3);
3698   else if (GET_CODE (base) == POST_INC) /* (R++) */
3699     return avr_asm_len ("st %0,%A1" CR_TAB
3700                         "st %0,%B1" CR_TAB
3701                         "st %0,%C1", op, plen, -3);
3702
3703   fatal_insn ("unknown move insn:",insn);
3704   return "";
3705 }
3706
3707
3708 /* Move around 24-bit stuff.  */
3709
3710 const char *
3711 avr_out_movpsi (rtx insn, rtx *op, int *plen)
3712 {
3713   rtx dest = op[0];
3714   rtx src = op[1];
3715   
3716   if (avr_mem_pgm_p (src)
3717       || avr_mem_pgm_p (dest))
3718     {
3719       return avr_out_lpm (insn, op, plen);
3720     }
3721   
3722   if (register_operand (dest, VOIDmode))
3723     {
3724       if (register_operand (src, VOIDmode)) /* mov r,r */
3725         {
3726           if (true_regnum (dest) > true_regnum (src))
3727             {
3728               avr_asm_len ("mov %C0,%C1", op, plen, -1);
3729
3730               if (AVR_HAVE_MOVW)
3731                 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
3732               else
3733                 return avr_asm_len ("mov %B0,%B1"  CR_TAB
3734                                     "mov %A0,%A1", op, plen, 2);
3735             }
3736           else
3737             {
3738               if (AVR_HAVE_MOVW)
3739                 avr_asm_len ("movw %A0,%A1", op, plen, -1);
3740               else
3741                 avr_asm_len ("mov %A0,%A1"  CR_TAB
3742                              "mov %B0,%B1", op, plen, -2);
3743               
3744               return avr_asm_len ("mov %C0,%C1", op, plen, 1);
3745             }
3746         }
3747       else if (CONSTANT_P (src))
3748         {
3749           return avr_out_reload_inpsi (op, NULL_RTX, plen);
3750         }
3751       else if (MEM_P (src))
3752         return avr_out_load_psi (insn, op, plen); /* mov r,m */
3753     }
3754   else if (MEM_P (dest))
3755     {
3756       rtx xop[2];
3757
3758       xop[0] = dest;
3759       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3760       
3761       return avr_out_store_psi (insn, xop, plen);
3762     }
3763     
3764   fatal_insn ("invalid insn:", insn);
3765   return "";
3766 }
3767
3768
3769 static const char*
3770 out_movqi_mr_r (rtx insn, rtx op[], int *plen)
3771 {
3772   rtx dest = op[0];
3773   rtx src = op[1];
3774   rtx x = XEXP (dest, 0);
3775   
3776   if (CONSTANT_ADDRESS_P (x))
3777     {
3778       return optimize > 0 && io_address_operand (x, QImode)
3779         ? avr_asm_len ("out %i0,%1", op, plen, -1)
3780         : avr_asm_len ("sts %m0,%1", op, plen, -2);
3781     }
3782   else if (GET_CODE (x) == PLUS
3783            && REG_P (XEXP (x, 0))
3784            && CONST_INT_P (XEXP (x, 1)))
3785     {
3786       /* memory access by reg+disp */
3787
3788       int disp = INTVAL (XEXP (x, 1));
3789
3790       if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
3791         {
3792           if (REGNO (XEXP (x, 0)) != REG_Y)
3793             fatal_insn ("incorrect insn:",insn);
3794
3795           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3796             return avr_asm_len ("adiw r28,%o0-63" CR_TAB
3797                                 "std Y+63,%1"     CR_TAB
3798                                 "sbiw r28,%o0-63", op, plen, -3);
3799
3800           return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
3801                               "sbci r29,hi8(-%o0)" CR_TAB
3802                               "st Y,%1"            CR_TAB
3803                               "subi r28,lo8(%o0)"  CR_TAB
3804                               "sbci r29,hi8(%o0)", op, plen, -5);
3805         }
3806       else if (REGNO (XEXP (x,0)) == REG_X)
3807         {
3808           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
3809             {
3810               avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
3811                            "adiw r26,%o0"       CR_TAB
3812                            "st X,__tmp_reg__", op, plen, -3);
3813             }
3814           else
3815             {
3816               avr_asm_len ("adiw r26,%o0" CR_TAB
3817                            "st X,%1", op, plen, -2);
3818             }
3819           
3820           if (!reg_unused_after (insn, XEXP (x,0)))
3821             avr_asm_len ("sbiw r26,%o0", op, plen, 1);
3822
3823           return "";
3824         }
3825       
3826       return avr_asm_len ("std %0,%1", op, plen, 1);
3827     }
3828   
3829   return avr_asm_len ("st %0,%1", op, plen, 1);
3830 }
3831
3832 static const char*
3833 out_movhi_mr_r (rtx insn, rtx op[], int *plen)
3834 {
3835   rtx dest = op[0];
3836   rtx src = op[1];
3837   rtx base = XEXP (dest, 0);
3838   int reg_base = true_regnum (base);
3839   int reg_src = true_regnum (src);
3840   /* "volatile" forces writing high byte first, even if less efficient,
3841      for correct operation with 16-bit I/O registers.  */
3842   int mem_volatile_p = MEM_VOLATILE_P (dest);
3843
3844   if (CONSTANT_ADDRESS_P (base))
3845     return optimize > 0 && io_address_operand (base, HImode)
3846       ? avr_asm_len ("out %i0+1,%B1" CR_TAB
3847                      "out %i0,%A1", op, plen, -2)
3848
3849       : avr_asm_len ("sts %m0+1,%B1" CR_TAB
3850                      "sts %m0,%A1", op, plen, -4);
3851   
3852   if (reg_base > 0)
3853     {
3854       if (reg_base != REG_X)
3855         return avr_asm_len ("std %0+1,%B1" CR_TAB
3856                             "st %0,%A1", op, plen, -2);
3857       
3858       if (reg_src == REG_X)
3859         /* "st X+,r26" and "st -X,r26" are undefined.  */
3860         return !mem_volatile_p && reg_unused_after (insn, src)
3861           ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
3862                          "st X,r26"            CR_TAB
3863                          "adiw r26,1"          CR_TAB
3864                          "st X,__tmp_reg__", op, plen, -4)
3865
3866           : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
3867                          "adiw r26,1"          CR_TAB
3868                          "st X,__tmp_reg__"    CR_TAB
3869                          "sbiw r26,1"          CR_TAB
3870                          "st X,r26", op, plen, -5);
3871       
3872       return !mem_volatile_p && reg_unused_after (insn, base)
3873         ? avr_asm_len ("st X+,%A1" CR_TAB
3874                        "st X,%B1", op, plen, -2)
3875         : avr_asm_len ("adiw r26,1" CR_TAB
3876                        "st X,%B1"   CR_TAB
3877                        "st -X,%A1", op, plen, -3);
3878     }
3879   else if (GET_CODE (base) == PLUS)
3880     {
3881       int disp = INTVAL (XEXP (base, 1));
3882       reg_base = REGNO (XEXP (base, 0));
3883       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3884         {
3885           if (reg_base != REG_Y)
3886             fatal_insn ("incorrect insn:",insn);
3887           
3888           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
3889             ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
3890                            "std Y+63,%B1"    CR_TAB
3891                            "std Y+62,%A1"    CR_TAB
3892                            "sbiw r28,%o0-62", op, plen, -4)
3893
3894             : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
3895                            "sbci r29,hi8(-%o0)" CR_TAB
3896                            "std Y+1,%B1"        CR_TAB
3897                            "st Y,%A1"           CR_TAB
3898                            "subi r28,lo8(%o0)"  CR_TAB
3899                            "sbci r29,hi8(%o0)", op, plen, -6);
3900         }
3901       
3902       if (reg_base != REG_X)
3903         return avr_asm_len ("std %B0,%B1" CR_TAB
3904                             "std %A0,%A1", op, plen, -2);
3905       /* (X + d) = R */
3906       return reg_src == REG_X
3907         ? avr_asm_len ("mov __tmp_reg__,r26"  CR_TAB
3908                        "mov __zero_reg__,r27" CR_TAB
3909                        "adiw r26,%o0+1"       CR_TAB
3910                        "st X,__zero_reg__"    CR_TAB
3911                        "st -X,__tmp_reg__"    CR_TAB
3912                        "clr __zero_reg__"     CR_TAB
3913                        "sbiw r26,%o0", op, plen, -7)
3914
3915         : avr_asm_len ("adiw r26,%o0+1" CR_TAB
3916                        "st X,%B1"       CR_TAB
3917                        "st -X,%A1"      CR_TAB
3918                        "sbiw r26,%o0", op, plen, -4);
3919     }
3920   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3921     {
3922       return avr_asm_len ("st %0,%B1" CR_TAB
3923                           "st %0,%A1", op, plen, -2);
3924     }
3925   else if (GET_CODE (base) == POST_INC) /* (R++) */
3926     {
3927       if (!mem_volatile_p)
3928         return avr_asm_len ("st %0,%A1"  CR_TAB
3929                             "st %0,%B1", op, plen, -2);
3930       
3931       return REGNO (XEXP (base, 0)) == REG_X
3932         ? avr_asm_len ("adiw r26,1"  CR_TAB
3933                        "st X,%B1"    CR_TAB
3934                        "st -X,%A1"   CR_TAB
3935                        "adiw r26,2", op, plen, -4)
3936
3937         : avr_asm_len ("std %p0+1,%B1" CR_TAB
3938                        "st %p0,%A1"    CR_TAB
3939                        "adiw %r0,2", op, plen, -3);
3940     }
3941   fatal_insn ("unknown move insn:",insn);
3942   return "";
3943 }
3944
3945 /* Return 1 if frame pointer for current function required.  */
3946
3947 static bool
3948 avr_frame_pointer_required_p (void)
3949 {
3950   return (cfun->calls_alloca
3951           || cfun->calls_setjmp
3952           || cfun->has_nonlocal_label
3953           || crtl->args.info.nregs == 0
3954           || get_frame_size () > 0);
3955 }
3956
3957 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
3958
3959 static RTX_CODE
3960 compare_condition (rtx insn)
3961 {
3962   rtx next = next_real_insn (insn);
3963
3964   if (next && JUMP_P (next))
3965     {
3966       rtx pat = PATTERN (next);
3967       rtx src = SET_SRC (pat);
3968       
3969       if (IF_THEN_ELSE == GET_CODE (src))
3970         return GET_CODE (XEXP (src, 0));
3971     }
3972   
3973   return UNKNOWN;
3974 }
3975
3976
3977 /* Returns true iff INSN is a tst insn that only tests the sign.  */
3978
3979 static bool
3980 compare_sign_p (rtx insn)
3981 {
3982   RTX_CODE cond = compare_condition (insn);
3983   return (cond == GE || cond == LT);
3984 }
3985
3986
3987 /* Returns true iff the next insn is a JUMP_INSN with a condition
3988    that needs to be swapped (GT, GTU, LE, LEU).  */
3989
3990 static bool
3991 compare_diff_p (rtx insn)
3992 {
3993   RTX_CODE cond = compare_condition (insn);
3994   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
3995 }
3996
3997 /* Returns true iff INSN is a compare insn with the EQ or NE condition.  */
3998
3999 static bool
4000 compare_eq_p (rtx insn)
4001 {
4002   RTX_CODE cond = compare_condition (insn);
4003   return (cond == EQ || cond == NE);
4004 }
4005
4006
4007 /* Output compare instruction
4008
4009       compare (XOP[0], XOP[1])
4010
4011    for an HI/SI register XOP[0] and an integer XOP[1].  Return "".
4012    XOP[2] is an 8-bit scratch register as needed.
4013
4014    PLEN == NULL:  Output instructions.
4015    PLEN != NULL:  Set *PLEN to the length (in words) of the sequence.
4016                   Don't output anything.  */
4017
4018 const char*
4019 avr_out_compare (rtx insn, rtx *xop, int *plen)
4020 {
4021   /* Register to compare and value to compare against. */
4022   rtx xreg = xop[0];
4023   rtx xval = xop[1];
4024   
4025   /* MODE of the comparison.  */
4026   enum machine_mode mode = GET_MODE (xreg);
4027
4028   /* Number of bytes to operate on.  */
4029   int i, n_bytes = GET_MODE_SIZE (mode);
4030
4031   /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown.  */
4032   int clobber_val = -1;
4033
4034   gcc_assert (REG_P (xreg)
4035               && CONST_INT_P (xval));
4036   
4037   if (plen)
4038     *plen = 0;
4039
4040   /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
4041      against 0 by ORing the bytes.  This is one instruction shorter.  */
4042
4043   if (!test_hard_reg_class (LD_REGS, xreg)
4044       && compare_eq_p (insn)
4045       && reg_unused_after (insn, xreg))
4046     {
4047       if (xval == const1_rtx)
4048         {
4049           avr_asm_len ("dec %A0" CR_TAB
4050                        "or %A0,%B0", xop, plen, 2);
4051           
4052           if (n_bytes >= 3)
4053             avr_asm_len ("or %A0,%C0", xop, plen, 1);
4054
4055           if (n_bytes >= 4)
4056             avr_asm_len ("or %A0,%D0", xop, plen, 1);
4057
4058           return "";
4059         }
4060       else if (xval == constm1_rtx)
4061         {
4062           if (n_bytes >= 4)
4063             avr_asm_len ("and %A0,%D0", xop, plen, 1);
4064           
4065           if (n_bytes >= 3)
4066             avr_asm_len ("and %A0,%C0", xop, plen, 1);
4067           
4068           return avr_asm_len ("and %A0,%B0" CR_TAB
4069                               "com %A0", xop, plen, 2);
4070         }
4071     }
4072
4073   for (i = 0; i < n_bytes; i++)
4074     {
4075       /* We compare byte-wise.  */
4076       rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
4077       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
4078
4079       /* 8-bit value to compare with this byte.  */
4080       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
4081
4082       /* Registers R16..R31 can operate with immediate.  */
4083       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
4084
4085       xop[0] = reg8;
4086       xop[1] = gen_int_mode (val8, QImode);
4087
4088       /* Word registers >= R24 can use SBIW/ADIW with 0..63.  */
4089
4090       if (i == 0
4091           && test_hard_reg_class (ADDW_REGS, reg8))
4092         {
4093           int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
4094           
4095           if (IN_RANGE (val16, 0, 63)
4096               && (val8 == 0
4097                   || reg_unused_after (insn, xreg)))
4098             {
4099               avr_asm_len ("sbiw %0,%1", xop, plen, 1);
4100               i++;
4101               continue;
4102             }
4103
4104           if (n_bytes == 2
4105               && IN_RANGE (val16, -63, -1)
4106               && compare_eq_p (insn)
4107               && reg_unused_after (insn, xreg))
4108             {
4109               return avr_asm_len ("adiw %0,%n1", xop, plen, 1);
4110             }
4111         }
4112
4113       /* Comparing against 0 is easy.  */
4114       
4115       if (val8 == 0)
4116         {
4117           avr_asm_len (i == 0
4118                        ? "cp %0,__zero_reg__"
4119                        : "cpc %0,__zero_reg__", xop, plen, 1);
4120           continue;
4121         }
4122
4123       /* Upper registers can compare and subtract-with-carry immediates.
4124          Notice that compare instructions do the same as respective subtract
4125          instruction; the only difference is that comparisons don't write
4126          the result back to the target register.  */
4127
4128       if (ld_reg_p)
4129         {
4130           if (i == 0)
4131             {
4132               avr_asm_len ("cpi %0,%1", xop, plen, 1);
4133               continue;
4134             }
4135           else if (reg_unused_after (insn, xreg))
4136             {
4137               avr_asm_len ("sbci %0,%1", xop, plen, 1);
4138               continue;
4139             }
4140         }
4141
4142       /* Must load the value into the scratch register.  */
4143
4144       gcc_assert (REG_P (xop[2]));
4145               
4146       if (clobber_val != (int) val8)
4147         avr_asm_len ("ldi %2,%1", xop, plen, 1);
4148       clobber_val = (int) val8;
4149               
4150       avr_asm_len (i == 0
4151                    ? "cp %0,%2"
4152                    : "cpc %0,%2", xop, plen, 1);
4153     }
4154
4155   return "";
4156 }
4157
4158
4159 /* Output test instruction for HImode.  */
4160
4161 const char*
4162 avr_out_tsthi (rtx insn, rtx *op, int *plen)
4163 {
4164   if (compare_sign_p (insn))
4165     {
4166       avr_asm_len ("tst %B0", op, plen, -1);
4167     }
4168   else if (reg_unused_after (insn, op[0])
4169            && compare_eq_p (insn))
4170     {
4171       /* Faster than sbiw if we can clobber the operand.  */
4172       avr_asm_len ("or %A0,%B0", op, plen, -1);
4173     }
4174   else
4175     {
4176       avr_out_compare (insn, op, plen);
4177     }
4178
4179   return "";
4180 }
4181
4182
4183 /* Output test instruction for PSImode.  */
4184
4185 const char*
4186 avr_out_tstpsi (rtx insn, rtx *op, int *plen)
4187 {
4188   if (compare_sign_p (insn))
4189     {
4190       avr_asm_len ("tst %C0", op, plen, -1);
4191     }
4192   else if (reg_unused_after (insn, op[0])
4193            && compare_eq_p (insn))
4194     {
4195       /* Faster than sbiw if we can clobber the operand.  */
4196       avr_asm_len ("or %A0,%B0" CR_TAB
4197                    "or %A0,%C0", op, plen, -2);
4198     }
4199   else
4200     {
4201       avr_out_compare (insn, op, plen);
4202     }
4203
4204   return "";
4205 }
4206
4207
4208 /* Output test instruction for SImode.  */
4209
4210 const char*
4211 avr_out_tstsi (rtx insn, rtx *op, int *plen)
4212 {
4213   if (compare_sign_p (insn))
4214     {
4215       avr_asm_len ("tst %D0", op, plen, -1);
4216     }
4217   else if (reg_unused_after (insn, op[0])
4218            && compare_eq_p (insn))
4219     {
4220       /* Faster than sbiw if we can clobber the operand.  */
4221       avr_asm_len ("or %A0,%B0" CR_TAB
4222                    "or %A0,%C0" CR_TAB
4223                    "or %A0,%D0", op, plen, -3);
4224     }
4225   else
4226     {
4227       avr_out_compare (insn, op, plen);
4228     }
4229
4230   return "";
4231 }
4232
4233
4234 /* Generate asm equivalent for various shifts.  This only handles cases
4235    that are not already carefully hand-optimized in ?sh??i3_out.
4236
4237    OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
4238    OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
4239    OPERANDS[3] is a QImode scratch register from LD regs if
4240                available and SCRATCH, otherwise (no scratch available)
4241
4242    TEMPL is an assembler template that shifts by one position.
4243    T_LEN is the length of this template.  */
4244
4245 void
4246 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
4247                     int *plen, int t_len)
4248 {
4249   bool second_label = true;
4250   bool saved_in_tmp = false;
4251   bool use_zero_reg = false;
4252   rtx op[5];
4253
4254   op[0] = operands[0];
4255   op[1] = operands[1];
4256   op[2] = operands[2];
4257   op[3] = operands[3];
4258
4259   if (plen)
4260     *plen = 0;
4261
4262   if (CONST_INT_P (operands[2]))
4263     {
4264       bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
4265                       && REG_P (operands[3]));
4266       int count = INTVAL (operands[2]);
4267       int max_len = 10;  /* If larger than this, always use a loop.  */
4268
4269       if (count <= 0)
4270           return;
4271
4272       if (count < 8 && !scratch)
4273         use_zero_reg = true;
4274
4275       if (optimize_size)
4276         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
4277
4278       if (t_len * count <= max_len)
4279         {
4280           /* Output shifts inline with no loop - faster.  */
4281           
4282           while (count-- > 0)
4283             avr_asm_len (templ, op, plen, t_len);
4284
4285           return;
4286         }
4287
4288       if (scratch)
4289         {
4290           avr_asm_len ("ldi %3,%2", op, plen, 1);
4291         }
4292       else if (use_zero_reg)
4293         {
4294           /* Hack to save one word: use __zero_reg__ as loop counter.
4295              Set one bit, then shift in a loop until it is 0 again.  */
4296
4297           op[3] = zero_reg_rtx;
4298
4299           avr_asm_len ("set" CR_TAB
4300                        "bld %3,%2-1", op, plen, 2);
4301         }
4302       else
4303         {
4304           /* No scratch register available, use one from LD_REGS (saved in
4305              __tmp_reg__) that doesn't overlap with registers to shift.  */
4306
4307           op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
4308           op[4] = tmp_reg_rtx;
4309           saved_in_tmp = true;
4310
4311           avr_asm_len ("mov %4,%3" CR_TAB
4312                        "ldi %3,%2", op, plen, 2);
4313         }
4314
4315       second_label = false;
4316     }
4317   else if (MEM_P (op[2]))
4318     {
4319       rtx op_mov[2];
4320       
4321       op_mov[0] = op[3] = tmp_reg_rtx;
4322       op_mov[1] = op[2];
4323
4324       out_movqi_r_mr (insn, op_mov, plen);
4325     }
4326   else if (register_operand (op[2], QImode))
4327     {
4328       op[3] = op[2];
4329       
4330       if (!reg_unused_after (insn, op[2])
4331           || reg_overlap_mentioned_p (op[0], op[2]))
4332         {
4333           op[3] = tmp_reg_rtx;
4334           avr_asm_len ("mov %3,%2", op, plen, 1);
4335         }
4336     }
4337   else
4338     fatal_insn ("bad shift insn:", insn);
4339
4340   if (second_label)
4341       avr_asm_len ("rjmp 2f", op, plen, 1);
4342
4343   avr_asm_len ("1:", op, plen, 0);
4344   avr_asm_len (templ, op, plen, t_len);
4345
4346   if (second_label)
4347     avr_asm_len ("2:", op, plen, 0);
4348
4349   avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
4350   avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
4351
4352   if (saved_in_tmp)
4353     avr_asm_len ("mov %3,%4", op, plen, 1);
4354 }
4355
4356
4357 /* 8bit shift left ((char)x << i)   */
4358
4359 const char *
4360 ashlqi3_out (rtx insn, rtx operands[], int *len)
4361 {
4362   if (GET_CODE (operands[2]) == CONST_INT)
4363     {
4364       int k;
4365
4366       if (!len)
4367         len = &k;
4368
4369       switch (INTVAL (operands[2]))
4370         {
4371         default:
4372           if (INTVAL (operands[2]) < 8)
4373             break;
4374
4375           *len = 1;
4376           return AS1 (clr,%0);
4377           
4378         case 1:
4379           *len = 1;
4380           return AS1 (lsl,%0);
4381           
4382         case 2:
4383           *len = 2;
4384           return (AS1 (lsl,%0) CR_TAB
4385                   AS1 (lsl,%0));
4386
4387         case 3:
4388           *len = 3;
4389           return (AS1 (lsl,%0) CR_TAB
4390                   AS1 (lsl,%0) CR_TAB
4391                   AS1 (lsl,%0));
4392
4393         case 4:
4394           if (test_hard_reg_class (LD_REGS, operands[0]))
4395             {
4396               *len = 2;
4397               return (AS1 (swap,%0) CR_TAB
4398                       AS2 (andi,%0,0xf0));
4399             }
4400           *len = 4;
4401           return (AS1 (lsl,%0) CR_TAB
4402                   AS1 (lsl,%0) CR_TAB
4403                   AS1 (lsl,%0) CR_TAB
4404                   AS1 (lsl,%0));
4405
4406         case 5:
4407           if (test_hard_reg_class (LD_REGS, operands[0]))
4408             {
4409               *len = 3;
4410               return (AS1 (swap,%0) CR_TAB
4411                       AS1 (lsl,%0)  CR_TAB
4412                       AS2 (andi,%0,0xe0));
4413             }
4414           *len = 5;
4415           return (AS1 (lsl,%0) CR_TAB
4416                   AS1 (lsl,%0) CR_TAB
4417                   AS1 (lsl,%0) CR_TAB
4418                   AS1 (lsl,%0) CR_TAB
4419                   AS1 (lsl,%0));
4420
4421         case 6:
4422           if (test_hard_reg_class (LD_REGS, operands[0]))
4423             {
4424               *len = 4;
4425               return (AS1 (swap,%0) CR_TAB
4426                       AS1 (lsl,%0)  CR_TAB
4427                       AS1 (lsl,%0)  CR_TAB
4428                       AS2 (andi,%0,0xc0));
4429             }
4430           *len = 6;
4431           return (AS1 (lsl,%0) CR_TAB
4432                   AS1 (lsl,%0) CR_TAB
4433                   AS1 (lsl,%0) CR_TAB
4434                   AS1 (lsl,%0) CR_TAB
4435                   AS1 (lsl,%0) CR_TAB
4436                   AS1 (lsl,%0));
4437
4438         case 7:
4439           *len = 3;
4440           return (AS1 (ror,%0) CR_TAB
4441                   AS1 (clr,%0) CR_TAB
4442                   AS1 (ror,%0));
4443         }
4444     }
4445   else if (CONSTANT_P (operands[2]))
4446     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
4447
4448   out_shift_with_cnt (AS1 (lsl,%0),
4449                       insn, operands, len, 1);
4450   return "";
4451 }
4452
4453
4454 /* 16bit shift left ((short)x << i)   */
4455
4456 const char *
4457 ashlhi3_out (rtx insn, rtx operands[], int *len)
4458 {
4459   if (GET_CODE (operands[2]) == CONST_INT)
4460     {
4461       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4462       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4463       int k;
4464       int *t = len;
4465
4466       if (!len)
4467         len = &k;
4468       
4469       switch (INTVAL (operands[2]))
4470         {
4471         default:
4472           if (INTVAL (operands[2]) < 16)
4473             break;
4474
4475           *len = 2;
4476           return (AS1 (clr,%B0) CR_TAB
4477                   AS1 (clr,%A0));
4478
4479         case 4:
4480           if (optimize_size && scratch)
4481             break;  /* 5 */
4482           if (ldi_ok)
4483             {
4484               *len = 6;
4485               return (AS1 (swap,%A0)      CR_TAB
4486                       AS1 (swap,%B0)      CR_TAB
4487                       AS2 (andi,%B0,0xf0) CR_TAB
4488                       AS2 (eor,%B0,%A0)   CR_TAB
4489                       AS2 (andi,%A0,0xf0) CR_TAB
4490                       AS2 (eor,%B0,%A0));
4491             }
4492           if (scratch)
4493             {
4494               *len = 7;
4495               return (AS1 (swap,%A0)    CR_TAB
4496                       AS1 (swap,%B0)    CR_TAB
4497                       AS2 (ldi,%3,0xf0) CR_TAB
4498                       "and %B0,%3"      CR_TAB
4499                       AS2 (eor,%B0,%A0) CR_TAB
4500                       "and %A0,%3"      CR_TAB
4501                       AS2 (eor,%B0,%A0));
4502             }
4503           break;  /* optimize_size ? 6 : 8 */
4504
4505         case 5:
4506           if (optimize_size)
4507             break;  /* scratch ? 5 : 6 */
4508           if (ldi_ok)
4509             {
4510               *len = 8;
4511               return (AS1 (lsl,%A0)       CR_TAB
4512                       AS1 (rol,%B0)       CR_TAB
4513                       AS1 (swap,%A0)      CR_TAB
4514                       AS1 (swap,%B0)      CR_TAB
4515                       AS2 (andi,%B0,0xf0) CR_TAB
4516                       AS2 (eor,%B0,%A0)   CR_TAB
4517                       AS2 (andi,%A0,0xf0) CR_TAB
4518                       AS2 (eor,%B0,%A0));
4519             }
4520           if (scratch)
4521             {
4522               *len = 9;
4523               return (AS1 (lsl,%A0)     CR_TAB
4524                       AS1 (rol,%B0)     CR_TAB
4525                       AS1 (swap,%A0)    CR_TAB
4526                       AS1 (swap,%B0)    CR_TAB
4527                       AS2 (ldi,%3,0xf0) CR_TAB
4528                       "and %B0,%3"      CR_TAB
4529                       AS2 (eor,%B0,%A0) CR_TAB
4530                       "and %A0,%3"      CR_TAB
4531                       AS2 (eor,%B0,%A0));
4532             }
4533           break;  /* 10 */
4534
4535         case 6:
4536           if (optimize_size)
4537             break;  /* scratch ? 5 : 6 */
4538           *len = 9;
4539           return (AS1 (clr,__tmp_reg__) CR_TAB
4540                   AS1 (lsr,%B0)         CR_TAB
4541                   AS1 (ror,%A0)         CR_TAB
4542                   AS1 (ror,__tmp_reg__) CR_TAB
4543                   AS1 (lsr,%B0)         CR_TAB
4544                   AS1 (ror,%A0)         CR_TAB
4545                   AS1 (ror,__tmp_reg__) CR_TAB
4546                   AS2 (mov,%B0,%A0)     CR_TAB
4547                   AS2 (mov,%A0,__tmp_reg__));
4548
4549         case 7:
4550           *len = 5;
4551           return (AS1 (lsr,%B0)     CR_TAB
4552                   AS2 (mov,%B0,%A0) CR_TAB
4553                   AS1 (clr,%A0)     CR_TAB
4554                   AS1 (ror,%B0)     CR_TAB
4555                   AS1 (ror,%A0));
4556
4557         case 8:
4558           return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
4559                             AS1 (clr,%A0));
4560
4561         case 9:
4562           *len = 3;
4563           return (AS2 (mov,%B0,%A0) CR_TAB
4564                   AS1 (clr,%A0)     CR_TAB
4565                   AS1 (lsl,%B0));
4566
4567         case 10:
4568           *len = 4;
4569           return (AS2 (mov,%B0,%A0) CR_TAB
4570                   AS1 (clr,%A0)     CR_TAB
4571                   AS1 (lsl,%B0)     CR_TAB
4572                   AS1 (lsl,%B0));
4573
4574         case 11:
4575           *len = 5;
4576           return (AS2 (mov,%B0,%A0) CR_TAB
4577                   AS1 (clr,%A0)     CR_TAB
4578                   AS1 (lsl,%B0)     CR_TAB
4579                   AS1 (lsl,%B0)     CR_TAB
4580                   AS1 (lsl,%B0));
4581
4582         case 12:
4583           if (ldi_ok)
4584             {
4585               *len = 4;
4586               return (AS2 (mov,%B0,%A0) CR_TAB
4587                       AS1 (clr,%A0)     CR_TAB
4588                       AS1 (swap,%B0)    CR_TAB
4589                       AS2 (andi,%B0,0xf0));
4590             }
4591           if (scratch)
4592             {
4593               *len = 5;
4594               return (AS2 (mov,%B0,%A0) CR_TAB
4595                       AS1 (clr,%A0)     CR_TAB
4596                       AS1 (swap,%B0)    CR_TAB
4597                       AS2 (ldi,%3,0xf0) CR_TAB
4598                       "and %B0,%3");
4599             }
4600           *len = 6;
4601           return (AS2 (mov,%B0,%A0) CR_TAB
4602                   AS1 (clr,%A0)     CR_TAB
4603                   AS1 (lsl,%B0)     CR_TAB
4604                   AS1 (lsl,%B0)     CR_TAB
4605                   AS1 (lsl,%B0)     CR_TAB
4606                   AS1 (lsl,%B0));
4607
4608         case 13:
4609           if (ldi_ok)
4610             {
4611               *len = 5;
4612               return (AS2 (mov,%B0,%A0) CR_TAB
4613                       AS1 (clr,%A0)     CR_TAB
4614                       AS1 (swap,%B0)    CR_TAB
4615                       AS1 (lsl,%B0)     CR_TAB
4616                       AS2 (andi,%B0,0xe0));
4617             }
4618           if (AVR_HAVE_MUL && scratch)
4619             {
4620               *len = 5;
4621               return (AS2 (ldi,%3,0x20) CR_TAB
4622                       AS2 (mul,%A0,%3)  CR_TAB
4623                       AS2 (mov,%B0,r0)  CR_TAB
4624                       AS1 (clr,%A0)     CR_TAB
4625                       AS1 (clr,__zero_reg__));
4626             }
4627           if (optimize_size && scratch)
4628             break;  /* 5 */
4629           if (scratch)
4630             {
4631               *len = 6;
4632               return (AS2 (mov,%B0,%A0) CR_TAB
4633                       AS1 (clr,%A0)     CR_TAB
4634                       AS1 (swap,%B0)    CR_TAB
4635                       AS1 (lsl,%B0)     CR_TAB
4636                       AS2 (ldi,%3,0xe0) CR_TAB
4637                       "and %B0,%3");
4638             }
4639           if (AVR_HAVE_MUL)
4640             {
4641               *len = 6;
4642               return ("set"            CR_TAB
4643                       AS2 (bld,r1,5)   CR_TAB
4644                       AS2 (mul,%A0,r1) CR_TAB
4645                       AS2 (mov,%B0,r0) CR_TAB
4646                       AS1 (clr,%A0)    CR_TAB
4647                       AS1 (clr,__zero_reg__));
4648             }
4649           *len = 7;
4650           return (AS2 (mov,%B0,%A0) CR_TAB
4651                   AS1 (clr,%A0)     CR_TAB
4652                   AS1 (lsl,%B0)     CR_TAB
4653                   AS1 (lsl,%B0)     CR_TAB
4654                   AS1 (lsl,%B0)     CR_TAB
4655                   AS1 (lsl,%B0)     CR_TAB
4656                   AS1 (lsl,%B0));
4657
4658         case 14:
4659           if (AVR_HAVE_MUL && ldi_ok)
4660             {
4661               *len = 5;
4662               return (AS2 (ldi,%B0,0x40) CR_TAB
4663                       AS2 (mul,%A0,%B0)  CR_TAB
4664                       AS2 (mov,%B0,r0)   CR_TAB
4665                       AS1 (clr,%A0)      CR_TAB
4666                       AS1 (clr,__zero_reg__));
4667             }
4668           if (AVR_HAVE_MUL && scratch)
4669             {
4670               *len = 5;
4671               return (AS2 (ldi,%3,0x40) CR_TAB
4672                       AS2 (mul,%A0,%3)  CR_TAB
4673                       AS2 (mov,%B0,r0)  CR_TAB
4674                       AS1 (clr,%A0)     CR_TAB
4675                       AS1 (clr,__zero_reg__));
4676             }
4677           if (optimize_size && ldi_ok)
4678             {
4679               *len = 5;
4680               return (AS2 (mov,%B0,%A0) CR_TAB
4681                       AS2 (ldi,%A0,6) "\n1:\t"
4682                       AS1 (lsl,%B0)     CR_TAB
4683                       AS1 (dec,%A0)     CR_TAB
4684                       AS1 (brne,1b));
4685             }
4686           if (optimize_size && scratch)
4687             break;  /* 5 */
4688           *len = 6;
4689           return (AS1 (clr,%B0) CR_TAB
4690                   AS1 (lsr,%A0) CR_TAB
4691                   AS1 (ror,%B0) CR_TAB
4692                   AS1 (lsr,%A0) CR_TAB
4693                   AS1 (ror,%B0) CR_TAB
4694                   AS1 (clr,%A0));
4695
4696         case 15:
4697           *len = 4;
4698           return (AS1 (clr,%B0) CR_TAB
4699                   AS1 (lsr,%A0) CR_TAB
4700                   AS1 (ror,%B0) CR_TAB
4701                   AS1 (clr,%A0));
4702         }
4703       len = t;
4704     }
4705   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
4706                        AS1 (rol,%B0)),
4707                        insn, operands, len, 2);
4708   return "";
4709 }
4710
4711
4712 /* 24-bit shift left */
4713
4714 const char*
4715 avr_out_ashlpsi3 (rtx insn, rtx *op, int *plen)
4716 {
4717   if (plen)
4718     *plen = 0;
4719   
4720   if (CONST_INT_P (op[2]))
4721     {
4722       switch (INTVAL (op[2]))
4723         {
4724         default:
4725           if (INTVAL (op[2]) < 24)
4726             break;
4727
4728           return avr_asm_len ("clr %A0" CR_TAB
4729                               "clr %B0" CR_TAB
4730                               "clr %C0", op, plen, 3);
4731
4732         case 8:
4733           {
4734             int reg0 = REGNO (op[0]);
4735             int reg1 = REGNO (op[1]);
4736             
4737             if (reg0 >= reg1)
4738               return avr_asm_len ("mov %C0,%B1"  CR_TAB
4739                                   "mov %B0,%A1"  CR_TAB
4740                                   "clr %A0", op, plen, 3);
4741             else
4742               return avr_asm_len ("clr %A0"      CR_TAB
4743                                   "mov %B0,%A1"  CR_TAB
4744                                   "mov %C0,%B1", op, plen, 3);
4745           }
4746
4747         case 16:
4748           {
4749             int reg0 = REGNO (op[0]);
4750             int reg1 = REGNO (op[1]);
4751
4752             if (reg0 + 2 != reg1)
4753               avr_asm_len ("mov %C0,%A0", op, plen, 1);
4754             
4755             return avr_asm_len ("clr %B0"  CR_TAB
4756                                 "clr %A0", op, plen, 2);
4757           }
4758
4759         case 23:
4760           return avr_asm_len ("clr %C0" CR_TAB
4761                               "lsr %A0" CR_TAB
4762                               "ror %C0" CR_TAB
4763                               "clr %B0" CR_TAB
4764                               "clr %A0", op, plen, 5);
4765         }
4766     }
4767   
4768   out_shift_with_cnt ("lsl %A0" CR_TAB
4769                       "rol %B0" CR_TAB
4770                       "rol %C0", insn, op, plen, 3);
4771   return "";
4772 }
4773
4774
4775 /* 32bit shift left ((long)x << i)   */
4776
4777 const char *
4778 ashlsi3_out (rtx insn, rtx operands[], int *len)
4779 {
4780   if (GET_CODE (operands[2]) == CONST_INT)
4781     {
4782       int k;
4783       int *t = len;
4784       
4785       if (!len)
4786         len = &k;
4787       
4788       switch (INTVAL (operands[2]))
4789         {
4790         default:
4791           if (INTVAL (operands[2]) < 32)
4792             break;
4793
4794           if (AVR_HAVE_MOVW)
4795             return *len = 3, (AS1 (clr,%D0) CR_TAB
4796                               AS1 (clr,%C0) CR_TAB
4797                               AS2 (movw,%A0,%C0));
4798           *len = 4;
4799           return (AS1 (clr,%D0) CR_TAB
4800                   AS1 (clr,%C0) CR_TAB
4801                   AS1 (clr,%B0) CR_TAB
4802                   AS1 (clr,%A0));
4803
4804         case 8:
4805           {
4806             int reg0 = true_regnum (operands[0]);
4807             int reg1 = true_regnum (operands[1]);
4808             *len = 4;
4809             if (reg0 >= reg1)
4810               return (AS2 (mov,%D0,%C1)  CR_TAB
4811                       AS2 (mov,%C0,%B1)  CR_TAB
4812                       AS2 (mov,%B0,%A1)  CR_TAB
4813                       AS1 (clr,%A0));
4814             else
4815               return (AS1 (clr,%A0)      CR_TAB
4816                       AS2 (mov,%B0,%A1)  CR_TAB
4817                       AS2 (mov,%C0,%B1)  CR_TAB
4818                       AS2 (mov,%D0,%C1));
4819           }
4820
4821         case 16:
4822           {
4823             int reg0 = true_regnum (operands[0]);
4824             int reg1 = true_regnum (operands[1]);
4825             if (reg0 + 2 == reg1)
4826               return *len = 2, (AS1 (clr,%B0)      CR_TAB
4827                                 AS1 (clr,%A0));
4828             if (AVR_HAVE_MOVW)
4829               return *len = 3, (AS2 (movw,%C0,%A1) CR_TAB
4830                                 AS1 (clr,%B0)      CR_TAB
4831                                 AS1 (clr,%A0));
4832             else
4833               return *len = 4, (AS2 (mov,%C0,%A1)  CR_TAB
4834                                 AS2 (mov,%D0,%B1)  CR_TAB
4835                                 AS1 (clr,%B0)      CR_TAB
4836                                 AS1 (clr,%A0));
4837           }
4838
4839         case 24:
4840           *len = 4;
4841           return (AS2 (mov,%D0,%A1)  CR_TAB
4842                   AS1 (clr,%C0)      CR_TAB
4843                   AS1 (clr,%B0)      CR_TAB
4844                   AS1 (clr,%A0));
4845
4846         case 31:
4847           *len = 6;
4848           return (AS1 (clr,%D0) CR_TAB
4849                   AS1 (lsr,%A0) CR_TAB
4850                   AS1 (ror,%D0) CR_TAB
4851                   AS1 (clr,%C0) CR_TAB
4852                   AS1 (clr,%B0) CR_TAB
4853                   AS1 (clr,%A0));
4854         }
4855       len = t;
4856     }
4857   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
4858                        AS1 (rol,%B0) CR_TAB
4859                        AS1 (rol,%C0) CR_TAB
4860                        AS1 (rol,%D0)),
4861                        insn, operands, len, 4);
4862   return "";
4863 }
4864
4865 /* 8bit arithmetic shift right  ((signed char)x >> i) */
4866
4867 const char *
4868 ashrqi3_out (rtx insn, rtx operands[], int *len)
4869 {
4870   if (GET_CODE (operands[2]) == CONST_INT)
4871     {
4872       int k;
4873
4874       if (!len)
4875         len = &k;
4876
4877       switch (INTVAL (operands[2]))
4878         {
4879         case 1:
4880           *len = 1;
4881           return AS1 (asr,%0);
4882
4883         case 2:
4884           *len = 2;
4885           return (AS1 (asr,%0) CR_TAB
4886                   AS1 (asr,%0));
4887
4888         case 3:
4889           *len = 3;
4890           return (AS1 (asr,%0) CR_TAB
4891                   AS1 (asr,%0) CR_TAB
4892                   AS1 (asr,%0));
4893
4894         case 4:
4895           *len = 4;
4896           return (AS1 (asr,%0) CR_TAB
4897                   AS1 (asr,%0) CR_TAB
4898                   AS1 (asr,%0) CR_TAB
4899                   AS1 (asr,%0));
4900
4901         case 5:
4902           *len = 5;
4903           return (AS1 (asr,%0) CR_TAB
4904                   AS1 (asr,%0) CR_TAB
4905                   AS1 (asr,%0) CR_TAB
4906                   AS1 (asr,%0) CR_TAB
4907                   AS1 (asr,%0));
4908
4909         case 6:
4910           *len = 4;
4911           return (AS2 (bst,%0,6)  CR_TAB
4912                   AS1 (lsl,%0)    CR_TAB
4913                   AS2 (sbc,%0,%0) CR_TAB
4914                   AS2 (bld,%0,0));
4915
4916         default:
4917           if (INTVAL (operands[2]) < 8)
4918             break;
4919
4920           /* fall through */
4921
4922         case 7:
4923           *len = 2;
4924           return (AS1 (lsl,%0) CR_TAB
4925                   AS2 (sbc,%0,%0));
4926         }
4927     }
4928   else if (CONSTANT_P (operands[2]))
4929     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
4930
4931   out_shift_with_cnt (AS1 (asr,%0),
4932                       insn, operands, len, 1);
4933   return "";
4934 }
4935
4936
4937 /* 16bit arithmetic shift right  ((signed short)x >> i) */
4938
4939 const char *
4940 ashrhi3_out (rtx insn, rtx operands[], int *len)
4941 {
4942   if (GET_CODE (operands[2]) == CONST_INT)
4943     {
4944       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4945       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4946       int k;
4947       int *t = len;
4948       
4949       if (!len)
4950         len = &k;
4951
4952       switch (INTVAL (operands[2]))
4953         {
4954         case 4:
4955         case 5:
4956           /* XXX try to optimize this too? */
4957           break;
4958
4959         case 6:
4960           if (optimize_size)
4961             break;  /* scratch ? 5 : 6 */
4962           *len = 8;
4963           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
4964                   AS2 (mov,%A0,%B0)         CR_TAB
4965                   AS1 (lsl,__tmp_reg__)     CR_TAB
4966                   AS1 (rol,%A0)             CR_TAB
4967                   AS2 (sbc,%B0,%B0)         CR_TAB
4968                   AS1 (lsl,__tmp_reg__)     CR_TAB
4969                   AS1 (rol,%A0)             CR_TAB
4970                   AS1 (rol,%B0));
4971
4972         case 7:
4973           *len = 4;
4974           return (AS1 (lsl,%A0)     CR_TAB
4975                   AS2 (mov,%A0,%B0) CR_TAB
4976                   AS1 (rol,%A0)     CR_TAB
4977                   AS2 (sbc,%B0,%B0));
4978
4979         case 8:
4980           {
4981             int reg0 = true_regnum (operands[0]);
4982             int reg1 = true_regnum (operands[1]);
4983
4984             if (reg0 == reg1)
4985               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
4986                                 AS1 (lsl,%B0)     CR_TAB
4987                                 AS2 (sbc,%B0,%B0));
4988             else 
4989               return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
4990                                 AS1 (clr,%B0)     CR_TAB
4991                                 AS2 (sbrc,%A0,7)  CR_TAB
4992                                 AS1 (dec,%B0));
4993           }
4994
4995         case 9:
4996           *len = 4;
4997           return (AS2 (mov,%A0,%B0) CR_TAB
4998                   AS1 (lsl,%B0)      CR_TAB
4999                   AS2 (sbc,%B0,%B0) CR_TAB
5000                   AS1 (asr,%A0));
5001
5002         case 10:
5003           *len = 5;
5004           return (AS2 (mov,%A0,%B0) CR_TAB
5005                   AS1 (lsl,%B0)     CR_TAB
5006                   AS2 (sbc,%B0,%B0) CR_TAB
5007                   AS1 (asr,%A0)     CR_TAB
5008                   AS1 (asr,%A0));
5009
5010         case 11:
5011           if (AVR_HAVE_MUL && ldi_ok)
5012             {
5013               *len = 5;
5014               return (AS2 (ldi,%A0,0x20) CR_TAB
5015                       AS2 (muls,%B0,%A0) CR_TAB
5016                       AS2 (mov,%A0,r1)   CR_TAB
5017                       AS2 (sbc,%B0,%B0)  CR_TAB
5018                       AS1 (clr,__zero_reg__));
5019             }
5020           if (optimize_size && scratch)
5021             break;  /* 5 */
5022           *len = 6;
5023           return (AS2 (mov,%A0,%B0) CR_TAB
5024                   AS1 (lsl,%B0)     CR_TAB
5025                   AS2 (sbc,%B0,%B0) CR_TAB
5026                   AS1 (asr,%A0)     CR_TAB
5027                   AS1 (asr,%A0)     CR_TAB
5028                   AS1 (asr,%A0));
5029
5030         case 12:
5031           if (AVR_HAVE_MUL && ldi_ok)
5032             {
5033               *len = 5;
5034               return (AS2 (ldi,%A0,0x10) CR_TAB
5035                       AS2 (muls,%B0,%A0) CR_TAB
5036                       AS2 (mov,%A0,r1)   CR_TAB
5037                       AS2 (sbc,%B0,%B0)  CR_TAB
5038                       AS1 (clr,__zero_reg__));
5039             }
5040           if (optimize_size && scratch)
5041             break;  /* 5 */
5042           *len = 7;
5043           return (AS2 (mov,%A0,%B0) CR_TAB
5044                   AS1 (lsl,%B0)     CR_TAB
5045                   AS2 (sbc,%B0,%B0) CR_TAB
5046                   AS1 (asr,%A0)     CR_TAB
5047                   AS1 (asr,%A0)     CR_TAB
5048                   AS1 (asr,%A0)     CR_TAB
5049                   AS1 (asr,%A0));
5050
5051         case 13:
5052           if (AVR_HAVE_MUL && ldi_ok)
5053             {
5054               *len = 5;
5055               return (AS2 (ldi,%A0,0x08) CR_TAB
5056                       AS2 (muls,%B0,%A0) CR_TAB
5057                       AS2 (mov,%A0,r1)   CR_TAB
5058                       AS2 (sbc,%B0,%B0)  CR_TAB
5059                       AS1 (clr,__zero_reg__));
5060             }
5061           if (optimize_size)
5062             break;  /* scratch ? 5 : 7 */
5063           *len = 8;
5064           return (AS2 (mov,%A0,%B0) CR_TAB
5065                   AS1 (lsl,%B0)     CR_TAB
5066                   AS2 (sbc,%B0,%B0) CR_TAB
5067                   AS1 (asr,%A0)     CR_TAB
5068                   AS1 (asr,%A0)     CR_TAB
5069                   AS1 (asr,%A0)     CR_TAB
5070                   AS1 (asr,%A0)     CR_TAB
5071                   AS1 (asr,%A0));
5072
5073         case 14:
5074           *len = 5;
5075           return (AS1 (lsl,%B0)     CR_TAB
5076                   AS2 (sbc,%A0,%A0) CR_TAB
5077                   AS1 (lsl,%B0)     CR_TAB
5078                   AS2 (mov,%B0,%A0) CR_TAB
5079                   AS1 (rol,%A0));
5080
5081         default:
5082           if (INTVAL (operands[2]) < 16)
5083             break;
5084
5085           /* fall through */
5086
5087         case 15:
5088           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
5089                             AS2 (sbc,%A0,%A0) CR_TAB
5090                             AS2 (mov,%B0,%A0));
5091         }
5092       len = t;
5093     }
5094   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
5095                        AS1 (ror,%A0)),
5096                        insn, operands, len, 2);
5097   return "";
5098 }
5099
5100
5101 /* 24-bit arithmetic shift right */
5102
5103 const char*
5104 avr_out_ashrpsi3 (rtx insn, rtx *op, int *plen)
5105 {
5106   int dest = REGNO (op[0]);
5107   int src = REGNO (op[1]);
5108
5109   if (CONST_INT_P (op[2]))
5110     {
5111       if (plen)
5112         *plen = 0;
5113       
5114       switch (INTVAL (op[2]))
5115         {
5116         case 8:
5117           if (dest <= src)
5118             return avr_asm_len ("mov %A0,%B1" CR_TAB
5119                                 "mov %B0,%C1" CR_TAB
5120                                 "clr %C0"     CR_TAB
5121                                 "sbrc %B0,7"  CR_TAB
5122                                 "dec %C0", op, plen, 5);
5123           else
5124             return avr_asm_len ("clr %C0"     CR_TAB
5125                                 "sbrc %C1,7"  CR_TAB
5126                                 "dec %C0"     CR_TAB
5127                                 "mov %B0,%C1" CR_TAB
5128                                 "mov %A0,%B1", op, plen, 5);
5129           
5130         case 16:
5131           if (dest != src + 2)
5132             avr_asm_len ("mov %A0,%C1", op, plen, 1);
5133           
5134           return avr_asm_len ("clr %B0"     CR_TAB
5135                               "sbrc %A0,7"  CR_TAB
5136                               "com %B0"     CR_TAB
5137                               "mov %C0,%B0", op, plen, 4);
5138
5139         default:
5140           if (INTVAL (op[2]) < 24)
5141             break;
5142
5143           /* fall through */
5144
5145         case 31:
5146           return avr_asm_len ("lsl %C0"     CR_TAB
5147                               "sbc %A0,%A0" CR_TAB
5148                               "mov %B0,%A0" CR_TAB
5149                               "mov %C0,%A0", op, plen, 4);
5150         } /* switch */
5151     }
5152   
5153   out_shift_with_cnt ("asr %C0" CR_TAB
5154                       "ror %B0" CR_TAB
5155                       "ror %A0", insn, op, plen, 3);
5156   return "";
5157 }
5158
5159
5160 /* 32bit arithmetic shift right  ((signed long)x >> i) */
5161
5162 const char *
5163 ashrsi3_out (rtx insn, rtx operands[], int *len)
5164 {
5165   if (GET_CODE (operands[2]) == CONST_INT)
5166     {
5167       int k;
5168       int *t = len;
5169       
5170       if (!len)
5171         len = &k;
5172       
5173       switch (INTVAL (operands[2]))
5174         {
5175         case 8:
5176           {
5177             int reg0 = true_regnum (operands[0]);
5178             int reg1 = true_regnum (operands[1]);
5179             *len=6;
5180             if (reg0 <= reg1)
5181               return (AS2 (mov,%A0,%B1) CR_TAB
5182                       AS2 (mov,%B0,%C1) CR_TAB
5183                       AS2 (mov,%C0,%D1) CR_TAB
5184                       AS1 (clr,%D0)     CR_TAB
5185                       AS2 (sbrc,%C0,7)  CR_TAB
5186                       AS1 (dec,%D0));
5187             else
5188               return (AS1 (clr,%D0)     CR_TAB
5189                       AS2 (sbrc,%D1,7)  CR_TAB
5190                       AS1 (dec,%D0)     CR_TAB
5191                       AS2 (mov,%C0,%D1) CR_TAB
5192                       AS2 (mov,%B0,%C1) CR_TAB
5193                       AS2 (mov,%A0,%B1));
5194           }
5195           
5196         case 16:
5197           {
5198             int reg0 = true_regnum (operands[0]);
5199             int reg1 = true_regnum (operands[1]);
5200             
5201             if (reg0 == reg1 + 2)
5202               return *len = 4, (AS1 (clr,%D0)     CR_TAB
5203                                 AS2 (sbrc,%B0,7)  CR_TAB
5204                                 AS1 (com,%D0)     CR_TAB
5205                                 AS2 (mov,%C0,%D0));
5206             if (AVR_HAVE_MOVW)
5207               return *len = 5, (AS2 (movw,%A0,%C1) CR_TAB
5208                                 AS1 (clr,%D0)      CR_TAB
5209                                 AS2 (sbrc,%B0,7)   CR_TAB
5210                                 AS1 (com,%D0)      CR_TAB
5211                                 AS2 (mov,%C0,%D0));
5212             else 
5213               return *len = 6, (AS2 (mov,%B0,%D1) CR_TAB
5214                                 AS2 (mov,%A0,%C1) CR_TAB
5215                                 AS1 (clr,%D0)     CR_TAB
5216                                 AS2 (sbrc,%B0,7)  CR_TAB
5217                                 AS1 (com,%D0)     CR_TAB
5218                                 AS2 (mov,%C0,%D0));
5219           }
5220
5221         case 24:
5222           return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
5223                             AS1 (clr,%D0)     CR_TAB
5224                             AS2 (sbrc,%A0,7)  CR_TAB
5225                             AS1 (com,%D0)     CR_TAB
5226                             AS2 (mov,%B0,%D0) CR_TAB
5227                             AS2 (mov,%C0,%D0));
5228
5229         default:
5230           if (INTVAL (operands[2]) < 32)
5231             break;
5232
5233           /* fall through */
5234
5235         case 31:
5236           if (AVR_HAVE_MOVW)
5237             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
5238                               AS2 (sbc,%A0,%A0) CR_TAB
5239                               AS2 (mov,%B0,%A0) CR_TAB
5240                               AS2 (movw,%C0,%A0));
5241           else
5242             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
5243                               AS2 (sbc,%A0,%A0) CR_TAB
5244                               AS2 (mov,%B0,%A0) CR_TAB
5245                               AS2 (mov,%C0,%A0) CR_TAB
5246                               AS2 (mov,%D0,%A0));
5247         }
5248       len = t;
5249     }
5250   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
5251                        AS1 (ror,%C0) CR_TAB
5252                        AS1 (ror,%B0) CR_TAB
5253                        AS1 (ror,%A0)),
5254                        insn, operands, len, 4);
5255   return "";
5256 }
5257
5258 /* 8bit logic shift right ((unsigned char)x >> i) */
5259
5260 const char *
5261 lshrqi3_out (rtx insn, rtx operands[], int *len)
5262 {
5263   if (GET_CODE (operands[2]) == CONST_INT)
5264     {
5265       int k;
5266
5267       if (!len)
5268         len = &k;
5269       
5270       switch (INTVAL (operands[2]))
5271         {
5272         default:
5273           if (INTVAL (operands[2]) < 8)
5274             break;
5275
5276           *len = 1;
5277           return AS1 (clr,%0);
5278
5279         case 1:
5280           *len = 1;
5281           return AS1 (lsr,%0);
5282
5283         case 2:
5284           *len = 2;
5285           return (AS1 (lsr,%0) CR_TAB
5286                   AS1 (lsr,%0));
5287         case 3:
5288           *len = 3;
5289           return (AS1 (lsr,%0) CR_TAB
5290                   AS1 (lsr,%0) CR_TAB
5291                   AS1 (lsr,%0));
5292           
5293         case 4:
5294           if (test_hard_reg_class (LD_REGS, operands[0]))
5295             {
5296               *len=2;
5297               return (AS1 (swap,%0) CR_TAB
5298                       AS2 (andi,%0,0x0f));
5299             }
5300           *len = 4;
5301           return (AS1 (lsr,%0) CR_TAB
5302                   AS1 (lsr,%0) CR_TAB
5303                   AS1 (lsr,%0) CR_TAB
5304                   AS1 (lsr,%0));
5305           
5306         case 5:
5307           if (test_hard_reg_class (LD_REGS, operands[0]))
5308             {
5309               *len = 3;
5310               return (AS1 (swap,%0) CR_TAB
5311                       AS1 (lsr,%0)  CR_TAB
5312                       AS2 (andi,%0,0x7));
5313             }
5314           *len = 5;
5315           return (AS1 (lsr,%0) CR_TAB
5316                   AS1 (lsr,%0) CR_TAB
5317                   AS1 (lsr,%0) CR_TAB
5318                   AS1 (lsr,%0) CR_TAB
5319                   AS1 (lsr,%0));
5320           
5321         case 6:
5322           if (test_hard_reg_class (LD_REGS, operands[0]))
5323             {
5324               *len = 4;
5325               return (AS1 (swap,%0) CR_TAB
5326                       AS1 (lsr,%0)  CR_TAB
5327                       AS1 (lsr,%0)  CR_TAB
5328                       AS2 (andi,%0,0x3));
5329             }
5330           *len = 6;
5331           return (AS1 (lsr,%0) CR_TAB
5332                   AS1 (lsr,%0) CR_TAB
5333                   AS1 (lsr,%0) CR_TAB
5334                   AS1 (lsr,%0) CR_TAB
5335                   AS1 (lsr,%0) CR_TAB
5336                   AS1 (lsr,%0));
5337           
5338         case 7:
5339           *len = 3;
5340           return (AS1 (rol,%0) CR_TAB
5341                   AS1 (clr,%0) CR_TAB
5342                   AS1 (rol,%0));
5343         }
5344     }
5345   else if (CONSTANT_P (operands[2]))
5346     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
5347   
5348   out_shift_with_cnt (AS1 (lsr,%0),
5349                       insn, operands, len, 1);
5350   return "";
5351 }
5352
5353 /* 16bit logic shift right ((unsigned short)x >> i) */
5354
5355 const char *
5356 lshrhi3_out (rtx insn, rtx operands[], int *len)
5357 {
5358   if (GET_CODE (operands[2]) == CONST_INT)
5359     {
5360       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5361       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5362       int k;
5363       int *t = len;
5364
5365       if (!len)
5366         len = &k;
5367       
5368       switch (INTVAL (operands[2]))
5369         {
5370         default:
5371           if (INTVAL (operands[2]) < 16)
5372             break;
5373
5374           *len = 2;
5375           return (AS1 (clr,%B0) CR_TAB
5376                   AS1 (clr,%A0));
5377
5378         case 4:
5379           if (optimize_size && scratch)
5380             break;  /* 5 */
5381           if (ldi_ok)
5382             {
5383               *len = 6;
5384               return (AS1 (swap,%B0)      CR_TAB
5385                       AS1 (swap,%A0)      CR_TAB
5386                       AS2 (andi,%A0,0x0f) CR_TAB
5387                       AS2 (eor,%A0,%B0)   CR_TAB
5388                       AS2 (andi,%B0,0x0f) CR_TAB
5389                       AS2 (eor,%A0,%B0));
5390             }
5391           if (scratch)
5392             {
5393               *len = 7;
5394               return (AS1 (swap,%B0)    CR_TAB
5395                       AS1 (swap,%A0)    CR_TAB
5396                       AS2 (ldi,%3,0x0f) CR_TAB
5397                       "and %A0,%3"      CR_TAB
5398                       AS2 (eor,%A0,%B0) CR_TAB
5399                       "and %B0,%3"      CR_TAB
5400                       AS2 (eor,%A0,%B0));
5401             }
5402           break;  /* optimize_size ? 6 : 8 */
5403
5404         case 5:
5405           if (optimize_size)
5406             break;  /* scratch ? 5 : 6 */
5407           if (ldi_ok)
5408             {
5409               *len = 8;
5410               return (AS1 (lsr,%B0)       CR_TAB
5411                       AS1 (ror,%A0)       CR_TAB
5412                       AS1 (swap,%B0)      CR_TAB
5413                       AS1 (swap,%A0)      CR_TAB
5414                       AS2 (andi,%A0,0x0f) CR_TAB
5415                       AS2 (eor,%A0,%B0)   CR_TAB
5416                       AS2 (andi,%B0,0x0f) CR_TAB
5417                       AS2 (eor,%A0,%B0));
5418             }
5419           if (scratch)
5420             {
5421               *len = 9;
5422               return (AS1 (lsr,%B0)     CR_TAB
5423                       AS1 (ror,%A0)     CR_TAB
5424                       AS1 (swap,%B0)    CR_TAB
5425                       AS1 (swap,%A0)    CR_TAB
5426                       AS2 (ldi,%3,0x0f) CR_TAB
5427                       "and %A0,%3"      CR_TAB
5428                       AS2 (eor,%A0,%B0) CR_TAB
5429                       "and %B0,%3"      CR_TAB
5430                       AS2 (eor,%A0,%B0));
5431             }
5432           break;  /* 10 */
5433
5434         case 6:
5435           if (optimize_size)
5436             break;  /* scratch ? 5 : 6 */
5437           *len = 9;
5438           return (AS1 (clr,__tmp_reg__) CR_TAB
5439                   AS1 (lsl,%A0)         CR_TAB
5440                   AS1 (rol,%B0)         CR_TAB
5441                   AS1 (rol,__tmp_reg__) CR_TAB
5442                   AS1 (lsl,%A0)         CR_TAB
5443                   AS1 (rol,%B0)         CR_TAB
5444                   AS1 (rol,__tmp_reg__) CR_TAB
5445                   AS2 (mov,%A0,%B0)     CR_TAB
5446                   AS2 (mov,%B0,__tmp_reg__));
5447
5448         case 7:
5449           *len = 5;
5450           return (AS1 (lsl,%A0)     CR_TAB
5451                   AS2 (mov,%A0,%B0) CR_TAB
5452                   AS1 (rol,%A0)     CR_TAB
5453                   AS2 (sbc,%B0,%B0) CR_TAB
5454                   AS1 (neg,%B0));
5455
5456         case 8:
5457           return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
5458                             AS1 (clr,%B0));
5459
5460         case 9:
5461           *len = 3;
5462           return (AS2 (mov,%A0,%B0) CR_TAB
5463                   AS1 (clr,%B0)     CR_TAB
5464                   AS1 (lsr,%A0));
5465
5466         case 10:
5467           *len = 4;
5468           return (AS2 (mov,%A0,%B0) CR_TAB
5469                   AS1 (clr,%B0)     CR_TAB
5470                   AS1 (lsr,%A0)     CR_TAB
5471                   AS1 (lsr,%A0));
5472
5473         case 11:
5474           *len = 5;
5475           return (AS2 (mov,%A0,%B0) CR_TAB
5476                   AS1 (clr,%B0)     CR_TAB
5477                   AS1 (lsr,%A0)     CR_TAB
5478                   AS1 (lsr,%A0)     CR_TAB
5479                   AS1 (lsr,%A0));
5480
5481         case 12:
5482           if (ldi_ok)
5483             {
5484               *len = 4;
5485               return (AS2 (mov,%A0,%B0) CR_TAB
5486                       AS1 (clr,%B0)     CR_TAB
5487                       AS1 (swap,%A0)    CR_TAB
5488                       AS2 (andi,%A0,0x0f));
5489             }
5490           if (scratch)
5491             {
5492               *len = 5;
5493               return (AS2 (mov,%A0,%B0) CR_TAB
5494                       AS1 (clr,%B0)     CR_TAB
5495                       AS1 (swap,%A0)    CR_TAB
5496                       AS2 (ldi,%3,0x0f) CR_TAB
5497                       "and %A0,%3");
5498             }
5499           *len = 6;
5500           return (AS2 (mov,%A0,%B0) CR_TAB
5501                   AS1 (clr,%B0)     CR_TAB
5502                   AS1 (lsr,%A0)     CR_TAB
5503                   AS1 (lsr,%A0)     CR_TAB
5504                   AS1 (lsr,%A0)     CR_TAB
5505                   AS1 (lsr,%A0));
5506
5507         case 13:
5508           if (ldi_ok)
5509             {
5510               *len = 5;
5511               return (AS2 (mov,%A0,%B0) CR_TAB
5512                       AS1 (clr,%B0)     CR_TAB
5513                       AS1 (swap,%A0)    CR_TAB
5514                       AS1 (lsr,%A0)     CR_TAB
5515                       AS2 (andi,%A0,0x07));
5516             }
5517           if (AVR_HAVE_MUL && scratch)
5518             {
5519               *len = 5;
5520               return (AS2 (ldi,%3,0x08) CR_TAB
5521                       AS2 (mul,%B0,%3)  CR_TAB
5522                       AS2 (mov,%A0,r1)  CR_TAB
5523                       AS1 (clr,%B0)     CR_TAB
5524                       AS1 (clr,__zero_reg__));
5525             }
5526           if (optimize_size && scratch)
5527             break;  /* 5 */
5528           if (scratch)
5529             {
5530               *len = 6;
5531               return (AS2 (mov,%A0,%B0) CR_TAB
5532                       AS1 (clr,%B0)     CR_TAB
5533                       AS1 (swap,%A0)    CR_TAB
5534                       AS1 (lsr,%A0)     CR_TAB
5535                       AS2 (ldi,%3,0x07) CR_TAB
5536                       "and %A0,%3");
5537             }
5538           if (AVR_HAVE_MUL)
5539             {
5540               *len = 6;
5541               return ("set"            CR_TAB
5542                       AS2 (bld,r1,3)   CR_TAB
5543                       AS2 (mul,%B0,r1) CR_TAB
5544                       AS2 (mov,%A0,r1) CR_TAB
5545                       AS1 (clr,%B0)    CR_TAB
5546                       AS1 (clr,__zero_reg__));
5547             }
5548           *len = 7;
5549           return (AS2 (mov,%A0,%B0) CR_TAB
5550                   AS1 (clr,%B0)     CR_TAB
5551                   AS1 (lsr,%A0)     CR_TAB
5552                   AS1 (lsr,%A0)     CR_TAB
5553                   AS1 (lsr,%A0)     CR_TAB
5554                   AS1 (lsr,%A0)     CR_TAB
5555                   AS1 (lsr,%A0));
5556
5557         case 14:
5558           if (AVR_HAVE_MUL && ldi_ok)
5559             {
5560               *len = 5;
5561               return (AS2 (ldi,%A0,0x04) CR_TAB
5562                       AS2 (mul,%B0,%A0)  CR_TAB
5563                       AS2 (mov,%A0,r1)   CR_TAB
5564                       AS1 (clr,%B0)      CR_TAB
5565                       AS1 (clr,__zero_reg__));
5566             }
5567           if (AVR_HAVE_MUL && scratch)
5568             {
5569               *len = 5;
5570               return (AS2 (ldi,%3,0x04) CR_TAB
5571                       AS2 (mul,%B0,%3)  CR_TAB
5572                       AS2 (mov,%A0,r1)  CR_TAB
5573                       AS1 (clr,%B0)     CR_TAB
5574                       AS1 (clr,__zero_reg__));
5575             }
5576           if (optimize_size && ldi_ok)
5577             {
5578               *len = 5;
5579               return (AS2 (mov,%A0,%B0) CR_TAB
5580                       AS2 (ldi,%B0,6) "\n1:\t"
5581                       AS1 (lsr,%A0)     CR_TAB
5582                       AS1 (dec,%B0)     CR_TAB
5583                       AS1 (brne,1b));
5584             }
5585           if (optimize_size && scratch)
5586             break;  /* 5 */
5587           *len = 6;
5588           return (AS1 (clr,%A0) CR_TAB
5589                   AS1 (lsl,%B0) CR_TAB
5590                   AS1 (rol,%A0) CR_TAB
5591                   AS1 (lsl,%B0) CR_TAB
5592                   AS1 (rol,%A0) CR_TAB
5593                   AS1 (clr,%B0));
5594
5595         case 15:
5596           *len = 4;
5597           return (AS1 (clr,%A0) CR_TAB
5598                   AS1 (lsl,%B0) CR_TAB
5599                   AS1 (rol,%A0) CR_TAB
5600                   AS1 (clr,%B0));
5601         }
5602       len = t;
5603     }
5604   out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
5605                        AS1 (ror,%A0)),
5606                        insn, operands, len, 2);
5607   return "";
5608 }
5609
5610
5611 /* 24-bit logic shift right */
5612
5613 const char*
5614 avr_out_lshrpsi3 (rtx insn, rtx *op, int *plen)
5615 {
5616   int dest = REGNO (op[0]);
5617   int src = REGNO (op[1]);
5618
5619   if (CONST_INT_P (op[2]))
5620     {
5621       if (plen)
5622         *plen = 0;
5623       
5624       switch (INTVAL (op[2]))
5625         {
5626         case 8:
5627           if (dest <= src)
5628             return avr_asm_len ("mov %A0,%B1" CR_TAB
5629                                 "mov %B0,%C1" CR_TAB
5630                                 "clr %C0", op, plen, 3);
5631           else
5632             return avr_asm_len ("clr %C0"     CR_TAB
5633                                 "mov %B0,%C1" CR_TAB
5634                                 "mov %A0,%B1", op, plen, 3);
5635           
5636         case 16:
5637           if (dest != src + 2)
5638             avr_asm_len ("mov %A0,%C1", op, plen, 1);
5639           
5640           return avr_asm_len ("clr %B0"  CR_TAB
5641                               "clr %C0", op, plen, 2);
5642
5643         default:
5644           if (INTVAL (op[2]) < 24)
5645             break;
5646
5647           /* fall through */
5648
5649         case 23:
5650           return avr_asm_len ("clr %A0"    CR_TAB
5651                               "sbrc %C0,7" CR_TAB
5652                               "inc %A0"    CR_TAB
5653                               "clr %B0"    CR_TAB
5654                               "clr %C0", op, plen, 5);
5655         } /* switch */
5656     }
5657   
5658   out_shift_with_cnt ("lsr %C0" CR_TAB
5659                       "ror %B0" CR_TAB
5660                       "ror %A0", insn, op, plen, 3);
5661   return "";
5662 }
5663
5664
5665 /* 32bit logic shift right ((unsigned int)x >> i) */
5666
5667 const char *
5668 lshrsi3_out (rtx insn, rtx operands[], int *len)
5669 {
5670   if (GET_CODE (operands[2]) == CONST_INT)
5671     {
5672       int k;
5673       int *t = len;
5674       
5675       if (!len)
5676         len = &k;
5677       
5678       switch (INTVAL (operands[2]))
5679         {
5680         default:
5681           if (INTVAL (operands[2]) < 32)
5682             break;
5683
5684           if (AVR_HAVE_MOVW)
5685             return *len = 3, (AS1 (clr,%D0) CR_TAB
5686                               AS1 (clr,%C0) CR_TAB
5687                               AS2 (movw,%A0,%C0));
5688           *len = 4;
5689           return (AS1 (clr,%D0) CR_TAB
5690                   AS1 (clr,%C0) CR_TAB
5691                   AS1 (clr,%B0) CR_TAB
5692                   AS1 (clr,%A0));
5693
5694         case 8:
5695           {
5696             int reg0 = true_regnum (operands[0]);
5697             int reg1 = true_regnum (operands[1]);
5698             *len = 4;
5699             if (reg0 <= reg1)
5700               return (AS2 (mov,%A0,%B1) CR_TAB
5701                       AS2 (mov,%B0,%C1) CR_TAB
5702                       AS2 (mov,%C0,%D1) CR_TAB
5703                       AS1 (clr,%D0));
5704             else
5705               return (AS1 (clr,%D0)     CR_TAB
5706                       AS2 (mov,%C0,%D1) CR_TAB
5707                       AS2 (mov,%B0,%C1) CR_TAB
5708                       AS2 (mov,%A0,%B1)); 
5709           }
5710           
5711         case 16:
5712           {
5713             int reg0 = true_regnum (operands[0]);
5714             int reg1 = true_regnum (operands[1]);
5715
5716             if (reg0 == reg1 + 2)
5717               return *len = 2, (AS1 (clr,%C0)     CR_TAB
5718                                 AS1 (clr,%D0));
5719             if (AVR_HAVE_MOVW)
5720               return *len = 3, (AS2 (movw,%A0,%C1) CR_TAB
5721                                 AS1 (clr,%C0)      CR_TAB
5722                                 AS1 (clr,%D0));
5723             else
5724               return *len = 4, (AS2 (mov,%B0,%D1) CR_TAB
5725                                 AS2 (mov,%A0,%C1) CR_TAB
5726                                 AS1 (clr,%C0)     CR_TAB
5727                                 AS1 (clr,%D0));
5728           }
5729           
5730         case 24:
5731           return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
5732                             AS1 (clr,%B0)     CR_TAB
5733                             AS1 (clr,%C0)     CR_TAB
5734                             AS1 (clr,%D0));
5735
5736         case 31:
5737           *len = 6;
5738           return (AS1 (clr,%A0)    CR_TAB
5739                   AS2 (sbrc,%D0,7) CR_TAB
5740                   AS1 (inc,%A0)    CR_TAB
5741                   AS1 (clr,%B0)    CR_TAB
5742                   AS1 (clr,%C0)    CR_TAB
5743                   AS1 (clr,%D0));
5744         }
5745       len = t;
5746     }
5747   out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
5748                        AS1 (ror,%C0) CR_TAB
5749                        AS1 (ror,%B0) CR_TAB
5750                        AS1 (ror,%A0)),
5751                       insn, operands, len, 4);
5752   return "";
5753 }
5754
5755
5756 /* Output addition of register XOP[0] and compile time constant XOP[2]:
5757
5758       XOP[0] = XOP[0] + XOP[2]
5759
5760    and return "".  If PLEN == NULL, print assembler instructions to perform the
5761    addition; otherwise, set *PLEN to the length of the instruction sequence (in
5762    words) printed with PLEN == NULL.  XOP[3] is an 8-bit scratch register.
5763    CODE == PLUS:  perform addition by using ADD instructions.
5764    CODE == MINUS: perform addition by using SUB instructions.
5765    Set *PCC to effect on cc0 according to respective CC_* insn attribute.  */
5766
5767 static void
5768 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc)
5769 {
5770   /* MODE of the operation.  */
5771   enum machine_mode mode = GET_MODE (xop[0]);
5772
5773   /* Number of bytes to operate on.  */
5774   int i, n_bytes = GET_MODE_SIZE (mode);
5775
5776   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
5777   int clobber_val = -1;
5778
5779   /* op[0]: 8-bit destination register
5780      op[1]: 8-bit const int
5781      op[2]: 8-bit scratch register */
5782   rtx op[3];
5783
5784   /* Started the operation?  Before starting the operation we may skip
5785      adding 0.  This is no more true after the operation started because
5786      carry must be taken into account.  */
5787   bool started = false;
5788
5789   /* Value to add.  There are two ways to add VAL: R += VAL and R -= -VAL.  */
5790   rtx xval = xop[2];
5791
5792   /* Except in the case of ADIW with 16-bit register (see below)
5793      addition does not set cc0 in a usable way.  */
5794   
5795   *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
5796
5797   if (MINUS == code)
5798     xval = gen_int_mode (-UINTVAL (xval), mode);
5799
5800   op[2] = xop[3];
5801
5802   if (plen)
5803     *plen = 0;
5804
5805   for (i = 0; i < n_bytes; i++)
5806     {
5807       /* We operate byte-wise on the destination.  */
5808       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
5809       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
5810
5811       /* 8-bit value to operate with this byte. */
5812       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
5813
5814       /* Registers R16..R31 can operate with immediate.  */
5815       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
5816
5817       op[0] = reg8;
5818       op[1] = gen_int_mode (val8, QImode);
5819
5820       /* To get usable cc0 no low-bytes must have been skipped.  */
5821       
5822       if (i && !started)
5823         *pcc = CC_CLOBBER;
5824       
5825       if (!started
5826           && i % 2 == 0
5827           && i + 2 <= n_bytes
5828           && test_hard_reg_class (ADDW_REGS, reg8))
5829         {
5830           rtx xval16 = simplify_gen_subreg (HImode, xval, mode, i);
5831           unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
5832
5833           /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
5834              i.e. operate word-wise.  */
5835
5836           if (val16 < 64)
5837             {
5838               if (val16 != 0)
5839                 {
5840                   started = true;
5841                   avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
5842                                op, plen, 1);
5843
5844                   if (n_bytes == 2 && PLUS == code)
5845                       *pcc = CC_SET_ZN;
5846                 }
5847
5848               i++;
5849               continue;
5850             }
5851         }
5852
5853       if (val8 == 0)
5854         {
5855           if (started)
5856             avr_asm_len (code == PLUS
5857                          ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
5858                          op, plen, 1);
5859           continue;
5860         }
5861       else if ((val8 == 1 || val8 == 0xff)
5862                && !started
5863                && i == n_bytes - 1)
5864         {
5865           avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
5866                        op, plen, 1);
5867           break;
5868         }
5869
5870       switch (code)
5871         {
5872         case PLUS:
5873
5874           gcc_assert (plen != NULL || REG_P (op[2]));
5875
5876           if (clobber_val != (int) val8)
5877             avr_asm_len ("ldi %2,%1", op, plen, 1);
5878           clobber_val = (int) val8;
5879               
5880           avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
5881
5882           break; /* PLUS */
5883
5884         case MINUS:
5885
5886           if (ld_reg_p)
5887             avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
5888           else
5889             {
5890               gcc_assert (plen != NULL || REG_P (op[2]));
5891
5892               if (clobber_val != (int) val8)
5893                 avr_asm_len ("ldi %2,%1", op, plen, 1);
5894               clobber_val = (int) val8;
5895               
5896               avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
5897             }
5898
5899           break; /* MINUS */
5900           
5901         default:
5902           /* Unknown code */
5903           gcc_unreachable();
5904         }
5905
5906       started = true;
5907
5908     } /* for all sub-bytes */
5909
5910   /* No output doesn't change cc0.  */
5911   
5912   if (plen && *plen == 0)
5913     *pcc = CC_NONE;
5914 }
5915
5916
5917 /* Output addition of register XOP[0] and compile time constant XOP[2]:
5918
5919       XOP[0] = XOP[0] + XOP[2]
5920
5921    and return "".  If PLEN == NULL, print assembler instructions to perform the
5922    addition; otherwise, set *PLEN to the length of the instruction sequence (in
5923    words) printed with PLEN == NULL.
5924    If PCC != 0 then set *PCC to the the instruction sequence's effect on the
5925    condition code (with respect to XOP[0]).  */
5926
5927 const char*
5928 avr_out_plus (rtx *xop, int *plen, int *pcc)
5929 {
5930   int len_plus, len_minus;
5931   int cc_plus, cc_minus, cc_dummy;
5932
5933   if (!pcc)
5934     pcc = &cc_dummy;
5935                                    
5936   /* Work out if  XOP[0] += XOP[2]  is better or  XOP[0] -= -XOP[2].  */
5937   
5938   avr_out_plus_1 (xop, &len_plus, PLUS, &cc_plus);
5939   avr_out_plus_1 (xop, &len_minus, MINUS, &cc_minus);
5940
5941   /* Prefer MINUS over PLUS if size is equal because it sets cc0.  */
5942   
5943   if (plen)
5944     {
5945       *plen = (len_minus <= len_plus) ? len_minus : len_plus;
5946       *pcc  = (len_minus <= len_plus) ? cc_minus : cc_plus;
5947     }
5948   else if (len_minus <= len_plus)
5949     avr_out_plus_1 (xop, NULL, MINUS, pcc);
5950   else
5951     avr_out_plus_1 (xop, NULL, PLUS, pcc);
5952
5953   return "";
5954 }
5955
5956
5957 /* Same as above but XOP has just 3 entries.
5958    Supply a dummy 4th operand.  */
5959
5960 const char*
5961 avr_out_plus_noclobber (rtx *xop, int *plen, int *pcc)
5962 {
5963   rtx op[4];
5964
5965   op[0] = xop[0];
5966   op[1] = xop[1];
5967   op[2] = xop[2];
5968   op[3] = NULL_RTX;
5969
5970   return avr_out_plus (op, plen, pcc);
5971 }
5972
5973 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
5974    time constant XOP[2]:
5975
5976       XOP[0] = XOP[0] <op> XOP[2]
5977
5978    and return "".  If PLEN == NULL, print assembler instructions to perform the
5979    operation; otherwise, set *PLEN to the length of the instruction sequence
5980    (in words) printed with PLEN == NULL.  XOP[3] is either an 8-bit clobber
5981    register or SCRATCH if no clobber register is needed for the operation.  */
5982
5983 const char*
5984 avr_out_bitop (rtx insn, rtx *xop, int *plen)
5985 {
5986   /* CODE and MODE of the operation.  */
5987   enum rtx_code code = GET_CODE (SET_SRC (single_set (insn)));
5988   enum machine_mode mode = GET_MODE (xop[0]);
5989
5990   /* Number of bytes to operate on.  */
5991   int i, n_bytes = GET_MODE_SIZE (mode);
5992
5993   /* Value of T-flag (0 or 1) or -1 if unknow.  */
5994   int set_t = -1;
5995
5996   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
5997   int clobber_val = -1;
5998
5999   /* op[0]: 8-bit destination register
6000      op[1]: 8-bit const int
6001      op[2]: 8-bit clobber register or SCRATCH
6002      op[3]: 8-bit register containing 0xff or NULL_RTX  */
6003   rtx op[4];
6004
6005   op[2] = xop[3];
6006   op[3] = NULL_RTX;
6007
6008   if (plen)
6009     *plen = 0;
6010
6011   for (i = 0; i < n_bytes; i++)
6012     {
6013       /* We operate byte-wise on the destination.  */
6014       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
6015       rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
6016
6017       /* 8-bit value to operate with this byte. */
6018       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
6019
6020       /* Number of bits set in the current byte of the constant.  */
6021       int pop8 = avr_popcount (val8);
6022
6023       /* Registers R16..R31 can operate with immediate.  */
6024       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
6025
6026       op[0] = reg8;
6027       op[1] = GEN_INT (val8);
6028     
6029       switch (code)
6030         {
6031         case IOR:
6032
6033           if (0 == pop8)
6034             continue;
6035           else if (ld_reg_p)
6036             avr_asm_len ("ori %0,%1", op, plen, 1);
6037           else if (1 == pop8)
6038             {
6039               if (set_t != 1)
6040                 avr_asm_len ("set", op, plen, 1);
6041               set_t = 1;
6042               
6043               op[1] = GEN_INT (exact_log2 (val8));
6044               avr_asm_len ("bld %0,%1", op, plen, 1);
6045             }
6046           else if (8 == pop8)
6047             {
6048               if (op[3] != NULL_RTX)
6049                 avr_asm_len ("mov %0,%3", op, plen, 1);
6050               else
6051                 avr_asm_len ("clr %0" CR_TAB
6052                              "dec %0", op, plen, 2);
6053
6054               op[3] = op[0];
6055             }
6056           else
6057             {
6058               if (clobber_val != (int) val8)
6059                 avr_asm_len ("ldi %2,%1", op, plen, 1);
6060               clobber_val = (int) val8;
6061               
6062               avr_asm_len ("or %0,%2", op, plen, 1);
6063             }
6064
6065           continue; /* IOR */
6066
6067         case AND:
6068
6069           if (8 == pop8)
6070             continue;
6071           else if (0 == pop8)
6072             avr_asm_len ("clr %0", op, plen, 1);
6073           else if (ld_reg_p)
6074             avr_asm_len ("andi %0,%1", op, plen, 1);
6075           else if (7 == pop8)
6076             {
6077               if (set_t != 0)
6078                 avr_asm_len ("clt", op, plen, 1);
6079               set_t = 0;
6080               
6081               op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
6082               avr_asm_len ("bld %0,%1", op, plen, 1);
6083             }
6084           else
6085             {
6086               if (clobber_val != (int) val8)
6087                 avr_asm_len ("ldi %2,%1", op, plen, 1);
6088               clobber_val = (int) val8;
6089               
6090               avr_asm_len ("and %0,%2", op, plen, 1);
6091             }
6092
6093           continue; /* AND */
6094           
6095         case XOR:
6096
6097           if (0 == pop8)
6098             continue;
6099           else if (8 == pop8)
6100             avr_asm_len ("com %0", op, plen, 1);
6101           else if (ld_reg_p && val8 == (1 << 7))
6102             avr_asm_len ("subi %0,%1", op, plen, 1);
6103           else
6104             {
6105               if (clobber_val != (int) val8)
6106                 avr_asm_len ("ldi %2,%1", op, plen, 1);
6107               clobber_val = (int) val8;
6108               
6109               avr_asm_len ("eor %0,%2", op, plen, 1);
6110             }
6111
6112           continue; /* XOR */
6113           
6114         default:
6115           /* Unknown rtx_code */
6116           gcc_unreachable();
6117         }
6118     } /* for all sub-bytes */
6119
6120   return "";
6121 }
6122
6123
6124 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
6125    PLEN != NULL: Set *PLEN to the length of that sequence.
6126    Return "".  */
6127
6128 const char*
6129 avr_out_addto_sp (rtx *op, int *plen)
6130 {
6131   int pc_len = AVR_2_BYTE_PC ? 2 : 3;
6132   int addend = INTVAL (op[0]);
6133
6134   if (plen)
6135     *plen = 0;
6136
6137   if (addend < 0)
6138     {
6139       if (flag_verbose_asm || flag_print_asm_name)
6140         avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
6141   
6142       while (addend <= -pc_len)
6143         {
6144           addend += pc_len;
6145           avr_asm_len ("rcall .", op, plen, 1);
6146         }
6147
6148       while (addend++ < 0)
6149         avr_asm_len ("push __zero_reg__", op, plen, 1);
6150     }
6151   else if (addend > 0)
6152     {
6153       if (flag_verbose_asm || flag_print_asm_name)
6154         avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
6155
6156       while (addend-- > 0)
6157         avr_asm_len ("pop __tmp_reg__", op, plen, 1);
6158     }
6159
6160   return "";
6161 }
6162
6163
6164 /* Create RTL split patterns for byte sized rotate expressions.  This
6165   produces a series of move instructions and considers overlap situations.
6166   Overlapping non-HImode operands need a scratch register.  */
6167
6168 bool
6169 avr_rotate_bytes (rtx operands[])
6170 {
6171     int i, j;
6172     enum machine_mode mode = GET_MODE (operands[0]);
6173     bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
6174     bool same_reg = rtx_equal_p (operands[0], operands[1]);
6175     int num = INTVAL (operands[2]);
6176     rtx scratch = operands[3];
6177     /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
6178        Word move if no scratch is needed, otherwise use size of scratch.  */
6179     enum machine_mode move_mode = QImode;
6180     int move_size, offset, size;
6181
6182     if (num & 0xf)
6183       move_mode = QImode;
6184     else if ((mode == SImode && !same_reg) || !overlapped)
6185       move_mode = HImode;
6186     else
6187       move_mode = GET_MODE (scratch);
6188
6189     /* Force DI rotate to use QI moves since other DI moves are currently split
6190        into QI moves so forward propagation works better.  */
6191     if (mode == DImode)
6192       move_mode = QImode;
6193     /* Make scratch smaller if needed.  */
6194     if (SCRATCH != GET_CODE (scratch)
6195         && HImode == GET_MODE (scratch)
6196         && QImode == move_mode)
6197       scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0); 
6198
6199     move_size = GET_MODE_SIZE (move_mode);
6200     /* Number of bytes/words to rotate.  */
6201     offset = (num  >> 3) / move_size;
6202     /* Number of moves needed.  */
6203     size = GET_MODE_SIZE (mode) / move_size;
6204     /* Himode byte swap is special case to avoid a scratch register.  */
6205     if (mode == HImode && same_reg)
6206       {
6207         /* HImode byte swap, using xor.  This is as quick as using scratch.  */
6208         rtx src, dst;
6209         src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
6210         dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
6211         if (!rtx_equal_p (dst, src))
6212           {
6213              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
6214              emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
6215              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
6216           }
6217       }    
6218     else  
6219       {
6220 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode)  */
6221         /* Create linked list of moves to determine move order.  */
6222         struct {
6223           rtx src, dst;
6224           int links;
6225         } move[MAX_SIZE + 8];
6226         int blocked, moves;
6227
6228         gcc_assert (size <= MAX_SIZE);
6229         /* Generate list of subreg moves.  */
6230         for (i = 0; i < size; i++)
6231           {
6232             int from = i;
6233             int to = (from + offset) % size;          
6234             move[i].src = simplify_gen_subreg (move_mode, operands[1],
6235                                                 mode, from * move_size);
6236             move[i].dst = simplify_gen_subreg (move_mode, operands[0],
6237                                                 mode, to   * move_size);
6238             move[i].links = -1;
6239            }
6240         /* Mark dependence where a dst of one move is the src of another move.
6241            The first move is a conflict as it must wait until second is
6242            performed.  We ignore moves to self - we catch this later.  */
6243         if (overlapped)
6244           for (i = 0; i < size; i++)
6245             if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
6246               for (j = 0; j < size; j++)
6247                 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
6248                   {
6249                     /* The dst of move i is the src of move j.  */
6250                     move[i].links = j;
6251                     break;
6252                   }
6253
6254         blocked = -1;
6255         moves = 0;
6256         /* Go through move list and perform non-conflicting moves.  As each
6257            non-overlapping move is made, it may remove other conflicts
6258            so the process is repeated until no conflicts remain.  */
6259         do
6260           {
6261             blocked = -1;
6262             moves = 0;
6263             /* Emit move where dst is not also a src or we have used that
6264                src already.  */
6265             for (i = 0; i < size; i++)
6266               if (move[i].src != NULL_RTX)
6267                 {
6268                   if (move[i].links == -1
6269                       || move[move[i].links].src == NULL_RTX)
6270                     {
6271                       moves++;
6272                       /* Ignore NOP moves to self.  */
6273                       if (!rtx_equal_p (move[i].dst, move[i].src))
6274                         emit_move_insn (move[i].dst, move[i].src);
6275
6276                       /* Remove  conflict from list.  */
6277                       move[i].src = NULL_RTX;
6278                     }
6279                   else
6280                     blocked = i;
6281                 }
6282
6283             /* Check for deadlock. This is when no moves occurred and we have
6284                at least one blocked move.  */
6285             if (moves == 0 && blocked != -1)
6286               {
6287                 /* Need to use scratch register to break deadlock.
6288                    Add move to put dst of blocked move into scratch.
6289                    When this move occurs, it will break chain deadlock.
6290                    The scratch register is substituted for real move.  */
6291
6292                 gcc_assert (SCRATCH != GET_CODE (scratch));
6293
6294                 move[size].src = move[blocked].dst;
6295                 move[size].dst =  scratch;
6296                 /* Scratch move is never blocked.  */
6297                 move[size].links = -1; 
6298                 /* Make sure we have valid link.  */
6299                 gcc_assert (move[blocked].links != -1);
6300                 /* Replace src of  blocking move with scratch reg.  */
6301                 move[move[blocked].links].src = scratch;
6302                 /* Make dependent on scratch move occuring.  */
6303                 move[blocked].links = size; 
6304                 size=size+1;
6305               }
6306           }
6307         while (blocked != -1);
6308       }
6309     return true;
6310 }
6311
6312 /* Modifies the length assigned to instruction INSN
6313    LEN is the initially computed length of the insn.  */
6314
6315 int
6316 adjust_insn_length (rtx insn, int len)
6317 {
6318   rtx *op = recog_data.operand;
6319   enum attr_adjust_len adjust_len;
6320
6321   /* Some complex insns don't need length adjustment and therefore
6322      the length need not/must not be adjusted for these insns.
6323      It is easier to state this in an insn attribute "adjust_len" than
6324      to clutter up code here...  */
6325   
6326   if (-1 == recog_memoized (insn))
6327     {
6328       return len;
6329     }
6330
6331   /* Read from insn attribute "adjust_len" if/how length is to be adjusted.  */
6332
6333   adjust_len = get_attr_adjust_len (insn);
6334
6335   if (adjust_len == ADJUST_LEN_NO)
6336     {
6337       /* Nothing to adjust: The length from attribute "length" is fine.
6338          This is the default.  */
6339       
6340       return len;
6341     }
6342   
6343   /* Extract insn's operands.  */
6344   
6345   extract_constrain_insn_cached (insn);
6346   
6347   /* Dispatch to right function.  */
6348   
6349   switch (adjust_len)
6350     {
6351     case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
6352     case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
6353     case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
6354       
6355     case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
6356       
6357     case ADJUST_LEN_OUT_PLUS: avr_out_plus (op, &len, NULL); break;
6358     case ADJUST_LEN_OUT_PLUS_NOCLOBBER:
6359       avr_out_plus_noclobber (op, &len, NULL); break;
6360
6361     case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
6362       
6363     case ADJUST_LEN_MOV8:  output_movqi (insn, op, &len); break;
6364     case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
6365     case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
6366     case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
6367     case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
6368     case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
6369
6370     case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
6371     case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
6372     case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
6373     case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
6374
6375     case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
6376     case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
6377     case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
6378
6379     case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
6380     case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
6381     case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
6382
6383     case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
6384     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
6385     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
6386       
6387     case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
6388     case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
6389     case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
6390
6391     case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
6392
6393     default:
6394       gcc_unreachable();
6395     }
6396   
6397   return len;
6398 }
6399
6400 /* Return nonzero if register REG dead after INSN.  */
6401
6402 int
6403 reg_unused_after (rtx insn, rtx reg)
6404 {
6405   return (dead_or_set_p (insn, reg)
6406           || (REG_P(reg) && _reg_unused_after (insn, reg)));
6407 }
6408
6409 /* Return nonzero if REG is not used after INSN.
6410    We assume REG is a reload reg, and therefore does
6411    not live past labels.  It may live past calls or jumps though.  */
6412
6413 int
6414 _reg_unused_after (rtx insn, rtx reg)
6415 {
6416   enum rtx_code code;
6417   rtx set;
6418
6419   /* If the reg is set by this instruction, then it is safe for our
6420      case.  Disregard the case where this is a store to memory, since
6421      we are checking a register used in the store address.  */
6422   set = single_set (insn);
6423   if (set && GET_CODE (SET_DEST (set)) != MEM
6424       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
6425     return 1;
6426
6427   while ((insn = NEXT_INSN (insn)))
6428     {
6429       rtx set;
6430       code = GET_CODE (insn);
6431
6432 #if 0
6433       /* If this is a label that existed before reload, then the register
6434          if dead here.  However, if this is a label added by reorg, then
6435          the register may still be live here.  We can't tell the difference,
6436          so we just ignore labels completely.  */
6437       if (code == CODE_LABEL)
6438         return 1;
6439       /* else */
6440 #endif
6441
6442       if (!INSN_P (insn))
6443         continue;
6444
6445       if (code == JUMP_INSN)
6446         return 0;
6447
6448       /* If this is a sequence, we must handle them all at once.
6449          We could have for instance a call that sets the target register,
6450          and an insn in a delay slot that uses the register.  In this case,
6451          we must return 0.  */
6452       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
6453         {
6454           int i;
6455           int retval = 0;
6456
6457           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
6458             {
6459               rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
6460               rtx set = single_set (this_insn);
6461
6462               if (GET_CODE (this_insn) == CALL_INSN)
6463                 code = CALL_INSN;
6464               else if (GET_CODE (this_insn) == JUMP_INSN)
6465                 {
6466                   if (INSN_ANNULLED_BRANCH_P (this_insn))
6467                     return 0;
6468                   code = JUMP_INSN;
6469                 }
6470
6471               if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
6472                 return 0;
6473               if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
6474                 {
6475                   if (GET_CODE (SET_DEST (set)) != MEM)
6476                     retval = 1;
6477                   else
6478                     return 0;
6479                 }
6480               if (set == 0
6481                   && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
6482                 return 0;
6483             }
6484           if (retval == 1)
6485             return 1;
6486           else if (code == JUMP_INSN)
6487             return 0;
6488         }
6489
6490       if (code == CALL_INSN)
6491         {
6492           rtx tem;
6493           for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
6494             if (GET_CODE (XEXP (tem, 0)) == USE
6495                 && REG_P (XEXP (XEXP (tem, 0), 0))
6496                 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
6497               return 0;
6498           if (call_used_regs[REGNO (reg)]) 
6499             return 1;
6500         }
6501
6502       set = single_set (insn);
6503
6504       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
6505         return 0;
6506       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
6507         return GET_CODE (SET_DEST (set)) != MEM;
6508       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
6509         return 0;
6510     }
6511   return 1;
6512 }
6513
6514
6515 /* Return RTX that represents the lower 16 bits of a constant address.
6516    Unfortunately, simplify_gen_subreg does not handle this case.  */
6517
6518 static rtx
6519 avr_const_address_lo16 (rtx x)
6520 {
6521   rtx lo16;
6522   
6523   switch (GET_CODE (x))
6524     {
6525     default:
6526       break;
6527       
6528     case CONST:
6529       if (PLUS == GET_CODE (XEXP (x, 0))
6530           && SYMBOL_REF == GET_CODE (XEXP (XEXP (x, 0), 0))
6531           && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
6532         {
6533           HOST_WIDE_INT offset = INTVAL (XEXP (XEXP (x, 0), 1));
6534           const char *name = XSTR (XEXP (XEXP (x, 0), 0), 0);
6535           
6536           lo16 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
6537           lo16 = gen_rtx_CONST (Pmode, plus_constant (lo16, offset));
6538           
6539           return lo16;
6540         }
6541       
6542       break;
6543       
6544     case SYMBOL_REF:
6545       {
6546         const char *name = XSTR (x, 0);
6547         
6548         return gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
6549       }
6550     }
6551   
6552   avr_edump ("\n%?: %r\n", x);
6553   gcc_unreachable();
6554 }
6555
6556
6557 /* Target hook for assembling integer objects.  The AVR version needs
6558    special handling for references to certain labels.  */
6559
6560 static bool
6561 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
6562 {
6563   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
6564       && text_segment_operand (x, VOIDmode) )
6565     {
6566       fputs ("\t.word\tgs(", asm_out_file);
6567       output_addr_const (asm_out_file, x);
6568       fputs (")\n", asm_out_file);
6569       
6570       return true;
6571     }
6572   else if (GET_MODE (x) == PSImode)
6573     {
6574       default_assemble_integer (avr_const_address_lo16 (x),
6575                                 GET_MODE_SIZE (HImode), aligned_p);
6576       
6577       fputs ("\t.warning\t\"assembling 24-bit address needs binutils extension for hh8(",
6578              asm_out_file);
6579       output_addr_const (asm_out_file, x);
6580       fputs (")\"\n", asm_out_file);
6581       
6582       fputs ("\t.byte\t0\t" ASM_COMMENT_START " hh8(", asm_out_file);
6583       output_addr_const (asm_out_file, x);
6584       fputs (")\n", asm_out_file);
6585       
6586       return true;
6587     }
6588   
6589   return default_assemble_integer (x, size, aligned_p);
6590 }
6591
6592
6593 /* Worker function for ASM_DECLARE_FUNCTION_NAME.  */
6594
6595 void
6596 avr_asm_declare_function_name (FILE *file, const char *name, tree decl)
6597 {
6598
6599   /* If the function has the 'signal' or 'interrupt' attribute, test to
6600      make sure that the name of the function is "__vector_NN" so as to
6601      catch when the user misspells the interrupt vector name.  */
6602
6603   if (cfun->machine->is_interrupt)
6604     {
6605       if (!STR_PREFIX_P (name, "__vector"))
6606         {
6607           warning_at (DECL_SOURCE_LOCATION (decl), 0,
6608                       "%qs appears to be a misspelled interrupt handler",
6609                       name);
6610         }
6611     }
6612   else if (cfun->machine->is_signal)
6613     {
6614       if (!STR_PREFIX_P (name, "__vector"))
6615         {
6616            warning_at (DECL_SOURCE_LOCATION (decl), 0,
6617                        "%qs appears to be a misspelled signal handler",
6618                        name);
6619         }
6620     }
6621
6622   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
6623   ASM_OUTPUT_LABEL (file, name);
6624 }
6625
6626
6627 /* Return value is nonzero if pseudos that have been
6628    assigned to registers of class CLASS would likely be spilled
6629    because registers of CLASS are needed for spill registers.  */
6630
6631 static bool
6632 avr_class_likely_spilled_p (reg_class_t c)
6633 {
6634   return (c != ALL_REGS && c != ADDW_REGS);
6635 }
6636
6637 /* Valid attributes:
6638    progmem - put data to program memory;
6639    signal - make a function to be hardware interrupt. After function
6640    prologue interrupts are disabled;
6641    interrupt - make a function to be hardware interrupt. After function
6642    prologue interrupts are enabled;
6643    naked     - don't generate function prologue/epilogue and `ret' command.
6644
6645    Only `progmem' attribute valid for type.  */
6646
6647 /* Handle a "progmem" attribute; arguments as in
6648    struct attribute_spec.handler.  */
6649 static tree
6650 avr_handle_progmem_attribute (tree *node, tree name,
6651                               tree args ATTRIBUTE_UNUSED,
6652                               int flags ATTRIBUTE_UNUSED,
6653                               bool *no_add_attrs)
6654 {
6655   if (DECL_P (*node))
6656     {
6657       if (TREE_CODE (*node) == TYPE_DECL)
6658         {
6659           /* This is really a decl attribute, not a type attribute,
6660              but try to handle it for GCC 3.0 backwards compatibility.  */
6661
6662           tree type = TREE_TYPE (*node);
6663           tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
6664           tree newtype = build_type_attribute_variant (type, attr);
6665
6666           TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
6667           TREE_TYPE (*node) = newtype;
6668           *no_add_attrs = true;
6669         }
6670       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
6671         {
6672           *no_add_attrs = false;
6673         }
6674       else
6675         {
6676           warning (OPT_Wattributes, "%qE attribute ignored",
6677                    name);
6678           *no_add_attrs = true;
6679         }
6680     }
6681
6682   return NULL_TREE;
6683 }
6684
6685 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
6686    struct attribute_spec.handler.  */
6687
6688 static tree
6689 avr_handle_fndecl_attribute (tree *node, tree name,
6690                              tree args ATTRIBUTE_UNUSED,
6691                              int flags ATTRIBUTE_UNUSED,
6692                              bool *no_add_attrs)
6693 {
6694   if (TREE_CODE (*node) != FUNCTION_DECL)
6695     {
6696       warning (OPT_Wattributes, "%qE attribute only applies to functions",
6697                name);
6698       *no_add_attrs = true;
6699     }
6700
6701   return NULL_TREE;
6702 }
6703
6704 static tree
6705 avr_handle_fntype_attribute (tree *node, tree name,
6706                              tree args ATTRIBUTE_UNUSED,
6707                              int flags ATTRIBUTE_UNUSED,
6708                              bool *no_add_attrs)
6709 {
6710   if (TREE_CODE (*node) != FUNCTION_TYPE)
6711     {
6712       warning (OPT_Wattributes, "%qE attribute only applies to functions",
6713                name);
6714       *no_add_attrs = true;
6715     }
6716
6717   return NULL_TREE;
6718 }
6719
6720
6721 /* AVR attributes.  */
6722 static const struct attribute_spec
6723 avr_attribute_table[] =
6724 {
6725   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
6726        affects_type_identity } */
6727   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute,
6728     false },
6729   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute,
6730     false },
6731   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
6732     false },
6733   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
6734     false },
6735   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
6736     false },
6737   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
6738     false },
6739   { NULL,        0, 0, false, false, false, NULL, false }
6740 };
6741
6742
6743 /* Look if DECL shall be placed in program memory space by
6744    means of attribute `progmem' or some address-space qualifier.
6745    Return non-zero if DECL is data that must end up in Flash and
6746    zero if the data lives in RAM (.bss, .data, .rodata, ...).
6747    
6748    Return 2   if DECL is located in 24-bit flash address-space
6749    Return 1   if DECL is located in 16-bit flash address-space
6750    Return -1  if attribute `progmem' occurs in DECL or ATTRIBUTES
6751    Return 0   otherwise  */
6752
6753 int
6754 avr_progmem_p (tree decl, tree attributes)
6755 {
6756   tree a;
6757
6758   if (TREE_CODE (decl) != VAR_DECL)
6759     return 0;
6760
6761   if (avr_decl_pgmx_p (decl))
6762     return 2;
6763
6764   if (avr_decl_pgm_p (decl))
6765     return 1;
6766
6767   if (NULL_TREE
6768       != lookup_attribute ("progmem", attributes))
6769     return -1;
6770
6771   a = decl;
6772  
6773   do
6774     a = TREE_TYPE(a);
6775   while (TREE_CODE (a) == ARRAY_TYPE);
6776
6777   if (a == error_mark_node)
6778     return 0;
6779
6780   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
6781     return -1;
6782   
6783   return 0;
6784 }
6785
6786
6787 /* Scan type TYP for pointer references to address space ASn.
6788    Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
6789    the AS are also declared to be CONST.
6790    Otherwise, return the respective addres space, i.e. a value != 0.  */
6791    
6792 static addr_space_t
6793 avr_nonconst_pointer_addrspace (tree typ)
6794 {
6795   while (ARRAY_TYPE == TREE_CODE (typ))
6796     typ = TREE_TYPE (typ);
6797
6798   if (POINTER_TYPE_P (typ))
6799     {
6800       tree target = TREE_TYPE (typ);
6801
6802       /* Pointer to function: Test the function's return type.  */
6803       
6804       if (FUNCTION_TYPE == TREE_CODE (target))
6805         return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
6806
6807       /* "Ordinary" pointers... */
6808
6809       while (TREE_CODE (target) == ARRAY_TYPE)
6810         target = TREE_TYPE (target);
6811
6812       if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (target))
6813           && !TYPE_READONLY (target))
6814         {
6815           /* Pointers to non-generic address space must be const.  */
6816           
6817           return TYPE_ADDR_SPACE (target);
6818         }
6819
6820       /* Scan pointer's target type.  */
6821       
6822       return avr_nonconst_pointer_addrspace (target);
6823     }
6824
6825   return ADDR_SPACE_GENERIC;
6826 }
6827
6828
6829 /* Sanity check NODE so that all pointers targeting address space AS1
6830    go along with CONST qualifier.  Writing to this address space should
6831    be detected and complained about as early as possible.  */
6832
6833 static bool
6834 avr_pgm_check_var_decl (tree node)
6835 {
6836   const char *reason = NULL;
6837   
6838   addr_space_t as = ADDR_SPACE_GENERIC;
6839
6840   gcc_assert (as == 0);
6841   
6842   if (avr_log.progmem)
6843     avr_edump ("%?: %t\n", node);
6844   
6845   switch (TREE_CODE (node))
6846     {
6847     default:
6848       break;
6849
6850     case VAR_DECL:
6851       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
6852         reason = "variable";
6853       break;
6854
6855     case PARM_DECL:
6856       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
6857         reason = "function parameter";
6858       break;
6859         
6860     case FIELD_DECL:
6861       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
6862         reason = "structure field";
6863       break;
6864         
6865     case FUNCTION_DECL:
6866       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
6867           as)
6868         reason = "return type of function";
6869       break;
6870
6871     case POINTER_TYPE:
6872       if (as = avr_nonconst_pointer_addrspace (node), as)
6873         reason = "pointer";
6874       break;
6875     }
6876
6877   if (reason)
6878     {
6879       if (TYPE_P (node))
6880         error ("pointer targeting address space %qs must be const in %qT",
6881                c_addr_space_name (as), node);
6882       else
6883         error ("pointer targeting address space %qs must be const in %s %q+D",
6884                c_addr_space_name (as), reason, node);
6885     }
6886
6887   return reason == NULL;
6888 }
6889
6890
6891 /* Add the section attribute if the variable is in progmem.  */
6892
6893 static void
6894 avr_insert_attributes (tree node, tree *attributes)
6895 {
6896   avr_pgm_check_var_decl (node);
6897
6898   if (TREE_CODE (node) == VAR_DECL
6899       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
6900       && avr_progmem_p (node, *attributes))
6901     {
6902       tree node0 = node;
6903
6904       /* For C++, we have to peel arrays in order to get correct
6905          determination of readonlyness.  */
6906       
6907       do
6908         node0 = TREE_TYPE (node0);
6909       while (TREE_CODE (node0) == ARRAY_TYPE);
6910
6911       if (error_mark_node == node0)
6912         return;
6913       
6914       if (!TYPE_READONLY (node0)
6915           && !TREE_READONLY (node))
6916         {
6917           addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (node));
6918           const char *reason = "__attribute__((progmem))";
6919
6920           if (!ADDR_SPACE_GENERIC_P (as))
6921             reason = c_addr_space_name (as);
6922           
6923           if (avr_log.progmem)
6924             avr_edump ("\n%?: %t\n%t\n", node, node0);
6925           
6926           error ("variable %q+D must be const in order to be put into"
6927                  " read-only section by means of %qs", node, reason);
6928         }
6929     }
6930 }
6931
6932
6933 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
6934 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
6935 /* Track need of __do_clear_bss.  */
6936
6937 void
6938 avr_asm_output_aligned_decl_common (FILE * stream,
6939                                     const_tree decl ATTRIBUTE_UNUSED,
6940                                     const char *name,
6941                                     unsigned HOST_WIDE_INT size,
6942                                     unsigned int align, bool local_p)
6943 {
6944   avr_need_clear_bss_p = true;
6945
6946   if (local_p)
6947     ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
6948   else
6949     ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
6950 }
6951
6952
6953 /* Unnamed section callback for data_section
6954    to track need of __do_copy_data.  */
6955
6956 static void
6957 avr_output_data_section_asm_op (const void *data)
6958 {
6959   avr_need_copy_data_p = true;
6960   
6961   /* Dispatch to default.  */
6962   output_section_asm_op (data);
6963 }
6964
6965
6966 /* Unnamed section callback for bss_section
6967    to track need of __do_clear_bss.  */
6968
6969 static void
6970 avr_output_bss_section_asm_op (const void *data)
6971 {
6972   avr_need_clear_bss_p = true;
6973   
6974   /* Dispatch to default.  */
6975   output_section_asm_op (data);
6976 }
6977
6978
6979 /* Unnamed section callback for progmem*.data sections.  */
6980
6981 static void
6982 avr_output_progmem_section_asm_op (const void *data)
6983 {
6984   fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
6985            (const char*) data);
6986 }
6987
6988
6989 /* Implement `TARGET_ASM_INIT_SECTIONS'.  */
6990
6991 static void
6992 avr_asm_init_sections (void)
6993 {
6994   unsigned int n;
6995   
6996   /* Set up a section for jump tables.  Alignment is handled by
6997      ASM_OUTPUT_BEFORE_CASE_LABEL.  */
6998   
6999   if (AVR_HAVE_JMP_CALL)
7000     {
7001       progmem_swtable_section
7002         = get_unnamed_section (0, output_section_asm_op,
7003                                "\t.section\t.progmem.gcc_sw_table"
7004                                ",\"a\",@progbits");
7005     }
7006   else
7007     {
7008       progmem_swtable_section
7009         = get_unnamed_section (SECTION_CODE, output_section_asm_op,
7010                                "\t.section\t.progmem.gcc_sw_table"
7011                                ",\"ax\",@progbits");
7012     }
7013
7014   for (n = 0; n < sizeof (progmem_section) / sizeof (*progmem_section); n++)
7015     {
7016       progmem_section[n]
7017         = get_unnamed_section (0, avr_output_progmem_section_asm_op,
7018                                progmem_section_prefix[n]);
7019     }
7020   
7021   /* Override section callbacks to keep track of `avr_need_clear_bss_p'
7022      resp. `avr_need_copy_data_p'.  */
7023   
7024   readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
7025   data_section->unnamed.callback = avr_output_data_section_asm_op;
7026   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
7027 }
7028
7029
7030 /* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'.  */
7031
7032 static section*
7033 avr_asm_function_rodata_section (tree decl)
7034 {
7035   /* If a function is unused and optimized out by -ffunction-sections
7036      and --gc-sections, ensure that the same will happen for its jump
7037      tables by putting them into individual sections.  */
7038
7039   unsigned int flags;
7040   section * frodata;
7041
7042   /* Get the frodata section from the default function in varasm.c
7043      but treat function-associated data-like jump tables as code
7044      rather than as user defined data.  AVR has no constant pools.  */
7045   {
7046     int fdata = flag_data_sections;
7047
7048     flag_data_sections = flag_function_sections;
7049     frodata = default_function_rodata_section (decl);
7050     flag_data_sections = fdata;
7051     flags = frodata->common.flags;
7052   }
7053
7054   if (frodata != readonly_data_section
7055       && flags & SECTION_NAMED)
7056     {
7057       /* Adjust section flags and replace section name prefix.  */
7058
7059       unsigned int i;
7060
7061       static const char* const prefix[] =
7062         {
7063           ".rodata",          ".progmem.gcc_sw_table",
7064           ".gnu.linkonce.r.", ".gnu.linkonce.t."
7065         };
7066
7067       for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2)
7068         {
7069           const char * old_prefix = prefix[i];
7070           const char * new_prefix = prefix[i+1];
7071           const char * name = frodata->named.name;
7072
7073           if (STR_PREFIX_P (name, old_prefix))
7074             {
7075               const char *rname = avr_replace_prefix (name,
7076                                                       old_prefix, new_prefix);
7077
7078               flags &= ~SECTION_CODE;
7079               flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
7080               
7081               return get_section (rname, flags, frodata->named.decl);
7082             }
7083         }
7084     }
7085         
7086   return progmem_swtable_section;
7087 }
7088
7089
7090 /* Implement `TARGET_ASM_NAMED_SECTION'.  */
7091 /* Track need of __do_clear_bss, __do_copy_data for named sections.  */
7092
7093 static void
7094 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
7095 {
7096   if (flags & AVR_SECTION_PROGMEM)
7097     {
7098       int segment = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP - 1;
7099       const char *old_prefix = ".rodata";
7100       const char *new_prefix = progmem_section_prefix[segment];
7101       const char *sname = new_prefix;
7102       
7103       if (STR_PREFIX_P (name, old_prefix))
7104         {
7105           sname = avr_replace_prefix (name, old_prefix, new_prefix);
7106         }
7107
7108       default_elf_asm_named_section (sname, flags, decl);
7109
7110       return;
7111     }
7112   
7113   if (!avr_need_copy_data_p)
7114     avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
7115                             || STR_PREFIX_P (name, ".rodata")
7116                             || STR_PREFIX_P (name, ".gnu.linkonce.d"));
7117   
7118   if (!avr_need_clear_bss_p)
7119     avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
7120   
7121   default_elf_asm_named_section (name, flags, decl);
7122 }
7123
7124 static unsigned int
7125 avr_section_type_flags (tree decl, const char *name, int reloc)
7126 {
7127   int prog;
7128   unsigned int flags = default_section_type_flags (decl, name, reloc);
7129
7130   if (STR_PREFIX_P (name, ".noinit"))
7131     {
7132       if (decl && TREE_CODE (decl) == VAR_DECL
7133           && DECL_INITIAL (decl) == NULL_TREE)
7134         flags |= SECTION_BSS;  /* @nobits */
7135       else
7136         warning (0, "only uninitialized variables can be placed in the "
7137                  ".noinit section");
7138     }
7139
7140   if (decl && DECL_P (decl)
7141       && (prog = avr_progmem_p (decl, DECL_ATTRIBUTES (decl)), prog))
7142     {
7143       int segment = 0;
7144
7145       if (prog == 1)
7146         segment = avr_pgm_segment (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
7147
7148       flags &= ~SECTION_WRITE;
7149       flags &= ~SECTION_BSS;
7150       flags |= (1 + segment % avr_current_arch->n_segments) * SECTION_MACH_DEP;
7151     }
7152   
7153   return flags;
7154 }
7155
7156
7157 /* Implement `TARGET_ENCODE_SECTION_INFO'.  */
7158
7159 static void
7160 avr_encode_section_info (tree decl, rtx rtl,
7161                          int new_decl_p)
7162 {
7163   /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
7164      readily available, see PR34734.  So we postpone the warning
7165      about uninitialized data in program memory section until here.  */
7166    
7167   if (new_decl_p
7168       && decl && DECL_P (decl)
7169       && NULL_TREE == DECL_INITIAL (decl)
7170       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
7171     {
7172       warning (OPT_Wuninitialized,
7173                "uninitialized variable %q+D put into "
7174                "program memory area", decl);
7175     }
7176
7177   default_encode_section_info (decl, rtl, new_decl_p);
7178 }
7179
7180
7181 /* Implement `TARGET_ASM_SELECT_SECTION' */
7182
7183 static section *
7184 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
7185 {
7186   int prog;
7187   
7188   section * sect = default_elf_select_section (decl, reloc, align);
7189   
7190   if (decl && DECL_P (decl)
7191       && (prog = avr_progmem_p (decl, DECL_ATTRIBUTES (decl)), prog))
7192     {
7193       int segment = 0;
7194       
7195       if (prog == 1)
7196         segment = avr_pgm_segment (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
7197
7198       segment %= avr_current_arch->n_segments;
7199       
7200       if (sect->common.flags & SECTION_NAMED)
7201         {
7202           const char * name = sect->named.name;
7203           const char * old_prefix = ".rodata";
7204           const char * new_prefix = progmem_section_prefix[segment];
7205
7206           if (STR_PREFIX_P (name, old_prefix))
7207             {
7208               const char *sname = avr_replace_prefix (name,
7209                                                       old_prefix, new_prefix);
7210
7211               return get_section (sname, sect->common.flags, sect->named.decl);
7212             }
7213         }
7214           
7215       return progmem_section[segment];
7216     }
7217
7218   return sect;
7219 }
7220
7221 /* Implement `TARGET_ASM_FILE_START'.  */
7222 /* Outputs some text at the start of each assembler file.  */
7223
7224 static void
7225 avr_file_start (void)
7226 {
7227   int sfr_offset = avr_current_arch->sfr_offset;
7228
7229   if (avr_current_arch->asm_only)
7230     error ("MCU %qs supported for assembler only", avr_current_device->name);
7231
7232   default_file_start ();
7233
7234   fprintf (asm_out_file,
7235            "__SREG__ = 0x%02x\n"
7236            "__SP_H__ = 0x%02x\n"
7237            "__SP_L__ = 0x%02x\n"
7238            "__RAMPZ__ = 0x%02x\n"
7239            "__tmp_reg__ = %d\n" 
7240            "__zero_reg__ = %d\n",
7241            -sfr_offset + SREG_ADDR,
7242            -sfr_offset + SP_ADDR + 1,
7243            -sfr_offset + SP_ADDR,
7244            -sfr_offset + RAMPZ_ADDR,
7245            TMP_REGNO,
7246            ZERO_REGNO);
7247 }
7248
7249
7250 /* Implement `TARGET_ASM_FILE_END'.  */
7251 /* Outputs to the stdio stream FILE some
7252    appropriate text to go at the end of an assembler file.  */
7253
7254 static void
7255 avr_file_end (void)
7256 {
7257   /* Output these only if there is anything in the
7258      .data* / .rodata* / .gnu.linkonce.* resp. .bss*
7259      input section(s) - some code size can be saved by not
7260      linking in the initialization code from libgcc if resp.
7261      sections are empty.  */
7262
7263   if (avr_need_copy_data_p)
7264     fputs (".global __do_copy_data\n", asm_out_file);
7265
7266   if (avr_need_clear_bss_p)
7267     fputs (".global __do_clear_bss\n", asm_out_file);
7268 }
7269
7270 /* Choose the order in which to allocate hard registers for
7271    pseudo-registers local to a basic block.
7272
7273    Store the desired register order in the array `reg_alloc_order'.
7274    Element 0 should be the register to allocate first; element 1, the
7275    next register; and so on.  */
7276
7277 void
7278 order_regs_for_local_alloc (void)
7279 {
7280   unsigned int i;
7281   static const int order_0[] = {
7282     24,25,
7283     18,19,
7284     20,21,
7285     22,23,
7286     30,31,
7287     26,27,
7288     28,29,
7289     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
7290     0,1,
7291     32,33,34,35
7292   };
7293   static const int order_1[] = {
7294     18,19,
7295     20,21,
7296     22,23,
7297     24,25,
7298     30,31,
7299     26,27,
7300     28,29,
7301     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
7302     0,1,
7303     32,33,34,35
7304   };
7305   static const int order_2[] = {
7306     25,24,
7307     23,22,
7308     21,20,
7309     19,18,
7310     30,31,
7311     26,27,
7312     28,29,
7313     17,16,
7314     15,14,13,12,11,10,9,8,7,6,5,4,3,2,
7315     1,0,
7316     32,33,34,35
7317   };
7318   
7319   const int *order = (TARGET_ORDER_1 ? order_1 :
7320                       TARGET_ORDER_2 ? order_2 :
7321                       order_0);
7322   for (i=0; i < ARRAY_SIZE (order_0); ++i)
7323       reg_alloc_order[i] = order[i];
7324 }
7325
7326
7327 /* Implement `TARGET_REGISTER_MOVE_COST' */
7328
7329 static int
7330 avr_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
7331                         reg_class_t from, reg_class_t to)
7332 {
7333   return (from == STACK_REG ? 6
7334           : to == STACK_REG ? 12
7335           : 2);
7336 }
7337
7338
7339 /* Implement `TARGET_MEMORY_MOVE_COST' */
7340
7341 static int
7342 avr_memory_move_cost (enum machine_mode mode,
7343                       reg_class_t rclass ATTRIBUTE_UNUSED,
7344                       bool in ATTRIBUTE_UNUSED)
7345 {
7346   return (mode == QImode ? 2
7347           : mode == HImode ? 4
7348           : mode == SImode ? 8
7349           : mode == SFmode ? 8
7350           : 16);
7351 }
7352
7353
7354 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
7355    cost of an RTX operand given its context.  X is the rtx of the
7356    operand, MODE is its mode, and OUTER is the rtx_code of this
7357    operand's parent operator.  */
7358
7359 static int
7360 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
7361                       int opno, bool speed)
7362 {
7363   enum rtx_code code = GET_CODE (x);
7364   int total;
7365
7366   switch (code)
7367     {
7368     case REG:
7369     case SUBREG:
7370       return 0;
7371
7372     case CONST_INT:
7373     case CONST_DOUBLE:
7374       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
7375
7376     default:
7377       break;
7378     }
7379
7380   total = 0;
7381   avr_rtx_costs (x, code, outer, opno, &total, speed);
7382   return total;
7383 }
7384
7385 /* Worker function for AVR backend's rtx_cost function.
7386    X is rtx expression whose cost is to be calculated.
7387    Return true if the complete cost has been computed.
7388    Return false if subexpressions should be scanned.
7389    In either case, *TOTAL contains the cost result.  */
7390
7391 static bool
7392 avr_rtx_costs_1 (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
7393                  int opno ATTRIBUTE_UNUSED, int *total, bool speed)
7394 {
7395   enum rtx_code code = (enum rtx_code) codearg;
7396   enum machine_mode mode = GET_MODE (x);
7397   HOST_WIDE_INT val;
7398
7399   switch (code)
7400     {
7401     case CONST_INT:
7402     case CONST_DOUBLE:
7403     case SYMBOL_REF:
7404     case CONST:
7405     case LABEL_REF:
7406       /* Immediate constants are as cheap as registers.  */
7407       *total = 0;
7408       return true;
7409
7410     case MEM:
7411       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
7412       return true;
7413
7414     case NEG:
7415       switch (mode)
7416         {
7417         case QImode:
7418         case SFmode:
7419           *total = COSTS_N_INSNS (1);
7420           break;
7421
7422         case HImode:
7423         case PSImode:
7424         case SImode:
7425           *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
7426           break;
7427
7428         default:
7429           return false;
7430         }
7431       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7432       return true;
7433
7434     case ABS:
7435       switch (mode)
7436         {
7437         case QImode:
7438         case SFmode:
7439           *total = COSTS_N_INSNS (1);
7440           break;
7441
7442         default:
7443           return false;
7444         }
7445       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7446       return true;
7447
7448     case NOT:
7449       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
7450       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7451       return true;
7452
7453     case ZERO_EXTEND:
7454       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
7455                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
7456       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7457       return true;
7458
7459     case SIGN_EXTEND:
7460       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
7461                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
7462       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7463       return true;
7464
7465     case PLUS:
7466       switch (mode)
7467         {
7468         case QImode:
7469           if (AVR_HAVE_MUL
7470               && MULT == GET_CODE (XEXP (x, 0))
7471               && register_operand (XEXP (x, 1), QImode))
7472             {
7473               /* multiply-add */
7474               *total = COSTS_N_INSNS (speed ? 4 : 3);
7475               /* multiply-add with constant: will be split and load constant. */
7476               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
7477                 *total = COSTS_N_INSNS (1) + *total;
7478               return true;
7479             }
7480           *total = COSTS_N_INSNS (1);
7481           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7482             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
7483           break;
7484
7485         case HImode:
7486           if (AVR_HAVE_MUL
7487               && (MULT == GET_CODE (XEXP (x, 0))
7488                   || ASHIFT == GET_CODE (XEXP (x, 0)))
7489               && register_operand (XEXP (x, 1), HImode)
7490               && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
7491                   || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
7492             {
7493               /* multiply-add */
7494               *total = COSTS_N_INSNS (speed ? 5 : 4);
7495               /* multiply-add with constant: will be split and load constant. */
7496               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
7497                 *total = COSTS_N_INSNS (1) + *total;
7498               return true;
7499             }
7500           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7501             {
7502               *total = COSTS_N_INSNS (2);
7503               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7504                                               speed);
7505             }
7506           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
7507             *total = COSTS_N_INSNS (1);
7508           else
7509             *total = COSTS_N_INSNS (2);
7510           break;
7511
7512         case PSImode:
7513           if (!CONST_INT_P (XEXP (x, 1)))
7514             {
7515               *total = COSTS_N_INSNS (3);
7516               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7517                                               speed);
7518             }
7519           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
7520             *total = COSTS_N_INSNS (2);
7521           else
7522             *total = COSTS_N_INSNS (3);
7523           break;
7524
7525         case SImode:
7526           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7527             {
7528               *total = COSTS_N_INSNS (4);
7529               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7530                                               speed);
7531             }
7532           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
7533             *total = COSTS_N_INSNS (1);
7534           else
7535             *total = COSTS_N_INSNS (4);
7536           break;
7537
7538         default:
7539           return false;
7540         }
7541       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7542       return true;
7543
7544     case MINUS:
7545       if (AVR_HAVE_MUL
7546           && QImode == mode
7547           && register_operand (XEXP (x, 0), QImode)
7548           && MULT == GET_CODE (XEXP (x, 1)))
7549         {
7550           /* multiply-sub */
7551           *total = COSTS_N_INSNS (speed ? 4 : 3);
7552           /* multiply-sub with constant: will be split and load constant. */
7553           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
7554             *total = COSTS_N_INSNS (1) + *total;
7555           return true;
7556         }
7557       if (AVR_HAVE_MUL
7558           && HImode == mode
7559           && register_operand (XEXP (x, 0), HImode)
7560           && (MULT == GET_CODE (XEXP (x, 1))
7561               || ASHIFT == GET_CODE (XEXP (x, 1)))
7562           && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
7563               || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
7564         {
7565           /* multiply-sub */
7566           *total = COSTS_N_INSNS (speed ? 5 : 4);
7567           /* multiply-sub with constant: will be split and load constant. */
7568           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
7569             *total = COSTS_N_INSNS (1) + *total;
7570           return true;
7571         }
7572       /* FALLTHRU */
7573     case AND:
7574     case IOR:
7575       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
7576       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7577       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7578         *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
7579       return true;
7580
7581     case XOR:
7582       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
7583       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7584       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
7585       return true;
7586
7587     case MULT:
7588       switch (mode)
7589         {
7590         case QImode:
7591           if (AVR_HAVE_MUL)
7592             *total = COSTS_N_INSNS (!speed ? 3 : 4);
7593           else if (!speed)
7594             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
7595           else
7596             return false;
7597           break;
7598
7599         case HImode:
7600           if (AVR_HAVE_MUL)
7601             {
7602               rtx op0 = XEXP (x, 0);
7603               rtx op1 = XEXP (x, 1);
7604               enum rtx_code code0 = GET_CODE (op0);
7605               enum rtx_code code1 = GET_CODE (op1);
7606               bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
7607               bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
7608
7609               if (ex0
7610                   && (u8_operand (op1, HImode)
7611                       || s8_operand (op1, HImode)))
7612                 {
7613                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
7614                   return true;
7615                 }
7616               if (ex0
7617                   && register_operand (op1, HImode))
7618                 {
7619                   *total = COSTS_N_INSNS (!speed ? 5 : 8);
7620                   return true;
7621                 }
7622               else if (ex0 || ex1)
7623                 {
7624                   *total = COSTS_N_INSNS (!speed ? 3 : 5);
7625                   return true;
7626                 }
7627               else if (register_operand (op0, HImode)
7628                        && (u8_operand (op1, HImode)
7629                            || s8_operand (op1, HImode)))
7630                 {
7631                   *total = COSTS_N_INSNS (!speed ? 6 : 9);
7632                   return true;
7633                 }
7634               else
7635                 *total = COSTS_N_INSNS (!speed ? 7 : 10);
7636             }
7637           else if (!speed)
7638             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
7639           else
7640             return false;
7641           break;
7642
7643         case PSImode:
7644           if (!speed)
7645             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
7646           else
7647             *total = 10;
7648           break;
7649
7650         case SImode:
7651           if (AVR_HAVE_MUL)
7652             {
7653               if (!speed)
7654                 {
7655                   /* Add some additional costs besides CALL like moves etc.  */
7656
7657                   *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
7658                 }
7659               else
7660                 {
7661                   /* Just a rough estimate.  Even with -O2 we don't want bulky
7662                      code expanded inline.  */
7663
7664                   *total = COSTS_N_INSNS (25);
7665                 }
7666             }
7667           else
7668             {
7669               if (speed)
7670                 *total = COSTS_N_INSNS (300);
7671               else
7672                 /* Add some additional costs besides CALL like moves etc.  */
7673                 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
7674             }
7675           
7676           return true;
7677           
7678         default:
7679           return false;
7680         }
7681       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7682       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
7683       return true;
7684
7685     case DIV:
7686     case MOD:
7687     case UDIV:
7688     case UMOD:
7689       if (!speed)
7690         *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
7691       else
7692         *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
7693       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7694       /* For div/mod with const-int divisor we have at least the cost of
7695          loading the divisor. */
7696       if (CONST_INT_P (XEXP (x, 1)))
7697         *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
7698       /* Add some overall penaly for clobbering and moving around registers */
7699       *total += COSTS_N_INSNS (2);
7700       return true;
7701
7702     case ROTATE:
7703       switch (mode)
7704         {
7705         case QImode:
7706           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
7707             *total = COSTS_N_INSNS (1);
7708
7709           break;
7710
7711         case HImode:
7712           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
7713             *total = COSTS_N_INSNS (3);
7714
7715           break;
7716
7717         case SImode:
7718           if (CONST_INT_P (XEXP (x, 1)))
7719             switch (INTVAL (XEXP (x, 1)))
7720               {
7721               case 8:
7722               case 24:
7723                 *total = COSTS_N_INSNS (5);
7724                 break;
7725               case 16:
7726                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
7727                 break;
7728               }
7729           break;
7730
7731         default:
7732           return false;
7733         }
7734       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7735       return true;    
7736
7737     case ASHIFT:
7738       switch (mode)
7739         {
7740         case QImode:
7741           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7742             {
7743               *total = COSTS_N_INSNS (!speed ? 4 : 17);
7744               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7745                                               speed);
7746             }
7747           else
7748             {
7749               val = INTVAL (XEXP (x, 1));
7750               if (val == 7)
7751                 *total = COSTS_N_INSNS (3);
7752               else if (val >= 0 && val <= 7)
7753                 *total = COSTS_N_INSNS (val);
7754               else
7755                 *total = COSTS_N_INSNS (1);
7756             }
7757           break;
7758
7759         case HImode:
7760           if (AVR_HAVE_MUL)
7761             {
7762               if (const_2_to_7_operand (XEXP (x, 1), HImode)
7763                   && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
7764                       || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
7765                 {
7766                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
7767                   return true;
7768                 }
7769             }
7770           
7771           if (const1_rtx == (XEXP (x, 1))
7772               && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
7773             {
7774               *total = COSTS_N_INSNS (2);
7775               return true;
7776             }
7777           
7778           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7779             {
7780               *total = COSTS_N_INSNS (!speed ? 5 : 41);
7781               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7782                                               speed);
7783             }
7784           else
7785             switch (INTVAL (XEXP (x, 1)))
7786               {
7787               case 0:
7788                 *total = 0;
7789                 break;
7790               case 1:
7791               case 8:
7792                 *total = COSTS_N_INSNS (2);
7793                 break;
7794               case 9:
7795                 *total = COSTS_N_INSNS (3);
7796                 break;
7797               case 2:
7798               case 3:
7799               case 10:
7800               case 15:
7801                 *total = COSTS_N_INSNS (4);
7802                 break;
7803               case 7:
7804               case 11:
7805               case 12:
7806                 *total = COSTS_N_INSNS (5);
7807                 break;
7808               case 4:
7809                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
7810                 break;
7811               case 6:
7812                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
7813                 break;
7814               case 5:
7815                 *total = COSTS_N_INSNS (!speed ? 5 : 10);
7816                 break;
7817               default:
7818                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
7819                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7820                                                 speed);
7821               }
7822           break;
7823
7824         case PSImode:
7825           if (!CONST_INT_P (XEXP (x, 1)))
7826             {
7827               *total = COSTS_N_INSNS (!speed ? 6 : 73);
7828             }
7829           else
7830             switch (INTVAL (XEXP (x, 1)))
7831               {
7832               case 0:
7833                 *total = 0;
7834                 break;
7835               case 1:
7836               case 8:
7837               case 16:
7838                 *total = COSTS_N_INSNS (3);
7839                 break;
7840               case 23:
7841                 *total = COSTS_N_INSNS (5);
7842                 break;
7843               default:
7844                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
7845                 break;
7846               }
7847           break;
7848
7849         case SImode:
7850           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7851             {
7852               *total = COSTS_N_INSNS (!speed ? 7 : 113);
7853               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7854                                               speed);
7855             }
7856           else
7857             switch (INTVAL (XEXP (x, 1)))
7858               {
7859               case 0:
7860                 *total = 0;
7861                 break;
7862               case 24:
7863                 *total = COSTS_N_INSNS (3);
7864                 break;
7865               case 1:
7866               case 8:
7867               case 16:
7868                 *total = COSTS_N_INSNS (4);
7869                 break;
7870               case 31:
7871                 *total = COSTS_N_INSNS (6);
7872                 break;
7873               case 2:
7874                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
7875                 break;
7876               default:
7877                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
7878                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7879                                                 speed);
7880               }
7881           break;
7882
7883         default:
7884           return false;
7885         }
7886       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
7887       return true;
7888
7889     case ASHIFTRT:
7890       switch (mode)
7891         {
7892         case QImode:
7893           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7894             {
7895               *total = COSTS_N_INSNS (!speed ? 4 : 17);
7896               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7897                                               speed);
7898             }
7899           else
7900             {
7901               val = INTVAL (XEXP (x, 1));
7902               if (val == 6)
7903                 *total = COSTS_N_INSNS (4);
7904               else if (val == 7)
7905                 *total = COSTS_N_INSNS (2);
7906               else if (val >= 0 && val <= 7)
7907                 *total = COSTS_N_INSNS (val);
7908               else
7909                 *total = COSTS_N_INSNS (1);
7910             }
7911           break;
7912
7913         case HImode:
7914           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7915             {
7916               *total = COSTS_N_INSNS (!speed ? 5 : 41);
7917               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7918                                               speed);
7919             }
7920           else
7921             switch (INTVAL (XEXP (x, 1)))
7922               {
7923               case 0:
7924                 *total = 0;
7925                 break;
7926               case 1:
7927                 *total = COSTS_N_INSNS (2);
7928                 break;
7929               case 15:
7930                 *total = COSTS_N_INSNS (3);
7931                 break;
7932               case 2:
7933               case 7:
7934               case 8:
7935               case 9:
7936                 *total = COSTS_N_INSNS (4);
7937                 break;
7938               case 10:
7939               case 14:
7940                 *total = COSTS_N_INSNS (5);
7941                 break;
7942               case 11:
7943                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
7944                 break;
7945               case 12:
7946                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
7947                 break;
7948               case 6:
7949               case 13:
7950                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
7951                 break;
7952               default:
7953                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
7954                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7955                                                 speed);
7956               }
7957           break;
7958
7959         case PSImode:
7960           if (!CONST_INT_P (XEXP (x, 1)))
7961             {
7962               *total = COSTS_N_INSNS (!speed ? 6 : 73);
7963             }
7964           else
7965             switch (INTVAL (XEXP (x, 1)))
7966               {
7967               case 0:
7968                 *total = 0;
7969                 break;
7970               case 1:
7971                 *total = COSTS_N_INSNS (3);
7972                 break;
7973               case 16:
7974               case 8:
7975                 *total = COSTS_N_INSNS (5);
7976                 break;
7977               case 23:
7978                 *total = COSTS_N_INSNS (4);
7979                 break;
7980               default:
7981                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
7982                 break;
7983               }
7984           break;
7985
7986         case SImode:
7987           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
7988             {
7989               *total = COSTS_N_INSNS (!speed ? 7 : 113);
7990               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
7991                                               speed);
7992             }
7993           else
7994             switch (INTVAL (XEXP (x, 1)))
7995               {
7996               case 0:
7997                 *total = 0;
7998                 break;
7999               case 1:
8000                 *total = COSTS_N_INSNS (4);
8001                 break;
8002               case 8:
8003               case 16:
8004               case 24:
8005                 *total = COSTS_N_INSNS (6);
8006                 break;
8007               case 2:
8008                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
8009                 break;
8010               case 31:
8011                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
8012                 break;
8013               default:
8014                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
8015                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8016                                                 speed);
8017               }
8018           break;
8019
8020         default:
8021           return false;
8022         }
8023       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8024       return true;
8025
8026     case LSHIFTRT:
8027       switch (mode)
8028         {
8029         case QImode:
8030           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8031             {
8032               *total = COSTS_N_INSNS (!speed ? 4 : 17);
8033               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8034                                               speed);
8035             }
8036           else
8037             {
8038               val = INTVAL (XEXP (x, 1));
8039               if (val == 7)
8040                 *total = COSTS_N_INSNS (3);
8041               else if (val >= 0 && val <= 7)
8042                 *total = COSTS_N_INSNS (val);
8043               else
8044                 *total = COSTS_N_INSNS (1);
8045             }
8046           break;
8047
8048         case HImode:
8049           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8050             {
8051               *total = COSTS_N_INSNS (!speed ? 5 : 41);
8052               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8053                                               speed);
8054             }
8055           else
8056             switch (INTVAL (XEXP (x, 1)))
8057               {
8058               case 0:
8059                 *total = 0;
8060                 break;
8061               case 1:
8062               case 8:
8063                 *total = COSTS_N_INSNS (2);
8064                 break;
8065               case 9:
8066                 *total = COSTS_N_INSNS (3);
8067                 break;
8068               case 2:
8069               case 10:
8070               case 15:
8071                 *total = COSTS_N_INSNS (4);
8072                 break;
8073               case 7:
8074               case 11:
8075                 *total = COSTS_N_INSNS (5);
8076                 break;
8077               case 3:
8078               case 12:
8079               case 13:
8080               case 14:
8081                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
8082                 break;
8083               case 4:
8084                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
8085                 break;
8086               case 5:
8087               case 6:
8088                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
8089                 break;
8090               default:
8091                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
8092                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8093                                                 speed);
8094               }
8095           break;
8096
8097         case PSImode:
8098           if (!CONST_INT_P (XEXP (x, 1)))
8099             {
8100               *total = COSTS_N_INSNS (!speed ? 6 : 73);
8101             }
8102           else
8103             switch (INTVAL (XEXP (x, 1)))
8104               {
8105               case 0:
8106                 *total = 0;
8107                 break;
8108               case 1:
8109               case 8:
8110               case 16:
8111                 *total = COSTS_N_INSNS (3);
8112                 break;
8113               case 23:
8114                 *total = COSTS_N_INSNS (5);
8115                 break;
8116               default:
8117                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
8118                 break;
8119               }
8120           break;
8121
8122         case SImode:
8123           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8124             {
8125               *total = COSTS_N_INSNS (!speed ? 7 : 113);
8126               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8127                                               speed);
8128             }
8129           else
8130             switch (INTVAL (XEXP (x, 1)))
8131               {
8132               case 0:
8133                 *total = 0;
8134                 break;
8135               case 1:
8136                 *total = COSTS_N_INSNS (4);
8137                 break;
8138               case 2:
8139                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
8140                 break;
8141               case 8:
8142               case 16:
8143               case 24:
8144                 *total = COSTS_N_INSNS (4);
8145                 break;
8146               case 31:
8147                 *total = COSTS_N_INSNS (6);
8148                 break;
8149               default:
8150                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
8151                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
8152                                                 speed);
8153               }
8154           break;
8155
8156         default:
8157           return false;
8158         }
8159       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8160       return true;
8161
8162     case COMPARE:
8163       switch (GET_MODE (XEXP (x, 0)))
8164         {
8165         case QImode:
8166           *total = COSTS_N_INSNS (1);
8167           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8168             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8169           break;
8170
8171         case HImode:
8172           *total = COSTS_N_INSNS (2);
8173           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8174             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8175           else if (INTVAL (XEXP (x, 1)) != 0)
8176             *total += COSTS_N_INSNS (1);
8177           break;
8178
8179         case PSImode:
8180           *total = COSTS_N_INSNS (3);
8181           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
8182             *total += COSTS_N_INSNS (2);
8183           break;
8184
8185         case SImode:
8186           *total = COSTS_N_INSNS (4);
8187           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
8188             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
8189           else if (INTVAL (XEXP (x, 1)) != 0)
8190             *total += COSTS_N_INSNS (3);
8191           break;
8192
8193         default:
8194           return false;
8195         }
8196       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
8197       return true;
8198
8199     case TRUNCATE:
8200       if (AVR_HAVE_MUL
8201           && LSHIFTRT == GET_CODE (XEXP (x, 0))
8202           && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
8203           && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
8204         {
8205           if (QImode == mode || HImode == mode)
8206             {
8207               *total = COSTS_N_INSNS (2);
8208               return true;
8209             }
8210         }
8211       break;
8212
8213     default:
8214       break;
8215     }
8216   return false;
8217 }
8218
8219
8220 /* Implement `TARGET_RTX_COSTS'.  */
8221
8222 static bool
8223 avr_rtx_costs (rtx x, int codearg, int outer_code,
8224                int opno, int *total, bool speed)
8225 {
8226   bool done = avr_rtx_costs_1 (x, codearg, outer_code,
8227                                opno, total, speed);
8228
8229   if (avr_log.rtx_costs)
8230     {
8231       avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
8232                  done, speed ? "speed" : "size", *total, outer_code, x);
8233     }
8234
8235   return done;
8236 }
8237
8238
8239 /* Implement `TARGET_ADDRESS_COST'.  */
8240
8241 static int
8242 avr_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
8243 {
8244   int cost = 4;
8245   
8246   if (GET_CODE (x) == PLUS
8247       && CONST_INT_P (XEXP (x, 1))
8248       && (REG_P (XEXP (x, 0))
8249           || GET_CODE (XEXP (x, 0)) == SUBREG))
8250     {
8251       if (INTVAL (XEXP (x, 1)) >= 61)
8252         cost = 18;
8253     }
8254   else if (CONSTANT_ADDRESS_P (x))
8255     {
8256       if (optimize > 0
8257           && io_address_operand (x, QImode))
8258         cost = 2;
8259     }
8260
8261   if (avr_log.address_cost)
8262     avr_edump ("\n%?: %d = %r\n", cost, x);
8263   
8264   return cost;
8265 }
8266
8267 /* Test for extra memory constraint 'Q'.
8268    It's a memory address based on Y or Z pointer with valid displacement.  */
8269
8270 int
8271 extra_constraint_Q (rtx x)
8272 {
8273   int ok = 0;
8274   
8275   if (GET_CODE (XEXP (x,0)) == PLUS
8276       && REG_P (XEXP (XEXP (x,0), 0))
8277       && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
8278       && (INTVAL (XEXP (XEXP (x,0), 1))
8279           <= MAX_LD_OFFSET (GET_MODE (x))))
8280     {
8281       rtx xx = XEXP (XEXP (x,0), 0);
8282       int regno = REGNO (xx);
8283       
8284       ok = (/* allocate pseudos */
8285             regno >= FIRST_PSEUDO_REGISTER
8286             /* strictly check */
8287             || regno == REG_Z || regno == REG_Y
8288             /* XXX frame & arg pointer checks */
8289             || xx == frame_pointer_rtx
8290             || xx == arg_pointer_rtx);
8291       
8292       if (avr_log.constraints)
8293         avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
8294                    ok, reload_completed, reload_in_progress, x);
8295     }
8296
8297   return ok;
8298 }
8299
8300 /* Convert condition code CONDITION to the valid AVR condition code.  */
8301
8302 RTX_CODE
8303 avr_normalize_condition (RTX_CODE condition)
8304 {
8305   switch (condition)
8306     {
8307     case GT:
8308       return GE;
8309     case GTU:
8310       return GEU;
8311     case LE:
8312       return LT;
8313     case LEU:
8314       return LTU;
8315     default:
8316       gcc_unreachable ();
8317     }
8318 }
8319
8320 /* Helper function for `avr_reorg'.  */
8321
8322 static rtx
8323 avr_compare_pattern (rtx insn)
8324 {
8325   rtx pattern = single_set (insn);
8326
8327   if (pattern
8328       && NONJUMP_INSN_P (insn)
8329       && SET_DEST (pattern) == cc0_rtx
8330       && GET_CODE (SET_SRC (pattern)) == COMPARE)
8331     {
8332       return pattern;
8333     }
8334
8335   return NULL_RTX;
8336 }
8337
8338 /* Helper function for `avr_reorg'.  */
8339
8340 /* Expansion of switch/case decision trees leads to code like
8341
8342        cc0 = compare (Reg, Num)
8343        if (cc0 == 0)
8344          goto L1
8345          
8346        cc0 = compare (Reg, Num)
8347        if (cc0 > 0)
8348          goto L2
8349
8350    The second comparison is superfluous and can be deleted.
8351    The second jump condition can be transformed from a
8352    "difficult" one to a "simple" one because "cc0 > 0" and
8353    "cc0 >= 0" will have the same effect here.
8354
8355    This function relies on the way switch/case is being expaned
8356    as binary decision tree.  For example code see PR 49903.
8357          
8358    Return TRUE if optimization performed.
8359    Return FALSE if nothing changed.
8360
8361    INSN1 is a comparison, i.e. avr_compare_pattern != 0.
8362
8363    We don't want to do this in text peephole because it is
8364    tedious to work out jump offsets there and the second comparison
8365    might have been transormed by `avr_reorg'.
8366
8367    RTL peephole won't do because peephole2 does not scan across
8368    basic blocks.  */                
8369                         
8370 static bool
8371 avr_reorg_remove_redundant_compare (rtx insn1)
8372 {
8373   rtx comp1, ifelse1, xcond1, branch1;
8374   rtx comp2, ifelse2, xcond2, branch2, insn2;
8375   enum rtx_code code;
8376   rtx jump, target, cond;
8377   
8378   /* Look out for:  compare1 - branch1 - compare2 - branch2  */
8379
8380   branch1 = next_nonnote_nondebug_insn (insn1);
8381   if (!branch1 || !JUMP_P (branch1))
8382     return false;
8383
8384   insn2 = next_nonnote_nondebug_insn (branch1);
8385   if (!insn2 || !avr_compare_pattern (insn2))
8386     return false;
8387
8388   branch2 = next_nonnote_nondebug_insn (insn2);
8389   if (!branch2 || !JUMP_P (branch2))
8390     return false;
8391
8392   comp1 = avr_compare_pattern (insn1);
8393   comp2 = avr_compare_pattern (insn2);
8394   xcond1 = single_set (branch1);
8395   xcond2 = single_set (branch2);
8396   
8397   if (!comp1 || !comp2
8398       || !rtx_equal_p (comp1, comp2)
8399       || !xcond1 || SET_DEST (xcond1) != pc_rtx
8400       || !xcond2 || SET_DEST (xcond2) != pc_rtx
8401       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
8402       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
8403     {
8404       return false;
8405     }
8406
8407   comp1 = SET_SRC (comp1);
8408   ifelse1 = SET_SRC (xcond1);
8409   ifelse2 = SET_SRC (xcond2);
8410
8411   /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE.  */
8412
8413   if (EQ != GET_CODE (XEXP (ifelse1, 0))
8414       || !REG_P (XEXP (comp1, 0))
8415       || !CONST_INT_P (XEXP (comp1, 1))
8416       || XEXP (ifelse1, 2) != pc_rtx
8417       || XEXP (ifelse2, 2) != pc_rtx
8418       || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
8419       || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
8420       || !COMPARISON_P (XEXP (ifelse2, 0))
8421       || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
8422       || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
8423       || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
8424       || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
8425     {
8426       return false;
8427     }
8428
8429   /* We filtered the insn sequence to look like
8430
8431         (set (cc0)
8432              (compare (reg:M N)
8433                       (const_int VAL)))
8434         (set (pc)
8435              (if_then_else (eq (cc0)
8436                                (const_int 0))
8437                            (label_ref L1)
8438                            (pc)))
8439                            
8440         (set (cc0)
8441              (compare (reg:M N)
8442                       (const_int VAL)))
8443         (set (pc)
8444              (if_then_else (CODE (cc0)
8445                                  (const_int 0))
8446                            (label_ref L2)
8447                            (pc)))
8448   */
8449
8450   code = GET_CODE (XEXP (ifelse2, 0));
8451
8452   /* Map GT/GTU to GE/GEU which is easier for AVR.
8453      The first two instructions compare/branch on EQ
8454      so we may replace the difficult
8455         
8456         if (x == VAL)   goto L1;
8457         if (x > VAL)    goto L2;
8458
8459      with easy
8460          
8461          if (x == VAL)   goto L1;
8462          if (x >= VAL)   goto L2;
8463
8464      Similarly, replace LE/LEU by LT/LTU.  */
8465   
8466   switch (code)
8467     {
8468     case EQ:
8469     case LT:  case LTU:
8470     case GE:  case GEU:
8471       break;
8472
8473     case LE:  case LEU:
8474     case GT:  case GTU:
8475       code = avr_normalize_condition (code);
8476       break;
8477       
8478     default:
8479       return false;
8480     }
8481
8482   /* Wrap the branches into UNSPECs so they won't be changed or
8483      optimized in the remainder.  */
8484
8485   target = XEXP (XEXP (ifelse1, 1), 0);
8486   cond = XEXP (ifelse1, 0);
8487   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
8488
8489   JUMP_LABEL (jump) = JUMP_LABEL (branch1);
8490
8491   target = XEXP (XEXP (ifelse2, 1), 0);
8492   cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
8493   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
8494
8495   JUMP_LABEL (jump) = JUMP_LABEL (branch2);
8496
8497   /* The comparisons in insn1 and insn2 are exactly the same;
8498      insn2 is superfluous so delete it.  */
8499      
8500   delete_insn (insn2);
8501   delete_insn (branch1);
8502   delete_insn (branch2);
8503
8504   return true;
8505 }
8506
8507
8508 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'.  */
8509 /* Optimize conditional jumps.  */
8510
8511 static void
8512 avr_reorg (void)
8513 {
8514   rtx insn = get_insns();
8515   
8516   for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
8517     {
8518       rtx pattern = avr_compare_pattern (insn);
8519       
8520       if (!pattern)
8521         continue;
8522
8523       if (optimize
8524           && avr_reorg_remove_redundant_compare (insn))
8525         {
8526           continue;
8527         }
8528
8529       if (compare_diff_p (insn))
8530         {
8531           /* Now we work under compare insn with difficult branch.  */
8532           
8533           rtx next = next_real_insn (insn);
8534           rtx pat = PATTERN (next);
8535
8536           pattern = SET_SRC (pattern);
8537           
8538           if (true_regnum (XEXP (pattern, 0)) >= 0
8539               && true_regnum (XEXP (pattern, 1)) >= 0)
8540             {
8541               rtx x = XEXP (pattern, 0);
8542               rtx src = SET_SRC (pat);
8543               rtx t = XEXP (src,0);
8544               PUT_CODE (t, swap_condition (GET_CODE (t)));
8545               XEXP (pattern, 0) = XEXP (pattern, 1);
8546               XEXP (pattern, 1) = x;
8547               INSN_CODE (next) = -1;
8548             }
8549           else if (true_regnum (XEXP (pattern, 0)) >= 0
8550                    && XEXP (pattern, 1) == const0_rtx)
8551             {
8552               /* This is a tst insn, we can reverse it.  */
8553               rtx src = SET_SRC (pat);
8554               rtx t = XEXP (src,0);
8555     
8556               PUT_CODE (t, swap_condition (GET_CODE (t)));
8557               XEXP (pattern, 1) = XEXP (pattern, 0);
8558               XEXP (pattern, 0) = const0_rtx;
8559               INSN_CODE (next) = -1;
8560               INSN_CODE (insn) = -1;
8561             }
8562           else if (true_regnum (XEXP (pattern, 0)) >= 0
8563                    && CONST_INT_P (XEXP (pattern, 1)))
8564             {
8565               rtx x = XEXP (pattern, 1);
8566               rtx src = SET_SRC (pat);
8567               rtx t = XEXP (src,0);
8568               enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
8569               
8570               if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
8571                 {
8572                   XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
8573                   PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
8574                   INSN_CODE (next) = -1;
8575                   INSN_CODE (insn) = -1;
8576                 }
8577             }
8578         }
8579     }
8580 }
8581
8582 /* Returns register number for function return value.*/
8583
8584 static inline unsigned int
8585 avr_ret_register (void)
8586 {
8587   return 24;
8588 }
8589
8590 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
8591
8592 static bool
8593 avr_function_value_regno_p (const unsigned int regno)
8594 {
8595   return (regno == avr_ret_register ());
8596 }
8597
8598 /* Create an RTX representing the place where a
8599    library function returns a value of mode MODE.  */
8600
8601 static rtx
8602 avr_libcall_value (enum machine_mode mode,
8603                    const_rtx func ATTRIBUTE_UNUSED)
8604 {
8605   int offs = GET_MODE_SIZE (mode);
8606   
8607   if (offs <= 4)
8608     offs = (offs + 1) & ~1;
8609   
8610   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
8611 }
8612
8613 /* Create an RTX representing the place where a
8614    function returns a value of data type VALTYPE.  */
8615
8616 static rtx
8617 avr_function_value (const_tree type,
8618                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
8619                     bool outgoing ATTRIBUTE_UNUSED)
8620 {
8621   unsigned int offs;
8622
8623   if (TYPE_MODE (type) != BLKmode)
8624     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
8625   
8626   offs = int_size_in_bytes (type);
8627   if (offs < 2)
8628     offs = 2;
8629   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
8630     offs = GET_MODE_SIZE (SImode);
8631   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
8632     offs = GET_MODE_SIZE (DImode);
8633   
8634   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
8635 }
8636
8637 int
8638 test_hard_reg_class (enum reg_class rclass, rtx x)
8639 {
8640   int regno = true_regnum (x);
8641   if (regno < 0)
8642     return 0;
8643
8644   if (TEST_HARD_REG_CLASS (rclass, regno))
8645     return 1;
8646
8647   return 0;
8648 }
8649
8650
8651 /* Helper for jump_over_one_insn_p:  Test if INSN is a 2-word instruction
8652    and thus is suitable to be skipped by CPSE, SBRC, etc.  */
8653
8654 static bool
8655 avr_2word_insn_p (rtx insn)
8656 {
8657   if (avr_current_device->errata_skip
8658       || !insn
8659       || 2 != get_attr_length (insn))
8660     {
8661       return false;
8662     }
8663
8664   switch (INSN_CODE (insn))
8665     {
8666     default:
8667       return false;
8668       
8669     case CODE_FOR_movqi_insn:
8670       {
8671         rtx set  = single_set (insn);
8672         rtx src  = SET_SRC (set);
8673         rtx dest = SET_DEST (set);
8674         
8675         /* Factor out LDS and STS from movqi_insn.  */
8676         
8677         if (MEM_P (dest)
8678             && (REG_P (src) || src == const0_rtx))
8679           {
8680             return CONSTANT_ADDRESS_P (XEXP (dest, 0));
8681           }
8682         else if (REG_P (dest)
8683                  && MEM_P (src))
8684           {
8685             return CONSTANT_ADDRESS_P (XEXP (src, 0));
8686           }
8687         
8688         return false;
8689       }
8690
8691     case CODE_FOR_call_insn:
8692     case CODE_FOR_call_value_insn:
8693       return true;
8694     }
8695 }
8696
8697
8698 int
8699 jump_over_one_insn_p (rtx insn, rtx dest)
8700 {
8701   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
8702                       ? XEXP (dest, 0)
8703                       : dest);
8704   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
8705   int dest_addr = INSN_ADDRESSES (uid);
8706   int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
8707   
8708   return (jump_offset == 1
8709           || (jump_offset == 2
8710               && avr_2word_insn_p (next_active_insn (insn))));
8711 }
8712
8713 /* Returns 1 if a value of mode MODE can be stored starting with hard
8714    register number REGNO.  On the enhanced core, anything larger than
8715    1 byte must start in even numbered register for "movw" to work
8716    (this way we don't have to check for odd registers everywhere).  */
8717
8718 int
8719 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
8720 {
8721   /* NOTE: 8-bit values must not be disallowed for R28 or R29.
8722         Disallowing QI et al. in these regs might lead to code like
8723             (set (subreg:QI (reg:HI 28) n) ...)
8724         which will result in wrong code because reload does not
8725         handle SUBREGs of hard regsisters like this.
8726         This could be fixed in reload.  However, it appears
8727         that fixing reload is not wanted by reload people.  */
8728   
8729   /* Any GENERAL_REGS register can hold 8-bit values.  */
8730   
8731   if (GET_MODE_SIZE (mode) == 1)
8732     return 1;
8733
8734   /* FIXME: Ideally, the following test is not needed.
8735         However, it turned out that it can reduce the number
8736         of spill fails.  AVR and it's poor endowment with
8737         address registers is extreme stress test for reload.  */
8738   
8739   if (GET_MODE_SIZE (mode) >= 4
8740       && regno >= REG_X)
8741     return 0;
8742
8743   /* All modes larger than 8 bits should start in an even register.  */
8744   
8745   return !(regno & 1);
8746 }
8747
8748
8749 /* Implement `MODE_CODE_BASE_REG_CLASS'.  */
8750
8751 reg_class_t
8752 avr_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
8753                               addr_space_t as, RTX_CODE outer_code,
8754                               RTX_CODE index_code ATTRIBUTE_UNUSED)
8755 {
8756   if (!ADDR_SPACE_GENERIC_P (as))
8757     {
8758       return POINTER_Z_REGS;
8759     }
8760  
8761   if (!avr_strict_X)
8762     return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
8763
8764   return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
8765 }
8766
8767
8768 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'.  */
8769
8770 bool
8771 avr_regno_mode_code_ok_for_base_p (int regno,
8772                                    enum machine_mode mode ATTRIBUTE_UNUSED,
8773                                    addr_space_t as ATTRIBUTE_UNUSED,
8774                                    RTX_CODE outer_code,
8775                                    RTX_CODE index_code ATTRIBUTE_UNUSED)
8776 {
8777   bool ok = false;
8778   
8779   if (!ADDR_SPACE_GENERIC_P (as))
8780     {
8781       if (regno < FIRST_PSEUDO_REGISTER
8782           && regno == REG_Z)
8783         {
8784           return true;
8785         }
8786       
8787       if (reg_renumber)
8788         {
8789           regno = reg_renumber[regno];
8790           
8791           if (regno == REG_Z)
8792             {
8793               return true;
8794             }
8795         }
8796       
8797       return false;
8798     }
8799
8800   if (regno < FIRST_PSEUDO_REGISTER
8801       && (regno == REG_X
8802           || regno == REG_Y
8803           || regno == REG_Z
8804           || regno == ARG_POINTER_REGNUM))
8805     {
8806       ok = true;
8807     }
8808   else if (reg_renumber)
8809     {
8810       regno = reg_renumber[regno];
8811
8812       if (regno == REG_X
8813           || regno == REG_Y
8814           || regno == REG_Z
8815           || regno == ARG_POINTER_REGNUM)
8816         {
8817           ok = true;
8818         }
8819     }
8820
8821   if (avr_strict_X
8822       && PLUS == outer_code
8823       && regno == REG_X)
8824     {
8825       ok = false;
8826     }
8827
8828   return ok;
8829 }
8830
8831
8832 /* A helper for `output_reload_insisf' and `output_reload_inhi'.  */
8833 /* Set 32-bit register OP[0] to compile-time constant OP[1].
8834    CLOBBER_REG is a QI clobber register or NULL_RTX.
8835    LEN == NULL: output instructions.
8836    LEN != NULL: set *LEN to the length of the instruction sequence
8837                 (in words) printed with LEN = NULL.
8838    If CLEAR_P is true, OP[0] had been cleard to Zero already.
8839    If CLEAR_P is false, nothing is known about OP[0].
8840
8841    The effect on cc0 is as follows:
8842
8843    Load 0 to any register          : NONE
8844    Load ld register with any value : NONE
8845    Anything else:                  : CLOBBER  */
8846
8847 static void
8848 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
8849 {
8850   rtx src = op[1];
8851   rtx dest = op[0];
8852   rtx xval, xdest[4];
8853   int ival[4];
8854   int clobber_val = 1234;
8855   bool cooked_clobber_p = false;
8856   bool set_p = false;
8857   enum machine_mode mode = GET_MODE (dest);
8858   int n, n_bytes = GET_MODE_SIZE (mode);
8859   
8860   gcc_assert (REG_P (dest)
8861               && CONSTANT_P (src));
8862
8863   if (len)
8864     *len = 0;
8865   
8866   /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
8867      but has some subregs that are in LD_REGS.  Use the MSB (REG:QI 17).  */
8868   
8869   if (REGNO (dest) < 16
8870       && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
8871     {
8872       clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
8873     }
8874
8875   /* We might need a clobber reg but don't have one.  Look at the value to
8876      be loaded more closely.  A clobber is only needed if it is a symbol
8877      or contains a byte that is neither 0, -1 or a power of 2.  */
8878   
8879   if (NULL_RTX == clobber_reg
8880       && !test_hard_reg_class (LD_REGS, dest)
8881       && (! (CONST_INT_P (src) || CONST_DOUBLE_P (src))
8882           || !avr_popcount_each_byte (src, n_bytes,
8883                                       (1 << 0) | (1 << 1) | (1 << 8))))
8884     {
8885       /* We have no clobber register but need one.  Cook one up.
8886          That's cheaper than loading from constant pool.  */
8887       
8888       cooked_clobber_p = true;
8889       clobber_reg = all_regs_rtx[REG_Z + 1];
8890       avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
8891     }
8892
8893   /* Now start filling DEST from LSB to MSB.  */
8894   
8895   for (n = 0; n < n_bytes; n++)
8896     {
8897       int ldreg_p;
8898       bool done_byte = false;
8899       int j;
8900       rtx xop[3];
8901
8902       /* Crop the n-th destination byte.  */
8903
8904       xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
8905       ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
8906
8907       if (!CONST_INT_P (src)
8908           && !CONST_DOUBLE_P (src))
8909         {
8910           static const char* const asm_code[][2] =
8911             {
8912               { "ldi %2,lo8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,lo8(%1)"  },
8913               { "ldi %2,hi8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,hi8(%1)"  },
8914               { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hlo8(%1)" },
8915               { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hhi8(%1)" }
8916             };
8917           
8918           xop[0] = xdest[n];
8919           xop[1] = src;
8920           xop[2] = clobber_reg;
8921
8922           if (n >= 2 + (avr_current_arch->n_segments > 1))
8923             avr_asm_len ("mov %0,__zero_reg__", xop, len, 1);
8924           else
8925             avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
8926           continue;
8927         }
8928
8929       /* Crop the n-th source byte.  */
8930
8931       xval = simplify_gen_subreg (QImode, src, mode, n);
8932       ival[n] = INTVAL (xval);
8933
8934       /* Look if we can reuse the low word by means of MOVW.  */
8935       
8936       if (n == 2
8937           && n_bytes >= 4
8938           && AVR_HAVE_MOVW)
8939         {
8940           rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
8941           rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
8942
8943           if (INTVAL (lo16) == INTVAL (hi16))
8944             {
8945               if (0 != INTVAL (lo16)
8946                   || !clear_p)
8947                 {
8948                   avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
8949                 }
8950               
8951               break;
8952             }
8953         }
8954
8955       /* Don't use CLR so that cc0 is set as expected.  */
8956       
8957       if (ival[n] == 0)
8958         {
8959           if (!clear_p)
8960             avr_asm_len (ldreg_p ? "ldi %0,0" : "mov %0,__zero_reg__",
8961                          &xdest[n], len, 1);
8962           continue;
8963         }
8964
8965       if (clobber_val == ival[n]
8966           && REGNO (clobber_reg) == REGNO (xdest[n]))
8967         {
8968           continue;
8969         }
8970
8971       /* LD_REGS can use LDI to move a constant value */
8972       
8973       if (ldreg_p)
8974         {
8975           xop[0] = xdest[n];
8976           xop[1] = xval;
8977           avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
8978           continue;
8979         }
8980
8981       /* Try to reuse value already loaded in some lower byte. */
8982       
8983       for (j = 0; j < n; j++)
8984         if (ival[j] == ival[n])
8985           {
8986             xop[0] = xdest[n];
8987             xop[1] = xdest[j];
8988             
8989             avr_asm_len ("mov %0,%1", xop, len, 1);
8990             done_byte = true;
8991             break;
8992           }
8993
8994       if (done_byte)
8995         continue;
8996
8997       /* Need no clobber reg for -1: Use CLR/DEC */
8998       
8999       if (-1 == ival[n])
9000         {
9001           if (!clear_p)
9002             avr_asm_len ("clr %0", &xdest[n], len, 1);
9003           
9004           avr_asm_len ("dec %0", &xdest[n], len, 1);
9005           continue;
9006         }
9007       else if (1 == ival[n])
9008         {
9009           if (!clear_p)
9010             avr_asm_len ("clr %0", &xdest[n], len, 1);
9011           
9012           avr_asm_len ("inc %0", &xdest[n], len, 1);
9013           continue;
9014         }
9015
9016       /* Use T flag or INC to manage powers of 2 if we have
9017          no clobber reg.  */
9018
9019       if (NULL_RTX == clobber_reg
9020           && single_one_operand (xval, QImode))
9021         {
9022           xop[0] = xdest[n];
9023           xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
9024
9025           gcc_assert (constm1_rtx != xop[1]);
9026
9027           if (!set_p)
9028             {
9029               set_p = true;
9030               avr_asm_len ("set", xop, len, 1);
9031             }
9032
9033           if (!clear_p)
9034             avr_asm_len ("clr %0", xop, len, 1);
9035           
9036           avr_asm_len ("bld %0,%1", xop, len, 1);
9037           continue;
9038         }
9039
9040       /* We actually need the LD_REGS clobber reg.  */
9041
9042       gcc_assert (NULL_RTX != clobber_reg);
9043         
9044       xop[0] = xdest[n];
9045       xop[1] = xval;
9046       xop[2] = clobber_reg;
9047       clobber_val = ival[n];
9048         
9049       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
9050                    "mov %0,%2", xop, len, 2);
9051     }
9052   
9053   /* If we cooked up a clobber reg above, restore it.  */
9054   
9055   if (cooked_clobber_p)
9056     {
9057       avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
9058     }
9059 }
9060
9061
9062 /* Reload the constant OP[1] into the HI register OP[0].
9063    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
9064    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
9065    need a clobber reg or have to cook one up.
9066
9067    PLEN == NULL: Output instructions.
9068    PLEN != NULL: Output nothing.  Set *PLEN to number of words occupied
9069                  by the insns printed.
9070
9071    Return "".  */
9072
9073 const char*
9074 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
9075 {
9076   output_reload_in_const (op, clobber_reg, plen, false);
9077   return "";
9078 }
9079
9080
9081 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
9082    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
9083    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
9084    need a clobber reg or have to cook one up.
9085
9086    LEN == NULL: Output instructions.
9087    
9088    LEN != NULL: Output nothing.  Set *LEN to number of words occupied
9089                 by the insns printed.
9090
9091    Return "".  */
9092
9093 const char *
9094 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
9095 {
9096   if (AVR_HAVE_MOVW
9097       && !test_hard_reg_class (LD_REGS, op[0])
9098       && (CONST_INT_P (op[1])
9099           || CONST_DOUBLE_P (op[1])))
9100     {
9101       int len_clr, len_noclr;
9102       
9103       /* In some cases it is better to clear the destination beforehand, e.g.
9104
9105              CLR R2   CLR R3   MOVW R4,R2   INC R2
9106
9107          is shorther than
9108
9109              CLR R2   INC R2   CLR  R3      CLR R4   CLR R5
9110
9111          We find it too tedious to work that out in the print function.
9112          Instead, we call the print function twice to get the lengths of
9113          both methods and use the shortest one.  */
9114          
9115       output_reload_in_const (op, clobber_reg, &len_clr, true);
9116       output_reload_in_const (op, clobber_reg, &len_noclr, false);
9117       
9118       if (len_noclr - len_clr == 4)
9119         {
9120           /* Default needs 4 CLR instructions: clear register beforehand.  */
9121           
9122           avr_asm_len ("clr %A0" CR_TAB
9123                        "clr %B0" CR_TAB
9124                        "movw %C0,%A0", &op[0], len, 3);
9125           
9126           output_reload_in_const (op, clobber_reg, len, true);
9127           
9128           if (len)
9129             *len += 3;
9130
9131           return "";
9132         }
9133     }
9134
9135   /* Default: destination not pre-cleared.  */
9136
9137   output_reload_in_const (op, clobber_reg, len, false);
9138   return "";
9139 }
9140
9141 const char *
9142 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
9143 {
9144   output_reload_in_const (op, clobber_reg, len, false);
9145   return "";
9146 }
9147
9148 void
9149 avr_output_bld (rtx operands[], int bit_nr)
9150 {
9151   static char s[] = "bld %A0,0";
9152
9153   s[5] = 'A' + (bit_nr >> 3);
9154   s[8] = '0' + (bit_nr & 7);
9155   output_asm_insn (s, operands);
9156 }
9157
9158 void
9159 avr_output_addr_vec_elt (FILE *stream, int value)
9160 {
9161   if (AVR_HAVE_JMP_CALL)
9162     fprintf (stream, "\t.word gs(.L%d)\n", value);
9163   else
9164     fprintf (stream, "\trjmp .L%d\n", value);
9165 }
9166
9167 /* Returns true if SCRATCH are safe to be allocated as a scratch
9168    registers (for a define_peephole2) in the current function.  */
9169
9170 static bool
9171 avr_hard_regno_scratch_ok (unsigned int regno)
9172 {
9173   /* Interrupt functions can only use registers that have already been saved
9174      by the prologue, even if they would normally be call-clobbered.  */
9175
9176   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
9177       && !df_regs_ever_live_p (regno))
9178     return false;
9179
9180   /* Don't allow hard registers that might be part of the frame pointer.
9181      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
9182      and don't care for a frame pointer that spans more than one register.  */
9183
9184   if ((!reload_completed || frame_pointer_needed)
9185       && (regno == REG_Y || regno == REG_Y + 1))
9186     {
9187       return false;
9188     }
9189
9190   return true;
9191 }
9192
9193 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
9194
9195 int
9196 avr_hard_regno_rename_ok (unsigned int old_reg,
9197                           unsigned int new_reg)
9198 {
9199   /* Interrupt functions can only use registers that have already been
9200      saved by the prologue, even if they would normally be
9201      call-clobbered.  */
9202
9203   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
9204       && !df_regs_ever_live_p (new_reg))
9205     return 0;
9206
9207   /* Don't allow hard registers that might be part of the frame pointer.
9208      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
9209      and don't care for a frame pointer that spans more than one register.  */
9210
9211   if ((!reload_completed || frame_pointer_needed)
9212       && (old_reg == REG_Y || old_reg == REG_Y + 1
9213           || new_reg == REG_Y || new_reg == REG_Y + 1))
9214     {
9215       return 0;
9216     }
9217   
9218   return 1;
9219 }
9220
9221 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
9222    or memory location in the I/O space (QImode only).
9223
9224    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
9225    Operand 1: register operand to test, or CONST_INT memory address.
9226    Operand 2: bit number.
9227    Operand 3: label to jump to if the test is true.  */
9228
9229 const char *
9230 avr_out_sbxx_branch (rtx insn, rtx operands[])
9231 {
9232   enum rtx_code comp = GET_CODE (operands[0]);
9233   bool long_jump = get_attr_length (insn) >= 4;
9234   bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
9235
9236   if (comp == GE)
9237     comp = EQ;
9238   else if (comp == LT)
9239     comp = NE;
9240
9241   if (reverse)
9242     comp = reverse_condition (comp);
9243
9244   switch (GET_CODE (operands[1]))
9245     {
9246     default:
9247       gcc_unreachable();
9248       
9249     case CONST_INT:
9250
9251       if (low_io_address_operand (operands[1], QImode))
9252         {
9253           if (comp == EQ)
9254             output_asm_insn ("sbis %i1,%2", operands);
9255           else
9256             output_asm_insn ("sbic %i1,%2", operands);
9257         }
9258       else
9259         {
9260           output_asm_insn ("in __tmp_reg__,%i1", operands);
9261           if (comp == EQ)
9262             output_asm_insn ("sbrs __tmp_reg__,%2", operands);
9263           else
9264             output_asm_insn ("sbrc __tmp_reg__,%2", operands);
9265         }
9266
9267       break; /* CONST_INT */
9268
9269     case REG:
9270
9271       if (GET_MODE (operands[1]) == QImode)
9272         {
9273           if (comp == EQ)
9274             output_asm_insn ("sbrs %1,%2", operands);
9275           else
9276             output_asm_insn ("sbrc %1,%2", operands);
9277         }
9278       else  /* HImode, PSImode or SImode */
9279         {
9280           static char buf[] = "sbrc %A1,0";
9281           unsigned int bit_nr = UINTVAL (operands[2]);
9282
9283           buf[3] = (comp == EQ) ? 's' : 'c';
9284           buf[6] = 'A' + (bit_nr / 8);
9285           buf[9] = '0' + (bit_nr % 8);
9286           output_asm_insn (buf, operands);
9287         }
9288
9289       break; /* REG */
9290     }        /* switch */
9291
9292   if (long_jump)
9293     return ("rjmp .+4" CR_TAB
9294             "jmp %x3");
9295
9296   if (!reverse)
9297     return "rjmp %x3";
9298
9299   return "";
9300 }
9301
9302 /* Worker function for TARGET_ASM_CONSTRUCTOR.  */
9303
9304 static void
9305 avr_asm_out_ctor (rtx symbol, int priority)
9306 {
9307   fputs ("\t.global __do_global_ctors\n", asm_out_file);
9308   default_ctor_section_asm_out_constructor (symbol, priority);
9309 }
9310
9311 /* Worker function for TARGET_ASM_DESTRUCTOR.  */
9312
9313 static void
9314 avr_asm_out_dtor (rtx symbol, int priority)
9315 {
9316   fputs ("\t.global __do_global_dtors\n", asm_out_file);
9317   default_dtor_section_asm_out_destructor (symbol, priority);
9318 }
9319
9320 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
9321
9322 static bool
9323 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
9324 {
9325   if (TYPE_MODE (type) == BLKmode)
9326     {
9327       HOST_WIDE_INT size = int_size_in_bytes (type);
9328       return (size == -1 || size > 8);
9329     }
9330   else
9331     return false;
9332 }
9333
9334 /* Worker function for CASE_VALUES_THRESHOLD.  */
9335
9336 static unsigned int
9337 avr_case_values_threshold (void)
9338 {
9339   return (!AVR_HAVE_JMP_CALL || TARGET_CALL_PROLOGUES) ? 8 : 17;
9340 }
9341
9342
9343 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'.  */
9344
9345 static enum machine_mode
9346 avr_addr_space_address_mode (addr_space_t as)
9347 {
9348   return as == ADDR_SPACE_PGMX ? PSImode : HImode;
9349 }
9350
9351
9352 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'.  */
9353
9354 static enum machine_mode
9355 avr_addr_space_pointer_mode (addr_space_t as)
9356 {
9357   return as == ADDR_SPACE_PGMX ? PSImode : HImode;
9358 }
9359
9360
9361 /* Helper for following function.  */
9362
9363 static bool
9364 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
9365 {
9366   gcc_assert (REG_P (reg));
9367
9368   if (strict)
9369     {
9370       return REGNO (reg) == REG_Z;
9371     }
9372   
9373   /* Avoid combine to propagate hard regs.  */
9374   
9375   if (can_create_pseudo_p()
9376       && REGNO (reg) < REG_Z)
9377     {
9378       return false;
9379     }
9380   
9381   return true;
9382 }
9383
9384
9385 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'.  */
9386
9387 static bool
9388 avr_addr_space_legitimate_address_p (enum machine_mode mode, rtx x,
9389                                      bool strict, addr_space_t as)
9390 {
9391   bool ok = false;
9392
9393   switch (as)
9394     {
9395     default:
9396       gcc_unreachable();
9397       
9398     case ADDR_SPACE_GENERIC:
9399       return avr_legitimate_address_p (mode, x, strict);
9400
9401     case ADDR_SPACE_PGM:
9402     case ADDR_SPACE_PGM1:
9403     case ADDR_SPACE_PGM2:
9404     case ADDR_SPACE_PGM3:
9405     case ADDR_SPACE_PGM4:
9406     case ADDR_SPACE_PGM5:
9407
9408       switch (GET_CODE (x))
9409         {
9410         case REG:
9411           ok = avr_reg_ok_for_pgm_addr (x, strict);
9412           break;
9413           
9414         case POST_INC:
9415           ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
9416           break;
9417           
9418         default:
9419           break;
9420         }
9421
9422       break; /* PGM */
9423       
9424     case ADDR_SPACE_PGMX:
9425       if (REG_P (x))
9426         ok = (!strict
9427               && can_create_pseudo_p());
9428
9429       if (LO_SUM == GET_CODE (x))
9430         {
9431           rtx hi = XEXP (x, 0);
9432           rtx lo = XEXP (x, 1);
9433
9434           ok = (REG_P (hi)
9435                 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
9436                 && REG_P (lo)
9437                 && REGNO (lo) == REG_Z);
9438         }
9439       
9440       break; /* PGMX */
9441     }
9442
9443   if (avr_log.legitimate_address_p)
9444     {
9445       avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
9446                  "reload_completed=%d reload_in_progress=%d %s:",
9447                  ok, mode, strict, reload_completed, reload_in_progress,
9448                  reg_renumber ? "(reg_renumber)" : "");
9449       
9450       if (GET_CODE (x) == PLUS
9451           && REG_P (XEXP (x, 0))
9452           && CONST_INT_P (XEXP (x, 1))
9453           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
9454           && reg_renumber)
9455         {
9456           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
9457                      true_regnum (XEXP (x, 0)));
9458         }
9459       
9460       avr_edump ("\n%r\n", x);
9461     }
9462
9463   return ok;
9464 }
9465
9466
9467 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'.  */
9468
9469 static rtx
9470 avr_addr_space_legitimize_address (rtx x, rtx old_x,
9471                                    enum machine_mode mode, addr_space_t as)
9472 {
9473   if (ADDR_SPACE_GENERIC_P (as))
9474     return avr_legitimize_address (x, old_x, mode);
9475
9476   if (avr_log.legitimize_address)
9477     {
9478       avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
9479     }
9480
9481   return old_x;
9482 }
9483
9484
9485 /* Implement `TARGET_ADDR_SPACE_CONVERT'.  */
9486
9487 static rtx
9488 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
9489 {
9490   addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
9491   addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
9492
9493   if (avr_log.progmem)
9494     avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
9495                src, type_from, type_to);
9496
9497   if (as_from != ADDR_SPACE_PGMX
9498       && as_to == ADDR_SPACE_PGMX)
9499     {
9500       rtx new_src;
9501       int n_segments = avr_current_arch->n_segments;
9502       RTX_CODE code = GET_CODE (src);
9503
9504       if (CONST == code
9505           && PLUS == GET_CODE (XEXP (src, 0))
9506           && SYMBOL_REF == GET_CODE (XEXP (XEXP (src, 0), 0))
9507           && CONST_INT_P (XEXP (XEXP (src, 0), 1)))
9508         {
9509           HOST_WIDE_INT offset = INTVAL (XEXP (XEXP (src, 0), 1));
9510           const char *name = XSTR (XEXP (XEXP (src, 0), 0), 0);
9511           
9512           new_src = gen_rtx_SYMBOL_REF (PSImode, ggc_strdup (name));
9513           new_src = gen_rtx_CONST (PSImode,
9514                                    plus_constant (new_src, offset));
9515           return new_src;
9516         }
9517
9518       if (SYMBOL_REF == code)
9519           {
9520             const char *name = XSTR (src, 0);
9521             
9522             return gen_rtx_SYMBOL_REF (PSImode, ggc_strdup (name));
9523           }
9524       
9525       src = force_reg (Pmode, src);
9526       
9527       if (ADDR_SPACE_GENERIC_P (as_from)
9528           || as_from == ADDR_SPACE_PGM
9529           || n_segments == 1)
9530         {
9531           return gen_rtx_ZERO_EXTEND (PSImode, src);
9532         }
9533       else
9534         {
9535           int segment = avr_pgm_segment (as_from) % n_segments;
9536
9537           new_src = gen_reg_rtx (PSImode);
9538           emit_insn (gen_n_extendhipsi2 (new_src, GEN_INT (segment), src));
9539
9540           return new_src;
9541         }
9542     }
9543   
9544   return src;
9545 }
9546
9547
9548 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'.  */
9549
9550 static bool
9551 avr_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
9552 {
9553   if (subset == ADDR_SPACE_PGMX
9554       && superset != ADDR_SPACE_PGMX)
9555     {
9556       return false;
9557     }
9558   
9559   return true;
9560 }
9561
9562
9563 /* Worker function for movmemhi insn.
9564    XOP[0]  Destination as MEM:BLK
9565    XOP[1]  Source      "     "
9566    XOP[2]  # Bytes to copy
9567
9568    Return TRUE  if the expansion is accomplished.
9569    Return FALSE if the operand compination is not supported.  */
9570
9571 bool
9572 avr_emit_movmemhi (rtx *xop)
9573 {
9574   HOST_WIDE_INT count;
9575   enum machine_mode loop_mode;
9576   addr_space_t as = MEM_ADDR_SPACE (xop[1]);
9577   rtx loop_reg, addr0, addr1, a_src, a_dest, insn, xas, reg_x;
9578   rtx a_hi8 = NULL_RTX;
9579
9580   if (avr_mem_pgm_p (xop[0]))
9581     return false;
9582
9583   if (!CONST_INT_P (xop[2]))
9584     return false;
9585
9586   count = INTVAL (xop[2]);
9587   if (count <= 0)
9588     return false;
9589
9590   a_src  = XEXP (xop[1], 0);
9591   a_dest = XEXP (xop[0], 0);
9592
9593   /* See if constant fits in 8 bits.  */
9594
9595   loop_mode = (count <= 0x100) ? QImode : HImode;
9596
9597   if (PSImode == GET_MODE (a_src))
9598     {
9599       addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
9600       a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
9601     }
9602   else
9603     {
9604       int seg = avr_pgm_segment (as);
9605       
9606       addr1 = a_src;
9607
9608       if (seg > 0
9609           && seg % avr_current_arch->n_segments > 0)
9610         {
9611           a_hi8 = GEN_INT (seg % avr_current_arch->n_segments);
9612         }
9613     }
9614
9615   if (a_hi8
9616       && avr_current_arch->n_segments > 1)
9617     {
9618       emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
9619     }
9620   else if (!ADDR_SPACE_GENERIC_P (as))
9621     {
9622       as = ADDR_SPACE_PGM;
9623     }
9624
9625   xas = GEN_INT (as);
9626
9627   /* Create loop counter register */
9628
9629   loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
9630
9631   /* Copy pointers into new pseudos - they will be changed */
9632
9633   addr0 = copy_to_mode_reg (HImode, a_dest);
9634   addr1 = copy_to_mode_reg (HImode, addr1);
9635
9636   /* FIXME: Register allocator might come up with spill fails if it is left
9637         on its own.  Thus, we allocate the pointer registers by hand.  */
9638
9639   emit_move_insn (lpm_addr_reg_rtx, addr1);
9640   addr1 = lpm_addr_reg_rtx;
9641
9642   reg_x = gen_rtx_REG (HImode, REG_X);
9643   emit_move_insn (reg_x, addr0);
9644   addr0 = reg_x;
9645
9646   /* FIXME: Register allocator does a bad job and might spill address
9647         register(s) inside the loop leading to additional move instruction
9648         to/from stack which could clobber tmp_reg.  Thus, do *not* emit
9649         load and store as seperate insns.  Instead, we perform the copy
9650         by means of one monolithic insn.  */
9651
9652   if (ADDR_SPACE_GENERIC_P (as))
9653     {
9654       rtx (*fun) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx)
9655         = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
9656
9657       insn = fun (addr0, addr1, xas, loop_reg,
9658                   addr0, addr1, tmp_reg_rtx, loop_reg);
9659     }
9660   else if (as == ADDR_SPACE_PGM)
9661     {
9662       rtx (*fun) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx)
9663         = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
9664
9665       insn = fun (addr0, addr1, xas, loop_reg, addr0, addr1,
9666                   AVR_HAVE_LPMX ? tmp_reg_rtx : lpm_reg_rtx, loop_reg);
9667     }
9668   else
9669     {
9670       rtx (*fun) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx)
9671         = QImode == loop_mode ? gen_movmem_qi_elpm : gen_movmem_hi_elpm;
9672       
9673       insn = fun (addr0, addr1, xas, loop_reg, addr0, addr1,
9674                   AVR_HAVE_ELPMX ? tmp_reg_rtx : lpm_reg_rtx, loop_reg,
9675                   a_hi8, a_hi8, GEN_INT (RAMPZ_ADDR));
9676     }
9677
9678   set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
9679   emit_insn (insn);
9680
9681   return true;
9682 }
9683
9684
9685 /* Print assembler for movmem_qi, movmem_hi insns...
9686        $0, $4 : & dest
9687        $1, $5 : & src
9688        $2     : Address Space
9689        $3, $7 : Loop register
9690        $6     : Scratch register
9691
9692    ...and movmem_qi_elpm, movmem_hi_elpm insns.
9693    
9694        $8, $9 : hh8 (& src)
9695        $10    : RAMPZ_ADDR
9696 */
9697
9698 const char*
9699 avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
9700 {
9701   addr_space_t as = (addr_space_t) INTVAL (xop[2]);
9702   enum machine_mode loop_mode = GET_MODE (xop[3]);
9703
9704   bool sbiw_p = test_hard_reg_class (ADDW_REGS, xop[3]);
9705
9706   gcc_assert (REG_X == REGNO (xop[0])
9707               && REG_Z == REGNO (xop[1]));
9708
9709   if (plen)
9710     *plen = 0;
9711
9712   /* Loop label */
9713
9714   avr_asm_len ("0:", xop, plen, 0);
9715
9716   /* Load with post-increment */
9717
9718   switch (as)
9719     {
9720     default:
9721       gcc_unreachable();
9722       
9723     case ADDR_SPACE_GENERIC:
9724
9725       avr_asm_len ("ld %6,%a1+", xop, plen, 1);
9726       break;
9727       
9728     case ADDR_SPACE_PGM:
9729
9730       if (AVR_HAVE_LPMX)
9731         avr_asm_len ("lpm %6,%a1+", xop, plen, 1);
9732       else
9733         avr_asm_len ("lpm" CR_TAB
9734                      "adiw %1,1", xop, plen, 2);
9735       break;
9736       
9737     case ADDR_SPACE_PGM1:
9738     case ADDR_SPACE_PGM2:
9739     case ADDR_SPACE_PGM3:
9740     case ADDR_SPACE_PGM4:
9741     case ADDR_SPACE_PGM5:
9742     case ADDR_SPACE_PGMX:
9743
9744       if (AVR_HAVE_ELPMX)
9745         avr_asm_len ("elpm %6,%a1+", xop, plen, 1);
9746       else
9747         avr_asm_len ("elpm" CR_TAB
9748                      "adiw %1,1", xop, plen, 2);
9749       
9750       if (as == ADDR_SPACE_PGMX
9751           && !AVR_HAVE_ELPMX)
9752         {
9753           avr_asm_len ("adc %8,__zero_reg__" CR_TAB
9754                        "out __RAMPZ__,%8", xop, plen, 2);
9755         }
9756       
9757       break;
9758     }
9759
9760   /* Store with post-increment */
9761
9762   avr_asm_len ("st %a0+,%6", xop, plen, 1);
9763
9764   /* Decrement loop-counter and set Z-flag */
9765
9766   if (QImode == loop_mode)
9767     {
9768       avr_asm_len ("dec %3", xop, plen, 1);
9769     }
9770   else if (sbiw_p)
9771     {
9772       avr_asm_len ("sbiw %3,1", xop, plen, 1);
9773     }
9774   else
9775     {
9776       avr_asm_len ("subi %A3,1" CR_TAB
9777                    "sbci %B3,0", xop, plen, 2);
9778     }
9779
9780   /* Loop until zero */
9781   
9782   return avr_asm_len ("brne 0b", xop, plen, 1);
9783 }
9784
9785
9786 \f
9787 /* Helper for __builtin_avr_delay_cycles */
9788
9789 static void
9790 avr_expand_delay_cycles (rtx operands0)
9791 {
9792   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0);
9793   unsigned HOST_WIDE_INT cycles_used;
9794   unsigned HOST_WIDE_INT loop_count;
9795   
9796   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
9797     {
9798       loop_count = ((cycles - 9) / 6) + 1;
9799       cycles_used = ((loop_count - 1) * 6) + 9;
9800       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode)));
9801       cycles -= cycles_used;
9802     }
9803   
9804   if (IN_RANGE (cycles, 262145, 83886081))
9805     {
9806       loop_count = ((cycles - 7) / 5) + 1;
9807       if (loop_count > 0xFFFFFF)
9808         loop_count = 0xFFFFFF;
9809       cycles_used = ((loop_count - 1) * 5) + 7;
9810       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode)));
9811       cycles -= cycles_used;
9812     }
9813   
9814   if (IN_RANGE (cycles, 768, 262144))
9815     {
9816       loop_count = ((cycles - 5) / 4) + 1;
9817       if (loop_count > 0xFFFF)
9818         loop_count = 0xFFFF;
9819       cycles_used = ((loop_count - 1) * 4) + 5;
9820       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode)));
9821       cycles -= cycles_used;
9822     }
9823   
9824   if (IN_RANGE (cycles, 6, 767))
9825     {
9826       loop_count = cycles / 3;
9827       if (loop_count > 255) 
9828         loop_count = 255;
9829       cycles_used = loop_count * 3;
9830       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode)));
9831       cycles -= cycles_used;
9832       }
9833   
9834   while (cycles >= 2)
9835     {
9836       emit_insn (gen_nopv (GEN_INT(2)));
9837       cycles -= 2;
9838     }
9839
9840   if (cycles == 1)
9841     {
9842       emit_insn (gen_nopv (GEN_INT(1)));
9843       cycles--;
9844     }
9845 }
9846
9847 /* IDs for all the AVR builtins.  */
9848
9849 enum avr_builtin_id
9850   {
9851     AVR_BUILTIN_NOP,
9852     AVR_BUILTIN_SEI,
9853     AVR_BUILTIN_CLI,
9854     AVR_BUILTIN_WDR,
9855     AVR_BUILTIN_SLEEP,
9856     AVR_BUILTIN_SWAP,
9857     AVR_BUILTIN_FMUL,
9858     AVR_BUILTIN_FMULS,
9859     AVR_BUILTIN_FMULSU,
9860     AVR_BUILTIN_DELAY_CYCLES
9861   };
9862
9863 static void
9864 avr_init_builtin_int24 (void)
9865 {
9866   tree int24_type  = make_signed_type (GET_MODE_BITSIZE (PSImode));
9867   tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
9868
9869   (*lang_hooks.types.register_builtin_type) (int24_type, "__int24");
9870   (*lang_hooks.types.register_builtin_type) (uint24_type, "__uint24");
9871 }
9872
9873 #define DEF_BUILTIN(NAME, TYPE, CODE)                                   \
9874   do                                                                    \
9875     {                                                                   \
9876       add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,        \
9877                             NULL, NULL_TREE);                           \
9878     } while (0)
9879
9880
9881 /* Implement `TARGET_INIT_BUILTINS' */
9882 /* Set up all builtin functions for this target.  */
9883
9884 static void
9885 avr_init_builtins (void)
9886 {
9887   tree void_ftype_void
9888     = build_function_type_list (void_type_node, NULL_TREE);
9889   tree uchar_ftype_uchar
9890     = build_function_type_list (unsigned_char_type_node, 
9891                                 unsigned_char_type_node,
9892                                 NULL_TREE);
9893   tree uint_ftype_uchar_uchar
9894     = build_function_type_list (unsigned_type_node, 
9895                                 unsigned_char_type_node,
9896                                 unsigned_char_type_node, 
9897                                 NULL_TREE);
9898   tree int_ftype_char_char
9899     = build_function_type_list (integer_type_node, 
9900                                 char_type_node,
9901                                 char_type_node, 
9902                                 NULL_TREE);
9903   tree int_ftype_char_uchar
9904     = build_function_type_list (integer_type_node, 
9905                                 char_type_node,
9906                                 unsigned_char_type_node, 
9907                                 NULL_TREE);
9908   tree void_ftype_ulong
9909     = build_function_type_list (void_type_node, 
9910                                 long_unsigned_type_node,
9911                                 NULL_TREE);
9912
9913   DEF_BUILTIN ("__builtin_avr_nop", void_ftype_void, AVR_BUILTIN_NOP);
9914   DEF_BUILTIN ("__builtin_avr_sei", void_ftype_void, AVR_BUILTIN_SEI);
9915   DEF_BUILTIN ("__builtin_avr_cli", void_ftype_void, AVR_BUILTIN_CLI);
9916   DEF_BUILTIN ("__builtin_avr_wdr", void_ftype_void, AVR_BUILTIN_WDR);
9917   DEF_BUILTIN ("__builtin_avr_sleep", void_ftype_void, AVR_BUILTIN_SLEEP);
9918   DEF_BUILTIN ("__builtin_avr_swap", uchar_ftype_uchar, AVR_BUILTIN_SWAP);
9919   DEF_BUILTIN ("__builtin_avr_delay_cycles", void_ftype_ulong, 
9920                AVR_BUILTIN_DELAY_CYCLES);
9921
9922   DEF_BUILTIN ("__builtin_avr_fmul", uint_ftype_uchar_uchar, 
9923                AVR_BUILTIN_FMUL);
9924   DEF_BUILTIN ("__builtin_avr_fmuls", int_ftype_char_char, 
9925                AVR_BUILTIN_FMULS);
9926   DEF_BUILTIN ("__builtin_avr_fmulsu", int_ftype_char_uchar, 
9927                AVR_BUILTIN_FMULSU);
9928
9929   avr_init_builtin_int24 ();
9930 }
9931
9932 #undef DEF_BUILTIN
9933
9934 struct avr_builtin_description
9935 {
9936   const enum insn_code icode;
9937   const char *const name;
9938   const enum avr_builtin_id id;
9939 };
9940
9941 static const struct avr_builtin_description
9942 bdesc_1arg[] =
9943   {
9944     { CODE_FOR_rotlqi3_4, "__builtin_avr_swap", AVR_BUILTIN_SWAP }
9945   };
9946
9947 static const struct avr_builtin_description
9948 bdesc_2arg[] =
9949   {
9950     { CODE_FOR_fmul, "__builtin_avr_fmul", AVR_BUILTIN_FMUL },
9951     { CODE_FOR_fmuls, "__builtin_avr_fmuls", AVR_BUILTIN_FMULS },
9952     { CODE_FOR_fmulsu, "__builtin_avr_fmulsu", AVR_BUILTIN_FMULSU }
9953   };
9954
9955 /* Subroutine of avr_expand_builtin to take care of unop insns.  */
9956
9957 static rtx
9958 avr_expand_unop_builtin (enum insn_code icode, tree exp,
9959                          rtx target)
9960 {
9961   rtx pat;
9962   tree arg0 = CALL_EXPR_ARG (exp, 0);
9963   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
9964   enum machine_mode op0mode = GET_MODE (op0);
9965   enum machine_mode tmode = insn_data[icode].operand[0].mode;
9966   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9967
9968   if (! target
9969       || GET_MODE (target) != tmode
9970       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9971     {
9972       target = gen_reg_rtx (tmode);
9973     }
9974
9975   if (op0mode == SImode && mode0 == HImode)
9976     {
9977       op0mode = HImode;
9978       op0 = gen_lowpart (HImode, op0);
9979     }
9980   
9981   gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
9982
9983   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9984     op0 = copy_to_mode_reg (mode0, op0);
9985
9986   pat = GEN_FCN (icode) (target, op0);
9987   if (! pat)
9988     return 0;
9989   
9990   emit_insn (pat);
9991   
9992   return target;
9993 }
9994
9995
9996 /* Subroutine of avr_expand_builtin to take care of binop insns.  */
9997
9998 static rtx
9999 avr_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10000 {
10001   rtx pat;
10002   tree arg0 = CALL_EXPR_ARG (exp, 0);
10003   tree arg1 = CALL_EXPR_ARG (exp, 1);
10004   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
10005   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
10006   enum machine_mode op0mode = GET_MODE (op0);
10007   enum machine_mode op1mode = GET_MODE (op1);
10008   enum machine_mode tmode = insn_data[icode].operand[0].mode;
10009   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10010   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10011
10012   if (! target
10013       || GET_MODE (target) != tmode
10014       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10015     {
10016       target = gen_reg_rtx (tmode);
10017     }
10018
10019   if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
10020     {
10021       op0mode = HImode;
10022       op0 = gen_lowpart (HImode, op0);
10023     }
10024   
10025   if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
10026     {
10027       op1mode = HImode;
10028       op1 = gen_lowpart (HImode, op1);
10029     }
10030   
10031   /* In case the insn wants input operands in modes different from
10032      the result, abort.  */
10033   
10034   gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
10035               && (op1mode == mode1 || op1mode == VOIDmode));
10036
10037   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10038     op0 = copy_to_mode_reg (mode0, op0);
10039   
10040   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10041     op1 = copy_to_mode_reg (mode1, op1);
10042
10043   pat = GEN_FCN (icode) (target, op0, op1);
10044   
10045   if (! pat)
10046     return 0;
10047
10048   emit_insn (pat);
10049   return target;
10050 }
10051
10052
10053 /* Expand an expression EXP that calls a built-in function,
10054    with result going to TARGET if that's convenient
10055    (and in mode MODE if that's convenient).
10056    SUBTARGET may be used as the target for computing one of EXP's operands.
10057    IGNORE is nonzero if the value is to be ignored.  */
10058
10059 static rtx
10060 avr_expand_builtin (tree exp, rtx target,
10061                     rtx subtarget ATTRIBUTE_UNUSED,
10062                     enum machine_mode mode ATTRIBUTE_UNUSED,
10063                     int ignore ATTRIBUTE_UNUSED)
10064 {
10065   size_t i;
10066   const struct avr_builtin_description *d;
10067   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10068   unsigned int id = DECL_FUNCTION_CODE (fndecl);
10069   tree arg0;
10070   rtx op0;
10071
10072   switch (id)
10073     {
10074     case AVR_BUILTIN_NOP:
10075       emit_insn (gen_nopv (GEN_INT(1)));
10076       return 0;
10077       
10078     case AVR_BUILTIN_SEI:
10079       emit_insn (gen_enable_interrupt ());
10080       return 0;
10081       
10082     case AVR_BUILTIN_CLI:
10083       emit_insn (gen_disable_interrupt ());
10084       return 0;
10085       
10086     case AVR_BUILTIN_WDR:
10087       emit_insn (gen_wdr ());
10088       return 0;
10089       
10090     case AVR_BUILTIN_SLEEP:
10091       emit_insn (gen_sleep ());
10092       return 0;
10093       
10094     case AVR_BUILTIN_DELAY_CYCLES:
10095       {
10096         arg0 = CALL_EXPR_ARG (exp, 0);
10097         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
10098
10099         if (! CONST_INT_P (op0))
10100           error ("__builtin_avr_delay_cycles expects a"
10101                  " compile time integer constant.");
10102
10103         avr_expand_delay_cycles (op0);
10104         return 0;
10105       }
10106     }
10107
10108   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10109     if (d->id == id)
10110       return avr_expand_unop_builtin (d->icode, exp, target);
10111
10112   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10113     if (d->id == id)
10114       return avr_expand_binop_builtin (d->icode, exp, target);
10115
10116   gcc_unreachable ();
10117 }
10118
10119 struct gcc_target targetm = TARGET_INITIALIZER;
10120
10121 #include "gt-avr.h"