OSDN Git Service

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