OSDN Git Service

2004-05-03 Uros Bizjak <uros@kss-loka.si>
[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, 2004 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   "sincos_optab->handlers[$A].insn_code = CODE_FOR_$(sincos$a3$)",
126   "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
127   "asin_optab->handlers[$A].insn_code = CODE_FOR_$(asin$a2$)",
128   "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
129   "acos_optab->handlers[$A].insn_code = CODE_FOR_$(acos$a2$)",
130   "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
131   "exp10_optab->handlers[$A].insn_code = CODE_FOR_$(exp10$a2$)",
132   "exp2_optab->handlers[$A].insn_code = CODE_FOR_$(exp2$a2$)",
133   "expm1_optab->handlers[$A].insn_code = CODE_FOR_$(expm1$a2$)",
134   "logb_optab->handlers[$A].insn_code = CODE_FOR_$(logb$a2$)",
135   "ilogb_optab->handlers[$A].insn_code = CODE_FOR_$(ilogb$a2$)",
136   "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
137   "log10_optab->handlers[$A].insn_code = CODE_FOR_$(log10$a2$)",  
138   "log2_optab->handlers[$A].insn_code = CODE_FOR_$(log2$a2$)",  
139   "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
140   "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
141   "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
142   "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
143   "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
144   "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
145   "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
146   "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
147   "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
148   "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
149   "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
150   "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
151   "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
152   "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
153   "bcc_gen_fctn[$C] = gen_$(b$c$)",
154   "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
155   "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
156   "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
157   "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
158   "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
159   "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
160   "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
161   "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
162   "movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
163   "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)",
164   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
165   "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
166   "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)",
167   "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)",
168   "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)" };
169
170 static void gen_insn (rtx);
171
172 static void
173 gen_insn (rtx insn)
174 {
175   const char *name = XSTR (insn, 0);
176   int m1 = 0, m2 = 0, op = 0;
177   size_t pindex;
178   int i;
179   const char *np, *pp, *p, *q;
180
181   /* Don't mention instructions whose names are the null string.
182      They are in the machine description just to be recognized.  */
183   if (*name == 0)
184     return;
185
186   /* See if NAME matches one of the patterns we have for the optabs we know
187      about.  */
188
189   for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
190     {
191       int force_float = 0, force_int = 0, force_partial_int = 0;
192       int force_consec = 0;
193       int matches = 1;
194
195       for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
196         ;
197
198       for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
199            pp++)
200         {
201           if (*pp != '$')
202             {
203               if (*pp != *np++)
204                 break;
205             }
206           else
207             switch (*++pp)
208               {
209               case 'N':
210                 force_consec = 1;
211                 break;
212               case 'I':
213                 force_int = 1;
214                 break;
215               case 'P':
216                 force_partial_int = 1;
217                 break;
218               case 'F':
219                 force_float = 1;
220                 break;
221               case 'V':
222                 break;
223               case 'c':
224                 for (op = 0; op < NUM_RTX_CODE; op++)
225                   {
226                     for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
227                       if (*p != *q)
228                         break;
229
230                     /* We have to be concerned about matching "gt" and
231                        missing "gtu", e.g., so verify we have reached the
232                        end of thing we are to match.  */
233                     if (*p == 0 && *q == 0
234                         && (GET_RTX_CLASS (op) == RTX_COMPARE
235                             || GET_RTX_CLASS (op) == RTX_COMM_COMPARE))
236                       break;
237                   }
238
239                 if (op == NUM_RTX_CODE)
240                   matches = 0;
241                 else
242                   np += strlen (GET_RTX_NAME(op));
243                 break;
244               case 'a':
245               case 'b':
246                 /* This loop will stop at the first prefix match, so
247                    look through the modes in reverse order, in case
248                    there are extra CC modes and CC is a prefix of the
249                    CC modes (as it should be).  */
250                 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
251                   {
252                     for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
253                       if (TOLOWER (*p) != *q)
254                         break;
255
256                     if (*p == 0
257                         && (! force_int || mode_class[i] == MODE_INT 
258                             || mode_class[i] == MODE_VECTOR_INT)
259                         && (! force_partial_int
260                             || mode_class[i] == MODE_INT
261                             || mode_class[i] == MODE_PARTIAL_INT
262                             || mode_class[i] == MODE_VECTOR_INT)
263                         && (! force_float || mode_class[i] == MODE_FLOAT 
264                             || mode_class[i] == MODE_VECTOR_FLOAT))
265                       break;
266                   }
267
268                 if (i < 0)
269                   matches = 0;
270                 else if (*pp == 'a')
271                   m1 = i, np += strlen (GET_MODE_NAME(i));
272                 else
273                   m2 = i, np += strlen (GET_MODE_NAME(i));
274
275                 force_int = force_partial_int = force_float = 0;
276                 break;
277
278               default:
279                 abort ();
280               }
281         }
282
283       if (matches && pp[0] == '$' && pp[1] == ')'
284           && *np == 0
285           && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
286         break;
287     }
288
289   if (pindex == ARRAY_SIZE (optabs))
290     return;
291
292   /* We found a match.  If this pattern is only conditionally present,
293      write out the "if" and two extra blanks.  */
294
295   if (*XSTR (insn, 2) != 0)
296     printf ("  if (HAVE_%s)\n  ", name);
297
298   printf ("  ");
299
300   /* Now write out the initialization, making all required substitutions.  */
301   for (pp = optabs[pindex]; *pp; pp++)
302     {
303       if (*pp != '$')
304         putchar (*pp);
305       else
306         switch (*++pp)
307           {
308           case '(':  case ')':
309           case 'I':  case 'F':  case 'N':
310             break;
311           case 'V':
312             if (GET_MODE_CLASS (m1) == MODE_FLOAT)
313               printf ("v");
314             break;
315           case 'a':
316             for (np = GET_MODE_NAME(m1); *np; np++)
317               putchar (TOLOWER (*np));
318             break;
319           case 'b':
320             for (np = GET_MODE_NAME(m2); *np; np++)
321               putchar (TOLOWER (*np));
322             break;
323           case 'A':
324             printf ("%smode", GET_MODE_NAME(m1));
325             break;
326           case 'B':
327             printf ("%smode", GET_MODE_NAME(m2));
328             break;
329           case 'c':
330             printf ("%s", GET_RTX_NAME(op));
331             break;
332           case 'C':
333             for (np = GET_RTX_NAME(op); *np; np++)
334               putchar (TOUPPER (*np));
335             break;
336           }
337     }
338
339   printf (";\n");
340 }
341
342 extern int main (int, char **);
343
344 int
345 main (int argc, char **argv)
346 {
347   rtx desc;
348
349   progname = "genopinit";
350
351   if (argc <= 1)
352     fatal ("no input file name");
353
354   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
355     return (FATAL_EXIT_CODE);
356
357   printf ("/* Generated automatically by the program `genopinit'\n\
358 from the machine description file `md'.  */\n\n");
359
360   printf ("#include \"config.h\"\n");
361   printf ("#include \"system.h\"\n");
362   printf ("#include \"coretypes.h\"\n");
363   printf ("#include \"tm.h\"\n");
364   printf ("#include \"rtl.h\"\n");
365   printf ("#include \"flags.h\"\n");
366   printf ("#include \"insn-config.h\"\n");
367   printf ("#include \"recog.h\"\n");
368   printf ("#include \"expr.h\"\n");
369   printf ("#include \"optabs.h\"\n");
370   printf ("#include \"reload.h\"\n\n");
371
372   printf ("void\ninit_all_optabs (void)\n{\n");
373
374   puts ("\
375 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
376   int i, j;\n\
377 #endif\n");
378
379   /* Read the machine description.  */
380
381   while (1)
382     {
383       int line_no, insn_code_number = 0;
384
385       desc = read_md_rtx (&line_no, &insn_code_number);
386       if (desc == NULL)
387         break;
388
389       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
390         gen_insn (desc);
391     }
392
393   puts ("\
394 \n\
395 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
396   /* This flag says the same insns that convert to a signed fixnum\n\
397      also convert validly to an unsigned one.  */\n\
398   for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
399     for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
400       ufixtrunc_optab->handlers[i][j].insn_code\n\
401       = sfixtrunc_optab->handlers[i][j].insn_code;\n\
402 #endif\n\
403 }");
404
405   fflush (stdout);
406   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
407 }
408
409 /* Define this so we can link with print-rtl.o to get debug_rtx function.  */
410 const char *
411 get_insn_name (int code ATTRIBUTE_UNUSED)
412 {
413   return NULL;
414 }