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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 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, 2010
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 "read-md.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 (int, 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 (int line_no, rtx insn)
192
{
193
  const char *name = XSTR (insn, 0);
194
  const char *p;
195
  const char *lt, *gt;
196
  int len;
197
  int truth = maybe_eval_c_test (XSTR (insn, 2));
198
 
199
  lt = strchr (name, '<');
200
  if (lt && strchr (lt + 1, '>'))
201
    {
202
      message_with_line (line_no, "unresolved iterator");
203
      have_error = 1;
204
      return;
205
    }
206
 
207
  gt = strchr (name, '>');
208
  if (lt || gt)
209
    {
210
      message_with_line (line_no,
211
                         "unmatched angle brackets, likely "
212
                         "an error in iterator syntax");
213
      have_error = 1;
214
      return;
215
    }
216
 
217
  /* Don't mention instructions whose names are the null string
218
     or begin with '*'.  They are in the machine description just
219
     to be recognized.  */
220
  if (name[0] == 0 || name[0] == '*')
221
    return;
222
 
223
  len = strlen (name);
224
 
225
  if (len > max_id_len)
226
    max_id_len = len;
227
 
228
  if (truth == 0)
229
    /* Emit nothing.  */;
230
  else if (truth == 1)
231
    printf ("#define HAVE_%s 1\n", name);
232
  else
233
    {
234
      /* Write the macro definition, putting \'s at the end of each line,
235
         if more than one.  */
236
      printf ("#define HAVE_%s (", name);
237
      for (p = XSTR (insn, 2); *p; p++)
238
        {
239
          if (IS_VSPACE (*p))
240
            fputs (" \\\n", stdout);
241
          else
242
            putchar (*p);
243
        }
244
      fputs (")\n", stdout);
245
    }
246
 
247
  obstack_grow (&obstack, &insn, sizeof (rtx));
248
}
249
 
250
int
251
main (int argc, char **argv)
252
{
253
  rtx desc;
254
  rtx dummy;
255
  rtx *insns;
256
  rtx *insn_ptr;
257
 
258
  progname = "genflags";
259
  obstack_init (&obstack);
260
 
261
  /* We need to see all the possibilities.  Elided insns may have
262
     direct calls to their generators in C code.  */
263
  insn_elision = 0;
264
 
265
  if (!init_rtx_reader_args (argc, argv))
266
    return (FATAL_EXIT_CODE);
267
 
268
  puts ("/* Generated automatically by the program `genflags'");
269
  puts ("   from the machine description file `md'.  */\n");
270
  puts ("#ifndef GCC_INSN_FLAGS_H");
271
  puts ("#define GCC_INSN_FLAGS_H\n");
272
 
273
  /* Read the machine description.  */
274
 
275
  while (1)
276
    {
277
      int line_no, insn_code_number = 0;
278
 
279
      desc = read_md_rtx (&line_no, &insn_code_number);
280
      if (desc == NULL)
281
        break;
282
      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
283
        gen_insn (line_no, desc);
284
    }
285
 
286
  /* Print out the prototypes now.  */
287
  dummy = (rtx) 0;
288
  obstack_grow (&obstack, &dummy, sizeof (rtx));
289
  insns = XOBFINISH (&obstack, rtx *);
290
 
291
  for (insn_ptr = insns; *insn_ptr; insn_ptr++)
292
    gen_proto (*insn_ptr);
293
 
294
  puts("\n#endif /* GCC_INSN_FLAGS_H */");
295
 
296
  if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
297
    return FATAL_EXIT_CODE;
298
 
299
  return SUCCESS_EXIT_CODE;
300
}

powered by: WebSVN 2.1.0

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