OSDN Git Service

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