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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [genflags.c] - Blame information for rev 20

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

Line No. Rev Author Line
1 12 jlechner
/* Generate from machine description:
2
   - some flags HAVE_... saying which simple standard instructions are
3
   available for this machine.
4
   Copyright (C) 1987, 1991, 1995, 1998,
5
   1999, 2000, 2003, 2004 Free Software Foundation, Inc.
6
 
7
This file is part of GCC.
8
 
9
GCC is free software; you can redistribute it and/or modify it under
10
the terms of the GNU General Public License as published by the Free
11
Software Foundation; either version 2, or (at your option) any later
12
version.
13
 
14
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15
WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17
for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with GCC; see the file COPYING.  If not, write to the Free
21
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.  */
23
 
24
 
25
#include "bconfig.h"
26
#include "system.h"
27
#include "coretypes.h"
28
#include "tm.h"
29
#include "rtl.h"
30
#include "obstack.h"
31
#include "errors.h"
32
#include "gensupport.h"
33
 
34
/* Obstack to remember insns with.  */
35
static struct obstack obstack;
36
 
37
/* Max size of names encountered.  */
38
static int max_id_len;
39
 
40
/* Max operand encountered in a scan over some insn.  */
41
static int max_opno;
42
 
43
static void max_operand_1 (rtx);
44
static int num_operands (rtx);
45
static void gen_proto (rtx);
46
static void gen_macro (const char *, int, int);
47
static void gen_insn (rtx);
48
 
49
/* Count the number of match_operand's found.  */
50
 
51
static void
52
max_operand_1 (rtx x)
53
{
54
  RTX_CODE code;
55
  int i;
56
  int len;
57
  const char *fmt;
58
 
59
  if (x == 0)
60
    return;
61
 
62
  code = GET_CODE (x);
63
 
64
  if (code == MATCH_OPERAND || code == MATCH_OPERATOR
65
      || code == MATCH_PARALLEL)
66
    max_opno = MAX (max_opno, XINT (x, 0));
67
 
68
  fmt = GET_RTX_FORMAT (code);
69
  len = GET_RTX_LENGTH (code);
70
  for (i = 0; i < len; i++)
71
    {
72
      if (fmt[i] == 'e' || fmt[i] == 'u')
73
        max_operand_1 (XEXP (x, i));
74
      else if (fmt[i] == 'E')
75
        {
76
          int j;
77
          for (j = 0; j < XVECLEN (x, i); j++)
78
            max_operand_1 (XVECEXP (x, i, j));
79
        }
80
    }
81
}
82
 
83
static int
84
num_operands (rtx insn)
85
{
86
  int len = XVECLEN (insn, 1);
87
  int i;
88
 
89
  max_opno = -1;
90
 
91
  for (i = 0; i < len; i++)
92
    max_operand_1 (XVECEXP (insn, 1, i));
93
 
94
  return max_opno + 1;
95
}
96
 
97
/* Print out a wrapper macro for a function which corrects the number
98
   of arguments it takes.  Any missing arguments are assumed to be at
99
   the end.  */
100
static void
101
gen_macro (const char *name, int real, int expect)
102
{
103
  int i;
104
 
105
  gcc_assert (real <= expect);
106
  gcc_assert (real);
107
 
108
  /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */
109
  fputs ("#define GEN_", stdout);
110
  for (i = 0; name[i]; i++)
111
    putchar (TOUPPER (name[i]));
112
 
113
  putchar('(');
114
  for (i = 0; i < expect - 1; i++)
115
    printf ("%c, ", i + 'A');
116
  printf ("%c) gen_%s (", i + 'A', name);
117
 
118
  for (i = 0; i < real - 1; i++)
119
    printf ("(%c), ", i + 'A');
120
  printf ("(%c))\n", i + 'A');
121
}
122
 
123
/* Print out prototype information for a generator function.  If the
124
   insn pattern has been elided, print out a dummy generator that
125
   does nothing.  */
126
 
