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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [genflags.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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