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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 38 julius
/* Subroutines used for code generation on the Argonaut ARC cpu.
2
   Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
   2005, 2007
4
   Free Software Foundation, Inc.
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
/* ??? This is an old port, and is undoubtedly suffering from bit rot.  */
23
 
24
#include "config.h"
25
#include "system.h"
26
#include "coretypes.h"
27
#include "tm.h"
28
#include "tree.h"
29
#include "rtl.h"
30
#include "regs.h"
31
#include "hard-reg-set.h"
32
#include "real.h"
33
#include "insn-config.h"
34
#include "conditions.h"
35
#include "output.h"
36
#include "insn-attr.h"
37
#include "flags.h"
38
#include "function.h"
39
#include "expr.h"
40
#include "recog.h"
41
#include "toplev.h"
42
#include "tm_p.h"
43
#include "target.h"
44
#include "target-def.h"
45
 
46
/* Which cpu we're compiling for.  */
47
int arc_cpu_type;
48
 
49
/* Name of mangle string to add to symbols to separate code compiled for each
50
   cpu (or NULL).  */
51
const char *arc_mangle_cpu;
52
 
53
/* Save the operands last given to a compare for use when we
54
   generate a scc or bcc insn.  */
55
rtx arc_compare_op0, arc_compare_op1;
56
 
57
/* Name of text, data, and rodata sections used in varasm.c.  */
58
const char *arc_text_section;
59
const char *arc_data_section;
60
const char *arc_rodata_section;
61
 
62
/* Array of valid operand punctuation characters.  */
63
char arc_punct_chars[256];
64
 
65
/* Variables used by arc_final_prescan_insn to implement conditional
66
   execution.  */
67
static int arc_ccfsm_state;
68
static int arc_ccfsm_current_cc;
69
static rtx arc_ccfsm_target_insn;
70
static int arc_ccfsm_target_label;
71
 
72
/* The maximum number of insns skipped which will be conditionalised if
73
   possible.  */
74
#define MAX_INSNS_SKIPPED 3
75
 
76
/* A nop is needed between a 4 byte insn that sets the condition codes and
77
   a branch that uses them (the same isn't true for an 8 byte insn that sets
78
   the condition codes).  Set by arc_final_prescan_insn.  Used by
79
   arc_print_operand.  */
80
static int last_insn_set_cc_p;
81
static int current_insn_set_cc_p;
82
static bool arc_handle_option (size_t, const char *, int);
83
static void record_cc_ref (rtx);
84
static void arc_init_reg_tables (void);
85
static int get_arc_condition_code (rtx);
86
const struct attribute_spec arc_attribute_table[];
87
static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
88
static bool arc_assemble_integer (rtx, unsigned int, int);
89
static void arc_output_function_prologue (FILE *, HOST_WIDE_INT);
90
static void arc_output_function_epilogue (FILE *, HOST_WIDE_INT);
91
static void arc_file_start (void);
92
static void arc_internal_label (FILE *, const char *, unsigned long);
93
static void arc_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
94
                                        tree, int *, int);
95
static bool arc_rtx_costs (rtx, int, int, int *);
96
static int arc_address_cost (rtx);
97
static void arc_external_libcall (rtx);
98
static bool arc_return_in_memory (tree, tree);
99
static bool arc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
100
                                   tree, bool);
101
 
102
/* Initialize the GCC target structure.  */
103
#undef TARGET_ASM_ALIGNED_HI_OP
104
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
105
#undef TARGET_ASM_ALIGNED_SI_OP
106
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
107
#undef TARGET_ASM_INTEGER
108
#define TARGET_ASM_INTEGER arc_assemble_integer
109
 
110
#undef TARGET_ASM_FUNCTION_PROLOGUE
111
#define TARGET_ASM_FUNCTION_PROLOGUE arc_output_function_prologue
112
#undef TARGET_ASM_FUNCTION_EPILOGUE
113
#define TARGET_ASM_FUNCTION_EPILOGUE arc_output_function_epilogue
114
#undef TARGET_ASM_FILE_START
115
#define TARGET_ASM_FILE_START arc_file_start
116
#undef TARGET_ATTRIBUTE_TABLE
117
#define TARGET_ATTRIBUTE_TABLE arc_attribute_table
118
#undef TARGET_ASM_INTERNAL_LABEL
119
#define TARGET_ASM_INTERNAL_LABEL arc_internal_label
120
#undef TARGET_ASM_EXTERNAL_LIBCALL
121
#define TARGET_ASM_EXTERNAL_LIBCALL arc_external_libcall
122
 
123
#undef TARGET_HANDLE_OPTION
124
#define TARGET_HANDLE_OPTION arc_handle_option
125
 
126
#undef TARGET_RTX_COSTS
127
#define TARGET_RTX_COSTS arc_rtx_costs
128
#undef TARGET_ADDRESS_COST
129
#define TARGET_ADDRESS_COST arc_address_cost
130
 
131
#undef TARGET_PROMOTE_FUNCTION_ARGS
132
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
133
#undef TARGET_PROMOTE_FUNCTION_RETURN
134
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
135
#undef TARGET_PROMOTE_PROTOTYPES
136
#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
137
 
138
#undef TARGET_RETURN_IN_MEMORY
139
#define TARGET_RETURN_IN_MEMORY arc_return_in_memory
140
#undef TARGET_PASS_BY_REFERENCE
141
#define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
142
#undef TARGET_CALLEE_COPIES
143
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
144
 
145
#undef TARGET_SETUP_INCOMING_VARARGS
146
#define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
147
 
148
struct gcc_target targetm = TARGET_INITIALIZER;
149
 
150
/* Implement TARGET_HANDLE_OPTION.  */
151
 
152
static bool
153
arc_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
154
{
155
  switch (code)
156
    {
157
    case OPT_mcpu_:
158
      return strcmp (arg, "base") == 0 || ARC_EXTENSION_CPU (arg);
159
 
160
    default:
161
      return true;
162
    }
163
}
164
 
165
/* Called by OVERRIDE_OPTIONS to initialize various things.  */
166
 
167
void
168
arc_init (void)
169
{
170
  char *tmp;
171
 
172
  /* Set the pseudo-ops for the various standard sections.  */
173
  arc_text_section = tmp = xmalloc (strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1);
174
  sprintf (tmp, ARC_SECTION_FORMAT, arc_text_string);
175
  arc_data_section = tmp = xmalloc (strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1);
176
  sprintf (tmp, ARC_SECTION_FORMAT, arc_data_string);
177
  arc_rodata_section = tmp = xmalloc (strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1);
178
  sprintf (tmp, ARC_SECTION_FORMAT, arc_rodata_string);
179
 
180
  arc_init_reg_tables ();
181
 
182
  /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
183
  memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
184
  arc_punct_chars['#'] = 1;
185
  arc_punct_chars['*'] = 1;
186
  arc_punct_chars['?'] = 1;
187
  arc_punct_chars['!'] = 1;
188
  arc_punct_chars['~'] = 1;
189
}
190
 
191
/* The condition codes of the ARC, and the inverse function.  */
192
static const char *const arc_condition_codes[] =
193
{
194
  "al", 0, "eq", "ne", "p", "n", "c", "nc", "v", "nv",
195
  "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
196
};
197
 
198
#define ARC_INVERSE_CONDITION_CODE(X)  ((X) ^ 1)
199
 
200
/* Returns the index of the ARC condition code string in
201
   `arc_condition_codes'.  COMPARISON should be an rtx like
202
   `(eq (...) (...))'.  */
203
 
204
static int
205
get_arc_condition_code (rtx comparison)
206
{
207
  switch (GET_CODE (comparison))
208
    {
209
    case EQ : return 2;
210
    case NE : return 3;
211
    case GT : return 10;
212
    case LE : return 11;
213
    case GE : return 12;
214
    case LT : return 13;
215
    case GTU : return 14;
216
    case LEU : return 15;
217
    case LTU : return 6;
218
    case GEU : return 7;
219
    default : gcc_unreachable ();
220
    }
221
  /*NOTREACHED*/
222
  return (42);
223
}
224
 
225
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
226
   return the mode to be used for the comparison.  */
227
 
228
enum machine_mode
229
arc_select_cc_mode (enum rtx_code op,
230
                    rtx x ATTRIBUTE_UNUSED,
231
                    rtx y ATTRIBUTE_UNUSED)
232
{
233
  switch (op)
234
    {
235
    case EQ :
236
    case NE :
237
      return CCZNmode;
238
    default :
239
      switch (GET_CODE (x))
240
        {
241
        case AND :
242
        case IOR :
243
        case XOR :
244
        case SIGN_EXTEND :
245
        case ZERO_EXTEND :
246
          return CCZNmode;
247
        case ASHIFT :
248
        case ASHIFTRT :
249
        case LSHIFTRT :
250
          return CCZNCmode;
251
        default:
252
          break;
253
        }
254
    }
255
  return CCmode;
256
}
257
 
258
/* Vectors to keep interesting information about registers where it can easily
259
   be got.  We use to use the actual mode value as the bit number, but there
260
   is (or may be) more than 32 modes now.  Instead we use two tables: one
261
   indexed by hard register number, and one indexed by mode.  */
262
 
263
/* The purpose of arc_mode_class is to shrink the range of modes so that
264
   they all fit (as bit numbers) in a 32 bit word (again).  Each real mode is
265
   mapped into one arc_mode_class mode.  */
266
 
267
enum arc_mode_class {
268
  C_MODE,
269
  S_MODE, D_MODE, T_MODE, O_MODE,
270
  SF_MODE, DF_MODE, TF_MODE, OF_MODE
271
};
272
 
273
/* Modes for condition codes.  */
274
#define C_MODES (1 << (int) C_MODE)
275
 
276
/* Modes for single-word and smaller quantities.  */
277
#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
278
 
279
/* Modes for double-word and smaller quantities.  */
280
#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
281
 
282
/* Modes for quad-word and smaller quantities.  */
283
#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
284
 
285
/* Value is 1 if register/mode pair is acceptable on arc.  */
286
 
287
const unsigned int arc_hard_regno_mode_ok[] = {
288
  T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
289
  T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
290
  T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
291
  D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
292
 
293
  /* ??? Leave these as S_MODES for now.  */
294
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
295
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
296
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
297
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES
298
};
299
 
300
unsigned int arc_mode_class [NUM_MACHINE_MODES];
301
 
302
enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
303
 
