OSDN Git Service

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