OSDN Git Service

PR target/49487
[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 /* Return maximum number of consecutive registers of
1495    class CLASS needed to hold a value of mode MODE.  */
1496
1497 int
1498 class_max_nregs (enum reg_class rclass ATTRIBUTE_UNUSED,enum machine_mode mode)
1499 {
1500   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1501 }
1502
1503 /* Choose mode for jump insn:
1504    1 - relative jump in range -63 <= x <= 62 ;
1505    2 - relative jump in range -2046 <= x <= 2045 ;
1506    3 - absolute jump (only for ATmega[16]03).  */
1507
1508 int
1509 avr_jump_mode (rtx x, rtx insn)
1510 {
1511   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
1512                                             ? XEXP (x, 0) : x));
1513   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1514   int jump_distance = cur_addr - dest_addr;
1515   
1516   if (-63 <= jump_distance && jump_distance <= 62)
1517     return 1;
1518   else if (-2046 <= jump_distance && jump_distance <= 2045)
1519     return 2;
1520   else if (AVR_HAVE_JMP_CALL)
1521     return 3;
1522   
1523   return 2;
1524 }
1525
1526 /* return an AVR condition jump commands.
1527    X is a comparison RTX.
1528    LEN is a number returned by avr_jump_mode function.
1529    if REVERSE nonzero then condition code in X must be reversed.  */
1530
1531 const char *
1532 ret_cond_branch (rtx x, int len, int reverse)
1533 {
1534   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1535   
1536   switch (cond)
1537     {
1538     case GT:
1539       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1540         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1541                             AS1 (brpl,%0)) :
1542                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1543                             AS1 (brmi,.+2) CR_TAB
1544                             AS1 (rjmp,%0)) :
1545                 (AS1 (breq,.+6) CR_TAB
1546                  AS1 (brmi,.+4) CR_TAB
1547                  AS1 (jmp,%0)));
1548           
1549       else
1550         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1551                             AS1 (brge,%0)) :
1552                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1553                             AS1 (brlt,.+2) CR_TAB
1554                             AS1 (rjmp,%0)) :
1555                 (AS1 (breq,.+6) CR_TAB
1556                  AS1 (brlt,.+4) CR_TAB
1557                  AS1 (jmp,%0)));
1558     case GTU:
1559       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1560                           AS1 (brsh,%0)) :
1561               len == 2 ? (AS1 (breq,.+4) CR_TAB
1562                           AS1 (brlo,.+2) CR_TAB
1563                           AS1 (rjmp,%0)) :
1564               (AS1 (breq,.+6) CR_TAB
1565                AS1 (brlo,.+4) CR_TAB
1566                AS1 (jmp,%0)));
1567     case LE:
1568       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1569         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1570                             AS1 (brmi,%0)) :
1571                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1572                             AS1 (brpl,.+2) CR_TAB
1573                             AS1 (rjmp,%0)) :
1574                 (AS1 (breq,.+2) CR_TAB
1575                  AS1 (brpl,.+4) CR_TAB
1576                  AS1 (jmp,%0)));
1577       else
1578         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1579                             AS1 (brlt,%0)) :
1580                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1581                             AS1 (brge,.+2) CR_TAB
1582                             AS1 (rjmp,%0)) :
1583                 (AS1 (breq,.+2) CR_TAB
1584                  AS1 (brge,.+4) CR_TAB
1585                  AS1 (jmp,%0)));
1586     case LEU:
1587       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1588                           AS1 (brlo,%0)) :
1589               len == 2 ? (AS1 (breq,.+2) CR_TAB
1590                           AS1 (brsh,.+2) CR_TAB
1591                           AS1 (rjmp,%0)) :
1592               (AS1 (breq,.+2) CR_TAB
1593                AS1 (brsh,.+4) CR_TAB
1594                AS1 (jmp,%0)));
1595     default:
1596       if (reverse)
1597         {
1598           switch (len)
1599             {
1600             case 1:
1601               return AS1 (br%k1,%0);
1602             case 2:
1603               return (AS1 (br%j1,.+2) CR_TAB
1604                       AS1 (rjmp,%0));
1605             default:
1606               return (AS1 (br%j1,.+4) CR_TAB
1607                       AS1 (jmp,%0));
1608             }
1609         }
1610         else
1611           {
1612             switch (len)
1613               {
1614               case 1:
1615                 return AS1 (br%j1,%0);
1616               case 2:
1617                 return (AS1 (br%k1,.+2) CR_TAB
1618                         AS1 (rjmp,%0));
1619               default:
1620                 return (AS1 (br%k1,.+4) CR_TAB
1621                         AS1 (jmp,%0));
1622               }
1623           }
1624     }
1625   return "";
1626 }
1627
1628 /* Predicate function for immediate operand which fits to byte (8bit) */
1629
1630 int
1631 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1632 {
1633   return (GET_CODE (op) == CONST_INT
1634           && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1635 }
1636
1637 /* Output insn cost for next insn.  */
1638
1639 void
1640 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1641                     int num_operands ATTRIBUTE_UNUSED)
1642 {
1643   if (TARGET_ALL_DEBUG)
1644     {
1645       fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
1646                rtx_cost (PATTERN (insn), INSN, !optimize_size));
1647     }
1648 }
1649
1650 /* Return 0 if undefined, 1 if always true or always false.  */
1651
1652 int
1653 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
1654 {
1655   unsigned int max = (mode == QImode ? 0xff :
1656                       mode == HImode ? 0xffff :
1657                       mode == SImode ? 0xffffffff : 0);
1658   if (max && op && GET_CODE (x) == CONST_INT)
1659     {
1660       if (unsigned_condition (op) != op)
1661         max >>= 1;
1662
1663       if (max != (INTVAL (x) & max)
1664           && INTVAL (x) != 0xff)
1665         return 1;
1666     }
1667   return 0;
1668 }
1669
1670
1671 /* Returns nonzero if REGNO is the number of a hard
1672    register in which function arguments are sometimes passed.  */
1673
1674 int
1675 function_arg_regno_p(int r)
1676 {
1677   return (r >= 8 && r <= 25);
1678 }
1679
1680 /* Initializing the variable cum for the state at the beginning
1681    of the argument list.  */
1682
1683 void
1684 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1685                       tree fndecl ATTRIBUTE_UNUSED)
1686 {
1687   cum->nregs = 18;
1688   cum->regno = FIRST_CUM_REG;
1689   if (!libname && stdarg_p (fntype))
1690     cum->nregs = 0;
1691
1692   /* Assume the calle may be tail called */
1693   
1694   cfun->machine->sibcall_fails = 0;
1695 }
1696
1697 /* Returns the number of registers to allocate for a function argument.  */
1698
1699 static int
1700 avr_num_arg_regs (enum machine_mode mode, const_tree type)
1701 {
1702   int size;
1703
1704   if (mode == BLKmode)
1705     size = int_size_in_bytes (type);
1706   else
1707     size = GET_MODE_SIZE (mode);
1708
1709   /* Align all function arguments to start in even-numbered registers.
1710      Odd-sized arguments leave holes above them.  */
1711
1712   return (size + 1) & ~1;
1713 }
1714
1715 /* Controls whether a function argument is passed
1716    in a register, and which register.  */
1717
1718 static rtx
1719 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
1720                   const_tree type, bool named ATTRIBUTE_UNUSED)
1721 {
1722   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1723   int bytes = avr_num_arg_regs (mode, type);
1724
1725   if (cum->nregs && bytes <= cum->nregs)
1726     return gen_rtx_REG (mode, cum->regno - bytes);
1727
1728   return NULL_RTX;
1729 }
1730
1731 /* Update the summarizer variable CUM to advance past an argument
1732    in the argument list.  */
1733    
1734 static void
1735 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1736                           const_tree type, bool named ATTRIBUTE_UNUSED)
1737 {
1738   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1739   int bytes = avr_num_arg_regs (mode, type);
1740
1741   cum->nregs -= bytes;
1742   cum->regno -= bytes;
1743
1744   /* A parameter is being passed in a call-saved register. As the original
1745      contents of these regs has to be restored before leaving the function,
1746      a function must not pass arguments in call-saved regs in order to get
1747      tail-called. */
1748   
1749   if (cum->regno >= 8
1750       && cum->nregs >= 0
1751       && !call_used_regs[cum->regno])
1752     {
1753       /* FIXME: We ship info on failing tail-call in struct machine_function.
1754          This uses internals of calls.c:expand_call() and the way args_so_far
1755          is used. targetm.function_ok_for_sibcall() needs to be extended to
1756          pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
1757          dependent so that such an extension is not wanted. */
1758       
1759       cfun->machine->sibcall_fails = 1;
1760     }
1761
1762   /* Test if all registers needed by the ABI are actually available.  If the
1763      user has fixed a GPR needed to pass an argument, an (implicit) function
1764      call would clobber that fixed register.  See PR45099 for an example.  */
1765   
1766   if (cum->regno >= 8
1767       && cum->nregs >= 0)
1768     {
1769       int regno;
1770
1771       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
1772         if (fixed_regs[regno])
1773           error ("Register %s is needed to pass a parameter but is fixed",
1774                  reg_names[regno]);
1775     }
1776       
1777   if (cum->nregs <= 0)
1778     {
1779       cum->nregs = 0;
1780       cum->regno = FIRST_CUM_REG;
1781     }
1782 }
1783
1784 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
1785 /* Decide whether we can make a sibling call to a function.  DECL is the
1786    declaration of the function being targeted by the call and EXP is the
1787    CALL_EXPR representing the call. */
1788
1789 static bool
1790 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
1791 {
1792   tree fntype_callee;
1793
1794   /* Tail-calling must fail if callee-saved regs are used to pass
1795      function args.  We must not tail-call when `epilogue_restores'
1796      is used.  Unfortunately, we cannot tell at this point if that
1797      actually will happen or not, and we cannot step back from
1798      tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
1799   
1800   if (cfun->machine->sibcall_fails
1801       || TARGET_CALL_PROLOGUES)
1802     {
1803       return false;
1804     }
1805   
1806   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
1807
1808   if (decl_callee)
1809     {
1810       decl_callee = TREE_TYPE (decl_callee);
1811     }
1812   else
1813     {
1814       decl_callee = fntype_callee;
1815       
1816       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
1817              && METHOD_TYPE != TREE_CODE (decl_callee))
1818         {
1819           decl_callee = TREE_TYPE (decl_callee);
1820         }
1821     }
1822
1823   /* Ensure that caller and callee have compatible epilogues */
1824   
1825   if (interrupt_function_p (current_function_decl)
1826       || signal_function_p (current_function_decl)
1827       || avr_naked_function_p (decl_callee)
1828       || avr_naked_function_p (current_function_decl)
1829       /* FIXME: For OS_task and OS_main, we are over-conservative.
1830          This is due to missing documentation of these attributes
1831          and what they actually should do and should not do. */
1832       || (avr_OS_task_function_p (decl_callee)
1833           != avr_OS_task_function_p (current_function_decl))
1834       || (avr_OS_main_function_p (decl_callee)
1835           != avr_OS_main_function_p (current_function_decl)))
1836     {
1837       return false;
1838     }
1839  
1840   return true;
1841 }
1842
1843 /***********************************************************************
1844   Functions for outputting various mov's for a various modes
1845 ************************************************************************/
1846 const char *
1847 output_movqi (rtx insn, rtx operands[], int *l)
1848 {
1849   int dummy;
1850   rtx dest = operands[0];
1851   rtx src = operands[1];
1852   int *real_l = l;
1853   
1854   if (!l)
1855     l = &dummy;
1856
1857   *l = 1;
1858   
1859   if (register_operand (dest, QImode))
1860     {
1861       if (register_operand (src, QImode)) /* mov r,r */
1862         {
1863           if (test_hard_reg_class (STACK_REG, dest))
1864             return AS2 (out,%0,%1);
1865           else if (test_hard_reg_class (STACK_REG, src))
1866             return AS2 (in,%0,%1);
1867           
1868           return AS2 (mov,%0,%1);
1869         }
1870       else if (CONSTANT_P (src))
1871         {
1872           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1873             return AS2 (ldi,%0,lo8(%1));
1874           
1875           if (GET_CODE (src) == CONST_INT)
1876             {
1877               if (src == const0_rtx) /* mov r,L */
1878                 return AS1 (clr,%0);
1879               else if (src == const1_rtx)
1880                 {
1881                   *l = 2;
1882                   return (AS1 (clr,%0) CR_TAB
1883                           AS1 (inc,%0));
1884                 }
1885               else if (src == constm1_rtx)
1886                 {
1887                   /* Immediate constants -1 to any register */
1888                   *l = 2;
1889                   return (AS1 (clr,%0) CR_TAB
1890                           AS1 (dec,%0));
1891                 }
1892               else
1893                 {
1894                   int bit_nr = exact_log2 (INTVAL (src));
1895
1896                   if (bit_nr >= 0)
1897                     {
1898                       *l = 3;
1899                       if (!real_l)
1900                         output_asm_insn ((AS1 (clr,%0) CR_TAB
1901                                           "set"), operands);
1902                       if (!real_l)
1903                         avr_output_bld (operands, bit_nr);
1904
1905                       return "";
1906                     }
1907                 }
1908             }
1909           
1910           /* Last resort, larger than loading from memory.  */
1911           *l = 4;
1912           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1913                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1914                   AS2 (mov,%0,r31)          CR_TAB
1915                   AS2 (mov,r31,__tmp_reg__));
1916         }
1917       else if (GET_CODE (src) == MEM)
1918         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1919     }
1920   else if (GET_CODE (dest) == MEM)
1921     {
1922       const char *templ;
1923
1924       if (src == const0_rtx)
1925         operands[1] = zero_reg_rtx;
1926
1927       templ = out_movqi_mr_r (insn, operands, real_l);
1928
1929       if (!real_l)
1930         output_asm_insn (templ, operands);
1931
1932       operands[1] = src;
1933     }
1934   return "";
1935 }
1936
1937
1938 const char *
1939 output_movhi (rtx insn, rtx operands[], int *l)
1940 {
1941   int dummy;
1942   rtx dest = operands[0];
1943   rtx src = operands[1];
1944   int *real_l = l;
1945   
1946   if (!l)
1947     l = &dummy;
1948   
1949   if (register_operand (dest, HImode))
1950     {
1951       if (register_operand (src, HImode)) /* mov r,r */
1952         {
1953           if (test_hard_reg_class (STACK_REG, dest))
1954             {
1955               if (AVR_HAVE_8BIT_SP)
1956                 return *l = 1, AS2 (out,__SP_L__,%A1);
1957               /* Use simple load of stack pointer if no interrupts are 
1958                  used.  */
1959               else if (TARGET_NO_INTERRUPTS)
1960                 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
1961                                 AS2 (out,__SP_L__,%A1));
1962               *l = 5;
1963               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
1964                       "cli"                          CR_TAB
1965                       AS2 (out,__SP_H__,%B1)         CR_TAB
1966                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1967                       AS2 (out,__SP_L__,%A1));
1968             }
1969           else if (test_hard_reg_class (STACK_REG, src))
1970             {
1971               *l = 2;   
1972               return (AS2 (in,%A0,__SP_L__) CR_TAB
1973                       AS2 (in,%B0,__SP_H__));
1974             }
1975
1976           if (AVR_HAVE_MOVW)
1977             {
1978               *l = 1;
1979               return (AS2 (movw,%0,%1));
1980             }
1981           else
1982             {
1983               *l = 2;
1984               return (AS2 (mov,%A0,%A1) CR_TAB
1985                       AS2 (mov,%B0,%B1));
1986             }
1987         }
1988       else if (CONSTANT_P (src))
1989         {
1990           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1991             {
1992               *l = 2;
1993               return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1994                       AS2 (ldi,%B0,hi8(%1)));
1995             }
1996           
1997           if (GET_CODE (src) == CONST_INT)
1998             {
1999               if (src == const0_rtx) /* mov r,L */
2000                 {
2001                   *l = 2;
2002                   return (AS1 (clr,%A0) CR_TAB
2003                           AS1 (clr,%B0));
2004                 }
2005               else if (src == const1_rtx)
2006                 {
2007                   *l = 3;
2008                   return (AS1 (clr,%A0) CR_TAB
2009                           AS1 (clr,%B0) CR_TAB
2010                           AS1 (inc,%A0));
2011                 }
2012               else if (src == constm1_rtx)
2013                 {
2014                   /* Immediate constants -1 to any register */
2015                   *l = 3;
2016                   return (AS1 (clr,%0)  CR_TAB
2017                           AS1 (dec,%A0) CR_TAB
2018                           AS2 (mov,%B0,%A0));
2019                 }
2020               else
2021                 {
2022                   int bit_nr = exact_log2 (INTVAL (src));
2023
2024                   if (bit_nr >= 0)
2025                     {
2026                       *l = 4;
2027                       if (!real_l)
2028                         output_asm_insn ((AS1 (clr,%A0) CR_TAB
2029                                           AS1 (clr,%B0) CR_TAB
2030                                           "set"), operands);
2031                       if (!real_l)
2032                         avr_output_bld (operands, bit_nr);
2033
2034                       return "";
2035                     }
2036                 }
2037
2038               if ((INTVAL (src) & 0xff) == 0)
2039                 {
2040                   *l = 5;
2041                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2042                           AS1 (clr,%A0)             CR_TAB
2043                           AS2 (ldi,r31,hi8(%1))     CR_TAB
2044                           AS2 (mov,%B0,r31)         CR_TAB
2045                           AS2 (mov,r31,__tmp_reg__));
2046                 }
2047               else if ((INTVAL (src) & 0xff00) == 0)
2048                 {
2049                   *l = 5;
2050                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2051                           AS2 (ldi,r31,lo8(%1))     CR_TAB
2052                           AS2 (mov,%A0,r31)         CR_TAB
2053                           AS1 (clr,%B0)             CR_TAB
2054                           AS2 (mov,r31,__tmp_reg__));
2055                 }
2056             }
2057           
2058           /* Last resort, equal to loading from memory.  */
2059           *l = 6;
2060           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2061                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2062                   AS2 (mov,%A0,r31)         CR_TAB
2063                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2064                   AS2 (mov,%B0,r31)         CR_TAB
2065                   AS2 (mov,r31,__tmp_reg__));
2066         }
2067       else if (GET_CODE (src) == MEM)
2068         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
2069     }
2070   else if (GET_CODE (dest) == MEM)
2071     {
2072       const char *templ;
2073
2074       if (src == const0_rtx)
2075         operands[1] = zero_reg_rtx;
2076
2077       templ = out_movhi_mr_r (insn, operands, real_l);
2078
2079       if (!real_l)
2080         output_asm_insn (templ, operands);
2081
2082       operands[1] = src;
2083       return "";
2084     }
2085   fatal_insn ("invalid insn:", insn);
2086   return "";
2087 }
2088
2089 const char *
2090 out_movqi_r_mr (rtx insn, rtx op[], int *l)
2091 {
2092   rtx dest = op[0];
2093   rtx src = op[1];
2094   rtx x = XEXP (src, 0);
2095   int dummy;
2096   
2097   if (!l)
2098     l = &dummy;
2099   
2100   if (CONSTANT_ADDRESS_P (x))
2101     {
2102       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2103         {
2104           *l = 1;
2105           return AS2 (in,%0,__SREG__);
2106         }
2107       if (optimize > 0 && io_address_operand (x, QImode))
2108         {
2109           *l = 1;
2110           return AS2 (in,%0,%m1-0x20);
2111         }
2112       *l = 2;
2113       return AS2 (lds,%0,%m1);
2114     }
2115   /* memory access by reg+disp */
2116   else if (GET_CODE (x) == PLUS
2117       && REG_P (XEXP (x,0))
2118       && GET_CODE (XEXP (x,1)) == CONST_INT)
2119     {
2120       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
2121         {
2122           int disp = INTVAL (XEXP (x,1));
2123           if (REGNO (XEXP (x,0)) != REG_Y)
2124             fatal_insn ("incorrect insn:",insn);
2125
2126           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2127             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
2128                             AS2 (ldd,%0,Y+63)     CR_TAB
2129                             AS2 (sbiw,r28,%o1-63));
2130
2131           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2132                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2133                           AS2 (ld,%0,Y)            CR_TAB
2134                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2135                           AS2 (sbci,r29,hi8(%o1)));
2136         }
2137       else if (REGNO (XEXP (x,0)) == REG_X)
2138         {
2139           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2140              it but I have this situation with extremal optimizing options.  */
2141           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
2142               || reg_unused_after (insn, XEXP (x,0)))
2143             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
2144                             AS2 (ld,%0,X));
2145
2146           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
2147                           AS2 (ld,%0,X)      CR_TAB
2148                           AS2 (sbiw,r26,%o1));
2149         }
2150       *l = 1;
2151       return AS2 (ldd,%0,%1);
2152     }
2153   *l = 1;
2154   return AS2 (ld,%0,%1);
2155 }
2156
2157 const char *
2158 out_movhi_r_mr (rtx insn, rtx op[], int *l)
2159 {
2160   rtx dest = op[0];
2161   rtx src = op[1];
2162   rtx base = XEXP (src, 0);
2163   int reg_dest = true_regnum (dest);
2164   int reg_base = true_regnum (base);
2165   /* "volatile" forces reading low byte first, even if less efficient,
2166      for correct operation with 16-bit I/O registers.  */
2167   int mem_volatile_p = MEM_VOLATILE_P (src);
2168   int tmp;
2169
2170   if (!l)
2171     l = &tmp;
2172
2173   if (reg_base > 0)
2174     {
2175       if (reg_dest == reg_base)         /* R = (R) */
2176         {
2177           *l = 3;
2178           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
2179                   AS2 (ld,%B0,%1) CR_TAB
2180                   AS2 (mov,%A0,__tmp_reg__));
2181         }
2182       else if (reg_base == REG_X)        /* (R26) */
2183         {
2184           if (reg_unused_after (insn, base))
2185             {
2186               *l = 2;
2187               return (AS2 (ld,%A0,X+) CR_TAB
2188                       AS2 (ld,%B0,X));
2189             }
2190           *l  = 3;
2191           return (AS2 (ld,%A0,X+) CR_TAB
2192                   AS2 (ld,%B0,X) CR_TAB
2193                   AS2 (sbiw,r26,1));
2194         }
2195       else                      /* (R)  */
2196         {
2197           *l = 2;
2198           return (AS2 (ld,%A0,%1)    CR_TAB
2199                   AS2 (ldd,%B0,%1+1));
2200         }
2201     }
2202   else if (GET_CODE (base) == PLUS) /* (R + i) */
2203     {
2204       int disp = INTVAL (XEXP (base, 1));
2205       int reg_base = true_regnum (XEXP (base, 0));
2206       
2207       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2208         {
2209           if (REGNO (XEXP (base, 0)) != REG_Y)
2210             fatal_insn ("incorrect insn:",insn);
2211           
2212           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2213             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
2214                             AS2 (ldd,%A0,Y+62)    CR_TAB
2215                             AS2 (ldd,%B0,Y+63)    CR_TAB
2216                             AS2 (sbiw,r28,%o1-62));
2217
2218           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2219                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2220                           AS2 (ld,%A0,Y)           CR_TAB
2221                           AS2 (ldd,%B0,Y+1)        CR_TAB
2222                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2223                           AS2 (sbci,r29,hi8(%o1)));
2224         }
2225       if (reg_base == REG_X)
2226         {
2227           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
2228              it but I have this situation with extremal
2229              optimization options.  */
2230           
2231           *l = 4;
2232           if (reg_base == reg_dest)
2233             return (AS2 (adiw,r26,%o1)      CR_TAB
2234                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2235                     AS2 (ld,%B0,X)          CR_TAB
2236                     AS2 (mov,%A0,__tmp_reg__));
2237
2238           return (AS2 (adiw,r26,%o1) CR_TAB
2239                   AS2 (ld,%A0,X+)    CR_TAB
2240                   AS2 (ld,%B0,X)     CR_TAB
2241                   AS2 (sbiw,r26,%o1+1));
2242         }
2243
2244       if (reg_base == reg_dest)
2245         {
2246           *l = 3;
2247           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2248                   AS2 (ldd,%B0,%B1)         CR_TAB
2249                   AS2 (mov,%A0,__tmp_reg__));
2250         }
2251       
2252       *l = 2;
2253       return (AS2 (ldd,%A0,%A1) CR_TAB
2254               AS2 (ldd,%B0,%B1));
2255     }
2256   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2257     {
2258       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2259         fatal_insn ("incorrect insn:", insn);
2260
2261       if (mem_volatile_p)
2262         {
2263           if (REGNO (XEXP (base, 0)) == REG_X)
2264             {
2265               *l = 4;
2266               return (AS2 (sbiw,r26,2)  CR_TAB
2267                       AS2 (ld,%A0,X+)   CR_TAB
2268                       AS2 (ld,%B0,X)    CR_TAB
2269                       AS2 (sbiw,r26,1));
2270             }
2271           else
2272             {
2273               *l = 3;
2274               return (AS2 (sbiw,%r1,2)   CR_TAB
2275                       AS2 (ld,%A0,%p1)  CR_TAB
2276                       AS2 (ldd,%B0,%p1+1));
2277             }
2278         }
2279
2280       *l = 2;
2281       return (AS2 (ld,%B0,%1) CR_TAB
2282               AS2 (ld,%A0,%1));
2283     }
2284   else if (GET_CODE (base) == POST_INC) /* (R++) */
2285     {
2286       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2287         fatal_insn ("incorrect insn:", insn);
2288
2289       *l = 2;
2290       return (AS2 (ld,%A0,%1)  CR_TAB
2291               AS2 (ld,%B0,%1));
2292     }
2293   else if (CONSTANT_ADDRESS_P (base))
2294     {
2295       if (optimize > 0 && io_address_operand (base, HImode))
2296         {
2297           *l = 2;
2298           return (AS2 (in,%A0,%m1-0x20) CR_TAB
2299                   AS2 (in,%B0,%m1+1-0x20));
2300         }
2301       *l = 4;
2302       return (AS2 (lds,%A0,%m1) CR_TAB
2303               AS2 (lds,%B0,%m1+1));
2304     }
2305   
2306   fatal_insn ("unknown move insn:",insn);
2307   return "";
2308 }
2309
2310 const char *
2311 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2312 {
2313   rtx dest = op[0];
2314   rtx src = op[1];
2315   rtx base = XEXP (src, 0);
2316   int reg_dest = true_regnum (dest);
2317   int reg_base = true_regnum (base);
2318   int tmp;
2319
2320   if (!l)
2321     l = &tmp;
2322   
2323   if (reg_base > 0)
2324     {
2325       if (reg_base == REG_X)        /* (R26) */
2326         {
2327           if (reg_dest == REG_X)
2328             /* "ld r26,-X" is undefined */
2329             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
2330                           AS2 (ld,r29,X)          CR_TAB
2331                           AS2 (ld,r28,-X)         CR_TAB
2332                           AS2 (ld,__tmp_reg__,-X) CR_TAB
2333                           AS2 (sbiw,r26,1)        CR_TAB
2334                           AS2 (ld,r26,X)          CR_TAB
2335                           AS2 (mov,r27,__tmp_reg__));
2336           else if (reg_dest == REG_X - 2)
2337             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2338                           AS2 (ld,%B0,X+) CR_TAB
2339                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
2340                           AS2 (ld,%D0,X)  CR_TAB
2341                           AS2 (mov,%C0,__tmp_reg__));
2342           else if (reg_unused_after (insn, base))
2343             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
2344                            AS2 (ld,%B0,X+) CR_TAB
2345                            AS2 (ld,%C0,X+) CR_TAB
2346                            AS2 (ld,%D0,X));
2347           else
2348             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2349                            AS2 (ld,%B0,X+) CR_TAB
2350                            AS2 (ld,%C0,X+) CR_TAB
2351                            AS2 (ld,%D0,X)  CR_TAB
2352                            AS2 (sbiw,r26,3));
2353         }
2354       else
2355         {
2356           if (reg_dest == reg_base)
2357             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2358                           AS2 (ldd,%C0,%1+2) CR_TAB
2359                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
2360                           AS2 (ld,%A0,%1)  CR_TAB
2361                           AS2 (mov,%B0,__tmp_reg__));
2362           else if (reg_base == reg_dest + 2)
2363             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2364                           AS2 (ldd,%B0,%1+1) CR_TAB
2365                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2366                           AS2 (ldd,%D0,%1+3) CR_TAB
2367                           AS2 (mov,%C0,__tmp_reg__));
2368           else
2369             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2370                           AS2 (ldd,%B0,%1+1) CR_TAB
2371                           AS2 (ldd,%C0,%1+2) CR_TAB
2372                           AS2 (ldd,%D0,%1+3));
2373         }
2374     }
2375   else if (GET_CODE (base) == PLUS) /* (R + i) */
2376     {
2377       int disp = INTVAL (XEXP (base, 1));
2378       
2379       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2380         {
2381           if (REGNO (XEXP (base, 0)) != REG_Y)
2382             fatal_insn ("incorrect insn:",insn);
2383
2384           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2385             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2386                             AS2 (ldd,%A0,Y+60)    CR_TAB
2387                             AS2 (ldd,%B0,Y+61)    CR_TAB
2388                             AS2 (ldd,%C0,Y+62)    CR_TAB
2389                             AS2 (ldd,%D0,Y+63)    CR_TAB
2390                             AS2 (sbiw,r28,%o1-60));
2391
2392           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2393                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2394                           AS2 (ld,%A0,Y)           CR_TAB
2395                           AS2 (ldd,%B0,Y+1)        CR_TAB
2396                           AS2 (ldd,%C0,Y+2)        CR_TAB
2397                           AS2 (ldd,%D0,Y+3)        CR_TAB
2398                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2399                           AS2 (sbci,r29,hi8(%o1)));
2400         }
2401
2402       reg_base = true_regnum (XEXP (base, 0));
2403       if (reg_base == REG_X)
2404         {
2405           /* R = (X + d) */
2406           if (reg_dest == REG_X)
2407             {
2408               *l = 7;
2409               /* "ld r26,-X" is undefined */
2410               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2411                       AS2 (ld,r29,X)          CR_TAB
2412                       AS2 (ld,r28,-X)         CR_TAB
2413                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2414                       AS2 (sbiw,r26,1)        CR_TAB
2415                       AS2 (ld,r26,X)          CR_TAB
2416                       AS2 (mov,r27,__tmp_reg__));
2417             }
2418           *l = 6;
2419           if (reg_dest == REG_X - 2)
2420             return (AS2 (adiw,r26,%o1)      CR_TAB
2421                     AS2 (ld,r24,X+)         CR_TAB
2422                     AS2 (ld,r25,X+)         CR_TAB
2423                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2424                     AS2 (ld,r27,X)          CR_TAB
2425                     AS2 (mov,r26,__tmp_reg__));
2426
2427           return (AS2 (adiw,r26,%o1) CR_TAB
2428                   AS2 (ld,%A0,X+)    CR_TAB
2429                   AS2 (ld,%B0,X+)    CR_TAB
2430                   AS2 (ld,%C0,X+)    CR_TAB
2431                   AS2 (ld,%D0,X)     CR_TAB
2432                   AS2 (sbiw,r26,%o1+3));
2433         }
2434       if (reg_dest == reg_base)
2435         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2436                       AS2 (ldd,%C0,%C1) CR_TAB
2437                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2438                       AS2 (ldd,%A0,%A1) CR_TAB
2439                       AS2 (mov,%B0,__tmp_reg__));
2440       else if (reg_dest == reg_base - 2)
2441         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2442                       AS2 (ldd,%B0,%B1) CR_TAB
2443                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2444                       AS2 (ldd,%D0,%D1) CR_TAB
2445                       AS2 (mov,%C0,__tmp_reg__));
2446       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2447                     AS2 (ldd,%B0,%B1) CR_TAB
2448                     AS2 (ldd,%C0,%C1) CR_TAB
2449                     AS2 (ldd,%D0,%D1));
2450     }
2451   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2452     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2453                   AS2 (ld,%C0,%1) CR_TAB
2454                   AS2 (ld,%B0,%1) CR_TAB
2455                   AS2 (ld,%A0,%1));
2456   else if (GET_CODE (base) == POST_INC) /* (R++) */
2457     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2458                   AS2 (ld,%B0,%1) CR_TAB
2459                   AS2 (ld,%C0,%1) CR_TAB
2460                   AS2 (ld,%D0,%1));
2461   else if (CONSTANT_ADDRESS_P (base))
2462       return *l=8, (AS2 (lds,%A0,%m1) CR_TAB
2463                     AS2 (lds,%B0,%m1+1) CR_TAB
2464                     AS2 (lds,%C0,%m1+2) CR_TAB
2465                     AS2 (lds,%D0,%m1+3));
2466     
2467   fatal_insn ("unknown move insn:",insn);
2468   return "";
2469 }
2470
2471 const char *
2472 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2473 {
2474   rtx dest = op[0];
2475   rtx src = op[1];
2476   rtx base = XEXP (dest, 0);
2477   int reg_base = true_regnum (base);
2478   int reg_src = true_regnum (src);
2479   int tmp;
2480   
2481   if (!l)
2482     l = &tmp;
2483   
2484   if (CONSTANT_ADDRESS_P (base))
2485     return *l=8,(AS2 (sts,%m0,%A1) CR_TAB
2486                  AS2 (sts,%m0+1,%B1) CR_TAB
2487                  AS2 (sts,%m0+2,%C1) CR_TAB
2488                  AS2 (sts,%m0+3,%D1));
2489   if (reg_base > 0)                 /* (r) */
2490     {
2491       if (reg_base == REG_X)                /* (R26) */
2492         {
2493           if (reg_src == REG_X)
2494             {
2495               /* "st X+,r26" is undefined */
2496               if (reg_unused_after (insn, base))
2497                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2498                               AS2 (st,X,r26)            CR_TAB
2499                               AS2 (adiw,r26,1)          CR_TAB
2500                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2501                               AS2 (st,X+,r28)           CR_TAB
2502                               AS2 (st,X,r29));
2503               else
2504                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2505                               AS2 (st,X,r26)            CR_TAB
2506                               AS2 (adiw,r26,1)          CR_TAB
2507                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2508                               AS2 (st,X+,r28)           CR_TAB
2509                               AS2 (st,X,r29)            CR_TAB
2510                               AS2 (sbiw,r26,3));
2511             }
2512           else if (reg_base == reg_src + 2)
2513             {
2514               if (reg_unused_after (insn, base))
2515                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2516                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2517                               AS2 (st,%0+,%A1) CR_TAB
2518                               AS2 (st,%0+,%B1) CR_TAB
2519                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2520                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2521                               AS1 (clr,__zero_reg__));
2522               else
2523                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2524                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2525                               AS2 (st,%0+,%A1) CR_TAB
2526                               AS2 (st,%0+,%B1) CR_TAB
2527                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2528                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2529                               AS1 (clr,__zero_reg__)     CR_TAB
2530                               AS2 (sbiw,r26,3));
2531             }
2532           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2533                         AS2 (st,%0+,%B1) CR_TAB
2534                         AS2 (st,%0+,%C1) CR_TAB
2535                         AS2 (st,%0,%D1)  CR_TAB
2536                         AS2 (sbiw,r26,3));
2537         }
2538       else
2539         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2540                       AS2 (std,%0+1,%B1) CR_TAB
2541                       AS2 (std,%0+2,%C1) CR_TAB
2542                       AS2 (std,%0+3,%D1));
2543     }
2544   else if (GET_CODE (base) == PLUS) /* (R + i) */
2545     {
2546       int disp = INTVAL (XEXP (base, 1));
2547       reg_base = REGNO (XEXP (base, 0));
2548       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2549         {
2550           if (reg_base != REG_Y)
2551             fatal_insn ("incorrect insn:",insn);
2552
2553           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2554             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2555                             AS2 (std,Y+60,%A1)    CR_TAB
2556                             AS2 (std,Y+61,%B1)    CR_TAB
2557                             AS2 (std,Y+62,%C1)    CR_TAB
2558                             AS2 (std,Y+63,%D1)    CR_TAB
2559                             AS2 (sbiw,r28,%o0-60));
2560
2561           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2562                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2563                           AS2 (st,Y,%A1)           CR_TAB
2564                           AS2 (std,Y+1,%B1)        CR_TAB
2565                           AS2 (std,Y+2,%C1)        CR_TAB
2566                           AS2 (std,Y+3,%D1)        CR_TAB
2567                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2568                           AS2 (sbci,r29,hi8(%o0)));
2569         }
2570       if (reg_base == REG_X)
2571         {
2572           /* (X + d) = R */
2573           if (reg_src == REG_X)
2574             {
2575               *l = 9;
2576               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2577                       AS2 (mov,__zero_reg__,r27) CR_TAB
2578                       AS2 (adiw,r26,%o0)         CR_TAB
2579                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2580                       AS2 (st,X+,__zero_reg__)   CR_TAB
2581                       AS2 (st,X+,r28)            CR_TAB
2582                       AS2 (st,X,r29)             CR_TAB
2583                       AS1 (clr,__zero_reg__)     CR_TAB
2584                       AS2 (sbiw,r26,%o0+3));
2585             }
2586           else if (reg_src == REG_X - 2)
2587             {
2588               *l = 9;
2589               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2590                       AS2 (mov,__zero_reg__,r27) CR_TAB
2591                       AS2 (adiw,r26,%o0)         CR_TAB
2592                       AS2 (st,X+,r24)            CR_TAB
2593                       AS2 (st,X+,r25)            CR_TAB
2594                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2595                       AS2 (st,X,__zero_reg__)    CR_TAB
2596                       AS1 (clr,__zero_reg__)     CR_TAB
2597                       AS2 (sbiw,r26,%o0+3));
2598             }
2599           *l = 6;
2600           return (AS2 (adiw,r26,%o0) CR_TAB
2601                   AS2 (st,X+,%A1)    CR_TAB
2602                   AS2 (st,X+,%B1)    CR_TAB
2603                   AS2 (st,X+,%C1)    CR_TAB
2604                   AS2 (st,X,%D1)     CR_TAB
2605                   AS2 (sbiw,r26,%o0+3));
2606         }
2607       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2608                     AS2 (std,%B0,%B1) CR_TAB
2609                     AS2 (std,%C0,%C1) CR_TAB
2610                     AS2 (std,%D0,%D1));
2611     }
2612   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2613     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2614                   AS2 (st,%0,%C1) CR_TAB
2615                   AS2 (st,%0,%B1) CR_TAB
2616                   AS2 (st,%0,%A1));
2617   else if (GET_CODE (base) == POST_INC) /* (R++) */
2618     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2619                   AS2 (st,%0,%B1) CR_TAB
2620                   AS2 (st,%0,%C1) CR_TAB
2621                   AS2 (st,%0,%D1));
2622   fatal_insn ("unknown move insn:",insn);
2623   return "";
2624 }
2625
2626 const char *
2627 output_movsisf (rtx insn, rtx operands[], rtx clobber_reg, int *l)
2628 {
2629   int dummy;
2630   rtx dest = operands[0];
2631   rtx src = operands[1];
2632   int *real_l = l;
2633   
2634   if (!l)
2635     l = &dummy;
2636   
2637   if (register_operand (dest, VOIDmode))
2638     {
2639       if (register_operand (src, VOIDmode)) /* mov r,r */
2640         {
2641           if (true_regnum (dest) > true_regnum (src))
2642             {
2643               if (AVR_HAVE_MOVW)
2644                 {
2645                   *l = 2;
2646                   return (AS2 (movw,%C0,%C1) CR_TAB
2647                           AS2 (movw,%A0,%A1));
2648                 }
2649               *l = 4;
2650               return (AS2 (mov,%D0,%D1) CR_TAB
2651                       AS2 (mov,%C0,%C1) CR_TAB
2652                       AS2 (mov,%B0,%B1) CR_TAB
2653                       AS2 (mov,%A0,%A1));
2654             }
2655           else
2656             {
2657               if (AVR_HAVE_MOVW)
2658                 {
2659                   *l = 2;
2660                   return (AS2 (movw,%A0,%A1) CR_TAB
2661                           AS2 (movw,%C0,%C1));
2662                 }
2663               *l = 4;
2664               return (AS2 (mov,%A0,%A1) CR_TAB
2665                       AS2 (mov,%B0,%B1) CR_TAB
2666                       AS2 (mov,%C0,%C1) CR_TAB
2667                       AS2 (mov,%D0,%D1));
2668             }
2669         }
2670       else if (CONST_INT_P (src)
2671                || CONST_DOUBLE_P (src))
2672         {
2673           return output_reload_insisf (insn, operands, clobber_reg, real_l);
2674         }
2675       else if (CONSTANT_P (src))
2676         {
2677           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2678             {
2679               *l = 4;
2680               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2681                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2682                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2683                       AS2 (ldi,%D0,hhi8(%1)));
2684             }
2685           /* Last resort, better than loading from memory.  */
2686           *l = 10;
2687           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2688                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2689                   AS2 (mov,%A0,r31)         CR_TAB
2690                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2691                   AS2 (mov,%B0,r31)         CR_TAB
2692                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2693                   AS2 (mov,%C0,r31)         CR_TAB
2694                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2695                   AS2 (mov,%D0,r31)         CR_TAB
2696                   AS2 (mov,r31,__tmp_reg__));
2697         }
2698       else if (GET_CODE (src) == MEM)
2699         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2700     }
2701   else if (GET_CODE (dest) == MEM)
2702     {
2703       const char *templ;
2704
2705       if (src == CONST0_RTX (GET_MODE (dest)))
2706           operands[1] = zero_reg_rtx;
2707
2708       templ = out_movsi_mr_r (insn, operands, real_l);
2709
2710       if (!real_l)
2711         output_asm_insn (templ, operands);
2712
2713       operands[1] = src;
2714       return "";
2715     }
2716   fatal_insn ("invalid insn:", insn);
2717   return "";
2718 }
2719
2720 const char *
2721 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2722 {
2723   rtx dest = op[0];
2724   rtx src = op[1];
2725   rtx x = XEXP (dest, 0);
2726   int dummy;
2727
2728   if (!l)
2729     l = &dummy;
2730   
2731   if (CONSTANT_ADDRESS_P (x))
2732     {
2733       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2734         {
2735           *l = 1;
2736           return AS2 (out,__SREG__,%1);
2737         }
2738       if (optimize > 0 && io_address_operand (x, QImode))
2739         {
2740           *l = 1;
2741           return AS2 (out,%m0-0x20,%1);
2742         }
2743       *l = 2;
2744       return AS2 (sts,%m0,%1);
2745     }
2746   /* memory access by reg+disp */
2747   else if (GET_CODE (x) == PLUS 
2748       && REG_P (XEXP (x,0))
2749       && GET_CODE (XEXP (x,1)) == CONST_INT)
2750     {
2751       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2752         {
2753           int disp = INTVAL (XEXP (x,1));
2754           if (REGNO (XEXP (x,0)) != REG_Y)
2755             fatal_insn ("incorrect insn:",insn);
2756
2757           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2758             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2759                             AS2 (std,Y+63,%1)     CR_TAB
2760                             AS2 (sbiw,r28,%o0-63));
2761
2762           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2763                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2764                           AS2 (st,Y,%1)            CR_TAB
2765                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2766                           AS2 (sbci,r29,hi8(%o0)));
2767         }
2768       else if (REGNO (XEXP (x,0)) == REG_X)
2769         {
2770           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2771             {
2772               if (reg_unused_after (insn, XEXP (x,0)))
2773                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2774                                 AS2 (adiw,r26,%o0)       CR_TAB
2775                                 AS2 (st,X,__tmp_reg__));
2776
2777               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2778                               AS2 (adiw,r26,%o0)       CR_TAB
2779                               AS2 (st,X,__tmp_reg__)   CR_TAB
2780                               AS2 (sbiw,r26,%o0));
2781             }
2782           else
2783             {
2784               if (reg_unused_after (insn, XEXP (x,0)))
2785                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2786                                 AS2 (st,X,%1));
2787
2788               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2789                               AS2 (st,X,%1)      CR_TAB
2790                               AS2 (sbiw,r26,%o0));
2791             }
2792         }
2793       *l = 1;
2794       return AS2 (std,%0,%1);
2795     }
2796   *l = 1;
2797   return AS2 (st,%0,%1);
2798 }
2799
2800 const char *
2801 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2802 {
2803   rtx dest = op[0];
2804   rtx src = op[1];
2805   rtx base = XEXP (dest, 0);
2806   int reg_base = true_regnum (base);
2807   int reg_src = true_regnum (src);
2808   /* "volatile" forces writing high byte first, even if less efficient,
2809      for correct operation with 16-bit I/O registers.  */
2810   int mem_volatile_p = MEM_VOLATILE_P (dest);
2811   int tmp;
2812
2813   if (!l)
2814     l = &tmp;
2815   if (CONSTANT_ADDRESS_P (base))
2816     {
2817       if (optimize > 0 && io_address_operand (base, HImode))
2818         {
2819           *l = 2;
2820           return (AS2 (out,%m0+1-0x20,%B1) CR_TAB
2821                   AS2 (out,%m0-0x20,%A1));
2822         }
2823       return *l = 4, (AS2 (sts,%m0+1,%B1) CR_TAB
2824                       AS2 (sts,%m0,%A1));
2825     }
2826   if (reg_base > 0)
2827     {
2828       if (reg_base == REG_X)
2829         {
2830           if (reg_src == REG_X)
2831             {
2832               /* "st X+,r26" and "st -X,r26" are undefined.  */
2833               if (!mem_volatile_p && reg_unused_after (insn, src))
2834                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2835                               AS2 (st,X,r26)            CR_TAB
2836                               AS2 (adiw,r26,1)          CR_TAB
2837                               AS2 (st,X,__tmp_reg__));
2838               else
2839                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2840                               AS2 (adiw,r26,1)          CR_TAB
2841                               AS2 (st,X,__tmp_reg__)    CR_TAB
2842                               AS2 (sbiw,r26,1)          CR_TAB
2843                               AS2 (st,X,r26));
2844             }
2845           else
2846             {
2847               if (!mem_volatile_p && reg_unused_after (insn, base))
2848                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2849                               AS2 (st,X,%B1));
2850               else
2851                 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2852                               AS2 (st,X,%B1)   CR_TAB
2853                               AS2 (st,-X,%A1));
2854             }
2855         }
2856       else
2857         return  *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2858                        AS2 (st,%0,%A1));
2859     }
2860   else if (GET_CODE (base) == PLUS)
2861     {
2862       int disp = INTVAL (XEXP (base, 1));
2863       reg_base = REGNO (XEXP (base, 0));
2864       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2865         {
2866           if (reg_base != REG_Y)
2867             fatal_insn ("incorrect insn:",insn);
2868
2869           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2870             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2871                             AS2 (std,Y+63,%B1)    CR_TAB
2872                             AS2 (std,Y+62,%A1)    CR_TAB
2873                             AS2 (sbiw,r28,%o0-62));
2874
2875           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2876                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2877                           AS2 (std,Y+1,%B1)        CR_TAB
2878                           AS2 (st,Y,%A1)           CR_TAB
2879                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2880                           AS2 (sbci,r29,hi8(%o0)));
2881         }
2882       if (reg_base == REG_X)
2883         {
2884           /* (X + d) = R */
2885           if (reg_src == REG_X)
2886             {
2887               *l = 7;
2888               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2889                       AS2 (mov,__zero_reg__,r27) CR_TAB
2890                       AS2 (adiw,r26,%o0+1)       CR_TAB
2891                       AS2 (st,X,__zero_reg__)    CR_TAB
2892                       AS2 (st,-X,__tmp_reg__)    CR_TAB
2893                       AS1 (clr,__zero_reg__)     CR_TAB
2894                       AS2 (sbiw,r26,%o0));
2895             }
2896           *l = 4;
2897           return (AS2 (adiw,r26,%o0+1) CR_TAB
2898                   AS2 (st,X,%B1)       CR_TAB
2899                   AS2 (st,-X,%A1)      CR_TAB
2900                   AS2 (sbiw,r26,%o0));
2901         }
2902       return *l=2, (AS2 (std,%B0,%B1)    CR_TAB
2903                     AS2 (std,%A0,%A1));
2904     }
2905   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2906     return *l=2, (AS2 (st,%0,%B1) CR_TAB
2907                   AS2 (st,%0,%A1));
2908   else if (GET_CODE (base) == POST_INC) /* (R++) */
2909     {
2910       if (mem_volatile_p)
2911         {
2912           if (REGNO (XEXP (base, 0)) == REG_X)
2913             {
2914               *l = 4;
2915               return (AS2 (adiw,r26,1)  CR_TAB
2916                       AS2 (st,X,%B1)    CR_TAB
2917                       AS2 (st,-X,%A1)   CR_TAB
2918                       AS2 (adiw,r26,2));
2919             }
2920           else
2921             {
2922               *l = 3;
2923               return (AS2 (std,%p0+1,%B1) CR_TAB
2924                       AS2 (st,%p0,%A1)    CR_TAB
2925                       AS2 (adiw,%r0,2));
2926             }
2927         }
2928
2929       *l = 2;
2930       return (AS2 (st,%0,%A1)  CR_TAB
2931             AS2 (st,%0,%B1));
2932     }
2933   fatal_insn ("unknown move insn:",insn);
2934   return "";
2935 }
2936
2937 /* Return 1 if frame pointer for current function required.  */
2938
2939 bool
2940 avr_frame_pointer_required_p (void)
2941 {
2942   return (cfun->calls_alloca
2943           || crtl->args.info.nregs == 0
2944           || get_frame_size () > 0);
2945 }
2946
2947 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
2948
2949 static RTX_CODE
2950 compare_condition (rtx insn)
2951 {
2952   rtx next = next_real_insn (insn);
2953   RTX_CODE cond = UNKNOWN;
2954   if (next && GET_CODE (next) == JUMP_INSN)
2955     {
2956       rtx pat = PATTERN (next);
2957       rtx src = SET_SRC (pat);
2958       rtx t = XEXP (src, 0);
2959       cond = GET_CODE (t);
2960     }
2961   return cond;
2962 }
2963
2964 /* Returns nonzero if INSN is a tst insn that only tests the sign.  */
2965
2966 static int
2967 compare_sign_p (rtx insn)
2968 {
2969   RTX_CODE cond = compare_condition (insn);
2970   return (cond == GE || cond == LT);
2971 }
2972
2973 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2974    that needs to be swapped (GT, GTU, LE, LEU).  */
2975
2976 int
2977 compare_diff_p (rtx insn)
2978 {
2979   RTX_CODE cond = compare_condition (insn);
2980   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2981 }
2982
2983 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition.  */
2984
2985 int
2986 compare_eq_p (rtx insn)
2987 {
2988   RTX_CODE cond = compare_condition (insn);
2989   return (cond == EQ || cond == NE);
2990 }
2991
2992
2993 /* Output test instruction for HImode.  */
2994
2995 const char *
2996 out_tsthi (rtx insn, rtx op, int *l)
2997 {
2998   if (compare_sign_p (insn))
2999     {
3000       if (l) *l = 1;
3001       return AS1 (tst,%B0);
3002     }
3003   if (reg_unused_after (insn, op)
3004       && compare_eq_p (insn))
3005     {
3006       /* Faster than sbiw if we can clobber the operand.  */
3007       if (l) *l = 1;
3008       return "or %A0,%B0";
3009     }
3010   if (test_hard_reg_class (ADDW_REGS, op))
3011     {
3012       if (l) *l = 1;
3013       return AS2 (sbiw,%0,0);
3014     }
3015   if (l) *l = 2;
3016   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
3017           AS2 (cpc,%B0,__zero_reg__));
3018 }
3019
3020
3021 /* Output test instruction for SImode.  */
3022
3023 const char *
3024 out_tstsi (rtx insn, rtx op, int *l)
3025 {
3026   if (compare_sign_p (insn))
3027     {
3028       if (l) *l = 1;
3029       return AS1 (tst,%D0);
3030     }
3031   if (test_hard_reg_class (ADDW_REGS, op))
3032     {
3033       if (l) *l = 3;
3034       return (AS2 (sbiw,%A0,0) CR_TAB
3035               AS2 (cpc,%C0,__zero_reg__) CR_TAB
3036               AS2 (cpc,%D0,__zero_reg__));
3037     }
3038   if (l) *l = 4;
3039   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
3040           AS2 (cpc,%B0,__zero_reg__) CR_TAB
3041           AS2 (cpc,%C0,__zero_reg__) CR_TAB
3042           AS2 (cpc,%D0,__zero_reg__));
3043 }
3044
3045
3046 /* Generate asm equivalent for various shifts.
3047    Shift count is a CONST_INT, MEM or REG.
3048    This only handles cases that are not already
3049    carefully hand-optimized in ?sh??i3_out.  */
3050
3051 void
3052 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
3053                     int *len, int t_len)
3054 {
3055   rtx op[10];
3056   char str[500];
3057   int second_label = 1;
3058   int saved_in_tmp = 0;
3059   int use_zero_reg = 0;
3060
3061   op[0] = operands[0];
3062   op[1] = operands[1];
3063   op[2] = operands[2];
3064   op[3] = operands[3];
3065   str[0] = 0;
3066
3067   if (len)
3068     *len = 1;
3069
3070   if (GET_CODE (operands[2]) == CONST_INT)
3071     {
3072       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3073       int count = INTVAL (operands[2]);
3074       int max_len = 10;  /* If larger than this, always use a loop.  */
3075
3076       if (count <= 0)
3077         {
3078           if (len)
3079             *len = 0;
3080           return;
3081         }
3082
3083       if (count < 8 && !scratch)
3084         use_zero_reg = 1;
3085
3086       if (optimize_size)
3087         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
3088
3089       if (t_len * count <= max_len)
3090         {
3091           /* Output shifts inline with no loop - faster.  */
3092           if (len)
3093             *len = t_len * count;
3094           else
3095             {
3096               while (count-- > 0)
3097                 output_asm_insn (templ, op);
3098             }
3099
3100           return;
3101         }
3102
3103       if (scratch)
3104         {
3105           if (!len)
3106             strcat (str, AS2 (ldi,%3,%2));
3107         }
3108       else if (use_zero_reg)
3109         {
3110           /* Hack to save one word: use __zero_reg__ as loop counter.
3111              Set one bit, then shift in a loop until it is 0 again.  */
3112
3113           op[3] = zero_reg_rtx;
3114           if (len)
3115             *len = 2;
3116           else
3117             strcat (str, ("set" CR_TAB
3118                           AS2 (bld,%3,%2-1)));
3119         }
3120       else
3121         {
3122           /* No scratch register available, use one from LD_REGS (saved in
3123              __tmp_reg__) that doesn't overlap with registers to shift.  */
3124
3125           op[3] = gen_rtx_REG (QImode,
3126                            ((true_regnum (operands[0]) - 1) & 15) + 16);
3127           op[4] = tmp_reg_rtx;
3128           saved_in_tmp = 1;
3129
3130           if (len)
3131             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
3132           else
3133             strcat (str, (AS2 (mov,%4,%3) CR_TAB
3134                           AS2 (ldi,%3,%2)));
3135         }
3136
3137       second_label = 0;
3138     }
3139   else if (GET_CODE (operands[2]) == MEM)
3140     {
3141       rtx op_mov[10];
3142       
3143       op[3] = op_mov[0] = tmp_reg_rtx;
3144       op_mov[1] = op[2];
3145
3146       if (len)
3147         out_movqi_r_mr (insn, op_mov, len);
3148       else
3149         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
3150     }
3151   else if (register_operand (operands[2], QImode))
3152     {
3153       if (reg_unused_after (insn, operands[2]))
3154         op[3] = op[2];
3155       else
3156         {
3157           op[3] = tmp_reg_rtx;
3158           if (!len)
3159             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
3160         }
3161     }
3162   else
3163     fatal_insn ("bad shift insn:", insn);
3164
3165   if (second_label)
3166     {
3167       if (len)
3168         ++*len;
3169       else
3170         strcat (str, AS1 (rjmp,2f));
3171     }
3172
3173   if (len)
3174     *len += t_len + 2;  /* template + dec + brXX */
3175   else
3176     {
3177       strcat (str, "\n1:\t");
3178       strcat (str, templ);
3179       strcat (str, second_label ? "\n2:\t" : "\n\t");
3180       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3181       strcat (str, CR_TAB);
3182       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3183       if (saved_in_tmp)
3184         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3185       output_asm_insn (str, op);
3186     }
3187 }
3188
3189
3190 /* 8bit shift left ((char)x << i)   */
3191
3192 const char *
3193 ashlqi3_out (rtx insn, rtx operands[], int *len)
3194 {
3195   if (GET_CODE (operands[2]) == CONST_INT)
3196     {
3197       int k;
3198
3199       if (!len)
3200         len = &k;
3201
3202       switch (INTVAL (operands[2]))
3203         {
3204         default:
3205           if (INTVAL (operands[2]) < 8)
3206             break;
3207
3208           *len = 1;
3209           return AS1 (clr,%0);
3210           
3211         case 1:
3212           *len = 1;
3213           return AS1 (lsl,%0);
3214           
3215         case 2:
3216           *len = 2;
3217           return (AS1 (lsl,%0) CR_TAB
3218                   AS1 (lsl,%0));
3219
3220         case 3:
3221           *len = 3;
3222           return (AS1 (lsl,%0) CR_TAB
3223                   AS1 (lsl,%0) CR_TAB
3224                   AS1 (lsl,%0));
3225
3226         case 4:
3227           if (test_hard_reg_class (LD_REGS, operands[0]))
3228             {
3229               *len = 2;
3230               return (AS1 (swap,%0) CR_TAB
3231                       AS2 (andi,%0,0xf0));
3232             }
3233           *len = 4;
3234           return (AS1 (lsl,%0) CR_TAB
3235                   AS1 (lsl,%0) CR_TAB
3236                   AS1 (lsl,%0) CR_TAB
3237                   AS1 (lsl,%0));
3238
3239         case 5:
3240           if (test_hard_reg_class (LD_REGS, operands[0]))
3241             {
3242               *len = 3;
3243               return (AS1 (swap,%0) CR_TAB
3244                       AS1 (lsl,%0)  CR_TAB
3245                       AS2 (andi,%0,0xe0));
3246             }
3247           *len = 5;
3248           return (AS1 (lsl,%0) CR_TAB
3249                   AS1 (lsl,%0) CR_TAB
3250                   AS1 (lsl,%0) CR_TAB
3251                   AS1 (lsl,%0) CR_TAB
3252                   AS1 (lsl,%0));
3253
3254         case 6:
3255           if (test_hard_reg_class (LD_REGS, operands[0]))
3256             {
3257               *len = 4;
3258               return (AS1 (swap,%0) CR_TAB
3259                       AS1 (lsl,%0)  CR_TAB
3260                       AS1 (lsl,%0)  CR_TAB
3261                       AS2 (andi,%0,0xc0));
3262             }
3263           *len = 6;
3264           return (AS1 (lsl,%0) CR_TAB
3265                   AS1 (lsl,%0) CR_TAB
3266                   AS1 (lsl,%0) CR_TAB
3267                   AS1 (lsl,%0) CR_TAB
3268                   AS1 (lsl,%0) CR_TAB
3269                   AS1 (lsl,%0));
3270
3271         case 7:
3272           *len = 3;
3273           return (AS1 (ror,%0) CR_TAB
3274                   AS1 (clr,%0) CR_TAB
3275                   AS1 (ror,%0));
3276         }
3277     }
3278   else if (CONSTANT_P (operands[2]))
3279     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3280
3281   out_shift_with_cnt (AS1 (lsl,%0),
3282                       insn, operands, len, 1);
3283   return "";
3284 }
3285
3286
3287 /* 16bit shift left ((short)x << i)   */
3288
3289 const char *
3290 ashlhi3_out (rtx insn, rtx operands[], int *len)
3291 {
3292   if (GET_CODE (operands[2]) == CONST_INT)
3293     {
3294       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3295       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3296       int k;
3297       int *t = len;
3298
3299       if (!len)
3300         len = &k;
3301       
3302       switch (INTVAL (operands[2]))
3303         {
3304         default:
3305           if (INTVAL (operands[2]) < 16)
3306             break;
3307
3308           *len = 2;
3309           return (AS1 (clr,%B0) CR_TAB
3310                   AS1 (clr,%A0));
3311
3312         case 4:
3313           if (optimize_size && scratch)
3314             break;  /* 5 */
3315           if (ldi_ok)
3316             {
3317               *len = 6;
3318               return (AS1 (swap,%A0)      CR_TAB
3319                       AS1 (swap,%B0)      CR_TAB
3320                       AS2 (andi,%B0,0xf0) CR_TAB
3321                       AS2 (eor,%B0,%A0)   CR_TAB
3322                       AS2 (andi,%A0,0xf0) CR_TAB
3323                       AS2 (eor,%B0,%A0));
3324             }
3325           if (scratch)
3326             {
3327               *len = 7;
3328               return (AS1 (swap,%A0)    CR_TAB
3329                       AS1 (swap,%B0)    CR_TAB
3330                       AS2 (ldi,%3,0xf0) CR_TAB
3331                       "and %B0,%3"      CR_TAB
3332                       AS2 (eor,%B0,%A0) CR_TAB
3333                       "and %A0,%3"      CR_TAB
3334                       AS2 (eor,%B0,%A0));
3335             }
3336           break;  /* optimize_size ? 6 : 8 */
3337
3338         case 5:
3339           if (optimize_size)
3340             break;  /* scratch ? 5 : 6 */
3341           if (ldi_ok)
3342             {
3343               *len = 8;
3344               return (AS1 (lsl,%A0)       CR_TAB
3345                       AS1 (rol,%B0)       CR_TAB
3346                       AS1 (swap,%A0)      CR_TAB
3347                       AS1 (swap,%B0)      CR_TAB
3348                       AS2 (andi,%B0,0xf0) CR_TAB
3349                       AS2 (eor,%B0,%A0)   CR_TAB
3350                       AS2 (andi,%A0,0xf0) CR_TAB
3351                       AS2 (eor,%B0,%A0));
3352             }
3353           if (scratch)
3354             {
3355               *len = 9;
3356               return (AS1 (lsl,%A0)     CR_TAB
3357                       AS1 (rol,%B0)     CR_TAB
3358                       AS1 (swap,%A0)    CR_TAB
3359                       AS1 (swap,%B0)    CR_TAB
3360                       AS2 (ldi,%3,0xf0) CR_TAB
3361                       "and %B0,%3"      CR_TAB
3362                       AS2 (eor,%B0,%A0) CR_TAB
3363                       "and %A0,%3"      CR_TAB
3364                       AS2 (eor,%B0,%A0));
3365             }
3366           break;  /* 10 */
3367
3368         case 6:
3369           if (optimize_size)
3370             break;  /* scratch ? 5 : 6 */
3371           *len = 9;
3372           return (AS1 (clr,__tmp_reg__) CR_TAB
3373                   AS1 (lsr,%B0)         CR_TAB
3374                   AS1 (ror,%A0)         CR_TAB
3375                   AS1 (ror,__tmp_reg__) CR_TAB
3376                   AS1 (lsr,%B0)         CR_TAB
3377                   AS1 (ror,%A0)         CR_TAB
3378                   AS1 (ror,__tmp_reg__) CR_TAB
3379                   AS2 (mov,%B0,%A0)     CR_TAB
3380                   AS2 (mov,%A0,__tmp_reg__));
3381
3382         case 7:
3383           *len = 5;
3384           return (AS1 (lsr,%B0)     CR_TAB
3385                   AS2 (mov,%B0,%A0) CR_TAB
3386                   AS1 (clr,%A0)     CR_TAB
3387                   AS1 (ror,%B0)     CR_TAB
3388                   AS1 (ror,%A0));
3389
3390         case 8:
3391           return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3392                             AS1 (clr,%A0));
3393
3394         case 9:
3395           *len = 3;
3396           return (AS2 (mov,%B0,%A0) CR_TAB
3397                   AS1 (clr,%A0)     CR_TAB
3398                   AS1 (lsl,%B0));
3399
3400         case 10:
3401           *len = 4;
3402           return (AS2 (mov,%B0,%A0) CR_TAB
3403                   AS1 (clr,%A0)     CR_TAB
3404                   AS1 (lsl,%B0)     CR_TAB
3405                   AS1 (lsl,%B0));
3406
3407         case 11:
3408           *len = 5;
3409           return (AS2 (mov,%B0,%A0) CR_TAB
3410                   AS1 (clr,%A0)     CR_TAB
3411                   AS1 (lsl,%B0)     CR_TAB
3412                   AS1 (lsl,%B0)     CR_TAB
3413                   AS1 (lsl,%B0));
3414
3415         case 12:
3416           if (ldi_ok)
3417             {
3418               *len = 4;
3419               return (AS2 (mov,%B0,%A0) CR_TAB
3420                       AS1 (clr,%A0)     CR_TAB
3421                       AS1 (swap,%B0)    CR_TAB
3422                       AS2 (andi,%B0,0xf0));
3423             }
3424           if (scratch)
3425             {
3426               *len = 5;
3427               return (AS2 (mov,%B0,%A0) CR_TAB
3428                       AS1 (clr,%A0)     CR_TAB
3429                       AS1 (swap,%B0)    CR_TAB
3430                       AS2 (ldi,%3,0xf0) CR_TAB
3431                       "and %B0,%3");
3432             }
3433           *len = 6;
3434           return (AS2 (mov,%B0,%A0) CR_TAB
3435                   AS1 (clr,%A0)     CR_TAB
3436                   AS1 (lsl,%B0)     CR_TAB
3437                   AS1 (lsl,%B0)     CR_TAB
3438                   AS1 (lsl,%B0)     CR_TAB
3439                   AS1 (lsl,%B0));
3440
3441         case 13:
3442           if (ldi_ok)
3443             {
3444               *len = 5;
3445               return (AS2 (mov,%B0,%A0) CR_TAB
3446                       AS1 (clr,%A0)     CR_TAB
3447                       AS1 (swap,%B0)    CR_TAB
3448                       AS1 (lsl,%B0)     CR_TAB
3449                       AS2 (andi,%B0,0xe0));
3450             }
3451           if (AVR_HAVE_MUL && scratch)
3452             {
3453               *len = 5;
3454               return (AS2 (ldi,%3,0x20) CR_TAB
3455                       AS2 (mul,%A0,%3)  CR_TAB
3456                       AS2 (mov,%B0,r0)  CR_TAB
3457                       AS1 (clr,%A0)     CR_TAB
3458                       AS1 (clr,__zero_reg__));
3459             }
3460           if (optimize_size && scratch)
3461             break;  /* 5 */
3462           if (scratch)
3463             {
3464               *len = 6;
3465               return (AS2 (mov,%B0,%A0) CR_TAB
3466                       AS1 (clr,%A0)     CR_TAB
3467                       AS1 (swap,%B0)    CR_TAB
3468                       AS1 (lsl,%B0)     CR_TAB
3469                       AS2 (ldi,%3,0xe0) CR_TAB
3470                       "and %B0,%3");
3471             }
3472           if (AVR_HAVE_MUL)
3473             {
3474               *len = 6;
3475               return ("set"            CR_TAB
3476                       AS2 (bld,r1,5)   CR_TAB
3477                       AS2 (mul,%A0,r1) CR_TAB
3478                       AS2 (mov,%B0,r0) CR_TAB
3479                       AS1 (clr,%A0)    CR_TAB
3480                       AS1 (clr,__zero_reg__));
3481             }
3482           *len = 7;
3483           return (AS2 (mov,%B0,%A0) CR_TAB
3484                   AS1 (clr,%A0)     CR_TAB
3485                   AS1 (lsl,%B0)     CR_TAB
3486                   AS1 (lsl,%B0)     CR_TAB
3487                   AS1 (lsl,%B0)     CR_TAB
3488                   AS1 (lsl,%B0)     CR_TAB
3489                   AS1 (lsl,%B0));
3490
3491         case 14:
3492           if (AVR_HAVE_MUL && ldi_ok)
3493             {
3494               *len = 5;
3495               return (AS2 (ldi,%B0,0x40) CR_TAB
3496                       AS2 (mul,%A0,%B0)  CR_TAB
3497                       AS2 (mov,%B0,r0)   CR_TAB
3498                       AS1 (clr,%A0)      CR_TAB
3499                       AS1 (clr,__zero_reg__));
3500             }
3501           if (AVR_HAVE_MUL && scratch)
3502             {
3503               *len = 5;
3504               return (AS2 (ldi,%3,0x40) CR_TAB
3505                       AS2 (mul,%A0,%3)  CR_TAB
3506                       AS2 (mov,%B0,r0)  CR_TAB
3507                       AS1 (clr,%A0)     CR_TAB
3508                       AS1 (clr,__zero_reg__));
3509             }
3510           if (optimize_size && ldi_ok)
3511             {
3512               *len = 5;
3513               return (AS2 (mov,%B0,%A0) CR_TAB
3514                       AS2 (ldi,%A0,6) "\n1:\t"
3515                       AS1 (lsl,%B0)     CR_TAB
3516                       AS1 (dec,%A0)     CR_TAB
3517                       AS1 (brne,1b));
3518             }
3519           if (optimize_size && scratch)
3520             break;  /* 5 */
3521           *len = 6;
3522           return (AS1 (clr,%B0) CR_TAB
3523                   AS1 (lsr,%A0) CR_TAB
3524                   AS1 (ror,%B0) CR_TAB
3525                   AS1 (lsr,%A0) CR_TAB
3526                   AS1 (ror,%B0) CR_TAB
3527                   AS1 (clr,%A0));
3528
3529         case 15:
3530           *len = 4;
3531           return (AS1 (clr,%B0) CR_TAB
3532                   AS1 (lsr,%A0) CR_TAB
3533                   AS1 (ror,%B0) CR_TAB
3534                   AS1 (clr,%A0));
3535         }
3536       len = t;
3537     }
3538   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3539                        AS1 (rol,%B0)),
3540                        insn, operands, len, 2);
3541   return "";
3542 }
3543
3544
3545 /* 32bit shift left ((long)x << i)   */
3546
3547 const char *
3548 ashlsi3_out (rtx insn, rtx operands[], int *len)
3549 {
3550   if (GET_CODE (operands[2]) == CONST_INT)
3551     {
3552       int k;
3553       int *t = len;
3554       
3555       if (!len)
3556         len = &k;
3557       
3558       switch (INTVAL (operands[2]))
3559         {
3560         default:
3561           if (INTVAL (operands[2]) < 32)
3562             break;
3563
3564           if (AVR_HAVE_MOVW)
3565             return *len = 3, (AS1 (clr,%D0) CR_TAB
3566                               AS1 (clr,%C0) CR_TAB
3567                               AS2 (movw,%A0,%C0));
3568           *len = 4;
3569           return (AS1 (clr,%D0) CR_TAB
3570                   AS1 (clr,%C0) CR_TAB
3571                   AS1 (clr,%B0) CR_TAB
3572                   AS1 (clr,%A0));
3573
3574         case 8:
3575           {
3576             int reg0 = true_regnum (operands[0]);
3577             int reg1 = true_regnum (operands[1]);
3578             *len = 4;
3579             if (reg0 >= reg1)
3580               return (AS2 (mov,%D0,%C1)  CR_TAB
3581                       AS2 (mov,%C0,%B1)  CR_TAB
3582                       AS2 (mov,%B0,%A1)  CR_TAB
3583                       AS1 (clr,%A0));
3584             else
3585               return (AS1 (clr,%A0)      CR_TAB
3586                       AS2 (mov,%B0,%A1)  CR_TAB
3587                       AS2 (mov,%C0,%B1)  CR_TAB
3588                       AS2 (mov,%D0,%C1));
3589           }
3590
3591         case 16:
3592           {
3593             int reg0 = true_regnum (operands[0]);
3594             int reg1 = true_regnum (operands[1]);
3595             if (reg0 + 2 == reg1)
3596               return *len = 2, (AS1 (clr,%B0)      CR_TAB
3597                                 AS1 (clr,%A0));
3598             if (AVR_HAVE_MOVW)
3599               return *len = 3, (AS2 (movw,%C0,%A1) CR_TAB
3600                                 AS1 (clr,%B0)      CR_TAB
3601                                 AS1 (clr,%A0));
3602             else
3603               return *len = 4, (AS2 (mov,%C0,%A1)  CR_TAB
3604                                 AS2 (mov,%D0,%B1)  CR_TAB
3605                                 AS1 (clr,%B0)      CR_TAB
3606                                 AS1 (clr,%A0));
3607           }
3608
3609         case 24:
3610           *len = 4;
3611           return (AS2 (mov,%D0,%A1)  CR_TAB
3612                   AS1 (clr,%C0)      CR_TAB
3613                   AS1 (clr,%B0)      CR_TAB
3614                   AS1 (clr,%A0));
3615
3616         case 31:
3617           *len = 6;
3618           return (AS1 (clr,%D0) CR_TAB
3619                   AS1 (lsr,%A0) CR_TAB
3620                   AS1 (ror,%D0) CR_TAB
3621                   AS1 (clr,%C0) CR_TAB
3622                   AS1 (clr,%B0) CR_TAB
3623                   AS1 (clr,%A0));
3624         }
3625       len = t;
3626     }
3627   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3628                        AS1 (rol,%B0) CR_TAB
3629                        AS1 (rol,%C0) CR_TAB
3630                        AS1 (rol,%D0)),
3631                        insn, operands, len, 4);
3632   return "";
3633 }
3634
3635 /* 8bit arithmetic shift right  ((signed char)x >> i) */
3636
3637 const char *
3638 ashrqi3_out (rtx insn, rtx operands[], int *len)
3639 {
3640   if (GET_CODE (operands[2]) == CONST_INT)
3641     {
3642       int k;
3643
3644       if (!len)
3645         len = &k;
3646
3647       switch (INTVAL (operands[2]))
3648         {
3649         case 1:
3650           *len = 1;
3651           return AS1 (asr,%0);
3652
3653         case 2:
3654           *len = 2;
3655           return (AS1 (asr,%0) CR_TAB
3656                   AS1 (asr,%0));
3657
3658         case 3:
3659           *len = 3;
3660           return (AS1 (asr,%0) CR_TAB
3661                   AS1 (asr,%0) CR_TAB
3662                   AS1 (asr,%0));
3663
3664         case 4:
3665           *len = 4;
3666           return (AS1 (asr,%0) CR_TAB
3667                   AS1 (asr,%0) CR_TAB
3668                   AS1 (asr,%0) CR_TAB
3669                   AS1 (asr,%0));
3670
3671         case 5:
3672           *len = 5;
3673           return (AS1 (asr,%0) CR_TAB
3674                   AS1 (asr,%0) CR_TAB
3675                   AS1 (asr,%0) CR_TAB
3676                   AS1 (asr,%0) CR_TAB
3677                   AS1 (asr,%0));
3678
3679         case 6:
3680           *len = 4;
3681           return (AS2 (bst,%0,6)  CR_TAB
3682                   AS1 (lsl,%0)    CR_TAB
3683                   AS2 (sbc,%0,%0) CR_TAB
3684                   AS2 (bld,%0,0));
3685
3686         default:
3687           if (INTVAL (operands[2]) < 8)
3688             break;
3689
3690           /* fall through */
3691
3692         case 7:
3693           *len = 2;
3694           return (AS1 (lsl,%0) CR_TAB
3695                   AS2 (sbc,%0,%0));
3696         }
3697     }
3698   else if (CONSTANT_P (operands[2]))
3699     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3700
3701   out_shift_with_cnt (AS1 (asr,%0),
3702                       insn, operands, len, 1);
3703   return "";
3704 }
3705
3706
3707 /* 16bit arithmetic shift right  ((signed short)x >> i) */
3708
3709 const char *
3710 ashrhi3_out (rtx insn, rtx operands[], int *len)
3711 {
3712   if (GET_CODE (operands[2]) == CONST_INT)
3713     {
3714       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3715       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3716       int k;
3717       int *t = len;
3718       
3719       if (!len)
3720         len = &k;
3721
3722       switch (INTVAL (operands[2]))
3723         {
3724         case 4:
3725         case 5:
3726           /* XXX try to optimize this too? */
3727           break;
3728
3729         case 6:
3730           if (optimize_size)
3731             break;  /* scratch ? 5 : 6 */
3732           *len = 8;
3733           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3734                   AS2 (mov,%A0,%B0)         CR_TAB
3735                   AS1 (lsl,__tmp_reg__)     CR_TAB
3736                   AS1 (rol,%A0)             CR_TAB
3737                   AS2 (sbc,%B0,%B0)         CR_TAB
3738                   AS1 (lsl,__tmp_reg__)     CR_TAB
3739                   AS1 (rol,%A0)             CR_TAB
3740                   AS1 (rol,%B0));
3741
3742         case 7:
3743           *len = 4;
3744           return (AS1 (lsl,%A0)     CR_TAB
3745                   AS2 (mov,%A0,%B0) CR_TAB
3746                   AS1 (rol,%A0)     CR_TAB
3747                   AS2 (sbc,%B0,%B0));
3748
3749         case 8:
3750           {
3751             int reg0 = true_regnum (operands[0]);
3752             int reg1 = true_regnum (operands[1]);
3753
3754             if (reg0 == reg1)
3755               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3756                                 AS1 (lsl,%B0)     CR_TAB
3757                                 AS2 (sbc,%B0,%B0));
3758             else 
3759               return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3760                                 AS1 (clr,%B0)     CR_TAB
3761                                 AS2 (sbrc,%A0,7)  CR_TAB
3762                                 AS1 (dec,%B0));
3763           }
3764
3765         case 9:
3766           *len = 4;
3767           return (AS2 (mov,%A0,%B0) CR_TAB
3768                   AS1 (lsl,%B0)      CR_TAB
3769                   AS2 (sbc,%B0,%B0) CR_TAB
3770                   AS1 (asr,%A0));
3771
3772         case 10:
3773           *len = 5;
3774           return (AS2 (mov,%A0,%B0) CR_TAB
3775                   AS1 (lsl,%B0)     CR_TAB
3776                   AS2 (sbc,%B0,%B0) CR_TAB
3777                   AS1 (asr,%A0)     CR_TAB
3778                   AS1 (asr,%A0));
3779
3780         case 11:
3781           if (AVR_HAVE_MUL && ldi_ok)
3782             {
3783               *len = 5;
3784               return (AS2 (ldi,%A0,0x20) CR_TAB
3785                       AS2 (muls,%B0,%A0) CR_TAB
3786                       AS2 (mov,%A0,r1)   CR_TAB
3787                       AS2 (sbc,%B0,%B0)  CR_TAB
3788                       AS1 (clr,__zero_reg__));
3789             }
3790           if (optimize_size && scratch)
3791             break;  /* 5 */
3792           *len = 6;
3793           return (AS2 (mov,%A0,%B0) CR_TAB
3794                   AS1 (lsl,%B0)     CR_TAB
3795                   AS2 (sbc,%B0,%B0) CR_TAB
3796                   AS1 (asr,%A0)     CR_TAB
3797                   AS1 (asr,%A0)     CR_TAB
3798                   AS1 (asr,%A0));
3799
3800         case 12:
3801           if (AVR_HAVE_MUL && ldi_ok)
3802             {
3803               *len = 5;
3804               return (AS2 (ldi,%A0,0x10) CR_TAB
3805                       AS2 (muls,%B0,%A0) CR_TAB
3806                       AS2 (mov,%A0,r1)   CR_TAB
3807                       AS2 (sbc,%B0,%B0)  CR_TAB
3808                       AS1 (clr,__zero_reg__));
3809             }
3810           if (optimize_size && scratch)
3811             break;  /* 5 */
3812           *len = 7;
3813           return (AS2 (mov,%A0,%B0) CR_TAB
3814                   AS1 (lsl,%B0)     CR_TAB
3815                   AS2 (sbc,%B0,%B0) CR_TAB
3816                   AS1 (asr,%A0)     CR_TAB
3817                   AS1 (asr,%A0)     CR_TAB
3818                   AS1 (asr,%A0)     CR_TAB
3819                   AS1 (asr,%A0));
3820
3821         case 13:
3822           if (AVR_HAVE_MUL && ldi_ok)
3823             {
3824               *len = 5;
3825               return (AS2 (ldi,%A0,0x08) CR_TAB
3826                       AS2 (muls,%B0,%A0) CR_TAB
3827                       AS2 (mov,%A0,r1)   CR_TAB
3828                       AS2 (sbc,%B0,%B0)  CR_TAB
3829                       AS1 (clr,__zero_reg__));
3830             }
3831           if (optimize_size)
3832             break;  /* scratch ? 5 : 7 */
3833           *len = 8;
3834           return (AS2 (mov,%A0,%B0) CR_TAB
3835                   AS1 (lsl,%B0)     CR_TAB
3836                   AS2 (sbc,%B0,%B0) CR_TAB
3837                   AS1 (asr,%A0)     CR_TAB
3838                   AS1 (asr,%A0)     CR_TAB
3839                   AS1 (asr,%A0)     CR_TAB
3840                   AS1 (asr,%A0)     CR_TAB
3841                   AS1 (asr,%A0));
3842
3843         case 14:
3844           *len = 5;
3845           return (AS1 (lsl,%B0)     CR_TAB
3846                   AS2 (sbc,%A0,%A0) CR_TAB
3847                   AS1 (lsl,%B0)     CR_TAB
3848                   AS2 (mov,%B0,%A0) CR_TAB
3849                   AS1 (rol,%A0));
3850
3851         default:
3852           if (INTVAL (operands[2]) < 16)
3853             break;
3854
3855           /* fall through */
3856
3857         case 15:
3858           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
3859                             AS2 (sbc,%A0,%A0) CR_TAB
3860                             AS2 (mov,%B0,%A0));
3861         }
3862       len = t;
3863     }
3864   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3865                        AS1 (ror,%A0)),
3866                        insn, operands, len, 2);
3867   return "";
3868 }
3869
3870
3871 /* 32bit arithmetic shift right  ((signed long)x >> i) */
3872
3873 const char *
3874 ashrsi3_out (rtx insn, rtx operands[], int *len)
3875 {
3876   if (GET_CODE (operands[2]) == CONST_INT)
3877     {
3878       int k;
3879       int *t = len;
3880       
3881       if (!len)
3882         len = &k;
3883       
3884       switch (INTVAL (operands[2]))
3885         {
3886         case 8:
3887           {
3888             int reg0 = true_regnum (operands[0]);
3889             int reg1 = true_regnum (operands[1]);
3890             *len=6;
3891             if (reg0 <= reg1)
3892               return (AS2 (mov,%A0,%B1) CR_TAB
3893                       AS2 (mov,%B0,%C1) CR_TAB
3894                       AS2 (mov,%C0,%D1) CR_TAB
3895                       AS1 (clr,%D0)     CR_TAB
3896                       AS2 (sbrc,%C0,7)  CR_TAB
3897                       AS1 (dec,%D0));
3898             else
3899               return (AS1 (clr,%D0)     CR_TAB
3900                       AS2 (sbrc,%D1,7)  CR_TAB
3901                       AS1 (dec,%D0)     CR_TAB
3902                       AS2 (mov,%C0,%D1) CR_TAB
3903                       AS2 (mov,%B0,%C1) CR_TAB
3904                       AS2 (mov,%A0,%B1));
3905           }
3906           
3907         case 16:
3908           {
3909             int reg0 = true_regnum (operands[0]);
3910             int reg1 = true_regnum (operands[1]);
3911             
3912             if (reg0 == reg1 + 2)
3913               return *len = 4, (AS1 (clr,%D0)     CR_TAB
3914                                 AS2 (sbrc,%B0,7)  CR_TAB
3915                                 AS1 (com,%D0)     CR_TAB
3916                                 AS2 (mov,%C0,%D0));
3917             if (AVR_HAVE_MOVW)
3918               return *len = 5, (AS2 (movw,%A0,%C1) CR_TAB
3919                                 AS1 (clr,%D0)      CR_TAB
3920                                 AS2 (sbrc,%B0,7)   CR_TAB
3921                                 AS1 (com,%D0)      CR_TAB
3922                                 AS2 (mov,%C0,%D0));
3923             else 
3924               return *len = 6, (AS2 (mov,%B0,%D1) CR_TAB
3925                                 AS2 (mov,%A0,%C1) CR_TAB
3926                                 AS1 (clr,%D0)     CR_TAB
3927                                 AS2 (sbrc,%B0,7)  CR_TAB
3928                                 AS1 (com,%D0)     CR_TAB
3929                                 AS2 (mov,%C0,%D0));
3930           }
3931
3932         case 24:
3933           return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3934                             AS1 (clr,%D0)     CR_TAB
3935                             AS2 (sbrc,%A0,7)  CR_TAB
3936                             AS1 (com,%D0)     CR_TAB
3937                             AS2 (mov,%B0,%D0) CR_TAB
3938                             AS2 (mov,%C0,%D0));
3939
3940         default:
3941           if (INTVAL (operands[2]) < 32)
3942             break;
3943
3944           /* fall through */
3945
3946         case 31:
3947           if (AVR_HAVE_MOVW)
3948             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
3949                               AS2 (sbc,%A0,%A0) CR_TAB
3950                               AS2 (mov,%B0,%A0) CR_TAB
3951                               AS2 (movw,%C0,%A0));
3952           else
3953             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
3954                               AS2 (sbc,%A0,%A0) CR_TAB
3955                               AS2 (mov,%B0,%A0) CR_TAB
3956                               AS2 (mov,%C0,%A0) CR_TAB
3957                               AS2 (mov,%D0,%A0));
3958         }
3959       len = t;
3960     }
3961   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3962                        AS1 (ror,%C0) CR_TAB
3963                        AS1 (ror,%B0) CR_TAB
3964                        AS1 (ror,%A0)),
3965                        insn, operands, len, 4);
3966   return "";
3967 }
3968
3969 /* 8bit logic shift right ((unsigned char)x >> i) */
3970
3971 const char *
3972 lshrqi3_out (rtx insn, rtx operands[], int *len)
3973 {
3974   if (GET_CODE (operands[2]) == CONST_INT)
3975     {
3976       int k;
3977
3978       if (!len)
3979         len = &k;
3980       
3981       switch (INTVAL (operands[2]))
3982         {
3983         default:
3984           if (INTVAL (operands[2]) < 8)
3985             break;
3986
3987           *len = 1;
3988           return AS1 (clr,%0);
3989
3990         case 1:
3991           *len = 1;
3992           return AS1 (lsr,%0);
3993
3994         case 2:
3995           *len = 2;
3996           return (AS1 (lsr,%0) CR_TAB
3997                   AS1 (lsr,%0));
3998         case 3:
3999           *len = 3;
4000           return (AS1 (lsr,%0) CR_TAB
4001                   AS1 (lsr,%0) CR_TAB
4002                   AS1 (lsr,%0));
4003           
4004         case 4:
4005           if (test_hard_reg_class (LD_REGS, operands[0]))
4006             {
4007               *len=2;
4008               return (AS1 (swap,%0) CR_TAB
4009                       AS2 (andi,%0,0x0f));
4010             }
4011           *len = 4;
4012           return (AS1 (lsr,%0) CR_TAB
4013                   AS1 (lsr,%0) CR_TAB
4014                   AS1 (lsr,%0) CR_TAB
4015                   AS1 (lsr,%0));
4016           
4017         case 5:
4018           if (test_hard_reg_class (LD_REGS, operands[0]))
4019             {
4020               *len = 3;
4021               return (AS1 (swap,%0) CR_TAB
4022                       AS1 (lsr,%0)  CR_TAB
4023                       AS2 (andi,%0,0x7));
4024             }
4025           *len = 5;
4026           return (AS1 (lsr,%0) CR_TAB
4027                   AS1 (lsr,%0) CR_TAB
4028                   AS1 (lsr,%0) CR_TAB
4029                   AS1 (lsr,%0) CR_TAB
4030                   AS1 (lsr,%0));
4031           
4032         case 6:
4033           if (test_hard_reg_class (LD_REGS, operands[0]))
4034             {
4035               *len = 4;
4036               return (AS1 (swap,%0) CR_TAB
4037                       AS1 (lsr,%0)  CR_TAB
4038                       AS1 (lsr,%0)  CR_TAB
4039                       AS2 (andi,%0,0x3));
4040             }
4041           *len = 6;
4042           return (AS1 (lsr,%0) CR_TAB
4043                   AS1 (lsr,%0) CR_TAB
4044                   AS1 (lsr,%0) CR_TAB
4045                   AS1 (lsr,%0) CR_TAB
4046                   AS1 (lsr,%0) CR_TAB
4047                   AS1 (lsr,%0));
4048           
4049         case 7:
4050           *len = 3;
4051           return (AS1 (rol,%0) CR_TAB
4052                   AS1 (clr,%0) CR_TAB
4053                   AS1 (rol,%0));
4054         }
4055     }
4056   else if (CONSTANT_P (operands[2]))
4057     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
4058   
4059   out_shift_with_cnt (AS1 (lsr,%0),
4060                       insn, operands, len, 1);
4061   return "";
4062 }
4063
4064 /* 16bit logic shift right ((unsigned short)x >> i) */
4065
4066 const char *
4067 lshrhi3_out (rtx insn, rtx operands[], int *len)
4068 {
4069   if (GET_CODE (operands[2]) == CONST_INT)
4070     {
4071       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4072       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4073       int k;
4074       int *t = len;
4075
4076       if (!len)
4077         len = &k;
4078       
4079       switch (INTVAL (operands[2]))
4080         {
4081         default:
4082           if (INTVAL (operands[2]) < 16)
4083             break;
4084
4085           *len = 2;
4086           return (AS1 (clr,%B0) CR_TAB
4087                   AS1 (clr,%A0));
4088
4089         case 4:
4090           if (optimize_size && scratch)
4091             break;  /* 5 */
4092           if (ldi_ok)
4093             {
4094               *len = 6;
4095               return (AS1 (swap,%B0)      CR_TAB
4096                       AS1 (swap,%A0)      CR_TAB
4097                       AS2 (andi,%A0,0x0f) CR_TAB
4098                       AS2 (eor,%A0,%B0)   CR_TAB
4099                       AS2 (andi,%B0,0x0f) CR_TAB
4100                       AS2 (eor,%A0,%B0));
4101             }
4102           if (scratch)
4103             {
4104               *len = 7;
4105               return (AS1 (swap,%B0)    CR_TAB
4106                       AS1 (swap,%A0)    CR_TAB
4107                       AS2 (ldi,%3,0x0f) CR_TAB
4108                       "and %A0,%3"      CR_TAB
4109                       AS2 (eor,%A0,%B0) CR_TAB
4110                       "and %B0,%3"      CR_TAB
4111                       AS2 (eor,%A0,%B0));
4112             }
4113           break;  /* optimize_size ? 6 : 8 */
4114
4115         case 5:
4116           if (optimize_size)
4117             break;  /* scratch ? 5 : 6 */
4118           if (ldi_ok)
4119             {
4120               *len = 8;
4121               return (AS1 (lsr,%B0)       CR_TAB
4122                       AS1 (ror,%A0)       CR_TAB
4123                       AS1 (swap,%B0)      CR_TAB
4124                       AS1 (swap,%A0)      CR_TAB
4125                       AS2 (andi,%A0,0x0f) CR_TAB
4126                       AS2 (eor,%A0,%B0)   CR_TAB
4127                       AS2 (andi,%B0,0x0f) CR_TAB
4128                       AS2 (eor,%A0,%B0));
4129             }
4130           if (scratch)
4131             {
4132               *len = 9;
4133               return (AS1 (lsr,%B0)     CR_TAB
4134                       AS1 (ror,%A0)     CR_TAB
4135                       AS1 (swap,%B0)    CR_TAB
4136                       AS1 (swap,%A0)    CR_TAB
4137                       AS2 (ldi,%3,0x0f) CR_TAB
4138                       "and %A0,%3"      CR_TAB
4139                       AS2 (eor,%A0,%B0) CR_TAB
4140                       "and %B0,%3"      CR_TAB
4141                       AS2 (eor,%A0,%B0));
4142             }
4143           break;  /* 10 */
4144
4145         case 6:
4146           if (optimize_size)
4147             break;  /* scratch ? 5 : 6 */
4148           *len = 9;
4149           return (AS1 (clr,__tmp_reg__) CR_TAB
4150                   AS1 (lsl,%A0)         CR_TAB
4151                   AS1 (rol,%B0)         CR_TAB
4152                   AS1 (rol,__tmp_reg__) CR_TAB
4153                   AS1 (lsl,%A0)         CR_TAB
4154                   AS1 (rol,%B0)         CR_TAB
4155                   AS1 (rol,__tmp_reg__) CR_TAB
4156                   AS2 (mov,%A0,%B0)     CR_TAB
4157                   AS2 (mov,%B0,__tmp_reg__));
4158
4159         case 7:
4160           *len = 5;
4161           return (AS1 (lsl,%A0)     CR_TAB
4162                   AS2 (mov,%A0,%B0) CR_TAB
4163                   AS1 (rol,%A0)     CR_TAB
4164                   AS2 (sbc,%B0,%B0) CR_TAB
4165                   AS1 (neg,%B0));
4166
4167         case 8:
4168           return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
4169                             AS1 (clr,%B0));
4170
4171         case 9:
4172           *len = 3;
4173           return (AS2 (mov,%A0,%B0) CR_TAB
4174                   AS1 (clr,%B0)     CR_TAB
4175                   AS1 (lsr,%A0));
4176
4177         case 10:
4178           *len = 4;
4179           return (AS2 (mov,%A0,%B0) CR_TAB
4180                   AS1 (clr,%B0)     CR_TAB
4181                   AS1 (lsr,%A0)     CR_TAB
4182                   AS1 (lsr,%A0));
4183
4184         case 11:
4185           *len = 5;
4186           return (AS2 (mov,%A0,%B0) CR_TAB
4187                   AS1 (clr,%B0)     CR_TAB
4188                   AS1 (lsr,%A0)     CR_TAB
4189                   AS1 (lsr,%A0)     CR_TAB
4190                   AS1 (lsr,%A0));
4191
4192         case 12:
4193           if (ldi_ok)
4194             {
4195               *len = 4;
4196               return (AS2 (mov,%A0,%B0) CR_TAB
4197                       AS1 (clr,%B0)     CR_TAB
4198                       AS1 (swap,%A0)    CR_TAB
4199                       AS2 (andi,%A0,0x0f));
4200             }
4201           if (scratch)
4202             {
4203               *len = 5;
4204               return (AS2 (mov,%A0,%B0) CR_TAB
4205                       AS1 (clr,%B0)     CR_TAB
4206                       AS1 (swap,%A0)    CR_TAB
4207                       AS2 (ldi,%3,0x0f) CR_TAB
4208                       "and %A0,%3");
4209             }
4210           *len = 6;
4211           return (AS2 (mov,%A0,%B0) CR_TAB
4212                   AS1 (clr,%B0)     CR_TAB
4213                   AS1 (lsr,%A0)     CR_TAB
4214                   AS1 (lsr,%A0)     CR_TAB
4215                   AS1 (lsr,%A0)     CR_TAB
4216                   AS1 (lsr,%A0));
4217
4218         case 13:
4219           if (ldi_ok)
4220             {
4221               *len = 5;
4222               return (AS2 (mov,%A0,%B0) CR_TAB
4223                       AS1 (clr,%B0)     CR_TAB
4224                       AS1 (swap,%A0)    CR_TAB
4225                       AS1 (lsr,%A0)     CR_TAB
4226                       AS2 (andi,%A0,0x07));
4227             }
4228           if (AVR_HAVE_MUL && scratch)
4229             {
4230               *len = 5;
4231               return (AS2 (ldi,%3,0x08) CR_TAB
4232                       AS2 (mul,%B0,%3)  CR_TAB
4233                       AS2 (mov,%A0,r1)  CR_TAB
4234                       AS1 (clr,%B0)     CR_TAB
4235                       AS1 (clr,__zero_reg__));
4236             }
4237           if (optimize_size && scratch)
4238             break;  /* 5 */
4239           if (scratch)
4240             {
4241               *len = 6;
4242               return (AS2 (mov,%A0,%B0) CR_TAB
4243                       AS1 (clr,%B0)     CR_TAB
4244                       AS1 (swap,%A0)    CR_TAB
4245                       AS1 (lsr,%A0)     CR_TAB
4246                       AS2 (ldi,%3,0x07) CR_TAB
4247                       "and %A0,%3");
4248             }
4249           if (AVR_HAVE_MUL)
4250             {
4251               *len = 6;
4252               return ("set"            CR_TAB
4253                       AS2 (bld,r1,3)   CR_TAB
4254                       AS2 (mul,%B0,r1) CR_TAB
4255                       AS2 (mov,%A0,r1) CR_TAB
4256                       AS1 (clr,%B0)    CR_TAB
4257                       AS1 (clr,__zero_reg__));
4258             }
4259           *len = 7;
4260           return (AS2 (mov,%A0,%B0) CR_TAB
4261                   AS1 (clr,%B0)     CR_TAB
4262                   AS1 (lsr,%A0)     CR_TAB
4263                   AS1 (lsr,%A0)     CR_TAB
4264                   AS1 (lsr,%A0)     CR_TAB
4265                   AS1 (lsr,%A0)     CR_TAB
4266                   AS1 (lsr,%A0));
4267
4268         case 14:
4269           if (AVR_HAVE_MUL && ldi_ok)
4270             {
4271               *len = 5;
4272               return (AS2 (ldi,%A0,0x04) CR_TAB
4273                       AS2 (mul,%B0,%A0)  CR_TAB
4274                       AS2 (mov,%A0,r1)   CR_TAB
4275                       AS1 (clr,%B0)      CR_TAB
4276                       AS1 (clr,__zero_reg__));
4277             }
4278           if (AVR_HAVE_MUL && scratch)
4279             {
4280               *len = 5;
4281               return (AS2 (ldi,%3,0x04) CR_TAB
4282                       AS2 (mul,%B0,%3)  CR_TAB
4283                       AS2 (mov,%A0,r1)  CR_TAB
4284                       AS1 (clr,%B0)     CR_TAB
4285                       AS1 (clr,__zero_reg__));
4286             }
4287           if (optimize_size && ldi_ok)
4288             {
4289               *len = 5;
4290               return (AS2 (mov,%A0,%B0) CR_TAB
4291                       AS2 (ldi,%B0,6) "\n1:\t"
4292                       AS1 (lsr,%A0)     CR_TAB
4293                       AS1 (dec,%B0)     CR_TAB
4294                       AS1 (brne,1b));
4295             }
4296           if (optimize_size && scratch)
4297             break;  /* 5 */
4298           *len = 6;
4299           return (AS1 (clr,%A0) CR_TAB
4300                   AS1 (lsl,%B0) CR_TAB
4301                   AS1 (rol,%A0) CR_TAB
4302                   AS1 (lsl,%B0) CR_TAB
4303                   AS1 (rol,%A0) CR_TAB
4304                   AS1 (clr,%B0));
4305
4306         case 15:
4307           *len = 4;
4308           return (AS1 (clr,%A0) CR_TAB
4309                   AS1 (lsl,%B0) CR_TAB
4310                   AS1 (rol,%A0) CR_TAB
4311                   AS1 (clr,%B0));
4312         }
4313       len = t;
4314     }
4315   out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4316                        AS1 (ror,%A0)),
4317                        insn, operands, len, 2);
4318   return "";
4319 }
4320
4321 /* 32bit logic shift right ((unsigned int)x >> i) */
4322
4323 const char *
4324 lshrsi3_out (rtx insn, rtx operands[], int *len)
4325 {
4326   if (GET_CODE (operands[2]) == CONST_INT)
4327     {
4328       int k;
4329       int *t = len;
4330       
4331       if (!len)
4332         len = &k;
4333       
4334       switch (INTVAL (operands[2]))
4335         {
4336         default:
4337           if (INTVAL (operands[2]) < 32)
4338             break;
4339
4340           if (AVR_HAVE_MOVW)
4341             return *len = 3, (AS1 (clr,%D0) CR_TAB
4342                               AS1 (clr,%C0) CR_TAB
4343                               AS2 (movw,%A0,%C0));
4344           *len = 4;
4345           return (AS1 (clr,%D0) CR_TAB
4346                   AS1 (clr,%C0) CR_TAB
4347                   AS1 (clr,%B0) CR_TAB
4348                   AS1 (clr,%A0));
4349
4350         case 8:
4351           {
4352             int reg0 = true_regnum (operands[0]);
4353             int reg1 = true_regnum (operands[1]);
4354             *len = 4;
4355             if (reg0 <= reg1)
4356               return (AS2 (mov,%A0,%B1) CR_TAB
4357                       AS2 (mov,%B0,%C1) CR_TAB
4358                       AS2 (mov,%C0,%D1) CR_TAB
4359                       AS1 (clr,%D0));
4360             else
4361               return (AS1 (clr,%D0)     CR_TAB
4362                       AS2 (mov,%C0,%D1) CR_TAB
4363                       AS2 (mov,%B0,%C1) CR_TAB
4364                       AS2 (mov,%A0,%B1)); 
4365           }
4366           
4367         case 16:
4368           {
4369             int reg0 = true_regnum (operands[0]);
4370             int reg1 = true_regnum (operands[1]);
4371
4372             if (reg0 == reg1 + 2)
4373               return *len = 2, (AS1 (clr,%C0)     CR_TAB
4374                                 AS1 (clr,%D0));
4375             if (AVR_HAVE_MOVW)
4376               return *len = 3, (AS2 (movw,%A0,%C1) CR_TAB
4377                                 AS1 (clr,%C0)      CR_TAB
4378                                 AS1 (clr,%D0));
4379             else
4380               return *len = 4, (AS2 (mov,%B0,%D1) CR_TAB
4381                                 AS2 (mov,%A0,%C1) CR_TAB
4382                                 AS1 (clr,%C0)     CR_TAB
4383                                 AS1 (clr,%D0));
4384           }
4385           
4386         case 24:
4387           return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4388                             AS1 (clr,%B0)     CR_TAB
4389                             AS1 (clr,%C0)     CR_TAB
4390                             AS1 (clr,%D0));
4391
4392         case 31:
4393           *len = 6;
4394           return (AS1 (clr,%A0)    CR_TAB
4395                   AS2 (sbrc,%D0,7) CR_TAB
4396                   AS1 (inc,%A0)    CR_TAB
4397                   AS1 (clr,%B0)    CR_TAB
4398                   AS1 (clr,%C0)    CR_TAB
4399                   AS1 (clr,%D0));
4400         }
4401       len = t;
4402     }
4403   out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4404                        AS1 (ror,%C0) CR_TAB
4405                        AS1 (ror,%B0) CR_TAB
4406                        AS1 (ror,%A0)),
4407                       insn, operands, len, 4);
4408   return "";
4409 }
4410
4411 /* Create RTL split patterns for byte sized rotate expressions.  This
4412   produces a series of move instructions and considers overlap situations.
4413   Overlapping non-HImode operands need a scratch register.  */
4414
4415 bool
4416 avr_rotate_bytes (rtx operands[])
4417 {
4418     int i, j;
4419     enum machine_mode mode = GET_MODE (operands[0]);
4420     bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
4421     bool same_reg = rtx_equal_p (operands[0], operands[1]);
4422     int num = INTVAL (operands[2]);
4423     rtx scratch = operands[3];
4424     /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
4425        Word move if no scratch is needed, otherwise use size of scratch.  */
4426     enum machine_mode move_mode = QImode;
4427     int move_size, offset, size;
4428
4429     if (num & 0xf)
4430       move_mode = QImode;
4431     else if ((mode == SImode && !same_reg) || !overlapped)
4432       move_mode = HImode;
4433     else
4434       move_mode = GET_MODE (scratch);
4435
4436     /* Force DI rotate to use QI moves since other DI moves are currently split
4437        into QI moves so forward propagation works better.  */
4438     if (mode == DImode)
4439       move_mode = QImode;
4440     /* Make scratch smaller if needed.  */
4441     if (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       /* Immediate constants are as cheap as registers.  */
5345       *total = 0;
5346       return true;
5347
5348     case MEM:
5349     case CONST:
5350     case LABEL_REF:
5351     case SYMBOL_REF:
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             *total = COSTS_N_INSNS (!speed ? 7 : 10);
5477           else if (!speed)
5478             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5479           else
5480             return false;
5481           break;
5482
5483         default:
5484           return false;
5485         }
5486       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5487       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5488       return true;
5489
5490     case DIV:
5491     case MOD:
5492     case UDIV:
5493     case UMOD:
5494       if (!speed)
5495         *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5496       else
5497         return false;
5498       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5499       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5500       return true;
5501
5502     case ROTATE:
5503       switch (mode)
5504         {
5505         case QImode:
5506           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
5507             *total = COSTS_N_INSNS (1);
5508
5509           break;
5510
5511         case HImode:
5512           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
5513             *total = COSTS_N_INSNS (3);
5514
5515           break;
5516
5517         case SImode:
5518           if (CONST_INT_P (XEXP (x, 1)))
5519             switch (INTVAL (XEXP (x, 1)))
5520               {
5521               case 8:
5522               case 24:
5523                 *total = COSTS_N_INSNS (5);
5524                 break;
5525               case 16:
5526                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
5527                 break;
5528               }
5529           break;
5530
5531         default:
5532           return false;
5533         }
5534       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5535       return true;    
5536
5537     case ASHIFT:
5538       switch (mode)
5539         {
5540         case QImode:
5541           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5542             {
5543               *total = COSTS_N_INSNS (!speed ? 4 : 17);
5544               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5545             }
5546           else
5547             {
5548               val = INTVAL (XEXP (x, 1));
5549               if (val == 7)
5550                 *total = COSTS_N_INSNS (3);
5551               else if (val >= 0 && val <= 7)
5552                 *total = COSTS_N_INSNS (val);
5553               else
5554                 *total = COSTS_N_INSNS (1);
5555             }
5556           break;
5557
5558         case HImode:
5559           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5560             {
5561               *total = COSTS_N_INSNS (!speed ? 5 : 41);
5562               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5563             }
5564           else
5565             switch (INTVAL (XEXP (x, 1)))
5566               {
5567               case 0:
5568                 *total = 0;
5569                 break;
5570               case 1:
5571               case 8:
5572                 *total = COSTS_N_INSNS (2);
5573                 break;
5574               case 9:
5575                 *total = COSTS_N_INSNS (3);
5576                 break;
5577               case 2:
5578               case 3:
5579               case 10:
5580               case 15:
5581                 *total = COSTS_N_INSNS (4);
5582                 break;
5583               case 7:
5584               case 11:
5585               case 12:
5586                 *total = COSTS_N_INSNS (5);
5587                 break;
5588               case 4:
5589                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
5590                 break;
5591               case 6:
5592                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
5593                 break;
5594               case 5:
5595                 *total = COSTS_N_INSNS (!speed ? 5 : 10);
5596                 break;
5597               default:
5598                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5599                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5600               }
5601           break;
5602
5603         case SImode:
5604           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5605             {
5606               *total = COSTS_N_INSNS (!speed ? 7 : 113);
5607               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5608             }
5609           else
5610             switch (INTVAL (XEXP (x, 1)))
5611               {
5612               case 0:
5613                 *total = 0;
5614                 break;
5615               case 24:
5616                 *total = COSTS_N_INSNS (3);
5617                 break;
5618               case 1:
5619               case 8:
5620               case 16:
5621                 *total = COSTS_N_INSNS (4);
5622                 break;
5623               case 31:
5624                 *total = COSTS_N_INSNS (6);
5625                 break;
5626               case 2:
5627                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5628                 break;
5629               default:
5630                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5631                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5632               }
5633           break;
5634
5635         default:
5636           return false;
5637         }
5638       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5639       return true;
5640
5641     case ASHIFTRT:
5642       switch (mode)
5643         {
5644         case QImode:
5645           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5646             {
5647               *total = COSTS_N_INSNS (!speed ? 4 : 17);
5648               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5649             }
5650           else
5651             {
5652               val = INTVAL (XEXP (x, 1));
5653               if (val == 6)
5654                 *total = COSTS_N_INSNS (4);
5655               else if (val == 7)
5656                 *total = COSTS_N_INSNS (2);
5657               else if (val >= 0 && val <= 7)
5658                 *total = COSTS_N_INSNS (val);
5659               else
5660                 *total = COSTS_N_INSNS (1);
5661             }
5662           break;
5663
5664         case HImode:
5665           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5666             {
5667               *total = COSTS_N_INSNS (!speed ? 5 : 41);
5668               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5669             }
5670           else
5671             switch (INTVAL (XEXP (x, 1)))
5672               {
5673               case 0:
5674                 *total = 0;
5675                 break;
5676               case 1:
5677                 *total = COSTS_N_INSNS (2);
5678                 break;
5679               case 15:
5680                 *total = COSTS_N_INSNS (3);
5681                 break;
5682               case 2:
5683               case 7:
5684               case 8:
5685               case 9:
5686                 *total = COSTS_N_INSNS (4);
5687                 break;
5688               case 10:
5689               case 14:
5690                 *total = COSTS_N_INSNS (5);
5691                 break;
5692               case 11:
5693                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
5694                 break;
5695               case 12:
5696                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
5697                 break;
5698               case 6:
5699               case 13:
5700                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
5701                 break;
5702               default:
5703                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5704                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5705               }
5706           break;
5707
5708         case SImode:
5709           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5710             {
5711               *total = COSTS_N_INSNS (!speed ? 7 : 113);
5712               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5713             }
5714           else
5715             switch (INTVAL (XEXP (x, 1)))
5716               {
5717               case 0:
5718                 *total = 0;
5719                 break;
5720               case 1:
5721                 *total = COSTS_N_INSNS (4);
5722                 break;
5723               case 8:
5724               case 16:
5725               case 24:
5726                 *total = COSTS_N_INSNS (6);
5727                 break;
5728               case 2:
5729                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5730                 break;
5731               case 31:
5732                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
5733                 break;
5734               default:
5735                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5736                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5737               }
5738           break;
5739
5740         default:
5741           return false;
5742         }
5743       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5744       return true;
5745
5746     case LSHIFTRT:
5747       switch (mode)
5748         {
5749         case QImode:
5750           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5751             {
5752               *total = COSTS_N_INSNS (!speed ? 4 : 17);
5753               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5754             }
5755           else
5756             {
5757               val = INTVAL (XEXP (x, 1));
5758               if (val == 7)
5759                 *total = COSTS_N_INSNS (3);
5760               else if (val >= 0 && val <= 7)
5761                 *total = COSTS_N_INSNS (val);
5762               else
5763                 *total = COSTS_N_INSNS (1);
5764             }
5765           break;
5766
5767         case HImode:
5768           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5769             {
5770               *total = COSTS_N_INSNS (!speed ? 5 : 41);
5771               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5772             }
5773           else
5774             switch (INTVAL (XEXP (x, 1)))
5775               {
5776               case 0:
5777                 *total = 0;
5778                 break;
5779               case 1:
5780               case 8:
5781                 *total = COSTS_N_INSNS (2);
5782                 break;
5783               case 9:
5784                 *total = COSTS_N_INSNS (3);
5785                 break;
5786               case 2:
5787               case 10:
5788               case 15:
5789                 *total = COSTS_N_INSNS (4);
5790                 break;
5791               case 7:
5792               case 11:
5793                 *total = COSTS_N_INSNS (5);
5794                 break;
5795               case 3:
5796               case 12:
5797               case 13:
5798               case 14:
5799                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
5800                 break;
5801               case 4:
5802                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
5803                 break;
5804               case 5:
5805               case 6:
5806                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
5807                 break;
5808               default:
5809                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5810                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5811               }
5812           break;
5813
5814         case SImode:
5815           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5816             {
5817               *total = COSTS_N_INSNS (!speed ? 7 : 113);
5818               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5819             }
5820           else
5821             switch (INTVAL (XEXP (x, 1)))
5822               {
5823               case 0:
5824                 *total = 0;
5825                 break;
5826               case 1:
5827                 *total = COSTS_N_INSNS (4);
5828                 break;
5829               case 2:
5830                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5831                 break;
5832               case 8:
5833               case 16:
5834               case 24:
5835                 *total = COSTS_N_INSNS (4);
5836                 break;
5837               case 31:
5838                 *total = COSTS_N_INSNS (6);
5839                 break;
5840               default:
5841                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5842                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5843               }
5844           break;
5845
5846         default:
5847           return false;
5848         }
5849       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5850       return true;
5851
5852     case COMPARE:
5853       switch (GET_MODE (XEXP (x, 0)))
5854         {
5855         case QImode:
5856           *total = COSTS_N_INSNS (1);
5857           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5858             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5859           break;
5860
5861         case HImode:
5862           *total = COSTS_N_INSNS (2);
5863           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5864             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5865           else if (INTVAL (XEXP (x, 1)) != 0)
5866             *total += COSTS_N_INSNS (1);
5867           break;
5868
5869         case SImode:
5870           *total = COSTS_N_INSNS (4);
5871           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5872             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5873           else if (INTVAL (XEXP (x, 1)) != 0)
5874             *total += COSTS_N_INSNS (3);
5875           break;
5876
5877         default:
5878           return false;
5879         }
5880       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5881       return true;
5882
5883     default:
5884       break;
5885     }
5886   return false;
5887 }
5888
5889 /* Calculate the cost of a memory address.  */
5890
5891 static int
5892 avr_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
5893 {
5894   if (GET_CODE (x) == PLUS
5895       && GET_CODE (XEXP (x,1)) == CONST_INT
5896       && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
5897       && INTVAL (XEXP (x,1)) >= 61)
5898     return 18;
5899   if (CONSTANT_ADDRESS_P (x))
5900     {
5901       if (optimize > 0 && io_address_operand (x, QImode))
5902         return 2;
5903       return 4;
5904     }
5905   return 4;
5906 }
5907
5908 /* Test for extra memory constraint 'Q'.
5909    It's a memory address based on Y or Z pointer with valid displacement.  */
5910
5911 int
5912 extra_constraint_Q (rtx x)
5913 {
5914   if (GET_CODE (XEXP (x,0)) == PLUS
5915       && REG_P (XEXP (XEXP (x,0), 0))
5916       && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
5917       && (INTVAL (XEXP (XEXP (x,0), 1))
5918           <= MAX_LD_OFFSET (GET_MODE (x))))
5919     {
5920       rtx xx = XEXP (XEXP (x,0), 0);
5921       int regno = REGNO (xx);
5922       if (TARGET_ALL_DEBUG)
5923         {
5924           fprintf (stderr, ("extra_constraint:\n"
5925                             "reload_completed: %d\n"
5926                             "reload_in_progress: %d\n"),
5927                    reload_completed, reload_in_progress);
5928           debug_rtx (x);
5929         }
5930       if (regno >= FIRST_PSEUDO_REGISTER)
5931         return 1;               /* allocate pseudos */
5932       else if (regno == REG_Z || regno == REG_Y)
5933         return 1;               /* strictly check */
5934       else if (xx == frame_pointer_rtx
5935                || xx == arg_pointer_rtx)
5936         return 1;               /* XXX frame & arg pointer checks */
5937     }
5938   return 0;
5939 }
5940
5941 /* Convert condition code CONDITION to the valid AVR condition code.  */
5942
5943 RTX_CODE
5944 avr_normalize_condition (RTX_CODE condition)
5945 {
5946   switch (condition)
5947     {
5948     case GT:
5949       return GE;
5950     case GTU:
5951       return GEU;
5952     case LE:
5953       return LT;
5954     case LEU:
5955       return LTU;
5956     default:
5957       gcc_unreachable ();
5958     }
5959 }
5960
5961 /* This function optimizes conditional jumps.  */
5962
5963 static void
5964 avr_reorg (void)
5965 {
5966   rtx insn, pattern;
5967   
5968   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5969     {
5970       if (! (GET_CODE (insn) == INSN
5971              || GET_CODE (insn) == CALL_INSN
5972              || GET_CODE (insn) == JUMP_INSN)
5973           || !single_set (insn))
5974         continue;
5975
5976       pattern = PATTERN (insn);
5977
5978       if (GET_CODE (pattern) == PARALLEL)
5979         pattern = XVECEXP (pattern, 0, 0);
5980       if (GET_CODE (pattern) == SET
5981           && SET_DEST (pattern) == cc0_rtx
5982           && compare_diff_p (insn))
5983         {
5984           if (GET_CODE (SET_SRC (pattern)) == COMPARE)
5985             {
5986               /* Now we work under compare insn.  */
5987               
5988               pattern = SET_SRC (pattern);
5989               if (true_regnum (XEXP (pattern,0)) >= 0
5990                   && true_regnum (XEXP (pattern,1)) >= 0 )
5991                 {
5992                   rtx x = XEXP (pattern,0);
5993                   rtx next = next_real_insn (insn);
5994                   rtx pat = PATTERN (next);
5995                   rtx src = SET_SRC (pat);
5996                   rtx t = XEXP (src,0);
5997                   PUT_CODE (t, swap_condition (GET_CODE (t)));
5998                   XEXP (pattern,0) = XEXP (pattern,1);
5999                   XEXP (pattern,1) = x;
6000                   INSN_CODE (next) = -1;
6001                 }
6002               else if (true_regnum (XEXP (pattern, 0)) >= 0
6003                        && XEXP (pattern, 1) == const0_rtx)
6004                 {
6005                   /* This is a tst insn, we can reverse it.  */
6006                   rtx next = next_real_insn (insn);
6007                   rtx pat = PATTERN (next);
6008                   rtx src = SET_SRC (pat);
6009                   rtx t = XEXP (src,0);
6010     
6011                   PUT_CODE (t, swap_condition (GET_CODE (t)));
6012                   XEXP (pattern, 1) = XEXP (pattern, 0);
6013                   XEXP (pattern, 0) = const0_rtx;
6014                   INSN_CODE (next) = -1;
6015                   INSN_CODE (insn) = -1;
6016                 }
6017               else if (true_regnum (XEXP (pattern,0)) >= 0
6018                        && GET_CODE (XEXP (pattern,1)) == CONST_INT)
6019                 {
6020                   rtx x = XEXP (pattern,1);
6021                   rtx next = next_real_insn (insn);
6022                   rtx pat = PATTERN (next);
6023                   rtx src = SET_SRC (pat);
6024                   rtx t = XEXP (src,0);
6025                   enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
6026
6027                   if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
6028                     {
6029                       XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
6030                       PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
6031                       INSN_CODE (next) = -1;
6032                       INSN_CODE (insn) = -1;
6033                     }
6034                 }
6035             }
6036         }
6037     }
6038 }
6039
6040 /* Returns register number for function return value.*/
6041
6042 static inline unsigned int
6043 avr_ret_register (void)
6044 {
6045   return 24;
6046 }
6047
6048 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
6049
6050 static bool
6051 avr_function_value_regno_p (const unsigned int regno)
6052 {
6053   return (regno == avr_ret_register ());
6054 }
6055
6056 /* Create an RTX representing the place where a
6057    library function returns a value of mode MODE.  */
6058
6059 static rtx
6060 avr_libcall_value (enum machine_mode mode,
6061                    const_rtx func ATTRIBUTE_UNUSED)
6062 {
6063   int offs = GET_MODE_SIZE (mode);
6064   if (offs < 2)
6065     offs = 2;
6066   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
6067 }
6068
6069 /* Create an RTX representing the place where a
6070    function returns a value of data type VALTYPE.  */
6071
6072 static rtx
6073 avr_function_value (const_tree type,
6074                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6075                     bool outgoing ATTRIBUTE_UNUSED)
6076 {
6077   unsigned int offs;
6078
6079   if (TYPE_MODE (type) != BLKmode)
6080     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
6081   
6082   offs = int_size_in_bytes (type);
6083   if (offs < 2)
6084     offs = 2;
6085   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
6086     offs = GET_MODE_SIZE (SImode);
6087   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
6088     offs = GET_MODE_SIZE (DImode);
6089   
6090   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
6091 }
6092
6093 int
6094 test_hard_reg_class (enum reg_class rclass, rtx x)
6095 {
6096   int regno = true_regnum (x);
6097   if (regno < 0)
6098     return 0;
6099
6100   if (TEST_HARD_REG_CLASS (rclass, regno))
6101     return 1;
6102
6103   return 0;
6104 }
6105
6106
6107 int
6108 jump_over_one_insn_p (rtx insn, rtx dest)
6109 {
6110   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
6111                       ? XEXP (dest, 0)
6112                       : dest);
6113   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
6114   int dest_addr = INSN_ADDRESSES (uid);
6115   return dest_addr - jump_addr == get_attr_length (insn) + 1;
6116 }
6117
6118 /* Returns 1 if a value of mode MODE can be stored starting with hard
6119    register number REGNO.  On the enhanced core, anything larger than
6120    1 byte must start in even numbered register for "movw" to work
6121    (this way we don't have to check for odd registers everywhere).  */
6122
6123 int
6124 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
6125 {
6126   /* NOTE: 8-bit values must not be disallowed for R28 or R29.
6127         Disallowing QI et al. in these regs might lead to code like
6128             (set (subreg:QI (reg:HI 28) n) ...)
6129         which will result in wrong code because reload does not
6130         handle SUBREGs of hard regsisters like this.
6131         This could be fixed in reload.  However, it appears
6132         that fixing reload is not wanted by reload people.  */
6133   
6134   /* Any GENERAL_REGS register can hold 8-bit values.  */
6135   
6136   if (GET_MODE_SIZE (mode) == 1)
6137     return 1;
6138
6139   /* FIXME: Ideally, the following test is not needed.
6140         However, it turned out that it can reduce the number
6141         of spill fails.  AVR and it's poor endowment with
6142         address registers is extreme stress test for reload.  */
6143   
6144   if (GET_MODE_SIZE (mode) >= 4
6145       && regno >= REG_X)
6146     return 0;
6147
6148   /* All modes larger than 8 bits should start in an even register.  */
6149   
6150   return !(regno & 1);
6151 }
6152
6153 const char *
6154 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
6155 {
6156   int tmp;
6157   if (!len)
6158     len = &tmp;
6159       
6160   if (GET_CODE (operands[1]) == CONST_INT)
6161     {
6162       int val = INTVAL (operands[1]);
6163       if ((val & 0xff) == 0)
6164         {
6165           *len = 3;
6166           return (AS2 (mov,%A0,__zero_reg__) CR_TAB
6167                   AS2 (ldi,%2,hi8(%1))       CR_TAB
6168                   AS2 (mov,%B0,%2));
6169         }
6170       else if ((val & 0xff00) == 0)
6171         {
6172           *len = 3;
6173           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
6174                   AS2 (mov,%A0,%2)     CR_TAB
6175                   AS2 (mov,%B0,__zero_reg__));
6176         }
6177       else if ((val & 0xff) == ((val & 0xff00) >> 8))
6178         {
6179           *len = 3;
6180           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
6181                   AS2 (mov,%A0,%2)     CR_TAB
6182                   AS2 (mov,%B0,%2));
6183         }
6184     }
6185   *len = 4;
6186   return (AS2 (ldi,%2,lo8(%1)) CR_TAB
6187           AS2 (mov,%A0,%2)     CR_TAB
6188           AS2 (ldi,%2,hi8(%1)) CR_TAB
6189           AS2 (mov,%B0,%2));
6190 }
6191
6192
6193 /* Reload a SI or SF compile time constant (OP[1]) into a GPR (OP[0]).
6194    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
6195    into a NO_LD_REGS.  If CLOBBER_REG is NULL_RTX we either don't need a
6196    clobber reg or have to cook one up.
6197
6198    LEN == NULL: Output instructions.
6199    
6200    LEN != NULL: Output nothing.  Increment *LEN by number of words occupied
6201                 by the insns printed.
6202
6203    Return "".  */
6204
6205 const char *
6206 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED,
6207                       rtx *op, rtx clobber_reg, int *len)
6208 {
6209   rtx src = op[1];
6210   rtx dest = op[0];
6211   rtx xval, xdest[4];
6212   int ival[4];
6213   int clobber_val = 1234;
6214   bool cooked_clobber_p = false;
6215   bool set_p = false;
6216   unsigned int n;
6217   enum machine_mode mode = GET_MODE (dest);
6218   
6219   gcc_assert (REG_P (dest));
6220
6221   if (len)
6222     *len = 0;
6223   
6224   /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
6225      but has some subregs that are in LD_REGS.  Use the MSB (REG:QI 17).  */
6226   
6227   if (14 == REGNO (dest))
6228     {
6229       clobber_reg = gen_rtx_REG (QImode, 17);
6230     }
6231
6232   /* We might need a clobber reg but don't have one.  Look at the value
6233      to be loaded more closely.  A clobber is only needed if it contains
6234      a byte that is neither 0, -1 or a power of 2.  */
6235   
6236   if (NULL_RTX == clobber_reg
6237       && !test_hard_reg_class (LD_REGS, dest))
6238     {
6239       for (n = 0; n < GET_MODE_SIZE (mode); n++)
6240         {
6241           xval = simplify_gen_subreg (QImode, src, mode, n);
6242
6243           if (!(const0_rtx == xval
6244                 || constm1_rtx == xval
6245                 || single_one_operand (xval, QImode)))
6246             {
6247               /* We have no clobber reg but need one.  Cook one up.
6248                  That's cheaper than loading from constant pool.  */
6249               
6250               cooked_clobber_p = true;
6251               clobber_reg = gen_rtx_REG (QImode, REG_Z + 1);
6252               avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
6253               break;
6254             }
6255         }
6256     }
6257
6258   /* Now start filling DEST from LSB to MSB.  */
6259   
6260   for (n = 0; n < GET_MODE_SIZE (mode); n++)
6261     {
6262       bool done_byte = false;
6263       unsigned int j;
6264       rtx xop[3];
6265
6266       /* Crop the n-th sub-byte.  */
6267       
6268       xval = simplify_gen_subreg (QImode, src, mode, n);
6269       xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
6270       ival[n] = INTVAL (xval);
6271
6272       /* Look if we can reuse the low word by means of MOVW.  */
6273       
6274       if (n == 2
6275           && AVR_HAVE_MOVW)
6276         {
6277           rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
6278           rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
6279
6280           if (INTVAL (lo16) == INTVAL (hi16))
6281             {
6282               avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
6283               break;
6284             }
6285         }
6286
6287       /* Use CLR to zero a value so that cc0 is set as expected
6288          for zero.  */
6289       
6290       if (ival[n] == 0)
6291         {
6292           avr_asm_len ("clr %0", &xdest[n], len, 1);
6293           continue;
6294         }
6295
6296       if (clobber_val == ival[n]
6297           && REGNO (clobber_reg) == REGNO (xdest[n]))
6298         {
6299           continue;
6300         }
6301
6302       /* LD_REGS can use LDI to move a constant value */
6303       
6304       if (test_hard_reg_class (LD_REGS, xdest[n]))
6305         {
6306           xop[0] = xdest[n];
6307           xop[1] = xval;
6308           avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
6309           continue;
6310         }
6311
6312       /* Try to reuse value already loaded in some lower byte. */
6313       
6314       for (j = 0; j < n; j++)
6315         if (ival[j] == ival[n])
6316           {
6317             xop[0] = xdest[n];
6318             xop[1] = xdest[j];
6319             
6320             avr_asm_len ("mov %0,%1", xop, len, 1);
6321             done_byte = true;
6322             break;
6323           }
6324
6325       if (done_byte)
6326         continue;
6327
6328       /* Need no clobber reg for -1: Use CLR/DEC */
6329       
6330       if (-1 == ival[n])
6331         {
6332           avr_asm_len ("clr %0" CR_TAB
6333                        "dec %0", &xdest[n], len, 2);
6334           continue;
6335         }
6336
6337       /* Use T flag or INC to manage powers of 2 if we have
6338          no clobber reg.  */
6339
6340       if (NULL_RTX == clobber_reg
6341           && single_one_operand (xval, QImode))
6342         {
6343           if (1 == ival[n])
6344             {
6345               avr_asm_len ("clr %0" CR_TAB
6346                            "inc %0", &xdest[n], len, 2);
6347               continue;
6348             }
6349           
6350           xop[0] = xdest[n];
6351           xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
6352
6353           gcc_assert (constm1_rtx != xop[1]);
6354
6355           if (!set_p)
6356             {
6357               set_p = true;
6358               avr_asm_len ("set", xop, len, 1);
6359             }
6360
6361           avr_asm_len ("clr %0" CR_TAB
6362                        "bld %0,%1", xop, len, 2);
6363           continue;
6364         }
6365
6366       /* We actually need the LD_REGS clobber reg.  */
6367
6368       gcc_assert (NULL_RTX != clobber_reg);
6369         
6370       xop[0] = xdest[n];
6371       xop[1] = xval;
6372       xop[2] = clobber_reg;
6373       clobber_val = ival[n];
6374         
6375       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
6376                    "mov %0,%2", xop, len, 2);
6377     }
6378   
6379   /* If we cooked up a clobber reg above, restore it.  */
6380   
6381   if (cooked_clobber_p)
6382     {
6383       avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
6384     }
6385   
6386   return "";
6387 }
6388
6389 void
6390 avr_output_bld (rtx operands[], int bit_nr)
6391 {
6392   static char s[] = "bld %A0,0";
6393
6394   s[5] = 'A' + (bit_nr >> 3);
6395   s[8] = '0' + (bit_nr & 7);
6396   output_asm_insn (s, operands);
6397 }
6398
6399 void
6400 avr_output_addr_vec_elt (FILE *stream, int value)
6401 {
6402   switch_to_section (progmem_section);
6403   if (AVR_HAVE_JMP_CALL)
6404     fprintf (stream, "\t.word gs(.L%d)\n", value);
6405   else
6406     fprintf (stream, "\trjmp .L%d\n", value);
6407 }
6408
6409 /* Returns true if SCRATCH are safe to be allocated as a scratch
6410    registers (for a define_peephole2) in the current function.  */
6411
6412 bool
6413 avr_hard_regno_scratch_ok (unsigned int regno)
6414 {
6415   /* Interrupt functions can only use registers that have already been saved
6416      by the prologue, even if they would normally be call-clobbered.  */
6417
6418   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
6419       && !df_regs_ever_live_p (regno))
6420     return false;
6421
6422   /* Don't allow hard registers that might be part of the frame pointer.
6423      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
6424      and don't care for a frame pointer that spans more than one register.  */
6425
6426   if ((!reload_completed || frame_pointer_needed)
6427       && (regno == REG_Y || regno == REG_Y + 1))
6428     {
6429       return false;
6430     }
6431
6432   return true;
6433 }
6434
6435 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
6436
6437 int
6438 avr_hard_regno_rename_ok (unsigned int old_reg,
6439                           unsigned int new_reg)
6440 {
6441   /* Interrupt functions can only use registers that have already been
6442      saved by the prologue, even if they would normally be
6443      call-clobbered.  */
6444
6445   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
6446       && !df_regs_ever_live_p (new_reg))
6447     return 0;
6448
6449   /* Don't allow hard registers that might be part of the frame pointer.
6450      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
6451      and don't care for a frame pointer that spans more than one register.  */
6452
6453   if ((!reload_completed || frame_pointer_needed)
6454       && (old_reg == REG_Y || old_reg == REG_Y + 1
6455           || new_reg == REG_Y || new_reg == REG_Y + 1))
6456     {
6457       return 0;
6458     }
6459   
6460   return 1;
6461 }
6462
6463 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
6464    or memory location in the I/O space (QImode only).
6465
6466    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
6467    Operand 1: register operand to test, or CONST_INT memory address.
6468    Operand 2: bit number.
6469    Operand 3: label to jump to if the test is true.  */
6470
6471 const char *
6472 avr_out_sbxx_branch (rtx insn, rtx operands[])
6473 {
6474   enum rtx_code comp = GET_CODE (operands[0]);
6475   int long_jump = (get_attr_length (insn) >= 4);
6476   int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
6477
6478   if (comp == GE)
6479     comp = EQ;
6480   else if (comp == LT)
6481     comp = NE;
6482
6483   if (reverse)
6484     comp = reverse_condition (comp);
6485
6486   if (GET_CODE (operands[1]) == CONST_INT)
6487     {
6488       if (INTVAL (operands[1]) < 0x40)
6489         {
6490           if (comp == EQ)
6491             output_asm_insn (AS2 (sbis,%m1-0x20,%2), operands);
6492           else
6493             output_asm_insn (AS2 (sbic,%m1-0x20,%2), operands);
6494         }
6495       else
6496         {
6497           output_asm_insn (AS2 (in,__tmp_reg__,%m1-0x20), operands);
6498           if (comp == EQ)
6499             output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
6500           else
6501             output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
6502         }
6503     }
6504   else  /* GET_CODE (operands[1]) == REG */
6505     {
6506       if (GET_MODE (operands[1]) == QImode)
6507         {
6508           if (comp == EQ)
6509             output_asm_insn (AS2 (sbrs,%1,%2), operands);
6510           else
6511             output_asm_insn (AS2 (sbrc,%1,%2), operands);
6512         }
6513       else  /* HImode or SImode */
6514         {
6515           static char buf[] = "sbrc %A1,0";
6516           int bit_nr = INTVAL (operands[2]);
6517           buf[3] = (comp == EQ) ? 's' : 'c';
6518           buf[6] = 'A' + (bit_nr >> 3);
6519           buf[9] = '0' + (bit_nr & 7);
6520           output_asm_insn (buf, operands);
6521         }
6522     }
6523
6524   if (long_jump)
6525     return (AS1 (rjmp,.+4) CR_TAB
6526             AS1 (jmp,%x3));
6527   if (!reverse)
6528     return AS1 (rjmp,%x3);
6529   return "";
6530 }
6531
6532 /* Worker function for TARGET_ASM_CONSTRUCTOR.  */
6533
6534 static void
6535 avr_asm_out_ctor (rtx symbol, int priority)
6536 {
6537   fputs ("\t.global __do_global_ctors\n", asm_out_file);
6538   default_ctor_section_asm_out_constructor (symbol, priority);
6539 }
6540
6541 /* Worker function for TARGET_ASM_DESTRUCTOR.  */
6542
6543 static void
6544 avr_asm_out_dtor (rtx symbol, int priority)
6545 {
6546   fputs ("\t.global __do_global_dtors\n", asm_out_file);
6547   default_dtor_section_asm_out_destructor (symbol, priority);
6548 }
6549
6550 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
6551
6552 static bool
6553 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6554 {
6555   if (TYPE_MODE (type) == BLKmode)
6556     {
6557       HOST_WIDE_INT size = int_size_in_bytes (type);
6558       return (size == -1 || size > 8);
6559     }
6560   else
6561     return false;
6562 }
6563
6564 /* Worker function for CASE_VALUES_THRESHOLD.  */
6565
6566 unsigned int avr_case_values_threshold (void)
6567 {
6568   return (!AVR_HAVE_JMP_CALL || TARGET_CALL_PROLOGUES) ? 8 : 17;
6569 }
6570
6571 /* Helper for __builtin_avr_delay_cycles */
6572
6573 static void
6574 avr_expand_delay_cycles (rtx operands0)
6575 {
6576   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0);
6577   unsigned HOST_WIDE_INT cycles_used;
6578   unsigned HOST_WIDE_INT loop_count;
6579   
6580   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
6581     {
6582       loop_count = ((cycles - 9) / 6) + 1;
6583       cycles_used = ((loop_count - 1) * 6) + 9;
6584       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode)));
6585       cycles -= cycles_used;
6586     }
6587   
6588   if (IN_RANGE (cycles, 262145, 83886081))
6589     {
6590       loop_count = ((cycles - 7) / 5) + 1;
6591       if (loop_count > 0xFFFFFF)
6592         loop_count = 0xFFFFFF;
6593       cycles_used = ((loop_count - 1) * 5) + 7;
6594       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode)));
6595       cycles -= cycles_used;
6596     }
6597   
6598   if (IN_RANGE (cycles, 768, 262144))
6599     {
6600       loop_count = ((cycles - 5) / 4) + 1;
6601       if (loop_count > 0xFFFF)
6602         loop_count = 0xFFFF;
6603       cycles_used = ((loop_count - 1) * 4) + 5;
6604       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode)));
6605       cycles -= cycles_used;
6606     }
6607   
6608   if (IN_RANGE (cycles, 6, 767))
6609     {
6610       loop_count = cycles / 3;
6611       if (loop_count > 255) 
6612         loop_count = 255;
6613       cycles_used = loop_count * 3;
6614       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode)));
6615       cycles -= cycles_used;
6616       }
6617   
6618   while (cycles >= 2)
6619     {
6620       emit_insn (gen_nopv (GEN_INT(2)));
6621       cycles -= 2;
6622     }
6623
6624   if (cycles == 1)
6625     {
6626       emit_insn (gen_nopv (GEN_INT(1)));
6627       cycles--;
6628     }
6629 }
6630
6631 /* IDs for all the AVR builtins.  */
6632
6633 enum avr_builtin_id
6634   {
6635     AVR_BUILTIN_NOP,
6636     AVR_BUILTIN_SEI,
6637     AVR_BUILTIN_CLI,
6638     AVR_BUILTIN_WDR,
6639     AVR_BUILTIN_SLEEP,
6640     AVR_BUILTIN_SWAP,
6641     AVR_BUILTIN_FMUL,
6642     AVR_BUILTIN_FMULS,
6643     AVR_BUILTIN_FMULSU,
6644     AVR_BUILTIN_DELAY_CYCLES
6645   };
6646
6647 #define DEF_BUILTIN(NAME, TYPE, CODE)                                   \
6648   do                                                                    \
6649     {                                                                   \
6650       add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,        \
6651                             NULL, NULL_TREE);                           \
6652     } while (0)
6653
6654
6655 /* Implement `TARGET_INIT_BUILTINS' */
6656 /* Set up all builtin functions for this target.  */
6657
6658 static void
6659 avr_init_builtins (void)
6660 {
6661   tree void_ftype_void
6662     = build_function_type_list (void_type_node, NULL_TREE);
6663   tree uchar_ftype_uchar
6664     = build_function_type_list (unsigned_char_type_node, 
6665                                 unsigned_char_type_node,
6666                                 NULL_TREE);
6667   tree uint_ftype_uchar_uchar
6668     = build_function_type_list (unsigned_type_node, 
6669                                 unsigned_char_type_node,
6670                                 unsigned_char_type_node, 
6671                                 NULL_TREE);
6672   tree int_ftype_char_char
6673     = build_function_type_list (integer_type_node, 
6674                                 char_type_node,
6675                                 char_type_node, 
6676                                 NULL_TREE);
6677   tree int_ftype_char_uchar
6678     = build_function_type_list (integer_type_node, 
6679                                 char_type_node,
6680                                 unsigned_char_type_node, 
6681                                 NULL_TREE);
6682   tree void_ftype_ulong
6683     = build_function_type_list (void_type_node, 
6684                                 long_unsigned_type_node,
6685                                 NULL_TREE);
6686
6687   DEF_BUILTIN ("__builtin_avr_nop", void_ftype_void, AVR_BUILTIN_NOP);
6688   DEF_BUILTIN ("__builtin_avr_sei", void_ftype_void, AVR_BUILTIN_SEI);
6689   DEF_BUILTIN ("__builtin_avr_cli", void_ftype_void, AVR_BUILTIN_CLI);
6690   DEF_BUILTIN ("__builtin_avr_wdr", void_ftype_void, AVR_BUILTIN_WDR);
6691   DEF_BUILTIN ("__builtin_avr_sleep", void_ftype_void, AVR_BUILTIN_SLEEP);
6692   DEF_BUILTIN ("__builtin_avr_swap", uchar_ftype_uchar, AVR_BUILTIN_SWAP);
6693   DEF_BUILTIN ("__builtin_avr_delay_cycles", void_ftype_ulong, 
6694                AVR_BUILTIN_DELAY_CYCLES);
6695
6696   DEF_BUILTIN ("__builtin_avr_fmul", uint_ftype_uchar_uchar, 
6697                AVR_BUILTIN_FMUL);
6698   DEF_BUILTIN ("__builtin_avr_fmuls", int_ftype_char_char, 
6699                AVR_BUILTIN_FMULS);
6700   DEF_BUILTIN ("__builtin_avr_fmulsu", int_ftype_char_uchar, 
6701                AVR_BUILTIN_FMULSU);
6702 }
6703
6704 #undef DEF_BUILTIN
6705
6706 struct avr_builtin_description
6707 {
6708   const enum insn_code icode;
6709   const char *const name;
6710   const enum avr_builtin_id id;
6711 };
6712
6713 static const struct avr_builtin_description
6714 bdesc_1arg[] =
6715   {
6716     { CODE_FOR_rotlqi3_4, "__builtin_avr_swap", AVR_BUILTIN_SWAP }
6717   };
6718
6719 static const struct avr_builtin_description
6720 bdesc_2arg[] =
6721   {
6722     { CODE_FOR_fmul, "__builtin_avr_fmul", AVR_BUILTIN_FMUL },
6723     { CODE_FOR_fmuls, "__builtin_avr_fmuls", AVR_BUILTIN_FMULS },
6724     { CODE_FOR_fmulsu, "__builtin_avr_fmulsu", AVR_BUILTIN_FMULSU }
6725   };
6726
6727 /* Subroutine of avr_expand_builtin to take care of unop insns.  */
6728
6729 static rtx
6730 avr_expand_unop_builtin (enum insn_code icode, tree exp,
6731                          rtx target)
6732 {
6733   rtx pat;
6734   tree arg0 = CALL_EXPR_ARG (exp, 0);
6735   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6736   enum machine_mode op0mode = GET_MODE (op0);
6737   enum machine_mode tmode = insn_data[icode].operand[0].mode;
6738   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6739
6740   if (! target
6741       || GET_MODE (target) != tmode
6742       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6743     {
6744       target = gen_reg_rtx (tmode);
6745     }
6746
6747   if (op0mode == SImode && mode0 == HImode)
6748     {
6749       op0mode = HImode;
6750       op0 = gen_lowpart (HImode, op0);
6751     }
6752   
6753   gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
6754
6755   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6756     op0 = copy_to_mode_reg (mode0, op0);
6757
6758   pat = GEN_FCN (icode) (target, op0);
6759   if (! pat)
6760     return 0;
6761   
6762   emit_insn (pat);
6763   
6764   return target;
6765 }
6766
6767
6768 /* Subroutine of avr_expand_builtin to take care of binop insns.  */
6769
6770 static rtx
6771 avr_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
6772 {
6773   rtx pat;
6774   tree arg0 = CALL_EXPR_ARG (exp, 0);
6775   tree arg1 = CALL_EXPR_ARG (exp, 1);
6776   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6777   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6778   enum machine_mode op0mode = GET_MODE (op0);
6779   enum machine_mode op1mode = GET_MODE (op1);
6780   enum machine_mode tmode = insn_data[icode].operand[0].mode;
6781   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6782   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6783
6784   if (! target
6785       || GET_MODE (target) != tmode
6786       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6787     {
6788       target = gen_reg_rtx (tmode);
6789     }
6790
6791   if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
6792     {
6793       op0mode = HImode;
6794       op0 = gen_lowpart (HImode, op0);
6795     }
6796   
6797   if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
6798     {
6799       op1mode = HImode;
6800       op1 = gen_lowpart (HImode, op1);
6801     }
6802   
6803   /* In case the insn wants input operands in modes different from
6804      the result, abort.  */
6805   
6806   gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
6807               && (op1mode == mode1 || op1mode == VOIDmode));
6808
6809   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6810     op0 = copy_to_mode_reg (mode0, op0);
6811   
6812   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6813     op1 = copy_to_mode_reg (mode1, op1);
6814
6815   pat = GEN_FCN (icode) (target, op0, op1);
6816   
6817   if (! pat)
6818     return 0;
6819
6820   emit_insn (pat);
6821   return target;
6822 }
6823
6824
6825 /* Expand an expression EXP that calls a built-in function,
6826    with result going to TARGET if that's convenient
6827    (and in mode MODE if that's convenient).
6828    SUBTARGET may be used as the target for computing one of EXP's operands.
6829    IGNORE is nonzero if the value is to be ignored.  */
6830
6831 static rtx
6832 avr_expand_builtin (tree exp, rtx target,
6833                     rtx subtarget ATTRIBUTE_UNUSED,
6834                     enum machine_mode mode ATTRIBUTE_UNUSED,
6835                     int ignore ATTRIBUTE_UNUSED)
6836 {
6837   size_t i;
6838   const struct avr_builtin_description *d;
6839   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6840   unsigned int id = DECL_FUNCTION_CODE (fndecl);
6841   tree arg0;
6842   rtx op0;
6843
6844   switch (id)
6845     {
6846     case AVR_BUILTIN_NOP:
6847       emit_insn (gen_nopv (GEN_INT(1)));
6848       return 0;
6849       
6850     case AVR_BUILTIN_SEI:
6851       emit_insn (gen_enable_interrupt ());
6852       return 0;
6853       
6854     case AVR_BUILTIN_CLI:
6855       emit_insn (gen_disable_interrupt ());
6856       return 0;
6857       
6858     case AVR_BUILTIN_WDR:
6859       emit_insn (gen_wdr ());
6860       return 0;
6861       
6862     case AVR_BUILTIN_SLEEP:
6863       emit_insn (gen_sleep ());
6864       return 0;
6865       
6866     case AVR_BUILTIN_DELAY_CYCLES:
6867       {
6868         arg0 = CALL_EXPR_ARG (exp, 0);
6869         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6870
6871         if (! CONST_INT_P (op0))
6872           error ("__builtin_avr_delay_cycles expects a compile time integer constant.");
6873
6874         avr_expand_delay_cycles (op0);
6875         return 0;
6876       }
6877     }
6878
6879   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
6880     if (d->id == id)
6881       return avr_expand_unop_builtin (d->icode, exp, target);
6882
6883   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
6884     if (d->id == id)
6885       return avr_expand_binop_builtin (d->icode, exp, target);
6886
6887   gcc_unreachable ();
6888 }
6889
6890
6891 #include "gt-avr.h"