127
static void
128
gen_proto (rtx insn)
129
{
130
  int num = num_operands (insn);
131
  int i;
132
  const char *name = XSTR (insn, 0);
133
  int truth = maybe_eval_c_test (XSTR (insn, 2));
134
 
135
  /* Many md files don't refer to the last two operands passed to the
136
     call patterns.  This means their generator functions will be two
137
     arguments too short.  Instead of changing every md file to touch
138
     those operands, we wrap the prototypes in macros that take the
139
     correct number of arguments.  */
140
  if (name[0] == 'c' || name[0] == 's')
141
    {
142
      if (!strcmp (name, "call")
143
          || !strcmp (name, "call_pop")
144
          || !strcmp (name, "sibcall")
145
          || !strcmp (name, "sibcall_pop"))
146
        gen_macro (name, num, 4);
147
      else if (!strcmp (name, "call_value")
148
               || !strcmp (name, "call_value_pop")
149
               || !strcmp (name, "sibcall_value")
150
               || !strcmp (name, "sibcall_value_pop"))
151
        gen_macro (name, num, 5);
152
    }
153
 
154
  if (truth != 0)
155
    printf ("extern rtx        gen_%-*s (", max_id_len, name);
156
  else
157
    printf ("static inline rtx gen_%-*s (", max_id_len, name);
158
 
159
  if (num == 0)
160
    fputs ("void", stdout);
161
  else
162
    {
163
      for (i = 1; i < num; i++)
164
        fputs ("rtx, ", stdout);
165
 
166
      fputs ("rtx", stdout);
167
    }
168
 
169
  puts (");");
170
 
171
  /* Some back ends want to take the address of generator functions,
172
     so we cannot simply use #define for these dummy definitions.  */
173
  if (truth == 0)
174
    {
175
      printf ("static inline rtx\ngen_%s", name);
176
      if (num > 0)
177
        {
178
          putchar ('(');
179
          for (i = 0; i < num-1; i++)
180
            printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
181
          printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
182
        }
183
      else
184
        puts ("(void)");
185
      puts ("{\n  return 0;\n}");
186
    }
187
 
188
}
189
 
190
static void
191
gen_insn (rtx insn)
192
{
193
  const char *name = XSTR (insn, 0);
194
  const char *p;
195
  int len;
196
  int truth = maybe_eval_c_test (XSTR (insn, 2));
197
 
198
  /* Don't mention instructions whose names are the null string
199
     or begin with '*'.  They are in the machine description just
200
     to be recognized.  */
201
  if (name[0] == 0 || name[0] == '*')
202
    return;
203
 
204
  len = strlen (name);
205
 
206
  if (len > max_id_len)
207
    max_id_len = len;
208
 
209
  if (truth == 0)
210
    /* Emit nothing.  */;
211
  else if (truth == 1)
212
    printf ("#define HAVE_%s 1\n", name);
213
  else
214
    {
215
      /* Write the macro definition, putting \'s at the end of each line,
216
         if more than one.  */
217
      printf ("#define HAVE_%s (", name);
218
      for (p = XSTR (insn, 2); *p; p++)
219
        {
220
          if (IS_VSPACE (*p))
221
            fputs (" \\\n", stdout);
222
          else
223
            putchar (*p);
224
        }
225
      fputs (")\n", stdout);
226
    }
227
 
228
  obstack_grow (&obstack, &insn, sizeof (rtx));
229
}
230
 
231
int
232
main (int argc, char **argv)
233
{
234
  rtx desc;
235
  rtx dummy;
236
  rtx *insns;
237
  rtx *insn_ptr;
238
 
239
  progname = "genflags";
240
  obstack_init (&obstack);
241
 
242
  /* We need to see all the possibilities.  Elided insns may have
243
     direct calls to their generators in C code.  */
244
  insn_elision = 0;
245
 
246
  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
247
    return (FATAL_EXIT_CODE);
248
 
249
  puts ("/* Generated automatically by the program `genflags'");
250
  puts ("   from the machine description file `md'.  */\n");
251
  puts ("#ifndef GCC_INSN_FLAGS_H");
252
  puts ("#define GCC_INSN_FLAGS_H\n");
253
 
254
  /* Read the machine description.  */
255
 
256
  while (1)
257
    {
258
      int line_no, insn_code_number = 0;
259
 
260
      desc = read_md_rtx (&line_no, &insn_code_number);
261
      if (desc == NULL)
262
        break;
263
      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
264
        gen_insn (desc);
265
    }
266
 
267
  /* Print out the prototypes now.  */
268
  dummy = (rtx) 0;
269
  obstack_grow (&obstack, &dummy, sizeof (rtx));
270
  insns = XOBFINISH (&obstack, rtx *);
271
 
272
  for (insn_ptr = insns; *insn_ptr; insn_ptr++)
273
    gen_proto (*insn_ptr);
274
 
275
  puts("\n#endif /* GCC_INSN_FLAGS_H */");
276
 
277
  if (ferror (stdout) || fflush (stdout) || fclose (stdout))
278
    return FATAL_EXIT_CODE;
279
 
280
  return SUCCESS_EXIT_CODE;
281
}
282
 
283
/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
284
const char *
285
get_insn_name (int ARG_UNUSED (code))
286
{
287
  return NULL;
288
}

powered by: WebSVN 2.1.0

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