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