OSDN Git Service

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