OSDN Git Service

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