304
static void
305
arc_init_reg_tables (void)
306
{
307
  int i;
308
 
309
  for (i = 0; i < NUM_MACHINE_MODES; i++)
310
    {
311
      switch (GET_MODE_CLASS (i))
312
        {
313
        case MODE_INT:
314
        case MODE_PARTIAL_INT:
315
        case MODE_COMPLEX_INT:
316
          if (GET_MODE_SIZE (i) <= 4)
317
            arc_mode_class[i] = 1 << (int) S_MODE;
318
          else if (GET_MODE_SIZE (i) == 8)
319
            arc_mode_class[i] = 1 << (int) D_MODE;
320
          else if (GET_MODE_SIZE (i) == 16)
321
            arc_mode_class[i] = 1 << (int) T_MODE;
322
          else if (GET_MODE_SIZE (i) == 32)
323
            arc_mode_class[i] = 1 << (int) O_MODE;
324
          else
325
            arc_mode_class[i] = 0;
326
          break;
327
        case MODE_FLOAT:
328
        case MODE_COMPLEX_FLOAT:
329
          if (GET_MODE_SIZE (i) <= 4)
330
            arc_mode_class[i] = 1 << (int) SF_MODE;
331
          else if (GET_MODE_SIZE (i) == 8)
332
            arc_mode_class[i] = 1 << (int) DF_MODE;
333
          else if (GET_MODE_SIZE (i) == 16)
334
            arc_mode_class[i] = 1 << (int) TF_MODE;
335
          else if (GET_MODE_SIZE (i) == 32)
336
            arc_mode_class[i] = 1 << (int) OF_MODE;
337
          else
338
            arc_mode_class[i] = 0;
339
          break;
340
        case MODE_CC:
341
          arc_mode_class[i] = 1 << (int) C_MODE;
342
          break;
343
        default:
344
          arc_mode_class[i] = 0;
345
          break;
346
        }
347
    }
348
 
349
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
350
    {
351
      if (i < 60)
352
        arc_regno_reg_class[i] = GENERAL_REGS;
353
      else if (i == 60)
354
        arc_regno_reg_class[i] = LPCOUNT_REG;
355
      else if (i == 61)
356
        arc_regno_reg_class[i] = NO_REGS /* CC_REG: must be NO_REGS */;
357
      else
358
        arc_regno_reg_class[i] = NO_REGS;
359
    }
360
}
361
 
362
/* ARC specific attribute support.
363
 
364
   The ARC has these attributes:
365
   interrupt - for interrupt functions
366
*/
367
 
368
const struct attribute_spec arc_attribute_table[] =
369
{
370
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
371
  { "interrupt", 1, 1, true,  false, false, arc_handle_interrupt_attribute },
372
  { NULL,        0, 0, false, false, false, NULL }
373
};
374
 
375
/* Handle an "interrupt" attribute; arguments as in
376
   struct attribute_spec.handler.  */
377
static tree
378
arc_handle_interrupt_attribute (tree *node ATTRIBUTE_UNUSED,
379
                                tree name,
380
                                tree args,
381
                                int flags ATTRIBUTE_UNUSED,
382
                                bool *no_add_attrs)
383
{
384
  tree value = TREE_VALUE (args);
385
 
386
  if (TREE_CODE (value) != STRING_CST)
387
    {
388
      warning (OPT_Wattributes,
389
               "argument of %qs attribute is not a string constant",
390
               IDENTIFIER_POINTER (name));
391
      *no_add_attrs = true;
392
    }
393
  else if (strcmp (TREE_STRING_POINTER (value), "ilink1")
394
           && strcmp (TREE_STRING_POINTER (value), "ilink2"))
395
    {
396
      warning (OPT_Wattributes,
397
               "argument of %qs attribute is not \"ilink1\" or \"ilink2\"",
398
               IDENTIFIER_POINTER (name));
399
      *no_add_attrs = true;
400
    }
401
 
402
  return NULL_TREE;
403
}
404
 
405
 
406
/* Acceptable arguments to the call insn.  */
407
 
408
int
409
call_address_operand (rtx op, enum machine_mode mode)
410
{
411
  return (symbolic_operand (op, mode)
412
          || (GET_CODE (op) == CONST_INT && LEGITIMATE_CONSTANT_P (op))
413
          || (GET_CODE (op) == REG));
414
}
415
 
416
int
417
call_operand (rtx op, enum machine_mode mode)
418
{
419
  if (GET_CODE (op) != MEM)
420
    return 0;
421
  op = XEXP (op, 0);
422
  return call_address_operand (op, mode);
423
}
424
 
425
/* Returns 1 if OP is a symbol reference.  */
426
 
427
int
428
symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
429
{
430
  switch (GET_CODE (op))
431
    {
432
    case SYMBOL_REF:
433
    case LABEL_REF:
434
    case CONST :
435
      return 1;
436
    default:
437
      return 0;
438
    }
439
}
440
 
441
/* Return truth value of statement that OP is a symbolic memory
442
   operand of mode MODE.  */
443
 
444
int
445
symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
446
{
447
  if (GET_CODE (op) == SUBREG)
448
    op = SUBREG_REG (op);
449
  if (GET_CODE (op) != MEM)
450
    return 0;
451
  op = XEXP (op, 0);
452
  return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
453
          || GET_CODE (op) == LABEL_REF);
454
}
455
 
456
/* Return true if OP is a short immediate (shimm) value.  */
457
 
458
int
459
short_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
460
{
461
  if (GET_CODE (op) != CONST_INT)
462
    return 0;
463
  return SMALL_INT (INTVAL (op));
464
}
465
 
466
/* Return true if OP will require a long immediate (limm) value.
467
   This is currently only used when calculating length attributes.  */
468
 
469
int
470
long_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
471
{
472
  switch (GET_CODE (op))
473
    {
474
    case SYMBOL_REF :
475
    case LABEL_REF :
476
    case CONST :
477
      return 1;
478
    case CONST_INT :
479
      return !SMALL_INT (INTVAL (op));
480
    case CONST_DOUBLE :
481
      /* These can happen because large unsigned 32 bit constants are
482
         represented this way (the multiplication patterns can cause these
483
         to be generated).  They also occur for SFmode values.  */
484
      return 1;
485
    default:
486
      break;
487
    }
488
  return 0;
489
}
490
 
491
/* Return true if OP is a MEM that when used as a load or store address will
492
   require an 8 byte insn.
493
   Load and store instructions don't allow the same possibilities but they're
494
   similar enough that this one function will do.
495
   This is currently only used when calculating length attributes.  */
496
 
497
int
498
long_immediate_loadstore_operand (rtx op,
499
                                  enum machine_mode mode ATTRIBUTE_UNUSED)
500
{
501
  if (GET_CODE (op) != MEM)
502
    return 0;
503
 
504
  op = XEXP (op, 0);
505
  switch (GET_CODE (op))
506
    {
507
    case SYMBOL_REF :
508
    case LABEL_REF :
509
    case CONST :
510
      return 1;
511
    case CONST_INT :
512
      /* This must be handled as "st c,[limm]".  Ditto for load.
513
         Technically, the assembler could translate some possibilities to
514
         "st c,[limm/2 + limm/2]" if limm/2 will fit in a shimm, but we don't
515
         assume that it does.  */
516
      return 1;
517
    case CONST_DOUBLE :
518
      /* These can happen because large unsigned 32 bit constants are
519
         represented this way (the multiplication patterns can cause these
520
         to be generated).  They also occur for SFmode values.  */
521
      return 1;
522
    case REG :
523
      return 0;
524
    case PLUS :
525
      if (GET_CODE (XEXP (op, 1)) == CONST_INT
526
          && !SMALL_INT (INTVAL (XEXP (op, 1))))
527
        return 1;
528
      return 0;
529
    default:
530
      break;
531
    }
532
  return 0;
533
}
534
 
535
/* Return true if OP is an acceptable argument for a single word
536
   move source.  */
537
 
538
int
539
move_src_operand (rtx op, enum machine_mode mode)
540
{
541
  switch (GET_CODE (op))
542
    {
543
    case SYMBOL_REF :
544
    case LABEL_REF :
545
    case CONST :
546
      return 1;
547
    case CONST_INT :
548
      return (LARGE_INT (INTVAL (op)));
549
    case CONST_DOUBLE :
550
      /* We can handle DImode integer constants in SImode if the value
551
         (signed or unsigned) will fit in 32 bits.  This is needed because
552
         large unsigned 32 bit constants are represented as CONST_DOUBLEs.  */
553
      if (mode == SImode)
554
        return arc_double_limm_p (op);
555
      /* We can handle 32 bit floating point constants.  */
556
      if (mode == SFmode)
557
        return GET_MODE (op) == SFmode;
558
      return 0;
559
    case REG :
560
      return register_operand (op, mode);
561
    case SUBREG :
562
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
563
         pseudo-reg and is now a stack slot.  */
564
      if (GET_CODE (SUBREG_REG (op)) == MEM)
565
        return address_operand (XEXP (SUBREG_REG (op), 0), mode);
566
      else
567
        return register_operand (op, mode);
568
    case MEM :
569
      return address_operand (XEXP (op, 0), mode);
570
    default :
571
      return 0;
572
    }
573
}
574
 
575
/* Return true if OP is an acceptable argument for a double word
576
   move source.  */
577
 
578
int
579
move_double_src_operand (rtx op, enum machine_mode mode)
580
{
581
  switch (GET_CODE (op))
582
    {
583
    case REG :
584
      return register_operand (op, mode);
585
    case SUBREG :
586
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
587
         pseudo-reg and is now a stack slot.  */
588
      if (GET_CODE (SUBREG_REG (op)) == MEM)
589
        return move_double_src_operand (SUBREG_REG (op), mode);
590
      else
591
        return register_operand (op, mode);
592
    case MEM :
593
      /* Disallow auto inc/dec for now.  */
594
      if (GET_CODE (XEXP (op, 0)) == PRE_DEC
595
          || GET_CODE (XEXP (op, 0)) == PRE_INC)
596
        return 0;
597
      return address_operand (XEXP (op, 0), mode);
598
    case CONST_INT :
599
    case CONST_DOUBLE :
600
      return 1;
601
    default :
602
      return 0;
603
    }
604
}
605
 
606
/* Return true if OP is an acceptable argument for a move destination.  */
607
 
608
int
609
move_dest_operand (rtx op, enum machine_mode mode)
610
{
611
  switch (GET_CODE (op))
612
    {
613
    case REG :
614
      return register_operand (op, mode);
615
    case SUBREG :
616
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
617
         pseudo-reg and is now a stack slot.  */
618
      if (GET_CODE (SUBREG_REG (op)) == MEM)
619
        return address_operand (XEXP (SUBREG_REG (op), 0), mode);
620
      else
621
        return register_operand (op, mode);
622
    case MEM :
623
      return address_operand (XEXP (op, 0), mode);
624
    default :
625
      return 0;
626
    }
627
}
628
 
629
/* Return true if OP is valid load with update operand.  */
630
 
