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