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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [gengenrtl.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Generate code to allocate RTL structures.
2
   Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2007, 2010
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 3, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
 
22
#include "bconfig.h"
23
#include "system.h"
24
 
25
struct rtx_definition
26
{
27
  const char *const enumname, *const name, *const format;
28
};
29
 
30
/* rtl.def needs CONST_DOUBLE_FORMAT, but we don't care what
31
   CONST_DOUBLE_FORMAT is because we're not going to be generating
32
   anything for CONST_DOUBLE anyway.  */
33
#define CONST_DOUBLE_FORMAT ""
34
 
35
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { #ENUM, NAME, FORMAT },
36
 
37
static const struct rtx_definition defs[] =
38
{
39
#include "rtl.def"              /* rtl expressions are documented here */
40
};
41
#define NUM_RTX_CODE ARRAY_SIZE(defs)
42
 
43
static const char *formats[NUM_RTX_CODE];
44
 
45
/* Decode a format letter into a C type string.  */
46
 
47
static const char *
48
type_from_format (int c)
49
{
50
  switch (c)
51
    {
52
    case 'i':
53
      return "int ";
54
 
55
    case 'w':
56
      return "HOST_WIDE_INT ";
57
 
58
    case 's':
59
      return "const char *";
60
 
61
    case 'e':  case 'u':
62
      return "rtx ";
63
 
64
    case 'E':
65
      return "rtvec ";
66
    case 't':
67
      return "union tree_node *";  /* tree - typedef not available */
68
    case 'B':
69
      return "struct basic_block_def *";  /* basic block - typedef not available */
70
    default:
71
      gcc_unreachable ();
72
    }
73
}
74
 
75
/* Decode a format letter into the proper accessor function.  */
76
 
77
static const char *
78
accessor_from_format (int c)
79
{
80
  switch (c)
81
    {
82
    case 'i':
83
      return "XINT";
84
 
85
    case 'w':
86
      return "XWINT";
87
 
88
    case 's':
89
      return "XSTR";
90
 
91
    case 'e':  case 'u':
92
      return "XEXP";
93
 
94
    case 'E':
95
      return "XVEC";
96
 
97
    case 't':
98
      return "XTREE";
99
 
100
    case 'B':
101
      return "XBBDEF";
102
 
103
    default:
104
      gcc_unreachable ();
105
    }
106
}
107
 
108
/* Return nonzero if we should ignore FMT, an RTL format, when making
109
   the list of formats we write routines to create.  */
110
 
111
static int
112
special_format (const char *fmt)
113
{
114
  return (strchr (fmt, '*') != 0
115
          || strchr (fmt, 'V') != 0
116
          || strchr (fmt, 'S') != 0
117
          || strchr (fmt, 'n') != 0);
118
}
119
 
120
/* Return nonzero if the RTL code given by index IDX is one that we should
121
   generate a gen_rtx_raw_FOO macro for, not gen_rtx_FOO (because gen_rtx_FOO
122
   is a wrapper in emit-rtl.c).  */
123
 
124
static int
125
special_rtx (int idx)
126
{
127
  return (strcmp (defs[idx].enumname, "CONST_INT") == 0
128
          || strcmp (defs[idx].enumname, "REG") == 0
129
          || strcmp (defs[idx].enumname, "SUBREG") == 0
130
          || strcmp (defs[idx].enumname, "MEM") == 0
131
          || strcmp (defs[idx].enumname, "PC") == 0
132
          || strcmp (defs[idx].enumname, "CC0") == 0
133
          || strcmp (defs[idx].enumname, "RETURN") == 0
134
          || strcmp (defs[idx].enumname, "SIMPLE_RETURN") == 0
135
          || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0);
136
}
137
 
138
/* Return nonzero if the RTL code given by index IDX is one that we should
139
   generate no macro for at all (because gen_rtx_FOO is never used or
140
   cannot have the obvious interface).  */
141
 
142
static int
143
excluded_rtx (int idx)
144
{
145
  return ((strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0)
146
          || (strcmp (defs[idx].enumname, "CONST_FIXED") == 0));
147
}
148
 
149
/* Place a list of all format specifiers we use into the array FORMAT.  */
150
 
151
static void
152
find_formats (void)
153
{
154
  unsigned int i;
155
 
156
  for (i = 0; i < NUM_RTX_CODE; i++)
157
    {
158
      const char **f;
159
 
160
      if (special_format (defs[i].format))
161
        continue;
162
 
163
      for (f = formats; *f; f++)
164
        if (! strcmp (*f, defs[i].format))
165
          break;
166
 
167
      if (*f == 0)
168
        *f = defs[i].format;
169
    }
170
}
171
 
172
 
173
/* Generate macros to generate RTL of code IDX using the functions we
174
   write.  */
175
 
176
static void
177
genmacro (int idx)
178
{
179
  const char *p;
180
  int i;
181
 
182
  /* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to
183
     gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE.  */
184
 
185
  if (excluded_rtx (idx))
186
    /* Don't define a macro for this code.  */
187
    return;
188
 
189
  printf ("#define gen_rtx_%s%s(MODE",
190
           special_rtx (idx) ? "raw_" : "", defs[idx].enumname);
191
 
192
  for (p = defs[idx].format, i = 0; *p != 0; p++)
193
    if (*p != '0')
194
      printf (", ARG%d", i++);
195
 
196
  printf (") \\\n  gen_rtx_fmt_%s (%s, (MODE)",
197
          defs[idx].format, defs[idx].enumname);
198
 
199
  for (p = defs[idx].format, i = 0; *p != 0; p++)
200
    if (*p != '0')
201
      printf (", (ARG%d)", i++);
202
 
203
  puts (")");
204
}
205
 
206
/* Generate the code for the function to generate RTL whose
207
   format is FORMAT.  */
208
 
209
static void
210
gendef (const char *format)
211
{
212
  const char *p;
213
  int i, j;
214
 
215
  /* Start by writing the definition of the function name and the types
216
     of the arguments.  */
217
 
218
  printf ("static inline rtx\ngen_rtx_fmt_%s_stat (RTX_CODE code, enum machine_mode mode", format);
219
  for (p = format, i = 0; *p != 0; p++)
220
    if (*p != '0')
221
      printf (",\n\t%sarg%d", type_from_format (*p), i++);
222
 
223
  puts (" MEM_STAT_DECL)");
224
 
225
  /* Now write out the body of the function itself, which allocates
226
     the memory and initializes it.  */
227
  puts ("{");
228
  puts ("  rtx rt;");
229
  puts ("  rt = rtx_alloc_stat (code PASS_MEM_STAT);\n");
230
 
231
  puts ("  PUT_MODE (rt, mode);");
232
 
233
  for (p = format, i = j = 0; *p ; ++p, ++i)
234
    if (*p != '0')
235
      printf ("  %s (rt, %d) = arg%d;\n", accessor_from_format (*p), i, j++);
236
    else
237
      printf ("  X0EXP (rt, %d) = NULL_RTX;\n", i);
238
 
239
  puts ("\n  return rt;\n}\n");
240
  printf ("#define gen_rtx_fmt_%s(c, m", format);
241
  for (p = format, i = 0; *p != 0; p++)
242
    if (*p != '0')
243
      printf (", p%i",i++);
244
  printf (")\\\n        gen_rtx_fmt_%s_stat (c, m", format);
245
  for (p = format, i = 0; *p != 0; p++)
246
    if (*p != '0')
247
      printf (", p%i",i++);
248
  printf (" MEM_STAT_INFO)\n\n");
249
}
250
 
251
/* Generate the documentation header for files we write.  */
252
 
253
static void
254
genlegend (void)
255
{
256
  puts ("/* Generated automatically by gengenrtl from rtl.def.  */\n");
257
}
258
 
259
/* Generate the text of the header file we make, genrtl.h.  */
260
 
261
static void
262
genheader (void)
263
{
264
  unsigned int i;
265
  const char **fmt;
266
 
267
  puts ("#ifndef GCC_GENRTL_H");
268
  puts ("#define GCC_GENRTL_H\n");
269
  puts ("#include \"statistics.h\"\n");
270
 
271
  for (fmt = formats; *fmt; ++fmt)
272
    gendef (*fmt);
273
 
274
  putchar ('\n');
275
 
276
  for (i = 0; i < NUM_RTX_CODE; i++)
277
    if (! special_format (defs[i].format))
278
      genmacro (i);
279
 
280
  puts ("\n#endif /* GCC_GENRTL_H */");
281
}
282
 
283
/* This is the main program.  */
284
 
285
int
286
main (void)
287
{
288
  find_formats ();
289
  genlegend ();
290
 
291
  genheader ();
292
 
293
  if (ferror (stdout) || fflush (stdout) || fclose (stdout))
294
    return FATAL_EXIT_CODE;
295
 
296
  return SUCCESS_EXIT_CODE;
297
}

powered by: WebSVN 2.1.0

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