631
int
632
load_update_operand (rtx op, enum machine_mode mode)
633
{
634
  if (GET_CODE (op) != MEM
635
      || GET_MODE (op) != mode)
636
    return 0;
637
  op = XEXP (op, 0);
638
  if (GET_CODE (op) != PLUS
639
      || GET_MODE (op) != Pmode
640
      || !register_operand (XEXP (op, 0), Pmode)
641
      || !nonmemory_operand (XEXP (op, 1), Pmode))
642
    return 0;
643
  return 1;
644
}
645
 
646
/* Return true if OP is valid store with update operand.  */
647
 
648
int
649
store_update_operand (rtx op, enum machine_mode mode)
650
{
651
  if (GET_CODE (op) != MEM
652
      || GET_MODE (op) != mode)
653
    return 0;
654
  op = XEXP (op, 0);
655
  if (GET_CODE (op) != PLUS
656
      || GET_MODE (op) != Pmode
657
      || !register_operand (XEXP (op, 0), Pmode)
658
      || !(GET_CODE (XEXP (op, 1)) == CONST_INT
659
           && SMALL_INT (INTVAL (XEXP (op, 1)))))
660
    return 0;
661
  return 1;
662
}
663
 
664
/* Return true if OP is a non-volatile non-immediate operand.
665
   Volatile memory refs require a special "cache-bypass" instruction
666
   and only the standard movXX patterns are set up to handle them.  */
667
 
668
int
669
nonvol_nonimm_operand (rtx op, enum machine_mode mode)
670
{
671
  if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
672
    return 0;
673
  return nonimmediate_operand (op, mode);
674
}
675
 
676
/* Accept integer operands in the range -0x80000000..0x7fffffff.  We have
677
   to check the range carefully since this predicate is used in DImode
678
   contexts.  */
679
 
680
int
681
const_sint32_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
682
{
683
  /* All allowed constants will fit a CONST_INT.  */
684
  return (GET_CODE (op) == CONST_INT
685
          && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
686
}
687
 
688
/* Accept integer operands in the range 0..0xffffffff.  We have to check the
689
   range carefully since this predicate is used in DImode contexts.  Also, we
690
   need some extra crud to make it work when hosted on 64-bit machines.  */
691
 
692
int
693
const_uint32_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
694
{
695
#if HOST_BITS_PER_WIDE_INT > 32
696
  /* All allowed constants will fit a CONST_INT.  */
697
  return (GET_CODE (op) == CONST_INT
698
          && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
699
#else
700
  return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
701
          || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
702
#endif
703
}
704
 
705
/* Return 1 if OP is a comparison operator valid for the mode of CC.
706
   This allows the use of MATCH_OPERATOR to recognize all the branch insns.
707
 
708
   Some insns only set a few bits in the condition code.  So only allow those
709
   comparisons that use the bits that are valid.  */
710
 
711
int
712
proper_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
713
{
714
  enum rtx_code code;
715
  if (!COMPARISON_P (op))
716
    return 0;
717
 
718
  code = GET_CODE (op);
719
  if (GET_MODE (XEXP (op, 0)) == CCZNmode)
720
    return (code == EQ || code == NE);
721
  if (GET_MODE (XEXP (op, 0)) == CCZNCmode)
722
    return (code == EQ || code == NE
723
            || code == LTU || code == GEU || code == GTU || code == LEU);
724
  return 1;
725
}
726
 
727
/* Misc. utilities.  */
728
 
729
/* X and Y are two things to compare using CODE.  Emit the compare insn and
730
   return the rtx for the cc reg in the proper mode.  */
731
 
732
rtx
733
gen_compare_reg (enum rtx_code code, rtx x, rtx y)
734
{
735
  enum machine_mode mode = SELECT_CC_MODE (code, x, y);
736
  rtx cc_reg;
737
 
738
  cc_reg = gen_rtx_REG (mode, 61);
739
 
740
  emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
741
                          gen_rtx_COMPARE (mode, x, y)));
742
 
743
  return cc_reg;
744
}
745
 
746
/* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
747
   We assume the value can be either signed or unsigned.  */
748
 
749
int
750
arc_double_limm_p (rtx value)
751
{
752
  HOST_WIDE_INT low, high;
753
 
754
  gcc_assert (GET_CODE (value) == CONST_DOUBLE);
755
 
756
  low = CONST_DOUBLE_LOW (value);
757
  high = CONST_DOUBLE_HIGH (value);
758
 
759
  if (low & 0x80000000)
760
    {
761
      return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
762
              || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
763
                   == - (unsigned HOST_WIDE_INT) 0x80000000)
764
                  && high == -1));
765
    }
766
  else
767
    {
768
      return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
769
    }
770
}
771
 
772
/* Do any needed setup for a variadic function.  For the ARC, we must
773
   create a register parameter block, and then copy any anonymous arguments
774
   in registers to memory.
775
 
776
   CUM has not been updated for the last named argument which has type TYPE
777
   and mode MODE, and we rely on this fact.
778
 
779
   We do things a little weird here.  We're supposed to only allocate space
780
   for the anonymous arguments.  However we need to keep the stack eight byte
781
   aligned.  So we round the space up if necessary, and leave it to va_start
782
   to compensate.  */
783
 
784
static void
785
arc_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
786
                            enum machine_mode mode,
787
                            tree type ATTRIBUTE_UNUSED,
788
                            int *pretend_size,
789
                            int no_rtl)
790
{
791
  int first_anon_arg;
792
 
793
  /* All BLKmode values are passed by reference.  */
794
  gcc_assert (mode != BLKmode);
795
 
796
  first_anon_arg = *cum + ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
797
                           / UNITS_PER_WORD);
798
 
799
  if (first_anon_arg < MAX_ARC_PARM_REGS && !no_rtl)
800
    {
801
      /* Note that first_reg_offset < MAX_ARC_PARM_REGS.  */
802
      int first_reg_offset = first_anon_arg;
803
      /* Size in words to "pretend" allocate.  */
804
      int size = MAX_ARC_PARM_REGS - first_reg_offset;
805
      /* Extra slop to keep stack eight byte aligned.  */
806
      int align_slop = size & 1;
807
      rtx regblock;
808
 
809
      regblock = gen_rtx_MEM (BLKmode,
810
                              plus_constant (arg_pointer_rtx,
811
                                             FIRST_PARM_OFFSET (0)
812
                                             + align_slop * UNITS_PER_WORD));
813
      set_mem_alias_set (regblock, get_varargs_alias_set ());
814
      set_mem_align (regblock, BITS_PER_WORD);
815
      move_block_from_reg (first_reg_offset, regblock,
816
                           MAX_ARC_PARM_REGS - first_reg_offset);
817
 
818
      *pretend_size = ((MAX_ARC_PARM_REGS - first_reg_offset + align_slop)
819
                       * UNITS_PER_WORD);
820
    }
821
}
822
 
823
/* Cost functions.  */
824
 
825
/* Compute a (partial) cost for rtx X.  Return true if the complete
826
   cost has been computed, and false if subexpressions should be
827
   scanned.  In either case, *TOTAL contains the cost result.  */
828
 
829
static bool
830
arc_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
831
{
832
  switch (code)
833
    {
834
      /* Small integers are as cheap as registers.  4 byte values can
835
         be fetched as immediate constants - let's give that the cost
836
         of an extra insn.  */
837
    case CONST_INT:
838
      if (SMALL_INT (INTVAL (x)))
839
        {
840
          *total = 0;
841
          return true;
842
        }
843
      /* FALLTHRU */
844
 
845
    case CONST:
846
    case LABEL_REF:
847
    case SYMBOL_REF:
848
      *total = COSTS_N_INSNS (1);
849
      return true;
850
 
851
    case CONST_DOUBLE:
852
      {
853
        rtx high, low;
854
        split_double (x, &high, &low);
855
        *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (high))
856
                                + !SMALL_INT (INTVAL (low)));
857
        return true;
858
      }
859
 
860
    /* Encourage synth_mult to find a synthetic multiply when reasonable.
861
       If we need more than 12 insns to do a multiply, then go out-of-line,
862
       since the call overhead will be < 10% of the cost of the multiply.  */
863
    case ASHIFT:
864
    case ASHIFTRT:
865
    case LSHIFTRT:
866
      if (TARGET_SHIFTER)
867
        *total = COSTS_N_INSNS (1);
868
      else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
869
        *total = COSTS_N_INSNS (16);
870
      else
871
        *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
872
      return false;
873
 
874
    default:
875
      return false;
876
    }
877
}
878
 
879
 
880
/* Provide the costs of an addressing mode that contains ADDR.
881
   If ADDR is not a valid address, its cost is irrelevant.  */
882
 
883
static int
884
arc_address_cost (rtx addr)
885
{
886
  switch (GET_CODE (addr))
887
    {
888
    case REG :
889
      return 1;
890
 
891
    case LABEL_REF :
892
    case SYMBOL_REF :
893
    case CONST :
894
      return 2;
895
 
896
    case PLUS :
897
      {
898
        register rtx plus0 = XEXP (addr, 0);
899
        register rtx plus1 = XEXP (addr, 1);
900
 
901
        if (GET_CODE (plus0) != REG)
902
          break;
903
 
904
        switch (GET_CODE (plus1))
905
          {
906
          case CONST_INT :
907
            return SMALL_INT (plus1) ? 1 : 2;
908
          case CONST :
909
          case SYMBOL_REF :
910
          case LABEL_REF :
911
            return 2;
912
          default:
913
            break;
914
          }
915
        break;
916
      }
917
    default:
918
      break;
919
    }
920
 
921
  return 4;
922
}
923
 
924
/* Function prologue/epilogue handlers.  */
925
 
926
/* ARC stack frames look like:
927
 
928
             Before call                       After call
929
        +-----------------------+       +-----------------------+
930
        |                       |       |                       |
931
   high |  local variables,     |       |  local variables,     |
932
   mem  |  reg save area, etc.  |       |  reg save area, etc.  |
933
        |                       |       |                       |
934
        +-----------------------+       +-----------------------+
935
        |                       |       |                       |
936
        |  arguments on stack.  |       |  arguments on stack.  |
937
        |                       |       |                       |
938
 SP+16->+-----------------------+FP+48->+-----------------------+
939
        | 4 word save area for  |       |  reg parm save area,  |
940
        | return addr, prev %fp |       |  only created for     |
941
  SP+0->+-----------------------+       |  variable argument    |
942
                                        |  functions            |
943
                                 FP+16->+-----------------------+
944
                                        | 4 word save area for  |
945
                                        | return addr, prev %fp |
946
                                  FP+0->+-----------------------+
947
                                        |                       |
948
                                        |  local variables      |
949
                                        |                       |
950
                                        +-----------------------+
951
                                        |                       |
952
                                        |  register save area   |
953
                                        |                       |
954
                                        +-----------------------+
955
                                        |                       |
956
                                        |  alloca allocations   |
957
                                        |                       |
958
                                        +-----------------------+
959
                                        |                       |
960
                                        |  arguments on stack   |
961
                                        |                       |
962
                                 SP+16->+-----------------------+
963
   low                                  | 4 word save area for  |
964
   memory                               | return addr, prev %fp |
965
                                  SP+0->+-----------------------+
966
 
967
Notes:
968
1) The "reg parm save area" does not exist for non variable argument fns.
969
   The "reg parm save area" can be eliminated completely if we created our
970
   own va-arc.h, but that has tradeoffs as well (so it's not done).  */
