OSDN Git Service

* Makefile.in (OBJS-common): Remove dwarfout.o.
[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, 1999, 2000,
3    2001, 2002, 2003 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22
23 #include "bconfig.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "errors.h"
29 #include "gensupport.h"
30
31
32 /* Many parts of GCC use arrays that are indexed by machine mode and
33    contain the insn codes for pattern in the MD file that perform a given
34    operation on operands of that mode.
35
36    These patterns are present in the MD file with names that contain
37    the mode(s) used and the name of the operation.  This program
38    writes a function `init_all_optabs' that initializes the optabs with
39    all the insn codes of the relevant patterns present in the MD file.
40
41    This array contains a list of optabs that need to be initialized.  Within
42    each string, the name of the pattern to be matched against is delimited
43    with $( and $).  In the string, $a and $b are used to match a short mode
44    name (the part of the mode name not including `mode' and converted to
45    lower-case).  When writing out the initializer, the entire string is
46    used.  $A and $B are replaced with the full name of the mode; $a and $b
47    are replaced with the short form of the name, as above.
48
49    If $N is present in the pattern, it means the two modes must be consecutive
50    widths in the same mode class (e.g, QImode and HImode).  $I means that
51    only full integer modes should be considered for the next mode, and $F
52    means that only float modes should be considered.
53    $P means that both full and partial integer modes should be considered.
54
55    $V means to emit 'v' if the first mode is a MODE_FLOAT mode.
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 static const char * const optabs[] =
62 { "sext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(extend$a$b2$)",
63   "zext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(zero_extend$a$b2$)",
64   "sfix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix$F$a$I$b2$)",
65   "ufix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns$F$a$b2$)",
66   "sfixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
67   "ufixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
68   "sfloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(float$I$a$F$b2$)",
69   "ufloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(floatuns$I$a$F$b2$)",
70   "trunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(trunc$a$b2$)",
71   "add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
72   "addv_optab->handlers[$A].insn_code =\n\
73     add_optab->handlers[$A].insn_code = CODE_FOR_$(add$F$a3$)",
74   "addv_optab->handlers[$A].insn_code = CODE_FOR_$(addv$I$a3$)",
75   "sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
76   "subv_optab->handlers[$A].insn_code =\n\
77     sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$F$a3$)",
78   "subv_optab->handlers[$A].insn_code = CODE_FOR_$(subv$I$a3$)",
79   "smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
80   "smulv_optab->handlers[$A].insn_code =\n\
81     smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$F$a3$)",
82   "smulv_optab->handlers[$A].insn_code = CODE_FOR_$(mulv$I$a3$)",
83   "umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
84   "smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
85   "smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
86   "umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
87   "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
88   "sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
89   "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
90   "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
91   "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
92   "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
93   "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
94   "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
95   "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
96   "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
97   "xor_optab->handlers[$A].insn_code = CODE_FOR_$(xor$a3$)",
98   "ashl_optab->handlers[$A].insn_code = CODE_FOR_$(ashl$a3$)",
99   "ashr_optab->handlers[$A].insn_code = CODE_FOR_$(ashr$a3$)",
100   "lshr_optab->handlers[$A].insn_code = CODE_FOR_$(lshr$a3$)",
101   "rotl_optab->handlers[$A].insn_code = CODE_FOR_$(rotl$a3$)",
102   "rotr_optab->handlers[$A].insn_code = CODE_FOR_$(rotr$a3$)",
103   "smin_optab->handlers[$A].insn_code = CODE_FOR_$(smin$I$a3$)",
104   "smin_optab->handlers[$A].insn_code = CODE_FOR_$(min$F$a3$)",
105   "smax_optab->handlers[$A].insn_code = CODE_FOR_$(smax$I$a3$)",
106   "smax_optab->handlers[$A].insn_code = CODE_FOR_$(max$F$a3$)",
107   "umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
108   "umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
109   "pow_optab->handlers[$A].insn_code = CODE_FOR_$(pow$a3$)",
110   "atan2_optab->handlers[$A].insn_code = CODE_FOR_$(atan2$a3$)",
111   "neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
112   "negv_optab->handlers[$A].insn_code =\n\
113     neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$F$a2$)",
114   "negv_optab->handlers[$A].insn_code = CODE_FOR_$(negv$I$a2$)",
115   "abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
116   "absv_optab->handlers[$A].insn_code =\n\
117     abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$F$a2$)",
118   "absv_optab->handlers[$A].insn_code = CODE_FOR_$(absv$I$a2$)",
119   "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
120   "floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
121   "ceil_optab->handlers[$A].insn_code = CODE_FOR_$(ceil$a2$)",
122   "round_optab->handlers[$A].insn_code = CODE_FOR_$(round$a2$)",
123   "trunc_optab->handlers[$A].insn_code = CODE_FOR_$(trunc$a2$)",
124   "nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
125   "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
126   "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
127   "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
128   "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
129   "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
130   "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
131   "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
132   "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
133   "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
134   "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
135   "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
136   "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
137   "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
138   "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
139   "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
140   "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
141   "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
142   "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
143   "bcc_gen_fctn[$C] = gen_$(b$c$)",
144   "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
145   "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
146   "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
147   "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
148   "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
149   "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
150   "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
151   "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
152   "movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
153   "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)",
154   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
155   "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)" };
156
157 static void gen_insn (rtx);
158
159 static void
160 gen_insn (rtx insn)
161 {
162   const char *name = XSTR (insn, 0);
163   int m1 = 0, m2 = 0, op = 0;
164   size_t pindex;
165   int i;
166   const char *np, *pp, *p, *q;
167
168   /* Don't mention instructions whose names are the null string.
169      They are in the machine description just to be recognized.  */
170   if (*name == 0)
171     return;
172
173   /* See if NAME matches one of the patterns we have for the optabs we know
174      about.  */
175
176   for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
177     {
178       int force_float = 0, force_int = 0, force_partial_int = 0;
179       int force_consec = 0;
180       int matches = 1;
181
182       for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
183         ;
184
185       for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
186            pp++)
187         {
188           if (*pp != '$')
189             {
190               if (*pp != *np++)
191                 break;
192             }
193           else
194             switch (*++pp)
195               {
196               case 'N':
197                 force_consec = 1;
198                 break;
199               case 'I':
200                 force_int = 1;
201                 break;
202               case 'P':
203                 force_partial_int = 1;
204                 break;
205               case 'F':
206                 force_float = 1;
207                 break;
208               case 'V':
209                 break;
210               case 'c':
211                 for (op = 0; op < NUM_RTX_CODE; op++)
212                   {
213                     for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
214                       if (*p != *q)
215                         break;
216
217                     /* We have to be concerned about matching "gt" and
218                        missing "gtu", e.g., so verify we have reached the
219                        end of thing we are to match.  */
220                     if (*p == 0 && *q == 0 && GET_RTX_CLASS(op) == '<')
221                       break;
222                   }
223
224                 if (op == NUM_RTX_CODE)
225                   matches = 0;
226                 else
227                   np += strlen (GET_RTX_NAME(op));
228                 break;
229               case 'a':
230               case 'b':
231                 /* This loop will stop at the first prefix match, so
232                    look through the modes in reverse order, in case
233                    there are extra CC modes and CC is a prefix of the
234                    CC modes (as it should be).  */
235                 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
236                   {
237                     for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
238                       if (TOLOWER (*p) != *q)
239                         break;
240
241                     if (*p == 0
242                         && (! force_int || mode_class[i] == MODE_INT 
243                             || mode_class[i] == MODE_VECTOR_INT)
244                         && (! force_partial_int
245                             || mode_class[i] == MODE_INT
246                             || mode_class[i] == MODE_PARTIAL_INT
247                             || mode_class[i] == MODE_VECTOR_INT)
248                         && (! force_float || mode_class[i] == MODE_FLOAT 
249                             || mode_class[i] == MODE_VECTOR_FLOAT))
250                       break;
251                   }
252
253                 if (i < 0)
254                   matches = 0;
255                 else if (*pp == 'a')
256                   m1 = i, np += strlen (GET_MODE_NAME(i));
257                 else
258                   m2 = i, np += strlen (GET_MODE_NAME(i));
259
260                 force_int = force_partial_int = force_float = 0;
261                 break;
262
263               default:
264                 abort ();
265               }
266         }
267
268       if (matches && pp[0] == '$' && pp[1] == ')'
269           && *np == 0
270           && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
271         break;
272     }
273
274   if (pindex == ARRAY_SIZE (optabs))
275     return;
276
277   /* We found a match.  If this pattern is only conditionally present,
278      write out the "if" and two extra blanks.  */
279
280   if (*XSTR (insn, 2) != 0)
281     printf ("  if (HAVE_%s)\n  ", name);
282
283   printf ("  ");
284
285   /* Now write out the initialization, making all required substitutions.  */
286   for (pp = optabs[pindex]; *pp; pp++)
287     {
288       if (*pp != '$')
289         putchar (*pp);
290       else
291         switch (*++pp)
292           {
293           case '(':  case ')':
294           case 'I':  case 'F':  case 'N':
295             break;
296           case 'V':
297             if (GET_MODE_CLASS (m1) == MODE_FLOAT)
298               printf ("v");
299             break;
300           case 'a':
301             for (np = GET_MODE_NAME(m1); *np; np++)
302               putchar (TOLOWER (*np));
303             break;
304           case 'b':
305             for (np = GET_MODE_NAME(m2); *np; np++)
306               putchar (TOLOWER (*np));
307             break;
308           case 'A':
309             printf ("%smode", GET_MODE_NAME(m1));
310             break;
311           case 'B':
312             printf ("%smode", GET_MODE_NAME(m2));
313             break;
314           case 'c':
315             printf ("%s", GET_RTX_NAME(op));
316             break;
317           case 'C':
318             for (np = GET_RTX_NAME(op); *np; np++)
319               putchar (TOUPPER (*np));
320             break;
321           }
322     }
323
324   printf (";\n");
325 }
326
327 extern int main (int, char **);
328
329 int
330 main (int argc, char **argv)
331 {
332   rtx desc;
333
334   progname = "genopinit";
335
336   if (argc <= 1)
337     fatal ("no input file name");
338
339   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
340     return (FATAL_EXIT_CODE);
341
342   printf ("/* Generated automatically by the program `genopinit'\n\
343 from the machine description file `md'.  */\n\n");
344
345   printf ("#include \"config.h\"\n");
346   printf ("#include \"system.h\"\n");
347   printf ("#include \"coretypes.h\"\n");
348   printf ("#include \"tm.h\"\n");
349   printf ("#include \"rtl.h\"\n");
350   printf ("#include \"flags.h\"\n");
351   printf ("#include \"insn-config.h\"\n");
352   printf ("#include \"recog.h\"\n");
353   printf ("#include \"expr.h\"\n");
354   printf ("#include \"optabs.h\"\n");
355   printf ("#include \"reload.h\"\n\n");
356
357   printf ("void\ninit_all_optabs (void)\n{\n");
358
359   puts ("\
360 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
361   int i, j;\n\
362 #endif\n");
363
364   /* Read the machine description.  */
365
366   while (1)
367     {
368       int line_no, insn_code_number = 0;
369
370       desc = read_md_rtx (&line_no, &insn_code_number);
371       if (desc == NULL)
372         break;
373
374       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
375         gen_insn (desc);
376     }
377
378   puts ("\
379 \n\
380 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
381   /* This flag says the same insns that convert to a signed fixnum\n\
382      also convert validly to an unsigned one.  */\n\
383   for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
384     for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
385       ufixtrunc_optab->handlers[i][j].insn_code\n\
386       = sfixtrunc_optab->handlers[i][j].insn_code;\n\
387 #endif\n\
388 }");
389
390   fflush (stdout);
391   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
392 }
393
394 /* Define this so we can link with print-rtl.o to get debug_rtx function.  */
395 const char *
396 get_insn_name (int code ATTRIBUTE_UNUSED)
397 {
398   return NULL;
399 }