OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc1/] [gcc/] [config/] [avr/] [avr.c] - Blame information for rev 338

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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