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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [genflags.c] - Blame information for rev 843

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

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

powered by: WebSVN 2.1.0

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