OSDN Git Service

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