OSDN Git Service

* common.opt (flag_stack_usage_info): New variable.
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
3    2009, 2010, 2011 Free Software Foundation, Inc.
4    Contributed by Denis Chertykov (chertykov@gmail.com)
5
6    This file is part of GCC.
7
8    GCC is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3, or (at your option)
11    any later version.
12    
13    GCC is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-attr.h"
32 #include "insn-codes.h"
33 #include "flags.h"
34 #include "reload.h"
35 #include "tree.h"
36 #include "output.h"
37 #include "expr.h"
38 #include "diagnostic-core.h"
39 #include "obstack.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "optabs.h"
43 #include "ggc.h"
44 #include "langhooks.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "target-def.h"
48 #include "params.h"
49 #include "df.h"
50
51 /* Maximal allowed offset for an address in the LD command */
52 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
53
54 static void avr_option_override (void);
55 static int avr_naked_function_p (tree);
56 static int interrupt_function_p (tree);
57 static int signal_function_p (tree);
58 static int avr_OS_task_function_p (tree);
59 static int avr_OS_main_function_p (tree);
60 static int avr_regs_to_save (HARD_REG_SET *);
61 static int get_sequence_length (rtx insns);
62 static int sequent_regs_live (void);
63 static const char *ptrreg_to_str (int);
64 static const char *cond_string (enum rtx_code);
65 static int avr_num_arg_regs (enum machine_mode, const_tree);
66
67 static RTX_CODE compare_condition (rtx insn);
68 static rtx avr_legitimize_address (rtx, rtx, enum machine_mode);
69 static int compare_sign_p (rtx insn);
70 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
71 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
72 static tree avr_handle_fntype_attribute (tree *, tree, tree, int, bool *);
73 static bool avr_assemble_integer (rtx, unsigned int, int);
74 static void avr_file_start (void);
75 static void avr_file_end (void);
76 static bool avr_legitimate_address_p (enum machine_mode, rtx, bool);
77 static void avr_asm_function_end_prologue (FILE *);
78 static void avr_asm_function_begin_epilogue (FILE *);
79 static bool avr_cannot_modify_jumps_p (void);
80 static rtx avr_function_value (const_tree, const_tree, bool);
81 static rtx avr_libcall_value (enum machine_mode, const_rtx);
82 static bool avr_function_value_regno_p (const unsigned int);
83 static void avr_insert_attributes (tree, tree *);
84 static void avr_asm_init_sections (void);
85 static unsigned int avr_section_type_flags (tree, const char *, int);
86
87 static void avr_reorg (void);
88 static void avr_asm_out_ctor (rtx, int);
89 static void avr_asm_out_dtor (rtx, int);
90 static int avr_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
91 static int avr_memory_move_cost (enum machine_mode, reg_class_t, bool);
92 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code, bool);
93 static bool avr_rtx_costs (rtx, int, int, int *, bool);
94 static int avr_address_cost (rtx, bool);
95 static bool avr_return_in_memory (const_tree, const_tree);
96 static struct machine_function * avr_init_machine_status (void);
97 static void avr_init_builtins (void);
98 static rtx avr_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
99 static rtx avr_builtin_setjmp_frame_value (void);
100 static bool avr_hard_regno_scratch_ok (unsigned int);
101 static unsigned int avr_case_values_threshold (void);
102 static bool avr_frame_pointer_required_p (void);
103 static bool avr_can_eliminate (const int, const int);
104 static bool avr_class_likely_spilled_p (reg_class_t c);
105 static rtx avr_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
106                              const_tree, bool);
107 static void avr_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
108                                       const_tree, bool);
109 static void avr_help (void);
110 static bool avr_function_ok_for_sibcall (tree, tree);
111 static void avr_asm_named_section (const char *name, unsigned int flags, tree decl);
112
113 /* Allocate registers from r25 to r8 for parameters for function calls.  */
114 #define FIRST_CUM_REG 26
115
116 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
117 static GTY(()) rtx tmp_reg_rtx;
118
119 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
120 static GTY(()) rtx zero_reg_rtx;
121
122 /* AVR register names {"r0", "r1", ..., "r31"} */
123 static const char *const avr_regnames[] = REGISTER_NAMES;
124
125 /* Preprocessor macros to define depending on MCU type.  */
126 const char *avr_extra_arch_macro;
127
128 /* Current architecture.  */
129 const struct base_arch_s *avr_current_arch;
130
131 /* Current device.  */
132 const struct mcu_type_s *avr_current_device;
133
134 section *progmem_section;
135
136 /* To track if code will use .bss and/or .data.  */
137 bool avr_need_clear_bss_p = false;
138 bool avr_need_copy_data_p = false;
139
140 /* AVR attributes.  */
141 static const struct attribute_spec avr_attribute_table[] =
142 {
143   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
144        affects_type_identity } */
145   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute,
146     false },
147   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute,
148     false },
149   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
150     false },
151   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
152     false },
153   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
154     false },
155   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
156     false },
157   { NULL,        0, 0, false, false, false, NULL, false }
158 };
159
160 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
161 static const struct default_options avr_option_optimization_table[] =
162   {
163     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
164     { OPT_LEVELS_NONE, 0, NULL, 0 }
165   };
166 \f
167 /* Initialize the GCC target structure.  */
168 #undef TARGET_ASM_ALIGNED_HI_OP
169 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
170 #undef TARGET_ASM_ALIGNED_SI_OP
171 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
172 #undef TARGET_ASM_UNALIGNED_HI_OP
173 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
174 #undef TARGET_ASM_UNALIGNED_SI_OP
175 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
176 #undef TARGET_ASM_INTEGER
177 #define TARGET_ASM_INTEGER avr_assemble_integer
178 #undef TARGET_ASM_FILE_START
179 #define TARGET_ASM_FILE_START avr_file_start
180 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
181 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
182 #undef TARGET_ASM_FILE_END
183 #define TARGET_ASM_FILE_END avr_file_end
184
185 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
186 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
187 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
188 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
189
190 #undef TARGET_FUNCTION_VALUE
191 #define TARGET_FUNCTION_VALUE avr_function_value
192 #undef TARGET_LIBCALL_VALUE
193 #define TARGET_LIBCALL_VALUE avr_libcall_value
194 #undef TARGET_FUNCTION_VALUE_REGNO_P
195 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
196
197 #undef TARGET_ATTRIBUTE_TABLE
198 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
199 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
200 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
201 #undef TARGET_INSERT_ATTRIBUTES
202 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
203 #undef TARGET_SECTION_TYPE_FLAGS
204 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
205
206 /* `TARGET_ASM_NAMED_SECTION' must be defined in avr.h.  */
207
208 #undef TARGET_ASM_INIT_SECTIONS
209 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
210
211 #undef TARGET_REGISTER_MOVE_COST
212 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
213 #undef TARGET_MEMORY_MOVE_COST
214 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
215 #undef TARGET_RTX_COSTS
216 #define TARGET_RTX_COSTS avr_rtx_costs
217 #undef TARGET_ADDRESS_COST
218 #define TARGET_ADDRESS_COST avr_address_cost
219 #undef TARGET_MACHINE_DEPENDENT_REORG
220 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
221 #undef TARGET_FUNCTION_ARG
222 #define TARGET_FUNCTION_ARG avr_function_arg
223 #undef TARGET_FUNCTION_ARG_ADVANCE
224 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
225
226 #undef TARGET_LEGITIMIZE_ADDRESS
227 #define TARGET_LEGITIMIZE_ADDRESS avr_legitimize_address
228
229 #undef TARGET_RETURN_IN_MEMORY
230 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
231
232 #undef TARGET_STRICT_ARGUMENT_NAMING
233 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
234
235 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
236 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
237
238 #undef TARGET_HARD_REGNO_SCRATCH_OK
239 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
240 #undef TARGET_CASE_VALUES_THRESHOLD
241 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
242
243 #undef TARGET_LEGITIMATE_ADDRESS_P
244 #define TARGET_LEGITIMATE_ADDRESS_P avr_legitimate_address_p
245
246 #undef TARGET_FRAME_POINTER_REQUIRED
247 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
248 #undef TARGET_CAN_ELIMINATE
249 #define TARGET_CAN_ELIMINATE avr_can_eliminate
250
251 #undef TARGET_CLASS_LIKELY_SPILLED_P
252 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
253
254 #undef TARGET_OPTION_OVERRIDE
255 #define TARGET_OPTION_OVERRIDE avr_option_override
256
257 #undef TARGET_OPTION_OPTIMIZATION_TABLE
258 #define TARGET_OPTION_OPTIMIZATION_TABLE avr_option_optimization_table
259
260 #undef TARGET_CANNOT_MODIFY_JUMPS_P
261 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
262
263 #undef TARGET_HELP
264 #define TARGET_HELP avr_help
265
266 #undef TARGET_EXCEPT_UNWIND_INFO
267 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
268
269 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
270 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
271
272 #undef TARGET_INIT_BUILTINS
273 #define TARGET_INIT_BUILTINS avr_init_builtins
274
275 #undef TARGET_EXPAND_BUILTIN
276 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
277
278
279 struct gcc_target targetm = TARGET_INITIALIZER;
280 \f
281 static void
282 avr_option_override (void)
283 {
284   const struct mcu_type_s *t;
285
286   flag_delete_null_pointer_checks = 0;
287
288   for (t = avr_mcu_types; t->name; t++)
289     if (strcmp (t->name, avr_mcu_name) == 0)
290       break;
291
292   if (!t->name)
293     {
294       error ("unrecognized argument to -mmcu= option: %qs", avr_mcu_name);
295       inform (input_location,  "See --target-help for supported MCUs");
296     }
297
298   avr_current_device = t;
299   avr_current_arch = &avr_arch_types[avr_current_device->arch];
300   avr_extra_arch_macro = avr_current_device->macro;
301
302   tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
303   zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
304
305   init_machine_status = avr_init_machine_status;
306 }
307
308 /* Implement TARGET_HELP */
309 /* Report extra information for --target-help */
310
311 static void
312 avr_help (void)
313 {
314   const struct mcu_type_s *t;
315   const char * const indent = "  ";
316   int len;
317
318   /* Give a list of MCUs that are accepted by -mmcu=* .
319      Note that MCUs supported by the compiler might differ from
320      MCUs supported by binutils. */
321
322   len = strlen (indent);
323   printf ("Known MCU names:\n%s", indent);
324
325   /* Print a blank-separated list of all supported MCUs */
326
327   for (t = avr_mcu_types; t->name; t++)
328     {
329       printf ("%s ", t->name);
330       len += 1 + strlen (t->name);
331
332       /* Break long lines */
333       
334       if (len > 66 && (t+1)->name)
335         {
336           printf ("\n%s", indent);
337           len = strlen (indent);
338         }
339     }
340
341   printf ("\n\n");
342 }
343
344 /*  return register class from register number.  */
345
346 static const enum reg_class reg_class_tab[]={
347   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
348   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
349   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
350   GENERAL_REGS, /* r0 - r15 */
351   LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
352   LD_REGS,                      /* r16 - 23 */
353   ADDW_REGS,ADDW_REGS,          /* r24,r25 */
354   POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
355   POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
356   POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
357   STACK_REG,STACK_REG           /* SPL,SPH */
358 };
359
360 /* Function to set up the backend function structure.  */
361
362 static struct machine_function *
363 avr_init_machine_status (void)
364 {
365   return ggc_alloc_cleared_machine_function ();
366 }
367
368 /* Return register class for register R.  */
369
370 enum reg_class
371 avr_regno_reg_class (int r)
372 {
373   if (r <= 33)
374     return reg_class_tab[r];
375   return ALL_REGS;
376 }
377
378 /* A helper for the subsequent function attribute used to dig for
379    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
380
381 static inline int
382 avr_lookup_function_attribute1 (const_tree func, const char *name)
383 {
384   if (FUNCTION_DECL == TREE_CODE (func))
385     {
386       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
387         {
388           return true;
389         }
390       
391       func = TREE_TYPE (func);
392     }
393
394   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
395               || TREE_CODE (func) == METHOD_TYPE);
396   
397   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
398 }
399
400 /* Return nonzero if FUNC is a naked function.  */
401
402 static int
403 avr_naked_function_p (tree func)
404 {
405   return avr_lookup_function_attribute1 (func, "naked");
406 }
407
408 /* Return nonzero if FUNC is an interrupt function as specified
409    by the "interrupt" attribute.  */
410
411 static int
412 interrupt_function_p (tree func)
413 {
414   return avr_lookup_function_attribute1 (func, "interrupt");
415 }
416
417 /* Return nonzero if FUNC is a signal function as specified
418    by the "signal" attribute.  */
419
420 static int
421 signal_function_p (tree func)
422 {
423   return avr_lookup_function_attribute1 (func, "signal");
424 }
425
426 /* Return nonzero if FUNC is a OS_task function.  */
427
428 static int
429 avr_OS_task_function_p (tree func)
430 {
431   return avr_lookup_function_attribute1 (func, "OS_task");
432 }
433
434 /* Return nonzero if FUNC is a OS_main function.  */
435
436 static int
437 avr_OS_main_function_p (tree func)
438 {
439   return avr_lookup_function_attribute1 (func, "OS_main");
440 }
441
442 /* Return the number of hard registers to push/pop in the prologue/epilogue
443    of the current function, and optionally store these registers in SET.  */
444
445 static int
446 avr_regs_to_save (HARD_REG_SET *set)
447 {
448   int reg, count;
449   int int_or_sig_p = (interrupt_function_p (current_function_decl)
450                       || signal_function_p (current_function_decl));
451
452   if (set)
453     CLEAR_HARD_REG_SET (*set);
454   count = 0;
455
456   /* No need to save any registers if the function never returns or 
457      is have "OS_task" or "OS_main" attribute.  */
458   if (TREE_THIS_VOLATILE (current_function_decl)
459       || cfun->machine->is_OS_task
460       || cfun->machine->is_OS_main)
461     return 0;
462
463   for (reg = 0; reg < 32; reg++)
464     {
465       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
466          any global register variables.  */
467       if (fixed_regs[reg])
468         continue;
469
470       if ((int_or_sig_p && !current_function_is_leaf && call_used_regs[reg])
471           || (df_regs_ever_live_p (reg)
472               && (int_or_sig_p || !call_used_regs[reg])
473               && !(frame_pointer_needed
474                    && (reg == REG_Y || reg == (REG_Y+1)))))
475         {
476           if (set)
477             SET_HARD_REG_BIT (*set, reg);
478           count++;
479         }
480     }
481   return count;
482 }
483
484 /* Return true if register FROM can be eliminated via register TO.  */
485
486 bool
487 avr_can_eliminate (const int from, const int to)
488 {
489   return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
490           || ((from == FRAME_POINTER_REGNUM 
491                || from == FRAME_POINTER_REGNUM + 1)
492               && !frame_pointer_needed));
493 }
494
495 /* Compute offset between arg_pointer and frame_pointer.  */
496
497 int
498 avr_initial_elimination_offset (int from, int to)
499 {
500   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
501     return 0;
502   else
503     {
504       int offset = frame_pointer_needed ? 2 : 0;
505       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
506
507       offset += avr_regs_to_save (NULL);
508       return get_frame_size () + (avr_pc_size) + 1 + offset;
509     }
510 }
511
512 /* Actual start of frame is virtual_stack_vars_rtx this is offset from 
513    frame pointer by +STARTING_FRAME_OFFSET.
514    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
515    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
516
517 rtx avr_builtin_setjmp_frame_value (void)
518 {
519   return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx, 
520                          gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
521 }
522
523 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3 byte PC).
524    This is return address of function.  */
525 rtx 
526 avr_return_addr_rtx (int count, rtx tem)
527 {
528   rtx r;
529     
530   /* Can only return this functions return address. Others not supported.  */
531   if (count)
532      return NULL;
533
534   if (AVR_3_BYTE_PC)
535     {
536       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
537       warning (0, "'builtin_return_address' contains only 2 bytes of address");
538     }
539   else
540     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
541
542   r = gen_rtx_PLUS (Pmode, tem, r);
543   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
544   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
545   return  r;
546 }
547
548 /* Return 1 if the function epilogue is just a single "ret".  */
549
550 int
551 avr_simple_epilogue (void)
552 {
553   return (! frame_pointer_needed
554           && get_frame_size () == 0
555           && avr_regs_to_save (NULL) == 0
556           && ! interrupt_function_p (current_function_decl)
557           && ! signal_function_p (current_function_decl)
558           && ! avr_naked_function_p (current_function_decl)
559           && ! TREE_THIS_VOLATILE (current_function_decl));
560 }
561
562 /* This function checks sequence of live registers.  */
563
564 static int
565 sequent_regs_live (void)
566 {
567   int reg;
568   int live_seq=0;
569   int cur_seq=0;
570
571   for (reg = 0; reg < 18; ++reg)
572     {
573       if (!call_used_regs[reg])
574         {
575           if (df_regs_ever_live_p (reg))
576             {
577               ++live_seq;
578               ++cur_seq;
579             }
580           else
581             cur_seq = 0;
582         }
583     }
584
585   if (!frame_pointer_needed)
586     {
587       if (df_regs_ever_live_p (REG_Y))
588         {
589           ++live_seq;
590           ++cur_seq;
591         }
592       else
593         cur_seq = 0;
594
595       if (df_regs_ever_live_p (REG_Y+1))
596         {
597           ++live_seq;
598           ++cur_seq;
599         }
600       else
601         cur_seq = 0;
602     }
603   else
604     {
605       cur_seq += 2;
606       live_seq += 2;
607     }
608   return (cur_seq == live_seq) ? live_seq : 0;
609 }
610
611 /* Obtain the length sequence of insns.  */
612
613 int
614 get_sequence_length (rtx insns)
615 {
616   rtx insn;
617   int length;
618   
619   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
620     length += get_attr_length (insn);
621                 
622   return length;
623 }
624
625 /*  Implement INCOMING_RETURN_ADDR_RTX.  */
626
627 rtx
628 avr_incoming_return_addr_rtx (void)
629 {
630   /* The return address is at the top of the stack.  Note that the push
631      was via post-decrement, which means the actual address is off by one.  */
632   return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
633 }
634
635 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
636
637 static void
638 emit_push_byte (unsigned regno, bool frame_related_p)
639 {
640   rtx mem, reg, insn;
641
642   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
643   mem = gen_frame_mem (QImode, mem);
644   reg = gen_rtx_REG (QImode, regno);
645
646   insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
647   if (frame_related_p)
648     RTX_FRAME_RELATED_P (insn) = 1;
649
650   cfun->machine->stack_usage++;
651 }
652
653
654 /*  Output function prologue.  */
655
656 void
657 expand_prologue (void)
658 {
659   int live_seq;
660   HARD_REG_SET set;
661   int minimize;
662   HOST_WIDE_INT size = get_frame_size();
663   rtx insn;
664   
665   /* Init cfun->machine.  */
666   cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
667   cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
668   cfun->machine->is_signal = signal_function_p (current_function_decl);
669   cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
670   cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
671   cfun->machine->stack_usage = 0;
672   
673   /* Prologue: naked.  */
674   if (cfun->machine->is_naked)
675     {
676       return;
677     }
678
679   avr_regs_to_save (&set);
680   live_seq = sequent_regs_live ();
681   minimize = (TARGET_CALL_PROLOGUES
682               && !cfun->machine->is_interrupt
683               && !cfun->machine->is_signal
684               && !cfun->machine->is_OS_task
685               && !cfun->machine->is_OS_main
686               && live_seq);
687
688   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
689     {
690       /* Enable interrupts.  */
691       if (cfun->machine->is_interrupt)
692         emit_insn (gen_enable_interrupt ());
693         
694       /* Push zero reg.  */
695       emit_push_byte (ZERO_REGNO, true);
696
697       /* Push tmp reg.  */
698       emit_push_byte (TMP_REGNO, true);
699
700       /* Push SREG.  */
701       /* ??? There's no dwarf2 column reserved for SREG.  */
702       emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
703       emit_push_byte (TMP_REGNO, false);
704
705       /* Push RAMPZ.  */
706       /* ??? There's no dwarf2 column reserved for RAMPZ.  */
707       if (AVR_HAVE_RAMPZ 
708           && TEST_HARD_REG_BIT (set, REG_Z)
709           && TEST_HARD_REG_BIT (set, REG_Z + 1))
710         {
711           emit_move_insn (tmp_reg_rtx,
712                           gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
713           emit_push_byte (TMP_REGNO, false);
714         }
715         
716       /* Clear zero reg.  */
717       emit_move_insn (zero_reg_rtx, const0_rtx);
718
719       /* Prevent any attempt to delete the setting of ZERO_REG!  */
720       emit_use (zero_reg_rtx);
721     }
722   if (minimize && (frame_pointer_needed 
723                    || (AVR_2_BYTE_PC && live_seq > 6)
724                    || live_seq > 7)) 
725     {
726       int first_reg, reg, offset;
727
728       emit_move_insn (gen_rtx_REG (HImode, REG_X), 
729                       gen_int_mode (size, HImode));
730
731       insn = emit_insn (gen_call_prologue_saves
732                         (gen_int_mode (live_seq, HImode),
733                          gen_int_mode (size + live_seq, HImode)));
734       RTX_FRAME_RELATED_P (insn) = 1;
735
736       /* Describe the effect of the unspec_volatile call to prologue_saves.
737          Note that this formulation assumes that add_reg_note pushes the
738          notes to the front.  Thus we build them in the reverse order of
739          how we want dwarf2out to process them.  */
740
741       /* The function does always set frame_pointer_rtx, but whether that
742          is going to be permanent in the function is frame_pointer_needed.  */
743       add_reg_note (insn, REG_CFA_ADJUST_CFA,
744                     gen_rtx_SET (VOIDmode,
745                                  (frame_pointer_needed
746                                   ? frame_pointer_rtx : stack_pointer_rtx),
747                                  plus_constant (stack_pointer_rtx,
748                                                 -(size + live_seq))));
749
750       /* Note that live_seq always contains r28+r29, but the other
751          registers to be saved are all below 18.  */
752       first_reg = 18 - (live_seq - 2);
753
754       for (reg = 29, offset = -live_seq + 1;
755            reg >= first_reg;
756            reg = (reg == 28 ? 17 : reg - 1), ++offset)
757         {
758           rtx m, r;
759
760           m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
761           r = gen_rtx_REG (QImode, reg);
762           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
763         }
764
765       cfun->machine->stack_usage += size + live_seq;
766     }
767   else
768     {
769       int reg;
770       for (reg = 0; reg < 32; ++reg)
771         if (TEST_HARD_REG_BIT (set, reg))
772           emit_push_byte (reg, true);
773
774       if (frame_pointer_needed)
775         {
776           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
777             {
778               /* Push frame pointer.  Always be consistent about the
779                  ordering of pushes -- epilogue_restores expects the
780                  register pair to be pushed low byte first.  */
781               emit_push_byte (REG_Y, true);
782               emit_push_byte (REG_Y + 1, true);
783             }
784
785           if (!size)
786             {
787               insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
788               RTX_FRAME_RELATED_P (insn) = 1;
789             }
790           else
791             {
792               /*  Creating a frame can be done by direct manipulation of the
793                   stack or via the frame pointer. These two methods are:
794                     fp=sp
795                     fp-=size
796                     sp=fp
797                 OR
798                     sp-=size
799                     fp=sp
800               the optimum method depends on function type, stack and frame size.
801               To avoid a complex logic, both methods are tested and shortest
802               is selected.  */
803               rtx myfp;
804               rtx fp_plus_insns; 
805
806               if (AVR_HAVE_8BIT_SP)
807                 {
808                   /* The high byte (r29) doesn't change.  Prefer 'subi'
809                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
810                   myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
811                 }
812               else 
813                 {
814                   /*  Normal sized addition.  */
815                   myfp = frame_pointer_rtx;
816                 }
817
818               /* Method 1-Adjust frame pointer.  */
819               start_sequence ();
820
821               /* Normally the dwarf2out frame-related-expr interpreter does
822                  not expect to have the CFA change once the frame pointer is
823                  set up.  Thus we avoid marking the move insn below and
824                  instead indicate that the entire operation is complete after
825                  the frame pointer subtraction is done.  */
826
827               emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
828
829               insn = emit_move_insn (myfp, plus_constant (myfp, -size));
830               RTX_FRAME_RELATED_P (insn) = 1;
831               add_reg_note (insn, REG_CFA_ADJUST_CFA,
832                             gen_rtx_SET (VOIDmode, frame_pointer_rtx,
833                                          plus_constant (stack_pointer_rtx,
834                                                         -size)));
835
836               /* Copy to stack pointer.  Note that since we've already
837                  changed the CFA to the frame pointer this operation
838                  need not be annotated at all.  */
839               if (AVR_HAVE_8BIT_SP)
840                 {
841                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
842                 }
843               else if (TARGET_NO_INTERRUPTS 
844                        || cfun->machine->is_signal
845                        || cfun->machine->is_OS_main)
846                 {
847                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
848                                                      frame_pointer_rtx));
849                 }
850               else if (cfun->machine->is_interrupt)
851                 {
852                   emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
853                                                     frame_pointer_rtx));
854                 }
855               else
856                 {
857                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
858                 }
859
860               fp_plus_insns = get_insns ();
861               end_sequence ();
862
863               /* Method 2-Adjust Stack pointer.  */
864               if (size <= 6)
865                 {
866                   rtx sp_plus_insns;
867
868                   start_sequence ();
869
870                   insn = plus_constant (stack_pointer_rtx, -size);
871                   insn = emit_move_insn (stack_pointer_rtx, insn);
872                   RTX_FRAME_RELATED_P (insn) = 1;
873                   
874                   insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
875                   RTX_FRAME_RELATED_P (insn) = 1;
876
877                   sp_plus_insns = get_insns ();
878                   end_sequence ();
879
880                   /* Use shortest method.  */
881                   if (get_sequence_length (sp_plus_insns) 
882                       < get_sequence_length (fp_plus_insns))
883                     emit_insn (sp_plus_insns);
884                   else
885                     emit_insn (fp_plus_insns);
886                 }
887               else
888                 emit_insn (fp_plus_insns);
889
890               cfun->machine->stack_usage += size;
891             }
892         }
893     }
894
895   if (flag_stack_usage_info)
896     current_function_static_stack_size = cfun->machine->stack_usage;
897 }
898
899 /* Output summary at end of function prologue.  */
900
901 static void
902 avr_asm_function_end_prologue (FILE *file)
903 {
904   if (cfun->machine->is_naked)
905     {
906       fputs ("/* prologue: naked */\n", file);
907     }
908   else
909     {
910       if (cfun->machine->is_interrupt)
911         {
912           fputs ("/* prologue: Interrupt */\n", file);
913         }
914       else if (cfun->machine->is_signal)
915         {
916           fputs ("/* prologue: Signal */\n", file);
917         }
918       else
919         fputs ("/* prologue: function */\n", file);
920     }
921   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
922                  get_frame_size());
923   fprintf (file, "/* stack size = %d */\n",
924                  cfun->machine->stack_usage);
925   /* Create symbol stack offset here so all functions have it. Add 1 to stack
926      usage for offset so that SP + .L__stack_offset = return address.  */
927   fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
928 }
929
930
931 /* Implement EPILOGUE_USES.  */
932
933 int
934 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
935 {
936   if (reload_completed 
937       && cfun->machine
938       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
939     return 1;
940   return 0;
941 }
942
943 /*  Helper for expand_epilogue.  Emit a pop of a byte register.  */
944
945 static void
946 emit_pop_byte (unsigned regno)
947 {
948   rtx mem, reg;
949
950   mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
951   mem = gen_frame_mem (QImode, mem);
952   reg = gen_rtx_REG (QImode, regno);
953
954   emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
955 }
956
957 /*  Output RTL epilogue.  */
958
959 void
960 expand_epilogue (bool sibcall_p)
961 {
962   int reg;
963   int live_seq;
964   HARD_REG_SET set;      
965   int minimize;
966   HOST_WIDE_INT size = get_frame_size();
967   
968   /* epilogue: naked  */
969   if (cfun->machine->is_naked)
970     {
971       gcc_assert (!sibcall_p);
972       
973       emit_jump_insn (gen_return ());
974       return;
975     }
976
977   avr_regs_to_save (&set);
978   live_seq = sequent_regs_live ();
979   minimize = (TARGET_CALL_PROLOGUES
980               && !cfun->machine->is_interrupt
981               && !cfun->machine->is_signal
982               && !cfun->machine->is_OS_task
983               && !cfun->machine->is_OS_main
984               && live_seq);
985   
986   if (minimize && (frame_pointer_needed || live_seq > 4))
987     {
988       if (frame_pointer_needed)
989         {
990           /*  Get rid of frame.  */
991           emit_move_insn(frame_pointer_rtx,
992                          gen_rtx_PLUS (HImode, frame_pointer_rtx,
993                                        gen_int_mode (size, HImode)));
994         }
995       else
996         {
997           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
998         }
999         
1000       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1001     }
1002   else
1003     {
1004       if (frame_pointer_needed)
1005         {
1006           if (size)
1007             {
1008               /* Try two methods to adjust stack and select shortest.  */
1009               rtx myfp;
1010               rtx fp_plus_insns;
1011
1012               if (AVR_HAVE_8BIT_SP)
1013                 {
1014                   /* The high byte (r29) doesn't change - prefer 'subi' 
1015                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
1016                   myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
1017                 }
1018               else 
1019                 {
1020                   /* Normal sized addition.  */
1021                   myfp = frame_pointer_rtx;
1022                 }
1023               
1024               /* Method 1-Adjust frame pointer.  */
1025               start_sequence ();
1026
1027               emit_move_insn (myfp, plus_constant (myfp, size));
1028
1029               /* Copy to stack pointer.  */
1030               if (AVR_HAVE_8BIT_SP)
1031                 {
1032                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1033                 }
1034               else if (TARGET_NO_INTERRUPTS 
1035                        || cfun->machine->is_signal)
1036                 {
1037                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
1038                                                      frame_pointer_rtx));
1039                 }
1040               else if (cfun->machine->is_interrupt)
1041                 {
1042                   emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
1043                                                     frame_pointer_rtx));
1044                 }
1045               else
1046                 {
1047                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1048                 }
1049
1050               fp_plus_insns = get_insns ();
1051               end_sequence ();        
1052
1053               /* Method 2-Adjust Stack pointer.  */
1054               if (size <= 5)
1055                 {
1056                   rtx sp_plus_insns;
1057
1058                   start_sequence ();
1059
1060                   emit_move_insn (stack_pointer_rtx,
1061                                   plus_constant (stack_pointer_rtx, size));
1062
1063                   sp_plus_insns = get_insns ();
1064                   end_sequence ();
1065
1066                   /* Use shortest method.  */
1067                   if (get_sequence_length (sp_plus_insns) 
1068                       < get_sequence_length (fp_plus_insns))
1069                     emit_insn (sp_plus_insns);
1070                   else
1071                     emit_insn (fp_plus_insns);
1072                 }
1073               else
1074                 emit_insn (fp_plus_insns);
1075             }
1076           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1077             {
1078               /* Restore previous frame_pointer.  See expand_prologue for
1079                  rationale for not using pophi.  */
1080               emit_pop_byte (REG_Y + 1);
1081               emit_pop_byte (REG_Y);
1082             }
1083         }
1084
1085       /* Restore used registers.  */
1086       for (reg = 31; reg >= 0; --reg)
1087         if (TEST_HARD_REG_BIT (set, reg))
1088           emit_pop_byte (reg);
1089
1090       if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1091         {
1092           /* Restore RAMPZ using tmp reg as scratch.  */
1093           if (AVR_HAVE_RAMPZ 
1094               && TEST_HARD_REG_BIT (set, REG_Z)
1095               && TEST_HARD_REG_BIT (set, REG_Z + 1))
1096             {
1097               emit_pop_byte (TMP_REGNO);
1098               emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)), 
1099                               tmp_reg_rtx);
1100             }
1101
1102           /* Restore SREG using tmp reg as scratch.  */
1103           emit_pop_byte (TMP_REGNO);
1104       
1105           emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)), 
1106                           tmp_reg_rtx);
1107
1108           /* Restore tmp REG.  */
1109           emit_pop_byte (TMP_REGNO);
1110
1111           /* Restore zero REG.  */
1112           emit_pop_byte (ZERO_REGNO);
1113         }
1114
1115       if (!sibcall_p)
1116         emit_jump_insn (gen_return ());
1117     }
1118 }
1119
1120 /* Output summary messages at beginning of function epilogue.  */
1121
1122 static void
1123 avr_asm_function_begin_epilogue (FILE *file)
1124 {
1125   fprintf (file, "/* epilogue start */\n");
1126 }
1127
1128
1129 /* Implement TARGET_CANNOT_MODITY_JUMPS_P */
1130
1131 static bool
1132 avr_cannot_modify_jumps_p (void)
1133 {
1134
1135   /* Naked Functions must not have any instructions after
1136      their epilogue, see PR42240 */
1137      
1138   if (reload_completed
1139       && cfun->machine
1140       && cfun->machine->is_naked)
1141     {
1142       return true;
1143     }
1144
1145   return false;
1146 }
1147
1148
1149 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1150    machine for a memory operand of mode MODE.  */
1151
1152 bool
1153 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1154 {
1155   enum reg_class r = NO_REGS;
1156   
1157   if (TARGET_ALL_DEBUG)
1158     {
1159       fprintf (stderr, "mode: (%s) %s %s %s %s:",
1160                GET_MODE_NAME(mode),
1161                strict ? "(strict)": "",
1162                reload_completed ? "(reload_completed)": "",
1163                reload_in_progress ? "(reload_in_progress)": "",
1164                reg_renumber ? "(reg_renumber)" : "");
1165       if (GET_CODE (x) == PLUS
1166           && REG_P (XEXP (x, 0))
1167           && GET_CODE (XEXP (x, 1)) == CONST_INT
1168           && INTVAL (XEXP (x, 1)) >= 0
1169           && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
1170           && reg_renumber
1171           )
1172         fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1173                  true_regnum (XEXP (x, 0)));
1174       debug_rtx (x);
1175     }
1176   if (!strict && GET_CODE (x) == SUBREG)
1177         x = SUBREG_REG (x);
1178   if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
1179                     : REG_OK_FOR_BASE_NOSTRICT_P (x)))
1180     r = POINTER_REGS;
1181   else if (CONSTANT_ADDRESS_P (x))
1182     r = ALL_REGS;
1183   else if (GET_CODE (x) == PLUS
1184            && REG_P (XEXP (x, 0))
1185            && GET_CODE (XEXP (x, 1)) == CONST_INT
1186            && INTVAL (XEXP (x, 1)) >= 0)
1187     {
1188       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1189       if (fit)
1190         {
1191           if (! strict
1192               || REGNO (XEXP (x,0)) == REG_X
1193               || REGNO (XEXP (x,0)) == REG_Y
1194               || REGNO (XEXP (x,0)) == REG_Z)
1195             r = BASE_POINTER_REGS;
1196           if (XEXP (x,0) == frame_pointer_rtx
1197               || XEXP (x,0) == arg_pointer_rtx)
1198             r = BASE_POINTER_REGS;
1199         }
1200       else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
1201         r = POINTER_Y_REGS;
1202     }
1203   else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
1204            && REG_P (XEXP (x, 0))
1205            && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
1206                : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
1207     {
1208       r = POINTER_REGS;
1209     }
1210   if (TARGET_ALL_DEBUG)
1211     {
1212       fprintf (stderr, "   ret = %c\n", r + '0');
1213     }
1214   return r == NO_REGS ? 0 : (int)r;
1215 }
1216
1217 /* Attempts to replace X with a valid
1218    memory address for an operand of mode MODE  */
1219
1220 rtx
1221 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1222 {
1223   x = oldx;
1224   if (TARGET_ALL_DEBUG)
1225     {
1226       fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
1227       debug_rtx (oldx);
1228     }
1229   
1230   if (GET_CODE (oldx) == PLUS
1231       && REG_P (XEXP (oldx,0)))
1232     {
1233       if (REG_P (XEXP (oldx,1)))
1234         x = force_reg (GET_MODE (oldx), oldx);
1235       else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1236         {
1237           int offs = INTVAL (XEXP (oldx,1));
1238           if (frame_pointer_rtx != XEXP (oldx,0))
1239             if (offs > MAX_LD_OFFSET (mode))
1240               {
1241                 if (TARGET_ALL_DEBUG)
1242                   fprintf (stderr, "force_reg (big offset)\n");
1243                 x = force_reg (GET_MODE (oldx), oldx);
1244               }
1245         }
1246     }
1247   return x;
1248 }
1249
1250
1251 /* Return a pointer register name as a string.  */
1252
1253 static const char *
1254 ptrreg_to_str (int regno)
1255 {
1256   switch (regno)
1257     {
1258     case REG_X: return "X";
1259     case REG_Y: return "Y";
1260     case REG_Z: return "Z";
1261     default:
1262       output_operand_lossage ("address operand requires constraint for X, Y, or Z register");
1263     }
1264   return NULL;
1265 }
1266
1267 /* Return the condition name as a string.
1268    Used in conditional jump constructing  */
1269
1270 static const char *
1271 cond_string (enum rtx_code code)
1272 {
1273   switch (code)
1274     {
1275     case NE:
1276       return "ne";
1277     case EQ:
1278       return "eq";
1279     case GE:
1280       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1281         return "pl";
1282       else
1283         return "ge";
1284     case LT:
1285       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1286         return "mi";
1287       else
1288         return "lt";
1289     case GEU:
1290       return "sh";
1291     case LTU:
1292       return "lo";
1293     default:
1294       gcc_unreachable ();
1295     }
1296 }
1297
1298 /* Output ADDR to FILE as address.  */
1299
1300 void
1301 print_operand_address (FILE *file, rtx addr)
1302 {
1303   switch (GET_CODE (addr))
1304     {
1305     case REG:
1306       fprintf (file, ptrreg_to_str (REGNO (addr)));
1307       break;
1308
1309     case PRE_DEC:
1310       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1311       break;
1312
1313     case POST_INC:
1314       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1315       break;
1316
1317     default:
1318       if (CONSTANT_ADDRESS_P (addr)
1319           && text_segment_operand (addr, VOIDmode))
1320         {
1321           rtx x = addr;
1322           if (GET_CODE (x) == CONST)
1323             x = XEXP (x, 0);
1324           if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
1325             {
1326               /* Assembler gs() will implant word address. Make offset 
1327                  a byte offset inside gs() for assembler. This is 
1328                  needed because the more logical (constant+gs(sym)) is not 
1329                  accepted by gas. For 128K and lower devices this is ok. For
1330                  large devices it will create a Trampoline to offset from symbol 
1331                  which may not be what the user really wanted.  */
1332               fprintf (file, "gs(");
1333               output_addr_const (file, XEXP (x,0));
1334               fprintf (file,"+" HOST_WIDE_INT_PRINT_DEC ")", 2 * INTVAL (XEXP (x,1)));
1335               if (AVR_3_BYTE_PC)
1336                 if (warning (0, "pointer offset from symbol maybe incorrect"))
1337                   {
1338                     output_addr_const (stderr, addr);
1339                     fprintf(stderr,"\n");
1340                   }
1341             }
1342           else
1343             {
1344               fprintf (file, "gs(");
1345               output_addr_const (file, addr);
1346               fprintf (file, ")");
1347             }
1348         }
1349       else
1350         output_addr_const (file, addr);
1351     }
1352 }
1353
1354
1355 /* Output X as assembler operand to file FILE.  */
1356      
1357 void
1358 print_operand (FILE *file, rtx x, int code)
1359 {
1360   int abcd = 0;
1361
1362   if (code >= 'A' && code <= 'D')
1363     abcd = code - 'A';
1364
1365   if (code == '~')
1366     {
1367       if (!AVR_HAVE_JMP_CALL)
1368         fputc ('r', file);
1369     }
1370   else if (code == '!')
1371     {
1372       if (AVR_HAVE_EIJMP_EICALL)
1373         fputc ('e', file);
1374     }
1375   else if (REG_P (x))
1376     {
1377       if (x == zero_reg_rtx)
1378         fprintf (file, "__zero_reg__");
1379       else
1380         fprintf (file, reg_names[true_regnum (x) + abcd]);
1381     }
1382   else if (GET_CODE (x) == CONST_INT)
1383     fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1384   else if (GET_CODE (x) == MEM)
1385     {
1386       rtx addr = XEXP (x,0);
1387       if (code == 'm')
1388         {
1389            if (!CONSTANT_P (addr))
1390             fatal_insn ("bad address, not a constant):", addr);
1391           /* Assembler template with m-code is data - not progmem section */
1392           if (text_segment_operand (addr, VOIDmode))
1393             if (warning ( 0, "accessing data memory with program memory address"))
1394               {
1395                 output_addr_const (stderr, addr);
1396                 fprintf(stderr,"\n");
1397               }
1398           output_addr_const (file, addr);
1399         }
1400       else if (code == 'o')
1401         {
1402           if (GET_CODE (addr) != PLUS)
1403             fatal_insn ("bad address, not (reg+disp):", addr);
1404
1405           print_operand (file, XEXP (addr, 1), 0);
1406         }
1407       else if (code == 'p' || code == 'r')
1408         {
1409           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1410             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1411           
1412           if (code == 'p')
1413             print_operand_address (file, XEXP (addr, 0));  /* X, Y, Z */
1414           else
1415             print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
1416         }
1417       else if (GET_CODE (addr) == PLUS)
1418         {
1419           print_operand_address (file, XEXP (addr,0));
1420           if (REGNO (XEXP (addr, 0)) == REG_X)
1421             fatal_insn ("internal compiler error.  Bad address:"
1422                         ,addr);
1423           fputc ('+', file);
1424           print_operand (file, XEXP (addr,1), code);
1425         }
1426       else
1427         print_operand_address (file, addr);
1428     }
1429   else if (code == 'x')
1430     {
1431       /* Constant progmem address - like used in jmp or call */
1432       if (0 == text_segment_operand (x, VOIDmode))
1433             if (warning ( 0, "accessing program  memory with data memory address"))
1434           {
1435             output_addr_const (stderr, x);
1436             fprintf(stderr,"\n");
1437           }
1438       /* Use normal symbol for direct address no linker trampoline needed */
1439       output_addr_const (file, x);
1440     }
1441   else if (GET_CODE (x) == CONST_DOUBLE)
1442     {
1443       long val;
1444       REAL_VALUE_TYPE rv;
1445       if (GET_MODE (x) != SFmode)
1446         fatal_insn ("internal compiler error.  Unknown mode:", x);
1447       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1448       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1449       fprintf (file, "0x%lx", val);
1450     }
1451   else if (code == 'j')
1452     fputs (cond_string (GET_CODE (x)), file);
1453   else if (code == 'k')
1454     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1455   else
1456     print_operand_address (file, x);
1457 }
1458
1459 /* Update the condition code in the INSN.  */
1460
1461 void
1462 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1463 {
1464   rtx set;
1465   
1466   switch (get_attr_cc (insn))
1467     {
1468     case CC_NONE:
1469       /* Insn does not affect CC at all.  */
1470       break;
1471
1472     case CC_SET_N:
1473       CC_STATUS_INIT;
1474       break;
1475
1476     case CC_SET_ZN:
1477       set = single_set (insn);
1478       CC_STATUS_INIT;
1479       if (set)
1480         {
1481           cc_status.flags |= CC_NO_OVERFLOW;
1482           cc_status.value1 = SET_DEST (set);
1483         }
1484       break;
1485
1486     case CC_SET_CZN:
1487       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1488          The V flag may or may not be known but that's ok because
1489          alter_cond will change tests to use EQ/NE.  */
1490       set = single_set (insn);
1491       CC_STATUS_INIT;
1492       if (set)
1493         {
1494           cc_status.value1 = SET_DEST (set);
1495           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1496         }
1497       break;
1498
1499     case CC_COMPARE:
1500       set = single_set (insn);
1501       CC_STATUS_INIT;
1502       if (set)
1503         cc_status.value1 = SET_SRC (set);
1504       break;
1505       
1506     case CC_CLOBBER:
1507       /* Insn doesn't leave CC in a usable state.  */
1508       CC_STATUS_INIT;
1509
1510       /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1511       set = single_set (insn);
1512       if (set)
1513         {
1514           rtx src = SET_SRC (set);
1515           
1516           if (GET_CODE (src) == ASHIFTRT
1517               && GET_MODE (src) == QImode)
1518             {
1519               rtx x = XEXP (src, 1);
1520
1521               if (GET_CODE (x) == CONST_INT
1522                   && INTVAL (x) > 0
1523                   && INTVAL (x) != 6)
1524                 {
1525                   cc_status.value1 = SET_DEST (set);
1526                   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1527                 }
1528             }
1529         }
1530       break;
1531     }
1532 }
1533
1534 /* Return maximum number of consecutive registers of
1535    class CLASS needed to hold a value of mode MODE.  */
1536
1537 int
1538 class_max_nregs (enum reg_class rclass ATTRIBUTE_UNUSED,enum machine_mode mode)
1539 {
1540   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1541 }
1542
1543 /* Choose mode for jump insn:
1544    1 - relative jump in range -63 <= x <= 62 ;
1545    2 - relative jump in range -2046 <= x <= 2045 ;
1546    3 - absolute jump (only for ATmega[16]03).  */
1547
1548 int
1549 avr_jump_mode (rtx x, rtx insn)
1550 {
1551   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
1552                                             ? XEXP (x, 0) : x));
1553   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1554   int jump_distance = cur_addr - dest_addr;
1555   
1556   if (-63 <= jump_distance && jump_distance <= 62)
1557     return 1;
1558   else if (-2046 <= jump_distance && jump_distance <= 2045)
1559     return 2;
1560   else if (AVR_HAVE_JMP_CALL)
1561     return 3;
1562   
1563   return 2;
1564 }
1565
1566 /* return an AVR condition jump commands.
1567    X is a comparison RTX.
1568    LEN is a number returned by avr_jump_mode function.
1569    if REVERSE nonzero then condition code in X must be reversed.  */
1570
1571 const char *
1572 ret_cond_branch (rtx x, int len, int reverse)
1573 {
1574   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1575   
1576   switch (cond)
1577     {
1578     case GT:
1579       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1580         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1581                             AS1 (brpl,%0)) :
1582                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1583                             AS1 (brmi,.+2) CR_TAB
1584                             AS1 (rjmp,%0)) :
1585                 (AS1 (breq,.+6) CR_TAB
1586                  AS1 (brmi,.+4) CR_TAB
1587                  AS1 (jmp,%0)));
1588           
1589       else
1590         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1591                             AS1 (brge,%0)) :
1592                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1593                             AS1 (brlt,.+2) CR_TAB
1594                             AS1 (rjmp,%0)) :
1595                 (AS1 (breq,.+6) CR_TAB
1596                  AS1 (brlt,.+4) CR_TAB
1597                  AS1 (jmp,%0)));
1598     case GTU:
1599       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1600                           AS1 (brsh,%0)) :
1601               len == 2 ? (AS1 (breq,.+4) CR_TAB
1602                           AS1 (brlo,.+2) CR_TAB
1603                           AS1 (rjmp,%0)) :
1604               (AS1 (breq,.+6) CR_TAB
1605                AS1 (brlo,.+4) CR_TAB
1606                AS1 (jmp,%0)));
1607     case LE:
1608       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1609         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1610                             AS1 (brmi,%0)) :
1611                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1612                             AS1 (brpl,.+2) CR_TAB
1613                             AS1 (rjmp,%0)) :
1614                 (AS1 (breq,.+2) CR_TAB
1615                  AS1 (brpl,.+4) CR_TAB
1616                  AS1 (jmp,%0)));
1617       else
1618         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1619                             AS1 (brlt,%0)) :
1620                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1621                             AS1 (brge,.+2) CR_TAB
1622                             AS1 (rjmp,%0)) :
1623                 (AS1 (breq,.+2) CR_TAB
1624                  AS1 (brge,.+4) CR_TAB
1625                  AS1 (jmp,%0)));
1626     case LEU:
1627       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1628                           AS1 (brlo,%0)) :
1629               len == 2 ? (AS1 (breq,.+2) CR_TAB
1630                           AS1 (brsh,.+2) CR_TAB
1631                           AS1 (rjmp,%0)) :
1632               (AS1 (breq,.+2) CR_TAB
1633                AS1 (brsh,.+4) CR_TAB
1634                AS1 (jmp,%0)));
1635     default:
1636       if (reverse)
1637         {
1638           switch (len)
1639             {
1640             case 1:
1641               return AS1 (br%k1,%0);
1642             case 2:
1643               return (AS1 (br%j1,.+2) CR_TAB
1644                       AS1 (rjmp,%0));
1645             default:
1646               return (AS1 (br%j1,.+4) CR_TAB
1647                       AS1 (jmp,%0));
1648             }
1649         }
1650         else
1651           {
1652             switch (len)
1653               {
1654               case 1:
1655                 return AS1 (br%j1,%0);
1656               case 2:
1657                 return (AS1 (br%k1,.+2) CR_TAB
1658                         AS1 (rjmp,%0));
1659               default:
1660                 return (AS1 (br%k1,.+4) CR_TAB
1661                         AS1 (jmp,%0));
1662               }
1663           }
1664     }
1665   return "";
1666 }
1667
1668 /* Predicate function for immediate operand which fits to byte (8bit) */
1669
1670 int
1671 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1672 {
1673   return (GET_CODE (op) == CONST_INT
1674           && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1675 }
1676
1677 /* Output insn cost for next insn.  */
1678
1679 void
1680 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1681                     int num_operands ATTRIBUTE_UNUSED)
1682 {
1683   if (TARGET_ALL_DEBUG)
1684     {
1685       fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
1686                rtx_cost (PATTERN (insn), INSN, !optimize_size));
1687     }
1688 }
1689
1690 /* Return 0 if undefined, 1 if always true or always false.  */
1691
1692 int
1693 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
1694 {
1695   unsigned int max = (mode == QImode ? 0xff :
1696                       mode == HImode ? 0xffff :
1697                       mode == SImode ? 0xffffffff : 0);
1698   if (max && op && GET_CODE (x) == CONST_INT)
1699     {
1700       if (unsigned_condition (op) != op)
1701         max >>= 1;
1702
1703       if (max != (INTVAL (x) & max)
1704           && INTVAL (x) != 0xff)
1705         return 1;
1706     }
1707   return 0;
1708 }
1709
1710
1711 /* Returns nonzero if REGNO is the number of a hard
1712    register in which function arguments are sometimes passed.  */
1713
1714 int
1715 function_arg_regno_p(int r)
1716 {
1717   return (r >= 8 && r <= 25);
1718 }
1719
1720 /* Initializing the variable cum for the state at the beginning
1721    of the argument list.  */
1722
1723 void
1724 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1725                       tree fndecl ATTRIBUTE_UNUSED)
1726 {
1727   cum->nregs = 18;
1728   cum->regno = FIRST_CUM_REG;
1729   if (!libname && stdarg_p (fntype))
1730     cum->nregs = 0;
1731
1732   /* Assume the calle may be tail called */
1733   
1734   cfun->machine->sibcall_fails = 0;
1735 }
1736
1737 /* Returns the number of registers to allocate for a function argument.  */
1738
1739 static int
1740 avr_num_arg_regs (enum machine_mode mode, const_tree type)
1741 {
1742   int size;
1743
1744   if (mode == BLKmode)
1745     size = int_size_in_bytes (type);
1746   else
1747     size = GET_MODE_SIZE (mode);
1748
1749   /* Align all function arguments to start in even-numbered registers.
1750      Odd-sized arguments leave holes above them.  */
1751
1752   return (size + 1) & ~1;
1753 }
1754
1755 /* Controls whether a function argument is passed
1756    in a register, and which register.  */
1757
1758 static rtx
1759 avr_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1760                   const_tree type, bool named ATTRIBUTE_UNUSED)
1761 {
1762   int bytes = avr_num_arg_regs (mode, type);
1763
1764   if (cum->nregs && bytes <= cum->nregs)
1765     return gen_rtx_REG (mode, cum->regno - bytes);
1766
1767   return NULL_RTX;
1768 }
1769
1770 /* Update the summarizer variable CUM to advance past an argument
1771    in the argument list.  */
1772    
1773 static void
1774 avr_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1775                           const_tree type, bool named ATTRIBUTE_UNUSED)
1776 {
1777   int bytes = avr_num_arg_regs (mode, type);
1778
1779   cum->nregs -= bytes;
1780   cum->regno -= bytes;
1781
1782   /* A parameter is being passed in a call-saved register. As the original
1783      contents of these regs has to be restored before leaving the function,
1784      a function must not pass arguments in call-saved regs in order to get
1785      tail-called. */
1786   
1787   if (cum->regno >= 0
1788       && !call_used_regs[cum->regno])
1789     {
1790       /* FIXME: We ship info on failing tail-call in struct machine_function.
1791          This uses internals of calls.c:expand_call() and the way args_so_far
1792          is used. targetm.function_ok_for_sibcall() needs to be extended to
1793          pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
1794          dependent so that such an extension is not wanted. */
1795       
1796       cfun->machine->sibcall_fails = 1;
1797     }
1798
1799   /* Test if all registers needed by the ABI are actually available.  If the
1800      user has fixed a GPR needed to pass an argument, an (implicit) function
1801      call would clobber that fixed register.  See PR45099 for an example.  */
1802   
1803   if (cum->regno >= 0)
1804     {
1805       int regno;
1806
1807       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
1808         if (fixed_regs[regno])
1809           error ("Register %s is needed to pass a parameter but is fixed",
1810                  reg_names[regno]);
1811     }
1812       
1813   if (cum->nregs <= 0)
1814     {
1815       cum->nregs = 0;
1816       cum->regno = FIRST_CUM_REG;
1817     }
1818 }
1819
1820 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
1821 /* Decide whether we can make a sibling call to a function.  DECL is the
1822    declaration of the function being targeted by the call and EXP is the
1823    CALL_EXPR representing the call. */
1824
1825 static bool
1826 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
1827 {
1828   tree fntype_callee;
1829
1830   /* Tail-calling must fail if callee-saved regs are used to pass
1831      function args.  We must not tail-call when `epilogue_restores'
1832      is used.  Unfortunately, we cannot tell at this point if that
1833      actually will happen or not, and we cannot step back from
1834      tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
1835   
1836   if (cfun->machine->sibcall_fails
1837       || TARGET_CALL_PROLOGUES)
1838     {
1839       return false;
1840     }
1841   
1842   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
1843
1844   if (decl_callee)
1845     {
1846       decl_callee = TREE_TYPE (decl_callee);
1847     }
1848   else
1849     {
1850       decl_callee = fntype_callee;
1851       
1852       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
1853              && METHOD_TYPE != TREE_CODE (decl_callee))
1854         {
1855           decl_callee = TREE_TYPE (decl_callee);
1856         }
1857     }
1858
1859   /* Ensure that caller and callee have compatible epilogues */
1860   
1861   if (interrupt_function_p (current_function_decl)
1862       || signal_function_p (current_function_decl)
1863       || avr_naked_function_p (decl_callee)
1864       || avr_naked_function_p (current_function_decl)
1865       /* FIXME: For OS_task and OS_main, we are over-conservative.
1866          This is due to missing documentation of these attributes
1867          and what they actually should do and should not do. */
1868       || (avr_OS_task_function_p (decl_callee)
1869           != avr_OS_task_function_p (current_function_decl))
1870       || (avr_OS_main_function_p (decl_callee)
1871           != avr_OS_main_function_p (current_function_decl)))
1872     {
1873       return false;
1874     }
1875  
1876   return true;
1877 }
1878
1879 /***********************************************************************
1880   Functions for outputting various mov's for a various modes
1881 ************************************************************************/
1882 const char *
1883 output_movqi (rtx insn, rtx operands[], int *l)
1884 {
1885   int dummy;
1886   rtx dest = operands[0];
1887   rtx src = operands[1];
1888   int *real_l = l;
1889   
1890   if (!l)
1891     l = &dummy;
1892
1893   *l = 1;
1894   
1895   if (register_operand (dest, QImode))
1896     {
1897       if (register_operand (src, QImode)) /* mov r,r */
1898         {
1899           if (test_hard_reg_class (STACK_REG, dest))
1900             return AS2 (out,%0,%1);
1901           else if (test_hard_reg_class (STACK_REG, src))
1902             return AS2 (in,%0,%1);
1903           
1904           return AS2 (mov,%0,%1);
1905         }
1906       else if (CONSTANT_P (src))
1907         {
1908           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1909             return AS2 (ldi,%0,lo8(%1));
1910           
1911           if (GET_CODE (src) == CONST_INT)
1912             {
1913               if (src == const0_rtx) /* mov r,L */
1914                 return AS1 (clr,%0);
1915               else if (src == const1_rtx)
1916                 {
1917                   *l = 2;
1918                   return (AS1 (clr,%0) CR_TAB
1919                           AS1 (inc,%0));
1920                 }
1921               else if (src == constm1_rtx)
1922                 {
1923                   /* Immediate constants -1 to any register */
1924                   *l = 2;
1925                   return (AS1 (clr,%0) CR_TAB
1926                           AS1 (dec,%0));
1927                 }
1928               else
1929                 {
1930                   int bit_nr = exact_log2 (INTVAL (src));
1931
1932                   if (bit_nr >= 0)
1933                     {
1934                       *l = 3;
1935                       if (!real_l)
1936                         output_asm_insn ((AS1 (clr,%0) CR_TAB
1937                                           "set"), operands);
1938                       if (!real_l)
1939                         avr_output_bld (operands, bit_nr);
1940
1941                       return "";
1942                     }
1943                 }
1944             }
1945           
1946           /* Last resort, larger than loading from memory.  */
1947           *l = 4;
1948           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1949                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1950                   AS2 (mov,%0,r31)          CR_TAB
1951                   AS2 (mov,r31,__tmp_reg__));
1952         }
1953       else if (GET_CODE (src) == MEM)
1954         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1955     }
1956   else if (GET_CODE (dest) == MEM)
1957     {
1958       const char *templ;
1959
1960       if (src == const0_rtx)
1961         operands[1] = zero_reg_rtx;
1962
1963       templ = out_movqi_mr_r (insn, operands, real_l);
1964
1965       if (!real_l)
1966         output_asm_insn (templ, operands);
1967
1968       operands[1] = src;
1969     }
1970   return "";
1971 }
1972
1973
1974 const char *
1975 output_movhi (rtx insn, rtx operands[], int *l)
1976 {
1977   int dummy;
1978   rtx dest = operands[0];
1979   rtx src = operands[1];
1980   int *real_l = l;
1981   
1982   if (!l)
1983     l = &dummy;
1984   
1985   if (register_operand (dest, HImode))
1986     {
1987       if (register_operand (src, HImode)) /* mov r,r */
1988         {
1989           if (test_hard_reg_class (STACK_REG, dest))
1990             {
1991               if (AVR_HAVE_8BIT_SP)
1992                 return *l = 1, AS2 (out,__SP_L__,%A1);
1993               /* Use simple load of stack pointer if no interrupts are 
1994                  used.  */
1995               else if (TARGET_NO_INTERRUPTS)
1996                 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
1997                                 AS2 (out,__SP_L__,%A1));
1998               *l = 5;
1999               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
2000                       "cli"                          CR_TAB
2001                       AS2 (out,__SP_H__,%B1)         CR_TAB
2002                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
2003                       AS2 (out,__SP_L__,%A1));
2004             }
2005           else if (test_hard_reg_class (STACK_REG, src))
2006             {
2007               *l = 2;   
2008               return (AS2 (in,%A0,__SP_L__) CR_TAB
2009                       AS2 (in,%B0,__SP_H__));
2010             }
2011
2012           if (AVR_HAVE_MOVW)
2013             {
2014               *l = 1;
2015               return (AS2 (movw,%0,%1));
2016             }
2017           else
2018             {
2019               *l = 2;
2020               return (AS2 (mov,%A0,%A1) CR_TAB
2021                       AS2 (mov,%B0,%B1));
2022             }
2023         }
2024       else if (CONSTANT_P (src))
2025         {
2026           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2027             {
2028               *l = 2;
2029               return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
2030                       AS2 (ldi,%B0,hi8(%1)));
2031             }
2032           
2033           if (GET_CODE (src) == CONST_INT)
2034             {
2035               if (src == const0_rtx) /* mov r,L */
2036                 {
2037                   *l = 2;
2038                   return (AS1 (clr,%A0) CR_TAB
2039                           AS1 (clr,%B0));
2040                 }
2041               else if (src == const1_rtx)
2042                 {
2043                   *l = 3;
2044                   return (AS1 (clr,%A0) CR_TAB
2045                           AS1 (clr,%B0) CR_TAB
2046                           AS1 (inc,%A0));
2047                 }
2048               else if (src == constm1_rtx)
2049                 {
2050                   /* Immediate constants -1 to any register */
2051                   *l = 3;
2052                   return (AS1 (clr,%0)  CR_TAB
2053                           AS1 (dec,%A0) CR_TAB
2054                           AS2 (mov,%B0,%A0));
2055                 }
2056               else
2057                 {
2058                   int bit_nr = exact_log2 (INTVAL (src));
2059
2060                   if (bit_nr >= 0)
2061                     {
2062                       *l = 4;
2063                       if (!real_l)
2064                         output_asm_insn ((AS1 (clr,%A0) CR_TAB
2065                                           AS1 (clr,%B0) CR_TAB
2066                                           "set"), operands);
2067                       if (!real_l)
2068                         avr_output_bld (operands, bit_nr);
2069
2070                       return "";
2071                     }
2072                 }
2073
2074               if ((INTVAL (src) & 0xff) == 0)
2075                 {
2076                   *l = 5;
2077                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2078                           AS1 (clr,%A0)             CR_TAB
2079                           AS2 (ldi,r31,hi8(%1))     CR_TAB
2080                           AS2 (mov,%B0,r31)         CR_TAB
2081                           AS2 (mov,r31,__tmp_reg__));
2082                 }
2083               else if ((INTVAL (src) & 0xff00) == 0)
2084                 {
2085                   *l = 5;
2086                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2087                           AS2 (ldi,r31,lo8(%1))     CR_TAB
2088                           AS2 (mov,%A0,r31)         CR_TAB
2089                           AS1 (clr,%B0)             CR_TAB
2090                           AS2 (mov,r31,__tmp_reg__));
2091                 }
2092             }
2093           
2094           /* Last resort, equal to loading from memory.  */
2095           *l = 6;
2096           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2097                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2098                   AS2 (mov,%A0,r31)         CR_TAB
2099                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2100                   AS2 (mov,%B0,r31)         CR_TAB
2101                   AS2 (mov,r31,__tmp_reg__));
2102         }
2103       else if (GET_CODE (src) == MEM)
2104         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
2105     }
2106   else if (GET_CODE (dest) == MEM)
2107     {
2108       const char *templ;
2109
2110       if (src == const0_rtx)
2111         operands[1] = zero_reg_rtx;
2112
2113       templ = out_movhi_mr_r (insn, operands, real_l);
2114
2115       if (!real_l)
2116         output_asm_insn (templ, operands);
2117
2118       operands[1] = src;
2119       return "";
2120     }
2121   fatal_insn ("invalid insn:", insn);
2122   return "";
2123 }
2124
2125 const char *
2126 out_movqi_r_mr (rtx insn, rtx op[], int *l)
2127 {
2128   rtx dest = op[0];
2129   rtx src = op[1];
2130   rtx x = XEXP (src, 0);
2131   int dummy;
2132   
2133   if (!l)
2134     l = &dummy;
2135   
2136   if (CONSTANT_ADDRESS_P (x))
2137     {
2138       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2139         {
2140           *l = 1;
2141           return AS2 (in,%0,__SREG__);
2142         }
2143       if (optimize > 0 && io_address_operand (x, QImode))
2144         {
2145           *l = 1;
2146           return AS2 (in,%0,%m1-0x20);
2147         }
2148       *l = 2;
2149       return AS2 (lds,%0,%m1);
2150     }
2151   /* memory access by reg+disp */
2152   else if (GET_CODE (x) == PLUS
2153       && REG_P (XEXP (x,0))
2154       && GET_CODE (XEXP (x,1)) == CONST_INT)
2155     {
2156       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
2157         {
2158           int disp = INTVAL (XEXP (x,1));
2159           if (REGNO (XEXP (x,0)) != REG_Y)
2160             fatal_insn ("incorrect insn:",insn);
2161
2162           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2163             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
2164                             AS2 (ldd,%0,Y+63)     CR_TAB
2165                             AS2 (sbiw,r28,%o1-63));
2166
2167           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2168                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2169                           AS2 (ld,%0,Y)            CR_TAB
2170                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2171                           AS2 (sbci,r29,hi8(%o1)));
2172         }
2173       else if (REGNO (XEXP (x,0)) == REG_X)
2174         {
2175           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2176              it but I have this situation with extremal optimizing options.  */
2177           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
2178               || reg_unused_after (insn, XEXP (x,0)))
2179             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
2180                             AS2 (ld,%0,X));
2181
2182           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
2183                           AS2 (ld,%0,X)      CR_TAB
2184                           AS2 (sbiw,r26,%o1));
2185         }
2186       *l = 1;
2187       return AS2 (ldd,%0,%1);
2188     }
2189   *l = 1;
2190   return AS2 (ld,%0,%1);
2191 }
2192
2193 const char *
2194 out_movhi_r_mr (rtx insn, rtx op[], int *l)
2195 {
2196   rtx dest = op[0];
2197   rtx src = op[1];
2198   rtx base = XEXP (src, 0);
2199   int reg_dest = true_regnum (dest);
2200   int reg_base = true_regnum (base);
2201   /* "volatile" forces reading low byte first, even if less efficient,
2202      for correct operation with 16-bit I/O registers.  */
2203   int mem_volatile_p = MEM_VOLATILE_P (src);
2204   int tmp;
2205
2206   if (!l)
2207     l = &tmp;
2208
2209   if (reg_base > 0)
2210     {
2211       if (reg_dest == reg_base)         /* R = (R) */
2212         {
2213           *l = 3;
2214           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
2215                   AS2 (ld,%B0,%1) CR_TAB
2216                   AS2 (mov,%A0,__tmp_reg__));
2217         }
2218       else if (reg_base == REG_X)        /* (R26) */
2219         {
2220           if (reg_unused_after (insn, base))
2221             {
2222               *l = 2;
2223               return (AS2 (ld,%A0,X+) CR_TAB
2224                       AS2 (ld,%B0,X));
2225             }
2226           *l  = 3;
2227           return (AS2 (ld,%A0,X+) CR_TAB
2228                   AS2 (ld,%B0,X) CR_TAB
2229                   AS2 (sbiw,r26,1));
2230         }
2231       else                      /* (R)  */
2232         {
2233           *l = 2;
2234           return (AS2 (ld,%A0,%1)    CR_TAB
2235                   AS2 (ldd,%B0,%1+1));
2236         }
2237     }
2238   else if (GET_CODE (base) == PLUS) /* (R + i) */
2239     {
2240       int disp = INTVAL (XEXP (base, 1));
2241       int reg_base = true_regnum (XEXP (base, 0));
2242       
2243       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2244         {
2245           if (REGNO (XEXP (base, 0)) != REG_Y)
2246             fatal_insn ("incorrect insn:",insn);
2247           
2248           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2249             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
2250                             AS2 (ldd,%A0,Y+62)    CR_TAB
2251                             AS2 (ldd,%B0,Y+63)    CR_TAB
2252                             AS2 (sbiw,r28,%o1-62));
2253
2254           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2255                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2256                           AS2 (ld,%A0,Y)           CR_TAB
2257                           AS2 (ldd,%B0,Y+1)        CR_TAB
2258                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2259                           AS2 (sbci,r29,hi8(%o1)));
2260         }
2261       if (reg_base == REG_X)
2262         {
2263           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
2264              it but I have this situation with extremal
2265              optimization options.  */
2266           
2267           *l = 4;
2268           if (reg_base == reg_dest)
2269             return (AS2 (adiw,r26,%o1)      CR_TAB
2270                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2271                     AS2 (ld,%B0,X)          CR_TAB
2272                     AS2 (mov,%A0,__tmp_reg__));
2273
2274           return (AS2 (adiw,r26,%o1) CR_TAB
2275                   AS2 (ld,%A0,X+)    CR_TAB
2276                   AS2 (ld,%B0,X)     CR_TAB
2277                   AS2 (sbiw,r26,%o1+1));
2278         }
2279
2280       if (reg_base == reg_dest)
2281         {
2282           *l = 3;
2283           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2284                   AS2 (ldd,%B0,%B1)         CR_TAB
2285                   AS2 (mov,%A0,__tmp_reg__));
2286         }
2287       
2288       *l = 2;
2289       return (AS2 (ldd,%A0,%A1) CR_TAB
2290               AS2 (ldd,%B0,%B1));
2291     }
2292   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2293     {
2294       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2295         fatal_insn ("incorrect insn:", insn);
2296
2297       if (mem_volatile_p)
2298         {
2299           if (REGNO (XEXP (base, 0)) == REG_X)
2300             {
2301               *l = 4;
2302               return (AS2 (sbiw,r26,2)  CR_TAB
2303                       AS2 (ld,%A0,X+)   CR_TAB
2304                       AS2 (ld,%B0,X)    CR_TAB
2305                       AS2 (sbiw,r26,1));
2306             }
2307           else
2308             {
2309               *l = 3;
2310               return (AS2 (sbiw,%r1,2)   CR_TAB
2311                       AS2 (ld,%A0,%p1)  CR_TAB
2312                       AS2 (ldd,%B0,%p1+1));
2313             }
2314         }
2315
2316       *l = 2;
2317       return (AS2 (ld,%B0,%1) CR_TAB
2318               AS2 (ld,%A0,%1));
2319     }
2320   else if (GET_CODE (base) == POST_INC) /* (R++) */
2321     {
2322       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2323         fatal_insn ("incorrect insn:", insn);
2324
2325       *l = 2;
2326       return (AS2 (ld,%A0,%1)  CR_TAB
2327               AS2 (ld,%B0,%1));
2328     }
2329   else if (CONSTANT_ADDRESS_P (base))
2330     {
2331       if (optimize > 0 && io_address_operand (base, HImode))
2332         {
2333           *l = 2;
2334           return (AS2 (in,%A0,%m1-0x20) CR_TAB
2335                   AS2 (in,%B0,%m1+1-0x20));
2336         }
2337       *l = 4;
2338       return (AS2 (lds,%A0,%m1) CR_TAB
2339               AS2 (lds,%B0,%m1+1));
2340     }
2341   
2342   fatal_insn ("unknown move insn:",insn);
2343   return "";
2344 }
2345
2346 const char *
2347 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2348 {
2349   rtx dest = op[0];
2350   rtx src = op[1];
2351   rtx base = XEXP (src, 0);
2352   int reg_dest = true_regnum (dest);
2353   int reg_base = true_regnum (base);
2354   int tmp;
2355
2356   if (!l)
2357     l = &tmp;
2358   
2359   if (reg_base > 0)
2360     {
2361       if (reg_base == REG_X)        /* (R26) */
2362         {
2363           if (reg_dest == REG_X)
2364             /* "ld r26,-X" is undefined */
2365             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
2366                           AS2 (ld,r29,X)          CR_TAB
2367                           AS2 (ld,r28,-X)         CR_TAB
2368                           AS2 (ld,__tmp_reg__,-X) CR_TAB
2369                           AS2 (sbiw,r26,1)        CR_TAB
2370                           AS2 (ld,r26,X)          CR_TAB
2371                           AS2 (mov,r27,__tmp_reg__));
2372           else if (reg_dest == REG_X - 2)
2373             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2374                           AS2 (ld,%B0,X+) CR_TAB
2375                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
2376                           AS2 (ld,%D0,X)  CR_TAB
2377                           AS2 (mov,%C0,__tmp_reg__));
2378           else if (reg_unused_after (insn, base))
2379             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
2380                            AS2 (ld,%B0,X+) CR_TAB
2381                            AS2 (ld,%C0,X+) CR_TAB
2382                            AS2 (ld,%D0,X));
2383           else
2384             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2385                            AS2 (ld,%B0,X+) CR_TAB
2386                            AS2 (ld,%C0,X+) CR_TAB
2387                            AS2 (ld,%D0,X)  CR_TAB
2388                            AS2 (sbiw,r26,3));
2389         }
2390       else
2391         {
2392           if (reg_dest == reg_base)
2393             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2394                           AS2 (ldd,%C0,%1+2) CR_TAB
2395                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
2396                           AS2 (ld,%A0,%1)  CR_TAB
2397                           AS2 (mov,%B0,__tmp_reg__));
2398           else if (reg_base == reg_dest + 2)
2399             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2400                           AS2 (ldd,%B0,%1+1) CR_TAB
2401                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2402                           AS2 (ldd,%D0,%1+3) CR_TAB
2403                           AS2 (mov,%C0,__tmp_reg__));
2404           else
2405             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2406                           AS2 (ldd,%B0,%1+1) CR_TAB
2407                           AS2 (ldd,%C0,%1+2) CR_TAB
2408                           AS2 (ldd,%D0,%1+3));
2409         }
2410     }
2411   else if (GET_CODE (base) == PLUS) /* (R + i) */
2412     {
2413       int disp = INTVAL (XEXP (base, 1));
2414       
2415       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2416         {
2417           if (REGNO (XEXP (base, 0)) != REG_Y)
2418             fatal_insn ("incorrect insn:",insn);
2419
2420           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2421             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2422                             AS2 (ldd,%A0,Y+60)    CR_TAB
2423                             AS2 (ldd,%B0,Y+61)    CR_TAB
2424                             AS2 (ldd,%C0,Y+62)    CR_TAB
2425                             AS2 (ldd,%D0,Y+63)    CR_TAB
2426                             AS2 (sbiw,r28,%o1-60));
2427
2428           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2429                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2430                           AS2 (ld,%A0,Y)           CR_TAB
2431                           AS2 (ldd,%B0,Y+1)        CR_TAB
2432                           AS2 (ldd,%C0,Y+2)        CR_TAB
2433                           AS2 (ldd,%D0,Y+3)        CR_TAB
2434                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2435                           AS2 (sbci,r29,hi8(%o1)));
2436         }
2437
2438       reg_base = true_regnum (XEXP (base, 0));
2439       if (reg_base == REG_X)
2440         {
2441           /* R = (X + d) */
2442           if (reg_dest == REG_X)
2443             {
2444               *l = 7;
2445               /* "ld r26,-X" is undefined */
2446               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2447                       AS2 (ld,r29,X)          CR_TAB
2448                       AS2 (ld,r28,-X)         CR_TAB
2449                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2450                       AS2 (sbiw,r26,1)        CR_TAB
2451                       AS2 (ld,r26,X)          CR_TAB
2452                       AS2 (mov,r27,__tmp_reg__));
2453             }
2454           *l = 6;
2455           if (reg_dest == REG_X - 2)
2456             return (AS2 (adiw,r26,%o1)      CR_TAB
2457                     AS2 (ld,r24,X+)         CR_TAB
2458                     AS2 (ld,r25,X+)         CR_TAB
2459                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2460                     AS2 (ld,r27,X)          CR_TAB
2461                     AS2 (mov,r26,__tmp_reg__));
2462
2463           return (AS2 (adiw,r26,%o1) CR_TAB
2464                   AS2 (ld,%A0,X+)    CR_TAB
2465                   AS2 (ld,%B0,X+)    CR_TAB
2466                   AS2 (ld,%C0,X+)    CR_TAB
2467                   AS2 (ld,%D0,X)     CR_TAB
2468                   AS2 (sbiw,r26,%o1+3));
2469         }
2470       if (reg_dest == reg_base)
2471         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2472                       AS2 (ldd,%C0,%C1) CR_TAB
2473                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2474                       AS2 (ldd,%A0,%A1) CR_TAB
2475                       AS2 (mov,%B0,__tmp_reg__));
2476       else if (reg_dest == reg_base - 2)
2477         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2478                       AS2 (ldd,%B0,%B1) CR_TAB
2479                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2480                       AS2 (ldd,%D0,%D1) CR_TAB
2481                       AS2 (mov,%C0,__tmp_reg__));
2482       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2483                     AS2 (ldd,%B0,%B1) CR_TAB
2484                     AS2 (ldd,%C0,%C1) CR_TAB
2485                     AS2 (ldd,%D0,%D1));
2486     }
2487   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2488     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2489                   AS2 (ld,%C0,%1) CR_TAB
2490                   AS2 (ld,%B0,%1) CR_TAB
2491                   AS2 (ld,%A0,%1));
2492   else if (GET_CODE (base) == POST_INC) /* (R++) */
2493     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2494                   AS2 (ld,%B0,%1) CR_TAB
2495                   AS2 (ld,%C0,%1) CR_TAB
2496                   AS2 (ld,%D0,%1));
2497   else if (CONSTANT_ADDRESS_P (base))
2498       return *l=8, (AS2 (lds,%A0,%m1) CR_TAB
2499                     AS2 (lds,%B0,%m1+1) CR_TAB
2500                     AS2 (lds,%C0,%m1+2) CR_TAB
2501                     AS2 (lds,%D0,%m1+3));
2502     
2503   fatal_insn ("unknown move insn:",insn);
2504   return "";
2505 }
2506
2507 const char *
2508 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2509 {
2510   rtx dest = op[0];
2511   rtx src = op[1];
2512   rtx base = XEXP (dest, 0);
2513   int reg_base = true_regnum (base);
2514   int reg_src = true_regnum (src);
2515   int tmp;
2516   
2517   if (!l)
2518     l = &tmp;
2519   
2520   if (CONSTANT_ADDRESS_P (base))
2521     return *l=8,(AS2 (sts,%m0,%A1) CR_TAB
2522                  AS2 (sts,%m0+1,%B1) CR_TAB
2523                  AS2 (sts,%m0+2,%C1) CR_TAB
2524                  AS2 (sts,%m0+3,%D1));
2525   if (reg_base > 0)                 /* (r) */
2526     {
2527       if (reg_base == REG_X)                /* (R26) */
2528         {
2529           if (reg_src == REG_X)
2530             {
2531               /* "st X+,r26" is undefined */
2532               if (reg_unused_after (insn, base))
2533                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2534                               AS2 (st,X,r26)            CR_TAB
2535                               AS2 (adiw,r26,1)          CR_TAB
2536                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2537                               AS2 (st,X+,r28)           CR_TAB
2538                               AS2 (st,X,r29));
2539               else
2540                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2541                               AS2 (st,X,r26)            CR_TAB
2542                               AS2 (adiw,r26,1)          CR_TAB
2543                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2544                               AS2 (st,X+,r28)           CR_TAB
2545                               AS2 (st,X,r29)            CR_TAB
2546                               AS2 (sbiw,r26,3));
2547             }
2548           else if (reg_base == reg_src + 2)
2549             {
2550               if (reg_unused_after (insn, base))
2551                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2552                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2553                               AS2 (st,%0+,%A1) CR_TAB
2554                               AS2 (st,%0+,%B1) CR_TAB
2555                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2556                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2557                               AS1 (clr,__zero_reg__));
2558               else
2559                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2560                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2561                               AS2 (st,%0+,%A1) CR_TAB
2562                               AS2 (st,%0+,%B1) CR_TAB
2563                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2564                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2565                               AS1 (clr,__zero_reg__)     CR_TAB
2566                               AS2 (sbiw,r26,3));
2567             }
2568           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2569                         AS2 (st,%0+,%B1) CR_TAB
2570                         AS2 (st,%0+,%C1) CR_TAB
2571                         AS2 (st,%0,%D1)  CR_TAB
2572                         AS2 (sbiw,r26,3));
2573         }
2574       else
2575         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2576                       AS2 (std,%0+1,%B1) CR_TAB
2577                       AS2 (std,%0+2,%C1) CR_TAB
2578                       AS2 (std,%0+3,%D1));
2579     }
2580   else if (GET_CODE (base) == PLUS) /* (R + i) */
2581     {
2582       int disp = INTVAL (XEXP (base, 1));
2583       reg_base = REGNO (XEXP (base, 0));
2584       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2585         {
2586           if (reg_base != REG_Y)
2587             fatal_insn ("incorrect insn:",insn);
2588
2589           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2590             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2591                             AS2 (std,Y+60,%A1)    CR_TAB
2592                             AS2 (std,Y+61,%B1)    CR_TAB
2593                             AS2 (std,Y+62,%C1)    CR_TAB
2594                             AS2 (std,Y+63,%D1)    CR_TAB
2595                             AS2 (sbiw,r28,%o0-60));
2596
2597           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2598                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2599                           AS2 (st,Y,%A1)           CR_TAB
2600                           AS2 (std,Y+1,%B1)        CR_TAB
2601                           AS2 (std,Y+2,%C1)        CR_TAB
2602                           AS2 (std,Y+3,%D1)        CR_TAB
2603                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2604                           AS2 (sbci,r29,hi8(%o0)));
2605         }
2606       if (reg_base == REG_X)
2607         {
2608           /* (X + d) = R */
2609           if (reg_src == REG_X)
2610             {
2611               *l = 9;
2612               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2613                       AS2 (mov,__zero_reg__,r27) CR_TAB
2614                       AS2 (adiw,r26,%o0)         CR_TAB
2615                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2616                       AS2 (st,X+,__zero_reg__)   CR_TAB
2617                       AS2 (st,X+,r28)            CR_TAB
2618                       AS2 (st,X,r29)             CR_TAB
2619                       AS1 (clr,__zero_reg__)     CR_TAB
2620                       AS2 (sbiw,r26,%o0+3));
2621             }
2622           else if (reg_src == REG_X - 2)
2623             {
2624               *l = 9;
2625               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2626                       AS2 (mov,__zero_reg__,r27) CR_TAB
2627                       AS2 (adiw,r26,%o0)         CR_TAB
2628                       AS2 (st,X+,r24)            CR_TAB
2629                       AS2 (st,X+,r25)            CR_TAB
2630                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2631                       AS2 (st,X,__zero_reg__)    CR_TAB
2632                       AS1 (clr,__zero_reg__)     CR_TAB
2633                       AS2 (sbiw,r26,%o0+3));
2634             }
2635           *l = 6;
2636           return (AS2 (adiw,r26,%o0) CR_TAB
2637                   AS2 (st,X+,%A1)    CR_TAB
2638                   AS2 (st,X+,%B1)    CR_TAB
2639                   AS2 (st,X+,%C1)    CR_TAB
2640                   AS2 (st,X,%D1)     CR_TAB
2641                   AS2 (sbiw,r26,%o0+3));
2642         }
2643       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2644                     AS2 (std,%B0,%B1) CR_TAB
2645                     AS2 (std,%C0,%C1) CR_TAB
2646                     AS2 (std,%D0,%D1));
2647     }
2648   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2649     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2650                   AS2 (st,%0,%C1) CR_TAB
2651                   AS2 (st,%0,%B1) CR_TAB
2652                   AS2 (st,%0,%A1));
2653   else if (GET_CODE (base) == POST_INC) /* (R++) */
2654     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2655                   AS2 (st,%0,%B1) CR_TAB
2656                   AS2 (st,%0,%C1) CR_TAB
2657                   AS2 (st,%0,%D1));
2658   fatal_insn ("unknown move insn:",insn);
2659   return "";
2660 }
2661
2662 const char *
2663 output_movsisf(rtx insn, rtx operands[], int *l)
2664 {
2665   int dummy;
2666   rtx dest = operands[0];
2667   rtx src = operands[1];
2668   int *real_l = l;
2669   
2670   if (!l)
2671     l = &dummy;
2672   
2673   if (register_operand (dest, VOIDmode))
2674     {
2675       if (register_operand (src, VOIDmode)) /* mov r,r */
2676         {
2677           if (true_regnum (dest) > true_regnum (src))
2678             {
2679               if (AVR_HAVE_MOVW)
2680                 {
2681                   *l = 2;
2682                   return (AS2 (movw,%C0,%C1) CR_TAB
2683                           AS2 (movw,%A0,%A1));
2684                 }
2685               *l = 4;
2686               return (AS2 (mov,%D0,%D1) CR_TAB
2687                       AS2 (mov,%C0,%C1) CR_TAB
2688                       AS2 (mov,%B0,%B1) CR_TAB
2689                       AS2 (mov,%A0,%A1));
2690             }
2691           else
2692             {
2693               if (AVR_HAVE_MOVW)
2694                 {
2695                   *l = 2;
2696                   return (AS2 (movw,%A0,%A1) CR_TAB
2697                           AS2 (movw,%C0,%C1));
2698                 }
2699               *l = 4;
2700               return (AS2 (mov,%A0,%A1) CR_TAB
2701                       AS2 (mov,%B0,%B1) CR_TAB
2702                       AS2 (mov,%C0,%C1) CR_TAB
2703                       AS2 (mov,%D0,%D1));
2704             }
2705         }
2706       else if (CONSTANT_P (src))
2707         {
2708           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2709             {
2710               *l = 4;
2711               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2712                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2713                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2714                       AS2 (ldi,%D0,hhi8(%1)));
2715             }
2716           
2717           if (GET_CODE (src) == CONST_INT)
2718             {
2719               const char *const clr_op0 =
2720                 AVR_HAVE_MOVW ? (AS1 (clr,%A0) CR_TAB
2721                                 AS1 (clr,%B0) CR_TAB
2722                                 AS2 (movw,%C0,%A0))
2723                              : (AS1 (clr,%A0) CR_TAB
2724                                 AS1 (clr,%B0) CR_TAB
2725                                 AS1 (clr,%C0) CR_TAB
2726                                 AS1 (clr,%D0));
2727
2728               if (src == const0_rtx) /* mov r,L */
2729                 {
2730                   *l = AVR_HAVE_MOVW ? 3 : 4;
2731                   return clr_op0;
2732                 }
2733               else if (src == const1_rtx)
2734                 {
2735                   if (!real_l)
2736                     output_asm_insn (clr_op0, operands);
2737                   *l = AVR_HAVE_MOVW ? 4 : 5;
2738                   return AS1 (inc,%A0);
2739                 }
2740               else if (src == constm1_rtx)
2741                 {
2742                   /* Immediate constants -1 to any register */
2743                   if (AVR_HAVE_MOVW)
2744                     {
2745                       *l = 4;
2746                       return (AS1 (clr,%A0)     CR_TAB
2747                               AS1 (dec,%A0)     CR_TAB
2748                               AS2 (mov,%B0,%A0) CR_TAB
2749                               AS2 (movw,%C0,%A0));
2750                     }
2751                   *l = 5;
2752                   return (AS1 (clr,%A0)     CR_TAB
2753                           AS1 (dec,%A0)     CR_TAB
2754                           AS2 (mov,%B0,%A0) CR_TAB
2755                           AS2 (mov,%C0,%A0) CR_TAB
2756                           AS2 (mov,%D0,%A0));
2757                 }
2758               else
2759                 {
2760                   int bit_nr = exact_log2 (INTVAL (src));
2761
2762                   if (bit_nr >= 0)
2763                     {
2764                       *l = AVR_HAVE_MOVW ? 5 : 6;
2765                       if (!real_l)
2766                         {
2767                           output_asm_insn (clr_op0, operands);
2768                           output_asm_insn ("set", operands);
2769                         }
2770                       if (!real_l)
2771                         avr_output_bld (operands, bit_nr);
2772
2773                       return "";
2774                     }
2775                 }
2776             }
2777           
2778           /* Last resort, better than loading from memory.  */
2779           *l = 10;
2780           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2781                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2782                   AS2 (mov,%A0,r31)         CR_TAB
2783                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2784                   AS2 (mov,%B0,r31)         CR_TAB
2785                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2786                   AS2 (mov,%C0,r31)         CR_TAB
2787                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2788                   AS2 (mov,%D0,r31)         CR_TAB
2789                   AS2 (mov,r31,__tmp_reg__));
2790         }
2791       else if (GET_CODE (src) == MEM)
2792         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2793     }
2794   else if (GET_CODE (dest) == MEM)
2795     {
2796       const char *templ;
2797
2798       if (src == const0_rtx)
2799           operands[1] = zero_reg_rtx;
2800
2801       templ = out_movsi_mr_r (insn, operands, real_l);
2802
2803       if (!real_l)
2804         output_asm_insn (templ, operands);
2805
2806       operands[1] = src;
2807       return "";
2808     }
2809   fatal_insn ("invalid insn:", insn);
2810   return "";
2811 }
2812
2813 const char *
2814 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2815 {
2816   rtx dest = op[0];
2817   rtx src = op[1];
2818   rtx x = XEXP (dest, 0);
2819   int dummy;
2820
2821   if (!l)
2822     l = &dummy;
2823   
2824   if (CONSTANT_ADDRESS_P (x))
2825     {
2826       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2827         {
2828           *l = 1;
2829           return AS2 (out,__SREG__,%1);
2830         }
2831       if (optimize > 0 && io_address_operand (x, QImode))
2832         {
2833           *l = 1;
2834           return AS2 (out,%m0-0x20,%1);
2835         }
2836       *l = 2;
2837       return AS2 (sts,%m0,%1);
2838     }
2839   /* memory access by reg+disp */
2840   else if (GET_CODE (x) == PLUS 
2841       && REG_P (XEXP (x,0))
2842       && GET_CODE (XEXP (x,1)) == CONST_INT)
2843     {
2844       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2845         {
2846           int disp = INTVAL (XEXP (x,1));
2847           if (REGNO (XEXP (x,0)) != REG_Y)
2848             fatal_insn ("incorrect insn:",insn);
2849
2850           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2851             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2852                             AS2 (std,Y+63,%1)     CR_TAB
2853                             AS2 (sbiw,r28,%o0-63));
2854
2855           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2856                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2857                           AS2 (st,Y,%1)            CR_TAB
2858                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2859                           AS2 (sbci,r29,hi8(%o0)));
2860         }
2861       else if (REGNO (XEXP (x,0)) == REG_X)
2862         {
2863           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2864             {
2865               if (reg_unused_after (insn, XEXP (x,0)))
2866                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2867                                 AS2 (adiw,r26,%o0)       CR_TAB
2868                                 AS2 (st,X,__tmp_reg__));
2869
2870               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2871                               AS2 (adiw,r26,%o0)       CR_TAB
2872                               AS2 (st,X,__tmp_reg__)   CR_TAB
2873                               AS2 (sbiw,r26,%o0));
2874             }
2875           else
2876             {
2877               if (reg_unused_after (insn, XEXP (x,0)))
2878                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2879                                 AS2 (st,X,%1));
2880
2881               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2882                               AS2 (st,X,%1)      CR_TAB
2883                               AS2 (sbiw,r26,%o0));
2884             }
2885         }
2886       *l = 1;
2887       return AS2 (std,%0,%1);
2888     }
2889   *l = 1;
2890   return AS2 (st,%0,%1);
2891 }
2892
2893 const char *
2894 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2895 {
2896   rtx dest = op[0];
2897   rtx src = op[1];
2898   rtx base = XEXP (dest, 0);
2899   int reg_base = true_regnum (base);
2900   int reg_src = true_regnum (src);
2901   /* "volatile" forces writing high byte first, even if less efficient,
2902      for correct operation with 16-bit I/O registers.  */
2903   int mem_volatile_p = MEM_VOLATILE_P (dest);
2904   int tmp;
2905
2906   if (!l)
2907     l = &tmp;
2908   if (CONSTANT_ADDRESS_P (base))
2909     {
2910       if (optimize > 0 && io_address_operand (base, HImode))
2911         {
2912           *l = 2;
2913           return (AS2 (out,%m0+1-0x20,%B1) CR_TAB
2914                   AS2 (out,%m0-0x20,%A1));
2915         }
2916       return *l = 4, (AS2 (sts,%m0+1,%B1) CR_TAB
2917                       AS2 (sts,%m0,%A1));
2918     }
2919   if (reg_base > 0)
2920     {
2921       if (reg_base == REG_X)
2922         {
2923           if (reg_src == REG_X)
2924             {
2925               /* "st X+,r26" and "st -X,r26" are undefined.  */
2926               if (!mem_volatile_p && reg_unused_after (insn, src))
2927                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2928                               AS2 (st,X,r26)            CR_TAB
2929                               AS2 (adiw,r26,1)          CR_TAB
2930                               AS2 (st,X,__tmp_reg__));
2931               else
2932                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2933                               AS2 (adiw,r26,1)          CR_TAB
2934                               AS2 (st,X,__tmp_reg__)    CR_TAB
2935                               AS2 (sbiw,r26,1)          CR_TAB
2936                               AS2 (st,X,r26));
2937             }
2938           else
2939             {
2940               if (!mem_volatile_p && reg_unused_after (insn, base))
2941                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2942                               AS2 (st,X,%B1));
2943               else
2944                 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2945                               AS2 (st,X,%B1)   CR_TAB
2946                               AS2 (st,-X,%A1));
2947             }
2948         }
2949       else
2950         return  *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2951                        AS2 (st,%0,%A1));
2952     }
2953   else if (GET_CODE (base) == PLUS)
2954     {
2955       int disp = INTVAL (XEXP (base, 1));
2956       reg_base = REGNO (XEXP (base, 0));
2957       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2958         {
2959           if (reg_base != REG_Y)
2960             fatal_insn ("incorrect insn:",insn);
2961
2962           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2963             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2964                             AS2 (std,Y+63,%B1)    CR_TAB
2965                             AS2 (std,Y+62,%A1)    CR_TAB
2966                             AS2 (sbiw,r28,%o0-62));
2967
2968           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2969                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2970                           AS2 (std,Y+1,%B1)        CR_TAB
2971                           AS2 (st,Y,%A1)           CR_TAB
2972                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2973                           AS2 (sbci,r29,hi8(%o0)));
2974         }
2975       if (reg_base == REG_X)
2976         {
2977           /* (X + d) = R */
2978           if (reg_src == REG_X)
2979             {
2980               *l = 7;
2981               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2982                       AS2 (mov,__zero_reg__,r27) CR_TAB
2983                       AS2 (adiw,r26,%o0+1)       CR_TAB
2984                       AS2 (st,X,__zero_reg__)    CR_TAB
2985                       AS2 (st,-X,__tmp_reg__)    CR_TAB
2986                       AS1 (clr,__zero_reg__)     CR_TAB
2987                       AS2 (sbiw,r26,%o0));
2988             }
2989           *l = 4;
2990           return (AS2 (adiw,r26,%o0+1) CR_TAB
2991                   AS2 (st,X,%B1)       CR_TAB
2992                   AS2 (st,-X,%A1)      CR_TAB
2993                   AS2 (sbiw,r26,%o0));
2994         }
2995       return *l=2, (AS2 (std,%B0,%B1)    CR_TAB
2996                     AS2 (std,%A0,%A1));
2997     }
2998   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2999     return *l=2, (AS2 (st,%0,%B1) CR_TAB
3000                   AS2 (st,%0,%A1));
3001   else if (GET_CODE (base) == POST_INC) /* (R++) */
3002     {
3003       if (mem_volatile_p)
3004         {
3005           if (REGNO (XEXP (base, 0)) == REG_X)
3006             {
3007               *l = 4;
3008               return (AS2 (adiw,r26,1)  CR_TAB
3009                       AS2 (st,X,%B1)    CR_TAB
3010                       AS2 (st,-X,%A1)   CR_TAB
3011                       AS2 (adiw,r26,2));
3012             }
3013           else
3014             {
3015               *l = 3;
3016               return (AS2 (std,%p0+1,%B1) CR_TAB
3017                       AS2 (st,%p0,%A1)    CR_TAB
3018                       AS2 (adiw,%r0,2));
3019             }
3020         }
3021
3022       *l = 2;
3023       return (AS2 (st,%0,%A1)  CR_TAB
3024             AS2 (st,%0,%B1));
3025     }
3026   fatal_insn ("unknown move insn:",insn);
3027   return "";
3028 }
3029
3030 /* Return 1 if frame pointer for current function required.  */
3031
3032 bool
3033 avr_frame_pointer_required_p (void)
3034 {
3035   return (cfun->calls_alloca
3036           || crtl->args.info.nregs == 0
3037           || get_frame_size () > 0);
3038 }
3039
3040 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
3041
3042 static RTX_CODE
3043 compare_condition (rtx insn)
3044 {
3045   rtx next = next_real_insn (insn);
3046   RTX_CODE cond = UNKNOWN;
3047   if (next && GET_CODE (next) == JUMP_INSN)
3048     {
3049       rtx pat = PATTERN (next);
3050       rtx src = SET_SRC (pat);
3051       rtx t = XEXP (src, 0);
3052       cond = GET_CODE (t);
3053     }
3054   return cond;
3055 }
3056
3057 /* Returns nonzero if INSN is a tst insn that only tests the sign.  */
3058
3059 static int
3060 compare_sign_p (rtx insn)
3061 {
3062   RTX_CODE cond = compare_condition (insn);
3063   return (cond == GE || cond == LT);
3064 }
3065
3066 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
3067    that needs to be swapped (GT, GTU, LE, LEU).  */
3068
3069 int
3070 compare_diff_p (rtx insn)
3071 {
3072   RTX_CODE cond = compare_condition (insn);
3073   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
3074 }
3075
3076 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition.  */
3077
3078 int
3079 compare_eq_p (rtx insn)
3080 {
3081   RTX_CODE cond = compare_condition (insn);
3082   return (cond == EQ || cond == NE);
3083 }
3084
3085
3086 /* Output test instruction for HImode.  */
3087
3088 const char *
3089 out_tsthi (rtx insn, rtx op, int *l)
3090 {
3091   if (compare_sign_p (insn))
3092     {
3093       if (l) *l = 1;
3094       return AS1 (tst,%B0);
3095     }
3096   if (reg_unused_after (insn, op)
3097       && compare_eq_p (insn))
3098     {
3099       /* Faster than sbiw if we can clobber the operand.  */
3100       if (l) *l = 1;
3101       return "or %A0,%B0";
3102     }
3103   if (test_hard_reg_class (ADDW_REGS, op))
3104     {
3105       if (l) *l = 1;
3106       return AS2 (sbiw,%0,0);
3107     }
3108   if (l) *l = 2;
3109   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
3110           AS2 (cpc,%B0,__zero_reg__));
3111 }
3112
3113
3114 /* Output test instruction for SImode.  */
3115
3116 const char *
3117 out_tstsi (rtx insn, rtx op, int *l)
3118 {
3119   if (compare_sign_p (insn))
3120     {
3121       if (l) *l = 1;
3122       return AS1 (tst,%D0);
3123     }
3124   if (test_hard_reg_class (ADDW_REGS, op))
3125     {
3126       if (l) *l = 3;
3127       return (AS2 (sbiw,%A0,0) CR_TAB
3128               AS2 (cpc,%C0,__zero_reg__) CR_TAB
3129               AS2 (cpc,%D0,__zero_reg__));
3130     }
3131   if (l) *l = 4;
3132   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
3133           AS2 (cpc,%B0,__zero_reg__) CR_TAB
3134           AS2 (cpc,%C0,__zero_reg__) CR_TAB
3135           AS2 (cpc,%D0,__zero_reg__));
3136 }
3137
3138
3139 /* Generate asm equivalent for various shifts.
3140    Shift count is a CONST_INT, MEM or REG.
3141    This only handles cases that are not already
3142    carefully hand-optimized in ?sh??i3_out.  */
3143
3144 void
3145 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
3146                     int *len, int t_len)
3147 {
3148   rtx op[10];
3149   char str[500];
3150   int second_label = 1;
3151   int saved_in_tmp = 0;
3152   int use_zero_reg = 0;
3153
3154   op[0] = operands[0];
3155   op[1] = operands[1];
3156   op[2] = operands[2];
3157   op[3] = operands[3];
3158   str[0] = 0;
3159
3160   if (len)
3161     *len = 1;
3162
3163   if (GET_CODE (operands[2]) == CONST_INT)
3164     {
3165       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3166       int count = INTVAL (operands[2]);
3167       int max_len = 10;  /* If larger than this, always use a loop.  */
3168
3169       if (count <= 0)
3170         {
3171           if (len)
3172             *len = 0;
3173           return;
3174         }
3175
3176       if (count < 8 && !scratch)
3177         use_zero_reg = 1;
3178
3179       if (optimize_size)
3180         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
3181
3182       if (t_len * count <= max_len)
3183         {
3184           /* Output shifts inline with no loop - faster.  */
3185           if (len)
3186             *len = t_len * count;
3187           else
3188             {
3189               while (count-- > 0)
3190                 output_asm_insn (templ, op);
3191             }
3192
3193           return;
3194         }
3195
3196       if (scratch)
3197         {
3198           if (!len)
3199             strcat (str, AS2 (ldi,%3,%2));
3200         }
3201       else if (use_zero_reg)
3202         {
3203           /* Hack to save one word: use __zero_reg__ as loop counter.
3204              Set one bit, then shift in a loop until it is 0 again.  */
3205
3206           op[3] = zero_reg_rtx;
3207           if (len)
3208             *len = 2;
3209           else
3210             strcat (str, ("set" CR_TAB
3211                           AS2 (bld,%3,%2-1)));
3212         }
3213       else
3214         {
3215           /* No scratch register available, use one from LD_REGS (saved in
3216              __tmp_reg__) that doesn't overlap with registers to shift.  */
3217
3218           op[3] = gen_rtx_REG (QImode,
3219                            ((true_regnum (operands[0]) - 1) & 15) + 16);
3220           op[4] = tmp_reg_rtx;
3221           saved_in_tmp = 1;
3222
3223           if (len)
3224             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
3225           else
3226             strcat (str, (AS2 (mov,%4,%3) CR_TAB
3227                           AS2 (ldi,%3,%2)));
3228         }
3229
3230       second_label = 0;
3231     }
3232   else if (GET_CODE (operands[2]) == MEM)
3233     {
3234       rtx op_mov[10];
3235       
3236       op[3] = op_mov[0] = tmp_reg_rtx;
3237       op_mov[1] = op[2];
3238
3239       if (len)
3240         out_movqi_r_mr (insn, op_mov, len);
3241       else
3242         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
3243     }
3244   else if (register_operand (operands[2], QImode))
3245     {
3246       if (reg_unused_after (insn, operands[2]))
3247         op[3] = op[2];
3248       else
3249         {
3250           op[3] = tmp_reg_rtx;
3251           if (!len)
3252             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
3253         }
3254     }
3255   else
3256     fatal_insn ("bad shift insn:", insn);
3257
3258   if (second_label)
3259     {
3260       if (len)
3261         ++*len;
3262       else
3263         strcat (str, AS1 (rjmp,2f));
3264     }
3265
3266   if (len)
3267     *len += t_len + 2;  /* template + dec + brXX */
3268   else
3269     {
3270       strcat (str, "\n1:\t");
3271       strcat (str, templ);
3272       strcat (str, second_label ? "\n2:\t" : "\n\t");
3273       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3274       strcat (str, CR_TAB);
3275       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3276       if (saved_in_tmp)
3277         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3278       output_asm_insn (str, op);
3279     }
3280 }
3281
3282
3283 /* 8bit shift left ((char)x << i)   */
3284
3285 const char *
3286 ashlqi3_out (rtx insn, rtx operands[], int *len)
3287 {
3288   if (GET_CODE (operands[2]) == CONST_INT)
3289     {
3290       int k;
3291
3292       if (!len)
3293         len = &k;
3294
3295       switch (INTVAL (operands[2]))
3296         {
3297         default:
3298           if (INTVAL (operands[2]) < 8)
3299             break;
3300
3301           *len = 1;
3302           return AS1 (clr,%0);
3303           
3304         case 1:
3305           *len = 1;
3306           return AS1 (lsl,%0);
3307           
3308         case 2:
3309           *len = 2;
3310           return (AS1 (lsl,%0) CR_TAB
3311                   AS1 (lsl,%0));
3312
3313         case 3:
3314           *len = 3;
3315           return (AS1 (lsl,%0) CR_TAB
3316                   AS1 (lsl,%0) CR_TAB
3317                   AS1 (lsl,%0));
3318
3319         case 4:
3320           if (test_hard_reg_class (LD_REGS, operands[0]))
3321             {
3322               *len = 2;
3323               return (AS1 (swap,%0) CR_TAB
3324                       AS2 (andi,%0,0xf0));
3325             }
3326           *len = 4;
3327           return (AS1 (lsl,%0) CR_TAB
3328                   AS1 (lsl,%0) CR_TAB
3329                   AS1 (lsl,%0) CR_TAB
3330                   AS1 (lsl,%0));
3331
3332         case 5:
3333           if (test_hard_reg_class (LD_REGS, operands[0]))
3334             {
3335               *len = 3;
3336               return (AS1 (swap,%0) CR_TAB
3337                       AS1 (lsl,%0)  CR_TAB
3338                       AS2 (andi,%0,0xe0));
3339             }
3340           *len = 5;
3341           return (AS1 (lsl,%0) CR_TAB
3342                   AS1 (lsl,%0) CR_TAB
3343                   AS1 (lsl,%0) CR_TAB
3344                   AS1 (lsl,%0) CR_TAB
3345                   AS1 (lsl,%0));
3346
3347         case 6:
3348           if (test_hard_reg_class (LD_REGS, operands[0]))
3349             {
3350               *len = 4;
3351               return (AS1 (swap,%0) CR_TAB
3352                       AS1 (lsl,%0)  CR_TAB
3353                       AS1 (lsl,%0)  CR_TAB
3354                       AS2 (andi,%0,0xc0));
3355             }
3356           *len = 6;
3357           return (AS1 (lsl,%0) CR_TAB
3358                   AS1 (lsl,%0) CR_TAB
3359                   AS1 (lsl,%0) CR_TAB
3360                   AS1 (lsl,%0) CR_TAB
3361                   AS1 (lsl,%0) CR_TAB
3362                   AS1 (lsl,%0));
3363
3364         case 7:
3365           *len = 3;
3366           return (AS1 (ror,%0) CR_TAB
3367                   AS1 (clr,%0) CR_TAB
3368                   AS1 (ror,%0));
3369         }
3370     }
3371   else if (CONSTANT_P (operands[2]))
3372     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3373
3374   out_shift_with_cnt (AS1 (lsl,%0),
3375                       insn, operands, len, 1);
3376   return "";
3377 }
3378
3379
3380 /* 16bit shift left ((short)x << i)   */
3381
3382 const char *
3383 ashlhi3_out (rtx insn, rtx operands[], int *len)
3384 {
3385   if (GET_CODE (operands[2]) == CONST_INT)
3386     {
3387       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3388       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3389       int k;
3390       int *t = len;
3391
3392       if (!len)
3393         len = &k;
3394       
3395       switch (INTVAL (operands[2]))
3396         {
3397         default:
3398           if (INTVAL (operands[2]) < 16)
3399             break;
3400
3401           *len = 2;
3402           return (AS1 (clr,%B0) CR_TAB
3403                   AS1 (clr,%A0));
3404
3405         case 4:
3406           if (optimize_size && scratch)
3407             break;  /* 5 */
3408           if (ldi_ok)
3409             {
3410               *len = 6;
3411               return (AS1 (swap,%A0)      CR_TAB
3412                       AS1 (swap,%B0)      CR_TAB
3413                       AS2 (andi,%B0,0xf0) CR_TAB
3414                       AS2 (eor,%B0,%A0)   CR_TAB
3415                       AS2 (andi,%A0,0xf0) CR_TAB
3416                       AS2 (eor,%B0,%A0));
3417             }
3418           if (scratch)
3419             {
3420               *len = 7;
3421               return (AS1 (swap,%A0)    CR_TAB
3422                       AS1 (swap,%B0)    CR_TAB
3423                       AS2 (ldi,%3,0xf0) CR_TAB
3424                       "and %B0,%3"      CR_TAB
3425                       AS2 (eor,%B0,%A0) CR_TAB
3426                       "and %A0,%3"      CR_TAB
3427                       AS2 (eor,%B0,%A0));
3428             }
3429           break;  /* optimize_size ? 6 : 8 */
3430
3431         case 5:
3432           if (optimize_size)
3433             break;  /* scratch ? 5 : 6 */
3434           if (ldi_ok)
3435             {
3436               *len = 8;
3437               return (AS1 (lsl,%A0)       CR_TAB
3438                       AS1 (rol,%B0)       CR_TAB
3439                       AS1 (swap,%A0)      CR_TAB
3440                       AS1 (swap,%B0)      CR_TAB
3441                       AS2 (andi,%B0,0xf0) CR_TAB
3442                       AS2 (eor,%B0,%A0)   CR_TAB
3443                       AS2 (andi,%A0,0xf0) CR_TAB
3444                       AS2 (eor,%B0,%A0));
3445             }
3446           if (scratch)
3447             {
3448               *len = 9;
3449               return (AS1 (lsl,%A0)     CR_TAB
3450                       AS1 (rol,%B0)     CR_TAB
3451                       AS1 (swap,%A0)    CR_TAB
3452                       AS1 (swap,%B0)    CR_TAB
3453                       AS2 (ldi,%3,0xf0) CR_TAB
3454                       "and %B0,%3"      CR_TAB
3455                       AS2 (eor,%B0,%A0) CR_TAB
3456                       "and %A0,%3"      CR_TAB
3457                       AS2 (eor,%B0,%A0));
3458             }
3459           break;  /* 10 */
3460
3461         case 6:
3462           if (optimize_size)
3463             break;  /* scratch ? 5 : 6 */
3464           *len = 9;
3465           return (AS1 (clr,__tmp_reg__) CR_TAB
3466                   AS1 (lsr,%B0)         CR_TAB
3467                   AS1 (ror,%A0)         CR_TAB
3468                   AS1 (ror,__tmp_reg__) CR_TAB
3469                   AS1 (lsr,%B0)         CR_TAB
3470                   AS1 (ror,%A0)         CR_TAB
3471                   AS1 (ror,__tmp_reg__) CR_TAB
3472                   AS2 (mov,%B0,%A0)     CR_TAB
3473                   AS2 (mov,%A0,__tmp_reg__));
3474
3475         case 7:
3476           *len = 5;
3477           return (AS1 (lsr,%B0)     CR_TAB
3478                   AS2 (mov,%B0,%A0) CR_TAB
3479                   AS1 (clr,%A0)     CR_TAB
3480                   AS1 (ror,%B0)     CR_TAB
3481                   AS1 (ror,%A0));
3482
3483         case 8:
3484           return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3485                             AS1 (clr,%A0));
3486
3487         case 9:
3488           *len = 3;
3489           return (AS2 (mov,%B0,%A0) CR_TAB
3490                   AS1 (clr,%A0)     CR_TAB
3491                   AS1 (lsl,%B0));
3492
3493         case 10:
3494           *len = 4;
3495           return (AS2 (mov,%B0,%A0) CR_TAB
3496                   AS1 (clr,%A0)     CR_TAB
3497                   AS1 (lsl,%B0)     CR_TAB
3498                   AS1 (lsl,%B0));
3499
3500         case 11:
3501           *len = 5;
3502           return (AS2 (mov,%B0,%A0) CR_TAB
3503                   AS1 (clr,%A0)     CR_TAB
3504                   AS1 (lsl,%B0)     CR_TAB
3505                   AS1 (lsl,%B0)     CR_TAB
3506                   AS1 (lsl,%B0));
3507
3508         case 12:
3509           if (ldi_ok)
3510             {
3511               *len = 4;
3512               return (AS2 (mov,%B0,%A0) CR_TAB
3513                       AS1 (clr,%A0)     CR_TAB
3514                       AS1 (swap,%B0)    CR_TAB
3515                       AS2 (andi,%B0,0xf0));
3516             }
3517           if (scratch)
3518             {
3519               *len = 5;
3520               return (AS2 (mov,%B0,%A0) CR_TAB
3521                       AS1 (clr,%A0)     CR_TAB
3522                       AS1 (swap,%B0)    CR_TAB
3523                       AS2 (ldi,%3,0xf0) CR_TAB
3524                       "and %B0,%3");
3525             }
3526           *len = 6;
3527           return (AS2 (mov,%B0,%A0) CR_TAB
3528                   AS1 (clr,%A0)     CR_TAB
3529                   AS1 (lsl,%B0)     CR_TAB
3530                   AS1 (lsl,%B0)     CR_TAB
3531                   AS1 (lsl,%B0)     CR_TAB
3532                   AS1 (lsl,%B0));
3533
3534         case 13:
3535           if (ldi_ok)
3536             {
3537               *len = 5;
3538               return (AS2 (mov,%B0,%A0) CR_TAB
3539                       AS1 (clr,%A0)     CR_TAB
3540                       AS1 (swap,%B0)    CR_TAB
3541                       AS1 (lsl,%B0)     CR_TAB
3542                       AS2 (andi,%B0,0xe0));
3543             }
3544           if (AVR_HAVE_MUL && scratch)
3545             {
3546               *len = 5;
3547               return (AS2 (ldi,%3,0x20) CR_TAB
3548                       AS2 (mul,%A0,%3)  CR_TAB
3549                       AS2 (mov,%B0,r0)  CR_TAB
3550                       AS1 (clr,%A0)     CR_TAB
3551                       AS1 (clr,__zero_reg__));
3552             }
3553           if (optimize_size && scratch)
3554             break;  /* 5 */
3555           if (scratch)
3556             {
3557               *len = 6;
3558               return (AS2 (mov,%B0,%A0) CR_TAB
3559                       AS1 (clr,%A0)     CR_TAB
3560                       AS1 (swap,%B0)    CR_TAB
3561                       AS1 (lsl,%B0)     CR_TAB
3562                       AS2 (ldi,%3,0xe0) CR_TAB
3563                       "and %B0,%3");
3564             }
3565           if (AVR_HAVE_MUL)
3566             {
3567               *len = 6;
3568               return ("set"            CR_TAB
3569                       AS2 (bld,r1,5)   CR_TAB
3570                       AS2 (mul,%A0,r1) CR_TAB
3571                       AS2 (mov,%B0,r0) CR_TAB
3572                       AS1 (clr,%A0)    CR_TAB
3573                       AS1 (clr,__zero_reg__));
3574             }
3575           *len = 7;
3576           return (AS2 (mov,%B0,%A0) CR_TAB
3577                   AS1 (clr,%A0)     CR_TAB
3578                   AS1 (lsl,%B0)     CR_TAB
3579                   AS1 (lsl,%B0)     CR_TAB
3580                   AS1 (lsl,%B0)     CR_TAB
3581                   AS1 (lsl,%B0)     CR_TAB
3582                   AS1 (lsl,%B0));
3583
3584         case 14:
3585           if (AVR_HAVE_MUL && ldi_ok)
3586             {
3587               *len = 5;
3588               return (AS2 (ldi,%B0,0x40) CR_TAB
3589                       AS2 (mul,%A0,%B0)  CR_TAB
3590                       AS2 (mov,%B0,r0)   CR_TAB
3591                       AS1 (clr,%A0)      CR_TAB
3592                       AS1 (clr,__zero_reg__));
3593             }
3594           if (AVR_HAVE_MUL && scratch)
3595             {
3596               *len = 5;
3597               return (AS2 (ldi,%3,0x40) CR_TAB
3598                       AS2 (mul,%A0,%3)  CR_TAB
3599                       AS2 (mov,%B0,r0)  CR_TAB
3600                       AS1 (clr,%A0)     CR_TAB
3601                       AS1 (clr,__zero_reg__));
3602             }
3603           if (optimize_size && ldi_ok)
3604             {
3605               *len = 5;
3606               return (AS2 (mov,%B0,%A0) CR_TAB
3607                       AS2 (ldi,%A0,6) "\n1:\t"
3608                       AS1 (lsl,%B0)     CR_TAB
3609                       AS1 (dec,%A0)     CR_TAB
3610                       AS1 (brne,1b));
3611             }
3612           if (optimize_size && scratch)
3613             break;  /* 5 */
3614           *len = 6;
3615           return (AS1 (clr,%B0) CR_TAB
3616                   AS1 (lsr,%A0) CR_TAB
3617                   AS1 (ror,%B0) CR_TAB
3618                   AS1 (lsr,%A0) CR_TAB
3619                   AS1 (ror,%B0) CR_TAB
3620                   AS1 (clr,%A0));
3621
3622         case 15:
3623           *len = 4;
3624           return (AS1 (clr,%B0) CR_TAB
3625                   AS1 (lsr,%A0) CR_TAB
3626                   AS1 (ror,%B0) CR_TAB
3627                   AS1 (clr,%A0));
3628         }
3629       len = t;
3630     }
3631   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3632                        AS1 (rol,%B0)),
3633                        insn, operands, len, 2);
3634   return "";
3635 }
3636
3637
3638 /* 32bit shift left ((long)x << i)   */
3639
3640 const char *
3641 ashlsi3_out (rtx insn, rtx operands[], int *len)
3642 {
3643   if (GET_CODE (operands[2]) == CONST_INT)
3644     {
3645       int k;
3646       int *t = len;
3647       
3648       if (!len)
3649         len = &k;
3650       
3651       switch (INTVAL (operands[2]))
3652         {
3653         default:
3654           if (INTVAL (operands[2]) < 32)
3655             break;
3656
3657           if (AVR_HAVE_MOVW)
3658             return *len = 3, (AS1 (clr,%D0) CR_TAB
3659                               AS1 (clr,%C0) CR_TAB
3660                               AS2 (movw,%A0,%C0));
3661           *len = 4;
3662           return (AS1 (clr,%D0) CR_TAB
3663                   AS1 (clr,%C0) CR_TAB
3664                   AS1 (clr,%B0) CR_TAB
3665                   AS1 (clr,%A0));
3666
3667         case 8:
3668           {
3669             int reg0 = true_regnum (operands[0]);
3670             int reg1 = true_regnum (operands[1]);
3671             *len = 4;
3672             if (reg0 >= reg1)
3673               return (AS2 (mov,%D0,%C1)  CR_TAB
3674                       AS2 (mov,%C0,%B1)  CR_TAB
3675                       AS2 (mov,%B0,%A1)  CR_TAB
3676                       AS1 (clr,%A0));
3677             else
3678               return (AS1 (clr,%A0)      CR_TAB
3679                       AS2 (mov,%B0,%A1)  CR_TAB
3680                       AS2 (mov,%C0,%B1)  CR_TAB
3681                       AS2 (mov,%D0,%C1));
3682           }
3683
3684         case 16:
3685           {
3686             int reg0 = true_regnum (operands[0]);
3687             int reg1 = true_regnum (operands[1]);
3688             if (reg0 + 2 == reg1)
3689               return *len = 2, (AS1 (clr,%B0)      CR_TAB
3690                                 AS1 (clr,%A0));
3691             if (AVR_HAVE_MOVW)
3692               return *len = 3, (AS2 (movw,%C0,%A1) CR_TAB
3693                                 AS1 (clr,%B0)      CR_TAB
3694                                 AS1 (clr,%A0));
3695             else
3696               return *len = 4, (AS2 (mov,%C0,%A1)  CR_TAB
3697                                 AS2 (mov,%D0,%B1)  CR_TAB
3698                                 AS1 (clr,%B0)      CR_TAB
3699                                 AS1 (clr,%A0));
3700           }
3701
3702         case 24:
3703           *len = 4;
3704           return (AS2 (mov,%D0,%A1)  CR_TAB
3705                   AS1 (clr,%C0)      CR_TAB
3706                   AS1 (clr,%B0)      CR_TAB
3707                   AS1 (clr,%A0));
3708
3709         case 31:
3710           *len = 6;
3711           return (AS1 (clr,%D0) CR_TAB
3712                   AS1 (lsr,%A0) CR_TAB
3713                   AS1 (ror,%D0) CR_TAB
3714                   AS1 (clr,%C0) CR_TAB
3715                   AS1 (clr,%B0) CR_TAB
3716                   AS1 (clr,%A0));
3717         }
3718       len = t;
3719     }
3720   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3721                        AS1 (rol,%B0) CR_TAB
3722                        AS1 (rol,%C0) CR_TAB
3723                        AS1 (rol,%D0)),
3724                        insn, operands, len, 4);
3725   return "";
3726 }
3727
3728 /* 8bit arithmetic shift right  ((signed char)x >> i) */
3729
3730 const char *
3731 ashrqi3_out (rtx insn, rtx operands[], int *len)
3732 {
3733   if (GET_CODE (operands[2]) == CONST_INT)
3734     {
3735       int k;
3736
3737       if (!len)
3738         len = &k;
3739
3740       switch (INTVAL (operands[2]))
3741         {
3742         case 1:
3743           *len = 1;
3744           return AS1 (asr,%0);
3745
3746         case 2:
3747           *len = 2;
3748           return (AS1 (asr,%0) CR_TAB
3749                   AS1 (asr,%0));
3750
3751         case 3:
3752           *len = 3;
3753           return (AS1 (asr,%0) CR_TAB
3754                   AS1 (asr,%0) CR_TAB
3755                   AS1 (asr,%0));
3756
3757         case 4:
3758           *len = 4;
3759           return (AS1 (asr,%0) CR_TAB
3760                   AS1 (asr,%0) CR_TAB
3761                   AS1 (asr,%0) CR_TAB
3762                   AS1 (asr,%0));
3763
3764         case 5:
3765           *len = 5;
3766           return (AS1 (asr,%0) CR_TAB
3767                   AS1 (asr,%0) CR_TAB
3768                   AS1 (asr,%0) CR_TAB
3769                   AS1 (asr,%0) CR_TAB
3770                   AS1 (asr,%0));
3771
3772         case 6:
3773           *len = 4;
3774           return (AS2 (bst,%0,6)  CR_TAB
3775                   AS1 (lsl,%0)    CR_TAB
3776                   AS2 (sbc,%0,%0) CR_TAB
3777                   AS2 (bld,%0,0));
3778
3779         default:
3780           if (INTVAL (operands[2]) < 8)
3781             break;
3782
3783           /* fall through */
3784
3785         case 7:
3786           *len = 2;
3787           return (AS1 (lsl,%0) CR_TAB
3788                   AS2 (sbc,%0,%0));
3789         }
3790     }
3791   else if (CONSTANT_P (operands[2]))
3792     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3793
3794   out_shift_with_cnt (AS1 (asr,%0),
3795                       insn, operands, len, 1);
3796   return "";
3797 }
3798
3799
3800 /* 16bit arithmetic shift right  ((signed short)x >> i) */
3801
3802 const char *
3803 ashrhi3_out (rtx insn, rtx operands[], int *len)
3804 {
3805   if (GET_CODE (operands[2]) == CONST_INT)
3806     {
3807       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3808       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3809       int k;
3810       int *t = len;
3811       
3812       if (!len)
3813         len = &k;
3814
3815       switch (INTVAL (operands[2]))
3816         {
3817         case 4:
3818         case 5:
3819           /* XXX try to optimize this too? */
3820           break;
3821
3822         case 6:
3823           if (optimize_size)
3824             break;  /* scratch ? 5 : 6 */
3825           *len = 8;
3826           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3827                   AS2 (mov,%A0,%B0)         CR_TAB
3828                   AS1 (lsl,__tmp_reg__)     CR_TAB
3829                   AS1 (rol,%A0)             CR_TAB
3830                   AS2 (sbc,%B0,%B0)         CR_TAB
3831                   AS1 (lsl,__tmp_reg__)     CR_TAB
3832                   AS1 (rol,%A0)             CR_TAB
3833                   AS1 (rol,%B0));
3834
3835         case 7:
3836           *len = 4;
3837           return (AS1 (lsl,%A0)     CR_TAB
3838                   AS2 (mov,%A0,%B0) CR_TAB
3839                   AS1 (rol,%A0)     CR_TAB
3840                   AS2 (sbc,%B0,%B0));
3841
3842         case 8:
3843           {
3844             int reg0 = true_regnum (operands[0]);
3845             int reg1 = true_regnum (operands[1]);
3846
3847             if (reg0 == reg1)
3848               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3849                                 AS1 (lsl,%B0)     CR_TAB
3850                                 AS2 (sbc,%B0,%B0));
3851             else 
3852               return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3853                                 AS1 (clr,%B0)     CR_TAB
3854                                 AS2 (sbrc,%A0,7)  CR_TAB
3855                                 AS1 (dec,%B0));
3856           }
3857
3858         case 9:
3859           *len = 4;
3860           return (AS2 (mov,%A0,%B0) CR_TAB
3861                   AS1 (lsl,%B0)      CR_TAB
3862                   AS2 (sbc,%B0,%B0) CR_TAB
3863                   AS1 (asr,%A0));
3864
3865         case 10:
3866           *len = 5;
3867           return (AS2 (mov,%A0,%B0) CR_TAB
3868                   AS1 (lsl,%B0)     CR_TAB
3869                   AS2 (sbc,%B0,%B0) CR_TAB
3870                   AS1 (asr,%A0)     CR_TAB
3871                   AS1 (asr,%A0));
3872
3873         case 11:
3874           if (AVR_HAVE_MUL && ldi_ok)
3875             {
3876               *len = 5;
3877               return (AS2 (ldi,%A0,0x20) CR_TAB
3878                       AS2 (muls,%B0,%A0) CR_TAB
3879                       AS2 (mov,%A0,r1)   CR_TAB
3880                       AS2 (sbc,%B0,%B0)  CR_TAB
3881                       AS1 (clr,__zero_reg__));
3882             }
3883           if (optimize_size && scratch)
3884             break;  /* 5 */
3885           *len = 6;
3886           return (AS2 (mov,%A0,%B0) CR_TAB
3887                   AS1 (lsl,%B0)     CR_TAB
3888                   AS2 (sbc,%B0,%B0) CR_TAB
3889                   AS1 (asr,%A0)     CR_TAB
3890                   AS1 (asr,%A0)     CR_TAB
3891                   AS1 (asr,%A0));
3892
3893         case 12:
3894           if (AVR_HAVE_MUL && ldi_ok)
3895             {
3896               *len = 5;
3897               return (AS2 (ldi,%A0,0x10) CR_TAB
3898                       AS2 (muls,%B0,%A0) CR_TAB
3899                       AS2 (mov,%A0,r1)   CR_TAB
3900                       AS2 (sbc,%B0,%B0)  CR_TAB
3901                       AS1 (clr,__zero_reg__));
3902             }
3903           if (optimize_size && scratch)
3904             break;  /* 5 */
3905           *len = 7;
3906           return (AS2 (mov,%A0,%B0) CR_TAB
3907                   AS1 (lsl,%B0)     CR_TAB
3908                   AS2 (sbc,%B0,%B0) CR_TAB
3909                   AS1 (asr,%A0)     CR_TAB
3910                   AS1 (asr,%A0)     CR_TAB
3911                   AS1 (asr,%A0)     CR_TAB
3912                   AS1 (asr,%A0));
3913
3914         case 13:
3915           if (AVR_HAVE_MUL && ldi_ok)
3916             {
3917               *len = 5;
3918               return (AS2 (ldi,%A0,0x08) CR_TAB
3919                       AS2 (muls,%B0,%A0) CR_TAB
3920                       AS2 (mov,%A0,r1)   CR_TAB
3921                       AS2 (sbc,%B0,%B0)  CR_TAB
3922                       AS1 (clr,__zero_reg__));
3923             }
3924           if (optimize_size)
3925             break;  /* scratch ? 5 : 7 */
3926           *len = 8;
3927           return (AS2 (mov,%A0,%B0) CR_TAB
3928                   AS1 (lsl,%B0)     CR_TAB
3929                   AS2 (sbc,%B0,%B0) CR_TAB
3930                   AS1 (asr,%A0)     CR_TAB
3931                   AS1 (asr,%A0)     CR_TAB
3932                   AS1 (asr,%A0)     CR_TAB
3933                   AS1 (asr,%A0)     CR_TAB
3934                   AS1 (asr,%A0));
3935
3936         case 14:
3937           *len = 5;
3938           return (AS1 (lsl,%B0)     CR_TAB
3939                   AS2 (sbc,%A0,%A0) CR_TAB
3940                   AS1 (lsl,%B0)     CR_TAB
3941                   AS2 (mov,%B0,%A0) CR_TAB
3942                   AS1 (rol,%A0));
3943
3944         default:
3945           if (INTVAL (operands[2]) < 16)
3946             break;
3947
3948           /* fall through */
3949
3950         case 15:
3951           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
3952                             AS2 (sbc,%A0,%A0) CR_TAB
3953                             AS2 (mov,%B0,%A0));
3954         }
3955       len = t;
3956     }
3957   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3958                        AS1 (ror,%A0)),
3959                        insn, operands, len, 2);
3960   return "";
3961 }
3962
3963
3964 /* 32bit arithmetic shift right  ((signed long)x >> i) */
3965
3966 const char *
3967 ashrsi3_out (rtx insn, rtx operands[], int *len)
3968 {
3969   if (GET_CODE (operands[2]) == CONST_INT)
3970     {
3971       int k;
3972       int *t = len;
3973       
3974       if (!len)
3975         len = &k;
3976       
3977       switch (INTVAL (operands[2]))
3978         {
3979         case 8:
3980           {
3981             int reg0 = true_regnum (operands[0]);
3982             int reg1 = true_regnum (operands[1]);
3983             *len=6;
3984             if (reg0 <= reg1)
3985               return (AS2 (mov,%A0,%B1) CR_TAB
3986                       AS2 (mov,%B0,%C1) CR_TAB
3987                       AS2 (mov,%C0,%D1) CR_TAB
3988                       AS1 (clr,%D0)     CR_TAB
3989                       AS2 (sbrc,%C0,7)  CR_TAB
3990                       AS1 (dec,%D0));
3991             else
3992               return (AS1 (clr,%D0)     CR_TAB
3993                       AS2 (sbrc,%D1,7)  CR_TAB
3994                       AS1 (dec,%D0)     CR_TAB
3995                       AS2 (mov,%C0,%D1) CR_TAB
3996                       AS2 (mov,%B0,%C1) CR_TAB
3997                       AS2 (mov,%A0,%B1));
3998           }
3999           
4000         case 16:
4001           {
4002             int reg0 = true_regnum (operands[0]);
4003             int reg1 = true_regnum (operands[1]);
4004             
4005             if (reg0 == reg1 + 2)
4006               return *len = 4, (AS1 (clr,%D0)     CR_TAB
4007                                 AS2 (sbrc,%B0,7)  CR_TAB
4008                                 AS1 (com,%D0)     CR_TAB
4009                                 AS2 (mov,%C0,%D0));
4010             if (AVR_HAVE_MOVW)
4011               return *len = 5, (AS2 (movw,%A0,%C1) CR_TAB
4012                                 AS1 (clr,%D0)      CR_TAB
4013                                 AS2 (sbrc,%B0,7)   CR_TAB
4014                                 AS1 (com,%D0)      CR_TAB
4015                                 AS2 (mov,%C0,%D0));
4016             else 
4017               return *len = 6, (AS2 (mov,%B0,%D1) CR_TAB
4018                                 AS2 (mov,%A0,%C1) CR_TAB
4019                                 AS1 (clr,%D0)     CR_TAB
4020                                 AS2 (sbrc,%B0,7)  CR_TAB
4021                                 AS1 (com,%D0)     CR_TAB
4022                                 AS2 (mov,%C0,%D0));
4023           }
4024
4025         case 24:
4026           return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
4027                             AS1 (clr,%D0)     CR_TAB
4028                             AS2 (sbrc,%A0,7)  CR_TAB
4029                             AS1 (com,%D0)     CR_TAB
4030                             AS2 (mov,%B0,%D0) CR_TAB
4031                             AS2 (mov,%C0,%D0));
4032
4033         default:
4034           if (INTVAL (operands[2]) < 32)
4035             break;
4036
4037           /* fall through */
4038
4039         case 31:
4040           if (AVR_HAVE_MOVW)
4041             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
4042                               AS2 (sbc,%A0,%A0) CR_TAB
4043                               AS2 (mov,%B0,%A0) CR_TAB
4044                               AS2 (movw,%C0,%A0));
4045           else
4046             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
4047                               AS2 (sbc,%A0,%A0) CR_TAB
4048                               AS2 (mov,%B0,%A0) CR_TAB
4049                               AS2 (mov,%C0,%A0) CR_TAB
4050                               AS2 (mov,%D0,%A0));
4051         }
4052       len = t;
4053     }
4054   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
4055                        AS1 (ror,%C0) CR_TAB
4056                        AS1 (ror,%B0) CR_TAB
4057                        AS1 (ror,%A0)),
4058                        insn, operands, len, 4);
4059   return "";
4060 }
4061
4062 /* 8bit logic shift right ((unsigned char)x >> i) */
4063
4064 const char *
4065 lshrqi3_out (rtx insn, rtx operands[], int *len)
4066 {
4067   if (GET_CODE (operands[2]) == CONST_INT)
4068     {
4069       int k;
4070
4071       if (!len)
4072         len = &k;
4073       
4074       switch (INTVAL (operands[2]))
4075         {
4076         default:
4077           if (INTVAL (operands[2]) < 8)
4078             break;
4079
4080           *len = 1;
4081           return AS1 (clr,%0);
4082
4083         case 1:
4084           *len = 1;
4085           return AS1 (lsr,%0);
4086
4087         case 2:
4088           *len = 2;
4089           return (AS1 (lsr,%0) CR_TAB
4090                   AS1 (lsr,%0));
4091         case 3:
4092           *len = 3;
4093           return (AS1 (lsr,%0) CR_TAB
4094                   AS1 (lsr,%0) CR_TAB
4095                   AS1 (lsr,%0));
4096           
4097         case 4:
4098           if (test_hard_reg_class (LD_REGS, operands[0]))
4099             {
4100               *len=2;
4101               return (AS1 (swap,%0) CR_TAB
4102                       AS2 (andi,%0,0x0f));
4103             }
4104           *len = 4;
4105           return (AS1 (lsr,%0) CR_TAB
4106                   AS1 (lsr,%0) CR_TAB
4107                   AS1 (lsr,%0) CR_TAB
4108                   AS1 (lsr,%0));
4109           
4110         case 5:
4111           if (test_hard_reg_class (LD_REGS, operands[0]))
4112             {
4113               *len = 3;
4114               return (AS1 (swap,%0) CR_TAB
4115                       AS1 (lsr,%0)  CR_TAB
4116                       AS2 (andi,%0,0x7));
4117             }
4118           *len = 5;
4119           return (AS1 (lsr,%0) CR_TAB
4120                   AS1 (lsr,%0) CR_TAB
4121                   AS1 (lsr,%0) CR_TAB
4122                   AS1 (lsr,%0) CR_TAB
4123                   AS1 (lsr,%0));
4124           
4125         case 6:
4126           if (test_hard_reg_class (LD_REGS, operands[0]))
4127             {
4128               *len = 4;
4129               return (AS1 (swap,%0) CR_TAB
4130                       AS1 (lsr,%0)  CR_TAB
4131                       AS1 (lsr,%0)  CR_TAB
4132                       AS2 (andi,%0,0x3));
4133             }
4134           *len = 6;
4135           return (AS1 (lsr,%0) CR_TAB
4136                   AS1 (lsr,%0) CR_TAB
4137                   AS1 (lsr,%0) CR_TAB
4138                   AS1 (lsr,%0) CR_TAB
4139                   AS1 (lsr,%0) CR_TAB
4140                   AS1 (lsr,%0));
4141           
4142         case 7:
4143           *len = 3;
4144           return (AS1 (rol,%0) CR_TAB
4145                   AS1 (clr,%0) CR_TAB
4146                   AS1 (rol,%0));
4147         }
4148     }
4149   else if (CONSTANT_P (operands[2]))
4150     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
4151   
4152   out_shift_with_cnt (AS1 (lsr,%0),
4153                       insn, operands, len, 1);
4154   return "";
4155 }
4156
4157 /* 16bit logic shift right ((unsigned short)x >> i) */
4158
4159 const char *
4160 lshrhi3_out (rtx insn, rtx operands[], int *len)
4161 {
4162   if (GET_CODE (operands[2]) == CONST_INT)
4163     {
4164       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4165       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4166       int k;
4167       int *t = len;
4168
4169       if (!len)
4170         len = &k;
4171       
4172       switch (INTVAL (operands[2]))
4173         {
4174         default:
4175           if (INTVAL (operands[2]) < 16)
4176             break;
4177
4178           *len = 2;
4179           return (AS1 (clr,%B0) CR_TAB
4180                   AS1 (clr,%A0));
4181
4182         case 4:
4183           if (optimize_size && scratch)
4184             break;  /* 5 */
4185           if (ldi_ok)
4186             {
4187               *len = 6;
4188               return (AS1 (swap,%B0)      CR_TAB
4189                       AS1 (swap,%A0)      CR_TAB
4190                       AS2 (andi,%A0,0x0f) CR_TAB
4191                       AS2 (eor,%A0,%B0)   CR_TAB
4192                       AS2 (andi,%B0,0x0f) CR_TAB
4193                       AS2 (eor,%A0,%B0));
4194             }
4195           if (scratch)
4196             {
4197               *len = 7;
4198               return (AS1 (swap,%B0)    CR_TAB
4199                       AS1 (swap,%A0)    CR_TAB
4200                       AS2 (ldi,%3,0x0f) CR_TAB
4201                       "and %A0,%3"      CR_TAB
4202                       AS2 (eor,%A0,%B0) CR_TAB
4203                       "and %B0,%3"      CR_TAB
4204                       AS2 (eor,%A0,%B0));
4205             }
4206           break;  /* optimize_size ? 6 : 8 */
4207
4208         case 5:
4209           if (optimize_size)
4210             break;  /* scratch ? 5 : 6 */
4211           if (ldi_ok)
4212             {
4213               *len = 8;
4214               return (AS1 (lsr,%B0)       CR_TAB
4215                       AS1 (ror,%A0)       CR_TAB
4216                       AS1 (swap,%B0)      CR_TAB
4217                       AS1 (swap,%A0)      CR_TAB
4218                       AS2 (andi,%A0,0x0f) CR_TAB
4219                       AS2 (eor,%A0,%B0)   CR_TAB
4220                       AS2 (andi,%B0,0x0f) CR_TAB
4221                       AS2 (eor,%A0,%B0));
4222             }
4223           if (scratch)
4224             {
4225               *len = 9;
4226               return (AS1 (lsr,%B0)     CR_TAB
4227                       AS1 (ror,%A0)     CR_TAB
4228                       AS1 (swap,%B0)    CR_TAB
4229                       AS1 (swap,%A0)    CR_TAB
4230                       AS2 (ldi,%3,0x0f) CR_TAB
4231                       "and %A0,%3"      CR_TAB
4232                       AS2 (eor,%A0,%B0) CR_TAB
4233                       "and %B0,%3"      CR_TAB
4234                       AS2 (eor,%A0,%B0));
4235             }
4236           break;  /* 10 */
4237
4238         case 6:
4239           if (optimize_size)
4240             break;  /* scratch ? 5 : 6 */
4241           *len = 9;
4242           return (AS1 (clr,__tmp_reg__) CR_TAB
4243                   AS1 (lsl,%A0)         CR_TAB
4244                   AS1 (rol,%B0)         CR_TAB
4245                   AS1 (rol,__tmp_reg__) CR_TAB
4246                   AS1 (lsl,%A0)         CR_TAB
4247                   AS1 (rol,%B0)         CR_TAB
4248                   AS1 (rol,__tmp_reg__) CR_TAB
4249                   AS2 (mov,%A0,%B0)     CR_TAB
4250                   AS2 (mov,%B0,__tmp_reg__));
4251
4252         case 7:
4253           *len = 5;
4254           return (AS1 (lsl,%A0)     CR_TAB
4255                   AS2 (mov,%A0,%B0) CR_TAB
4256                   AS1 (rol,%A0)     CR_TAB
4257                   AS2 (sbc,%B0,%B0) CR_TAB
4258                   AS1 (neg,%B0));
4259
4260         case 8:
4261           return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
4262                             AS1 (clr,%B0));
4263
4264         case 9:
4265           *len = 3;
4266           return (AS2 (mov,%A0,%B0) CR_TAB
4267                   AS1 (clr,%B0)     CR_TAB
4268                   AS1 (lsr,%A0));
4269
4270         case 10:
4271           *len = 4;
4272           return (AS2 (mov,%A0,%B0) CR_TAB
4273                   AS1 (clr,%B0)     CR_TAB
4274                   AS1 (lsr,%A0)     CR_TAB
4275                   AS1 (lsr,%A0));
4276
4277         case 11:
4278           *len = 5;
4279           return (AS2 (mov,%A0,%B0) CR_TAB
4280                   AS1 (clr,%B0)     CR_TAB
4281                   AS1 (lsr,%A0)     CR_TAB
4282                   AS1 (lsr,%A0)     CR_TAB
4283                   AS1 (lsr,%A0));
4284
4285         case 12:
4286           if (ldi_ok)
4287             {
4288               *len = 4;
4289               return (AS2 (mov,%A0,%B0) CR_TAB
4290                       AS1 (clr,%B0)     CR_TAB
4291                       AS1 (swap,%A0)    CR_TAB
4292                       AS2 (andi,%A0,0x0f));
4293             }
4294           if (scratch)
4295             {
4296               *len = 5;
4297               return (AS2 (mov,%A0,%B0) CR_TAB
4298                       AS1 (clr,%B0)     CR_TAB
4299                       AS1 (swap,%A0)    CR_TAB
4300                       AS2 (ldi,%3,0x0f) CR_TAB
4301                       "and %A0,%3");
4302             }
4303           *len = 6;
4304           return (AS2 (mov,%A0,%B0) CR_TAB
4305                   AS1 (clr,%B0)     CR_TAB
4306                   AS1 (lsr,%A0)     CR_TAB
4307                   AS1 (lsr,%A0)     CR_TAB
4308                   AS1 (lsr,%A0)     CR_TAB
4309                   AS1 (lsr,%A0));
4310
4311         case 13:
4312           if (ldi_ok)
4313             {
4314               *len = 5;
4315               return (AS2 (mov,%A0,%B0) CR_TAB
4316                       AS1 (clr,%B0)     CR_TAB
4317                       AS1 (swap,%A0)    CR_TAB
4318                       AS1 (lsr,%A0)     CR_TAB
4319                       AS2 (andi,%A0,0x07));
4320             }
4321           if (AVR_HAVE_MUL && scratch)
4322             {
4323               *len = 5;
4324               return (AS2 (ldi,%3,0x08) CR_TAB
4325                       AS2 (mul,%B0,%3)  CR_TAB
4326                       AS2 (mov,%A0,r1)  CR_TAB
4327                       AS1 (clr,%B0)     CR_TAB
4328                       AS1 (clr,__zero_reg__));
4329             }
4330           if (optimize_size && scratch)
4331             break;  /* 5 */
4332           if (scratch)
4333             {
4334               *len = 6;
4335               return (AS2 (mov,%A0,%B0) CR_TAB
4336                       AS1 (clr,%B0)     CR_TAB
4337                       AS1 (swap,%A0)    CR_TAB
4338                       AS1 (lsr,%A0)     CR_TAB
4339                       AS2 (ldi,%3,0x07) CR_TAB
4340                       "and %A0,%3");
4341             }
4342           if (AVR_HAVE_MUL)
4343             {
4344               *len = 6;
4345               return ("set"            CR_TAB
4346                       AS2 (bld,r1,3)   CR_TAB
4347                       AS2 (mul,%B0,r1) CR_TAB
4348                       AS2 (mov,%A0,r1) CR_TAB
4349                       AS1 (clr,%B0)    CR_TAB
4350                       AS1 (clr,__zero_reg__));
4351             }
4352           *len = 7;
4353           return (AS2 (mov,%A0,%B0) CR_TAB
4354                   AS1 (clr,%B0)     CR_TAB
4355                   AS1 (lsr,%A0)     CR_TAB
4356                   AS1 (lsr,%A0)     CR_TAB
4357                   AS1 (lsr,%A0)     CR_TAB
4358                   AS1 (lsr,%A0)     CR_TAB
4359                   AS1 (lsr,%A0));
4360
4361         case 14:
4362           if (AVR_HAVE_MUL && ldi_ok)
4363             {
4364               *len = 5;
4365               return (AS2 (ldi,%A0,0x04) CR_TAB
4366                       AS2 (mul,%B0,%A0)  CR_TAB
4367                       AS2 (mov,%A0,r1)   CR_TAB
4368                       AS1 (clr,%B0)      CR_TAB
4369                       AS1 (clr,__zero_reg__));
4370             }
4371           if (AVR_HAVE_MUL && scratch)
4372             {
4373               *len = 5;
4374               return (AS2 (ldi,%3,0x04) CR_TAB
4375                       AS2 (mul,%B0,%3)  CR_TAB
4376                       AS2 (mov,%A0,r1)  CR_TAB
4377                       AS1 (clr,%B0)     CR_TAB
4378                       AS1 (clr,__zero_reg__));
4379             }
4380           if (optimize_size && ldi_ok)
4381             {
4382               *len = 5;
4383               return (AS2 (mov,%A0,%B0) CR_TAB
4384                       AS2 (ldi,%B0,6) "\n1:\t"
4385                       AS1 (lsr,%A0)     CR_TAB
4386                       AS1 (dec,%B0)     CR_TAB
4387                       AS1 (brne,1b));
4388             }
4389           if (optimize_size && scratch)
4390             break;  /* 5 */
4391           *len = 6;
4392           return (AS1 (clr,%A0) CR_TAB
4393                   AS1 (lsl,%B0) CR_TAB
4394                   AS1 (rol,%A0) CR_TAB
4395                   AS1 (lsl,%B0) CR_TAB
4396                   AS1 (rol,%A0) CR_TAB
4397                   AS1 (clr,%B0));
4398
4399         case 15:
4400           *len = 4;
4401           return (AS1 (clr,%A0) CR_TAB
4402                   AS1 (lsl,%B0) CR_TAB
4403                   AS1 (rol,%A0) CR_TAB
4404                   AS1 (clr,%B0));
4405         }
4406       len = t;
4407     }
4408   out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4409                        AS1 (ror,%A0)),
4410                        insn, operands, len, 2);
4411   return "";
4412 }
4413
4414 /* 32bit logic shift right ((unsigned int)x >> i) */
4415
4416 const char *
4417 lshrsi3_out (rtx insn, rtx operands[], int *len)
4418 {
4419   if (GET_CODE (operands[2]) == CONST_INT)
4420     {
4421       int k;
4422       int *t = len;
4423       
4424       if (!len)
4425         len = &k;
4426       
4427       switch (INTVAL (operands[2]))
4428         {
4429         default:
4430           if (INTVAL (operands[2]) < 32)
4431             break;
4432
4433           if (AVR_HAVE_MOVW)
4434             return *len = 3, (AS1 (clr,%D0) CR_TAB
4435                               AS1 (clr,%C0) CR_TAB
4436                               AS2 (movw,%A0,%C0));
4437           *len = 4;
4438           return (AS1 (clr,%D0) CR_TAB
4439                   AS1 (clr,%C0) CR_TAB
4440                   AS1 (clr,%B0) CR_TAB
4441                   AS1 (clr,%A0));
4442
4443         case 8:
4444           {
4445             int reg0 = true_regnum (operands[0]);
4446             int reg1 = true_regnum (operands[1]);
4447             *len = 4;
4448             if (reg0 <= reg1)
4449               return (AS2 (mov,%A0,%B1) CR_TAB
4450                       AS2 (mov,%B0,%C1) CR_TAB
4451                       AS2 (mov,%C0,%D1) CR_TAB
4452                       AS1 (clr,%D0));
4453             else
4454               return (AS1 (clr,%D0)     CR_TAB
4455                       AS2 (mov,%C0,%D1) CR_TAB
4456                       AS2 (mov,%B0,%C1) CR_TAB
4457                       AS2 (mov,%A0,%B1)); 
4458           }
4459           
4460         case 16:
4461           {
4462             int reg0 = true_regnum (operands[0]);
4463             int reg1 = true_regnum (operands[1]);
4464
4465             if (reg0 == reg1 + 2)
4466               return *len = 2, (AS1 (clr,%C0)     CR_TAB
4467                                 AS1 (clr,%D0));
4468             if (AVR_HAVE_MOVW)
4469               return *len = 3, (AS2 (movw,%A0,%C1) CR_TAB
4470                                 AS1 (clr,%C0)      CR_TAB
4471                                 AS1 (clr,%D0));
4472             else
4473               return *len = 4, (AS2 (mov,%B0,%D1) CR_TAB
4474                                 AS2 (mov,%A0,%C1) CR_TAB
4475                                 AS1 (clr,%C0)     CR_TAB
4476                                 AS1 (clr,%D0));
4477           }
4478           
4479         case 24:
4480           return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4481                             AS1 (clr,%B0)     CR_TAB
4482                             AS1 (clr,%C0)     CR_TAB
4483                             AS1 (clr,%D0));
4484
4485         case 31:
4486           *len = 6;
4487           return (AS1 (clr,%A0)    CR_TAB
4488                   AS2 (sbrc,%D0,7) CR_TAB
4489                   AS1 (inc,%A0)    CR_TAB
4490                   AS1 (clr,%B0)    CR_TAB
4491                   AS1 (clr,%C0)    CR_TAB
4492                   AS1 (clr,%D0));
4493         }
4494       len = t;
4495     }
4496   out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4497                        AS1 (ror,%C0) CR_TAB
4498                        AS1 (ror,%B0) CR_TAB
4499                        AS1 (ror,%A0)),
4500                       insn, operands, len, 4);
4501   return "";
4502 }
4503
4504 /* Create RTL split patterns for byte sized rotate expressions.  This
4505   produces a series of move instructions and considers overlap situations.
4506   Overlapping non-HImode operands need a scratch register.  */
4507
4508 bool
4509 avr_rotate_bytes (rtx operands[])
4510 {
4511     int i, j;
4512     enum machine_mode mode = GET_MODE (operands[0]);
4513     bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
4514     bool same_reg = rtx_equal_p (operands[0], operands[1]);
4515     int num = INTVAL (operands[2]);
4516     rtx scratch = operands[3];
4517     /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
4518        Word move if no scratch is needed, otherwise use size of scratch.  */
4519     enum machine_mode move_mode = QImode;
4520     int move_size, offset, size;
4521
4522     if (num & 0xf)
4523       move_mode = QImode;
4524     else if ((mode == SImode && !same_reg) || !overlapped)
4525       move_mode = HImode;
4526     else
4527       move_mode = GET_MODE (scratch);
4528
4529     /* Force DI rotate to use QI moves since other DI moves are currently split
4530        into QI moves so forward propagation works better.  */
4531     if (mode == DImode)
4532       move_mode = QImode;
4533     /* Make scratch smaller if needed.  */
4534     if (GET_MODE (scratch) == HImode && move_mode == QImode)
4535       scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0); 
4536
4537     move_size = GET_MODE_SIZE (move_mode);
4538     /* Number of bytes/words to rotate.  */
4539     offset = (num  >> 3) / move_size;
4540     /* Number of moves needed.  */
4541     size = GET_MODE_SIZE (mode) / move_size;
4542     /* Himode byte swap is special case to avoid a scratch register.  */
4543     if (mode == HImode && same_reg)
4544       {
4545         /* HImode byte swap, using xor.  This is as quick as using scratch.  */
4546         rtx src, dst;
4547         src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
4548         dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
4549         if (!rtx_equal_p (dst, src))
4550           {
4551              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
4552              emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
4553              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
4554           }
4555       }    
4556     else  
4557       {
4558 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode)  */
4559         /* Create linked list of moves to determine move order.  */
4560         struct {
4561           rtx src, dst;
4562           int links;
4563         } move[MAX_SIZE + 8];
4564         int blocked, moves;
4565
4566         gcc_assert (size <= MAX_SIZE);
4567         /* Generate list of subreg moves.  */
4568         for (i = 0; i < size; i++)
4569           {
4570             int from = i;
4571             int to = (from + offset) % size;          
4572             move[i].src = simplify_gen_subreg (move_mode, operands[1],
4573                                                 mode, from * move_size);
4574             move[i].dst = simplify_gen_subreg (move_mode, operands[0],
4575                                                 mode, to   * move_size);
4576             move[i].links = -1;
4577            }
4578         /* Mark dependence where a dst of one move is the src of another move.
4579            The first move is a conflict as it must wait until second is
4580            performed.  We ignore moves to self - we catch this later.  */
4581         if (overlapped)
4582           for (i = 0; i < size; i++)
4583             if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
4584               for (j = 0; j < size; j++)
4585                 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
4586                   {
4587                     /* The dst of move i is the src of move j.  */
4588                     move[i].links = j;
4589                     break;
4590                   }
4591
4592         blocked = -1;
4593         moves = 0;
4594         /* Go through move list and perform non-conflicting moves.  As each
4595            non-overlapping move is made, it may remove other conflicts
4596            so the process is repeated until no conflicts remain.  */
4597         do
4598           {
4599             blocked = -1;
4600             moves = 0;
4601             /* Emit move where dst is not also a src or we have used that
4602                src already.  */
4603             for (i = 0; i < size; i++)
4604               if (move[i].src != NULL_RTX)
4605                 {
4606                   if (move[i].links == -1
4607                       || move[move[i].links].src == NULL_RTX)
4608                     {
4609                       moves++;
4610                       /* Ignore NOP moves to self.  */
4611                       if (!rtx_equal_p (move[i].dst, move[i].src))
4612                         emit_move_insn (move[i].dst, move[i].src);
4613
4614                       /* Remove  conflict from list.  */
4615                       move[i].src = NULL_RTX;
4616                     }
4617                   else
4618                     blocked = i;
4619                 }
4620
4621             /* Check for deadlock. This is when no moves occurred and we have
4622                at least one blocked move.  */
4623             if (moves == 0 && blocked != -1)
4624               {
4625                 /* Need to use scratch register to break deadlock.
4626                    Add move to put dst of blocked move into scratch.
4627                    When this move occurs, it will break chain deadlock.
4628                    The scratch register is substituted for real move.  */
4629
4630                 move[size].src = move[blocked].dst;
4631                 move[size].dst =  scratch;
4632                 /* Scratch move is never blocked.  */
4633                 move[size].links = -1; 
4634                 /* Make sure we have valid link.  */
4635                 gcc_assert (move[blocked].links != -1);
4636                 /* Replace src of  blocking move with scratch reg.  */
4637                 move[move[blocked].links].src = scratch;
4638                 /* Make dependent on scratch move occuring.  */
4639                 move[blocked].links = size; 
4640                 size=size+1;
4641               }
4642           }
4643         while (blocked != -1);
4644       }
4645     return true;
4646 }
4647
4648 /* Modifies the length assigned to instruction INSN
4649  LEN is the initially computed length of the insn.  */
4650
4651 int
4652 adjust_insn_length (rtx insn, int len)
4653 {
4654   rtx patt = PATTERN (insn);
4655   rtx set;
4656
4657   if (GET_CODE (patt) == SET)
4658     {
4659       rtx op[10];
4660       op[1] = SET_SRC (patt);
4661       op[0] = SET_DEST (patt);
4662       if (general_operand (op[1], VOIDmode)
4663           && general_operand (op[0], VOIDmode))
4664         {
4665           switch (GET_MODE (op[0]))
4666             {
4667             case QImode:
4668               output_movqi (insn, op, &len);
4669               break;
4670             case HImode:
4671               output_movhi (insn, op, &len);
4672               break;
4673             case SImode:
4674             case SFmode:
4675               output_movsisf (insn, op, &len);
4676               break;
4677             default:
4678               break;
4679             }
4680         }
4681       else if (op[0] == cc0_rtx && REG_P (op[1]))
4682         {
4683           switch (GET_MODE (op[1]))
4684             {
4685             case HImode: out_tsthi (insn, op[1], &len); break;
4686             case SImode: out_tstsi (insn, op[1], &len); break;
4687             default: break;
4688             }
4689         }
4690       else if (GET_CODE (op[1]) == AND)
4691         {
4692           if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4693             {
4694               HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4695               if (GET_MODE (op[1]) == SImode)
4696                 len = (((mask & 0xff) != 0xff)
4697                        + ((mask & 0xff00) != 0xff00)
4698                        + ((mask & 0xff0000L) != 0xff0000L)
4699                        + ((mask & 0xff000000L) != 0xff000000L));
4700               else if (GET_MODE (op[1]) == HImode)
4701                 len = (((mask & 0xff) != 0xff)
4702                        + ((mask & 0xff00) != 0xff00));
4703             }
4704         }
4705       else if (GET_CODE (op[1]) == IOR)
4706         {
4707           if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4708             {
4709               HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4710               if (GET_MODE (op[1]) == SImode)
4711                 len = (((mask & 0xff) != 0)
4712                        + ((mask & 0xff00) != 0)
4713                        + ((mask & 0xff0000L) != 0)
4714                        + ((mask & 0xff000000L) != 0));
4715               else if (GET_MODE (op[1]) == HImode)
4716                 len = (((mask & 0xff) != 0)
4717                        + ((mask & 0xff00) != 0));
4718             }
4719         }
4720     }
4721   set = single_set (insn);
4722   if (set)
4723     {
4724       rtx op[10];
4725
4726       op[1] = SET_SRC (set);
4727       op[0] = SET_DEST (set);
4728
4729       if (GET_CODE (patt) == PARALLEL
4730           && general_operand (op[1], VOIDmode)
4731           && general_operand (op[0], VOIDmode))
4732         {
4733           if (XVECLEN (patt, 0) == 2)
4734             op[2] = XVECEXP (patt, 0, 1);
4735
4736           switch (GET_MODE (op[0]))
4737             {
4738             case QImode:
4739               len = 2;
4740               break;
4741             case HImode:
4742               output_reload_inhi (insn, op, &len);
4743               break;
4744             case SImode:
4745             case SFmode:
4746               output_reload_insisf (insn, op, &len);
4747               break;
4748             default:
4749               break;
4750             }
4751         }
4752       else if (GET_CODE (op[1]) == ASHIFT
4753           || GET_CODE (op[1]) == ASHIFTRT
4754           || GET_CODE (op[1]) == LSHIFTRT)
4755         {
4756           rtx ops[10];
4757           ops[0] = op[0];
4758           ops[1] = XEXP (op[1],0);
4759           ops[2] = XEXP (op[1],1);
4760           switch (GET_CODE (op[1]))
4761             {
4762             case ASHIFT:
4763               switch (GET_MODE (op[0]))
4764                 {
4765                 case QImode: ashlqi3_out (insn,ops,&len); break;
4766                 case HImode: ashlhi3_out (insn,ops,&len); break;
4767                 case SImode: ashlsi3_out (insn,ops,&len); break;
4768                 default: break;
4769                 }
4770               break;
4771             case ASHIFTRT:
4772               switch (GET_MODE (op[0]))
4773                 {
4774                 case QImode: ashrqi3_out (insn,ops,&len); break;
4775                 case HImode: ashrhi3_out (insn,ops,&len); break;
4776                 case SImode: ashrsi3_out (insn,ops,&len); break;
4777                 default: break;
4778                 }
4779               break;
4780             case LSHIFTRT:
4781               switch (GET_MODE (op[0]))
4782                 {
4783                 case QImode: lshrqi3_out (insn,ops,&len); break;
4784                 case HImode: lshrhi3_out (insn,ops,&len); break;
4785                 case SImode: lshrsi3_out (insn,ops,&len); break;
4786                 default: break;
4787                 }
4788               break;
4789             default:
4790               break;
4791             }
4792         }
4793     }
4794   return len;
4795 }
4796
4797 /* Return nonzero if register REG dead after INSN.  */
4798
4799 int
4800 reg_unused_after (rtx insn, rtx reg)
4801 {
4802   return (dead_or_set_p (insn, reg)
4803           || (REG_P(reg) && _reg_unused_after (insn, reg)));
4804 }
4805
4806 /* Return nonzero if REG is not used after INSN.
4807    We assume REG is a reload reg, and therefore does
4808    not live past labels.  It may live past calls or jumps though.  */
4809
4810 int
4811 _reg_unused_after (rtx insn, rtx reg)
4812 {
4813   enum rtx_code code;
4814   rtx set;
4815
4816   /* If the reg is set by this instruction, then it is safe for our
4817      case.  Disregard the case where this is a store to memory, since
4818      we are checking a register used in the store address.  */
4819   set = single_set (insn);
4820   if (set && GET_CODE (SET_DEST (set)) != MEM
4821       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4822     return 1;
4823
4824   while ((insn = NEXT_INSN (insn)))
4825     {
4826       rtx set;
4827       code = GET_CODE (insn);
4828
4829 #if 0
4830       /* If this is a label that existed before reload, then the register
4831          if dead here.  However, if this is a label added by reorg, then
4832          the register may still be live here.  We can't tell the difference,
4833          so we just ignore labels completely.  */
4834       if (code == CODE_LABEL)
4835         return 1;
4836       /* else */
4837 #endif
4838
4839       if (!INSN_P (insn))
4840         continue;
4841
4842       if (code == JUMP_INSN)
4843         return 0;
4844
4845       /* If this is a sequence, we must handle them all at once.
4846          We could have for instance a call that sets the target register,
4847          and an insn in a delay slot that uses the register.  In this case,
4848          we must return 0.  */
4849       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4850         {
4851           int i;
4852           int retval = 0;
4853
4854           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4855             {
4856               rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4857               rtx set = single_set (this_insn);
4858
4859               if (GET_CODE (this_insn) == CALL_INSN)
4860                 code = CALL_INSN;
4861               else if (GET_CODE (this_insn) == JUMP_INSN)
4862                 {
4863                   if (INSN_ANNULLED_BRANCH_P (this_insn))
4864                     return 0;
4865                   code = JUMP_INSN;
4866                 }
4867
4868               if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4869                 return 0;
4870               if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4871                 {
4872                   if (GET_CODE (SET_DEST (set)) != MEM)
4873                     retval = 1;
4874                   else
4875                     return 0;
4876                 }
4877               if (set == 0
4878                   && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4879                 return 0;
4880             }
4881           if (retval == 1)
4882             return 1;
4883           else if (code == JUMP_INSN)
4884             return 0;
4885         }
4886
4887       if (code == CALL_INSN)
4888         {
4889           rtx tem;
4890           for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4891             if (GET_CODE (XEXP (tem, 0)) == USE
4892                 && REG_P (XEXP (XEXP (tem, 0), 0))
4893                 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4894               return 0;
4895           if (call_used_regs[REGNO (reg)]) 
4896             return 1;
4897         }
4898
4899       set = single_set (insn);
4900
4901       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4902         return 0;
4903       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4904         return GET_CODE (SET_DEST (set)) != MEM;
4905       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4906         return 0;
4907     }
4908   return 1;
4909 }
4910
4911 /* Target hook for assembling integer objects.  The AVR version needs
4912    special handling for references to certain labels.  */
4913
4914 static bool
4915 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4916 {
4917   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4918       && text_segment_operand (x, VOIDmode) )
4919     {
4920       fputs ("\t.word\tgs(", asm_out_file);
4921       output_addr_const (asm_out_file, x);
4922       fputs (")\n", asm_out_file);
4923       return true;
4924     }
4925   return default_assemble_integer (x, size, aligned_p);
4926 }
4927
4928 /* Worker function for ASM_DECLARE_FUNCTION_NAME.  */
4929
4930 void
4931 avr_asm_declare_function_name (FILE *file, const char *name, tree decl)
4932 {
4933
4934   /* If the function has the 'signal' or 'interrupt' attribute, test to
4935      make sure that the name of the function is "__vector_NN" so as to
4936      catch when the user misspells the interrupt vector name.  */
4937
4938   if (cfun->machine->is_interrupt)
4939     {
4940       if (strncmp (name, "__vector", strlen ("__vector")) != 0)
4941         {
4942           warning_at (DECL_SOURCE_LOCATION (decl), 0,
4943                       "%qs appears to be a misspelled interrupt handler",
4944                       name);
4945         }
4946     }
4947   else if (cfun->machine->is_signal)
4948     {
4949       if (strncmp (name, "__vector", strlen ("__vector")) != 0)
4950         {
4951            warning_at (DECL_SOURCE_LOCATION (decl), 0,
4952                        "%qs appears to be a misspelled signal handler",
4953                        name);
4954         }
4955     }
4956
4957   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
4958   ASM_OUTPUT_LABEL (file, name);
4959 }
4960
4961 /* The routine used to output NUL terminated strings.  We use a special
4962    version of this for most svr4 targets because doing so makes the
4963    generated assembly code more compact (and thus faster to assemble)
4964    as well as more readable, especially for targets like the i386
4965    (where the only alternative is to output character sequences as
4966    comma separated lists of numbers).  */
4967
4968 void
4969 gas_output_limited_string(FILE *file, const char *str)
4970 {
4971   const unsigned char *_limited_str = (const unsigned char *) str;
4972   unsigned ch;
4973   fprintf (file, "%s\"", STRING_ASM_OP);
4974   for (; (ch = *_limited_str); _limited_str++)
4975     {
4976       int escape;
4977       switch (escape = ESCAPES[ch])
4978         {
4979         case 0:
4980           putc (ch, file);
4981           break;
4982         case 1:
4983           fprintf (file, "\\%03o", ch);
4984           break;
4985         default:
4986           putc ('\\', file);
4987           putc (escape, file);
4988           break;
4989         }
4990     }
4991   fprintf (file, "\"\n");
4992 }
4993
4994 /* The routine used to output sequences of byte values.  We use a special
4995    version of this for most svr4 targets because doing so makes the
4996    generated assembly code more compact (and thus faster to assemble)
4997    as well as more readable.  Note that if we find subparts of the
4998    character sequence which end with NUL (and which are shorter than
4999    STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
5000
5001 void
5002 gas_output_ascii(FILE *file, const char *str, size_t length)
5003 {
5004   const unsigned char *_ascii_bytes = (const unsigned char *) str;
5005   const unsigned char *limit = _ascii_bytes + length;
5006   unsigned bytes_in_chunk = 0;
5007   for (; _ascii_bytes < limit; _ascii_bytes++)
5008     {
5009       const unsigned char *p;
5010       if (bytes_in_chunk >= 60)
5011         {
5012           fprintf (file, "\"\n");
5013           bytes_in_chunk = 0;
5014         }
5015       for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
5016         continue;
5017       if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
5018         {
5019           if (bytes_in_chunk > 0)
5020             {
5021               fprintf (file, "\"\n");
5022               bytes_in_chunk = 0;
5023             }
5024           gas_output_limited_string (file, (const char*)_ascii_bytes);
5025           _ascii_bytes = p;
5026         }
5027       else
5028         {
5029           int escape;
5030           unsigned ch;
5031           if (bytes_in_chunk == 0)
5032             fprintf (file, "\t.ascii\t\"");
5033           switch (escape = ESCAPES[ch = *_ascii_bytes])
5034             {
5035             case 0:
5036               putc (ch, file);
5037               bytes_in_chunk++;
5038               break;
5039             case 1:
5040               fprintf (file, "\\%03o", ch);
5041               bytes_in_chunk += 4;
5042               break;
5043             default:
5044               putc ('\\', file);
5045               putc (escape, file);
5046               bytes_in_chunk += 2;
5047               break;
5048             }
5049         }
5050     }
5051   if (bytes_in_chunk > 0)
5052     fprintf (file, "\"\n");
5053 }
5054
5055 /* Return value is nonzero if pseudos that have been
5056    assigned to registers of class CLASS would likely be spilled
5057    because registers of CLASS are needed for spill registers.  */
5058
5059 static bool
5060 avr_class_likely_spilled_p (reg_class_t c)
5061 {
5062   return (c != ALL_REGS && c != ADDW_REGS);
5063 }
5064
5065 /* Valid attributes:
5066    progmem - put data to program memory;
5067    signal - make a function to be hardware interrupt. After function
5068    prologue interrupts are disabled;
5069    interrupt - make a function to be hardware interrupt. After function
5070    prologue interrupts are enabled;
5071    naked     - don't generate function prologue/epilogue and `ret' command.
5072
5073    Only `progmem' attribute valid for type.  */
5074
5075 /* Handle a "progmem" attribute; arguments as in
5076    struct attribute_spec.handler.  */
5077 static tree
5078 avr_handle_progmem_attribute (tree *node, tree name,
5079                               tree args ATTRIBUTE_UNUSED,
5080                               int flags ATTRIBUTE_UNUSED,
5081                               bool *no_add_attrs)
5082 {
5083   if (DECL_P (*node))
5084     {
5085       if (TREE_CODE (*node) == TYPE_DECL)
5086         {
5087           /* This is really a decl attribute, not a type attribute,
5088              but try to handle it for GCC 3.0 backwards compatibility.  */
5089
5090           tree type = TREE_TYPE (*node);
5091           tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
5092           tree newtype = build_type_attribute_variant (type, attr);
5093
5094           TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
5095           TREE_TYPE (*node) = newtype;
5096           *no_add_attrs = true;
5097         }
5098       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
5099         {
5100           if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
5101             {
5102               warning (0, "only initialized variables can be placed into "
5103                        "program memory area");
5104               *no_add_attrs = true;
5105             }
5106         }
5107       else
5108         {
5109           warning (OPT_Wattributes, "%qE attribute ignored",
5110                    name);
5111           *no_add_attrs = true;
5112         }
5113     }
5114
5115   return NULL_TREE;
5116 }
5117
5118 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
5119    struct attribute_spec.handler.  */
5120
5121 static tree
5122 avr_handle_fndecl_attribute (tree *node, tree name,
5123                              tree args ATTRIBUTE_UNUSED,
5124                              int flags ATTRIBUTE_UNUSED,
5125                              bool *no_add_attrs)
5126 {
5127   if (TREE_CODE (*node) != FUNCTION_DECL)
5128     {
5129       warning (OPT_Wattributes, "%qE attribute only applies to functions",
5130                name);
5131       *no_add_attrs = true;
5132     }
5133
5134   return NULL_TREE;
5135 }
5136
5137 static tree
5138 avr_handle_fntype_attribute (tree *node, tree name,
5139                              tree args ATTRIBUTE_UNUSED,
5140                              int flags ATTRIBUTE_UNUSED,
5141                              bool *no_add_attrs)
5142 {
5143   if (TREE_CODE (*node) != FUNCTION_TYPE)
5144     {
5145       warning (OPT_Wattributes, "%qE attribute only applies to functions",
5146                name);
5147       *no_add_attrs = true;
5148     }
5149
5150   return NULL_TREE;
5151 }
5152
5153 /* Look for attribute `progmem' in DECL
5154    if found return 1, otherwise 0.  */
5155
5156 int
5157 avr_progmem_p (tree decl, tree attributes)
5158 {
5159   tree a;
5160
5161   if (TREE_CODE (decl) != VAR_DECL)
5162     return 0;
5163
5164   if (NULL_TREE
5165       != lookup_attribute ("progmem", attributes))
5166     return 1;
5167
5168   a=decl;
5169   do
5170     a = TREE_TYPE(a);
5171   while (TREE_CODE (a) == ARRAY_TYPE);
5172
5173   if (a == error_mark_node)
5174     return 0;
5175
5176   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
5177     return 1;
5178   
5179   return 0;
5180 }
5181
5182 /* Add the section attribute if the variable is in progmem.  */
5183
5184 static void
5185 avr_insert_attributes (tree node, tree *attributes)
5186 {
5187   if (TREE_CODE (node) == VAR_DECL
5188       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
5189       && avr_progmem_p (node, *attributes))
5190     {
5191       if (TREE_READONLY (node)) 
5192         {
5193           static const char dsec[] = ".progmem.data";
5194
5195           *attributes = tree_cons (get_identifier ("section"),
5196                                    build_tree_list (NULL, build_string (strlen (dsec), dsec)),
5197                                    *attributes);
5198         }
5199       else
5200         {
5201           error ("variable %q+D must be const in order to be put into"
5202                  " read-only section by means of %<__attribute__((progmem))%>",
5203                  node);
5204         }
5205     }
5206 }
5207
5208 /* A get_unnamed_section callback for switching to progmem_section.  */
5209
5210 static void
5211 avr_output_progmem_section_asm_op (const void *arg ATTRIBUTE_UNUSED)
5212 {
5213   fprintf (asm_out_file,
5214            "\t.section .progmem.gcc_sw_table, \"%s\", @progbits\n",
5215            AVR_HAVE_JMP_CALL ? "a" : "ax");
5216   /* Should already be aligned, this is just to be safe if it isn't.  */
5217   fprintf (asm_out_file, "\t.p2align 1\n");
5218 }
5219
5220
5221 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
5222 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
5223 /* Track need of __do_clear_bss.  */
5224
5225 void
5226 avr_asm_output_aligned_decl_common (FILE * stream, const_tree decl ATTRIBUTE_UNUSED,
5227                                     const char *name, unsigned HOST_WIDE_INT size,
5228                                     unsigned int align, bool local_p)
5229 {
5230   avr_need_clear_bss_p = true;
5231
5232   if (local_p)
5233     {
5234       fputs ("\t.local\t", stream);
5235       assemble_name (stream, name);
5236       fputs ("\n", stream);
5237     }
5238   
5239   fputs ("\t.comm\t", stream);
5240   assemble_name (stream, name);
5241   fprintf (stream,
5242            "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
5243            size, align / BITS_PER_UNIT);
5244 }
5245
5246
5247 /* Unnamed section callback for data_section
5248    to track need of __do_copy_data.  */
5249
5250 static void
5251 avr_output_data_section_asm_op (const void *data)
5252 {
5253   avr_need_copy_data_p = true;
5254   
5255   /* Dispatch to default.  */
5256   output_section_asm_op (data);
5257 }
5258
5259
5260 /* Unnamed section callback for bss_section
5261    to track need of __do_clear_bss.  */
5262
5263 static void
5264 avr_output_bss_section_asm_op (const void *data)
5265 {
5266   avr_need_clear_bss_p = true;
5267   
5268   /* Dispatch to default.  */
5269   output_section_asm_op (data);
5270 }
5271
5272
5273 /* Implement `TARGET_ASM_INIT_SECTIONS'.  */
5274
5275 static void
5276 avr_asm_init_sections (void)
5277 {
5278   progmem_section = get_unnamed_section (AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE,
5279                                          avr_output_progmem_section_asm_op,
5280                                          NULL);
5281   readonly_data_section = data_section;
5282
5283   data_section->unnamed.callback = avr_output_data_section_asm_op;
5284   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
5285 }
5286
5287
5288 /* Implement `TARGET_ASM_NAMED_SECTION'.  */
5289 /* Track need of __do_clear_bss, __do_copy_data for named sections.  */
5290
5291 void
5292 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
5293 {
5294   if (!avr_need_copy_data_p)
5295     avr_need_copy_data_p = (0 == strncmp (name, ".data", 5)
5296                             || 0 == strncmp (name, ".rodata", 7)
5297                             || 0 == strncmp (name, ".gnu.linkonce.d", 15));
5298   
5299   if (!avr_need_clear_bss_p)
5300     avr_need_clear_bss_p = (0 == strncmp (name, ".bss", 4));
5301   
5302   default_elf_asm_named_section (name, flags, decl);
5303 }
5304
5305 static unsigned int
5306 avr_section_type_flags (tree decl, const char *name, int reloc)
5307 {
5308   unsigned int flags = default_section_type_flags (decl, name, reloc);
5309
5310   if (strncmp (name, ".noinit", 7) == 0)
5311     {
5312       if (decl && TREE_CODE (decl) == VAR_DECL
5313           && DECL_INITIAL (decl) == NULL_TREE)
5314         flags |= SECTION_BSS;  /* @nobits */
5315       else
5316         warning (0, "only uninitialized variables can be placed in the "
5317                  ".noinit section");
5318     }
5319
5320   return flags;
5321 }
5322
5323
5324 /* Implement `TARGET_ASM_FILE_START'.  */
5325 /* Outputs some appropriate text to go at the start of an assembler
5326    file.  */
5327
5328 static void
5329 avr_file_start (void)
5330 {
5331   if (avr_current_arch->asm_only)
5332     error ("MCU %qs supported for assembler only", avr_mcu_name);
5333
5334   default_file_start ();
5335
5336 /*  fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);*/
5337   fputs ("__SREG__ = 0x3f\n"
5338          "__SP_H__ = 0x3e\n"
5339          "__SP_L__ = 0x3d\n", asm_out_file);
5340   
5341   fputs ("__tmp_reg__ = 0\n" 
5342          "__zero_reg__ = 1\n", asm_out_file);
5343 }
5344
5345
5346 /* Implement `TARGET_ASM_FILE_END'.  */
5347 /* Outputs to the stdio stream FILE some
5348    appropriate text to go at the end of an assembler file.  */
5349
5350 static void
5351 avr_file_end (void)
5352 {
5353   /* Output these only if there is anything in the
5354      .data* / .rodata* / .gnu.linkonce.* resp. .bss*
5355      input section(s) - some code size can be saved by not
5356      linking in the initialization code from libgcc if resp.
5357      sections are empty.  */
5358
5359   if (avr_need_copy_data_p)
5360     fputs (".global __do_copy_data\n", asm_out_file);
5361
5362   if (avr_need_clear_bss_p)
5363     fputs (".global __do_clear_bss\n", asm_out_file);
5364 }
5365
5366 /* Choose the order in which to allocate hard registers for
5367    pseudo-registers local to a basic block.
5368
5369    Store the desired register order in the array `reg_alloc_order'.
5370    Element 0 should be the register to allocate first; element 1, the
5371    next register; and so on.  */
5372
5373 void
5374 order_regs_for_local_alloc (void)
5375 {
5376   unsigned int i;
5377   static const int order_0[] = {
5378     24,25,
5379     18,19,
5380     20,21,
5381     22,23,
5382     30,31,
5383     26,27,
5384     28,29,
5385     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5386     0,1,
5387     32,33,34,35
5388   };
5389   static const int order_1[] = {
5390     18,19,
5391     20,21,
5392     22,23,
5393     24,25,
5394     30,31,
5395     26,27,
5396     28,29,
5397     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5398     0,1,
5399     32,33,34,35
5400   };
5401   static const int order_2[] = {
5402     25,24,
5403     23,22,
5404     21,20,
5405     19,18,
5406     30,31,
5407     26,27,
5408     28,29,
5409     17,16,
5410     15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5411     1,0,
5412     32,33,34,35
5413   };
5414   
5415   const int *order = (TARGET_ORDER_1 ? order_1 :
5416                       TARGET_ORDER_2 ? order_2 :
5417                       order_0);
5418   for (i=0; i < ARRAY_SIZE (order_0); ++i)
5419       reg_alloc_order[i] = order[i];
5420 }
5421
5422
5423 /* Implement `TARGET_REGISTER_MOVE_COST' */
5424
5425 static int
5426 avr_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
5427                         reg_class_t from, reg_class_t to)
5428 {
5429   return (from == STACK_REG ? 6
5430           : to == STACK_REG ? 12
5431           : 2);
5432 }
5433
5434
5435 /* Implement `TARGET_MEMORY_MOVE_COST' */
5436
5437 static int
5438 avr_memory_move_cost (enum machine_mode mode, reg_class_t rclass ATTRIBUTE_UNUSED,
5439                       bool in ATTRIBUTE_UNUSED)
5440 {
5441   return (mode == QImode ? 2
5442           : mode == HImode ? 4
5443           : mode == SImode ? 8
5444           : mode == SFmode ? 8
5445           : 16);
5446 }
5447
5448
5449 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
5450    cost of an RTX operand given its context.  X is the rtx of the
5451    operand, MODE is its mode, and OUTER is the rtx_code of this
5452    operand's parent operator.  */
5453
5454 static int
5455 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
5456                       bool speed)
5457 {
5458   enum rtx_code code = GET_CODE (x);
5459   int total;
5460
5461   switch (code)
5462     {
5463     case REG:
5464     case SUBREG:
5465       return 0;
5466
5467     case CONST_INT:
5468     case CONST_DOUBLE:
5469       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
5470
5471     default:
5472       break;
5473     }
5474
5475   total = 0;
5476   avr_rtx_costs (x, code, outer, &total, speed);
5477   return total;
5478 }
5479
5480 /* The AVR backend's rtx_cost function.  X is rtx expression whose cost
5481    is to be calculated.  Return true if the complete cost has been
5482    computed, and false if subexpressions should be scanned.  In either
5483    case, *TOTAL contains the cost result.  */
5484
5485 static bool
5486 avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, int *total,
5487                bool speed)
5488 {
5489   enum rtx_code code = (enum rtx_code) codearg;
5490   enum machine_mode mode = GET_MODE (x);
5491   HOST_WIDE_INT val;
5492
5493   switch (code)
5494     {
5495     case CONST_INT:
5496     case CONST_DOUBLE:
5497       /* Immediate constants are as cheap as registers.  */
5498       *total = 0;
5499       return true;
5500
5501     case MEM:
5502     case CONST:
5503     case LABEL_REF:
5504     case SYMBOL_REF:
5505       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5506       return true;
5507
5508     case NEG:
5509       switch (mode)
5510         {
5511         case QImode:
5512         case SFmode:
5513           *total = COSTS_N_INSNS (1);
5514           break;
5515
5516         case HImode:
5517           *total = COSTS_N_INSNS (3);
5518           break;
5519
5520         case SImode:
5521           *total = COSTS_N_INSNS (7);
5522           break;
5523
5524         default:
5525           return false;
5526         }
5527       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5528       return true;
5529
5530     case ABS:
5531       switch (mode)
5532         {
5533         case QImode:
5534         case SFmode:
5535           *total = COSTS_N_INSNS (1);
5536           break;
5537
5538         default:
5539           return false;
5540         }
5541       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5542       return true;
5543
5544     case NOT:
5545       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5546       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5547       return true;
5548
5549     case ZERO_EXTEND:
5550       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
5551                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5552       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5553       return true;
5554
5555     case SIGN_EXTEND:
5556       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
5557                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5558       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5559       return true;
5560
5561     case PLUS:
5562       switch (mode)
5563         {
5564         case QImode:
5565           *total = COSTS_N_INSNS (1);
5566           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5567             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5568           break;
5569
5570         case HImode:
5571           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5572             {
5573               *total = COSTS_N_INSNS (2);
5574               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5575             }
5576           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5577             *total = COSTS_N_INSNS (1);
5578           else
5579             *total = COSTS_N_INSNS (2);
5580           break;
5581
5582         case SImode:
5583           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5584             {
5585               *total = COSTS_N_INSNS (4);
5586               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5587             }
5588           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5589             *total = COSTS_N_INSNS (1);
5590           else
5591             *total = COSTS_N_INSNS (4);
5592           break;
5593
5594         default:
5595           return false;
5596         }
5597       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5598       return true;
5599
5600     case MINUS:
5601     case AND:
5602     case IOR:
5603       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5604       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5605       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5606           *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5607       return true;
5608
5609     case XOR:
5610       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5611       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5612       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5613       return true;
5614
5615     case MULT:
5616       switch (mode)
5617         {
5618         case QImode:
5619           if (AVR_HAVE_MUL)
5620             *total = COSTS_N_INSNS (!speed ? 3 : 4);
5621           else if (!speed)
5622             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5623           else
5624             return false;
5625           break;
5626
5627         case HImode:
5628           if (AVR_HAVE_MUL)
5629             *total = COSTS_N_INSNS (!speed ? 7 : 10);
5630           else if (!speed)
5631             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5632           else
5633             return false;
5634           break;
5635
5636         default:
5637           return false;
5638         }
5639       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5640       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5641       return true;
5642
5643     case DIV:
5644     case MOD:
5645     case UDIV:
5646     case UMOD:
5647       if (!speed)
5648         *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
5649       else
5650         return false;
5651       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5652       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5653       return true;
5654
5655     case ROTATE:
5656       switch (mode)
5657         {
5658         case QImode:
5659           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
5660             *total = COSTS_N_INSNS (1);
5661
5662           break;
5663
5664         case HImode:
5665           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
5666             *total = COSTS_N_INSNS (3);
5667
5668           break;
5669
5670         case SImode:
5671           if (CONST_INT_P (XEXP (x, 1)))
5672             switch (INTVAL (XEXP (x, 1)))
5673               {
5674               case 8:
5675               case 24:
5676                 *total = COSTS_N_INSNS (5);
5677                 break;
5678               case 16:
5679                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
5680                 break;
5681               }
5682           break;
5683
5684         default:
5685           return false;
5686         }
5687       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5688       return true;    
5689
5690     case ASHIFT:
5691       switch (mode)
5692         {
5693         case QImode:
5694           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5695             {
5696               *total = COSTS_N_INSNS (!speed ? 4 : 17);
5697               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5698             }
5699           else
5700             {
5701               val = INTVAL (XEXP (x, 1));
5702               if (val == 7)
5703                 *total = COSTS_N_INSNS (3);
5704               else if (val >= 0 && val <= 7)
5705                 *total = COSTS_N_INSNS (val);
5706               else
5707                 *total = COSTS_N_INSNS (1);
5708             }
5709           break;
5710
5711         case HImode:
5712           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5713             {
5714               *total = COSTS_N_INSNS (!speed ? 5 : 41);
5715               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5716             }
5717           else
5718             switch (INTVAL (XEXP (x, 1)))
5719               {
5720               case 0:
5721                 *total = 0;
5722                 break;
5723               case 1:
5724               case 8:
5725                 *total = COSTS_N_INSNS (2);
5726                 break;
5727               case 9:
5728                 *total = COSTS_N_INSNS (3);
5729                 break;
5730               case 2:
5731               case 3:
5732               case 10:
5733               case 15:
5734                 *total = COSTS_N_INSNS (4);
5735                 break;
5736               case 7:
5737               case 11:
5738               case 12:
5739                 *total = COSTS_N_INSNS (5);
5740                 break;
5741               case 4:
5742                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
5743                 break;
5744               case 6:
5745                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
5746                 break;
5747               case 5:
5748                 *total = COSTS_N_INSNS (!speed ? 5 : 10);
5749                 break;
5750               default:
5751                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5752                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5753               }
5754           break;
5755
5756         case SImode:
5757           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5758             {
5759               *total = COSTS_N_INSNS (!speed ? 7 : 113);
5760               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5761             }
5762           else
5763             switch (INTVAL (XEXP (x, 1)))
5764               {
5765               case 0:
5766                 *total = 0;
5767                 break;
5768               case 24:
5769                 *total = COSTS_N_INSNS (3);
5770                 break;
5771               case 1:
5772               case 8:
5773               case 16:
5774                 *total = COSTS_N_INSNS (4);
5775                 break;
5776               case 31:
5777                 *total = COSTS_N_INSNS (6);
5778                 break;
5779               case 2:
5780                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5781                 break;
5782               default:
5783                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5784                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5785               }
5786           break;
5787
5788         default:
5789           return false;
5790         }
5791       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5792       return true;
5793
5794     case ASHIFTRT:
5795       switch (mode)
5796         {
5797         case QImode:
5798           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5799             {
5800               *total = COSTS_N_INSNS (!speed ? 4 : 17);
5801               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5802             }
5803           else
5804             {
5805               val = INTVAL (XEXP (x, 1));
5806               if (val == 6)
5807                 *total = COSTS_N_INSNS (4);
5808               else if (val == 7)
5809                 *total = COSTS_N_INSNS (2);
5810               else if (val >= 0 && val <= 7)
5811                 *total = COSTS_N_INSNS (val);
5812               else
5813                 *total = COSTS_N_INSNS (1);
5814             }
5815           break;
5816
5817         case HImode:
5818           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5819             {
5820               *total = COSTS_N_INSNS (!speed ? 5 : 41);
5821               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5822             }
5823           else
5824             switch (INTVAL (XEXP (x, 1)))
5825               {
5826               case 0:
5827                 *total = 0;
5828                 break;
5829               case 1:
5830                 *total = COSTS_N_INSNS (2);
5831                 break;
5832               case 15:
5833                 *total = COSTS_N_INSNS (3);
5834                 break;
5835               case 2:
5836               case 7:
5837               case 8:
5838               case 9:
5839                 *total = COSTS_N_INSNS (4);
5840                 break;
5841               case 10:
5842               case 14:
5843                 *total = COSTS_N_INSNS (5);
5844                 break;
5845               case 11:
5846                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
5847                 break;
5848               case 12:
5849                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
5850                 break;
5851               case 6:
5852               case 13:
5853                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
5854                 break;
5855               default:
5856                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5857                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5858               }
5859           break;
5860
5861         case SImode:
5862           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5863             {
5864               *total = COSTS_N_INSNS (!speed ? 7 : 113);
5865               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5866             }
5867           else
5868             switch (INTVAL (XEXP (x, 1)))
5869               {
5870               case 0:
5871                 *total = 0;
5872                 break;
5873               case 1:
5874                 *total = COSTS_N_INSNS (4);
5875                 break;
5876               case 8:
5877               case 16:
5878               case 24:
5879                 *total = COSTS_N_INSNS (6);
5880                 break;
5881               case 2:
5882                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5883                 break;
5884               case 31:
5885                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
5886                 break;
5887               default:
5888                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5889                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5890               }
5891           break;
5892
5893         default:
5894           return false;
5895         }
5896       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
5897       return true;
5898
5899     case LSHIFTRT:
5900       switch (mode)
5901         {
5902         case QImode:
5903           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5904             {
5905               *total = COSTS_N_INSNS (!speed ? 4 : 17);
5906               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5907             }
5908           else
5909             {
5910               val = INTVAL (XEXP (x, 1));
5911               if (val == 7)
5912                 *total = COSTS_N_INSNS (3);
5913               else if (val >= 0 && val <= 7)
5914                 *total = COSTS_N_INSNS (val);
5915               else
5916                 *total = COSTS_N_INSNS (1);
5917             }
5918           break;
5919
5920         case HImode:
5921           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5922             {
5923               *total = COSTS_N_INSNS (!speed ? 5 : 41);
5924               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5925             }
5926           else
5927             switch (INTVAL (XEXP (x, 1)))
5928               {
5929               case 0:
5930                 *total = 0;
5931                 break;
5932               case 1:
5933               case 8:
5934                 *total = COSTS_N_INSNS (2);
5935                 break;
5936               case 9:
5937                 *total = COSTS_N_INSNS (3);
5938                 break;
5939               case 2:
5940               case 10:
5941               case 15:
5942                 *total = COSTS_N_INSNS (4);
5943                 break;
5944               case 7:
5945               case 11:
5946                 *total = COSTS_N_INSNS (5);
5947                 break;
5948               case 3:
5949               case 12:
5950               case 13:
5951               case 14:
5952                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
5953                 break;
5954               case 4:
5955                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
5956                 break;
5957               case 5:
5958               case 6:
5959                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
5960                 break;
5961               default:
5962                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
5963                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5964               }
5965           break;
5966
5967         case SImode:
5968           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5969             {
5970               *total = COSTS_N_INSNS (!speed ? 7 : 113);
5971               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5972             }
5973           else
5974             switch (INTVAL (XEXP (x, 1)))
5975               {
5976               case 0:
5977                 *total = 0;
5978                 break;
5979               case 1:
5980                 *total = COSTS_N_INSNS (4);
5981                 break;
5982               case 2:
5983                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
5984                 break;
5985               case 8:
5986               case 16:
5987               case 24:
5988                 *total = COSTS_N_INSNS (4);
5989                 break;
5990               case 31:
5991                 *total = COSTS_N_INSNS (6);
5992                 break;
5993               default:
5994                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
5995                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
5996               }
5997           break;
5998
5999         default:
6000           return false;
6001         }
6002       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
6003       return true;
6004
6005     case COMPARE:
6006       switch (GET_MODE (XEXP (x, 0)))
6007         {
6008         case QImode:
6009           *total = COSTS_N_INSNS (1);
6010           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6011             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
6012           break;
6013
6014         case HImode:
6015           *total = COSTS_N_INSNS (2);
6016           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6017             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
6018           else if (INTVAL (XEXP (x, 1)) != 0)
6019             *total += COSTS_N_INSNS (1);
6020           break;
6021
6022         case SImode:
6023           *total = COSTS_N_INSNS (4);
6024           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6025             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, speed);
6026           else if (INTVAL (XEXP (x, 1)) != 0)
6027             *total += COSTS_N_INSNS (3);
6028           break;
6029
6030         default:
6031           return false;
6032         }
6033       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, speed);
6034       return true;
6035
6036     default:
6037       break;
6038     }
6039   return false;
6040 }
6041
6042 /* Calculate the cost of a memory address.  */
6043
6044 static int
6045 avr_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
6046 {
6047   if (GET_CODE (x) == PLUS
6048       && GET_CODE (XEXP (x,1)) == CONST_INT
6049       && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
6050       && INTVAL (XEXP (x,1)) >= 61)
6051     return 18;
6052   if (CONSTANT_ADDRESS_P (x))
6053     {
6054       if (optimize > 0 && io_address_operand (x, QImode))
6055         return 2;
6056       return 4;
6057     }
6058   return 4;
6059 }
6060
6061 /* Test for extra memory constraint 'Q'.
6062    It's a memory address based on Y or Z pointer with valid displacement.  */
6063
6064 int
6065 extra_constraint_Q (rtx x)
6066 {
6067   if (GET_CODE (XEXP (x,0)) == PLUS
6068       && REG_P (XEXP (XEXP (x,0), 0))
6069       && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
6070       && (INTVAL (XEXP (XEXP (x,0), 1))
6071           <= MAX_LD_OFFSET (GET_MODE (x))))
6072     {
6073       rtx xx = XEXP (XEXP (x,0), 0);
6074       int regno = REGNO (xx);
6075       if (TARGET_ALL_DEBUG)
6076         {
6077           fprintf (stderr, ("extra_constraint:\n"
6078                             "reload_completed: %d\n"
6079                             "reload_in_progress: %d\n"),
6080                    reload_completed, reload_in_progress);
6081           debug_rtx (x);
6082         }
6083       if (regno >= FIRST_PSEUDO_REGISTER)
6084         return 1;               /* allocate pseudos */
6085       else if (regno == REG_Z || regno == REG_Y)
6086         return 1;               /* strictly check */
6087       else if (xx == frame_pointer_rtx
6088                || xx == arg_pointer_rtx)
6089         return 1;               /* XXX frame & arg pointer checks */
6090     }
6091   return 0;
6092 }
6093
6094 /* Convert condition code CONDITION to the valid AVR condition code.  */
6095
6096 RTX_CODE
6097 avr_normalize_condition (RTX_CODE condition)
6098 {
6099   switch (condition)
6100     {
6101     case GT:
6102       return GE;
6103     case GTU:
6104       return GEU;
6105     case LE:
6106       return LT;
6107     case LEU:
6108       return LTU;
6109     default:
6110       gcc_unreachable ();
6111     }
6112 }
6113
6114 /* This function optimizes conditional jumps.  */
6115
6116 static void
6117 avr_reorg (void)
6118 {
6119   rtx insn, pattern;
6120   
6121   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6122     {
6123       if (! (GET_CODE (insn) == INSN
6124              || GET_CODE (insn) == CALL_INSN
6125              || GET_CODE (insn) == JUMP_INSN)
6126           || !single_set (insn))
6127         continue;
6128
6129       pattern = PATTERN (insn);
6130
6131       if (GET_CODE (pattern) == PARALLEL)
6132         pattern = XVECEXP (pattern, 0, 0);
6133       if (GET_CODE (pattern) == SET
6134           && SET_DEST (pattern) == cc0_rtx
6135           && compare_diff_p (insn))
6136         {
6137           if (GET_CODE (SET_SRC (pattern)) == COMPARE)
6138             {
6139               /* Now we work under compare insn.  */
6140               
6141               pattern = SET_SRC (pattern);
6142               if (true_regnum (XEXP (pattern,0)) >= 0
6143                   && true_regnum (XEXP (pattern,1)) >= 0 )
6144                 {
6145                   rtx x = XEXP (pattern,0);
6146                   rtx next = next_real_insn (insn);
6147                   rtx pat = PATTERN (next);
6148                   rtx src = SET_SRC (pat);
6149                   rtx t = XEXP (src,0);
6150                   PUT_CODE (t, swap_condition (GET_CODE (t)));
6151                   XEXP (pattern,0) = XEXP (pattern,1);
6152                   XEXP (pattern,1) = x;
6153                   INSN_CODE (next) = -1;
6154                 }
6155               else if (true_regnum (XEXP (pattern, 0)) >= 0
6156                        && XEXP (pattern, 1) == const0_rtx)
6157                 {
6158                   /* This is a tst insn, we can reverse it.  */
6159                   rtx next = next_real_insn (insn);
6160                   rtx pat = PATTERN (next);
6161                   rtx src = SET_SRC (pat);
6162                   rtx t = XEXP (src,0);
6163     
6164                   PUT_CODE (t, swap_condition (GET_CODE (t)));
6165                   XEXP (pattern, 1) = XEXP (pattern, 0);
6166                   XEXP (pattern, 0) = const0_rtx;
6167                   INSN_CODE (next) = -1;
6168                   INSN_CODE (insn) = -1;
6169                 }
6170               else if (true_regnum (XEXP (pattern,0)) >= 0
6171                        && GET_CODE (XEXP (pattern,1)) == CONST_INT)
6172                 {
6173                   rtx x = XEXP (pattern,1);
6174                   rtx next = next_real_insn (insn);
6175                   rtx pat = PATTERN (next);
6176                   rtx src = SET_SRC (pat);
6177                   rtx t = XEXP (src,0);
6178                   enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
6179
6180                   if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
6181                     {
6182                       XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
6183                       PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
6184                       INSN_CODE (next) = -1;
6185                       INSN_CODE (insn) = -1;
6186                     }
6187                 }
6188             }
6189         }
6190     }
6191 }
6192
6193 /* Returns register number for function return value.*/
6194
6195 static inline unsigned int
6196 avr_ret_register (void)
6197 {
6198   return 24;
6199 }
6200
6201 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
6202
6203 static bool
6204 avr_function_value_regno_p (const unsigned int regno)
6205 {
6206   return (regno == avr_ret_register ());
6207 }
6208
6209 /* Create an RTX representing the place where a
6210    library function returns a value of mode MODE.  */
6211
6212 static rtx
6213 avr_libcall_value (enum machine_mode mode,
6214                    const_rtx func ATTRIBUTE_UNUSED)
6215 {
6216   int offs = GET_MODE_SIZE (mode);
6217   if (offs < 2)
6218     offs = 2;
6219   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
6220 }
6221
6222 /* Create an RTX representing the place where a
6223    function returns a value of data type VALTYPE.  */
6224
6225 static rtx
6226 avr_function_value (const_tree type,
6227                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6228                     bool outgoing ATTRIBUTE_UNUSED)
6229 {
6230   unsigned int offs;
6231
6232   if (TYPE_MODE (type) != BLKmode)
6233     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
6234   
6235   offs = int_size_in_bytes (type);
6236   if (offs < 2)
6237     offs = 2;
6238   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
6239     offs = GET_MODE_SIZE (SImode);
6240   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
6241     offs = GET_MODE_SIZE (DImode);
6242   
6243   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
6244 }
6245
6246 int
6247 test_hard_reg_class (enum reg_class rclass, rtx x)
6248 {
6249   int regno = true_regnum (x);
6250   if (regno < 0)
6251     return 0;
6252
6253   if (TEST_HARD_REG_CLASS (rclass, regno))
6254     return 1;
6255
6256   return 0;
6257 }
6258
6259
6260 int
6261 jump_over_one_insn_p (rtx insn, rtx dest)
6262 {
6263   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
6264                       ? XEXP (dest, 0)
6265                       : dest);
6266   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
6267   int dest_addr = INSN_ADDRESSES (uid);
6268   return dest_addr - jump_addr == get_attr_length (insn) + 1;
6269 }
6270
6271 /* Returns 1 if a value of mode MODE can be stored starting with hard
6272    register number REGNO.  On the enhanced core, anything larger than
6273    1 byte must start in even numbered register for "movw" to work
6274    (this way we don't have to check for odd registers everywhere).  */
6275
6276 int
6277 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
6278 {
6279   /* Disallow QImode in stack pointer regs.  */
6280   if ((regno == REG_SP || regno == (REG_SP + 1)) && mode == QImode)
6281     return 0;
6282
6283   /* The only thing that can go into registers r28:r29 is a Pmode.  */
6284   if (regno == REG_Y && mode == Pmode)
6285     return 1;
6286
6287   /* Otherwise disallow all regno/mode combinations that span r28:r29.  */
6288   if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
6289     return 0;
6290
6291   if (mode == QImode)
6292     return 1;
6293
6294   /* Modes larger than QImode occupy consecutive registers.  */
6295   if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
6296     return 0;
6297
6298   /* All modes larger than QImode should start in an even register.  */
6299   return !(regno & 1);
6300 }
6301
6302 const char *
6303 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
6304 {
6305   int tmp;
6306   if (!len)
6307     len = &tmp;
6308       
6309   if (GET_CODE (operands[1]) == CONST_INT)
6310     {
6311       int val = INTVAL (operands[1]);
6312       if ((val & 0xff) == 0)
6313         {
6314           *len = 3;
6315           return (AS2 (mov,%A0,__zero_reg__) CR_TAB
6316                   AS2 (ldi,%2,hi8(%1))       CR_TAB
6317                   AS2 (mov,%B0,%2));
6318         }
6319       else if ((val & 0xff00) == 0)
6320         {
6321           *len = 3;
6322           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
6323                   AS2 (mov,%A0,%2)     CR_TAB
6324                   AS2 (mov,%B0,__zero_reg__));
6325         }
6326       else if ((val & 0xff) == ((val & 0xff00) >> 8))
6327         {
6328           *len = 3;
6329           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
6330                   AS2 (mov,%A0,%2)     CR_TAB
6331                   AS2 (mov,%B0,%2));
6332         }
6333     }
6334   *len = 4;
6335   return (AS2 (ldi,%2,lo8(%1)) CR_TAB
6336           AS2 (mov,%A0,%2)     CR_TAB
6337           AS2 (ldi,%2,hi8(%1)) CR_TAB
6338           AS2 (mov,%B0,%2));
6339 }
6340
6341
6342 const char *
6343 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
6344 {
6345   rtx src = operands[1];
6346   int cnst = (GET_CODE (src) == CONST_INT);
6347
6348   if (len)
6349     {
6350       if (cnst)
6351         *len = 4 + ((INTVAL (src) & 0xff) != 0)
6352                 + ((INTVAL (src) & 0xff00) != 0)
6353                 + ((INTVAL (src) & 0xff0000) != 0)
6354                 + ((INTVAL (src) & 0xff000000) != 0);
6355       else
6356         *len = 8;
6357
6358       return "";
6359     }
6360
6361   if (cnst && ((INTVAL (src) & 0xff) == 0))
6362     output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
6363   else
6364     {
6365       output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
6366       output_asm_insn (AS2 (mov, %A0, %2), operands);
6367     }
6368   if (cnst && ((INTVAL (src) & 0xff00) == 0))
6369     output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
6370   else
6371     {
6372       output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
6373       output_asm_insn (AS2 (mov, %B0, %2), operands);
6374     }
6375   if (cnst && ((INTVAL (src) & 0xff0000) == 0))
6376     output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
6377   else
6378     {
6379       output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
6380       output_asm_insn (AS2 (mov, %C0, %2), operands);
6381     }
6382   if (cnst && ((INTVAL (src) & 0xff000000) == 0))
6383     output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
6384   else
6385     {
6386       output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
6387       output_asm_insn (AS2 (mov, %D0, %2), operands);
6388     }
6389   return "";
6390 }
6391
6392 void
6393 avr_output_bld (rtx operands[], int bit_nr)
6394 {
6395   static char s[] = "bld %A0,0";
6396
6397   s[5] = 'A' + (bit_nr >> 3);
6398   s[8] = '0' + (bit_nr & 7);
6399   output_asm_insn (s, operands);
6400 }
6401
6402 void
6403 avr_output_addr_vec_elt (FILE *stream, int value)
6404 {
6405   switch_to_section (progmem_section);
6406   if (AVR_HAVE_JMP_CALL)
6407     fprintf (stream, "\t.word gs(.L%d)\n", value);
6408   else
6409     fprintf (stream, "\trjmp .L%d\n", value);
6410 }
6411
6412 /* Returns true if SCRATCH are safe to be allocated as a scratch
6413    registers (for a define_peephole2) in the current function.  */
6414
6415 bool
6416 avr_hard_regno_scratch_ok (unsigned int regno)
6417 {
6418   /* Interrupt functions can only use registers that have already been saved
6419      by the prologue, even if they would normally be call-clobbered.  */
6420
6421   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
6422       && !df_regs_ever_live_p (regno))
6423     return false;
6424
6425   return true;
6426 }
6427
6428 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
6429
6430 int
6431 avr_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
6432                           unsigned int new_reg)
6433 {
6434   /* Interrupt functions can only use registers that have already been
6435      saved by the prologue, even if they would normally be
6436      call-clobbered.  */
6437
6438   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
6439       && !df_regs_ever_live_p (new_reg))
6440     return 0;
6441
6442   return 1;
6443 }
6444
6445 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
6446    or memory location in the I/O space (QImode only).
6447
6448    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
6449    Operand 1: register operand to test, or CONST_INT memory address.
6450    Operand 2: bit number.
6451    Operand 3: label to jump to if the test is true.  */
6452
6453 const char *
6454 avr_out_sbxx_branch (rtx insn, rtx operands[])
6455 {
6456   enum rtx_code comp = GET_CODE (operands[0]);
6457   int long_jump = (get_attr_length (insn) >= 4);
6458   int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
6459
6460   if (comp == GE)
6461     comp = EQ;
6462   else if (comp == LT)
6463     comp = NE;
6464
6465   if (reverse)
6466     comp = reverse_condition (comp);
6467
6468   if (GET_CODE (operands[1]) == CONST_INT)
6469     {
6470       if (INTVAL (operands[1]) < 0x40)
6471         {
6472           if (comp == EQ)
6473             output_asm_insn (AS2 (sbis,%m1-0x20,%2), operands);
6474           else
6475             output_asm_insn (AS2 (sbic,%m1-0x20,%2), operands);
6476         }
6477       else
6478         {
6479           output_asm_insn (AS2 (in,__tmp_reg__,%m1-0x20), operands);
6480           if (comp == EQ)
6481             output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
6482           else
6483             output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
6484         }
6485     }
6486   else  /* GET_CODE (operands[1]) == REG */
6487     {
6488       if (GET_MODE (operands[1]) == QImode)
6489         {
6490           if (comp == EQ)
6491             output_asm_insn (AS2 (sbrs,%1,%2), operands);
6492           else
6493             output_asm_insn (AS2 (sbrc,%1,%2), operands);
6494         }
6495       else  /* HImode or SImode */
6496         {
6497           static char buf[] = "sbrc %A1,0";
6498           int bit_nr = INTVAL (operands[2]);
6499           buf[3] = (comp == EQ) ? 's' : 'c';
6500           buf[6] = 'A' + (bit_nr >> 3);
6501           buf[9] = '0' + (bit_nr & 7);
6502           output_asm_insn (buf, operands);
6503         }
6504     }
6505
6506   if (long_jump)
6507     return (AS1 (rjmp,.+4) CR_TAB
6508             AS1 (jmp,%x3));
6509   if (!reverse)
6510     return AS1 (rjmp,%x3);
6511   return "";
6512 }
6513
6514 /* Worker function for TARGET_ASM_CONSTRUCTOR.  */
6515
6516 static void
6517 avr_asm_out_ctor (rtx symbol, int priority)
6518 {
6519   fputs ("\t.global __do_global_ctors\n", asm_out_file);
6520   default_ctor_section_asm_out_constructor (symbol, priority);
6521 }
6522
6523 /* Worker function for TARGET_ASM_DESTRUCTOR.  */
6524
6525 static void
6526 avr_asm_out_dtor (rtx symbol, int priority)
6527 {
6528   fputs ("\t.global __do_global_dtors\n", asm_out_file);
6529   default_dtor_section_asm_out_destructor (symbol, priority);
6530 }
6531
6532 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
6533
6534 static bool
6535 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6536 {
6537   if (TYPE_MODE (type) == BLKmode)
6538     {
6539       HOST_WIDE_INT size = int_size_in_bytes (type);
6540       return (size == -1 || size > 8);
6541     }
6542   else
6543     return false;
6544 }
6545
6546 /* Worker function for CASE_VALUES_THRESHOLD.  */
6547
6548 unsigned int avr_case_values_threshold (void)
6549 {
6550   return (!AVR_HAVE_JMP_CALL || TARGET_CALL_PROLOGUES) ? 8 : 17;
6551 }
6552
6553 /* Helper for __builtin_avr_delay_cycles */
6554
6555 static void
6556 avr_expand_delay_cycles (rtx operands0)
6557 {
6558   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0);
6559   unsigned HOST_WIDE_INT cycles_used;
6560   unsigned HOST_WIDE_INT loop_count;
6561   
6562   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
6563     {
6564       loop_count = ((cycles - 9) / 6) + 1;
6565       cycles_used = ((loop_count - 1) * 6) + 9;
6566       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode)));
6567       cycles -= cycles_used;
6568     }
6569   
6570   if (IN_RANGE (cycles, 262145, 83886081))
6571     {
6572       loop_count = ((cycles - 7) / 5) + 1;
6573       if (loop_count > 0xFFFFFF)
6574         loop_count = 0xFFFFFF;
6575       cycles_used = ((loop_count - 1) * 5) + 7;
6576       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode)));
6577       cycles -= cycles_used;
6578     }
6579   
6580   if (IN_RANGE (cycles, 768, 262144))
6581     {
6582       loop_count = ((cycles - 5) / 4) + 1;
6583       if (loop_count > 0xFFFF)
6584         loop_count = 0xFFFF;
6585       cycles_used = ((loop_count - 1) * 4) + 5;
6586       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode)));
6587       cycles -= cycles_used;
6588     }
6589   
6590   if (IN_RANGE (cycles, 6, 767))
6591     {
6592       loop_count = cycles / 3;
6593       if (loop_count > 255) 
6594         loop_count = 255;
6595       cycles_used = loop_count * 3;
6596       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode)));
6597       cycles -= cycles_used;
6598       }
6599   
6600   while (cycles >= 2)
6601     {
6602       emit_insn (gen_nopv (GEN_INT(2)));
6603       cycles -= 2;
6604     }
6605
6606   if (cycles == 1)
6607     {
6608       emit_insn (gen_nopv (GEN_INT(1)));
6609       cycles--;
6610     }
6611 }
6612
6613 /* IDs for all the AVR builtins.  */
6614
6615 enum avr_builtin_id
6616   {
6617     AVR_BUILTIN_NOP,
6618     AVR_BUILTIN_SEI,
6619     AVR_BUILTIN_CLI,
6620     AVR_BUILTIN_WDR,
6621     AVR_BUILTIN_SLEEP,
6622     AVR_BUILTIN_SWAP,
6623     AVR_BUILTIN_FMUL,
6624     AVR_BUILTIN_FMULS,
6625     AVR_BUILTIN_FMULSU,
6626     AVR_BUILTIN_DELAY_CYCLES
6627   };
6628
6629 #define DEF_BUILTIN(NAME, TYPE, CODE)                                   \
6630   do                                                                    \
6631     {                                                                   \
6632       add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,        \
6633                             NULL, NULL_TREE);                           \
6634     } while (0)
6635
6636
6637 /* Implement `TARGET_INIT_BUILTINS' */
6638 /* Set up all builtin functions for this target.  */
6639
6640 static void
6641 avr_init_builtins (void)
6642 {
6643   tree void_ftype_void
6644     = build_function_type_list (void_type_node, NULL_TREE);
6645   tree uchar_ftype_uchar
6646     = build_function_type_list (unsigned_char_type_node, 
6647                                 unsigned_char_type_node,
6648                                 NULL_TREE);
6649   tree uint_ftype_uchar_uchar
6650     = build_function_type_list (unsigned_type_node, 
6651                                 unsigned_char_type_node,
6652                                 unsigned_char_type_node, 
6653                                 NULL_TREE);
6654   tree int_ftype_char_char
6655     = build_function_type_list (integer_type_node, 
6656                                 char_type_node,
6657                                 char_type_node, 
6658                                 NULL_TREE);
6659   tree int_ftype_char_uchar
6660     = build_function_type_list (integer_type_node, 
6661                                 char_type_node,
6662                                 unsigned_char_type_node, 
6663                                 NULL_TREE);
6664   tree void_ftype_ulong
6665     = build_function_type_list (void_type_node, 
6666                                 long_unsigned_type_node,
6667                                 NULL_TREE);
6668
6669   DEF_BUILTIN ("__builtin_avr_nop", void_ftype_void, AVR_BUILTIN_NOP);
6670   DEF_BUILTIN ("__builtin_avr_sei", void_ftype_void, AVR_BUILTIN_SEI);
6671   DEF_BUILTIN ("__builtin_avr_cli", void_ftype_void, AVR_BUILTIN_CLI);
6672   DEF_BUILTIN ("__builtin_avr_wdr", void_ftype_void, AVR_BUILTIN_WDR);
6673   DEF_BUILTIN ("__builtin_avr_sleep", void_ftype_void, AVR_BUILTIN_SLEEP);
6674   DEF_BUILTIN ("__builtin_avr_swap", uchar_ftype_uchar, AVR_BUILTIN_SWAP);
6675   DEF_BUILTIN ("__builtin_avr_delay_cycles", void_ftype_ulong, 
6676                AVR_BUILTIN_DELAY_CYCLES);
6677
6678   if (AVR_HAVE_MUL)
6679     {
6680       /* FIXME: If !AVR_HAVE_MUL, make respective functions available
6681          in libgcc. For fmul and fmuls this is straight forward with
6682          upcoming fixed point support. */
6683       
6684       DEF_BUILTIN ("__builtin_avr_fmul", uint_ftype_uchar_uchar, 
6685                    AVR_BUILTIN_FMUL);
6686       DEF_BUILTIN ("__builtin_avr_fmuls", int_ftype_char_char, 
6687                    AVR_BUILTIN_FMULS);
6688       DEF_BUILTIN ("__builtin_avr_fmulsu", int_ftype_char_uchar, 
6689                    AVR_BUILTIN_FMULSU);
6690     }
6691 }
6692
6693 #undef DEF_BUILTIN
6694
6695 struct avr_builtin_description
6696 {
6697   const enum insn_code icode;
6698   const char *const name;
6699   const enum avr_builtin_id id;
6700 };
6701
6702 static const struct avr_builtin_description
6703 bdesc_1arg[] =
6704   {
6705     { CODE_FOR_rotlqi3_4, "__builtin_avr_swap", AVR_BUILTIN_SWAP }
6706   };
6707
6708 static const struct avr_builtin_description
6709 bdesc_2arg[] =
6710   {
6711     { CODE_FOR_fmul, "__builtin_avr_fmul", AVR_BUILTIN_FMUL },
6712     { CODE_FOR_fmuls, "__builtin_avr_fmuls", AVR_BUILTIN_FMULS },
6713     { CODE_FOR_fmulsu, "__builtin_avr_fmulsu", AVR_BUILTIN_FMULSU }
6714   };
6715
6716 /* Subroutine of avr_expand_builtin to take care of unop insns.  */
6717
6718 static rtx
6719 avr_expand_unop_builtin (enum insn_code icode, tree exp,
6720                          rtx target)
6721 {
6722   rtx pat;
6723   tree arg0 = CALL_EXPR_ARG (exp, 0);
6724   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6725   enum machine_mode op0mode = GET_MODE (op0);
6726   enum machine_mode tmode = insn_data[icode].operand[0].mode;
6727   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6728
6729   if (! target
6730       || GET_MODE (target) != tmode
6731       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6732     {
6733       target = gen_reg_rtx (tmode);
6734     }
6735
6736   if (op0mode == SImode && mode0 == HImode)
6737     {
6738       op0mode = HImode;
6739       op0 = gen_lowpart (HImode, op0);
6740     }
6741   
6742   gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
6743
6744   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6745     op0 = copy_to_mode_reg (mode0, op0);
6746
6747   pat = GEN_FCN (icode) (target, op0);
6748   if (! pat)
6749     return 0;
6750   
6751   emit_insn (pat);
6752   
6753   return target;
6754 }
6755
6756
6757 /* Subroutine of avr_expand_builtin to take care of binop insns.  */
6758
6759 static rtx
6760 avr_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
6761 {
6762   rtx pat;
6763   tree arg0 = CALL_EXPR_ARG (exp, 0);
6764   tree arg1 = CALL_EXPR_ARG (exp, 1);
6765   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6766   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6767   enum machine_mode op0mode = GET_MODE (op0);
6768   enum machine_mode op1mode = GET_MODE (op1);
6769   enum machine_mode tmode = insn_data[icode].operand[0].mode;
6770   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6771   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6772
6773   if (! target
6774       || GET_MODE (target) != tmode
6775       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6776     {
6777       target = gen_reg_rtx (tmode);
6778     }
6779
6780   if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
6781     {
6782       op0mode = HImode;
6783       op0 = gen_lowpart (HImode, op0);
6784     }
6785   
6786   if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
6787     {
6788       op1mode = HImode;
6789       op1 = gen_lowpart (HImode, op1);
6790     }
6791   
6792   /* In case the insn wants input operands in modes different from
6793      the result, abort.  */
6794   
6795   gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
6796               && (op1mode == mode1 || op1mode == VOIDmode));
6797
6798   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6799     op0 = copy_to_mode_reg (mode0, op0);
6800   
6801   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6802     op1 = copy_to_mode_reg (mode1, op1);
6803
6804   pat = GEN_FCN (icode) (target, op0, op1);
6805   
6806   if (! pat)
6807     return 0;
6808
6809   emit_insn (pat);
6810   return target;
6811 }
6812
6813
6814 /* Expand an expression EXP that calls a built-in function,
6815    with result going to TARGET if that's convenient
6816    (and in mode MODE if that's convenient).
6817    SUBTARGET may be used as the target for computing one of EXP's operands.
6818    IGNORE is nonzero if the value is to be ignored.  */
6819
6820 static rtx
6821 avr_expand_builtin (tree exp, rtx target,
6822                     rtx subtarget ATTRIBUTE_UNUSED,
6823                     enum machine_mode mode ATTRIBUTE_UNUSED,
6824                     int ignore ATTRIBUTE_UNUSED)
6825 {
6826   size_t i;
6827   const struct avr_builtin_description *d;
6828   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6829   unsigned int id = DECL_FUNCTION_CODE (fndecl);
6830   tree arg0;
6831   rtx op0;
6832
6833   switch (id)
6834     {
6835     case AVR_BUILTIN_NOP:
6836       emit_insn (gen_nopv (GEN_INT(1)));
6837       return 0;
6838       
6839     case AVR_BUILTIN_SEI:
6840       emit_insn (gen_enable_interrupt ());
6841       return 0;
6842       
6843     case AVR_BUILTIN_CLI:
6844       emit_insn (gen_disable_interrupt ());
6845       return 0;
6846       
6847     case AVR_BUILTIN_WDR:
6848       emit_insn (gen_wdr ());
6849       return 0;
6850       
6851     case AVR_BUILTIN_SLEEP:
6852       emit_insn (gen_sleep ());
6853       return 0;
6854       
6855     case AVR_BUILTIN_DELAY_CYCLES:
6856       {
6857         arg0 = CALL_EXPR_ARG (exp, 0);
6858         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6859
6860         if (! CONST_INT_P (op0))
6861           error ("__builtin_avr_delay_cycles expects a compile time integer constant.");
6862
6863         avr_expand_delay_cycles (op0);
6864         return 0;
6865       }
6866     }
6867
6868   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
6869     if (d->id == id)
6870       return avr_expand_unop_builtin (d->icode, exp, target);
6871
6872   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
6873     if (d->id == id)
6874       return avr_expand_binop_builtin (d->icode, exp, target);
6875
6876   gcc_unreachable ();
6877 }
6878
6879
6880 #include "gt-avr.h"