OSDN Git Service

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