OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [avr/] [avr.c] - Blame information for rev 820

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.