OSDN Git Service

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