OSDN Git Service

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