971
 
972
/* Structure to be filled in by arc_compute_frame_size with register
973
   save masks, and offsets for the current function.  */
974
struct arc_frame_info
975
{
976
  unsigned int total_size;      /* # bytes that the entire frame takes up.  */
977
  unsigned int extra_size;      /* # bytes of extra stuff.  */
978
  unsigned int pretend_size;    /* # bytes we push and pretend caller did.  */
979
  unsigned int args_size;       /* # bytes that outgoing arguments take up.  */
980
  unsigned int reg_size;        /* # bytes needed to store regs.  */
981
  unsigned int var_size;        /* # bytes that variables take up.  */
982
  unsigned int reg_offset;      /* Offset from new sp to store regs.  */
983
  unsigned int gmask;           /* Mask of saved gp registers.  */
984
  int          initialized;     /* Nonzero if frame size already calculated.  */
985
};
986
 
987
/* Current frame information calculated by arc_compute_frame_size.  */
988
static struct arc_frame_info current_frame_info;
989
 
990
/* Zero structure to initialize current_frame_info.  */
991
static struct arc_frame_info zero_frame_info;
992
 
993
/* Type of function DECL.
994
 
995
   The result is cached.  To reset the cache at the end of a function,
996
   call with DECL = NULL_TREE.  */
997
 
