OSDN Git Service

a16d0e17c6bc10238d83580415fce3fd0091d0c4
[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, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, 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   "usmul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(usmul$a$b3$)$N",
88   "smadd_widen_optab->handlers[$B].insn_code = CODE_FOR_$(madd$a$b4$)$N",
89   "umadd_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umadd$a$b4$)$N",
90   "smsub_widen_optab->handlers[$B].insn_code = CODE_FOR_$(msub$a$b4$)$N",
91   "umsub_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umsub$a$b4$)$N",
92   "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
93   "sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
94   "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
95   "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
96   "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
97   "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
98   "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
99   "fmod_optab->handlers[$A].insn_code = CODE_FOR_$(fmod$a3$)",
100   "remainder_optab->handlers[$A].insn_code = CODE_FOR_$(remainder$a3$)",
101   "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
102   "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
103   "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
104   "xor_optab->handlers[$A].insn_code = CODE_FOR_$(xor$a3$)",
105   "ashl_optab->handlers[$A].insn_code = CODE_FOR_$(ashl$a3$)",
106   "ashr_optab->handlers[$A].insn_code = CODE_FOR_$(ashr$a3$)",
107   "lshr_optab->handlers[$A].insn_code = CODE_FOR_$(lshr$a3$)",
108   "rotl_optab->handlers[$A].insn_code = CODE_FOR_$(rotl$a3$)",
109   "rotr_optab->handlers[$A].insn_code = CODE_FOR_$(rotr$a3$)",
110   "smin_optab->handlers[$A].insn_code = CODE_FOR_$(smin$a3$)",
111   "smax_optab->handlers[$A].insn_code = CODE_FOR_$(smax$a3$)",
112   "umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
113   "umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
114   "pow_optab->handlers[$A].insn_code = CODE_FOR_$(pow$a3$)",
115   "atan2_optab->handlers[$A].insn_code = CODE_FOR_$(atan2$a3$)",
116   "neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
117   "negv_optab->handlers[$A].insn_code =\n\
118     neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$F$a2$)",
119   "negv_optab->handlers[$A].insn_code = CODE_FOR_$(negv$I$a2$)",
120   "abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
121   "absv_optab->handlers[$A].insn_code =\n\
122     abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$F$a2$)",
123   "absv_optab->handlers[$A].insn_code = CODE_FOR_$(absv$I$a2$)",
124   "copysign_optab->handlers[$A].insn_code = CODE_FOR_$(copysign$F$a3$)",
125   "isinf_optab->handlers[$A].insn_code = CODE_FOR_$(isinf$a2$)",
126   "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
127   "floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
128   "lfloor_optab->handlers[$B][$A].insn_code = CODE_FOR_$(lfloor$F$a$I$b2$)",
129   "ceil_optab->handlers[$A].insn_code = CODE_FOR_$(ceil$a2$)",
130   "lceil_optab->handlers[$B][$A].insn_code = CODE_FOR_$(lceil$F$a$I$b2$)",
131   "round_optab->handlers[$A].insn_code = CODE_FOR_$(round$a2$)",
132   "btrunc_optab->handlers[$A].insn_code = CODE_FOR_$(btrunc$a2$)",
133   "nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
134   "rint_optab->handlers[$A].insn_code = CODE_FOR_$(rint$a2$)",
135   "lrint_optab->handlers[$B][$A].insn_code = CODE_FOR_$(lrint$F$a$I$b2$)",
136   "lround_optab->handlers[$B][$A].insn_code = CODE_FOR_$(lround$F$a$I$b2$)",
137   "sincos_optab->handlers[$A].insn_code = CODE_FOR_$(sincos$a3$)",
138   "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
139   "asin_optab->handlers[$A].insn_code = CODE_FOR_$(asin$a2$)",
140   "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
141   "acos_optab->handlers[$A].insn_code = CODE_FOR_$(acos$a2$)",
142   "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
143   "exp10_optab->handlers[$A].insn_code = CODE_FOR_$(exp10$a2$)",
144   "exp2_optab->handlers[$A].insn_code = CODE_FOR_$(exp2$a2$)",
145   "expm1_optab->handlers[$A].insn_code = CODE_FOR_$(expm1$a2$)",
146   "ldexp_optab->handlers[$A].insn_code = CODE_FOR_$(ldexp$a3$)",
147   "scalb_optab->handlers[$A].insn_code = CODE_FOR_$(scalb$a3$)",
148   "logb_optab->handlers[$A].insn_code = CODE_FOR_$(logb$a2$)",
149   "ilogb_optab->handlers[$A].insn_code = CODE_FOR_$(ilogb$a2$)",
150   "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
151   "log10_optab->handlers[$A].insn_code = CODE_FOR_$(log10$a2$)",  
152   "log2_optab->handlers[$A].insn_code = CODE_FOR_$(log2$a2$)",  
153   "log1p_optab->handlers[$A].insn_code = CODE_FOR_$(log1p$a2$)",  
154   "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
155   "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
156   "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
157   "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
158   "bswap_optab->handlers[$A].insn_code = CODE_FOR_$(bswap$a2$)",
159   "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
160   "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
161   "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
162   "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
163   "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
164   "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
165   "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
166   "movmisalign_optab->handlers[$A].insn_code = CODE_FOR_$(movmisalign$a$)",
167   "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
168   "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
169   "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
170   "bcc_gen_fctn[$C] = gen_$(b$c$)",
171   "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
172   "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
173   "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
174   "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
175   "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
176   "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
177   "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
178   "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
179   "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
180   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
181   "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
182   "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
183   "setmem_optab[$A] = CODE_FOR_$(setmem$a$)",
184   "sync_add_optab[$A] = CODE_FOR_$(sync_add$I$a$)",
185   "sync_sub_optab[$A] = CODE_FOR_$(sync_sub$I$a$)",
186   "sync_ior_optab[$A] = CODE_FOR_$(sync_ior$I$a$)",
187   "sync_and_optab[$A] = CODE_FOR_$(sync_and$I$a$)",
188   "sync_xor_optab[$A] = CODE_FOR_$(sync_xor$I$a$)",
189   "sync_nand_optab[$A] = CODE_FOR_$(sync_nand$I$a$)",
190   "sync_old_add_optab[$A] = CODE_FOR_$(sync_old_add$I$a$)",
191   "sync_old_sub_optab[$A] = CODE_FOR_$(sync_old_sub$I$a$)",
192   "sync_old_ior_optab[$A] = CODE_FOR_$(sync_old_ior$I$a$)",
193   "sync_old_and_optab[$A] = CODE_FOR_$(sync_old_and$I$a$)",
194   "sync_old_xor_optab[$A] = CODE_FOR_$(sync_old_xor$I$a$)",
195   "sync_old_nand_optab[$A] = CODE_FOR_$(sync_old_nand$I$a$)",
196   "sync_new_add_optab[$A] = CODE_FOR_$(sync_new_add$I$a$)",
197   "sync_new_sub_optab[$A] = CODE_FOR_$(sync_new_sub$I$a$)",
198   "sync_new_ior_optab[$A] = CODE_FOR_$(sync_new_ior$I$a$)",
199   "sync_new_and_optab[$A] = CODE_FOR_$(sync_new_and$I$a$)",
200   "sync_new_xor_optab[$A] = CODE_FOR_$(sync_new_xor$I$a$)",
201   "sync_new_nand_optab[$A] = CODE_FOR_$(sync_new_nand$I$a$)",
202   "sync_compare_and_swap[$A] = CODE_FOR_$(sync_compare_and_swap$I$a$)",
203   "sync_compare_and_swap_cc[$A] = CODE_FOR_$(sync_compare_and_swap_cc$I$a$)",
204   "sync_lock_test_and_set[$A] = CODE_FOR_$(sync_lock_test_and_set$I$a$)",
205   "sync_lock_release[$A] = CODE_FOR_$(sync_lock_release$I$a$)",
206   "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)",
207   "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)",
208   "vec_extract_even_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract_even$a$)",
209   "vec_extract_odd_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract_odd$a$)",
210   "vec_interleave_high_optab->handlers[$A].insn_code = CODE_FOR_$(vec_interleave_high$a$)",
211   "vec_interleave_low_optab->handlers[$A].insn_code = CODE_FOR_$(vec_interleave_low$a$)",
212   "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)",
213   "vec_shl_optab->handlers[$A].insn_code = CODE_FOR_$(vec_shl_$a$)",
214   "vec_shr_optab->handlers[$A].insn_code = CODE_FOR_$(vec_shr_$a$)",
215   "vec_realign_load_optab->handlers[$A].insn_code = CODE_FOR_$(vec_realign_load_$a$)",
216   "vcond_gen_code[$A] = CODE_FOR_$(vcond$a$)",
217   "vcondu_gen_code[$A] = CODE_FOR_$(vcondu$a$)",
218   "ssum_widen_optab->handlers[$A].insn_code = CODE_FOR_$(widen_ssum$I$a3$)",
219   "usum_widen_optab->handlers[$A].insn_code = CODE_FOR_$(widen_usum$I$a3$)",
220   "udot_prod_optab->handlers[$A].insn_code = CODE_FOR_$(udot_prod$I$a$)",
221   "sdot_prod_optab->handlers[$A].insn_code = CODE_FOR_$(sdot_prod$I$a$)",
222   "reduc_smax_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_smax_$a$)",
223   "reduc_umax_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_umax_$a$)",
224   "reduc_smin_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_smin_$a$)",
225   "reduc_umin_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_umin_$a$)",
226   "reduc_splus_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_splus_$a$)" ,
227   "reduc_uplus_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_uplus_$a$)",
228   "vec_widen_umult_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_umult_hi_$a$)",
229   "vec_widen_umult_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_umult_lo_$a$)",
230   "vec_widen_smult_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_smult_hi_$a$)",
231   "vec_widen_smult_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_smult_lo_$a$)",
232   "vec_unpacks_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_hi_$a$)",
233   "vec_unpacks_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_lo_$a$)",
234   "vec_unpacku_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_hi_$a$)",
235   "vec_unpacku_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_lo_$a$)",
236   "vec_unpacks_float_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_float_hi_$a$)",
237   "vec_unpacks_float_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_float_lo_$a$)",
238   "vec_unpacku_float_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_float_hi_$a$)",
239   "vec_unpacku_float_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_float_lo_$a$)",
240   "vec_pack_trunc_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_trunc_$a$)",
241   "vec_pack_ssat_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_ssat_$a$)",
242   "vec_pack_usat_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_usat_$a$)",
243   "vec_pack_sfix_trunc_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_sfix_trunc_$a$)",
244   "vec_pack_ufix_trunc_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_ufix_trunc_$a$)"
245 };
246
247 static void gen_insn (rtx);
248
249 static void
250 gen_insn (rtx insn)
251 {
252   const char *name = XSTR (insn, 0);
253   int m1 = 0, m2 = 0, op = 0;
254   size_t pindex;
255   int i;
256   const char *np, *pp, *p, *q;
257
258   /* Don't mention instructions whose names are the null string.
259      They are in the machine description just to be recognized.  */
260   if (*name == 0)
261     return;
262
263   /* See if NAME matches one of the patterns we have for the optabs we know
264      about.  */
265
266   for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
267     {
268       int force_float = 0, force_int = 0, force_partial_int = 0;
269       int force_consec = 0;
270       int matches = 1;
271
272       for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
273         ;
274
275       for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
276            pp++)
277         {
278           if (*pp != '$')
279             {
280               if (*pp != *np++)
281                 break;
282             }
283           else
284             switch (*++pp)
285               {
286               case 'N':
287                 force_consec = 1;
288                 break;
289               case 'I':
290                 force_int = 1;
291                 break;
292               case 'P':
293                 force_partial_int = 1;
294                 break;
295               case 'F':
296                 force_float = 1;
297                 break;
298               case 'V':
299                 break;
300               case 'c':
301                 for (op = 0; op < NUM_RTX_CODE; op++)
302                   {
303                     for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
304                       if (*p != *q)
305                         break;
306
307                     /* We have to be concerned about matching "gt" and
308                        missing "gtu", e.g., so verify we have reached the
309                        end of thing we are to match.  */
310                     if (*p == 0 && *q == 0
311                         && (GET_RTX_CLASS (op) == RTX_COMPARE
312                             || GET_RTX_CLASS (op) == RTX_COMM_COMPARE))
313                       break;
314                   }
315
316                 if (op == NUM_RTX_CODE)
317                   matches = 0;
318                 else
319                   np += strlen (GET_RTX_NAME(op));
320                 break;
321               case 'a':
322               case 'b':
323                 /* This loop will stop at the first prefix match, so
324                    look through the modes in reverse order, in case
325                    there are extra CC modes and CC is a prefix of the
326                    CC modes (as it should be).  */
327                 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
328                   {
329                     for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
330                       if (TOLOWER (*p) != *q)
331                         break;
332
333                     if (*p == 0
334                         && (! force_int || mode_class[i] == MODE_INT 
335                             || mode_class[i] == MODE_VECTOR_INT)
336                         && (! force_partial_int
337                             || mode_class[i] == MODE_INT
338                             || mode_class[i] == MODE_PARTIAL_INT
339                             || mode_class[i] == MODE_VECTOR_INT)
340                         && (! force_float
341                             || mode_class[i] == MODE_FLOAT 
342                             || mode_class[i] == MODE_DECIMAL_FLOAT
343                             || mode_class[i] == MODE_COMPLEX_FLOAT
344                             || mode_class[i] == MODE_VECTOR_FLOAT))
345                       break;
346                   }
347
348                 if (i < 0)
349                   matches = 0;
350                 else if (*pp == 'a')
351                   m1 = i, np += strlen (GET_MODE_NAME(i));
352                 else
353                   m2 = i, np += strlen (GET_MODE_NAME(i));
354
355                 force_int = force_partial_int = force_float = 0;
356                 break;
357
358               default:
359                 gcc_unreachable ();
360               }
361         }
362
363       if (matches && pp[0] == '$' && pp[1] == ')'
364           && *np == 0
365           && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
366         break;
367     }
368
369   if (pindex == ARRAY_SIZE (optabs))
370     return;
371
372   /* We found a match.  If this pattern is only conditionally present,
373      write out the "if" and two extra blanks.  */
374
375   if (*XSTR (insn, 2) != 0)
376     printf ("  if (HAVE_%s)\n  ", name);
377
378   printf ("  ");
379
380   /* Now write out the initialization, making all required substitutions.  */
381   for (pp = optabs[pindex]; *pp; pp++)
382     {
383       if (*pp != '$')
384         putchar (*pp);
385       else
386         switch (*++pp)
387           {
388           case '(':  case ')':
389           case 'I':  case 'F':  case 'N':
390             break;
391           case 'V':
392             if (SCALAR_FLOAT_MODE_P (m1))
393               printf ("v");
394             break;
395           case 'a':
396             for (np = GET_MODE_NAME(m1); *np; np++)
397               putchar (TOLOWER (*np));
398             break;
399           case 'b':
400             for (np = GET_MODE_NAME(m2); *np; np++)
401               putchar (TOLOWER (*np));
402             break;
403           case 'A':
404             printf ("%smode", GET_MODE_NAME(m1));
405             break;
406           case 'B':
407             printf ("%smode", GET_MODE_NAME(m2));
408             break;
409           case 'c':
410             printf ("%s", GET_RTX_NAME(op));
411             break;
412           case 'C':
413             for (np = GET_RTX_NAME(op); *np; np++)
414               putchar (TOUPPER (*np));
415             break;
416           }
417     }
418
419   printf (";\n");
420 }
421
422 extern int main (int, char **);
423
424 int
425 main (int argc, char **argv)
426 {
427   rtx desc;
428
429   progname = "genopinit";
430
431   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
432     return (FATAL_EXIT_CODE);
433
434   printf ("/* Generated automatically by the program `genopinit'\n\
435 from the machine description file `md'.  */\n\n");
436
437   printf ("#include \"config.h\"\n");
438   printf ("#include \"system.h\"\n");
439   printf ("#include \"coretypes.h\"\n");
440   printf ("#include \"tm.h\"\n");
441   printf ("#include \"rtl.h\"\n");
442   printf ("#include \"flags.h\"\n");
443   printf ("#include \"insn-config.h\"\n");
444   printf ("#include \"recog.h\"\n");
445   printf ("#include \"expr.h\"\n");
446   printf ("#include \"optabs.h\"\n");
447   printf ("#include \"reload.h\"\n\n");
448
449   printf ("void\ninit_all_optabs (void)\n{\n");
450
451   puts ("\
452 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
453   int i, j;\n\
454 #endif\n");
455
456   /* Read the machine description.  */
457
458   while (1)
459     {
460       int line_no, insn_code_number = 0;
461
462       desc = read_md_rtx (&line_no, &insn_code_number);
463       if (desc == NULL)
464         break;
465
466       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
467         gen_insn (desc);
468     }
469
470   puts ("\
471 \n\
472 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
473   /* This flag says the same insns that convert to a signed fixnum\n\
474      also convert validly to an unsigned one.  */\n\
475   for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
476     for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
477       ufixtrunc_optab->handlers[i][j].insn_code\n\
478       = sfixtrunc_optab->handlers[i][j].insn_code;\n\
479 #endif\n\
480 }");
481
482   fflush (stdout);
483   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
484 }