OSDN Git Service

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