OSDN Git Service

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