OSDN Git Service

* decl.c (init_decl_processing): Remove duplicate decl of
[pf3gnuchains/gcc-fork.git] / gcc / genopinit.c
1 /* Generate code to initialize optabs from machine description.
2    Copyright (C) 1993, 94-99, 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21
22 #include "hconfig.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "obstack.h"
26 #include "errors.h"
27
28 static struct obstack obstack;
29 struct obstack *rtl_obstack = &obstack;
30
31 #define obstack_chunk_alloc xmalloc
32 #define obstack_chunk_free free
33
34 /* Many parts of GCC use arrays that are indexed by machine mode and
35    contain the insn codes for pattern in the MD file that perform a given
36    operation on operands of that mode.
37
38    These patterns are present in the MD file with names that contain
39    the mode(s) used and the name of the operation.  This program
40    writes a function `init_all_optabs' that initializes the optabs with
41    all the insn codes of the relevant patterns present in the MD file.
42
43    This array contains a list of optabs that need to be initialized.  Within
44    each string, the name of the pattern to be matched against is delimited
45    with %( and %).  In the string, %a and %b are used to match a short mode
46    name (the part of the mode name not including `mode' and converted to
47    lower-case).  When writing out the initializer, the entire string is
48    used.  %A and %B are replaced with the full name of the mode; %a and %b
49    are replaced with the short form of the name, as above.
50
51    If %N is present in the pattern, it means the two modes must be consecutive
52    widths in the same mode class (e.g, QImode and HImode).  %I means that
53    only integer modes should be considered for the next mode, and %F means
54    that only float modes should be considered.
55
56    For some optabs, we store the operation by RTL codes.  These are only
57    used for comparisons.  In that case, %c and %C are the lower-case and
58    upper-case forms of the comparison, respectively.  */
59
60 /* The reason we use \% is to avoid sequences of the form %-capletter-%
61    which SCCS treats as magic.  This gets warnings which you should ignore.  */
62
63 const char * const optabs[] =
64 { "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)",
65   "extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)",
66   "fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)",
67   "fixtab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns%F\%a%b2%)",
68   "fixtrunctab[(int) %A][(int) %B][0] = CODE_FOR_%(fix_trunc%F\%a%I\%b2%)",
69   "fixtrunctab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns_trunc%F\%a%I\%b2%)",
70   "floattab[(int) %B][(int) %A][0] = CODE_FOR_%(float%I\%a%F\%b2%)",
71   "floattab[(int) %B][(int) %A][1] = CODE_FOR_%(floatuns%I\%a%F\%b2%)",
72   "add_optab->handlers[(int) %A].insn_code = CODE_FOR_%(add%a3%)",
73   "sub_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sub%a3%)",
74   "smul_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mul%a3%)",
75   "umul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umul%a3_highpart%)",
76   "smul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smul%a3_highpart%)",
77   "smul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(mul%a%b3%)%N",
78   "umul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(umul%a%b3%)%N",
79   "sdiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%I\%a3%)",
80   "udiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udiv%I\%a3%)",
81   "sdivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(divmod%a4%)",
82   "udivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udivmod%a4%)",
83   "smod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mod%a3%)",
84   "umod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umod%a3%)",
85   "flodiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%F\%a3%)",
86   "ftrunc_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ftrunc%F\%a2%)",
87   "and_optab->handlers[(int) %A].insn_code = CODE_FOR_%(and%a3%)",
88   "ior_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ior%a3%)",
89   "xor_optab->handlers[(int) %A].insn_code = CODE_FOR_%(xor%a3%)",
90   "ashl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashl%a3%)",
91   "ashr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashr%a3%)",
92   "lshr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshr%a3%)",
93   "rotl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotl%a3%)",
94   "rotr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotr%a3%)",
95   "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smin%I\%a3%)",
96   "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(min%F\%a3%)",
97   "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smax%I\%a3%)",
98   "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(max%F\%a3%)",
99   "umin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umin%I\%a3%)",
100   "umax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umax%I\%a3%)",
101   "neg_optab->handlers[(int) %A].insn_code = CODE_FOR_%(neg%a2%)",
102   "abs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(abs%a2%)",
103   "sqrt_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sqrt%a2%)",
104   "sin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sin%a2%)",
105   "cos_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cos%a2%)",
106   "strlen_optab->handlers[(int) %A].insn_code = CODE_FOR_%(strlen%a%)",
107   "one_cmpl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(one_cmpl%a2%)",
108   "ffs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ffs%a2%)",
109   "mov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mov%a%)",
110   "movstrict_optab->handlers[(int) %A].insn_code = CODE_FOR_%(movstrict%a%)",
111   "cmp_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmp%a%)",
112   "tst_optab->handlers[(int) %A].insn_code = CODE_FOR_%(tst%a%)",
113   "bcc_gen_fctn[(int) %C] = gen_%(b%c%)",
114   "setcc_gen_code[(int) %C] = CODE_FOR_%(s%c%)",
115   "movcc_gen_code[(int) %A] = CODE_FOR_%(mov%acc%)",
116   "cbranch_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cbranch%a4%)",
117   "cmov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmov%a6%)",
118   "cstore_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cstore%a4%)",
119   "reload_in_optab[(int) %A] = CODE_FOR_%(reload_in%a%)",
120   "reload_out_optab[(int) %A] = CODE_FOR_%(reload_out%a%)",
121   "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)",
122   "clrstr_optab[(int) %A] = CODE_FOR_%(clrstr%a%)" };
123
124 static void gen_insn PARAMS ((rtx));
125
126 static void
127 gen_insn (insn)
128      rtx insn;
129 {
130   char *name = XSTR (insn, 0);
131   int m1 = 0, m2 = 0, op = 0;
132   size_t pindex;
133   int i;
134   const char *np, *pp, *p, *q;
135
136   /* Don't mention instructions whose names are the null string.
137      They are in the machine description just to be recognized.  */
138   if (*name == 0)
139     return;
140
141   /* See if NAME matches one of the patterns we have for the optabs we know
142      about.  */
143
144   for (pindex = 0; pindex < sizeof optabs / sizeof optabs[0]; pindex++)
145     {
146       int force_float = 0, force_int = 0;
147       int force_consec = 0;
148       int matches = 1;
149
150       for (pp = optabs[pindex]; pp[0] != '%' || pp[1] != '('; pp++)
151         ;
152
153       for (pp += 2, np = name; matches && ! (pp[0] == '%' && pp[1] == ')');
154            pp++)
155         {
156           if (*pp != '%')
157             {
158               if (*pp != *np++)
159                 break;
160             }
161           else
162             switch (*++pp)
163               {
164               case 'N':
165                 force_consec = 1;
166                 break;
167               case 'I':
168                 force_int = 1;
169                 break;
170               case 'F':
171                 force_float = 1;
172                 break;
173               case 'c':
174                 for (op = 0; op < NUM_RTX_CODE; op++)
175                   {
176                     for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
177                       if (*p != *q)
178                         break;
179
180                     /* We have to be concerned about matching "gt" and
181                        missing "gtu", e.g., so verify we have reached the
182                        end of thing we are to match.  */
183                     if (*p == 0 && *q == 0 && GET_RTX_CLASS(op) == '<')
184                       break;
185                   }
186
187                 if (op == NUM_RTX_CODE)
188                   matches = 0;
189                 else
190                   np += strlen (GET_RTX_NAME(op));
191                 break;
192               case 'a':
193               case 'b':
194                 /* This loop will stop at the first prefix match, so
195                    look through the modes in reverse order, in case
196                    EXTRA_CC_MODES was used and CC is a prefix of the
197                    CC modes (as it should be).  */
198                 for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
199                   {
200                     for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
201                       if (TOLOWER (*p) != *q)
202                         break;
203
204                     if (*p == 0
205                         && (! force_int || mode_class[i] == MODE_INT)
206                         && (! force_float || mode_class[i] == MODE_FLOAT))
207                       break;
208                   }
209
210                 if (i < 0)
211                   matches = 0;
212                 else if (*pp == 'a')
213                   m1 = i, np += strlen (GET_MODE_NAME(i));
214                 else
215                   m2 = i, np += strlen (GET_MODE_NAME(i));
216
217                 force_int = force_float = 0;
218                 break;
219
220               default:
221                 abort ();
222               }
223         }
224
225       if (matches && pp[0] == '%' && pp[1] == ')'
226           && *np == 0
227           && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
228         break;
229     }
230
231   if (pindex == sizeof optabs / sizeof optabs[0])
232     return;
233
234   /* We found a match.  If this pattern is only conditionally present,
235      write out the "if" and two extra blanks.  */
236
237   if (*XSTR (insn, 2) != 0)
238     printf ("  if (HAVE_%s)\n  ", name);
239
240   printf ("  ");
241
242   /* Now write out the initialization, making all required substitutions.  */
243   for (pp = optabs[pindex]; *pp; pp++)
244     {
245       if (*pp != '%')
246         printf ("%c", *pp);
247       else
248         switch (*++pp)
249           {
250           case '(':  case ')':
251           case 'I':  case 'F':  case 'N':
252             break;
253           case 'a':
254             for (np = GET_MODE_NAME(m1); *np; np++)
255               putchar (TOLOWER (*np));
256             break;
257           case 'b':
258             for (np = GET_MODE_NAME(m2); *np; np++)
259               putchar (TOLOWER (*np));
260             break;
261           case 'A':
262             printf ("%smode", GET_MODE_NAME(m1));
263             break;
264           case 'B':
265             printf ("%smode", GET_MODE_NAME(m2));
266             break;
267           case 'c':
268             printf ("%s", GET_RTX_NAME(op));
269             break;
270           case 'C':
271             for (np = GET_RTX_NAME(op); *np; np++)
272               putchar (TOUPPER (*np));
273             break;
274           }
275     }
276
277   printf (";\n");
278 }
279 \f
280 PTR
281 xmalloc (size)
282   size_t size;
283 {
284   register PTR val = (PTR) malloc (size);
285
286   if (val == 0)
287     fatal ("virtual memory exhausted");
288
289   return val;
290 }
291
292 PTR
293 xrealloc (old, size)
294   PTR old;
295   size_t size;
296 {
297   register PTR ptr;
298   if (old)
299     ptr = (PTR) realloc (old, size);
300   else
301     ptr = (PTR) malloc (size);
302   if (!ptr)
303     fatal ("virtual memory exhausted");
304   return ptr;
305 }
306
307 extern int main PARAMS ((int, char **));
308
309 int
310 main (argc, argv)
311      int argc;
312      char **argv;
313 {
314   rtx desc;
315   FILE *infile;
316   register int c;
317
318   progname = "genopinit";
319   obstack_init (rtl_obstack);
320
321   if (argc <= 1)
322     fatal ("No input file name.");
323
324   infile = fopen (argv[1], "r");
325   if (infile == 0)
326     {
327       perror (argv[1]);
328       return (FATAL_EXIT_CODE);
329     }
330   read_rtx_filename = argv[1];
331
332   printf ("/* Generated automatically by the program `genopinit'\n\
333 from the machine description file `md'.  */\n\n");
334
335   printf ("#include \"config.h\"\n");
336   printf ("#include \"system.h\"\n");
337   printf ("#include \"rtl.h\"\n");
338   printf ("#include \"flags.h\"\n");
339   printf ("#include \"insn-flags.h\"\n");
340   printf ("#include \"insn-codes.h\"\n");
341   printf ("#include \"insn-config.h\"\n");
342   printf ("#include \"recog.h\"\n");
343   printf ("#include \"expr.h\"\n");
344   printf ("#include \"reload.h\"\n\n");
345
346   printf ("void\ninit_all_optabs ()\n{\n");
347
348   /* Read the machine description.  */
349
350   while (1)
351     {
352       c = read_skip_spaces (infile);
353       if (c == EOF)
354         break;
355       ungetc (c, infile);
356
357       desc = read_rtx (infile);
358       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
359         gen_insn (desc);
360     }
361
362   printf ("}\n");
363
364   fflush (stdout);
365   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
366 }
367
368 /* Define this so we can link with print-rtl.o to get debug_rtx function.  */
369 const char *
370 get_insn_name (code)
371      int code ATTRIBUTE_UNUSED;
372 {
373   return NULL;
374 }