998
enum arc_function_type
999
arc_compute_function_type (tree decl)
1000
{
1001
  tree a;
1002
  /* Cached value.  */
1003
  static enum arc_function_type fn_type = ARC_FUNCTION_UNKNOWN;
1004
  /* Last function we were called for.  */
1005
  static tree last_fn = NULL_TREE;
1006
 
1007
  /* Resetting the cached value?  */
1008
  if (decl == NULL_TREE)
1009
    {
1010
      fn_type = ARC_FUNCTION_UNKNOWN;
1011
      last_fn = NULL_TREE;
1012
      return fn_type;
1013
    }
1014
 
1015
  if (decl == last_fn && fn_type != ARC_FUNCTION_UNKNOWN)
1016
    return fn_type;
1017
 
1018
  /* Assume we have a normal function (not an interrupt handler).  */
1019
  fn_type = ARC_FUNCTION_NORMAL;
1020
 
1021
  /* Now see if this is an interrupt handler.  */
1022
  for (a = DECL_ATTRIBUTES (current_function_decl);
1023
       a;
1024
       a = TREE_CHAIN (a))
1025
    {
1026
      tree name = TREE_PURPOSE (a), args = TREE_VALUE (a);
1027
 
1028
      if (name == get_identifier ("__interrupt__")
1029
          && list_length (args) == 1
1030
          && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
1031
        {
1032
          tree value = TREE_VALUE (args);
1033
 
1034
          if (!strcmp (TREE_STRING_POINTER (value), "ilink1"))
1035
            fn_type = ARC_FUNCTION_ILINK1;
1036
          else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
1037
            fn_type = ARC_FUNCTION_ILINK2;
1038
          else
1039
            gcc_unreachable ();
1040
          break;
1041
        }
1042
    }
1043
 
1044
  last_fn = decl;
1045
  return fn_type;
1046
}
1047
 
1048
#define ILINK1_REGNUM 29
1049
#define ILINK2_REGNUM 30
1050
#define RETURN_ADDR_REGNUM 31
1051
#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
1052
#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
1053
 
1054
/* Tell prologue and epilogue if register REGNO should be saved / restored.
1055
   The return address and frame pointer are treated separately.
1056
   Don't consider them here.  */
1057
#define MUST_SAVE_REGISTER(regno, interrupt_p) \
1058
((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
1059
 && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
1060
 
1061
#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
1062
 
1063
/* Return the bytes needed to compute the frame pointer from the current
1064
   stack pointer.
1065
 
1066
   SIZE is the size needed for local variables.  */
1067
 
1068
unsigned int
1069
arc_compute_frame_size (int size /* # of var. bytes allocated.  */)
1070
{
1071
  int regno;
1072
  unsigned int total_size, var_size, args_size, pretend_size, extra_size;
1073
  unsigned int reg_size, reg_offset;
1074
  unsigned int gmask;
1075
  enum arc_function_type fn_type;
1076
  int interrupt_p;
1077
 
1078
  var_size      = size;
1079
  args_size     = current_function_outgoing_args_size;
1080
  pretend_size  = current_function_pretend_args_size;
1081
  extra_size    = FIRST_PARM_OFFSET (0);
1082
  total_size    = extra_size + pretend_size + args_size + var_size;
1083
  reg_offset    = FIRST_PARM_OFFSET(0) + current_function_outgoing_args_size;
1084
  reg_size      = 0;
1085
  gmask         = 0;
1086
 
1087
  /* See if this is an interrupt handler.  Call used registers must be saved
1088
     for them too.  */
1089
  fn_type = arc_compute_function_type (current_function_decl);
1090
  interrupt_p = ARC_INTERRUPT_P (fn_type);
1091
 
1092
  /* Calculate space needed for registers.
1093
     ??? We ignore the extension registers for now.  */
1094
 
1095
  for (regno = 0; regno <= 31; regno++)
1096
    {
1097
      if (MUST_SAVE_REGISTER (regno, interrupt_p))
1098
        {
1099
          reg_size += UNITS_PER_WORD;
1100
          gmask |= 1 << regno;
1101
        }
1102
    }
1103
 
1104
  total_size += reg_size;
1105
 
1106
  /* If the only space to allocate is the fp/blink save area this is an
1107
     empty frame.  However, if we'll be making a function call we need to
1108
     allocate a stack frame for our callee's fp/blink save area.  */
1109
  if (total_size == extra_size
1110
      && !MUST_SAVE_RETURN_ADDR)
1111
    total_size = extra_size = 0;
1112
 
1113
  total_size = ARC_STACK_ALIGN (total_size);
1114
 
1115
  /* Save computed information.  */
1116
  current_frame_info.total_size   = total_size;
1117
  current_frame_info.extra_size   = extra_size;
1118
  current_frame_info.pretend_size = pretend_size;
1119
  current_frame_info.var_size     = var_size;
1120
  current_frame_info.args_size    = args_size;
1121
  current_frame_info.reg_size     = reg_size;
1122
  current_frame_info.reg_offset   = reg_offset;
1123
  current_frame_info.gmask        = gmask;
1124
  current_frame_info.initialized  = reload_completed;
1125
 
1126
  /* Ok, we're done.  */
1127
  return total_size;
1128
}
1129
 
1130
/* Common code to save/restore registers.  */
1131
 
1132
void
1133
arc_save_restore (FILE *file,
1134
                  const char *base_reg,
1135
                  unsigned int offset,
1136
                  unsigned int gmask,
1137
                  const char *op)
1138
{
1139
  int regno;
1140
 
1141
  if (gmask == 0)
1142
    return;
1143
 
1144
  for (regno = 0; regno <= 31; regno++)
1145
    {
1146
      if ((gmask & (1L << regno)) != 0)
1147
        {
1148
          fprintf (file, "\t%s %s,[%s,%d]\n",
1149
                     op, reg_names[regno], base_reg, offset);
1150
          offset += UNITS_PER_WORD;
1151
        }
1152
    }
1153
}
1154
 
1155
/* Target hook to assemble an integer object.  The ARC version needs to
1156
   emit a special directive for references to labels and function
1157
   symbols.  */
1158
 
1159
static bool
1160
arc_assemble_integer (rtx x, unsigned int size, int aligned_p)
1161
{
1162
  if (size == UNITS_PER_WORD && aligned_p
1163
      && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
1164
          || GET_CODE (x) == LABEL_REF))
1165
    {
1166
      fputs ("\t.word\t%st(", asm_out_file);
1167
      output_addr_const (asm_out_file, x);
1168
      fputs (")\n", asm_out_file);
1169
      return true;
1170
    }
1171
  return default_assemble_integer (x, size, aligned_p);
1172
}
1173
 
1174
/* Set up the stack and frame pointer (if desired) for the function.  */
1175
 
1176
static void
1177
arc_output_function_prologue (FILE *file, HOST_WIDE_INT size)
1178
{
1179
  const char *sp_str = reg_names[STACK_POINTER_REGNUM];
1180
  const char *fp_str = reg_names[FRAME_POINTER_REGNUM];
1181
  unsigned int gmask = current_frame_info.gmask;
1182
  enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
1183
 
1184
  /* If this is an interrupt handler, set up our stack frame.
1185
     ??? Optimize later.  */
1186
  if (ARC_INTERRUPT_P (fn_type))
1187
    {
1188
      fprintf (file, "\t%s interrupt handler\n",
1189
               ASM_COMMENT_START);
1190
      fprintf (file, "\tsub %s,%s,16\n", sp_str, sp_str);
1191
    }
1192
 
1193
  /* This is only for the human reader.  */
1194
  fprintf (file, "\t%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d\n",
1195
           ASM_COMMENT_START, ASM_COMMENT_START,
1196
           current_frame_info.var_size,
1197
           current_frame_info.reg_size / 4,
1198
           current_frame_info.args_size,
1199
           current_frame_info.extra_size);
1200
 
1201
  size = ARC_STACK_ALIGN (size);
1202
  size = (! current_frame_info.initialized
1203
           ? arc_compute_frame_size (size)
1204
           : current_frame_info.total_size);
1205
 
1206
  /* These cases shouldn't happen.  Catch them now.  */
1207
  gcc_assert (size || !gmask);
1208
 
1209
  /* Allocate space for register arguments if this is a variadic function.  */
1210
  if (current_frame_info.pretend_size != 0)
1211
    fprintf (file, "\tsub %s,%s,%d\n",
1212
             sp_str, sp_str, current_frame_info.pretend_size);
1213
 
1214
  /* The home-grown ABI says link register is saved first.  */
1215
  if (MUST_SAVE_RETURN_ADDR)
1216
    fprintf (file, "\tst %s,[%s,%d]\n",
1217
             reg_names[RETURN_ADDR_REGNUM], sp_str, UNITS_PER_WORD);
1218
 
1219
  /* Set up the previous frame pointer next (if we need to).  */
1220
  if (frame_pointer_needed)
1221
    {
1222
      fprintf (file, "\tst %s,[%s]\n", fp_str, sp_str);
1223
      fprintf (file, "\tmov %s,%s\n", fp_str, sp_str);
1224
    }
1225
 
1226
  /* ??? We don't handle the case where the saved regs are more than 252
1227
     bytes away from sp.  This can be handled by decrementing sp once, saving
1228
     the regs, and then decrementing it again.  The epilogue doesn't have this
1229
     problem as the `ld' insn takes reg+limm values (though it would be more
1230
     efficient to avoid reg+limm).  */
1231
 
1232
  /* Allocate the stack frame.  */
1233
  if (size - current_frame_info.pretend_size > 0)
1234
    fprintf (file, "\tsub %s,%s," HOST_WIDE_INT_PRINT_DEC "\n",
1235
             sp_str, sp_str, size - current_frame_info.pretend_size);
1236
 
1237
  /* Save any needed call-saved regs (and call-used if this is an
1238
     interrupt handler).  */
1239
  arc_save_restore (file, sp_str, current_frame_info.reg_offset,
1240
                    /* The zeroing of these two bits is unnecessary,
1241
                       but leave this in for clarity.  */
1242
                    gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
1243
                    "st");
1244
 
1245
  fprintf (file, "\t%s END PROLOGUE\n", ASM_COMMENT_START);
1246
}
1247
 
1248
/* Do any necessary cleanup after a function to restore stack, frame,
1249
   and regs.  */
1250
 
1251
static void
1252
arc_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
1253
{
1254
  rtx epilogue_delay = current_function_epilogue_delay_list;
1255
  int noepilogue = FALSE;
1256
  enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
1257
 
1258
  /* This is only for the human reader.  */
1259
  fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
1260
 
1261
  size = ARC_STACK_ALIGN (size);
1262
  size = (!current_frame_info.initialized
1263
           ? arc_compute_frame_size (size)
1264
           : current_frame_info.total_size);
1265
 
1266
  if (size == 0 && epilogue_delay == 0)
1267
    {
1268
      rtx insn = get_last_insn ();
1269
 
1270
      /* If the last insn was a BARRIER, we don't have to write any code
1271
         because a jump (aka return) was put there.  */
1272
      if (GET_CODE (insn) == NOTE)
1273
        insn = prev_nonnote_insn (insn);
1274
      if (insn && GET_CODE (insn) == BARRIER)
1275
        noepilogue = TRUE;
1276
    }
1277
 
1278
  if (!noepilogue)
1279
    {
1280
      unsigned int pretend_size = current_frame_info.pretend_size;
1281
      unsigned int frame_size = size - pretend_size;
1282
      int restored, fp_restored_p;
1283
      int can_trust_sp_p = !current_function_calls_alloca;
1284
      const char *sp_str = reg_names[STACK_POINTER_REGNUM];
1285
      const char *fp_str = reg_names[FRAME_POINTER_REGNUM];
1286
 
1287
      /* ??? There are lots of optimizations that can be done here.
1288
         EG: Use fp to restore regs if it's closer.
1289
         Maybe in time we'll do them all.  For now, always restore regs from
1290
         sp, but don't restore sp if we don't have to.  */
1291
 
1292
      if (!can_trust_sp_p)
1293
        {
1294
          gcc_assert (frame_pointer_needed);
1295
          fprintf (file,"\tsub %s,%s,%d\t\t%s sp not trusted here\n",
1296
                   sp_str, fp_str, frame_size, ASM_COMMENT_START);
1297
        }
1298
 
1299
      /* Restore any saved registers.  */
1300
      arc_save_restore (file, sp_str, current_frame_info.reg_offset,
1301
                        /* The zeroing of these two bits is unnecessary,
1302
                           but leave this in for clarity.  */
1303
                        current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
1304
                        "ld");
1305
 
1306
      if (MUST_SAVE_RETURN_ADDR)
1307
        fprintf (file, "\tld %s,[%s,%d]\n",
1308
                 reg_names[RETURN_ADDR_REGNUM],
1309
                 frame_pointer_needed ? fp_str : sp_str,
1310
                 UNITS_PER_WORD + (frame_pointer_needed ? 0 : frame_size));
1311
 
1312
      /* Keep track of how much of the stack pointer we've restored.
1313
         It makes the following a lot more readable.  */
1314
      restored = 0;
1315
      fp_restored_p = 0;
1316
 
1317
      /* We try to emit the epilogue delay slot insn right after the load
1318
         of the return address register so that it can execute with the
1319
         stack intact.  Secondly, loads are delayed.  */
1320
      /* ??? If stack intactness is important, always emit now.  */
1321
      if (MUST_SAVE_RETURN_ADDR && epilogue_delay != NULL_RTX)
1322
        {
1323
          final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
1324
          epilogue_delay = NULL_RTX;
1325
        }
1326
 
1327
      if (frame_pointer_needed)
1328
        {
1329
          /* Try to restore the frame pointer in the delay slot.  We can't,
1330
             however, if any of these is true.  */
1331
          if (epilogue_delay != NULL_RTX
1332
              || !SMALL_INT (frame_size)
1333
              || pretend_size
1334
              || ARC_INTERRUPT_P (fn_type))
1335
            {
1336
              /* Note that we restore fp and sp here!  */
1337
              fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
1338
              restored += frame_size;
1339
              fp_restored_p = 1;
1340
            }
1341
        }
1342
      else if (!SMALL_INT (size /* frame_size + pretend_size */)
1343
               || ARC_INTERRUPT_P (fn_type))
1344
        {
1345
          fprintf (file, "\tadd %s,%s,%d\n", sp_str, sp_str, frame_size);
1346
          restored += frame_size;
1347
        }
1348
 
1349
      /* These must be done before the return insn because the delay slot
1350
         does the final stack restore.  */
1351
      if (ARC_INTERRUPT_P (fn_type))
1352
        {
1353
          if (epilogue_delay)
1354
            {
1355
              final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
1356
            }
1357
        }
1358
 
1359
      /* Emit the return instruction.  */
1360
      {
1361
        static const int regs[4] = {
1362
          0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM
1363
        };
1364
 
1365
        /* Update the flags, if returning from an interrupt handler. */
1366
        if (ARC_INTERRUPT_P (fn_type))
1367
          fprintf (file, "\tj.d.f %s\n", reg_names[regs[fn_type]]);
1368
        else
1369
          fprintf (file, "\tj.d %s\n", reg_names[regs[fn_type]]);
1370
        }
1371
 
1372
      /* If the only register saved is the return address, we need a
1373
         nop, unless we have an instruction to put into it.  Otherwise
1374
         we don't since reloading multiple registers doesn't reference
1375
         the register being loaded.  */
1376
 
1377
      if (ARC_INTERRUPT_P (fn_type))
1378
        fprintf (file, "\tadd %s,%s,16\n", sp_str, sp_str);
1379
      else if (epilogue_delay != NULL_RTX)
1380
        {
1381
          gcc_assert (!frame_pointer_needed || fp_restored_p);
1382
          gcc_assert (restored >= size);
1383
          final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
1384
        }
1385
      else if (frame_pointer_needed && !fp_restored_p)
1386
        {
1387
          gcc_assert (SMALL_INT (frame_size));
1388
          /* Note that we restore fp and sp here!  */
1389
          fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
1390
        }
1391
      else if (restored < size)
1392
        {
1393
          gcc_assert (SMALL_INT (size - restored));
1394
          fprintf (file, "\tadd %s,%s," HOST_WIDE_INT_PRINT_DEC "\n",
1395
                   sp_str, sp_str, size - restored);
1396
        }
1397
      else
1398
        fprintf (file, "\tnop\n");
1399
    }
1400
 
1401
  /* Reset state info for each function.  */
1402
  current_frame_info = zero_frame_info;
1403
  arc_compute_function_type (NULL_TREE);
1404
}
1405
 
1406
/* Define the number of delay slots needed for the function epilogue.
1407
 
1408
   Interrupt handlers can't have any epilogue delay slots (it's always needed
1409
   for something else, I think).  For normal functions, we have to worry about
1410
   using call-saved regs as they'll be restored before the delay slot insn.
1411
   Functions with non-empty frames already have enough choices for the epilogue
1412
   delay slot so for now we only consider functions with empty frames.  */
1413
 
1414
int
1415
arc_delay_slots_for_epilogue (void)
1416
{
1417
  if (arc_compute_function_type (current_function_decl) != ARC_FUNCTION_NORMAL)
1418
    return 0;
1419
  if (!current_frame_info.initialized)
1420
    (void) arc_compute_frame_size (get_frame_size ());
1421
  if (current_frame_info.total_size == 0)
1422
    return 1;
1423
  return 0;
1424
}
1425
 
1426
/* Return true if TRIAL is a valid insn for the epilogue delay slot.
1427
   Any single length instruction which doesn't reference the stack or frame
1428
   pointer or any call-saved register is OK.  SLOT will always be 0.  */
1429
 
1430
int
1431
arc_eligible_for_epilogue_delay (rtx trial, int slot)
1432
{
1433
  gcc_assert (!slot);
1434
 
1435
  if (get_attr_length (trial) == 1
1436
      /* If registers where saved, presumably there's more than enough
1437
         possibilities for the delay slot.  The alternative is something
1438
         more complicated (of course, if we expanded the epilogue as rtl
1439
         this problem would go away).  */
1440
      /* ??? Note that this will always be true since only functions with
1441
         empty frames have epilogue delay slots.  See
1442
         arc_delay_slots_for_epilogue.  */
1443
      && current_frame_info.gmask == 0
1444
      && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
1445
      && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
1446
    return 1;
1447
  return 0;
1448
}
1449
 
1450
/* Return true if OP is a shift operator.  */
1451
 
1452
int
1453
shift_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1454
{
1455
  switch (GET_CODE (op))
1456
    {
1457
    case ASHIFTRT:
1458
    case LSHIFTRT:
1459
    case ASHIFT:
1460
      return 1;
1461
    default:
1462
      return 0;
1463
    }
1464
}
1465
 
1466
/* Output the assembler code for doing a shift.
1467
   We go to a bit of trouble to generate efficient code as the ARC only has
1468
   single bit shifts.  This is taken from the h8300 port.  We only have one
1469
   mode of shifting and can't access individual bytes like the h8300 can, so
1470
   this is greatly simplified (at the expense of not generating hyper-
1471
   efficient code).
1472
 
1473
   This function is not used if the variable shift insns are present.  */
1474
 
1475
/* ??? We assume the output operand is the same as operand 1.
1476
   This can be optimized (deleted) in the case of 1 bit shifts.  */
1477
/* ??? We use the loop register here.  We don't use it elsewhere (yet) and
1478
   using it here will give us a chance to play with it.  */
1479
 
1480
const char *
1481
output_shift (rtx *operands)
1482
{
1483
  rtx shift = operands[3];
1484
  enum machine_mode mode = GET_MODE (shift);
1485
  enum rtx_code code = GET_CODE (shift);
1486
  const char *shift_one;
1487
 
1488
  gcc_assert (mode == SImode);
1489
 
1490
  switch (code)
1491
    {
1492
    case ASHIFT:   shift_one = "asl %0,%0"; break;
1493
    case ASHIFTRT: shift_one = "asr %0,%0"; break;
1494
    case LSHIFTRT: shift_one = "lsr %0,%0"; break;
1495
    default:       gcc_unreachable ();
1496
    }
1497
 
1498
  if (GET_CODE (operands[2]) != CONST_INT)
1499
    {
1500
      if (optimize)
1501
        {
1502
          output_asm_insn ("sub.f 0,%2,0", operands);
1503
          output_asm_insn ("mov lp_count,%2", operands);
1504
          output_asm_insn ("bz 2f", operands);
1505
        }
1506
      else
1507
        output_asm_insn ("mov %4,%2", operands);
1508
      goto shiftloop;
1509
    }
1510
  else
1511
    {
1512
      int n = INTVAL (operands[2]);
1513
 
1514
      /* If the count is negative, make it 0.  */
1515
      if (n < 0)
1516
        n = 0;
1517
      /* If the count is too big, truncate it.
1518
         ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
1519
         do the intuitive thing.  */
1520
      else if (n > GET_MODE_BITSIZE (mode))
1521
        n = GET_MODE_BITSIZE (mode);
1522
 
1523
      /* First see if we can do them inline.  */
1524
      if (n <= 8)
1525
        {
1526
          while (--n >= 0)
1527
            output_asm_insn (shift_one, operands);
1528
        }
1529
      /* See if we can use a rotate/and.  */
1530
      else if (n == BITS_PER_WORD - 1)
1531
        {
1532
          switch (code)
1533
            {
1534
            case ASHIFT :
1535
              output_asm_insn ("and %0,%0,1\n\tror %0,%0", operands);
1536
              break;
1537
            case ASHIFTRT :
1538
              /* The ARC doesn't have a rol insn.  Use something else.  */
1539
              output_asm_insn ("asl.f 0,%0\n\tsbc %0,0,0", operands);
1540
              break;
1541
            case LSHIFTRT :
1542
              /* The ARC doesn't have a rol insn.  Use something else.  */
1543
              output_asm_insn ("asl.f 0,%0\n\tadc %0,0,0", operands);
1544
              break;
1545
            default:
1546
              break;
1547
            }
1548
        }
1549
      /* Must loop.  */
1550
      else
1551
        {
1552
          char buf[100];
1553
 
1554
          if (optimize)
1555
            output_asm_insn ("mov lp_count,%c2", operands);
1556
          else
1557
            output_asm_insn ("mov %4,%c2", operands);
1558
        shiftloop:
1559
          if (optimize)
1560
            {
1561
              if (flag_pic)
1562
                sprintf (buf, "lr %%4,[status]\n\tadd %%4,%%4,6\t%s single insn loop start",
1563
                         ASM_COMMENT_START);
1564
              else
1565
                sprintf (buf, "mov %%4,%%%%st(1f)\t%s (single insn loop start) >> 2",
1566
                         ASM_COMMENT_START);
1567
              output_asm_insn (buf, operands);
1568
              output_asm_insn ("sr %4,[lp_start]", operands);
1569
              output_asm_insn ("add %4,%4,1", operands);
1570
              output_asm_insn ("sr %4,[lp_end]", operands);
1571
              output_asm_insn ("nop\n\tnop", operands);
1572
              if (flag_pic)
1573
                fprintf (asm_out_file, "\t%s single insn loop\n",
1574
                         ASM_COMMENT_START);
1575
              else
1576
                fprintf (asm_out_file, "1:\t%s single insn loop\n",
1577
                         ASM_COMMENT_START);
1578
              output_asm_insn (shift_one, operands);
1579
              fprintf (asm_out_file, "2:\t%s end single insn loop\n",
1580
                       ASM_COMMENT_START);
1581
            }
1582
          else
1583
            {
1584
              fprintf (asm_out_file, "1:\t%s begin shift loop\n",
1585
                       ASM_COMMENT_START);
1586
              output_asm_insn ("sub.f %4,%4,1", operands);
1587
              output_asm_insn ("nop", operands);
1588
              output_asm_insn ("bn.nd 2f", operands);
1589
              output_asm_insn (shift_one, operands);
1590
              output_asm_insn ("b.nd 1b", operands);
1591
              fprintf (asm_out_file, "2:\t%s end shift loop\n",
1592
                       ASM_COMMENT_START);
1593
            }
1594
        }
1595
    }
1596
 
1597
  return "";
1598
}
1599
 
1600
/* Nested function support.  */
1601
 
1602
/* Emit RTL insns to initialize the variable parts of a trampoline.
1603
   FNADDR is an RTX for the address of the function's pure code.
1604
   CXT is an RTX for the static chain value for the function.  */
1605
 
1606
void
1607
arc_initialize_trampoline (rtx tramp ATTRIBUTE_UNUSED,
1608
                           rtx fnaddr ATTRIBUTE_UNUSED,
1609
                           rtx cxt ATTRIBUTE_UNUSED)
1610
{
1611
}
1612
 
1613
/* Set the cpu type and print out other fancy things,
1614
   at the top of the file.  */
1615
 
1616
static void
1617
arc_file_start (void)
1618
{
1619
  default_file_start ();
1620
  fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
1621
}
1622
 
1623
/* Print operand X (an rtx) in assembler syntax to file FILE.
1624
   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
1625
   For `%' followed by punctuation, CODE is the punctuation and X is null.  */
1626
 
1627
void
1628
arc_print_operand (FILE *file, rtx x, int code)
1629
{
1630
  switch (code)
1631
    {
1632
    case '#' :
1633
      /* Conditional branches.  For now these are equivalent.  */
1634
    case '*' :
1635
      /* Unconditional branches.  Output the appropriate delay slot suffix.  */
1636
      if (!final_sequence || XVECLEN (final_sequence, 0) == 1)
1637
        {
1638
          /* There's nothing in the delay slot.  */
1639
          fputs (".nd", file);
1640
        }
1641
      else
1642
        {
1643
          rtx jump = XVECEXP (final_sequence, 0, 0);
1644
          rtx delay = XVECEXP (final_sequence, 0, 1);
1645
          if (INSN_ANNULLED_BRANCH_P (jump))
1646
            fputs (INSN_FROM_TARGET_P (delay) ? ".jd" : ".nd", file);
1647
          else
1648
            fputs (".d", file);
1649
        }
1650
      return;
1651
    case '?' : /* with leading "." */
1652
    case '!' : /* without leading "." */
1653
      /* This insn can be conditionally executed.  See if the ccfsm machinery
1654
         says it should be conditionalized.  */
1655
      if (arc_ccfsm_state == 3 || arc_ccfsm_state == 4)
1656
        {
1657
          /* Is this insn in a delay slot?  */
1658
          if (final_sequence && XVECLEN (final_sequence, 0) == 2)
1659
            {
1660
              rtx insn = XVECEXP (final_sequence, 0, 1);
1661
 
1662
              /* If the insn is annulled and is from the target path, we need
1663
                 to inverse the condition test.  */
1664
              if (INSN_ANNULLED_BRANCH_P (insn))
1665
                {
1666
                  if (INSN_FROM_TARGET_P (insn))
1667
                    fprintf (file, "%s%s",
1668
                             code == '?' ? "." : "",
1669
                             arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc)]);
1670
                  else
1671
                    fprintf (file, "%s%s",
1672
                             code == '?' ? "." : "",
1673
                             arc_condition_codes[arc_ccfsm_current_cc]);
1674
                }
1675
              else
1676
                {
1677
                  /* This insn is executed for either path, so don't
1678
                     conditionalize it at all.  */
1679
                  ; /* nothing to do */
1680
                }
1681
            }
1682
          else
1683
            {
1684
              /* This insn isn't in a delay slot.  */
1685
              fprintf (file, "%s%s",
1686
                       code == '?' ? "." : "",
1687
                       arc_condition_codes[arc_ccfsm_current_cc]);
1688
            }
1689
        }
1690
      return;
1691
    case '~' :
1692
      /* Output a nop if we're between a set of the condition codes,
1693
         and a conditional branch.  */
1694
      if (last_insn_set_cc_p)
1695
        fputs ("nop\n\t", file);
1696
      return;
1697
    case 'd' :
1698
      fputs (arc_condition_codes[get_arc_condition_code (x)], file);
1699
      return;
1700
    case 'D' :
1701
      fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
1702
                                 (get_arc_condition_code (x))],
1703
             file);
1704
      return;
1705
    case 'R' :
1706
      /* Write second word of DImode or DFmode reference,
1707
         register or memory.  */
1708
      if (GET_CODE (x) == REG)
1709
        fputs (reg_names[REGNO (x)+1], file);
1710
      else if (GET_CODE (x) == MEM)
1711
        {
1712
          fputc ('[', file);
1713
          /* Handle possible auto-increment.  Since it is pre-increment and
1714
             we have already done it, we can just use an offset of four.  */
1715
          /* ??? This is taken from rs6000.c I think.  I don't think it is
1716
             currently necessary, but keep it around.  */
1717
          if (GET_CODE (XEXP (x, 0)) == PRE_INC
1718
              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
1719
            output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
1720
          else
1721
            output_address (plus_constant (XEXP (x, 0), 4));
1722
          fputc (']', file);
1723
        }
1724
      else
1725
        output_operand_lossage ("invalid operand to %%R code");
1726
      return;
1727
    case 'S' :
1728
      if ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
1729
          || GET_CODE (x) == LABEL_REF)
1730
        {
1731
          fprintf (file, "%%st(");
1732
          output_addr_const (file, x);
1733
          fprintf (file, ")");
1734
          return;
1735
        }
1736
      break;
1737
    case 'H' :
1738
    case 'L' :
1739
      if (GET_CODE (x) == REG)
1740
        {
1741
          /* L = least significant word, H = most significant word */
1742
          if ((TARGET_BIG_ENDIAN != 0) ^ (code == 'L'))
1743
            fputs (reg_names[REGNO (x)], file);
1744
          else
1745
            fputs (reg_names[REGNO (x)+1], file);
1746
        }
1747
      else if (GET_CODE (x) == CONST_INT
1748
               || GET_CODE (x) == CONST_DOUBLE)
1749
        {
1750
          rtx first, second;
1751
 
1752
          split_double (x, &first, &second);
1753
          fprintf (file, "0x%08lx",
1754
                   (long)(code == 'L' ? INTVAL (first) : INTVAL (second)));
1755
        }
1756
      else
1757
        output_operand_lossage ("invalid operand to %%H/%%L code");
1758
      return;
1759
    case 'A' :
1760
      {
1761
        char str[30];
1762
 
1763
        gcc_assert (GET_CODE (x) == CONST_DOUBLE
1764
                    && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
1765
 
1766
        real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
1767
        fprintf (file, "%s", str);
1768
        return;
1769
      }
1770
    case 'U' :
1771
      /* Output a load/store with update indicator if appropriate.  */
1772
      if (GET_CODE (x) == MEM)
1773
        {
1774
          if (GET_CODE (XEXP (x, 0)) == PRE_INC
1775
              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
1776
            fputs (".a", file);
1777
        }
1778
      else
1779
        output_operand_lossage ("invalid operand to %%U code");
1780
      return;
1781
    case 'V' :
1782
      /* Output cache bypass indicator for a load/store insn.  Volatile memory
1783
         refs are defined to use the cache bypass mechanism.  */
1784
      if (GET_CODE (x) == MEM)
1785
        {
1786
          if (MEM_VOLATILE_P (x))
1787
            fputs (".di", file);
1788
        }
1789
      else
1790
        output_operand_lossage ("invalid operand to %%V code");
1791
      return;
1792
    case 0 :
1793
      /* Do nothing special.  */
1794
      break;
1795
    default :
1796
      /* Unknown flag.  */
1797
      output_operand_lossage ("invalid operand output code");
1798
    }
1799
 
1800
  switch (GET_CODE (x))
1801
    {
1802
    case REG :
1803
      fputs (reg_names[REGNO (x)], file);
1804
      break;
1805
    case MEM :
1806
      fputc ('[', file);
1807
      if (GET_CODE (XEXP (x, 0)) == PRE_INC)
1808
        output_address (plus_constant (XEXP (XEXP (x, 0), 0),
1809
                                       GET_MODE_SIZE (GET_MODE (x))));
1810
      else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
1811
        output_address (plus_constant (XEXP (XEXP (x, 0), 0),
1812
                                       - GET_MODE_SIZE (GET_MODE (x))));
1813
      else
1814
        output_address (XEXP (x, 0));
1815
      fputc (']', file);
1816
      break;
1817
    case CONST_DOUBLE :
1818
      /* We handle SFmode constants here as output_addr_const doesn't.  */
1819
      if (GET_MODE (x) == SFmode)
1820
        {
1821
          REAL_VALUE_TYPE d;
1822
          long l;
1823
 
1824
          REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1825
          REAL_VALUE_TO_TARGET_SINGLE (d, l);
1826
          fprintf (file, "0x%08lx", l);
1827
          break;
1828
        }
1829
      /* Fall through.  Let output_addr_const deal with it.  */
1830
    default :
1831
      output_addr_const (file, x);
1832
      break;
1833
    }
1834
}
1835
 
1836
/* Print a memory address as an operand to reference that memory location.  */
1837
 
1838
void
1839
arc_print_operand_address (FILE *file, rtx addr)
1840
{
1841
  register rtx base, index = 0;
1842
  int offset = 0;
1843
 
1844
  switch (GET_CODE (addr))
1845
    {
1846
    case REG :
1847
      fputs (reg_names[REGNO (addr)], file);
1848
      break;
1849
    case SYMBOL_REF :
1850
      if (/*???*/ 0 && SYMBOL_REF_FUNCTION_P (addr))
1851
        {
1852
          fprintf (file, "%%st(");
1853
          output_addr_const (file, addr);
1854
          fprintf (file, ")");
1855
        }
1856
      else
1857
        output_addr_const (file, addr);
1858
      break;
1859
    case PLUS :
1860
      if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1861
        offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
1862
      else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
1863
        offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
1864
      else
1865
        base = XEXP (addr, 0), index = XEXP (addr, 1);
1866
      gcc_assert (GET_CODE (base) == REG);
1867
      fputs (reg_names[REGNO (base)], file);
1868
      if (index == 0)
1869
        {
1870
          if (offset != 0)
1871
            fprintf (file, ",%d", offset);
1872
        }
1873
      else
1874
        {
1875
          switch (GET_CODE (index))
1876
            {
1877
            case REG:
1878
              fprintf (file, ",%s", reg_names[REGNO (index)]);
1879
              break;
1880
            case SYMBOL_REF:
1881
              fputc (',', file), output_addr_const (file, index);
1882
              break;
1883
            default:
1884
              gcc_unreachable ();
1885
            }
1886
        }
1887
      break;
1888
    case PRE_INC :
1889
    case PRE_DEC :
1890
      /* We shouldn't get here as we've lost the mode of the memory object
1891
         (which says how much to inc/dec by.  */
1892
      gcc_unreachable ();
1893
      break;
1894
    default :
1895
      output_addr_const (file, addr);
1896
      break;
1897
    }
1898
}
1899
 
1900
/* Update compare/branch separation marker.  */
1901
 
1902
static void
1903
record_cc_ref (rtx insn)
1904
{
1905
  last_insn_set_cc_p = current_insn_set_cc_p;
1906
 
1907
  switch (get_attr_cond (insn))
1908
    {
1909
    case COND_SET :
1910
    case COND_SET_ZN :
1911
    case COND_SET_ZNC :
1912
      if (get_attr_length (insn) == 1)
1913
        current_insn_set_cc_p = 1;
1914
      else
1915
        current_insn_set_cc_p = 0;
1916
      break;
1917
    default :
1918
      current_insn_set_cc_p = 0;
1919
      break;
1920
    }
1921
}
1922
 
1923
/* Conditional execution support.
1924
 
1925
   This is based on the ARM port but for now is much simpler.
1926
 
1927
   A finite state machine takes care of noticing whether or not instructions
1928
   can be conditionally executed, and thus decrease execution time and code
1929
   size by deleting branch instructions.  The fsm is controlled by
1930
   final_prescan_insn, and controls the actions of PRINT_OPERAND.  The patterns
1931
   in the .md file for the branch insns also have a hand in this.  */
1932
 
1933
/* The state of the fsm controlling condition codes are:
1934
   0: normal, do nothing special
1935
   1: don't output this insn
1936
   2: don't output this insn
1937
   3: make insns conditional
1938
   4: make insns conditional
1939
 
1940
   State transitions (state->state by whom, under what condition):
1941
 
1942
 
1943
   1 -> 3 branch patterns, after having not output the conditional branch
1944
   2 -> 4 branch patterns, after having not output the conditional branch
1945
   3 -> 0 (*targetm.asm_out.internal_label), if the `target' label is reached
1946
          (the target label has CODE_LABEL_NUMBER equal to
1947
          arc_ccfsm_target_label).
1948
   4 -> 0 final_prescan_insn, if `target' unconditional branch is reached
1949
 
1950
   If the jump clobbers the conditions then we use states 2 and 4.
1951
 
1952
   A similar thing can be done with conditional return insns.
1953
 
1954
   We also handle separating branches from sets of the condition code.
1955
   This is done here because knowledge of the ccfsm state is required,
1956
   we may not be outputting the branch.  */
1957
 
1958
void
1959
arc_final_prescan_insn (rtx insn,
1960
                        rtx *opvec ATTRIBUTE_UNUSED,
1961
                        int noperands ATTRIBUTE_UNUSED)
1962
{
1963
  /* BODY will hold the body of INSN.  */
1964
  register rtx body = PATTERN (insn);
1965
 
1966
  /* This will be 1 if trying to repeat the trick (i.e.: do the `else' part of
1967
     an if/then/else), and things need to be reversed.  */
1968
  int reverse = 0;
1969
 
1970
  /* If we start with a return insn, we only succeed if we find another one.  */
1971
  int seeking_return = 0;
1972
 
1973
  /* START_INSN will hold the insn from where we start looking.  This is the
1974
     first insn after the following code_label if REVERSE is true.  */
1975
  rtx start_insn = insn;
1976
 
1977
  /* Update compare/branch separation marker.  */
1978
  record_cc_ref (insn);
1979
 
1980
  /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
1981
     We can't do this in macro FINAL_PRESCAN_INSN because its called from
1982
     final_scan_insn which has `optimize' as a local.  */
1983
  if (optimize < 2 || TARGET_NO_COND_EXEC)
1984
    return;
1985
 
1986
  /* If in state 4, check if the target branch is reached, in order to
1987
     change back to state 0.  */
1988
  if (arc_ccfsm_state == 4)
1989
    {
1990
      if (insn == arc_ccfsm_target_insn)
1991
        {
1992
          arc_ccfsm_target_insn = NULL;
1993
          arc_ccfsm_state = 0;
1994
        }
1995
      return;
1996
    }
1997
 
1998
  /* If in state 3, it is possible to repeat the trick, if this insn is an
1999
     unconditional branch to a label, and immediately following this branch
2000
     is the previous target label which is only used once, and the label this
2001
     branch jumps to is not too far off.  Or in other words "we've done the
2002
     `then' part, see if we can do the `else' part."  */
2003
  if (arc_ccfsm_state == 3)
2004
    {
2005
      if (simplejump_p (insn))
2006
        {
2007
          start_insn = next_nonnote_insn (start_insn);
2008
          if (GET_CODE (start_insn) == BARRIER)
2009
            {
2010
              /* ??? Isn't this always a barrier?  */
2011
              start_insn = next_nonnote_insn (start_insn);
2012
            }
2013
          if (GET_CODE (start_insn) == CODE_LABEL
2014
              && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
2015
              && LABEL_NUSES (start_insn) == 1)
2016
            reverse = TRUE;
2017
          else
2018
            return;
2019
        }
2020
      else if (GET_CODE (body) == RETURN)
2021
        {
2022
          start_insn = next_nonnote_insn (start_insn);
2023
          if (GET_CODE (start_insn) == BARRIER)
2024
            start_insn = next_nonnote_insn (start_insn);
2025
          if (GET_CODE (start_insn) == CODE_LABEL
2026
              && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
2027
              && LABEL_NUSES (start_insn) == 1)
2028
            {
2029
              reverse = TRUE;
2030
              seeking_return = 1;
2031
            }
2032
          else
2033
            return;
2034
        }
2035
      else
2036
        return;
2037
    }
2038
 
2039
  if (GET_CODE (insn) != JUMP_INSN)
2040
    return;
2041
 
2042
  /* This jump might be paralleled with a clobber of the condition codes,
2043
     the jump should always come first.  */
2044
  if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
2045
    body = XVECEXP (body, 0, 0);
2046
 
2047
  if (reverse
2048
      || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
2049
          && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
2050
    {
2051
      int insns_skipped = 0, fail = FALSE, succeed = FALSE;
2052
      /* Flag which part of the IF_THEN_ELSE is the LABEL_REF.  */
2053
      int then_not_else = TRUE;
2054
      /* Nonzero if next insn must be the target label.  */
2055
      int next_must_be_target_label_p;
2056
      rtx this_insn = start_insn, label = 0;
2057
 
2058
      /* Register the insn jumped to.  */
2059
      if (reverse)
2060
        {
2061
          if (!seeking_return)
2062
            label = XEXP (SET_SRC (body), 0);
2063
        }
2064
      else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
2065
        label = XEXP (XEXP (SET_SRC (body), 1), 0);
2066
      else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
2067
        {
2068
          label = XEXP (XEXP (SET_SRC (body), 2), 0);
2069
          then_not_else = FALSE;
2070
        }
2071
      else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
2072
        seeking_return = 1;
2073
      else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
2074
        {
2075
          seeking_return = 1;
2076
          then_not_else = FALSE;
2077
        }
2078
      else
2079
        gcc_unreachable ();
2080
 
2081
      /* See how many insns this branch skips, and what kind of insns.  If all
2082
         insns are okay, and the label or unconditional branch to the same
2083
         label is not too far away, succeed.  */
2084
      for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
2085
           !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
2086
           insns_skipped++)
2087
        {
2088
          rtx scanbody;
2089
 
2090
          this_insn = next_nonnote_insn (this_insn);
2091
          if (!this_insn)
2092
            break;
2093
 
2094
          if (next_must_be_target_label_p)
2095
            {
2096
              if (GET_CODE (this_insn) == BARRIER)
2097
                continue;
2098
              if (GET_CODE (this_insn) == CODE_LABEL
2099
                  && this_insn == label)
2100
                {
2101
                  arc_ccfsm_state = 1;
2102
                  succeed = TRUE;
2103
                }
2104
              else
2105
                fail = TRUE;
2106
              break;
2107
            }
2108
 
2109
          scanbody = PATTERN (this_insn);
2110
 
2111
          switch (GET_CODE (this_insn))
2112
            {
2113
            case CODE_LABEL:
2114
              /* Succeed if it is the target label, otherwise fail since
2115
                 control falls in from somewhere else.  */
2116
              if (this_insn == label)
2117
                {
2118
                  arc_ccfsm_state = 1;
2119
                  succeed = TRUE;
2120
                }
2121
              else
2122
                fail = TRUE;
2123
              break;
2124
 
2125
            case BARRIER:
2126
              /* Succeed if the following insn is the target label.
2127
                 Otherwise fail.
2128
                 If return insns are used then the last insn in a function
2129
                 will be a barrier.  */
2130
              next_must_be_target_label_p = TRUE;
2131
              break;
2132
 
2133
            case CALL_INSN:
2134
              /* Can handle a call insn if there are no insns after it.
2135
                 IE: The next "insn" is the target label.  We don't have to
2136
                 worry about delay slots as such insns are SEQUENCE's inside
2137
                 INSN's.  ??? It is possible to handle such insns though.  */
2138
              if (get_attr_cond (this_insn) == COND_CANUSE)
2139
                next_must_be_target_label_p = TRUE;
2140
              else
2141
                fail = TRUE;
2142
              break;
2143
 
2144
            case JUMP_INSN:
2145
              /* If this is an unconditional branch to the same label, succeed.
2146
                 If it is to another label, do nothing.  If it is conditional,
2147
                 fail.  */
2148
              /* ??? Probably, the test for the SET and the PC are unnecessary.  */
2149
 
2150
              if (GET_CODE (scanbody) == SET
2151
                  && GET_CODE (SET_DEST (scanbody)) == PC)
2152
                {
2153
                  if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
2154
                      && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
2155
                    {
2156
                      arc_ccfsm_state = 2;
2157
                      succeed = TRUE;
2158
                    }
2159
                  else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
2160
                    fail = TRUE;
2161
                }
2162
              else if (GET_CODE (scanbody) == RETURN
2163
                       && seeking_return)
2164
                {
2165
                  arc_ccfsm_state = 2;
2166
                  succeed = TRUE;
2167
                }
2168
              else if (GET_CODE (scanbody) == PARALLEL)
2169
                {
2170
                  if (get_attr_cond (this_insn) != COND_CANUSE)
2171
                    fail = TRUE;
2172
                }
2173
              break;
2174
 
2175
            case INSN:
2176
              /* We can only do this with insns that can use the condition
2177
                 codes (and don't set them).  */
2178
              if (GET_CODE (scanbody) == SET
2179
                  || GET_CODE (scanbody) == PARALLEL)
2180
                {
2181
                  if (get_attr_cond (this_insn) != COND_CANUSE)
2182
                    fail = TRUE;
2183
                }
2184
              /* We can't handle other insns like sequences.  */
2185
              else
2186
                fail = TRUE;
2187
              break;
2188
 
2189
            default:
2190
              break;
2191
            }
2192
        }
2193
 
2194
      if (succeed)
2195
        {
2196
          if ((!seeking_return) && (arc_ccfsm_state == 1 || reverse))
2197
            arc_ccfsm_target_label = CODE_LABEL_NUMBER (label);
2198
          else
2199
            {
2200
              gcc_assert (seeking_return || arc_ccfsm_state == 2);
2201
              while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
2202
                {
2203
                  this_insn = next_nonnote_insn (this_insn);
2204
                  gcc_assert (!this_insn
2205
                              || (GET_CODE (this_insn) != BARRIER
2206
                                  && GET_CODE (this_insn) != CODE_LABEL));
2207
                }
2208
              if (!this_insn)
2209
                {
2210
                  /* Oh dear! we ran off the end, give up.  */
2211
                  extract_insn_cached (insn);
2212
                  arc_ccfsm_state = 0;
2213
                  arc_ccfsm_target_insn = NULL;
2214
                  return;
2215
                }
2216
              arc_ccfsm_target_insn = this_insn;
2217
            }
2218
 
2219
          /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
2220
             what it was.  */
2221
          if (!reverse)
2222
            arc_ccfsm_current_cc = get_arc_condition_code (XEXP (SET_SRC (body),
2223
                                                                 0));
2224
 
2225
          if (reverse || then_not_else)
2226
            arc_ccfsm_current_cc = ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc);
2227
        }
2228
 
2229
      /* Restore recog_data.  Getting the attributes of other insns can
2230
         destroy this array, but final.c assumes that it remains intact
2231
         across this call.  */
2232
      extract_insn_cached (insn);
2233
    }
2234
}
2235
 
