118334Speter/* Generate code to initialize optabs from machine description.
2132718Skan   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3169689Skan   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2118334Speter
2218334Speter
23132718Skan#include "bconfig.h"
2450397Sobrien#include "system.h"
25132718Skan#include "coretypes.h"
26132718Skan#include "tm.h"
2718334Speter#include "rtl.h"
2890075Sobrien#include "errors.h"
2990075Sobrien#include "gensupport.h"
3018334Speter
3118334Speter
3218334Speter/* Many parts of GCC use arrays that are indexed by machine mode and
3318334Speter   contain the insn codes for pattern in the MD file that perform a given
3418334Speter   operation on operands of that mode.
3518334Speter
3618334Speter   These patterns are present in the MD file with names that contain
3718334Speter   the mode(s) used and the name of the operation.  This program
3818334Speter   writes a function `init_all_optabs' that initializes the optabs with
3918334Speter   all the insn codes of the relevant patterns present in the MD file.
4018334Speter
4118334Speter   This array contains a list of optabs that need to be initialized.  Within
4218334Speter   each string, the name of the pattern to be matched against is delimited
4390075Sobrien   with $( and $).  In the string, $a and $b are used to match a short mode
4418334Speter   name (the part of the mode name not including `mode' and converted to
4518334Speter   lower-case).  When writing out the initializer, the entire string is
4690075Sobrien   used.  $A and $B are replaced with the full name of the mode; $a and $b
4718334Speter   are replaced with the short form of the name, as above.
4818334Speter
4990075Sobrien   If $N is present in the pattern, it means the two modes must be consecutive
5090075Sobrien   widths in the same mode class (e.g, QImode and HImode).  $I means that
5190075Sobrien   only full integer modes should be considered for the next mode, and $F
5290075Sobrien   means that only float modes should be considered.
5390075Sobrien   $P means that both full and partial integer modes should be considered.
5418334Speter
5590075Sobrien   $V means to emit 'v' if the first mode is a MODE_FLOAT mode.
5690075Sobrien
5718334Speter   For some optabs, we store the operation by RTL codes.  These are only
5890075Sobrien   used for comparisons.  In that case, $c and $C are the lower-case and
5918334Speter   upper-case forms of the comparison, respectively.  */
6018334Speter
6190075Sobrienstatic const char * const optabs[] =
62132718Skan{ "sext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(extend$a$b2$)",
63132718Skan  "zext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(zero_extend$a$b2$)",
64132718Skan  "sfix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix$F$a$I$b2$)",
65132718Skan  "ufix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns$F$a$b2$)",
66132718Skan  "sfixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
67132718Skan  "ufixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
68132718Skan  "sfloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(float$I$a$F$b2$)",
69132718Skan  "ufloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(floatuns$I$a$F$b2$)",
70132718Skan  "trunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(trunc$a$b2$)",
7190075Sobrien  "add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
72132718Skan  "addv_optab->handlers[$A].insn_code =\n\
73132718Skan    add_optab->handlers[$A].insn_code = CODE_FOR_$(add$F$a3$)",
74132718Skan  "addv_optab->handlers[$A].insn_code = CODE_FOR_$(addv$I$a3$)",
7590075Sobrien  "sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
76132718Skan  "subv_optab->handlers[$A].insn_code =\n\
77132718Skan    sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$F$a3$)",
78132718Skan  "subv_optab->handlers[$A].insn_code = CODE_FOR_$(subv$I$a3$)",
7990075Sobrien  "smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
80132718Skan  "smulv_optab->handlers[$A].insn_code =\n\
81132718Skan    smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$F$a3$)",
82132718Skan  "smulv_optab->handlers[$A].insn_code = CODE_FOR_$(mulv$I$a3$)",
8390075Sobrien  "umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
8490075Sobrien  "smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
8590075Sobrien  "smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
8690075Sobrien  "umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
87169689Skan  "usmul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(usmul$a$b3$)$N",
8890075Sobrien  "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
89132718Skan  "sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
9090075Sobrien  "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
9190075Sobrien  "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
9290075Sobrien  "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
9390075Sobrien  "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
9490075Sobrien  "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
95169689Skan  "fmod_optab->handlers[$A].insn_code = CODE_FOR_$(fmod$a3$)",
96169689Skan  "drem_optab->handlers[$A].insn_code = CODE_FOR_$(drem$a3$)",
9790075Sobrien  "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
9890075Sobrien  "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
9990075Sobrien  "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
10090075Sobrien  "xor_optab->handlers[$A].insn_code = CODE_FOR_$(xor$a3$)",
10190075Sobrien  "ashl_optab->handlers[$A].insn_code = CODE_FOR_$(ashl$a3$)",
10290075Sobrien  "ashr_optab->handlers[$A].insn_code = CODE_FOR_$(ashr$a3$)",
10390075Sobrien  "lshr_optab->handlers[$A].insn_code = CODE_FOR_$(lshr$a3$)",
10490075Sobrien  "rotl_optab->handlers[$A].insn_code = CODE_FOR_$(rotl$a3$)",
10590075Sobrien  "rotr_optab->handlers[$A].insn_code = CODE_FOR_$(rotr$a3$)",
106169689Skan  "smin_optab->handlers[$A].insn_code = CODE_FOR_$(smin$a3$)",
107169689Skan  "smax_optab->handlers[$A].insn_code = CODE_FOR_$(smax$a3$)",
10890075Sobrien  "umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
10990075Sobrien  "umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
110132718Skan  "pow_optab->handlers[$A].insn_code = CODE_FOR_$(pow$a3$)",
111132718Skan  "atan2_optab->handlers[$A].insn_code = CODE_FOR_$(atan2$a3$)",
11290075Sobrien  "neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
113132718Skan  "negv_optab->handlers[$A].insn_code =\n\
114132718Skan    neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$F$a2$)",
115132718Skan  "negv_optab->handlers[$A].insn_code = CODE_FOR_$(negv$I$a2$)",
11690075Sobrien  "abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
117132718Skan  "absv_optab->handlers[$A].insn_code =\n\
118132718Skan    abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$F$a2$)",
119132718Skan  "absv_optab->handlers[$A].insn_code = CODE_FOR_$(absv$I$a2$)",
120169689Skan  "copysign_optab->handlers[$A].insn_code = CODE_FOR_$(copysign$F$a3$)",
12190075Sobrien  "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
122132718Skan  "floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
123169689Skan  "lfloor_optab->handlers[$A].insn_code = CODE_FOR_$(lfloor$a2$)",
124132718Skan  "ceil_optab->handlers[$A].insn_code = CODE_FOR_$(ceil$a2$)",
125169689Skan  "lceil_optab->handlers[$A].insn_code = CODE_FOR_$(lceil$a2$)",
126132718Skan  "round_optab->handlers[$A].insn_code = CODE_FOR_$(round$a2$)",
127169689Skan  "btrunc_optab->handlers[$A].insn_code = CODE_FOR_$(btrunc$a2$)",
128132718Skan  "nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
129169689Skan  "rint_optab->handlers[$A].insn_code = CODE_FOR_$(rint$a2$)",
130169689Skan  "lrint_optab->handlers[$A].insn_code = CODE_FOR_$(lrint$a2$)",
131169689Skan  "sincos_optab->handlers[$A].insn_code = CODE_FOR_$(sincos$a3$)",
13290075Sobrien  "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
133169689Skan  "asin_optab->handlers[$A].insn_code = CODE_FOR_$(asin$a2$)",
13490075Sobrien  "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
135169689Skan  "acos_optab->handlers[$A].insn_code = CODE_FOR_$(acos$a2$)",
136117395Skan  "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
137169689Skan  "exp10_optab->handlers[$A].insn_code = CODE_FOR_$(exp10$a2$)",
138169689Skan  "exp2_optab->handlers[$A].insn_code = CODE_FOR_$(exp2$a2$)",
139169689Skan  "expm1_optab->handlers[$A].insn_code = CODE_FOR_$(expm1$a2$)",
140169689Skan  "ldexp_optab->handlers[$A].insn_code = CODE_FOR_$(ldexp$a3$)",
141169689Skan  "logb_optab->handlers[$A].insn_code = CODE_FOR_$(logb$a2$)",
142169689Skan  "ilogb_optab->handlers[$A].insn_code = CODE_FOR_$(ilogb$a2$)",
143117395Skan  "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
144169689Skan  "log10_optab->handlers[$A].insn_code = CODE_FOR_$(log10$a2$)",
145169689Skan  "log2_optab->handlers[$A].insn_code = CODE_FOR_$(log2$a2$)",
146169689Skan  "log1p_optab->handlers[$A].insn_code = CODE_FOR_$(log1p$a2$)",
147132718Skan  "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
148132718Skan  "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
14990075Sobrien  "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
15090075Sobrien  "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
151259563Spfg  "bswap_optab->handlers[$A].insn_code = CODE_FOR_$(bswap$a2$)",
15290075Sobrien  "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
153132718Skan  "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
154132718Skan  "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
155132718Skan  "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
156132718Skan  "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
15790075Sobrien  "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
15890075Sobrien  "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
159169689Skan  "movmisalign_optab->handlers[$A].insn_code = CODE_FOR_$(movmisalign$a$)",
16090075Sobrien  "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
16190075Sobrien  "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
162132718Skan  "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
16390075Sobrien  "bcc_gen_fctn[$C] = gen_$(b$c$)",
16490075Sobrien  "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
16590075Sobrien  "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
16690075Sobrien  "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
16790075Sobrien  "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
16890075Sobrien  "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
16990075Sobrien  "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
17090075Sobrien  "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
17190075Sobrien  "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
172169689Skan  "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
173132718Skan  "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
174169689Skan  "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
175132718Skan  "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
176169689Skan  "setmem_optab[$A] = CODE_FOR_$(setmem$a$)",
177169689Skan  "sync_add_optab[$A] = CODE_FOR_$(sync_add$I$a$)",
178169689Skan  "sync_sub_optab[$A] = CODE_FOR_$(sync_sub$I$a$)",
179169689Skan  "sync_ior_optab[$A] = CODE_FOR_$(sync_ior$I$a$)",
180169689Skan  "sync_and_optab[$A] = CODE_FOR_$(sync_and$I$a$)",
181169689Skan  "sync_xor_optab[$A] = CODE_FOR_$(sync_xor$I$a$)",
182169689Skan  "sync_nand_optab[$A] = CODE_FOR_$(sync_nand$I$a$)",
183169689Skan  "sync_old_add_optab[$A] = CODE_FOR_$(sync_old_add$I$a$)",
184169689Skan  "sync_old_sub_optab[$A] = CODE_FOR_$(sync_old_sub$I$a$)",
185169689Skan  "sync_old_ior_optab[$A] = CODE_FOR_$(sync_old_ior$I$a$)",
186169689Skan  "sync_old_and_optab[$A] = CODE_FOR_$(sync_old_and$I$a$)",
187169689Skan  "sync_old_xor_optab[$A] = CODE_FOR_$(sync_old_xor$I$a$)",
188169689Skan  "sync_old_nand_optab[$A] = CODE_FOR_$(sync_old_nand$I$a$)",
189169689Skan  "sync_new_add_optab[$A] = CODE_FOR_$(sync_new_add$I$a$)",
190169689Skan  "sync_new_sub_optab[$A] = CODE_FOR_$(sync_new_sub$I$a$)",
191169689Skan  "sync_new_ior_optab[$A] = CODE_FOR_$(sync_new_ior$I$a$)",
192169689Skan  "sync_new_and_optab[$A] = CODE_FOR_$(sync_new_and$I$a$)",
193169689Skan  "sync_new_xor_optab[$A] = CODE_FOR_$(sync_new_xor$I$a$)",
194169689Skan  "sync_new_nand_optab[$A] = CODE_FOR_$(sync_new_nand$I$a$)",
195169689Skan  "sync_compare_and_swap[$A] = CODE_FOR_$(sync_compare_and_swap$I$a$)",
196169689Skan  "sync_compare_and_swap_cc[$A] = CODE_FOR_$(sync_compare_and_swap_cc$I$a$)",
197169689Skan  "sync_lock_test_and_set[$A] = CODE_FOR_$(sync_lock_test_and_set$I$a$)",
198169689Skan  "sync_lock_release[$A] = CODE_FOR_$(sync_lock_release$I$a$)",
199132718Skan  "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)",
200132718Skan  "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)",
201169689Skan  "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)",
202169689Skan  "vec_shl_optab->handlers[$A].insn_code = CODE_FOR_$(vec_shl_$a$)",
203169689Skan  "vec_shr_optab->handlers[$A].insn_code = CODE_FOR_$(vec_shr_$a$)",
204169689Skan  "vec_realign_load_optab->handlers[$A].insn_code = CODE_FOR_$(vec_realign_load_$a$)",
205169689Skan  "vcond_gen_code[$A] = CODE_FOR_$(vcond$a$)",
206169689Skan  "vcondu_gen_code[$A] = CODE_FOR_$(vcondu$a$)",
207169689Skan  "ssum_widen_optab->handlers[$A].insn_code = CODE_FOR_$(widen_ssum$I$a3$)",
208169689Skan  "usum_widen_optab->handlers[$A].insn_code = CODE_FOR_$(widen_usum$I$a3$)",
209169689Skan  "udot_prod_optab->handlers[$A].insn_code = CODE_FOR_$(udot_prod$I$a$)",
210169689Skan  "sdot_prod_optab->handlers[$A].insn_code = CODE_FOR_$(sdot_prod$I$a$)",
211169689Skan  "reduc_smax_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_smax_$a$)",
212169689Skan  "reduc_umax_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_umax_$a$)",
213169689Skan  "reduc_smin_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_smin_$a$)",
214169689Skan  "reduc_umin_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_umin_$a$)",
215169689Skan  "reduc_splus_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_splus_$a$)" ,
216169689Skan  "reduc_uplus_optab->handlers[$A].insn_code = CODE_FOR_$(reduc_uplus_$a$)"
217169689Skan};
21818334Speter
219132718Skanstatic void gen_insn (rtx);
22018334Speter
22118334Speterstatic void
222132718Skangen_insn (rtx insn)
22318334Speter{
22490075Sobrien  const char *name = XSTR (insn, 0);
22590075Sobrien  int m1 = 0, m2 = 0, op = 0;
22650397Sobrien  size_t pindex;
22718334Speter  int i;
22852284Sobrien  const char *np, *pp, *p, *q;
22918334Speter
23018334Speter  /* Don't mention instructions whose names are the null string.
23118334Speter     They are in the machine description just to be recognized.  */
23218334Speter  if (*name == 0)
23318334Speter    return;
23418334Speter
23518334Speter  /* See if NAME matches one of the patterns we have for the optabs we know
23618334Speter     about.  */
23718334Speter
23890075Sobrien  for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
23918334Speter    {
24090075Sobrien      int force_float = 0, force_int = 0, force_partial_int = 0;
24118334Speter      int force_consec = 0;
24218334Speter      int matches = 1;
24318334Speter
24490075Sobrien      for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
24518334Speter	;
24618334Speter
24790075Sobrien      for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
24818334Speter	   pp++)
24918334Speter	{
25090075Sobrien	  if (*pp != '$')
25118334Speter	    {
25218334Speter	      if (*pp != *np++)
25318334Speter		break;
25418334Speter	    }
25518334Speter	  else
25618334Speter	    switch (*++pp)
25718334Speter	      {
25818334Speter	      case 'N':
25918334Speter		force_consec = 1;
26018334Speter		break;
26118334Speter	      case 'I':
26218334Speter		force_int = 1;
26318334Speter		break;
26490075Sobrien	      case 'P':
26590075Sobrien                force_partial_int = 1;
26690075Sobrien                break;
26718334Speter	      case 'F':
26818334Speter		force_float = 1;
26918334Speter		break;
27090075Sobrien	      case 'V':
27190075Sobrien                break;
27218334Speter	      case 'c':
27318334Speter		for (op = 0; op < NUM_RTX_CODE; op++)
27418334Speter		  {
27590075Sobrien		    for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
27618334Speter		      if (*p != *q)
27718334Speter			break;
27818334Speter
27918334Speter		    /* We have to be concerned about matching "gt" and
28018334Speter		       missing "gtu", e.g., so verify we have reached the
28150397Sobrien		       end of thing we are to match.  */
282169689Skan		    if (*p == 0 && *q == 0
283169689Skan			&& (GET_RTX_CLASS (op) == RTX_COMPARE
284169689Skan			    || GET_RTX_CLASS (op) == RTX_COMM_COMPARE))
28518334Speter		      break;
28618334Speter		  }
28718334Speter
28818334Speter		if (op == NUM_RTX_CODE)
28918334Speter		  matches = 0;
29018334Speter		else
29190075Sobrien		  np += strlen (GET_RTX_NAME(op));
29218334Speter		break;
29318334Speter	      case 'a':
29418334Speter	      case 'b':
29550397Sobrien		/* This loop will stop at the first prefix match, so
29650397Sobrien                   look through the modes in reverse order, in case
297132718Skan                   there are extra CC modes and CC is a prefix of the
29850397Sobrien                   CC modes (as it should be).  */
299132718Skan		for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
30018334Speter		  {
30190075Sobrien		    for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
30290075Sobrien		      if (TOLOWER (*p) != *q)
30318334Speter			break;
30418334Speter
30518334Speter		    if (*p == 0
30690075Sobrien			&& (! force_int || mode_class[i] == MODE_INT
30790075Sobrien			    || mode_class[i] == MODE_VECTOR_INT)
30890075Sobrien		        && (! force_partial_int
30990075Sobrien                            || mode_class[i] == MODE_INT
31090075Sobrien                            || mode_class[i] == MODE_PARTIAL_INT
31190075Sobrien			    || mode_class[i] == MODE_VECTOR_INT)
312169689Skan			&& (! force_float
313169689Skan			    || mode_class[i] == MODE_FLOAT
314169689Skan			    || mode_class[i] == MODE_DECIMAL_FLOAT
315169689Skan			    || mode_class[i] == MODE_COMPLEX_FLOAT
31690075Sobrien			    || mode_class[i] == MODE_VECTOR_FLOAT))
31718334Speter		      break;
31818334Speter		  }
31918334Speter
32050397Sobrien		if (i < 0)
32118334Speter		  matches = 0;
32218334Speter		else if (*pp == 'a')
32390075Sobrien		  m1 = i, np += strlen (GET_MODE_NAME(i));
32418334Speter		else
32590075Sobrien		  m2 = i, np += strlen (GET_MODE_NAME(i));
32618334Speter
32790075Sobrien		force_int = force_partial_int = force_float = 0;
32818334Speter		break;
32918334Speter
33018334Speter	      default:
331169689Skan		gcc_unreachable ();
33218334Speter	      }
33318334Speter	}
33418334Speter
33590075Sobrien      if (matches && pp[0] == '$' && pp[1] == ')'
33618334Speter	  && *np == 0
33718334Speter	  && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
33818334Speter	break;
33918334Speter    }
34018334Speter
34190075Sobrien  if (pindex == ARRAY_SIZE (optabs))
34218334Speter    return;
34318334Speter
34418334Speter  /* We found a match.  If this pattern is only conditionally present,
34518334Speter     write out the "if" and two extra blanks.  */
34618334Speter
34718334Speter  if (*XSTR (insn, 2) != 0)
34818334Speter    printf ("  if (HAVE_%s)\n  ", name);
34918334Speter
35018334Speter  printf ("  ");
35118334Speter
35218334Speter  /* Now write out the initialization, making all required substitutions.  */
35318334Speter  for (pp = optabs[pindex]; *pp; pp++)
35418334Speter    {
35590075Sobrien      if (*pp != '$')
35690075Sobrien	putchar (*pp);
35718334Speter      else
35818334Speter	switch (*++pp)
35918334Speter	  {
36018334Speter	  case '(':  case ')':
36118334Speter	  case 'I':  case 'F':  case 'N':
36218334Speter	    break;
36390075Sobrien	  case 'V':
364169689Skan	    if (SCALAR_FLOAT_MODE_P (m1))
36590075Sobrien              printf ("v");
36690075Sobrien            break;
36718334Speter	  case 'a':
36890075Sobrien	    for (np = GET_MODE_NAME(m1); *np; np++)
36990075Sobrien	      putchar (TOLOWER (*np));
37018334Speter	    break;
37118334Speter	  case 'b':
37290075Sobrien	    for (np = GET_MODE_NAME(m2); *np; np++)
37390075Sobrien	      putchar (TOLOWER (*np));
37418334Speter	    break;
37518334Speter	  case 'A':
376132718Skan	    printf ("%smode", GET_MODE_NAME(m1));
37718334Speter	    break;
37818334Speter	  case 'B':
379132718Skan	    printf ("%smode", GET_MODE_NAME(m2));
38018334Speter	    break;
38118334Speter	  case 'c':
38290075Sobrien	    printf ("%s", GET_RTX_NAME(op));
38318334Speter	    break;
38418334Speter	  case 'C':
38590075Sobrien	    for (np = GET_RTX_NAME(op); *np; np++)
38690075Sobrien	      putchar (TOUPPER (*np));
38718334Speter	    break;
38818334Speter	  }
38918334Speter    }
39018334Speter
39118334Speter  printf (";\n");
39218334Speter}
39318334Speter
394132718Skanextern int main (int, char **);
39518334Speter
39618334Speterint
397132718Skanmain (int argc, char **argv)
39818334Speter{
39918334Speter  rtx desc;
40018334Speter
40190075Sobrien  progname = "genopinit";
40218334Speter
40390075Sobrien  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
40490075Sobrien    return (FATAL_EXIT_CODE);
40518334Speter
40618334Speter  printf ("/* Generated automatically by the program `genopinit'\n\
40718334Speterfrom the machine description file `md'.  */\n\n");
40818334Speter
40918334Speter  printf ("#include \"config.h\"\n");
41050397Sobrien  printf ("#include \"system.h\"\n");
411132718Skan  printf ("#include \"coretypes.h\"\n");
412132718Skan  printf ("#include \"tm.h\"\n");
41318334Speter  printf ("#include \"rtl.h\"\n");
41418334Speter  printf ("#include \"flags.h\"\n");
41518334Speter  printf ("#include \"insn-config.h\"\n");
41618334Speter  printf ("#include \"recog.h\"\n");
41718334Speter  printf ("#include \"expr.h\"\n");
41890075Sobrien  printf ("#include \"optabs.h\"\n");
41918334Speter  printf ("#include \"reload.h\"\n\n");
42018334Speter
421132718Skan  printf ("void\ninit_all_optabs (void)\n{\n");
42218334Speter
423132718Skan  puts ("\
424132718Skan#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
425132718Skan  int i, j;\n\
426132718Skan#endif\n");
427132718Skan
42818334Speter  /* Read the machine description.  */
42918334Speter
43018334Speter  while (1)
43118334Speter    {
43290075Sobrien      int line_no, insn_code_number = 0;
43390075Sobrien
43490075Sobrien      desc = read_md_rtx (&line_no, &insn_code_number);
43590075Sobrien      if (desc == NULL)
43618334Speter	break;
43718334Speter
43818334Speter      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
43918334Speter	gen_insn (desc);
44018334Speter    }
44118334Speter
442132718Skan  puts ("\
443132718Skan\n\
444132718Skan#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
445132718Skan  /* This flag says the same insns that convert to a signed fixnum\n\
446132718Skan     also convert validly to an unsigned one.  */\n\
447132718Skan  for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
448132718Skan    for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
449132718Skan      ufixtrunc_optab->handlers[i][j].insn_code\n\
450132718Skan      = sfixtrunc_optab->handlers[i][j].insn_code;\n\
451132718Skan#endif\n\
452132718Skan}");
45318334Speter
45418334Speter  fflush (stdout);
45590075Sobrien  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
45618334Speter}
457