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