xref: /dflybsd-src/contrib/gcc-8.0/gcc/genpreds.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Generate from machine description:
2*38fd1498Szrj    - prototype declarations for operand predicates (tm-preds.h)
3*38fd1498Szrj    - function definitions of operand predicates, if defined new-style
4*38fd1498Szrj      (insn-preds.c)
5*38fd1498Szrj    Copyright (C) 2001-2018 Free Software Foundation, Inc.
6*38fd1498Szrj 
7*38fd1498Szrj This file is part of GCC.
8*38fd1498Szrj 
9*38fd1498Szrj GCC is free software; you can redistribute it and/or modify
10*38fd1498Szrj it under the terms of the GNU General Public License as published by
11*38fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
12*38fd1498Szrj any later version.
13*38fd1498Szrj 
14*38fd1498Szrj GCC is distributed in the hope that it will be useful,
15*38fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
16*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*38fd1498Szrj GNU General Public License for more details.
18*38fd1498Szrj 
19*38fd1498Szrj You should have received a copy of the GNU General Public License
20*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
21*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
22*38fd1498Szrj 
23*38fd1498Szrj #include "bconfig.h"
24*38fd1498Szrj #include "system.h"
25*38fd1498Szrj #include "coretypes.h"
26*38fd1498Szrj #include "tm.h"
27*38fd1498Szrj #include "rtl.h"
28*38fd1498Szrj #include "errors.h"
29*38fd1498Szrj #include "obstack.h"
30*38fd1498Szrj #include "read-md.h"
31*38fd1498Szrj #include "gensupport.h"
32*38fd1498Szrj 
33*38fd1498Szrj static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 };
34*38fd1498Szrj 
35*38fd1498Szrj /* Given a predicate expression EXP, from form NAME at location LOC,
36*38fd1498Szrj    verify that it does not contain any RTL constructs which are not
37*38fd1498Szrj    valid in predicate definitions.  Returns true if EXP is
38*38fd1498Szrj    INvalid; issues error messages, caller need not.  */
39*38fd1498Szrj static bool
validate_exp(rtx exp,const char * name,file_location loc)40*38fd1498Szrj validate_exp (rtx exp, const char *name, file_location loc)
41*38fd1498Szrj {
42*38fd1498Szrj   if (exp == 0)
43*38fd1498Szrj     {
44*38fd1498Szrj       message_at (loc, "%s: must give a predicate expression", name);
45*38fd1498Szrj       return true;
46*38fd1498Szrj     }
47*38fd1498Szrj 
48*38fd1498Szrj   switch (GET_CODE (exp))
49*38fd1498Szrj     {
50*38fd1498Szrj       /* Ternary, binary, unary expressions: recurse into subexpressions.  */
51*38fd1498Szrj     case IF_THEN_ELSE:
52*38fd1498Szrj       if (validate_exp (XEXP (exp, 2), name, loc))
53*38fd1498Szrj 	return true;
54*38fd1498Szrj       /* fall through */
55*38fd1498Szrj     case AND:
56*38fd1498Szrj     case IOR:
57*38fd1498Szrj       if (validate_exp (XEXP (exp, 1), name, loc))
58*38fd1498Szrj 	return true;
59*38fd1498Szrj       /* fall through */
60*38fd1498Szrj     case NOT:
61*38fd1498Szrj       return validate_exp (XEXP (exp, 0), name, loc);
62*38fd1498Szrj 
63*38fd1498Szrj       /* MATCH_CODE might have a syntax error in its path expression.  */
64*38fd1498Szrj     case MATCH_CODE:
65*38fd1498Szrj       {
66*38fd1498Szrj 	const char *p;
67*38fd1498Szrj 	for (p = XSTR (exp, 1); *p; p++)
68*38fd1498Szrj 	  {
69*38fd1498Szrj 	    if (!ISDIGIT (*p) && !ISLOWER (*p))
70*38fd1498Szrj 	      {
71*38fd1498Szrj 		error_at (loc, "%s: invalid character in path "
72*38fd1498Szrj 			  "string '%s'", name, XSTR (exp, 1));
73*38fd1498Szrj 		return true;
74*38fd1498Szrj 	      }
75*38fd1498Szrj 	  }
76*38fd1498Szrj       }
77*38fd1498Szrj       gcc_fallthrough ();
78*38fd1498Szrj 
79*38fd1498Szrj       /* These need no special checking.  */
80*38fd1498Szrj     case MATCH_OPERAND:
81*38fd1498Szrj     case MATCH_TEST:
82*38fd1498Szrj       return false;
83*38fd1498Szrj 
84*38fd1498Szrj     default:
85*38fd1498Szrj       error_at (loc, "%s: cannot use '%s' in a predicate expression",
86*38fd1498Szrj 		name, GET_RTX_NAME (GET_CODE (exp)));
87*38fd1498Szrj       return true;
88*38fd1498Szrj     }
89*38fd1498Szrj }
90*38fd1498Szrj 
91*38fd1498Szrj /* Predicates are defined with (define_predicate) or
92*38fd1498Szrj    (define_special_predicate) expressions in the machine description.  */
93*38fd1498Szrj static void
process_define_predicate(md_rtx_info * info)94*38fd1498Szrj process_define_predicate (md_rtx_info *info)
95*38fd1498Szrj {
96*38fd1498Szrj   validate_exp (XEXP (info->def, 1), XSTR (info->def, 0), info->loc);
97*38fd1498Szrj }
98*38fd1498Szrj 
99*38fd1498Szrj /* Given a predicate, if it has an embedded C block, write the block
100*38fd1498Szrj    out as a static inline subroutine, and augment the RTL test with a
101*38fd1498Szrj    match_test that calls that subroutine.  For instance,
102*38fd1498Szrj 
103*38fd1498Szrj        (define_predicate "basereg_operand"
104*38fd1498Szrj          (match_operand 0 "register_operand")
105*38fd1498Szrj        {
106*38fd1498Szrj          if (GET_CODE (op) == SUBREG)
107*38fd1498Szrj            op = SUBREG_REG (op);
108*38fd1498Szrj          return REG_POINTER (op);
109*38fd1498Szrj        })
110*38fd1498Szrj 
111*38fd1498Szrj    becomes
112*38fd1498Szrj 
113*38fd1498Szrj        static inline int basereg_operand_1(rtx op, machine_mode mode)
114*38fd1498Szrj        {
115*38fd1498Szrj          if (GET_CODE (op) == SUBREG)
116*38fd1498Szrj            op = SUBREG_REG (op);
117*38fd1498Szrj          return REG_POINTER (op);
118*38fd1498Szrj        }
119*38fd1498Szrj 
120*38fd1498Szrj        (define_predicate "basereg_operand"
121*38fd1498Szrj          (and (match_operand 0 "register_operand")
122*38fd1498Szrj 	      (match_test "basereg_operand_1 (op, mode)")))
123*38fd1498Szrj 
124*38fd1498Szrj    The only wart is that there's no way to insist on a { } string in
125*38fd1498Szrj    an RTL template, so we have to handle "" strings.  */
126*38fd1498Szrj 
127*38fd1498Szrj 
128*38fd1498Szrj static void
write_predicate_subfunction(struct pred_data * p)129*38fd1498Szrj write_predicate_subfunction (struct pred_data *p)
130*38fd1498Szrj {
131*38fd1498Szrj   const char *match_test_str;
132*38fd1498Szrj   rtx match_test_exp, and_exp;
133*38fd1498Szrj 
134*38fd1498Szrj   if (p->c_block[0] == '\0')
135*38fd1498Szrj     return;
136*38fd1498Szrj 
137*38fd1498Szrj   /* Construct the function-call expression.  */
138*38fd1498Szrj   obstack_grow (rtl_obstack, p->name, strlen (p->name));
139*38fd1498Szrj   obstack_grow (rtl_obstack, "_1 (op, mode)",
140*38fd1498Szrj 		sizeof "_1 (op, mode)");
141*38fd1498Szrj   match_test_str = XOBFINISH (rtl_obstack, const char *);
142*38fd1498Szrj 
143*38fd1498Szrj   /* Add the function-call expression to the complete expression to be
144*38fd1498Szrj      evaluated.  */
145*38fd1498Szrj   match_test_exp = rtx_alloc (MATCH_TEST);
146*38fd1498Szrj   XSTR (match_test_exp, 0) = match_test_str;
147*38fd1498Szrj 
148*38fd1498Szrj   and_exp = rtx_alloc (AND);
149*38fd1498Szrj   XEXP (and_exp, 0) = p->exp;
150*38fd1498Szrj   XEXP (and_exp, 1) = match_test_exp;
151*38fd1498Szrj 
152*38fd1498Szrj   p->exp = and_exp;
153*38fd1498Szrj 
154*38fd1498Szrj   printf ("static inline int\n"
155*38fd1498Szrj 	  "%s_1 (rtx op, machine_mode mode ATTRIBUTE_UNUSED)\n",
156*38fd1498Szrj 	  p->name);
157*38fd1498Szrj   rtx_reader_ptr->print_md_ptr_loc (p->c_block);
158*38fd1498Szrj   if (p->c_block[0] == '{')
159*38fd1498Szrj     fputs (p->c_block, stdout);
160*38fd1498Szrj   else
161*38fd1498Szrj     printf ("{\n  %s\n}", p->c_block);
162*38fd1498Szrj   fputs ("\n\n", stdout);
163*38fd1498Szrj }
164*38fd1498Szrj 
165*38fd1498Szrj /* Given a predicate expression EXP, from form NAME, determine whether
166*38fd1498Szrj    it refers to the variable given as VAR.  */
167*38fd1498Szrj static bool
needs_variable(rtx exp,const char * var)168*38fd1498Szrj needs_variable (rtx exp, const char *var)
169*38fd1498Szrj {
170*38fd1498Szrj   switch (GET_CODE (exp))
171*38fd1498Szrj     {
172*38fd1498Szrj       /* Ternary, binary, unary expressions need a variable if
173*38fd1498Szrj 	 any of their subexpressions do.  */
174*38fd1498Szrj     case IF_THEN_ELSE:
175*38fd1498Szrj       if (needs_variable (XEXP (exp, 2), var))
176*38fd1498Szrj 	return true;
177*38fd1498Szrj       /* fall through */
178*38fd1498Szrj     case AND:
179*38fd1498Szrj     case IOR:
180*38fd1498Szrj       if (needs_variable (XEXP (exp, 1), var))
181*38fd1498Szrj 	return true;
182*38fd1498Szrj       /* fall through */
183*38fd1498Szrj     case NOT:
184*38fd1498Szrj       return needs_variable (XEXP (exp, 0), var);
185*38fd1498Szrj 
186*38fd1498Szrj       /* MATCH_CODE uses "op", but nothing else.  */
187*38fd1498Szrj     case MATCH_CODE:
188*38fd1498Szrj       return !strcmp (var, "op");
189*38fd1498Szrj 
190*38fd1498Szrj       /* MATCH_OPERAND uses "op" and may use "mode".  */
191*38fd1498Szrj     case MATCH_OPERAND:
192*38fd1498Szrj       if (!strcmp (var, "op"))
193*38fd1498Szrj 	return true;
194*38fd1498Szrj       if (!strcmp (var, "mode") && GET_MODE (exp) == VOIDmode)
195*38fd1498Szrj 	return true;
196*38fd1498Szrj       return false;
197*38fd1498Szrj 
198*38fd1498Szrj       /* MATCH_TEST uses var if XSTR (exp, 0) =~ /\b${var}\b/o; */
199*38fd1498Szrj     case MATCH_TEST:
200*38fd1498Szrj       {
201*38fd1498Szrj 	const char *p = XSTR (exp, 0);
202*38fd1498Szrj 	const char *q = strstr (p, var);
203*38fd1498Szrj 	if (!q)
204*38fd1498Szrj 	  return false;
205*38fd1498Szrj 	if (q != p && (ISALNUM (q[-1]) || q[-1] == '_'))
206*38fd1498Szrj 	  return false;
207*38fd1498Szrj 	q += strlen (var);
208*38fd1498Szrj 	if (ISALNUM (q[0]) || q[0] == '_')
209*38fd1498Szrj 	  return false;
210*38fd1498Szrj       }
211*38fd1498Szrj       return true;
212*38fd1498Szrj 
213*38fd1498Szrj     default:
214*38fd1498Szrj       gcc_unreachable ();
215*38fd1498Szrj     }
216*38fd1498Szrj }
217*38fd1498Szrj 
218*38fd1498Szrj /* Given an RTL expression EXP, find all subexpressions which we may
219*38fd1498Szrj    assume to perform mode tests.  Normal MATCH_OPERAND does;
220*38fd1498Szrj    MATCH_CODE doesn't as such (although certain codes always have
221*38fd1498Szrj    VOIDmode); and we have to assume that MATCH_TEST does not.
222*38fd1498Szrj    These combine in almost-boolean fashion - the only exception is
223*38fd1498Szrj    that (not X) must be assumed not to perform a mode test, whether
224*38fd1498Szrj    or not X does.
225*38fd1498Szrj 
226*38fd1498Szrj    The mark is the RTL /v flag, which is true for subexpressions which
227*38fd1498Szrj    do *not* perform mode tests.
228*38fd1498Szrj */
229*38fd1498Szrj #define NO_MODE_TEST(EXP) RTX_FLAG (EXP, volatil)
230*38fd1498Szrj static void
mark_mode_tests(rtx exp)231*38fd1498Szrj mark_mode_tests (rtx exp)
232*38fd1498Szrj {
233*38fd1498Szrj   switch (GET_CODE (exp))
234*38fd1498Szrj     {
235*38fd1498Szrj     case MATCH_OPERAND:
236*38fd1498Szrj       {
237*38fd1498Szrj 	struct pred_data *p = lookup_predicate (XSTR (exp, 1));
238*38fd1498Szrj 	if (!p)
239*38fd1498Szrj 	  error ("reference to undefined predicate '%s'", XSTR (exp, 1));
240*38fd1498Szrj 	else if (p->special || GET_MODE (exp) != VOIDmode)
241*38fd1498Szrj 	  NO_MODE_TEST (exp) = 1;
242*38fd1498Szrj       }
243*38fd1498Szrj       break;
244*38fd1498Szrj 
245*38fd1498Szrj     case MATCH_CODE:
246*38fd1498Szrj       NO_MODE_TEST (exp) = 1;
247*38fd1498Szrj       break;
248*38fd1498Szrj 
249*38fd1498Szrj     case MATCH_TEST:
250*38fd1498Szrj     case NOT:
251*38fd1498Szrj       NO_MODE_TEST (exp) = 1;
252*38fd1498Szrj       break;
253*38fd1498Szrj 
254*38fd1498Szrj     case AND:
255*38fd1498Szrj       mark_mode_tests (XEXP (exp, 0));
256*38fd1498Szrj       mark_mode_tests (XEXP (exp, 1));
257*38fd1498Szrj 
258*38fd1498Szrj       NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
259*38fd1498Szrj 			    && NO_MODE_TEST (XEXP (exp, 1)));
260*38fd1498Szrj       break;
261*38fd1498Szrj 
262*38fd1498Szrj     case IOR:
263*38fd1498Szrj       mark_mode_tests (XEXP (exp, 0));
264*38fd1498Szrj       mark_mode_tests (XEXP (exp, 1));
265*38fd1498Szrj 
266*38fd1498Szrj       NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
267*38fd1498Szrj 			    || NO_MODE_TEST (XEXP (exp, 1)));
268*38fd1498Szrj       break;
269*38fd1498Szrj 
270*38fd1498Szrj     case IF_THEN_ELSE:
271*38fd1498Szrj       /* A ? B : C does a mode test if (one of A and B) does a mode
272*38fd1498Szrj 	 test, and C does too.  */
273*38fd1498Szrj       mark_mode_tests (XEXP (exp, 0));
274*38fd1498Szrj       mark_mode_tests (XEXP (exp, 1));
275*38fd1498Szrj       mark_mode_tests (XEXP (exp, 2));
276*38fd1498Szrj 
277*38fd1498Szrj       NO_MODE_TEST (exp) = ((NO_MODE_TEST (XEXP (exp, 0))
278*38fd1498Szrj 			     && NO_MODE_TEST (XEXP (exp, 1)))
279*38fd1498Szrj 			    || NO_MODE_TEST (XEXP (exp, 2)));
280*38fd1498Szrj       break;
281*38fd1498Szrj 
282*38fd1498Szrj     default:
283*38fd1498Szrj       gcc_unreachable ();
284*38fd1498Szrj     }
285*38fd1498Szrj }
286*38fd1498Szrj 
287*38fd1498Szrj /* Determine whether the expression EXP is a MATCH_CODE that should
288*38fd1498Szrj    be written as a switch statement.  */
289*38fd1498Szrj static bool
generate_switch_p(rtx exp)290*38fd1498Szrj generate_switch_p (rtx exp)
291*38fd1498Szrj {
292*38fd1498Szrj   return GET_CODE (exp) == MATCH_CODE
293*38fd1498Szrj 	 && strchr (XSTR (exp, 0), ',');
294*38fd1498Szrj }
295*38fd1498Szrj 
296*38fd1498Szrj /* Given a predicate, work out where in its RTL expression to add
297*38fd1498Szrj    tests for proper modes.  Special predicates do not get any such
298*38fd1498Szrj    tests.  We try to avoid adding tests when we don't have to; in
299*38fd1498Szrj    particular, other normal predicates can be counted on to do it for
300*38fd1498Szrj    us.  */
301*38fd1498Szrj 
302*38fd1498Szrj static void
add_mode_tests(struct pred_data * p)303*38fd1498Szrj add_mode_tests (struct pred_data *p)
304*38fd1498Szrj {
305*38fd1498Szrj   rtx match_test_exp, and_exp;
306*38fd1498Szrj   rtx *pos;
307*38fd1498Szrj 
308*38fd1498Szrj   /* Don't touch special predicates.  */
309*38fd1498Szrj   if (p->special)
310*38fd1498Szrj     return;
311*38fd1498Szrj 
312*38fd1498Szrj   /* Check whether the predicate accepts const scalar ints (which always
313*38fd1498Szrj      have a stored mode of VOIDmode, but logically have a real mode)
314*38fd1498Szrj      and whether it matches anything besides const scalar ints.  */
315*38fd1498Szrj   bool matches_const_scalar_int_p = false;
316*38fd1498Szrj   bool matches_other_p = false;
317*38fd1498Szrj   for (int i = 0; i < NUM_RTX_CODE; ++i)
318*38fd1498Szrj     if (p->codes[i])
319*38fd1498Szrj       switch (i)
320*38fd1498Szrj 	{
321*38fd1498Szrj 	case CONST_INT:
322*38fd1498Szrj 	case CONST_WIDE_INT:
323*38fd1498Szrj 	  /* Special handling for (VOIDmode) LABEL_REFs.  */
324*38fd1498Szrj 	case LABEL_REF:
325*38fd1498Szrj 	  matches_const_scalar_int_p = true;
326*38fd1498Szrj 	  break;
327*38fd1498Szrj 
328*38fd1498Szrj 	case CONST_DOUBLE:
329*38fd1498Szrj 	  if (!TARGET_SUPPORTS_WIDE_INT)
330*38fd1498Szrj 	    matches_const_scalar_int_p = true;
331*38fd1498Szrj 	  matches_other_p = true;
332*38fd1498Szrj 	  break;
333*38fd1498Szrj 
334*38fd1498Szrj 	default:
335*38fd1498Szrj 	  matches_other_p = true;
336*38fd1498Szrj 	  break;
337*38fd1498Szrj 	}
338*38fd1498Szrj 
339*38fd1498Szrj   /* There's no need for a mode check if the predicate only accepts
340*38fd1498Szrj      constant integers.  The code checks in the predicate are enough
341*38fd1498Szrj      to establish that the mode is VOIDmode.
342*38fd1498Szrj 
343*38fd1498Szrj      Note that the predicate itself should check whether a scalar
344*38fd1498Szrj      integer is in range of the given mode.  */
345*38fd1498Szrj   if (!matches_other_p)
346*38fd1498Szrj     return;
347*38fd1498Szrj 
348*38fd1498Szrj   mark_mode_tests (p->exp);
349*38fd1498Szrj 
350*38fd1498Szrj   /* If the whole expression already tests the mode, we're done.  */
351*38fd1498Szrj   if (!NO_MODE_TEST (p->exp))
352*38fd1498Szrj     return;
353*38fd1498Szrj 
354*38fd1498Szrj   match_test_exp = rtx_alloc (MATCH_TEST);
355*38fd1498Szrj   if (matches_const_scalar_int_p)
356*38fd1498Szrj     XSTR (match_test_exp, 0) = ("mode == VOIDmode || GET_MODE (op) == mode"
357*38fd1498Szrj 				" || GET_MODE (op) == VOIDmode");
358*38fd1498Szrj   else
359*38fd1498Szrj     XSTR (match_test_exp, 0) = "mode == VOIDmode || GET_MODE (op) == mode";
360*38fd1498Szrj   and_exp = rtx_alloc (AND);
361*38fd1498Szrj   XEXP (and_exp, 1) = match_test_exp;
362*38fd1498Szrj 
363*38fd1498Szrj   /* It is always correct to rewrite p->exp as
364*38fd1498Szrj 
365*38fd1498Szrj         (and (...) (match_test "mode == VOIDmode || GET_MODE (op) == mode"))
366*38fd1498Szrj 
367*38fd1498Szrj      but there are a couple forms where we can do better.  If the
368*38fd1498Szrj      top-level pattern is an IOR, and one of the two branches does test
369*38fd1498Szrj      the mode, we can wrap just the branch that doesn't.  Likewise, if
370*38fd1498Szrj      we have an IF_THEN_ELSE, and one side of it tests the mode, we can
371*38fd1498Szrj      wrap just the side that doesn't.  And, of course, we can repeat this
372*38fd1498Szrj      descent as many times as it works.  */
373*38fd1498Szrj 
374*38fd1498Szrj   pos = &p->exp;
375*38fd1498Szrj   for (;;)
376*38fd1498Szrj     {
377*38fd1498Szrj       rtx subexp = *pos;
378*38fd1498Szrj 
379*38fd1498Szrj       switch (GET_CODE (subexp))
380*38fd1498Szrj 	{
381*38fd1498Szrj 	case AND:
382*38fd1498Szrj 	  /* The switch code generation in write_predicate_stmts prefers
383*38fd1498Szrj 	     rtx code tests to be at the top of the expression tree.  So
384*38fd1498Szrj 	     push this AND down into the second operand of an existing
385*38fd1498Szrj 	     AND expression.  */
386*38fd1498Szrj 	  if (generate_switch_p (XEXP (subexp, 0)))
387*38fd1498Szrj 	    pos = &XEXP (subexp, 1);
388*38fd1498Szrj 	  goto break_loop;
389*38fd1498Szrj 
390*38fd1498Szrj 	case IOR:
391*38fd1498Szrj 	  {
392*38fd1498Szrj 	    int test0 = NO_MODE_TEST (XEXP (subexp, 0));
393*38fd1498Szrj 	    int test1 = NO_MODE_TEST (XEXP (subexp, 1));
394*38fd1498Szrj 
395*38fd1498Szrj 	    gcc_assert (test0 || test1);
396*38fd1498Szrj 
397*38fd1498Szrj 	    if (test0 && test1)
398*38fd1498Szrj 	      goto break_loop;
399*38fd1498Szrj 	    pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
400*38fd1498Szrj 	  }
401*38fd1498Szrj 	  break;
402*38fd1498Szrj 
403*38fd1498Szrj 	case IF_THEN_ELSE:
404*38fd1498Szrj 	  {
405*38fd1498Szrj 	    int test0 = NO_MODE_TEST (XEXP (subexp, 0));
406*38fd1498Szrj 	    int test1 = NO_MODE_TEST (XEXP (subexp, 1));
407*38fd1498Szrj 	    int test2 = NO_MODE_TEST (XEXP (subexp, 2));
408*38fd1498Szrj 
409*38fd1498Szrj 	    gcc_assert ((test0 && test1) || test2);
410*38fd1498Szrj 
411*38fd1498Szrj 	    if (test0 && test1 && test2)
412*38fd1498Szrj 	      goto break_loop;
413*38fd1498Szrj 	    if (test0 && test1)
414*38fd1498Szrj 	      /* Must put it on the dependent clause, not the
415*38fd1498Szrj 	      	 controlling expression, or we change the meaning of
416*38fd1498Szrj 	      	 the test.  */
417*38fd1498Szrj 	      pos = &XEXP (subexp, 1);
418*38fd1498Szrj 	    else
419*38fd1498Szrj 	      pos = &XEXP (subexp, 2);
420*38fd1498Szrj 	  }
421*38fd1498Szrj 	  break;
422*38fd1498Szrj 
423*38fd1498Szrj 	default:
424*38fd1498Szrj 	  goto break_loop;
425*38fd1498Szrj 	}
426*38fd1498Szrj     }
427*38fd1498Szrj  break_loop:
428*38fd1498Szrj   XEXP (and_exp, 0) = *pos;
429*38fd1498Szrj   *pos = and_exp;
430*38fd1498Szrj }
431*38fd1498Szrj 
432*38fd1498Szrj /* PATH is a string describing a path from the root of an RTL
433*38fd1498Szrj    expression to an inner subexpression to be tested.  Output
434*38fd1498Szrj    code which computes the subexpression from the variable
435*38fd1498Szrj    holding the root of the expression.  */
436*38fd1498Szrj static void
write_extract_subexp(const char * path)437*38fd1498Szrj write_extract_subexp (const char *path)
438*38fd1498Szrj {
439*38fd1498Szrj   int len = strlen (path);
440*38fd1498Szrj   int i;
441*38fd1498Szrj 
442*38fd1498Szrj   /* We first write out the operations (XEXP or XVECEXP) in reverse
443*38fd1498Szrj      order, then write "op", then the indices in forward order.  */
444*38fd1498Szrj   for (i = len - 1; i >= 0; i--)
445*38fd1498Szrj     {
446*38fd1498Szrj       if (ISLOWER (path[i]))
447*38fd1498Szrj 	fputs ("XVECEXP (", stdout);
448*38fd1498Szrj       else if (ISDIGIT (path[i]))
449*38fd1498Szrj 	fputs ("XEXP (", stdout);
450*38fd1498Szrj       else
451*38fd1498Szrj 	gcc_unreachable ();
452*38fd1498Szrj     }
453*38fd1498Szrj 
454*38fd1498Szrj   fputs ("op", stdout);
455*38fd1498Szrj 
456*38fd1498Szrj   for (i = 0; i < len; i++)
457*38fd1498Szrj     {
458*38fd1498Szrj       if (ISLOWER (path[i]))
459*38fd1498Szrj 	printf (", 0, %d)", path[i] - 'a');
460*38fd1498Szrj       else if (ISDIGIT (path[i]))
461*38fd1498Szrj 	printf (", %d)", path[i] - '0');
462*38fd1498Szrj       else
463*38fd1498Szrj 	gcc_unreachable ();
464*38fd1498Szrj     }
465*38fd1498Szrj }
466*38fd1498Szrj 
467*38fd1498Szrj /* CODES is a list of RTX codes.  Write out an expression which
468*38fd1498Szrj    determines whether the operand has one of those codes.  */
469*38fd1498Szrj static void
write_match_code(const char * path,const char * codes)470*38fd1498Szrj write_match_code (const char *path, const char *codes)
471*38fd1498Szrj {
472*38fd1498Szrj   const char *code;
473*38fd1498Szrj 
474*38fd1498Szrj   while ((code = scan_comma_elt (&codes)) != 0)
475*38fd1498Szrj     {
476*38fd1498Szrj       fputs ("GET_CODE (", stdout);
477*38fd1498Szrj       write_extract_subexp (path);
478*38fd1498Szrj       fputs (") == ", stdout);
479*38fd1498Szrj       while (code < codes)
480*38fd1498Szrj 	{
481*38fd1498Szrj 	  putchar (TOUPPER (*code));
482*38fd1498Szrj 	  code++;
483*38fd1498Szrj 	}
484*38fd1498Szrj 
485*38fd1498Szrj       if (*codes == ',')
486*38fd1498Szrj 	fputs (" || ", stdout);
487*38fd1498Szrj     }
488*38fd1498Szrj }
489*38fd1498Szrj 
490*38fd1498Szrj /* EXP is an RTL (sub)expression for a predicate.  Recursively
491*38fd1498Szrj    descend the expression and write out an equivalent C expression.  */
492*38fd1498Szrj static void
write_predicate_expr(rtx exp)493*38fd1498Szrj write_predicate_expr (rtx exp)
494*38fd1498Szrj {
495*38fd1498Szrj   switch (GET_CODE (exp))
496*38fd1498Szrj     {
497*38fd1498Szrj     case AND:
498*38fd1498Szrj       putchar ('(');
499*38fd1498Szrj       write_predicate_expr (XEXP (exp, 0));
500*38fd1498Szrj       fputs (") && (", stdout);
501*38fd1498Szrj       write_predicate_expr (XEXP (exp, 1));
502*38fd1498Szrj       putchar (')');
503*38fd1498Szrj       break;
504*38fd1498Szrj 
505*38fd1498Szrj     case IOR:
506*38fd1498Szrj       putchar ('(');
507*38fd1498Szrj       write_predicate_expr (XEXP (exp, 0));
508*38fd1498Szrj       fputs (") || (", stdout);
509*38fd1498Szrj       write_predicate_expr (XEXP (exp, 1));
510*38fd1498Szrj       putchar (')');
511*38fd1498Szrj       break;
512*38fd1498Szrj 
513*38fd1498Szrj     case NOT:
514*38fd1498Szrj       fputs ("!(", stdout);
515*38fd1498Szrj       write_predicate_expr (XEXP (exp, 0));
516*38fd1498Szrj       putchar (')');
517*38fd1498Szrj       break;
518*38fd1498Szrj 
519*38fd1498Szrj     case IF_THEN_ELSE:
520*38fd1498Szrj       putchar ('(');
521*38fd1498Szrj       write_predicate_expr (XEXP (exp, 0));
522*38fd1498Szrj       fputs (") ? (", stdout);
523*38fd1498Szrj       write_predicate_expr (XEXP (exp, 1));
524*38fd1498Szrj       fputs (") : (", stdout);
525*38fd1498Szrj       write_predicate_expr (XEXP (exp, 2));
526*38fd1498Szrj       putchar (')');
527*38fd1498Szrj       break;
528*38fd1498Szrj 
529*38fd1498Szrj     case MATCH_OPERAND:
530*38fd1498Szrj       if (GET_MODE (exp) == VOIDmode)
531*38fd1498Szrj         printf ("%s (op, mode)", XSTR (exp, 1));
532*38fd1498Szrj       else
533*38fd1498Szrj         printf ("%s (op, %smode)", XSTR (exp, 1), mode_name[GET_MODE (exp)]);
534*38fd1498Szrj       break;
535*38fd1498Szrj 
536*38fd1498Szrj     case MATCH_CODE:
537*38fd1498Szrj       write_match_code (XSTR (exp, 1), XSTR (exp, 0));
538*38fd1498Szrj       break;
539*38fd1498Szrj 
540*38fd1498Szrj     case MATCH_TEST:
541*38fd1498Szrj       rtx_reader_ptr->print_c_condition (XSTR (exp, 0));
542*38fd1498Szrj       break;
543*38fd1498Szrj 
544*38fd1498Szrj     default:
545*38fd1498Szrj       gcc_unreachable ();
546*38fd1498Szrj     }
547*38fd1498Szrj }
548*38fd1498Szrj 
549*38fd1498Szrj /* Write the MATCH_CODE expression EXP as a switch statement.  */
550*38fd1498Szrj 
551*38fd1498Szrj static void
write_match_code_switch(rtx exp)552*38fd1498Szrj write_match_code_switch (rtx exp)
553*38fd1498Szrj {
554*38fd1498Szrj   const char *codes = XSTR (exp, 0);
555*38fd1498Szrj   const char *path = XSTR (exp, 1);
556*38fd1498Szrj   const char *code;
557*38fd1498Szrj 
558*38fd1498Szrj   fputs ("  switch (GET_CODE (", stdout);
559*38fd1498Szrj   write_extract_subexp (path);
560*38fd1498Szrj   fputs ("))\n    {\n", stdout);
561*38fd1498Szrj 
562*38fd1498Szrj   while ((code = scan_comma_elt (&codes)) != 0)
563*38fd1498Szrj     {
564*38fd1498Szrj       fputs ("    case ", stdout);
565*38fd1498Szrj       while (code < codes)
566*38fd1498Szrj 	{
567*38fd1498Szrj 	  putchar (TOUPPER (*code));
568*38fd1498Szrj 	  code++;
569*38fd1498Szrj 	}
570*38fd1498Szrj       fputs (":\n", stdout);
571*38fd1498Szrj     }
572*38fd1498Szrj }
573*38fd1498Szrj 
574*38fd1498Szrj /* Given a predicate expression EXP, write out a sequence of stmts
575*38fd1498Szrj    to evaluate it.  This is similar to write_predicate_expr but can
576*38fd1498Szrj    generate efficient switch statements.  */
577*38fd1498Szrj 
578*38fd1498Szrj static void
write_predicate_stmts(rtx exp)579*38fd1498Szrj write_predicate_stmts (rtx exp)
580*38fd1498Szrj {
581*38fd1498Szrj   switch (GET_CODE (exp))
582*38fd1498Szrj     {
583*38fd1498Szrj     case MATCH_CODE:
584*38fd1498Szrj       if (generate_switch_p (exp))
585*38fd1498Szrj 	{
586*38fd1498Szrj 	  write_match_code_switch (exp);
587*38fd1498Szrj 	  puts ("      return true;\n"
588*38fd1498Szrj 		"    default:\n"
589*38fd1498Szrj 		"      break;\n"
590*38fd1498Szrj 		"    }\n"
591*38fd1498Szrj 		"  return false;");
592*38fd1498Szrj 	  return;
593*38fd1498Szrj 	}
594*38fd1498Szrj       break;
595*38fd1498Szrj 
596*38fd1498Szrj     case AND:
597*38fd1498Szrj       if (generate_switch_p (XEXP (exp, 0)))
598*38fd1498Szrj 	{
599*38fd1498Szrj 	  write_match_code_switch (XEXP (exp, 0));
600*38fd1498Szrj 	  puts ("      break;\n"
601*38fd1498Szrj 		"    default:\n"
602*38fd1498Szrj 		"      return false;\n"
603*38fd1498Szrj 		"    }");
604*38fd1498Szrj 	  exp = XEXP (exp, 1);
605*38fd1498Szrj 	}
606*38fd1498Szrj       break;
607*38fd1498Szrj 
608*38fd1498Szrj     case IOR:
609*38fd1498Szrj       if (generate_switch_p (XEXP (exp, 0)))
610*38fd1498Szrj 	{
611*38fd1498Szrj 	  write_match_code_switch (XEXP (exp, 0));
612*38fd1498Szrj 	  puts ("      return true;\n"
613*38fd1498Szrj 		"    default:\n"
614*38fd1498Szrj 		"      break;\n"
615*38fd1498Szrj 		"    }");
616*38fd1498Szrj 	  exp = XEXP (exp, 1);
617*38fd1498Szrj 	}
618*38fd1498Szrj       break;
619*38fd1498Szrj 
620*38fd1498Szrj     case NOT:
621*38fd1498Szrj       if (generate_switch_p (XEXP (exp, 0)))
622*38fd1498Szrj 	{
623*38fd1498Szrj 	  write_match_code_switch (XEXP (exp, 0));
624*38fd1498Szrj 	  puts ("      return false;\n"
625*38fd1498Szrj 		"    default:\n"
626*38fd1498Szrj 		"      break;\n"
627*38fd1498Szrj 		"    }\n"
628*38fd1498Szrj 		"  return true;");
629*38fd1498Szrj 	  return;
630*38fd1498Szrj 	}
631*38fd1498Szrj       break;
632*38fd1498Szrj 
633*38fd1498Szrj     default:
634*38fd1498Szrj       break;
635*38fd1498Szrj     }
636*38fd1498Szrj 
637*38fd1498Szrj   fputs ("  return ",stdout);
638*38fd1498Szrj   write_predicate_expr (exp);
639*38fd1498Szrj   fputs (";\n", stdout);
640*38fd1498Szrj }
641*38fd1498Szrj 
642*38fd1498Szrj /* Given a predicate, write out a complete C function to compute it.  */
643*38fd1498Szrj static void
write_one_predicate_function(struct pred_data * p)644*38fd1498Szrj write_one_predicate_function (struct pred_data *p)
645*38fd1498Szrj {
646*38fd1498Szrj   if (!p->exp)
647*38fd1498Szrj     return;
648*38fd1498Szrj 
649*38fd1498Szrj   write_predicate_subfunction (p);
650*38fd1498Szrj   add_mode_tests (p);
651*38fd1498Szrj 
652*38fd1498Szrj   /* A normal predicate can legitimately not look at machine_mode
653*38fd1498Szrj      if it accepts only CONST_INTs and/or CONST_WIDE_INT and/or CONST_DOUBLEs.  */
654*38fd1498Szrj   printf ("int\n%s (rtx op, machine_mode mode ATTRIBUTE_UNUSED)\n{\n",
655*38fd1498Szrj 	  p->name);
656*38fd1498Szrj   write_predicate_stmts (p->exp);
657*38fd1498Szrj   fputs ("}\n\n", stdout);
658*38fd1498Szrj }
659*38fd1498Szrj 
660*38fd1498Szrj /* Constraints fall into two categories: register constraints
661*38fd1498Szrj    (define_register_constraint), and others (define_constraint,
662*38fd1498Szrj    define_memory_constraint, define_special_memory_constraint,
663*38fd1498Szrj    define_address_constraint).  We work out automatically which of the
664*38fd1498Szrj    various old-style macros they correspond to, and produce
665*38fd1498Szrj    appropriate code.  They all go in the same hash table so we can
666*38fd1498Szrj    verify that there are no duplicate names.  */
667*38fd1498Szrj 
668*38fd1498Szrj /* All data from one constraint definition.  */
669*38fd1498Szrj struct constraint_data
670*38fd1498Szrj {
671*38fd1498Szrj   struct constraint_data *next_this_letter;
672*38fd1498Szrj   struct constraint_data *next_textual;
673*38fd1498Szrj   const char *name;
674*38fd1498Szrj   const char *c_name;    /* same as .name unless mangling is necessary */
675*38fd1498Szrj   file_location loc;     /* location of definition */
676*38fd1498Szrj   size_t namelen;
677*38fd1498Szrj   const char *regclass;  /* for register constraints */
678*38fd1498Szrj   rtx exp;               /* for other constraints */
679*38fd1498Szrj   unsigned int is_register	: 1;
680*38fd1498Szrj   unsigned int is_const_int	: 1;
681*38fd1498Szrj   unsigned int is_const_dbl	: 1;
682*38fd1498Szrj   unsigned int is_extra		: 1;
683*38fd1498Szrj   unsigned int is_memory	: 1;
684*38fd1498Szrj   unsigned int is_special_memory: 1;
685*38fd1498Szrj   unsigned int is_address	: 1;
686*38fd1498Szrj   unsigned int maybe_allows_reg : 1;
687*38fd1498Szrj   unsigned int maybe_allows_mem : 1;
688*38fd1498Szrj };
689*38fd1498Szrj 
690*38fd1498Szrj /* Overview of all constraints beginning with a given letter.  */
691*38fd1498Szrj 
692*38fd1498Szrj static struct constraint_data *
693*38fd1498Szrj constraints_by_letter_table[1<<CHAR_BIT];
694*38fd1498Szrj 
695*38fd1498Szrj /* For looking up all the constraints in the order that they appeared
696*38fd1498Szrj    in the machine description.  */
697*38fd1498Szrj static struct constraint_data *first_constraint;
698*38fd1498Szrj static struct constraint_data **last_constraint_ptr = &first_constraint;
699*38fd1498Szrj 
700*38fd1498Szrj #define FOR_ALL_CONSTRAINTS(iter_) \
701*38fd1498Szrj   for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
702*38fd1498Szrj 
703*38fd1498Szrj /* Contraint letters that have a special meaning and that cannot be used
704*38fd1498Szrj    in define*_constraints.  */
705*38fd1498Szrj static const char generic_constraint_letters[] = "g";
706*38fd1498Szrj 
707*38fd1498Szrj /* Machine-independent code expects that constraints with these
708*38fd1498Szrj    (initial) letters will allow only (a subset of all) CONST_INTs.  */
709*38fd1498Szrj 
710*38fd1498Szrj static const char const_int_constraints[] = "IJKLMNOP";
711*38fd1498Szrj 
712*38fd1498Szrj /* Machine-independent code expects that constraints with these
713*38fd1498Szrj    (initial) letters will allow only (a subset of all) CONST_DOUBLEs.  */
714*38fd1498Szrj 
715*38fd1498Szrj static const char const_dbl_constraints[] = "GH";
716*38fd1498Szrj 
717*38fd1498Szrj /* Summary data used to decide whether to output various functions and
718*38fd1498Szrj    macro definitions.  */
719*38fd1498Szrj static unsigned int constraint_max_namelen;
720*38fd1498Szrj static bool have_register_constraints;
721*38fd1498Szrj static bool have_memory_constraints;
722*38fd1498Szrj static bool have_special_memory_constraints;
723*38fd1498Szrj static bool have_address_constraints;
724*38fd1498Szrj static bool have_extra_constraints;
725*38fd1498Szrj static bool have_const_int_constraints;
726*38fd1498Szrj static unsigned int num_constraints;
727*38fd1498Szrj 
728*38fd1498Szrj static const constraint_data **enum_order;
729*38fd1498Szrj static unsigned int register_start, register_end;
730*38fd1498Szrj static unsigned int satisfied_start;
731*38fd1498Szrj static unsigned int const_int_start, const_int_end;
732*38fd1498Szrj static unsigned int memory_start, memory_end;
733*38fd1498Szrj static unsigned int special_memory_start, special_memory_end;
734*38fd1498Szrj static unsigned int address_start, address_end;
735*38fd1498Szrj static unsigned int maybe_allows_none_start, maybe_allows_none_end;
736*38fd1498Szrj static unsigned int maybe_allows_reg_start, maybe_allows_reg_end;
737*38fd1498Szrj static unsigned int maybe_allows_mem_start, maybe_allows_mem_end;
738*38fd1498Szrj 
739*38fd1498Szrj /* Convert NAME, which contains angle brackets and/or underscores, to
740*38fd1498Szrj    a string that can be used as part of a C identifier.  The string
741*38fd1498Szrj    comes from the rtl_obstack.  */
742*38fd1498Szrj static const char *
mangle(const char * name)743*38fd1498Szrj mangle (const char *name)
744*38fd1498Szrj {
745*38fd1498Szrj   for (; *name; name++)
746*38fd1498Szrj     switch (*name)
747*38fd1498Szrj       {
748*38fd1498Szrj       case '_': obstack_grow (rtl_obstack, "__", 2); break;
749*38fd1498Szrj       case '<':	obstack_grow (rtl_obstack, "_l", 2); break;
750*38fd1498Szrj       case '>':	obstack_grow (rtl_obstack, "_g", 2); break;
751*38fd1498Szrj       default: obstack_1grow (rtl_obstack, *name); break;
752*38fd1498Szrj       }
753*38fd1498Szrj 
754*38fd1498Szrj   obstack_1grow (rtl_obstack, '\0');
755*38fd1498Szrj   return XOBFINISH (rtl_obstack, const char *);
756*38fd1498Szrj }
757*38fd1498Szrj 
758*38fd1498Szrj /* Add one constraint, of any sort, to the tables.  NAME is its name;
759*38fd1498Szrj    REGCLASS is the register class, if any; EXP is the expression to
760*38fd1498Szrj    test, if any; IS_MEMORY, IS_SPECIAL_MEMORY and IS_ADDRESS indicate
761*38fd1498Szrj    memory, special memory, and address constraints, respectively; LOC
762*38fd1498Szrj    is the .md file location.
763*38fd1498Szrj 
764*38fd1498Szrj    Not all combinations of arguments are valid; most importantly,
765*38fd1498Szrj    REGCLASS is mutually exclusive with EXP, and
766*38fd1498Szrj    IS_MEMORY/IS_SPECIAL_MEMORY/IS_ADDRESS are only meaningful for
767*38fd1498Szrj    constraints with EXP.
768*38fd1498Szrj 
769*38fd1498Szrj    This function enforces all syntactic and semantic rules about what
770*38fd1498Szrj    constraints can be defined.  */
771*38fd1498Szrj 
772*38fd1498Szrj static void
add_constraint(const char * name,const char * regclass,rtx exp,bool is_memory,bool is_special_memory,bool is_address,file_location loc)773*38fd1498Szrj add_constraint (const char *name, const char *regclass,
774*38fd1498Szrj 		rtx exp, bool is_memory, bool is_special_memory,
775*38fd1498Szrj 		bool is_address, file_location loc)
776*38fd1498Szrj {
777*38fd1498Szrj   struct constraint_data *c, **iter, **slot;
778*38fd1498Szrj   const char *p;
779*38fd1498Szrj   bool need_mangled_name = false;
780*38fd1498Szrj   bool is_const_int;
781*38fd1498Szrj   bool is_const_dbl;
782*38fd1498Szrj   size_t namelen;
783*38fd1498Szrj 
784*38fd1498Szrj   if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
785*38fd1498Szrj     name = general_mem;
786*38fd1498Szrj 
787*38fd1498Szrj   if (exp && validate_exp (exp, name, loc))
788*38fd1498Szrj     return;
789*38fd1498Szrj 
790*38fd1498Szrj   for (p = name; *p; p++)
791*38fd1498Szrj     if (!ISALNUM (*p))
792*38fd1498Szrj       {
793*38fd1498Szrj 	if (*p == '<' || *p == '>' || *p == '_')
794*38fd1498Szrj 	  need_mangled_name = true;
795*38fd1498Szrj 	else
796*38fd1498Szrj 	  {
797*38fd1498Szrj 	    error_at (loc, "constraint name '%s' must be composed of letters,"
798*38fd1498Szrj 		      " digits, underscores, and angle brackets", name);
799*38fd1498Szrj 	    return;
800*38fd1498Szrj 	  }
801*38fd1498Szrj       }
802*38fd1498Szrj 
803*38fd1498Szrj   if (strchr (generic_constraint_letters, name[0]))
804*38fd1498Szrj     {
805*38fd1498Szrj       if (name[1] == '\0')
806*38fd1498Szrj 	error_at (loc, "constraint letter '%s' cannot be "
807*38fd1498Szrj 		  "redefined by the machine description", name);
808*38fd1498Szrj       else
809*38fd1498Szrj 	error_at (loc, "constraint name '%s' cannot be defined by the machine"
810*38fd1498Szrj 		  " description, as it begins with '%c'", name, name[0]);
811*38fd1498Szrj       return;
812*38fd1498Szrj     }
813*38fd1498Szrj 
814*38fd1498Szrj 
815*38fd1498Szrj   namelen = strlen (name);
816*38fd1498Szrj   slot = &constraints_by_letter_table[(unsigned int)name[0]];
817*38fd1498Szrj   for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
818*38fd1498Szrj     {
819*38fd1498Szrj       /* This causes slot to end up pointing to the
820*38fd1498Szrj 	 next_this_letter field of the last constraint with a name
821*38fd1498Szrj 	 of equal or greater length than the new constraint; hence
822*38fd1498Szrj 	 the new constraint will be inserted after all previous
823*38fd1498Szrj 	 constraints with names of the same length.  */
824*38fd1498Szrj       if ((*iter)->namelen >= namelen)
825*38fd1498Szrj 	slot = iter;
826*38fd1498Szrj 
827*38fd1498Szrj       if (!strcmp ((*iter)->name, name))
828*38fd1498Szrj 	{
829*38fd1498Szrj 	  error_at (loc, "redefinition of constraint '%s'", name);
830*38fd1498Szrj 	  message_at ((*iter)->loc, "previous definition is here");
831*38fd1498Szrj 	  return;
832*38fd1498Szrj 	}
833*38fd1498Szrj       else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
834*38fd1498Szrj 	{
835*38fd1498Szrj 	  error_at (loc, "defining constraint '%s' here", name);
836*38fd1498Szrj 	  message_at ((*iter)->loc, "renders constraint '%s' "
837*38fd1498Szrj 		      "(defined here) a prefix", (*iter)->name);
838*38fd1498Szrj 	  return;
839*38fd1498Szrj 	}
840*38fd1498Szrj       else if (!strncmp ((*iter)->name, name, namelen))
841*38fd1498Szrj 	{
842*38fd1498Szrj 	  error_at (loc, "constraint '%s' is a prefix", name);
843*38fd1498Szrj 	  message_at ((*iter)->loc, "of constraint '%s' (defined here)",
844*38fd1498Szrj 		      (*iter)->name);
845*38fd1498Szrj 	  return;
846*38fd1498Szrj 	}
847*38fd1498Szrj     }
848*38fd1498Szrj 
849*38fd1498Szrj   is_const_int = strchr (const_int_constraints, name[0]) != 0;
850*38fd1498Szrj   is_const_dbl = strchr (const_dbl_constraints, name[0]) != 0;
851*38fd1498Szrj 
852*38fd1498Szrj   if (is_const_int || is_const_dbl)
853*38fd1498Szrj     {
854*38fd1498Szrj       enum rtx_code appropriate_code
855*38fd1498Szrj 	= is_const_int ? CONST_INT : CONST_DOUBLE;
856*38fd1498Szrj 
857*38fd1498Szrj       /* Consider relaxing this requirement in the future.  */
858*38fd1498Szrj       if (regclass
859*38fd1498Szrj 	  || GET_CODE (exp) != AND
860*38fd1498Szrj 	  || GET_CODE (XEXP (exp, 0)) != MATCH_CODE
861*38fd1498Szrj 	  || strcmp (XSTR (XEXP (exp, 0), 0),
862*38fd1498Szrj 		     GET_RTX_NAME (appropriate_code)))
863*38fd1498Szrj 	{
864*38fd1498Szrj 	  if (name[1] == '\0')
865*38fd1498Szrj 	    error_at (loc, "constraint letter '%c' is reserved "
866*38fd1498Szrj 		      "for %s constraints", name[0],
867*38fd1498Szrj 		      GET_RTX_NAME (appropriate_code));
868*38fd1498Szrj 	  else
869*38fd1498Szrj 	    error_at (loc, "constraint names beginning with '%c' "
870*38fd1498Szrj 		      "(%s) are reserved for %s constraints",
871*38fd1498Szrj 		      name[0], name, GET_RTX_NAME (appropriate_code));
872*38fd1498Szrj 	  return;
873*38fd1498Szrj 	}
874*38fd1498Szrj 
875*38fd1498Szrj       if (is_memory)
876*38fd1498Szrj 	{
877*38fd1498Szrj 	  if (name[1] == '\0')
878*38fd1498Szrj 	    error_at (loc, "constraint letter '%c' cannot be a "
879*38fd1498Szrj 		      "memory constraint", name[0]);
880*38fd1498Szrj 	  else
881*38fd1498Szrj 	    error_at (loc, "constraint name '%s' begins with '%c', "
882*38fd1498Szrj 		      "and therefore cannot be a memory constraint",
883*38fd1498Szrj 		      name, name[0]);
884*38fd1498Szrj 	  return;
885*38fd1498Szrj 	}
886*38fd1498Szrj       else if (is_special_memory)
887*38fd1498Szrj 	{
888*38fd1498Szrj 	  if (name[1] == '\0')
889*38fd1498Szrj 	    error_at (loc, "constraint letter '%c' cannot be a "
890*38fd1498Szrj 		      "special memory constraint", name[0]);
891*38fd1498Szrj 	  else
892*38fd1498Szrj 	    error_at (loc, "constraint name '%s' begins with '%c', "
893*38fd1498Szrj 		      "and therefore cannot be a special memory constraint",
894*38fd1498Szrj 		      name, name[0]);
895*38fd1498Szrj 	  return;
896*38fd1498Szrj 	}
897*38fd1498Szrj       else if (is_address)
898*38fd1498Szrj 	{
899*38fd1498Szrj 	  if (name[1] == '\0')
900*38fd1498Szrj 	    error_at (loc, "constraint letter '%c' cannot be an "
901*38fd1498Szrj 		      "address constraint", name[0]);
902*38fd1498Szrj 	  else
903*38fd1498Szrj 	    error_at (loc, "constraint name '%s' begins with '%c', "
904*38fd1498Szrj 		      "and therefore cannot be an address constraint",
905*38fd1498Szrj 		      name, name[0]);
906*38fd1498Szrj 	  return;
907*38fd1498Szrj 	}
908*38fd1498Szrj     }
909*38fd1498Szrj 
910*38fd1498Szrj 
911*38fd1498Szrj   c = XOBNEW (rtl_obstack, struct constraint_data);
912*38fd1498Szrj   c->name = name;
913*38fd1498Szrj   c->c_name = need_mangled_name ? mangle (name) : name;
914*38fd1498Szrj   c->loc = loc;
915*38fd1498Szrj   c->namelen = namelen;
916*38fd1498Szrj   c->regclass = regclass;
917*38fd1498Szrj   c->exp = exp;
918*38fd1498Szrj   c->is_register = regclass != 0;
919*38fd1498Szrj   c->is_const_int = is_const_int;
920*38fd1498Szrj   c->is_const_dbl = is_const_dbl;
921*38fd1498Szrj   c->is_extra = !(regclass || is_const_int || is_const_dbl);
922*38fd1498Szrj   c->is_memory = is_memory;
923*38fd1498Szrj   c->is_special_memory = is_special_memory;
924*38fd1498Szrj   c->is_address = is_address;
925*38fd1498Szrj   c->maybe_allows_reg = true;
926*38fd1498Szrj   c->maybe_allows_mem = true;
927*38fd1498Szrj   if (exp)
928*38fd1498Szrj     {
929*38fd1498Szrj       char codes[NUM_RTX_CODE];
930*38fd1498Szrj       compute_test_codes (exp, loc, codes);
931*38fd1498Szrj       if (!codes[REG] && !codes[SUBREG])
932*38fd1498Szrj 	c->maybe_allows_reg = false;
933*38fd1498Szrj       if (!codes[MEM])
934*38fd1498Szrj 	c->maybe_allows_mem = false;
935*38fd1498Szrj     }
936*38fd1498Szrj   c->next_this_letter = *slot;
937*38fd1498Szrj   *slot = c;
938*38fd1498Szrj 
939*38fd1498Szrj   /* Insert this constraint in the list of all constraints in textual
940*38fd1498Szrj      order.  */
941*38fd1498Szrj   c->next_textual = 0;
942*38fd1498Szrj   *last_constraint_ptr = c;
943*38fd1498Szrj   last_constraint_ptr = &c->next_textual;
944*38fd1498Szrj 
945*38fd1498Szrj   constraint_max_namelen = MAX (constraint_max_namelen, strlen (name));
946*38fd1498Szrj   have_register_constraints |= c->is_register;
947*38fd1498Szrj   have_const_int_constraints |= c->is_const_int;
948*38fd1498Szrj   have_extra_constraints |= c->is_extra;
949*38fd1498Szrj   have_memory_constraints |= c->is_memory;
950*38fd1498Szrj   have_special_memory_constraints |= c->is_special_memory;
951*38fd1498Szrj   have_address_constraints |= c->is_address;
952*38fd1498Szrj   num_constraints += 1;
953*38fd1498Szrj }
954*38fd1498Szrj 
955*38fd1498Szrj /* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT,
956*38fd1498Szrj    DEFINE_SPECIAL_MEMORY_CONSTRAINT, or DEFINE_ADDRESS_CONSTRAINT
957*38fd1498Szrj    expression, C.  */
958*38fd1498Szrj static void
process_define_constraint(md_rtx_info * info)959*38fd1498Szrj process_define_constraint (md_rtx_info *info)
960*38fd1498Szrj {
961*38fd1498Szrj   add_constraint (XSTR (info->def, 0), 0, XEXP (info->def, 2),
962*38fd1498Szrj 		  GET_CODE (info->def) == DEFINE_MEMORY_CONSTRAINT,
963*38fd1498Szrj 		  GET_CODE (info->def) == DEFINE_SPECIAL_MEMORY_CONSTRAINT,
964*38fd1498Szrj 		  GET_CODE (info->def) == DEFINE_ADDRESS_CONSTRAINT,
965*38fd1498Szrj 		  info->loc);
966*38fd1498Szrj }
967*38fd1498Szrj 
968*38fd1498Szrj /* Process a DEFINE_REGISTER_CONSTRAINT expression, C.  */
969*38fd1498Szrj static void
process_define_register_constraint(md_rtx_info * info)970*38fd1498Szrj process_define_register_constraint (md_rtx_info *info)
971*38fd1498Szrj {
972*38fd1498Szrj   add_constraint (XSTR (info->def, 0), XSTR (info->def, 1),
973*38fd1498Szrj 		  0, false, false, false, info->loc);
974*38fd1498Szrj }
975*38fd1498Szrj 
976*38fd1498Szrj /* Put the constraints into enum order.  We want to keep constraints
977*38fd1498Szrj    of the same type together so that query functions can be simple
978*38fd1498Szrj    range checks.  */
979*38fd1498Szrj static void
choose_enum_order(void)980*38fd1498Szrj choose_enum_order (void)
981*38fd1498Szrj {
982*38fd1498Szrj   struct constraint_data *c;
983*38fd1498Szrj 
984*38fd1498Szrj   enum_order = XNEWVEC (const constraint_data *, num_constraints);
985*38fd1498Szrj   unsigned int next = 0;
986*38fd1498Szrj 
987*38fd1498Szrj   register_start = next;
988*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
989*38fd1498Szrj     if (c->is_register)
990*38fd1498Szrj       enum_order[next++] = c;
991*38fd1498Szrj   register_end = next;
992*38fd1498Szrj 
993*38fd1498Szrj   satisfied_start = next;
994*38fd1498Szrj 
995*38fd1498Szrj   const_int_start = next;
996*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
997*38fd1498Szrj     if (c->is_const_int)
998*38fd1498Szrj       enum_order[next++] = c;
999*38fd1498Szrj   const_int_end = next;
1000*38fd1498Szrj 
1001*38fd1498Szrj   memory_start = next;
1002*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1003*38fd1498Szrj     if (c->is_memory)
1004*38fd1498Szrj       enum_order[next++] = c;
1005*38fd1498Szrj   memory_end = next;
1006*38fd1498Szrj 
1007*38fd1498Szrj   special_memory_start = next;
1008*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1009*38fd1498Szrj     if (c->is_special_memory)
1010*38fd1498Szrj       enum_order[next++] = c;
1011*38fd1498Szrj   special_memory_end = next;
1012*38fd1498Szrj 
1013*38fd1498Szrj   address_start = next;
1014*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1015*38fd1498Szrj     if (c->is_address)
1016*38fd1498Szrj       enum_order[next++] = c;
1017*38fd1498Szrj   address_end = next;
1018*38fd1498Szrj 
1019*38fd1498Szrj   maybe_allows_none_start = next;
1020*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1021*38fd1498Szrj     if (!c->is_register && !c->is_const_int && !c->is_memory
1022*38fd1498Szrj 	&& !c->is_special_memory && !c->is_address
1023*38fd1498Szrj 	&& !c->maybe_allows_reg && !c->maybe_allows_mem)
1024*38fd1498Szrj       enum_order[next++] = c;
1025*38fd1498Szrj   maybe_allows_none_end = next;
1026*38fd1498Szrj 
1027*38fd1498Szrj   maybe_allows_reg_start = next;
1028*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1029*38fd1498Szrj     if (!c->is_register && !c->is_const_int && !c->is_memory
1030*38fd1498Szrj 	&& !c->is_special_memory && !c->is_address
1031*38fd1498Szrj 	&& c->maybe_allows_reg && !c->maybe_allows_mem)
1032*38fd1498Szrj       enum_order[next++] = c;
1033*38fd1498Szrj   maybe_allows_reg_end = next;
1034*38fd1498Szrj 
1035*38fd1498Szrj   maybe_allows_mem_start = next;
1036*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1037*38fd1498Szrj     if (!c->is_register && !c->is_const_int && !c->is_memory
1038*38fd1498Szrj 	&& !c->is_special_memory && !c->is_address
1039*38fd1498Szrj 	&& !c->maybe_allows_reg && c->maybe_allows_mem)
1040*38fd1498Szrj       enum_order[next++] = c;
1041*38fd1498Szrj   maybe_allows_mem_end = next;
1042*38fd1498Szrj 
1043*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1044*38fd1498Szrj     if (!c->is_register && !c->is_const_int && !c->is_memory
1045*38fd1498Szrj 	&& !c->is_special_memory && !c->is_address
1046*38fd1498Szrj 	&& c->maybe_allows_reg && c->maybe_allows_mem)
1047*38fd1498Szrj       enum_order[next++] = c;
1048*38fd1498Szrj   gcc_assert (next == num_constraints);
1049*38fd1498Szrj }
1050*38fd1498Szrj 
1051*38fd1498Szrj /* Write out an enumeration with one entry per machine-specific
1052*38fd1498Szrj    constraint.  */
1053*38fd1498Szrj static void
write_enum_constraint_num(void)1054*38fd1498Szrj write_enum_constraint_num (void)
1055*38fd1498Szrj {
1056*38fd1498Szrj   fputs ("#define CONSTRAINT_NUM_DEFINED_P 1\n", stdout);
1057*38fd1498Szrj   fputs ("enum constraint_num\n"
1058*38fd1498Szrj 	 "{\n"
1059*38fd1498Szrj 	 "  CONSTRAINT__UNKNOWN = 0", stdout);
1060*38fd1498Szrj   for (unsigned int i = 0; i < num_constraints; ++i)
1061*38fd1498Szrj     printf (",\n  CONSTRAINT_%s", enum_order[i]->c_name);
1062*38fd1498Szrj   puts (",\n  CONSTRAINT__LIMIT\n};\n");
1063*38fd1498Szrj }
1064*38fd1498Szrj 
1065*38fd1498Szrj /* Write out a function which looks at a string and determines what
1066*38fd1498Szrj    constraint name, if any, it begins with.  */
1067*38fd1498Szrj static void
write_lookup_constraint_1(void)1068*38fd1498Szrj write_lookup_constraint_1 (void)
1069*38fd1498Szrj {
1070*38fd1498Szrj   unsigned int i;
1071*38fd1498Szrj   puts ("enum constraint_num\n"
1072*38fd1498Szrj 	"lookup_constraint_1 (const char *str)\n"
1073*38fd1498Szrj 	"{\n"
1074*38fd1498Szrj 	"  switch (str[0])\n"
1075*38fd1498Szrj 	"    {");
1076*38fd1498Szrj 
1077*38fd1498Szrj   for (i = 0; i < ARRAY_SIZE (constraints_by_letter_table); i++)
1078*38fd1498Szrj     {
1079*38fd1498Szrj       struct constraint_data *c = constraints_by_letter_table[i];
1080*38fd1498Szrj       if (!c)
1081*38fd1498Szrj 	continue;
1082*38fd1498Szrj 
1083*38fd1498Szrj       printf ("    case '%c':\n", i);
1084*38fd1498Szrj       if (c->namelen == 1)
1085*38fd1498Szrj 	printf ("      return CONSTRAINT_%s;\n", c->c_name);
1086*38fd1498Szrj       else
1087*38fd1498Szrj 	{
1088*38fd1498Szrj 	  do
1089*38fd1498Szrj 	    {
1090*38fd1498Szrj 	      printf ("      if (!strncmp (str + 1, \"%s\", %lu))\n"
1091*38fd1498Szrj 		      "        return CONSTRAINT_%s;\n",
1092*38fd1498Szrj 		      c->name + 1, (unsigned long int) c->namelen - 1,
1093*38fd1498Szrj 		      c->c_name);
1094*38fd1498Szrj 	      c = c->next_this_letter;
1095*38fd1498Szrj 	    }
1096*38fd1498Szrj 	  while (c);
1097*38fd1498Szrj 	  puts ("      break;");
1098*38fd1498Szrj 	}
1099*38fd1498Szrj     }
1100*38fd1498Szrj 
1101*38fd1498Szrj   puts ("    default: break;\n"
1102*38fd1498Szrj 	"    }\n"
1103*38fd1498Szrj 	"  return CONSTRAINT__UNKNOWN;\n"
1104*38fd1498Szrj 	"}\n");
1105*38fd1498Szrj }
1106*38fd1498Szrj 
1107*38fd1498Szrj /* Write out an array that maps single-letter characters to their
1108*38fd1498Szrj    constraints (if that fits in a character) or 255 if lookup_constraint_1
1109*38fd1498Szrj    must be called.  */
1110*38fd1498Szrj static void
write_lookup_constraint_array(void)1111*38fd1498Szrj write_lookup_constraint_array (void)
1112*38fd1498Szrj {
1113*38fd1498Szrj   unsigned int i;
1114*38fd1498Szrj   printf ("const unsigned char lookup_constraint_array[] = {\n  ");
1115*38fd1498Szrj   for (i = 0; i < ARRAY_SIZE (constraints_by_letter_table); i++)
1116*38fd1498Szrj     {
1117*38fd1498Szrj       if (i != 0)
1118*38fd1498Szrj 	printf (",\n  ");
1119*38fd1498Szrj       struct constraint_data *c = constraints_by_letter_table[i];
1120*38fd1498Szrj       if (!c)
1121*38fd1498Szrj 	printf ("CONSTRAINT__UNKNOWN");
1122*38fd1498Szrj       else if (c->namelen == 1)
1123*38fd1498Szrj 	printf ("MIN ((int) CONSTRAINT_%s, (int) UCHAR_MAX)", c->c_name);
1124*38fd1498Szrj       else
1125*38fd1498Szrj 	printf ("UCHAR_MAX");
1126*38fd1498Szrj     }
1127*38fd1498Szrj   printf ("\n};\n\n");
1128*38fd1498Szrj }
1129*38fd1498Szrj 
1130*38fd1498Szrj /* Write out a function which looks at a string and determines what
1131*38fd1498Szrj    the constraint name length is.  */
1132*38fd1498Szrj static void
write_insn_constraint_len(void)1133*38fd1498Szrj write_insn_constraint_len (void)
1134*38fd1498Szrj {
1135*38fd1498Szrj   unsigned int i;
1136*38fd1498Szrj 
1137*38fd1498Szrj   puts ("static inline size_t\n"
1138*38fd1498Szrj 	"insn_constraint_len (char fc, const char *str ATTRIBUTE_UNUSED)\n"
1139*38fd1498Szrj 	"{\n"
1140*38fd1498Szrj 	"  switch (fc)\n"
1141*38fd1498Szrj 	"    {");
1142*38fd1498Szrj 
1143*38fd1498Szrj   for (i = 0; i < ARRAY_SIZE (constraints_by_letter_table); i++)
1144*38fd1498Szrj     {
1145*38fd1498Szrj       struct constraint_data *c = constraints_by_letter_table[i];
1146*38fd1498Szrj 
1147*38fd1498Szrj       if (!c
1148*38fd1498Szrj       	  || c->namelen == 1)
1149*38fd1498Szrj 	continue;
1150*38fd1498Szrj 
1151*38fd1498Szrj       /* Constraints with multiple characters should have the same
1152*38fd1498Szrj 	 length.  */
1153*38fd1498Szrj       {
1154*38fd1498Szrj 	struct constraint_data *c2 = c->next_this_letter;
1155*38fd1498Szrj 	size_t len = c->namelen;
1156*38fd1498Szrj 	while (c2)
1157*38fd1498Szrj 	  {
1158*38fd1498Szrj 	    if (c2->namelen != len)
1159*38fd1498Szrj 	      error ("Multi-letter constraints with first letter '%c' "
1160*38fd1498Szrj 		     "should have same length", i);
1161*38fd1498Szrj 	    c2 = c2->next_this_letter;
1162*38fd1498Szrj 	  }
1163*38fd1498Szrj       }
1164*38fd1498Szrj 
1165*38fd1498Szrj       printf ("    case '%c': return %lu;\n",
1166*38fd1498Szrj 	      i, (unsigned long int) c->namelen);
1167*38fd1498Szrj     }
1168*38fd1498Szrj 
1169*38fd1498Szrj   puts ("    default: break;\n"
1170*38fd1498Szrj 	"    }\n"
1171*38fd1498Szrj 	"  return 1;\n"
1172*38fd1498Szrj 	"}\n");
1173*38fd1498Szrj }
1174*38fd1498Szrj 
1175*38fd1498Szrj /* Write out the function which computes the register class corresponding
1176*38fd1498Szrj    to a register constraint.  */
1177*38fd1498Szrj static void
write_reg_class_for_constraint_1(void)1178*38fd1498Szrj write_reg_class_for_constraint_1 (void)
1179*38fd1498Szrj {
1180*38fd1498Szrj   struct constraint_data *c;
1181*38fd1498Szrj 
1182*38fd1498Szrj   puts ("enum reg_class\n"
1183*38fd1498Szrj 	"reg_class_for_constraint_1 (enum constraint_num c)\n"
1184*38fd1498Szrj 	"{\n"
1185*38fd1498Szrj 	"  switch (c)\n"
1186*38fd1498Szrj 	"    {");
1187*38fd1498Szrj 
1188*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1189*38fd1498Szrj     if (c->is_register)
1190*38fd1498Szrj       printf ("    case CONSTRAINT_%s: return %s;\n", c->c_name, c->regclass);
1191*38fd1498Szrj 
1192*38fd1498Szrj   puts ("    default: break;\n"
1193*38fd1498Szrj 	"    }\n"
1194*38fd1498Szrj 	"  return NO_REGS;\n"
1195*38fd1498Szrj 	"}\n");
1196*38fd1498Szrj }
1197*38fd1498Szrj 
1198*38fd1498Szrj /* Write out the functions which compute whether a given value matches
1199*38fd1498Szrj    a given non-register constraint.  */
1200*38fd1498Szrj static void
write_tm_constrs_h(void)1201*38fd1498Szrj write_tm_constrs_h (void)
1202*38fd1498Szrj {
1203*38fd1498Szrj   struct constraint_data *c;
1204*38fd1498Szrj 
1205*38fd1498Szrj   printf ("\
1206*38fd1498Szrj /* Generated automatically by the program '%s'\n\
1207*38fd1498Szrj    from the machine description file '%s'.  */\n\n", progname,
1208*38fd1498Szrj 	  md_reader_ptr->get_top_level_filename ());
1209*38fd1498Szrj 
1210*38fd1498Szrj   puts ("\
1211*38fd1498Szrj #ifndef GCC_TM_CONSTRS_H\n\
1212*38fd1498Szrj #define GCC_TM_CONSTRS_H\n");
1213*38fd1498Szrj 
1214*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1215*38fd1498Szrj     if (!c->is_register)
1216*38fd1498Szrj       {
1217*38fd1498Szrj 	bool needs_ival = needs_variable (c->exp, "ival");
1218*38fd1498Szrj 	bool needs_hval = needs_variable (c->exp, "hval");
1219*38fd1498Szrj 	bool needs_lval = needs_variable (c->exp, "lval");
1220*38fd1498Szrj 	bool needs_rval = needs_variable (c->exp, "rval");
1221*38fd1498Szrj 	bool needs_mode = (needs_variable (c->exp, "mode")
1222*38fd1498Szrj 			   || needs_hval || needs_lval || needs_rval);
1223*38fd1498Szrj 	bool needs_op = (needs_variable (c->exp, "op")
1224*38fd1498Szrj 			 || needs_ival || needs_mode);
1225*38fd1498Szrj 
1226*38fd1498Szrj 	printf ("static inline bool\n"
1227*38fd1498Szrj 		"satisfies_constraint_%s (rtx %s)\n"
1228*38fd1498Szrj 		"{\n", c->c_name,
1229*38fd1498Szrj 		needs_op ? "op" : "ARG_UNUSED (op)");
1230*38fd1498Szrj 	if (needs_mode)
1231*38fd1498Szrj 	  puts ("  machine_mode mode = GET_MODE (op);");
1232*38fd1498Szrj 	if (needs_ival)
1233*38fd1498Szrj 	  puts ("  HOST_WIDE_INT ival = 0;");
1234*38fd1498Szrj 	if (needs_hval)
1235*38fd1498Szrj 	  puts ("  HOST_WIDE_INT hval = 0;");
1236*38fd1498Szrj 	if (needs_lval)
1237*38fd1498Szrj 	  puts ("  unsigned HOST_WIDE_INT lval = 0;");
1238*38fd1498Szrj 	if (needs_rval)
1239*38fd1498Szrj 	  puts ("  const REAL_VALUE_TYPE *rval = 0;");
1240*38fd1498Szrj 
1241*38fd1498Szrj 	if (needs_ival)
1242*38fd1498Szrj 	  puts ("  if (CONST_INT_P (op))\n"
1243*38fd1498Szrj 		"    ival = INTVAL (op);");
1244*38fd1498Szrj #if TARGET_SUPPORTS_WIDE_INT
1245*38fd1498Szrj 	if (needs_lval || needs_hval)
1246*38fd1498Szrj 	  error ("you can't use lval or hval");
1247*38fd1498Szrj #else
1248*38fd1498Szrj 	if (needs_hval)
1249*38fd1498Szrj 	  puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
1250*38fd1498Szrj 		"    hval = CONST_DOUBLE_HIGH (op);");
1251*38fd1498Szrj 	if (needs_lval)
1252*38fd1498Szrj 	  puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
1253*38fd1498Szrj 		"    lval = CONST_DOUBLE_LOW (op);");
1254*38fd1498Szrj #endif
1255*38fd1498Szrj 	if (needs_rval)
1256*38fd1498Szrj 	  puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode != VOIDmode)"
1257*38fd1498Szrj 		"    rval = CONST_DOUBLE_REAL_VALUE (op);");
1258*38fd1498Szrj 
1259*38fd1498Szrj 	write_predicate_stmts (c->exp);
1260*38fd1498Szrj 	fputs ("}\n", stdout);
1261*38fd1498Szrj       }
1262*38fd1498Szrj   puts ("#endif /* tm-constrs.h */");
1263*38fd1498Szrj }
1264*38fd1498Szrj 
1265*38fd1498Szrj /* Write out the wrapper function, constraint_satisfied_p, that maps
1266*38fd1498Szrj    a CONSTRAINT_xxx constant to one of the predicate functions generated
1267*38fd1498Szrj    above.  */
1268*38fd1498Szrj static void
write_constraint_satisfied_p_array(void)1269*38fd1498Szrj write_constraint_satisfied_p_array (void)
1270*38fd1498Szrj {
1271*38fd1498Szrj   if (satisfied_start == num_constraints)
1272*38fd1498Szrj     return;
1273*38fd1498Szrj 
1274*38fd1498Szrj   printf ("bool (*constraint_satisfied_p_array[]) (rtx) = {\n  ");
1275*38fd1498Szrj   for (unsigned int i = satisfied_start; i < num_constraints; ++i)
1276*38fd1498Szrj     {
1277*38fd1498Szrj       if (i != satisfied_start)
1278*38fd1498Szrj 	printf (",\n  ");
1279*38fd1498Szrj       printf ("satisfies_constraint_%s", enum_order[i]->c_name);
1280*38fd1498Szrj     }
1281*38fd1498Szrj   printf ("\n};\n\n");
1282*38fd1498Szrj }
1283*38fd1498Szrj 
1284*38fd1498Szrj /* Write out the function which computes whether a given value matches
1285*38fd1498Szrj    a given CONST_INT constraint.  This doesn't just forward to
1286*38fd1498Szrj    constraint_satisfied_p because caller passes the INTVAL, not the RTX.  */
1287*38fd1498Szrj static void
write_insn_const_int_ok_for_constraint(void)1288*38fd1498Szrj write_insn_const_int_ok_for_constraint (void)
1289*38fd1498Szrj {
1290*38fd1498Szrj   struct constraint_data *c;
1291*38fd1498Szrj 
1292*38fd1498Szrj   puts ("bool\n"
1293*38fd1498Szrj 	"insn_const_int_ok_for_constraint (HOST_WIDE_INT ival, "
1294*38fd1498Szrj 	                                  "enum constraint_num c)\n"
1295*38fd1498Szrj 	"{\n"
1296*38fd1498Szrj 	"  switch (c)\n"
1297*38fd1498Szrj 	"    {");
1298*38fd1498Szrj 
1299*38fd1498Szrj   FOR_ALL_CONSTRAINTS (c)
1300*38fd1498Szrj     if (c->is_const_int)
1301*38fd1498Szrj       {
1302*38fd1498Szrj 	printf ("    case CONSTRAINT_%s:\n      return ", c->c_name);
1303*38fd1498Szrj 	/* c->exp is guaranteed to be (and (match_code "const_int") (...));
1304*38fd1498Szrj 	   we know at this point that we have a const_int, so we need not
1305*38fd1498Szrj 	   bother with that part of the test.  */
1306*38fd1498Szrj 	write_predicate_expr (XEXP (c->exp, 1));
1307*38fd1498Szrj 	fputs (";\n\n", stdout);
1308*38fd1498Szrj       }
1309*38fd1498Szrj 
1310*38fd1498Szrj   puts ("    default: break;\n"
1311*38fd1498Szrj 	"    }\n"
1312*38fd1498Szrj 	"  return false;\n"
1313*38fd1498Szrj 	"}\n");
1314*38fd1498Szrj }
1315*38fd1498Szrj 
1316*38fd1498Szrj /* Write a definition for a function NAME that returns true if a given
1317*38fd1498Szrj    constraint_num is in the range [START, END).  */
1318*38fd1498Szrj static void
write_range_function(const char * name,unsigned int start,unsigned int end)1319*38fd1498Szrj write_range_function (const char *name, unsigned int start, unsigned int end)
1320*38fd1498Szrj {
1321*38fd1498Szrj   printf ("static inline bool\n");
1322*38fd1498Szrj   if (start != end)
1323*38fd1498Szrj     printf ("%s (enum constraint_num c)\n"
1324*38fd1498Szrj 	    "{\n"
1325*38fd1498Szrj 	    "  return c >= CONSTRAINT_%s && c <= CONSTRAINT_%s;\n"
1326*38fd1498Szrj 	    "}\n\n",
1327*38fd1498Szrj 	    name, enum_order[start]->c_name, enum_order[end - 1]->c_name);
1328*38fd1498Szrj   else
1329*38fd1498Szrj     printf ("%s (enum constraint_num)\n"
1330*38fd1498Szrj 	    "{\n"
1331*38fd1498Szrj 	    "  return false;\n"
1332*38fd1498Szrj 	    "}\n\n", name);
1333*38fd1498Szrj }
1334*38fd1498Szrj 
1335*38fd1498Szrj /* Write a definition for insn_extra_constraint_allows_reg_mem function.  */
1336*38fd1498Szrj static void
write_allows_reg_mem_function(void)1337*38fd1498Szrj write_allows_reg_mem_function (void)
1338*38fd1498Szrj {
1339*38fd1498Szrj   printf ("static inline void\n"
1340*38fd1498Szrj 	  "insn_extra_constraint_allows_reg_mem (enum constraint_num c,\n"
1341*38fd1498Szrj 	  "\t\t\t\t      bool *allows_reg, bool *allows_mem)\n"
1342*38fd1498Szrj 	  "{\n");
1343*38fd1498Szrj   if (maybe_allows_none_start != maybe_allows_none_end)
1344*38fd1498Szrj     printf ("  if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n"
1345*38fd1498Szrj 	    "    return;\n",
1346*38fd1498Szrj 	    enum_order[maybe_allows_none_start]->c_name,
1347*38fd1498Szrj 	    enum_order[maybe_allows_none_end - 1]->c_name);
1348*38fd1498Szrj   if (maybe_allows_reg_start != maybe_allows_reg_end)
1349*38fd1498Szrj     printf ("  if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n"
1350*38fd1498Szrj 	    "    {\n"
1351*38fd1498Szrj 	    "      *allows_reg = true;\n"
1352*38fd1498Szrj 	    "      return;\n"
1353*38fd1498Szrj 	    "    }\n",
1354*38fd1498Szrj 	    enum_order[maybe_allows_reg_start]->c_name,
1355*38fd1498Szrj 	    enum_order[maybe_allows_reg_end - 1]->c_name);
1356*38fd1498Szrj   if (maybe_allows_mem_start != maybe_allows_mem_end)
1357*38fd1498Szrj     printf ("  if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n"
1358*38fd1498Szrj 	    "    {\n"
1359*38fd1498Szrj 	    "      *allows_mem = true;\n"
1360*38fd1498Szrj 	    "      return;\n"
1361*38fd1498Szrj 	    "    }\n",
1362*38fd1498Szrj 	    enum_order[maybe_allows_mem_start]->c_name,
1363*38fd1498Szrj 	    enum_order[maybe_allows_mem_end - 1]->c_name);
1364*38fd1498Szrj   printf ("  (void) c;\n"
1365*38fd1498Szrj 	  "  *allows_reg = true;\n"
1366*38fd1498Szrj 	  "  *allows_mem = true;\n"
1367*38fd1498Szrj 	  "}\n\n");
1368*38fd1498Szrj }
1369*38fd1498Szrj 
1370*38fd1498Szrj /* VEC is a list of key/value pairs, with the keys being lower bounds
1371*38fd1498Szrj    of a range.  Output a decision tree that handles the keys covered by
1372*38fd1498Szrj    [VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s.
1373*38fd1498Szrj    INDENT is the number of spaces to indent the code.  */
1374*38fd1498Szrj static void
print_type_tree(const vec<std::pair<unsigned int,const char * >> & vec,unsigned int start,unsigned int end,const char * fallback,unsigned int indent)1375*38fd1498Szrj print_type_tree (const vec <std::pair <unsigned int, const char *> > &vec,
1376*38fd1498Szrj 		 unsigned int start, unsigned int end, const char *fallback,
1377*38fd1498Szrj 		 unsigned int indent)
1378*38fd1498Szrj {
1379*38fd1498Szrj   while (start < end)
1380*38fd1498Szrj     {
1381*38fd1498Szrj       unsigned int mid = (start + end) / 2;
1382*38fd1498Szrj       printf ("%*sif (c >= CONSTRAINT_%s)\n",
1383*38fd1498Szrj 	      indent, "", enum_order[vec[mid].first]->c_name);
1384*38fd1498Szrj       if (mid + 1 == end)
1385*38fd1498Szrj 	print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 2);
1386*38fd1498Szrj       else
1387*38fd1498Szrj 	{
1388*38fd1498Szrj 	  printf ("%*s{\n", indent + 2, "");
1389*38fd1498Szrj 	  print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 4);
1390*38fd1498Szrj 	  printf ("%*s}\n", indent + 2, "");
1391*38fd1498Szrj 	}
1392*38fd1498Szrj       end = mid;
1393*38fd1498Szrj     }
1394*38fd1498Szrj   printf ("%*sreturn %s;\n", indent, "", fallback);
1395*38fd1498Szrj }
1396*38fd1498Szrj 
1397*38fd1498Szrj /* Write tm-preds.h.  Unfortunately, it is impossible to forward-declare
1398*38fd1498Szrj    an enumeration in portable C, so we have to condition all these
1399*38fd1498Szrj    prototypes on HAVE_MACHINE_MODES.  */
1400*38fd1498Szrj static void
write_tm_preds_h(void)1401*38fd1498Szrj write_tm_preds_h (void)
1402*38fd1498Szrj {
1403*38fd1498Szrj   struct pred_data *p;
1404*38fd1498Szrj 
1405*38fd1498Szrj   printf ("\
1406*38fd1498Szrj /* Generated automatically by the program '%s'\n\
1407*38fd1498Szrj    from the machine description file '%s'.  */\n\n", progname,
1408*38fd1498Szrj 	  md_reader_ptr->get_top_level_filename ());
1409*38fd1498Szrj 
1410*38fd1498Szrj   puts ("\
1411*38fd1498Szrj #ifndef GCC_TM_PREDS_H\n\
1412*38fd1498Szrj #define GCC_TM_PREDS_H\n\
1413*38fd1498Szrj \n\
1414*38fd1498Szrj #ifdef HAVE_MACHINE_MODES");
1415*38fd1498Szrj 
1416*38fd1498Szrj   FOR_ALL_PREDICATES (p)
1417*38fd1498Szrj     printf ("extern int %s (rtx, machine_mode);\n", p->name);
1418*38fd1498Szrj 
1419*38fd1498Szrj   puts ("#endif /* HAVE_MACHINE_MODES */\n");
1420*38fd1498Szrj 
1421*38fd1498Szrj   if (constraint_max_namelen > 0)
1422*38fd1498Szrj     {
1423*38fd1498Szrj       write_enum_constraint_num ();
1424*38fd1498Szrj       puts ("extern enum constraint_num lookup_constraint_1 (const char *);\n"
1425*38fd1498Szrj 	    "extern const unsigned char lookup_constraint_array[];\n"
1426*38fd1498Szrj 	    "\n"
1427*38fd1498Szrj 	    "/* Return the constraint at the beginning of P, or"
1428*38fd1498Szrj 	    " CONSTRAINT__UNKNOWN if it\n"
1429*38fd1498Szrj 	    "   isn't recognized.  */\n"
1430*38fd1498Szrj 	    "\n"
1431*38fd1498Szrj 	    "static inline enum constraint_num\n"
1432*38fd1498Szrj 	    "lookup_constraint (const char *p)\n"
1433*38fd1498Szrj 	    "{\n"
1434*38fd1498Szrj 	    "  unsigned int index = lookup_constraint_array"
1435*38fd1498Szrj 	    "[(unsigned char) *p];\n"
1436*38fd1498Szrj 	    "  return (index == UCHAR_MAX\n"
1437*38fd1498Szrj 	    "          ? lookup_constraint_1 (p)\n"
1438*38fd1498Szrj 	    "          : (enum constraint_num) index);\n"
1439*38fd1498Szrj 	    "}\n");
1440*38fd1498Szrj       if (satisfied_start == num_constraints)
1441*38fd1498Szrj 	puts ("/* Return true if X satisfies constraint C.  */\n"
1442*38fd1498Szrj 	      "\n"
1443*38fd1498Szrj 	      "static inline bool\n"
1444*38fd1498Szrj 	      "constraint_satisfied_p (rtx, enum constraint_num)\n"
1445*38fd1498Szrj 	      "{\n"
1446*38fd1498Szrj 	      "  return false;\n"
1447*38fd1498Szrj 	      "}\n");
1448*38fd1498Szrj       else
1449*38fd1498Szrj 	printf ("extern bool (*constraint_satisfied_p_array[]) (rtx);\n"
1450*38fd1498Szrj 		"\n"
1451*38fd1498Szrj 		"/* Return true if X satisfies constraint C.  */\n"
1452*38fd1498Szrj 		"\n"
1453*38fd1498Szrj 		"static inline bool\n"
1454*38fd1498Szrj 		"constraint_satisfied_p (rtx x, enum constraint_num c)\n"
1455*38fd1498Szrj 		"{\n"
1456*38fd1498Szrj 		"  int i = (int) c - (int) CONSTRAINT_%s;\n"
1457*38fd1498Szrj 		"  return i >= 0 && constraint_satisfied_p_array[i] (x);\n"
1458*38fd1498Szrj 		"}\n"
1459*38fd1498Szrj 		"\n",
1460*38fd1498Szrj 		enum_order[satisfied_start]->name);
1461*38fd1498Szrj 
1462*38fd1498Szrj       write_range_function ("insn_extra_register_constraint",
1463*38fd1498Szrj 			    register_start, register_end);
1464*38fd1498Szrj       write_range_function ("insn_extra_memory_constraint",
1465*38fd1498Szrj 			    memory_start, memory_end);
1466*38fd1498Szrj       write_range_function ("insn_extra_special_memory_constraint",
1467*38fd1498Szrj 			    special_memory_start, special_memory_end);
1468*38fd1498Szrj       write_range_function ("insn_extra_address_constraint",
1469*38fd1498Szrj 			    address_start, address_end);
1470*38fd1498Szrj       write_allows_reg_mem_function ();
1471*38fd1498Szrj 
1472*38fd1498Szrj       if (constraint_max_namelen > 1)
1473*38fd1498Szrj         {
1474*38fd1498Szrj 	  write_insn_constraint_len ();
1475*38fd1498Szrj 	  puts ("#define CONSTRAINT_LEN(c_,s_) "
1476*38fd1498Szrj 		"insn_constraint_len (c_,s_)\n");
1477*38fd1498Szrj 	}
1478*38fd1498Szrj       else
1479*38fd1498Szrj 	puts ("#define CONSTRAINT_LEN(c_,s_) 1\n");
1480*38fd1498Szrj       if (have_register_constraints)
1481*38fd1498Szrj 	puts ("extern enum reg_class reg_class_for_constraint_1 "
1482*38fd1498Szrj 	      "(enum constraint_num);\n"
1483*38fd1498Szrj 	      "\n"
1484*38fd1498Szrj 	      "static inline enum reg_class\n"
1485*38fd1498Szrj 	      "reg_class_for_constraint (enum constraint_num c)\n"
1486*38fd1498Szrj 	      "{\n"
1487*38fd1498Szrj 	      "  if (insn_extra_register_constraint (c))\n"
1488*38fd1498Szrj 	      "    return reg_class_for_constraint_1 (c);\n"
1489*38fd1498Szrj 	      "  return NO_REGS;\n"
1490*38fd1498Szrj 	      "}\n");
1491*38fd1498Szrj       else
1492*38fd1498Szrj 	puts ("static inline enum reg_class\n"
1493*38fd1498Szrj 	      "reg_class_for_constraint (enum constraint_num)\n"
1494*38fd1498Szrj 	      "{\n"
1495*38fd1498Szrj 	      "  return NO_REGS;\n"
1496*38fd1498Szrj 	      "}\n");
1497*38fd1498Szrj       if (have_const_int_constraints)
1498*38fd1498Szrj 	puts ("extern bool insn_const_int_ok_for_constraint "
1499*38fd1498Szrj 	      "(HOST_WIDE_INT, enum constraint_num);\n"
1500*38fd1498Szrj 	      "#define CONST_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n"
1501*38fd1498Szrj 	      "    insn_const_int_ok_for_constraint (v_, "
1502*38fd1498Szrj 	      "lookup_constraint (s_))\n");
1503*38fd1498Szrj       else
1504*38fd1498Szrj 	puts ("static inline bool\n"
1505*38fd1498Szrj 	      "insn_const_int_ok_for_constraint (HOST_WIDE_INT,"
1506*38fd1498Szrj 	      " enum constraint_num)\n"
1507*38fd1498Szrj 	      "{\n"
1508*38fd1498Szrj 	      "  return false;\n"
1509*38fd1498Szrj 	      "}\n");
1510*38fd1498Szrj 
1511*38fd1498Szrj       puts ("enum constraint_type\n"
1512*38fd1498Szrj 	    "{\n"
1513*38fd1498Szrj 	    "  CT_REGISTER,\n"
1514*38fd1498Szrj 	    "  CT_CONST_INT,\n"
1515*38fd1498Szrj 	    "  CT_MEMORY,\n"
1516*38fd1498Szrj 	    "  CT_SPECIAL_MEMORY,\n"
1517*38fd1498Szrj 	    "  CT_ADDRESS,\n"
1518*38fd1498Szrj 	    "  CT_FIXED_FORM\n"
1519*38fd1498Szrj 	    "};\n"
1520*38fd1498Szrj 	    "\n"
1521*38fd1498Szrj 	    "static inline enum constraint_type\n"
1522*38fd1498Szrj 	    "get_constraint_type (enum constraint_num c)\n"
1523*38fd1498Szrj 	    "{");
1524*38fd1498Szrj       auto_vec <std::pair <unsigned int, const char *>, 4> values;
1525*38fd1498Szrj       if (const_int_start != const_int_end)
1526*38fd1498Szrj 	values.safe_push (std::make_pair (const_int_start, "CT_CONST_INT"));
1527*38fd1498Szrj       if (memory_start != memory_end)
1528*38fd1498Szrj 	values.safe_push (std::make_pair (memory_start, "CT_MEMORY"));
1529*38fd1498Szrj       if (special_memory_start != special_memory_end)
1530*38fd1498Szrj 	values.safe_push (std::make_pair (special_memory_start, "CT_SPECIAL_MEMORY"));
1531*38fd1498Szrj       if (address_start != address_end)
1532*38fd1498Szrj 	values.safe_push (std::make_pair (address_start, "CT_ADDRESS"));
1533*38fd1498Szrj       if (address_end != num_constraints)
1534*38fd1498Szrj 	values.safe_push (std::make_pair (address_end, "CT_FIXED_FORM"));
1535*38fd1498Szrj       print_type_tree (values, 0, values.length (), "CT_REGISTER", 2);
1536*38fd1498Szrj       puts ("}");
1537*38fd1498Szrj     }
1538*38fd1498Szrj 
1539*38fd1498Szrj   puts ("#endif /* tm-preds.h */");
1540*38fd1498Szrj }
1541*38fd1498Szrj 
1542*38fd1498Szrj /* Write insn-preds.c.
1543*38fd1498Szrj    N.B. the list of headers to include was copied from genrecog; it
1544*38fd1498Szrj    may not be ideal.
1545*38fd1498Szrj 
1546*38fd1498Szrj    FUTURE: Write #line markers referring back to the machine
1547*38fd1498Szrj    description.  (Can't practically do this now since we don't know
1548*38fd1498Szrj    the line number of the C block - just the line number of the enclosing
1549*38fd1498Szrj    expression.)  */
1550*38fd1498Szrj static void
write_insn_preds_c(void)1551*38fd1498Szrj write_insn_preds_c (void)
1552*38fd1498Szrj {
1553*38fd1498Szrj   struct pred_data *p;
1554*38fd1498Szrj 
1555*38fd1498Szrj   printf ("\
1556*38fd1498Szrj /* Generated automatically by the program '%s'\n\
1557*38fd1498Szrj    from the machine description file '%s'.  */\n\n", progname,
1558*38fd1498Szrj 	  md_reader_ptr->get_top_level_filename ());
1559*38fd1498Szrj 
1560*38fd1498Szrj   puts ("\
1561*38fd1498Szrj #define IN_TARGET_CODE 1\n\
1562*38fd1498Szrj #include \"config.h\"\n\
1563*38fd1498Szrj #include \"system.h\"\n\
1564*38fd1498Szrj #include \"coretypes.h\"\n\
1565*38fd1498Szrj #include \"backend.h\"\n\
1566*38fd1498Szrj #include \"predict.h\"\n\
1567*38fd1498Szrj #include \"tree.h\"\n\
1568*38fd1498Szrj #include \"rtl.h\"\n\
1569*38fd1498Szrj #include \"alias.h\"\n\
1570*38fd1498Szrj #include \"varasm.h\"\n\
1571*38fd1498Szrj #include \"stor-layout.h\"\n\
1572*38fd1498Szrj #include \"calls.h\"\n\
1573*38fd1498Szrj #include \"memmodel.h\"\n\
1574*38fd1498Szrj #include \"tm_p.h\"\n\
1575*38fd1498Szrj #include \"insn-config.h\"\n\
1576*38fd1498Szrj #include \"recog.h\"\n\
1577*38fd1498Szrj #include \"output.h\"\n\
1578*38fd1498Szrj #include \"flags.h\"\n\
1579*38fd1498Szrj #include \"df.h\"\n\
1580*38fd1498Szrj #include \"resource.h\"\n\
1581*38fd1498Szrj #include \"diagnostic-core.h\"\n\
1582*38fd1498Szrj #include \"reload.h\"\n\
1583*38fd1498Szrj #include \"regs.h\"\n\
1584*38fd1498Szrj #include \"emit-rtl.h\"\n\
1585*38fd1498Szrj #include \"tm-constrs.h\"\n\
1586*38fd1498Szrj #include \"target.h\"\n");
1587*38fd1498Szrj 
1588*38fd1498Szrj   FOR_ALL_PREDICATES (p)
1589*38fd1498Szrj     write_one_predicate_function (p);
1590*38fd1498Szrj 
1591*38fd1498Szrj   if (constraint_max_namelen > 0)
1592*38fd1498Szrj     {
1593*38fd1498Szrj       write_lookup_constraint_1 ();
1594*38fd1498Szrj       write_lookup_constraint_array ();
1595*38fd1498Szrj       if (have_register_constraints)
1596*38fd1498Szrj 	write_reg_class_for_constraint_1 ();
1597*38fd1498Szrj       write_constraint_satisfied_p_array ();
1598*38fd1498Szrj 
1599*38fd1498Szrj       if (have_const_int_constraints)
1600*38fd1498Szrj 	write_insn_const_int_ok_for_constraint ();
1601*38fd1498Szrj     }
1602*38fd1498Szrj }
1603*38fd1498Szrj 
1604*38fd1498Szrj /* Argument parsing.  */
1605*38fd1498Szrj static bool gen_header;
1606*38fd1498Szrj static bool gen_constrs;
1607*38fd1498Szrj 
1608*38fd1498Szrj static bool
parse_option(const char * opt)1609*38fd1498Szrj parse_option (const char *opt)
1610*38fd1498Szrj {
1611*38fd1498Szrj   if (!strcmp (opt, "-h"))
1612*38fd1498Szrj     {
1613*38fd1498Szrj       gen_header = true;
1614*38fd1498Szrj       return 1;
1615*38fd1498Szrj     }
1616*38fd1498Szrj   else if (!strcmp (opt, "-c"))
1617*38fd1498Szrj     {
1618*38fd1498Szrj       gen_constrs = true;
1619*38fd1498Szrj       return 1;
1620*38fd1498Szrj     }
1621*38fd1498Szrj   else
1622*38fd1498Szrj     return 0;
1623*38fd1498Szrj }
1624*38fd1498Szrj 
1625*38fd1498Szrj /* Master control.  */
1626*38fd1498Szrj int
main(int argc,const char ** argv)1627*38fd1498Szrj main (int argc, const char **argv)
1628*38fd1498Szrj {
1629*38fd1498Szrj   progname = argv[0];
1630*38fd1498Szrj   if (argc <= 1)
1631*38fd1498Szrj     fatal ("no input file name");
1632*38fd1498Szrj   if (!init_rtx_reader_args_cb (argc, argv, parse_option))
1633*38fd1498Szrj     return FATAL_EXIT_CODE;
1634*38fd1498Szrj 
1635*38fd1498Szrj   md_rtx_info info;
1636*38fd1498Szrj   while (read_md_rtx (&info))
1637*38fd1498Szrj     switch (GET_CODE (info.def))
1638*38fd1498Szrj       {
1639*38fd1498Szrj       case DEFINE_PREDICATE:
1640*38fd1498Szrj       case DEFINE_SPECIAL_PREDICATE:
1641*38fd1498Szrj 	process_define_predicate (&info);
1642*38fd1498Szrj 	break;
1643*38fd1498Szrj 
1644*38fd1498Szrj       case DEFINE_CONSTRAINT:
1645*38fd1498Szrj       case DEFINE_MEMORY_CONSTRAINT:
1646*38fd1498Szrj       case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
1647*38fd1498Szrj       case DEFINE_ADDRESS_CONSTRAINT:
1648*38fd1498Szrj 	process_define_constraint (&info);
1649*38fd1498Szrj 	break;
1650*38fd1498Szrj 
1651*38fd1498Szrj       case DEFINE_REGISTER_CONSTRAINT:
1652*38fd1498Szrj 	process_define_register_constraint (&info);
1653*38fd1498Szrj 	break;
1654*38fd1498Szrj 
1655*38fd1498Szrj       default:
1656*38fd1498Szrj 	break;
1657*38fd1498Szrj       }
1658*38fd1498Szrj 
1659*38fd1498Szrj   choose_enum_order ();
1660*38fd1498Szrj 
1661*38fd1498Szrj   if (gen_header)
1662*38fd1498Szrj     write_tm_preds_h ();
1663*38fd1498Szrj   else if (gen_constrs)
1664*38fd1498Szrj     write_tm_constrs_h ();
1665*38fd1498Szrj   else
1666*38fd1498Szrj     write_insn_preds_c ();
1667*38fd1498Szrj 
1668*38fd1498Szrj   if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
1669*38fd1498Szrj     return FATAL_EXIT_CODE;
1670*38fd1498Szrj 
1671*38fd1498Szrj   return SUCCESS_EXIT_CODE;
1672*38fd1498Szrj }
1673