OSDN Git Service

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