OSDN Git Service

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