OSDN Git Service

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