OSDN Git Service

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