OSDN Git Service

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