OSDN Git Service

2007-07-09 Wolfgang Gellerich <gellerich@de.ibm.com>
[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   "storent_optab->handlers[$A].insn_code = CODE_FOR_$(storent$a$)",
168   "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
169   "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
170   "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
171   "bcc_gen_fctn[$C] = gen_$(b$c$)",
172   "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
173   "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
174   "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
175   "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
176   "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
177   "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
178   "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
179   "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
180   "signbit_optab[$A] = CODE_FOR_$(signbit$F$a2$)",
181   "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
182   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
183   "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
184   "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
185   "setmem_optab[$A] = CODE_FOR_$(setmem$a$)",
186   "sync_add_optab[$A] = CODE_FOR_$(sync_add$I$a$)",
187   "sync_sub_optab[$A] = CODE_FOR_$(sync_sub$I$a$)",
188   "sync_ior_optab[$A] = CODE_FOR_$(sync_ior$I$a$)",
189   "sync_and_optab[$A] = CODE_FOR_$(sync_and$I$a$)",
190   "sync_xor_optab[$A] = CODE_FOR_$(sync_xor$I$a$)",
191   "sync_nand_optab[$A] = CODE_FOR_$(sync_nand$I$a$)",
192   "sync_old_add_optab[$A] = CODE_FOR_$(sync_old_add$I$a$)",
193   "sync_old_sub_optab[$A] = CODE_FOR_$(sync_old_sub$I$a$)",
194   "sync_old_ior_optab[$A] = CODE_FOR_$(sync_old_ior$I$a$)",
195   "sync_old_and_optab[$A] = CODE_FOR_$(sync_old_and$I$a$)",
196   "sync_old_xor_optab[$A] = CODE_FOR_$(sync_old_xor$I$a$)",
197   "sync_old_nand_optab[$A] = CODE_FOR_$(sync_old_nand$I$a$)",
198   "sync_new_add_optab[$A] = CODE_FOR_$(sync_new_add$I$a$)",
199   "sync_new_sub_optab[$A] = CODE_FOR_$(sync_new_sub$I$a$)",
200   "sync_new_ior_optab[$A] = CODE_FOR_$(sync_new_ior$I$a$)",
201   "sync_new_and_optab[$A] = CODE_FOR_$(sync_new_and$I$a$)",
202   "sync_new_xor_optab[$A] = CODE_FOR_$(sync_new_xor$I$a$)",
203   "sync_new_nand_optab[$A] = CODE_FOR_$(sync_new_nand$I$a$)",
204   "sync_compare_and_swap[$A] = CODE_FOR_$(sync_compare_and_swap$I$a$)",
205   "sync_compare_and_swap_cc[$A] = CODE_FOR_$(sync_compare_and_swap_cc$I$a$)",
206   "sync_lock_test_and_set[$A] = CODE_FOR_$(sync_lock_test_and_set$I$a$)",
207   "sync_lock_release[$A] = CODE_FOR_$(sync_lock_release$I$a$)",
208   "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)",
209   "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)",
210   "vec_extract_even_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract_even$a$)",
211   "vec_extract_odd_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract_odd$a$)",
212   "vec_interleave_high_optab->handlers[$A].insn_code = CODE_FOR_$(vec_interleave_high$a$)",
213   "vec_interleave_low_optab->handlers[$A].insn_code = CODE_FOR_$(vec_interleave_low$a$)",
214   "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)",
215   "vec_shl_optab->handlers[$A].insn_code = CODE_FOR_$(vec_shl_$a$)",
216   "vec_shr_optab->handlers[$A].insn_code = CODE_FOR_$(vec_shr_$a$)",
217   "vec_realign_load_optab->handlers[$A].insn_code = CODE_FOR_$(vec_realign_load_$a$)",
218   "vcond_gen_code[$A] = CODE_FOR_$(vcond$a$)",
219   "vcondu_gen_code[$A] = CODE_FOR_$(vcondu$a$)",
220   "ssum_widen_optab->handlers[$A].insn_code = CODE_FOR_$(widen_ssum$I$a3$)",
221   "usum_widen_optab->handlers[$A].insn_code = CODE_FOR_$(widen_usum$I$a3$)",
222   "udot_prod_optab->handlers[$A].insn_code = CODE_FOR_$(udot_prod$I$a$)",
223   "sdot_prod_optab->handlers[$A].insn_code = CODE_FOR_$(sdot_prod$I$a$)",
224   "reduc_smax_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_smax_$a$)",
225   "reduc_umax_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_umax_$a$)",
226   "reduc_smin_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_smin_$a$)",
227   "reduc_umin_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_umin_$a$)",
228   "reduc_splus_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_splus_$a$)" ,
229   "reduc_uplus_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_uplus_$a$)",
230   "vec_widen_umult_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_umult_hi_$a$)",
231   "vec_widen_umult_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_umult_lo_$a$)",
232   "vec_widen_smult_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_smult_hi_$a$)",
233   "vec_widen_smult_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_widen_smult_lo_$a$)",
234   "vec_unpacks_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_hi_$a$)",
235   "vec_unpacks_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_lo_$a$)",
236   "vec_unpacku_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_hi_$a$)",
237   "vec_unpacku_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_lo_$a$)",
238   "vec_unpacks_float_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_float_hi_$a$)",
239   "vec_unpacks_float_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacks_float_lo_$a$)",
240   "vec_unpacku_float_hi_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_float_hi_$a$)",
241   "vec_unpacku_float_lo_optab->handlers[$A].insn_code = CODE_FOR_$(vec_unpacku_float_lo_$a$)",
242   "vec_pack_trunc_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_trunc_$a$)",
243   "vec_pack_ssat_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_ssat_$a$)",
244   "vec_pack_usat_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_usat_$a$)",
245   "vec_pack_sfix_trunc_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_sfix_trunc_$a$)",
246   "vec_pack_ufix_trunc_optab->handlers[$A].insn_code = CODE_FOR_$(vec_pack_ufix_trunc_$a$)"
247 };
248
249 static void gen_insn (rtx);
250
251 static void
252 gen_insn (rtx insn)
253 {
254   const char *name = XSTR (insn, 0);
255   int m1 = 0, m2 = 0, op = 0;
256   size_t pindex;
257   int i;
258   const char *np, *pp, *p, *q;
259
260   /* Don't mention instructions whose names are the null string.
261      They are in the machine description just to be recognized.  */
262   if (*name == 0)
263     return;
264
265   /* See if NAME matches one of the patterns we have for the optabs we know
266      about.  */
267
268   for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
269     {
270       int force_float = 0, force_int = 0, force_partial_int = 0;
271       int force_consec = 0;
272       int matches = 1;
273
274       for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
275         ;
276
277       for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
278            pp++)
279         {
280           if (*pp != '$')
281             {
282               if (*pp != *np++)
283                 break;
284             }
285           else
286             switch (*++pp)
287               {
288               case 'N':
289                 force_consec = 1;
290                 break;
291               case 'I':
292                 force_int = 1;
293                 break;
294               case 'P':
295                 force_partial_int = 1;
296                 break;
297               case 'F':
298                 force_float = 1;
299                 break;
300               case 'V':
301                 break;
302               case 'c':
303                 for (op = 0; op < NUM_RTX_CODE; op++)
304                   {
305                     for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
306                       if (*p != *q)
307                         break;
308
309                     /* We have to be concerned about matching "gt" and
310                        missing "gtu", e.g., so verify we have reached the
311                        end of thing we are to match.  */
312                     if (*p == 0 && *q == 0
313                         && (GET_RTX_CLASS (op) == RTX_COMPARE
314                             || GET_RTX_CLASS (op) == RTX_COMM_COMPARE))
315                       break;
316                   }
317
318                 if (op == NUM_RTX_CODE)
319                   matches = 0;
320                 else
321                   np += strlen (GET_RTX_NAME(op));
322                 break;
323               case 'a':
324               case 'b':
325                 /* This loop will stop at the first prefix match, so
326                    look through the modes in reverse order, in case
327                    there are extra CC modes and CC is a prefix of the
328                    CC modes (as it should be).  */
329                 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
330                   {
331                     for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
332                       if (TOLOWER (*p) != *q)
333                         break;
334
335                     if (*p == 0
336                         && (! force_int || mode_class[i] == MODE_INT 
337                             || mode_class[i] == MODE_VECTOR_INT)
338                         && (! force_partial_int
339                             || mode_class[i] == MODE_INT
340                             || mode_class[i] == MODE_PARTIAL_INT
341                             || mode_class[i] == MODE_VECTOR_INT)
342                         && (! force_float
343                             || mode_class[i] == MODE_FLOAT 
344                             || mode_class[i] == MODE_DECIMAL_FLOAT
345                             || mode_class[i] == MODE_COMPLEX_FLOAT
346                             || mode_class[i] == MODE_VECTOR_FLOAT))
347                       break;
348                   }
349
350                 if (i < 0)
351                   matches = 0;
352                 else if (*pp == 'a')
353                   m1 = i, np += strlen (GET_MODE_NAME(i));
354                 else
355                   m2 = i, np += strlen (GET_MODE_NAME(i));
356
357                 force_int = force_partial_int = force_float = 0;
358                 break;
359
360               default:
361                 gcc_unreachable ();
362               }
363         }
364
365       if (matches && pp[0] == '$' && pp[1] == ')'
366           && *np == 0
367           && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
368         break;
369     }
370
371   if (pindex == ARRAY_SIZE (optabs))
372     return;
373
374   /* We found a match.  If this pattern is only conditionally present,
375      write out the "if" and two extra blanks.  */
376
377   if (*XSTR (insn, 2) != 0)
378     printf ("  if (HAVE_%s)\n  ", name);
379
380   printf ("  ");
381
382   /* Now write out the initialization, making all required substitutions.  */
383   for (pp = optabs[pindex]; *pp; pp++)
384     {
385       if (*pp != '$')
386         putchar (*pp);
387       else
388         switch (*++pp)
389           {
390           case '(':  case ')':
391           case 'I':  case 'F':  case 'N':
392             break;
393           case 'V':
394             if (SCALAR_FLOAT_MODE_P (m1))
395               printf ("v");
396             break;
397           case 'a':
398             for (np = GET_MODE_NAME(m1); *np; np++)
399               putchar (TOLOWER (*np));
400             break;
401           case 'b':
402             for (np = GET_MODE_NAME(m2); *np; np++)
403               putchar (TOLOWER (*np));
404             break;
405           case 'A':
406             printf ("%smode", GET_MODE_NAME(m1));
407             break;
408           case 'B':
409             printf ("%smode", GET_MODE_NAME(m2));
410             break;
411           case 'c':
412             printf ("%s", GET_RTX_NAME(op));
413             break;
414           case 'C':
415             for (np = GET_RTX_NAME(op); *np; np++)
416               putchar (TOUPPER (*np));
417             break;
418           }
419     }
420
421   printf (";\n");
422 }
423
424 extern int main (int, char **);
425
426 int
427 main (int argc, char **argv)
428 {
429   rtx desc;
430
431   progname = "genopinit";
432
433   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
434     return (FATAL_EXIT_CODE);
435
436   printf ("/* Generated automatically by the program `genopinit'\n\
437 from the machine description file `md'.  */\n\n");
438
439   printf ("#include \"config.h\"\n");
440   printf ("#include \"system.h\"\n");
441   printf ("#include \"coretypes.h\"\n");
442   printf ("#include \"tm.h\"\n");
443   printf ("#include \"rtl.h\"\n");
444   printf ("#include \"flags.h\"\n");
445   printf ("#include \"insn-config.h\"\n");
446   printf ("#include \"recog.h\"\n");
447   printf ("#include \"expr.h\"\n");
448   printf ("#include \"optabs.h\"\n");
449   printf ("#include \"reload.h\"\n\n");
450
451   printf ("void\ninit_all_optabs (void)\n{\n");
452
453   puts ("\
454 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
455   int i, j;\n\
456 #endif\n");
457
458   /* Read the machine description.  */
459
460   while (1)
461     {
462       int line_no, insn_code_number = 0;
463
464       desc = read_md_rtx (&line_no, &insn_code_number);
465       if (desc == NULL)
466         break;
467
468       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
469         gen_insn (desc);
470     }
471
472   puts ("\
473 \n\
474 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
475   /* This flag says the same insns that convert to a signed fixnum\n\
476      also convert validly to an unsigned one.  */\n\
477   for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
478     for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
479       ufixtrunc_optab->handlers[i][j].insn_code\n\
480       = sfixtrunc_optab->handlers[i][j].insn_code;\n\
481 #endif\n\
482 }");
483
484   fflush (stdout);
485   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
486 }