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