2236
/* Record that we are currently outputting label NUM with prefix PREFIX.
2237
   It it's the label we're looking for, reset the ccfsm machinery.
2238
 
2239
   Called from (*targetm.asm_out.internal_label).  */
2240
 
2241
void
2242
arc_ccfsm_at_label (const char *prefix, int num)
2243
{
2244
  if (arc_ccfsm_state == 3 && arc_ccfsm_target_label == num
2245
      && !strcmp (prefix, "L"))
2246
    {
2247
      arc_ccfsm_state = 0;
2248
      arc_ccfsm_target_insn = NULL_RTX;
2249
    }
2250
}
2251
 
2252
/* See if the current insn, which is a conditional branch, is to be
2253
   deleted.  */
2254
 
2255
int
2256
arc_ccfsm_branch_deleted_p (void)
2257
{
2258
  if (arc_ccfsm_state == 1 || arc_ccfsm_state == 2)
2259
    return 1;
2260
  return 0;
2261
}
2262
 
2263
/* Record a branch isn't output because subsequent insns can be
2264
   conditionalized.  */
2265
 
2266
void
2267
arc_ccfsm_record_branch_deleted (void)
2268
{
2269
  /* Indicate we're conditionalizing insns now.  */
2270
  arc_ccfsm_state += 2;
2271
 
2272
  /* If the next insn is a subroutine call, we still need a nop between the
2273
     cc setter and user.  We need to undo the effect of calling record_cc_ref
2274
     for the just deleted branch.  */
2275
  current_insn_set_cc_p = last_insn_set_cc_p;
2276
}
2277
 
