OSDN Git Service

(fold, COND_EXPR case): All simplified results
[pf3gnuchains/gcc-fork.git] / gcc / genopinit.c
1 /* Generate code to initialize optabs from machine description.
2    Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 #include <stdio.h>
22 #include "hconfig.h"
23 #include "rtl.h"
24 #include "obstack.h"
25 #include <ctype.h>
26
27 static struct obstack obstack;
28 struct obstack *rtl_obstack = &obstack;
29
30 #define obstack_chunk_alloc xmalloc
31 #define obstack_chunk_free free
32
33 extern void free ();
34 extern rtx read_rtx ();
35
36 char *xmalloc ();
37 static void fatal ();
38 void fancy_abort ();
39
40 /* Many parts of GCC use arrays that are indexed by machine mode and
41    contain the insn codes for pattern in the MD file that perform a given
42    operation on operands of that mode.
43
44    These patterns are present in the MD file with names that contain
45    the mode(s) used and the name of the operation.  This program
46    writes a function `init_all_optabs' that initializes the optabs with
47    all the insn codes of the relevant patterns present in the MD file.
48
49    This array contains a list of optabs that need to be initialized.  Within
50    each string, the name of the pattern to be matched against is delimited
51    with %( and %).  In the string, %a and %b are used to match a short mode
52    name (the part of the mode name not including `mode' and converted to
53    lower-case).  When writing out the initializer, the entire string is
54    used.  %A and %B are replaced with the full name of the mode; %a and %b
55    are replaced with the short form of the name, as above.
56
57    If %N is present in the pattern, it means the two modes must be consecutive
58    widths in the same mode class (e.g, QImode and HImode).  %I means that
59    only integer modes should be considered for the next mode, and %F means
60    that only float modes should be considered.
61
62    For some optabs, we store the operation by RTL codes.  These are only
63    used for comparisons.  In that case, %c and %C are the lower-case and
64    upper-case forms of the comparison, respectively.  */
65
66 /* The reason we use \% is to avoid sequences of the form %-capletter-%
67    which SCCS treats as magic.  This gets warnings which you should ignore.  */
68
69 char *optabs[] =
70 { "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)",
71   "extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)",
72   "fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)",
73   "fixtab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns%F\%a%b2%)",
74   "fixtrunctab[(int) %A][(int) %B][0] = CODE_FOR_%(fix_trunc%F\%a%I\%b2%)",
75   "fixtrunctab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns_trunc%F\%a%I\%b2%)",
76   "floattab[(int) %B][(int) %A][0] = CODE_FOR_%(float%I\%a%F\%b2%)",
77   "floattab[(int) %B][(int) %A][1] = CODE_FOR_%(floatuns%I\%a%F\%b2%)",
78   "add_optab->handlers[(int) %A].insn_code = CODE_FOR_%(add%a3%)",
79   "sub_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sub%a3%)",
80   "smul_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mul%a3%)",
81   "smul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(mul%a%b3%)%N",
82   "umul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(umul%a%b3%)%N",
83   "sdiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%I\%a3%)",
84   "udiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udiv%I\%a3%)",
85   "sdivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(divmod%a4%)",
86   "udivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udivmod%a4%)",
87   "smod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mod%a3%)",
88   "umod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umod%a3%)",
89   "flodiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%F\%a3%)",
90   "ftrunc_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ftrunc%F\%a2%)",
91   "and_optab->handlers[(int) %A].insn_code = CODE_FOR_%(and%a3%)",
92   "ior_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ior%a3%)",
93   "xor_optab->handlers[(int) %A].insn_code = CODE_FOR_%(xor%a3%)",
94   "ashl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashl%a3%)",
95   "ashr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashr%a3%)",
96   "lshl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshl%a3%)",
97   "lshr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshr%a3%)",
98   "rotl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotl%a3%)",
99   "rotr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotr%a3%)",
100   "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smin%I\%a3%)",
101   "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(min%F\%a3%)",
102   "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smax%I\%a3%)",
103   "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(max%F\%a3%)",
104   "umin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umin%I\%a3%)",
105   "umax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umax%I\%a3%)",
106   "neg_optab->handlers[(int) %A].insn_code = CODE_FOR_%(neg%a2%)",
107   "abs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(abs%a2%)",
108   "sqrt_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sqrt%a2%)",
109   "sin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sin%a2%)",
110   "cos_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cos%a2%)",
111   "strlen_optab->handlers[(int) %A].insn_code = CODE_FOR_%(strlen%a%)",
112   "one_cmpl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(one_cmpl%a2%)",
113   "ffs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ffs%a2%)",
114   "mov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mov%a%)",
115   "movstrict_optab->handlers[(int) %A].insn_code = CODE_FOR_%(movstrict%a%)",
116   "cmp_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmp%a%)",
117   "tst_optab->handlers[(int) %A].insn_code = CODE_FOR_%(tst%a%)",
118   "bcc_gen_fctn[(int) %C] = gen_%(b%c%)",
119   "setcc_gen_code[(int) %C] = CODE_FOR_%(s%c%)",
120   "reload_in_optab[(int) %A] = CODE_FOR_%(reload_in%a%)",
121   "reload_out_optab[(int) %A] = CODE_FOR_%(reload_out%a%)",
122   "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)" };
123
124 /* Allow linking with print-rtl.c.  */
125 char **insn_name_ptr;
126
127 static void
128 gen_insn (insn)
129      rtx insn;
130 {
131   char *name = XSTR (insn, 0);
132   int m1, m2, op;
133   int pindex;
134   int i;
135   char *np, *pp, *p, *q;
136   struct obstack *obstack_ptr;
137
138   /* Don't mention instructions whose names are the null string.
139      They are in the machine description just to be recognized.  */
140   if (*name == 0)
141     return;
142
143   /* See if NAME matches one of the patterns we have for the optabs we know
144      about.  */
145
146   for (pindex = 0; pindex < sizeof optabs / sizeof optabs[0]; pindex++)
147     {
148       int force_float = 0, force_int = 0;
149       int force_consec = 0;
150       int matches = 1;
151
152       for (pp = optabs[pindex]; pp[0] != '%' || pp[1] != '('; pp++)
153         ;
154
155       for (pp += 2, np = name; matches && ! (pp[0] == '%' && pp[1] == ')');
156            pp++)
157         {
158           if (*pp != '%')
159             {
160               if (*pp != *np++)
161                 break;
162             }
163           else
164             switch (*++pp)
165               {
166               case 'N':
167                 force_consec = 1;
168                 break;
169               case 'I':
170                 force_int = 1;
171                 break;
172               case 'F':
173                 force_float = 1;
174                 break;
175               case 'c':
176                 for (op = 0; op < NUM_RTX_CODE; op++)
177                   {
178                     for (p = rtx_name[op], q = np; *p; p++, q++)
179                       if (*p != *q)
180                         break;
181
182                     /* We have to be concerned about matching "gt" and
183                        missing "gtu", e.g., so verify we have reached the
184                        end of thing we are to match.  We do not have this
185                        problem with modes since no mode is a prefix of
186                        another.  */
187                     if (*p == 0 && *q == 0 && rtx_class[op] == '<')
188                       break;
189                   }
190
191                 if (op == NUM_RTX_CODE)
192                   matches = 0;
193                 else
194                   np += strlen (rtx_name[op]);
195                 break;
196               case 'a':
197               case 'b':
198                 for (i = 0; i < (int) MAX_MACHINE_MODE; i++)
199                   {
200                     for (p = 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 == (int) MAX_MACHINE_MODE)
211                   matches = 0;
212                 else if (*pp == 'a')
213                   m1 = i, np += strlen (mode_name[i]);
214                 else
215                   m2 = i, np += strlen (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) 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 = mode_name[m1]; *np; np++)
255               printf ("%c", tolower (*np));
256             break;
257           case 'b':
258             for (np = mode_name[m2]; *np; np++)
259               printf ("%c", tolower (*np));
260             break;
261           case 'A':
262             printf ("%smode", mode_name[m1]);
263             break;
264           case 'B':
265             printf ("%smode", mode_name[m2]);
266             break;
267           case 'c':
268             printf ("%s", rtx_name[op]);
269             break;
270           case 'C':
271             for (np = rtx_name[op]; *np; np++)
272               printf ("%c", toupper (*np));
273             break;
274           }
275     }
276
277   printf (";\n");
278 }
279 \f
280 char *
281 xmalloc (size)
282      unsigned size;
283 {
284   register char *val = (char *) malloc (size);
285
286   if (val == 0)
287     fatal ("virtual memory exhausted");
288
289   return val;
290 }
291
292 char *
293 xrealloc (ptr, size)
294      char *ptr;
295      unsigned size;
296 {
297   char *result = (char *) realloc (ptr, size);
298   if (!result)
299     fatal ("virtual memory exhausted");
300   return result;
301 }
302
303 static void
304 fatal (s, a1, a2)
305      char *s;
306 {
307   fprintf (stderr, "genopinit: ");
308   fprintf (stderr, s, a1, a2);
309   fprintf (stderr, "\n");
310   exit (FATAL_EXIT_CODE);
311 }
312
313 /* More 'friendly' abort that prints the line and file.
314    config.h can #define abort fancy_abort if you like that sort of thing.  */
315
316 void
317 fancy_abort ()
318 {
319   fatal ("Internal gcc abort.");
320 }
321 \f
322 int
323 main (argc, argv)
324      int argc;
325      char **argv;
326 {
327   rtx desc;
328   rtx dummy;
329   rtx *insn_ptr;
330   FILE *infile;
331   register int c;
332
333   obstack_init (rtl_obstack);
334
335   if (argc <= 1)
336     fatal ("No input file name.");
337
338   infile = fopen (argv[1], "r");
339   if (infile == 0)
340     {
341       perror (argv[1]);
342       exit (FATAL_EXIT_CODE);
343     }
344
345   init_rtl ();
346
347   printf ("/* Generated automatically by the program `genopinit'\n\
348 from the machine description file `md'.  */\n\n");
349
350   printf ("#include \"config.h\"\n");
351   printf ("#include \"rtl.h\"\n");
352   printf ("#include \"flags.h\"\n");
353   printf ("#include \"insn-flags.h\"\n");
354   printf ("#include \"insn-codes.h\"\n");
355   printf ("#include \"insn-config.h\"\n");
356   printf ("#include \"recog.h\"\n");
357   printf ("#include \"expr.h\"\n");
358   printf ("#include \"reload.h\"\n\n");
359
360   printf ("void\ninit_all_optabs ()\n{\n");
361
362   /* Read the machine description.  */
363
364   while (1)
365     {
366       c = read_skip_spaces (infile);
367       if (c == EOF)
368         break;
369       ungetc (c, infile);
370
371       desc = read_rtx (infile);
372       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
373         gen_insn (desc);
374     }
375
376   printf ("}\n");
377
378   fflush (stdout);
379   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
380   /* NOTREACHED */
381   return 0;
382 }