OSDN Git Service

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