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