2278
void
2279
arc_va_start (tree valist, rtx nextarg)
2280
{
2281
  /* See arc_setup_incoming_varargs for reasons for this oddity.  */
2282
  if (current_function_args_info < 8
2283
      && (current_function_args_info & 1))
2284
    nextarg = plus_constant (nextarg, UNITS_PER_WORD);
2285
 
2286
  std_expand_builtin_va_start (valist, nextarg);
2287
}
2288
 
2289
/* This is how to output a definition of an internal numbered label where
2290
   PREFIX is the class of label and NUM is the number within the class.  */
2291
 
2292
static void
2293
arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
2294
{
2295
  arc_ccfsm_at_label (prefix, labelno);
2296
  default_internal_label (stream, prefix, labelno);
2297
}
2298
 
2299
/* Worker function for TARGET_ASM_EXTERNAL_LIBCALL.  */
2300
 
2301
static void
2302
arc_external_libcall (rtx fun ATTRIBUTE_UNUSED)
2303
{
2304
#if 0
2305
/* On the ARC we want to have libgcc's for multiple cpus in one binary.
2306
   We can't use `assemble_name' here as that will call ASM_OUTPUT_LABELREF
2307
   and we'll get another suffix added on if -mmangle-cpu.  */
2308
  if (TARGET_MANGLE_CPU_LIBGCC)
2309
    {
2310
      fprintf (FILE, "\t.rename\t_%s, _%s%s\n",
2311
               XSTR (SYMREF, 0), XSTR (SYMREF, 0),
2312
               arc_mangle_suffix);
2313
    }
2314
#endif
2315
}
2316
 
2317
/* Worker function for TARGET_RETURN_IN_MEMORY.  */
2318
 
2319
static bool
2320
arc_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
2321
{
2322
  if (AGGREGATE_TYPE_P (type))
2323
    return true;
2324
  else
2325
    {
2326
      HOST_WIDE_INT size = int_size_in_bytes (type);
2327
      return (size == -1 || size > 8);
2328
    }
2329
}
2330
 
2331
/* For ARC, All aggregates and arguments greater than 8 bytes are
2332
   passed by reference.  */
2333
 
2334
static bool
2335
arc_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2336
                       enum machine_mode mode, tree type,
2337
                       bool named ATTRIBUTE_UNUSED)
2338
{
2339
  unsigned HOST_WIDE_INT size;
2340
 
2341
  if (type)
2342
    {
2343
      if (AGGREGATE_TYPE_P (type))
2344
        return true;
2345
      size = int_size_in_bytes (type);
2346
    }
2347
  else
2348
    size = GET_MODE_SIZE (mode);
2349
 
2350
  return size > 8;
2351
}

powered by: WebSVN 2.1.0

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