190075Sobrien/* Generate from machine description:
2169689Skan   - prototype declarations for operand predicates (tm-preds.h)
3169689Skan   - function definitions of operand predicates, if defined new-style
4169689Skan     (insn-preds.c)
5169689Skan   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
690075Sobrien
790075SobrienThis file is part of GCC.
890075Sobrien
990075SobrienGCC is free software; you can redistribute it and/or modify
1090075Sobrienit under the terms of the GNU General Public License as published by
1190075Sobrienthe Free Software Foundation; either version 2, or (at your option)
1290075Sobrienany later version.
1390075Sobrien
1490075SobrienGCC is distributed in the hope that it will be useful,
1590075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1690075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1790075SobrienGNU General Public License for more details.
1890075Sobrien
1990075SobrienYou should have received a copy of the GNU General Public License
2090075Sobrienalong with GCC; see the file COPYING.  If not, write to
21169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
22169689SkanBoston, MA 02110-1301, USA.  */
2390075Sobrien
24132718Skan#include "bconfig.h"
2590075Sobrien#include "system.h"
26132718Skan#include "coretypes.h"
27132718Skan#include "tm.h"
2890075Sobrien#include "rtl.h"
29169689Skan#include "errors.h"
30169689Skan#include "obstack.h"
31169689Skan#include "gensupport.h"
3290075Sobrien
33169689Skan/* Given a predicate expression EXP, from form NAME at line LINENO,
34169689Skan   verify that it does not contain any RTL constructs which are not
35169689Skan   valid in predicate definitions.  Returns true if EXP is
36169689Skan   INvalid; issues error messages, caller need not.  */
37169689Skanstatic bool
38169689Skanvalidate_exp (rtx exp, const char *name, int lineno)
39169689Skan{
40169689Skan  if (exp == 0)
41169689Skan    {
42169689Skan      message_with_line (lineno, "%s: must give a predicate expression", name);
43169689Skan      return true;
44169689Skan    }
4590075Sobrien
46169689Skan  switch (GET_CODE (exp))
47169689Skan    {
48169689Skan      /* Ternary, binary, unary expressions: recurse into subexpressions.  */
49169689Skan    case IF_THEN_ELSE:
50169689Skan      if (validate_exp (XEXP (exp, 2), name, lineno))
51169689Skan	return true;
52169689Skan      /* else fall through */
53169689Skan    case AND:
54169689Skan    case IOR:
55169689Skan      if (validate_exp (XEXP (exp, 1), name, lineno))
56169689Skan	return true;
57169689Skan      /* else fall through */
58169689Skan    case NOT:
59169689Skan      return validate_exp (XEXP (exp, 0), name, lineno);
60169689Skan
61169689Skan      /* MATCH_CODE might have a syntax error in its path expression.  */
62169689Skan    case MATCH_CODE:
63169689Skan      {
64169689Skan	const char *p;
65169689Skan	for (p = XSTR (exp, 1); *p; p++)
66169689Skan	  {
67169689Skan	    if (!ISDIGIT (*p) && !ISLOWER (*p))
68169689Skan	      {
69169689Skan		message_with_line (lineno, "%s: invalid character in path "
70169689Skan				   "string '%s'", name, XSTR (exp, 1));
71169689Skan		have_error = 1;
72169689Skan		return true;
73169689Skan	      }
74169689Skan	  }
75169689Skan      }
76169689Skan      /* fall through */
77169689Skan
78169689Skan      /* These need no special checking.  */
79169689Skan    case MATCH_OPERAND:
80169689Skan    case MATCH_TEST:
81169689Skan      return false;
82169689Skan
83169689Skan    default:
84169689Skan      message_with_line (lineno,
85169689Skan			 "%s: cannot use '%s' in a predicate expression",
86169689Skan			 name, GET_RTX_NAME (GET_CODE (exp)));
87169689Skan      have_error = 1;
88169689Skan      return true;
89169689Skan    }
90169689Skan}
91169689Skan
92169689Skan/* Predicates are defined with (define_predicate) or
93169689Skan   (define_special_predicate) expressions in the machine description.  */
9490075Sobrienstatic void
95169689Skanprocess_define_predicate (rtx defn, int lineno)
9690075Sobrien{
97169689Skan  struct pred_data *pred;
98169689Skan  const char *p;
9990075Sobrien
100169689Skan  if (!ISALPHA (XSTR (defn, 0)[0]) && XSTR (defn, 0)[0] != '_')
101169689Skan    goto bad_name;
102169689Skan  for (p = XSTR (defn, 0) + 1; *p; p++)
103169689Skan    if (!ISALNUM (*p) && *p != '_')
104169689Skan      goto bad_name;
105169689Skan
106169689Skan  if (validate_exp (XEXP (defn, 1), XSTR (defn, 0), lineno))
107169689Skan    return;
108169689Skan
109169689Skan  pred = XCNEW (struct pred_data);
110169689Skan  pred->name = XSTR (defn, 0);
111169689Skan  pred->exp = XEXP (defn, 1);
112169689Skan  pred->c_block = XSTR (defn, 2);
113169689Skan
114169689Skan  if (GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
115169689Skan    pred->special = true;
116169689Skan
117169689Skan  add_predicate (pred);
118169689Skan  return;
119169689Skan
120169689Skan bad_name:
121169689Skan  message_with_line (lineno,
122169689Skan		     "%s: predicate name must be a valid C function name",
123169689Skan		     XSTR (defn, 0));
124169689Skan  have_error = 1;
125169689Skan  return;
12690075Sobrien}
12790075Sobrien
128169689Skan/* Given a predicate, if it has an embedded C block, write the block
129169689Skan   out as a static inline subroutine, and augment the RTL test with a
130169689Skan   match_test that calls that subroutine.  For instance,
131169689Skan
132169689Skan       (define_predicate "basereg_operand"
133169689Skan         (match_operand 0 "register_operand")
134169689Skan       {
135169689Skan         if (GET_CODE (op) == SUBREG)
136169689Skan           op = SUBREG_REG (op);
137169689Skan         return REG_POINTER (op);
138169689Skan       })
139169689Skan
140169689Skan   becomes
141169689Skan
142169689Skan       static inline int basereg_operand_1(rtx op, enum machine_mode mode)
143169689Skan       {
144169689Skan         if (GET_CODE (op) == SUBREG)
145169689Skan           op = SUBREG_REG (op);
146169689Skan         return REG_POINTER (op);
147169689Skan       }
148169689Skan
149169689Skan       (define_predicate "basereg_operand"
150169689Skan         (and (match_operand 0 "register_operand")
151169689Skan	      (match_test "basereg_operand_1 (op, mode)")))
152169689Skan
153169689Skan   The only wart is that there's no way to insist on a { } string in
154169689Skan   an RTL template, so we have to handle "" strings.  */
155169689Skan
156169689Skan
157169689Skanstatic void
158169689Skanwrite_predicate_subfunction (struct pred_data *p)
159169689Skan{
160169689Skan  const char *match_test_str;
161169689Skan  rtx match_test_exp, and_exp;
162169689Skan
163169689Skan  if (p->c_block[0] == '\0')
164169689Skan    return;
165169689Skan
166169689Skan  /* Construct the function-call expression.  */
167169689Skan  obstack_grow (rtl_obstack, p->name, strlen (p->name));
168169689Skan  obstack_grow (rtl_obstack, "_1 (op, mode)",
169169689Skan		sizeof "_1 (op, mode)");
170169689Skan  match_test_str = XOBFINISH (rtl_obstack, const char *);
171169689Skan
172169689Skan  /* Add the function-call expression to the complete expression to be
173169689Skan     evaluated.  */
174169689Skan  match_test_exp = rtx_alloc (MATCH_TEST);
175169689Skan  XSTR (match_test_exp, 0) = match_test_str;
176169689Skan
177169689Skan  and_exp = rtx_alloc (AND);
178169689Skan  XEXP (and_exp, 0) = p->exp;
179169689Skan  XEXP (and_exp, 1) = match_test_exp;
180169689Skan
181169689Skan  p->exp = and_exp;
182169689Skan
183169689Skan  printf ("static inline int\n"
184169689Skan	  "%s_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n",
185169689Skan	  p->name);
186169689Skan  print_rtx_ptr_loc (p->c_block);
187169689Skan  if (p->c_block[0] == '{')
188169689Skan    fputs (p->c_block, stdout);
189169689Skan  else
190169689Skan    printf ("{\n  %s\n}", p->c_block);
191169689Skan  fputs ("\n\n", stdout);
192169689Skan}
193169689Skan
194169689Skan/* Given a predicate expression EXP, from form NAME, determine whether
195169689Skan   it refers to the variable given as VAR.  */
196169689Skanstatic bool
197169689Skanneeds_variable (rtx exp, const char *var)
198169689Skan{
199169689Skan  switch (GET_CODE (exp))
200169689Skan    {
201169689Skan      /* Ternary, binary, unary expressions need a variable if
202169689Skan	 any of their subexpressions do.  */
203169689Skan    case IF_THEN_ELSE:
204169689Skan      if (needs_variable (XEXP (exp, 2), var))
205169689Skan	return true;
206169689Skan      /* else fall through */
207169689Skan    case AND:
208169689Skan    case IOR:
209169689Skan      if (needs_variable (XEXP (exp, 1), var))
210169689Skan	return true;
211169689Skan      /* else fall through */
212169689Skan    case NOT:
213169689Skan      return needs_variable (XEXP (exp, 0), var);
214169689Skan
215169689Skan      /* MATCH_CODE uses "op", but nothing else.  */
216169689Skan    case MATCH_CODE:
217169689Skan      return !strcmp (var, "op");
218169689Skan
219169689Skan      /* MATCH_OPERAND uses "op" and may use "mode".  */
220169689Skan    case MATCH_OPERAND:
221169689Skan      if (!strcmp (var, "op"))
222169689Skan	return true;
223169689Skan      if (!strcmp (var, "mode") && GET_MODE (exp) == VOIDmode)
224169689Skan	return true;
225169689Skan      return false;
226169689Skan
227169689Skan      /* MATCH_TEST uses var if XSTR (exp, 0) =~ /\b${var}\b/o; */
228169689Skan    case MATCH_TEST:
229169689Skan      {
230169689Skan	const char *p = XSTR (exp, 0);
231169689Skan	const char *q = strstr (p, var);
232169689Skan	if (!q)
233169689Skan	  return false;
234169689Skan	if (q != p && (ISALNUM (q[-1]) || q[-1] == '_'))
235169689Skan	  return false;
236169689Skan	q += strlen (var);
237169689Skan	if (ISALNUM (q[0] || q[0] == '_'))
238169689Skan	  return false;
239169689Skan      }
240169689Skan      return true;
241169689Skan
242169689Skan    default:
243169689Skan      gcc_unreachable ();
244169689Skan    }
245169689Skan}
246169689Skan
247169689Skan/* Given an RTL expression EXP, find all subexpressions which we may
248169689Skan   assume to perform mode tests.  Normal MATCH_OPERAND does;
249169689Skan   MATCH_CODE does if it applies to the whole expression and accepts
250169689Skan   CONST_INT or CONST_DOUBLE; and we have to assume that MATCH_TEST
251169689Skan   does not.  These combine in almost-boolean fashion - the only
252169689Skan   exception is that (not X) must be assumed not to perform a mode
253169689Skan   test, whether or not X does.
254169689Skan
255169689Skan   The mark is the RTL /v flag, which is true for subexpressions which
256169689Skan   do *not* perform mode tests.
257169689Skan*/
258169689Skan#define NO_MODE_TEST(EXP) RTX_FLAG (EXP, volatil)
259169689Skanstatic void
260169689Skanmark_mode_tests (rtx exp)
261169689Skan{
262169689Skan  switch (GET_CODE (exp))
263169689Skan    {
264169689Skan    case MATCH_OPERAND:
265169689Skan      {
266169689Skan	struct pred_data *p = lookup_predicate (XSTR (exp, 1));
267169689Skan	if (!p)
268169689Skan	  error ("reference to undefined predicate '%s'", XSTR (exp, 1));
269169689Skan	else if (p->special || GET_MODE (exp) != VOIDmode)
270169689Skan	  NO_MODE_TEST (exp) = 1;
271169689Skan      }
272169689Skan      break;
273169689Skan
274169689Skan    case MATCH_CODE:
275169689Skan      if (XSTR (exp, 1)[0] != '\0'
276169689Skan	  || (!strstr (XSTR (exp, 0), "const_int")
277169689Skan	      && !strstr (XSTR (exp, 0), "const_double")))
278169689Skan	NO_MODE_TEST (exp) = 1;
279169689Skan      break;
280169689Skan
281169689Skan    case MATCH_TEST:
282169689Skan    case NOT:
283169689Skan      NO_MODE_TEST (exp) = 1;
284169689Skan      break;
285169689Skan
286169689Skan    case AND:
287169689Skan      mark_mode_tests (XEXP (exp, 0));
288169689Skan      mark_mode_tests (XEXP (exp, 1));
289169689Skan
290169689Skan      NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
291169689Skan			    && NO_MODE_TEST (XEXP (exp, 1)));
292169689Skan      break;
293169689Skan
294169689Skan    case IOR:
295169689Skan      mark_mode_tests (XEXP (exp, 0));
296169689Skan      mark_mode_tests (XEXP (exp, 1));
297169689Skan
298169689Skan      NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
299169689Skan			    || NO_MODE_TEST (XEXP (exp, 1)));
300169689Skan      break;
301169689Skan
302169689Skan    case IF_THEN_ELSE:
303169689Skan      /* A ? B : C does a mode test if (one of A and B) does a mode
304169689Skan	 test, and C does too.  */
305169689Skan      mark_mode_tests (XEXP (exp, 0));
306169689Skan      mark_mode_tests (XEXP (exp, 1));
307169689Skan      mark_mode_tests (XEXP (exp, 2));
308169689Skan
309169689Skan      NO_MODE_TEST (exp) = ((NO_MODE_TEST (XEXP (exp, 0))
310169689Skan			     && NO_MODE_TEST (XEXP (exp, 1)))
311169689Skan			    || NO_MODE_TEST (XEXP (exp, 2)));
312169689Skan      break;
313169689Skan
314169689Skan    default:
315169689Skan      gcc_unreachable ();
316169689Skan    }
317169689Skan}
318169689Skan
319169689Skan/* Determine whether the expression EXP is a MATCH_CODE that should
320169689Skan   be written as a switch statement.  */
321169689Skanstatic bool
322169689Skangenerate_switch_p (rtx exp)
323169689Skan{
324169689Skan  return GET_CODE (exp) == MATCH_CODE
325169689Skan	 && strchr (XSTR (exp, 0), ',');
326169689Skan}
327169689Skan
328169689Skan/* Given a predicate, work out where in its RTL expression to add
329169689Skan   tests for proper modes.  Special predicates do not get any such
330169689Skan   tests.  We try to avoid adding tests when we don't have to; in
331169689Skan   particular, other normal predicates can be counted on to do it for
332169689Skan   us.  */
333169689Skan
334169689Skanstatic void
335169689Skanadd_mode_tests (struct pred_data *p)
336169689Skan{
337169689Skan  rtx match_test_exp, and_exp;
338169689Skan  rtx *pos;
339169689Skan
340169689Skan  /* Don't touch special predicates.  */
341169689Skan  if (p->special)
342169689Skan    return;
343169689Skan
344169689Skan  mark_mode_tests (p->exp);
345169689Skan
346169689Skan  /* If the whole expression already tests the mode, we're done.  */
347169689Skan  if (!NO_MODE_TEST (p->exp))
348169689Skan    return;
349169689Skan
350169689Skan  match_test_exp = rtx_alloc (MATCH_TEST);
351169689Skan  XSTR (match_test_exp, 0) = "mode == VOIDmode || GET_MODE (op) == mode";
352169689Skan  and_exp = rtx_alloc (AND);
353169689Skan  XEXP (and_exp, 1) = match_test_exp;
354169689Skan
355169689Skan  /* It is always correct to rewrite p->exp as
356169689Skan
357169689Skan        (and (...) (match_test "mode == VOIDmode || GET_MODE (op) == mode"))
358169689Skan
359169689Skan     but there are a couple forms where we can do better.  If the
360169689Skan     top-level pattern is an IOR, and one of the two branches does test
361169689Skan     the mode, we can wrap just the branch that doesn't.  Likewise, if
362169689Skan     we have an IF_THEN_ELSE, and one side of it tests the mode, we can
363169689Skan     wrap just the side that doesn't.  And, of course, we can repeat this
364169689Skan     descent as many times as it works.  */
365169689Skan
366169689Skan  pos = &p->exp;
367169689Skan  for (;;)
368169689Skan    {
369169689Skan      rtx subexp = *pos;
370169689Skan
371169689Skan      switch (GET_CODE (subexp))
372169689Skan	{
373169689Skan	case AND:
374169689Skan	  /* The switch code generation in write_predicate_stmts prefers
375169689Skan	     rtx code tests to be at the top of the expression tree.  So
376169689Skan	     push this AND down into the second operand of an existing
377169689Skan	     AND expression.  */
378169689Skan	  if (generate_switch_p (XEXP (subexp, 0)))
379169689Skan	    pos = &XEXP (subexp, 1);
380169689Skan	  goto break_loop;
381169689Skan
382169689Skan	case IOR:
383169689Skan	  {
384169689Skan	    int test0 = NO_MODE_TEST (XEXP (subexp, 0));
385169689Skan	    int test1 = NO_MODE_TEST (XEXP (subexp, 1));
386169689Skan
387169689Skan	    gcc_assert (test0 || test1);
388169689Skan
389169689Skan	    if (test0 && test1)
390169689Skan	      goto break_loop;
391169689Skan	    pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
392169689Skan	  }
393169689Skan	  break;
394169689Skan
395169689Skan	case IF_THEN_ELSE:
396169689Skan	  {
397169689Skan	    int test0 = NO_MODE_TEST (XEXP (subexp, 0));
398169689Skan	    int test1 = NO_MODE_TEST (XEXP (subexp, 1));
399169689Skan	    int test2 = NO_MODE_TEST (XEXP (subexp, 2));
400169689Skan
401169689Skan	    gcc_assert ((test0 && test1) || test2);
402169689Skan
403169689Skan	    if (test0 && test1 && test2)
404169689Skan	      goto break_loop;
405169689Skan	    if (test0 && test1)
406169689Skan	      /* Must put it on the dependent clause, not the
407169689Skan	      	 controlling expression, or we change the meaning of
408169689Skan	      	 the test.  */
409169689Skan	      pos = &XEXP (subexp, 1);
410169689Skan	    else
411169689Skan	      pos = &XEXP (subexp, 2);
412169689Skan	  }
413169689Skan	  break;
414169689Skan
415169689Skan	default:
416169689Skan	  goto break_loop;
417169689Skan	}
418169689Skan    }
419169689Skan break_loop:
420169689Skan  XEXP (and_exp, 0) = *pos;
421169689Skan  *pos = and_exp;
422169689Skan}
423169689Skan
424169689Skan/* PATH is a string describing a path from the root of an RTL
425169689Skan   expression to an inner subexpression to be tested.  Output
426169689Skan   code which computes the subexpression from the variable
427169689Skan   holding the root of the expression.  */
428169689Skanstatic void
429169689Skanwrite_extract_subexp (const char *path)
430169689Skan{
431169689Skan  int len = strlen (path);
432169689Skan  int i;
433169689Skan
434169689Skan  /* We first write out the operations (XEXP or XVECEXP) in reverse
435169689Skan     order, then write "op", then the indices in forward order.  */
436169689Skan  for (i = len - 1; i >= 0; i--)
437169689Skan    {
438169689Skan      if (ISLOWER (path[i]))
439169689Skan	fputs ("XVECEXP (", stdout);
440169689Skan      else if (ISDIGIT (path[i]))
441169689Skan	fputs ("XEXP (", stdout);
442169689Skan      else
443169689Skan	gcc_unreachable ();
444169689Skan    }
445169689Skan
446169689Skan  fputs ("op", stdout);
447169689Skan
448169689Skan  for (i = 0; i < len; i++)
449169689Skan    {
450169689Skan      if (ISLOWER (path[i]))
451169689Skan	printf (", 0, %d)", path[i] - 'a');
452169689Skan      else if (ISDIGIT (path[i]))
453169689Skan	printf (", %d)", path[i] - '0');
454169689Skan      else
455169689Skan	gcc_unreachable ();
456169689Skan    }
457169689Skan}
458169689Skan
459169689Skan/* CODES is a list of RTX codes.  Write out an expression which
460169689Skan   determines whether the operand has one of those codes.  */
461169689Skanstatic void
462169689Skanwrite_match_code (const char *path, const char *codes)
463169689Skan{
464169689Skan  const char *code;
465169689Skan
466169689Skan  while ((code = scan_comma_elt (&codes)) != 0)
467169689Skan    {
468169689Skan      fputs ("GET_CODE (", stdout);
469169689Skan      write_extract_subexp (path);
470169689Skan      fputs (") == ", stdout);
471169689Skan      while (code < codes)
472169689Skan	{
473169689Skan	  putchar (TOUPPER (*code));
474169689Skan	  code++;
475169689Skan	}
476169689Skan
477169689Skan      if (*codes == ',')
478169689Skan	fputs (" || ", stdout);
479169689Skan    }
480169689Skan}
481169689Skan
482169689Skan/* EXP is an RTL (sub)expression for a predicate.  Recursively
483169689Skan   descend the expression and write out an equivalent C expression.  */
484169689Skanstatic void
485169689Skanwrite_predicate_expr (rtx exp)
486169689Skan{
487169689Skan  switch (GET_CODE (exp))
488169689Skan    {
489169689Skan    case AND:
490169689Skan      putchar ('(');
491169689Skan      write_predicate_expr (XEXP (exp, 0));
492169689Skan      fputs (") && (", stdout);
493169689Skan      write_predicate_expr (XEXP (exp, 1));
494169689Skan      putchar (')');
495169689Skan      break;
496169689Skan
497169689Skan    case IOR:
498169689Skan      putchar ('(');
499169689Skan      write_predicate_expr (XEXP (exp, 0));
500169689Skan      fputs (") || (", stdout);
501169689Skan      write_predicate_expr (XEXP (exp, 1));
502169689Skan      putchar (')');
503169689Skan      break;
504169689Skan
505169689Skan    case NOT:
506169689Skan      fputs ("!(", stdout);
507169689Skan      write_predicate_expr (XEXP (exp, 0));
508169689Skan      putchar (')');
509169689Skan      break;
510169689Skan
511169689Skan    case IF_THEN_ELSE:
512169689Skan      putchar ('(');
513169689Skan      write_predicate_expr (XEXP (exp, 0));
514169689Skan      fputs (") ? (", stdout);
515169689Skan      write_predicate_expr (XEXP (exp, 1));
516169689Skan      fputs (") : (", stdout);
517169689Skan      write_predicate_expr (XEXP (exp, 2));
518169689Skan      putchar (')');
519169689Skan      break;
520169689Skan
521169689Skan    case MATCH_OPERAND:
522169689Skan      if (GET_MODE (exp) == VOIDmode)
523169689Skan        printf ("%s (op, mode)", XSTR (exp, 1));
524169689Skan      else
525169689Skan        printf ("%s (op, %smode)", XSTR (exp, 1), mode_name[GET_MODE (exp)]);
526169689Skan      break;
527169689Skan
528169689Skan    case MATCH_CODE:
529169689Skan      write_match_code (XSTR (exp, 1), XSTR (exp, 0));
530169689Skan      break;
531169689Skan
532169689Skan    case MATCH_TEST:
533169689Skan      print_c_condition (XSTR (exp, 0));
534169689Skan      break;
535169689Skan
536169689Skan    default:
537169689Skan      gcc_unreachable ();
538169689Skan    }
539169689Skan}
540169689Skan
541169689Skan/* Write the MATCH_CODE expression EXP as a switch statement.  */
542169689Skan
543169689Skanstatic void
544169689Skanwrite_match_code_switch (rtx exp)
545169689Skan{
546169689Skan  const char *codes = XSTR (exp, 0);
547169689Skan  const char *path = XSTR (exp, 1);
548169689Skan  const char *code;
549169689Skan
550169689Skan  fputs ("  switch (GET_CODE (", stdout);
551169689Skan  write_extract_subexp (path);
552169689Skan  fputs ("))\n    {\n", stdout);
553169689Skan
554169689Skan  while ((code = scan_comma_elt (&codes)) != 0)
555169689Skan    {
556169689Skan      fputs ("    case ", stdout);
557169689Skan      while (code < codes)
558169689Skan	{
559169689Skan	  putchar (TOUPPER (*code));
560169689Skan	  code++;
561169689Skan	}
562169689Skan      fputs(":\n", stdout);
563169689Skan    }
564169689Skan}
565169689Skan
566169689Skan/* Given a predicate expression EXP, write out a sequence of stmts
567169689Skan   to evaluate it.  This is similar to write_predicate_expr but can
568169689Skan   generate efficient switch statements.  */
569169689Skan
570169689Skanstatic void
571169689Skanwrite_predicate_stmts (rtx exp)
572169689Skan{
573169689Skan  switch (GET_CODE (exp))
574169689Skan    {
575169689Skan    case MATCH_CODE:
576169689Skan      if (generate_switch_p (exp))
577169689Skan	{
578169689Skan	  write_match_code_switch (exp);
579169689Skan	  puts ("      return true;\n"
580169689Skan		"    default:\n"
581169689Skan		"      break;\n"
582169689Skan		"    }\n"
583169689Skan		"  return false;");
584169689Skan	  return;
585169689Skan	}
586169689Skan      break;
587169689Skan
588169689Skan    case AND:
589169689Skan      if (generate_switch_p (XEXP (exp, 0)))
590169689Skan	{
591169689Skan	  write_match_code_switch (XEXP (exp, 0));
592169689Skan	  puts ("      break;\n"
593169689Skan		"    default:\n"
594169689Skan		"      return false;\n"
595169689Skan		"    }");
596169689Skan	  exp = XEXP (exp, 1);
597169689Skan	}
598169689Skan      break;
599169689Skan
600169689Skan    case IOR:
601169689Skan      if (generate_switch_p (XEXP (exp, 0)))
602169689Skan	{
603169689Skan	  write_match_code_switch (XEXP (exp, 0));
604169689Skan	  puts ("      return true;\n"
605169689Skan		"    default:\n"
606169689Skan		"      break;\n"
607169689Skan		"    }");
608169689Skan	  exp = XEXP (exp, 1);
609169689Skan	}
610169689Skan      break;
611169689Skan
612169689Skan    case NOT:
613169689Skan      if (generate_switch_p (XEXP (exp, 0)))
614169689Skan	{
615169689Skan	  write_match_code_switch (XEXP (exp, 0));
616169689Skan	  puts ("      return false;\n"
617169689Skan		"    default:\n"
618169689Skan		"      break;\n"
619169689Skan		"    }\n"
620169689Skan		"  return true;");
621169689Skan	  return;
622169689Skan	}
623169689Skan      break;
624169689Skan
625169689Skan    default:
626169689Skan      break;
627169689Skan    }
628169689Skan
629169689Skan  fputs("  return ",stdout);
630169689Skan  write_predicate_expr (exp);
631169689Skan  fputs(";\n", stdout);
632169689Skan}
633169689Skan
634169689Skan/* Given a predicate, write out a complete C function to compute it.  */
635169689Skanstatic void
636169689Skanwrite_one_predicate_function (struct pred_data *p)
637169689Skan{
638169689Skan  if (!p->exp)
639169689Skan    return;
640169689Skan
641169689Skan  write_predicate_subfunction (p);
642169689Skan  add_mode_tests (p);
643169689Skan
644169689Skan  /* A normal predicate can legitimately not look at enum machine_mode
645169689Skan     if it accepts only CONST_INTs and/or CONST_DOUBLEs.  */
646169689Skan  printf ("int\n%s (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n{\n",
647169689Skan	  p->name);
648169689Skan  write_predicate_stmts (p->exp);
649169689Skan  fputs ("}\n\n", stdout);
650169689Skan}
651169689Skan
652169689Skan/* Constraints fall into two categories: register constraints
653169689Skan   (define_register_constraint), and others (define_constraint,
654169689Skan   define_memory_constraint, define_address_constraint).  We
655169689Skan   work out automatically which of the various old-style macros
656169689Skan   they correspond to, and produce appropriate code.  They all
657169689Skan   go in the same hash table so we can verify that there are no
658169689Skan   duplicate names.  */
659169689Skan
660169689Skan/* All data from one constraint definition.  */
661169689Skanstruct constraint_data
662169689Skan{
663169689Skan  struct constraint_data *next_this_letter;
664169689Skan  struct constraint_data *next_textual;
665169689Skan  const char *name;
666169689Skan  const char *c_name;    /* same as .name unless mangling is necessary */
667169689Skan  size_t namelen;
668169689Skan  const char *regclass;  /* for register constraints */
669169689Skan  rtx exp;               /* for other constraints */
670169689Skan  unsigned int lineno;   /* line of definition */
671169689Skan  unsigned int is_register  : 1;
672169689Skan  unsigned int is_const_int : 1;
673169689Skan  unsigned int is_const_dbl : 1;
674169689Skan  unsigned int is_extra     : 1;
675169689Skan  unsigned int is_memory    : 1;
676169689Skan  unsigned int is_address   : 1;
677169689Skan};
678169689Skan
679169689Skan/* Overview of all constraints beginning with a given letter.  */
680169689Skan
681169689Skanstatic struct constraint_data *
682169689Skanconstraints_by_letter_table[1<<CHAR_BIT];
683169689Skan
684169689Skan/* For looking up all the constraints in the order that they appeared
685169689Skan   in the machine description.  */
686169689Skanstatic struct constraint_data *first_constraint;
687169689Skanstatic struct constraint_data **last_constraint_ptr = &first_constraint;
688169689Skan
689169689Skan#define FOR_ALL_CONSTRAINTS(iter_) \
690169689Skan  for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
691169689Skan
692169689Skan/* These letters, and all names beginning with them, are reserved for
693169689Skan   generic constraints.  */
694169689Skanstatic const char generic_constraint_letters[] = "EFVXgimnoprs";
695169689Skan
696169689Skan/* Machine-independent code expects that constraints with these
697169689Skan   (initial) letters will allow only (a subset of all) CONST_INTs.  */
698169689Skan
699169689Skanstatic const char const_int_constraints[] = "IJKLMNOP";
700169689Skan
701169689Skan/* Machine-independent code expects that constraints with these
702169689Skan   (initial) letters will allow only (a subset of all) CONST_DOUBLEs.  */
703169689Skan
704169689Skanstatic const char const_dbl_constraints[] = "GH";
705169689Skan
706169689Skan/* Summary data used to decide whether to output various functions and
707169689Skan   macro definitions.  */
708169689Skanstatic unsigned int constraint_max_namelen;
709169689Skanstatic bool have_register_constraints;
710169689Skanstatic bool have_memory_constraints;
711169689Skanstatic bool have_address_constraints;
712169689Skanstatic bool have_extra_constraints;
713169689Skanstatic bool have_const_int_constraints;
714169689Skanstatic bool have_const_dbl_constraints;
715169689Skan
716169689Skan/* Convert NAME, which contains angle brackets and/or underscores, to
717169689Skan   a string that can be used as part of a C identifier.  The string
718169689Skan   comes from the rtl_obstack.  */
719169689Skanstatic const char *
720169689Skanmangle (const char *name)
721169689Skan{
722169689Skan  for (; *name; name++)
723169689Skan    switch (*name)
724169689Skan      {
725169689Skan      case '_': obstack_grow (rtl_obstack, "__", 2); break;
726169689Skan      case '<':	obstack_grow (rtl_obstack, "_l", 2); break;
727169689Skan      case '>':	obstack_grow (rtl_obstack, "_g", 2); break;
728169689Skan      default: obstack_1grow (rtl_obstack, *name); break;
729169689Skan      }
730169689Skan
731169689Skan  obstack_1grow (rtl_obstack, '\0');
732169689Skan  return obstack_finish (rtl_obstack);
733169689Skan}
734169689Skan
735169689Skan/* Add one constraint, of any sort, to the tables.  NAME is its name;
736169689Skan   REGCLASS is the register class, if any; EXP is the expression to
737169689Skan   test, if any;  IS_MEMORY and IS_ADDRESS indicate memory and address
738169689Skan   constraints, respectively; LINENO is the line number from the MD reader.
739169689Skan   Not all combinations of arguments are valid; most importantly, REGCLASS
740169689Skan   is mutually exclusive with EXP, and IS_MEMORY/IS_ADDRESS are only
741169689Skan   meaningful for constraints with EXP.
742169689Skan
743169689Skan   This function enforces all syntactic and semantic rules about what
744169689Skan   constraints can be defined.  */
745169689Skan
746169689Skanstatic void
747169689Skanadd_constraint (const char *name, const char *regclass,
748169689Skan		rtx exp, bool is_memory, bool is_address,
749169689Skan		int lineno)
750169689Skan{
751169689Skan  struct constraint_data *c, **iter, **slot;
752169689Skan  const char *p;
753169689Skan  bool need_mangled_name = false;
754169689Skan  bool is_const_int;
755169689Skan  bool is_const_dbl;
756169689Skan  size_t namelen;
757169689Skan
758169689Skan  if (exp && validate_exp (exp, name, lineno))
759169689Skan    return;
760169689Skan
761169689Skan  if (!ISALPHA (name[0]) && name[0] != '_')
762169689Skan    {
763169689Skan      if (name[1] == '\0')
764169689Skan	message_with_line (lineno, "constraint name '%s' is not "
765169689Skan			   "a letter or underscore", name);
766169689Skan      else
767169689Skan	message_with_line (lineno, "constraint name '%s' does not begin "
768169689Skan			   "with a letter or underscore", name);
769169689Skan      have_error = 1;
770169689Skan      return;
771169689Skan    }
772169689Skan  for (p = name; *p; p++)
773169689Skan    if (!ISALNUM (*p))
774169689Skan      {
775169689Skan	if (*p == '<' || *p == '>' || *p == '_')
776169689Skan	  need_mangled_name = true;
777169689Skan	else
778169689Skan	  {
779169689Skan	    message_with_line (lineno,
780169689Skan			       "constraint name '%s' must be composed of "
781169689Skan			       "letters, digits, underscores, and "
782169689Skan			       "angle brackets", name);
783169689Skan	    have_error = 1;
784169689Skan	    return;
785169689Skan	  }
786169689Skan      }
787169689Skan
788169689Skan  if (strchr (generic_constraint_letters, name[0]))
789169689Skan    {
790169689Skan      if (name[1] == '\0')
791169689Skan	message_with_line (lineno, "constraint letter '%s' cannot be "
792169689Skan			   "redefined by the machine description", name);
793169689Skan      else
794169689Skan	message_with_line (lineno, "constraint name '%s' cannot be defined by "
795169689Skan			   "the machine description, as it begins with '%c'",
796169689Skan			   name, name[0]);
797169689Skan      have_error = 1;
798169689Skan      return;
799169689Skan    }
800169689Skan
801169689Skan
802169689Skan  namelen = strlen (name);
803169689Skan  slot = &constraints_by_letter_table[(unsigned int)name[0]];
804169689Skan  for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
805169689Skan    {
806169689Skan      /* This causes slot to end up pointing to the
807169689Skan	 next_this_letter field of the last constraint with a name
808169689Skan	 of equal or greater length than the new constraint; hence
809169689Skan	 the new constraint will be inserted after all previous
810169689Skan	 constraints with names of the same length.  */
811169689Skan      if ((*iter)->namelen >= namelen)
812169689Skan	slot = iter;
813169689Skan
814169689Skan      if (!strcmp ((*iter)->name, name))
815169689Skan	{
816169689Skan	  message_with_line (lineno, "redefinition of constraint '%s'", name);
817169689Skan	  message_with_line ((*iter)->lineno, "previous definition is here");
818169689Skan	  have_error = 1;
819169689Skan	  return;
820169689Skan	}
821169689Skan      else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
822169689Skan	{
823169689Skan	  message_with_line (lineno, "defining constraint '%s' here", name);
824169689Skan	  message_with_line ((*iter)->lineno, "renders constraint '%s' "
825169689Skan			     "(defined here) a prefix", (*iter)->name);
826169689Skan	  have_error = 1;
827169689Skan	  return;
828169689Skan	}
829169689Skan      else if (!strncmp ((*iter)->name, name, namelen))
830169689Skan	{
831169689Skan	  message_with_line (lineno, "constraint '%s' is a prefix", name);
832169689Skan	  message_with_line ((*iter)->lineno, "of constraint '%s' "
833169689Skan			     "(defined here)", (*iter)->name);
834169689Skan	  have_error = 1;
835169689Skan	  return;
836169689Skan	}
837169689Skan    }
838169689Skan
839169689Skan  is_const_int = strchr (const_int_constraints, name[0]) != 0;
840169689Skan  is_const_dbl = strchr (const_dbl_constraints, name[0]) != 0;
841169689Skan
842169689Skan  if (is_const_int || is_const_dbl)
843169689Skan    {
844169689Skan      enum rtx_code appropriate_code
845169689Skan	= is_const_int ? CONST_INT : CONST_DOUBLE;
846169689Skan
847169689Skan      /* Consider relaxing this requirement in the future.  */
848169689Skan      if (regclass
849169689Skan	  || GET_CODE (exp) != AND
850169689Skan	  || GET_CODE (XEXP (exp, 0)) != MATCH_CODE
851169689Skan	  || strcmp (XSTR (XEXP (exp, 0), 0),
852169689Skan		     GET_RTX_NAME (appropriate_code)))
853169689Skan	{
854169689Skan	  if (name[1] == '\0')
855169689Skan	    message_with_line (lineno, "constraint letter '%c' is reserved "
856169689Skan			       "for %s constraints",
857169689Skan			       name[0], GET_RTX_NAME (appropriate_code));
858169689Skan	  else
859169689Skan	    message_with_line (lineno, "constraint names beginning with '%c' "
860169689Skan			       "(%s) are reserved for %s constraints",
861169689Skan			       name[0], name,
862169689Skan			       GET_RTX_NAME (appropriate_code));
863169689Skan
864169689Skan	  have_error = 1;
865169689Skan	  return;
866169689Skan	}
867169689Skan
868169689Skan      if (is_memory)
869169689Skan	{
870169689Skan	  if (name[1] == '\0')
871169689Skan	    message_with_line (lineno, "constraint letter '%c' cannot be a "
872169689Skan			       "memory constraint", name[0]);
873169689Skan	  else
874169689Skan	    message_with_line (lineno, "constraint name '%s' begins with '%c', "
875169689Skan			       "and therefore cannot be a memory constraint",
876169689Skan			       name, name[0]);
877169689Skan
878169689Skan	  have_error = 1;
879169689Skan	  return;
880169689Skan	}
881169689Skan      else if (is_address)
882169689Skan	{
883169689Skan	  if (name[1] == '\0')
884169689Skan	    message_with_line (lineno, "constraint letter '%c' cannot be a "
885169689Skan			       "memory constraint", name[0]);
886169689Skan	  else
887169689Skan	    message_with_line (lineno, "constraint name '%s' begins with '%c', "
888169689Skan			       "and therefore cannot be a memory constraint",
889169689Skan			       name, name[0]);
890169689Skan
891169689Skan	  have_error = 1;
892169689Skan	  return;
893169689Skan	}
894169689Skan    }
895169689Skan
896169689Skan
897169689Skan  c = obstack_alloc (rtl_obstack, sizeof (struct constraint_data));
898169689Skan  c->name = name;
899169689Skan  c->c_name = need_mangled_name ? mangle (name) : name;
900169689Skan  c->lineno = lineno;
901169689Skan  c->namelen = namelen;
902169689Skan  c->regclass = regclass;
903169689Skan  c->exp = exp;
904169689Skan  c->is_register = regclass != 0;
905169689Skan  c->is_const_int = is_const_int;
906169689Skan  c->is_const_dbl = is_const_dbl;
907169689Skan  c->is_extra = !(regclass || is_const_int || is_const_dbl);
908169689Skan  c->is_memory = is_memory;
909169689Skan  c->is_address = is_address;
910169689Skan
911169689Skan  c->next_this_letter = *slot;
912169689Skan  *slot = c;
913169689Skan
914169689Skan  /* Insert this constraint in the list of all constraints in textual
915169689Skan     order.  */
916169689Skan  c->next_textual = 0;
917169689Skan  *last_constraint_ptr = c;
918169689Skan  last_constraint_ptr = &c->next_textual;
919169689Skan
920169689Skan  constraint_max_namelen = MAX (constraint_max_namelen, strlen (name));
921169689Skan  have_register_constraints |= c->is_register;
922169689Skan  have_const_int_constraints |= c->is_const_int;
923169689Skan  have_const_dbl_constraints |= c->is_const_dbl;
924169689Skan  have_extra_constraints |= c->is_extra;
925169689Skan  have_memory_constraints |= c->is_memory;
926169689Skan  have_address_constraints |= c->is_address;
927169689Skan}
928169689Skan
929169689Skan/* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or
930169689Skan   DEFINE_ADDRESS_CONSTRAINT expression, C.  */
931169689Skanstatic void
932169689Skanprocess_define_constraint (rtx c, int lineno)
933169689Skan{
934169689Skan  add_constraint (XSTR (c, 0), 0, XEXP (c, 2),
935169689Skan		  GET_CODE (c) == DEFINE_MEMORY_CONSTRAINT,
936169689Skan		  GET_CODE (c) == DEFINE_ADDRESS_CONSTRAINT,
937169689Skan		  lineno);
938169689Skan}
939169689Skan
940169689Skan/* Process a DEFINE_REGISTER_CONSTRAINT expression, C.  */
941169689Skanstatic void
942169689Skanprocess_define_register_constraint (rtx c, int lineno)
943169689Skan{
944169689Skan  add_constraint (XSTR (c, 0), XSTR (c, 1), 0, false, false, lineno);
945169689Skan}
946169689Skan
947169689Skan/* Write out an enumeration with one entry per machine-specific
948169689Skan   constraint.  */
949169689Skanstatic void
950169689Skanwrite_enum_constraint_num (void)
951169689Skan{
952169689Skan  struct constraint_data *c;
953169689Skan
954169689Skan  fputs ("enum constraint_num\n"
955169689Skan	 "{\n"
956169689Skan	 "  CONSTRAINT__UNKNOWN = 0", stdout);
957169689Skan  FOR_ALL_CONSTRAINTS (c)
958169689Skan    printf (",\n  CONSTRAINT_%s", c->c_name);
959169689Skan  puts ("\n};\n");
960169689Skan}
961169689Skan
962169689Skan/* Write out a function which looks at a string and determines what
963169689Skan   constraint name, if any, it begins with.  */
964169689Skanstatic void
965169689Skanwrite_lookup_constraint (void)
966169689Skan{
967169689Skan  unsigned int i;
968169689Skan  puts ("enum constraint_num\n"
969169689Skan	"lookup_constraint (const char *str)\n"
970169689Skan	"{\n"
971169689Skan	"  switch (str[0])\n"
972169689Skan	"    {");
973169689Skan
974169689Skan  for (i = 0; i < ARRAY_SIZE(constraints_by_letter_table); i++)
975169689Skan    {
976169689Skan      struct constraint_data *c = constraints_by_letter_table[i];
977169689Skan      if (!c)
978169689Skan	continue;
979169689Skan
980169689Skan      printf ("    case '%c':\n", i);
981169689Skan      if (c->namelen == 1)
982169689Skan	printf ("      return CONSTRAINT_%s;\n", c->c_name);
983169689Skan      else
984169689Skan	{
985169689Skan	  do
986169689Skan	    {
987169689Skan	      printf ("      if (!strncmp (str, \"%s\", %lu))\n"
988169689Skan		      "        return CONSTRAINT_%s;\n",
989169689Skan		      c->name, (unsigned long int) c->namelen, c->c_name);
990169689Skan	      c = c->next_this_letter;
991169689Skan	    }
992169689Skan	  while (c);
993169689Skan	  puts ("      break;");
994169689Skan	}
995169689Skan    }
996169689Skan
997169689Skan  puts ("    default: break;\n"
998169689Skan	"    }\n"
999169689Skan	"  return CONSTRAINT__UNKNOWN;\n"
1000169689Skan	"}\n");
1001169689Skan}
1002169689Skan
1003169689Skan/* Write out the function which computes constraint name lengths from
1004169689Skan   their enumerators. */
1005169689Skanstatic void
1006169689Skanwrite_insn_constraint_len (void)
1007169689Skan{
1008169689Skan  struct constraint_data *c;
1009169689Skan
1010169689Skan  if (constraint_max_namelen == 1)
1011169689Skan    return;
1012169689Skan
1013169689Skan  puts ("size_t\n"
1014169689Skan	"insn_constraint_len (enum constraint_num c)\n"
1015169689Skan	"{\n"
1016169689Skan	"  switch (c)\n"
1017169689Skan	"    {");
1018169689Skan
1019169689Skan  FOR_ALL_CONSTRAINTS (c)
1020169689Skan    if (c->namelen > 1)
1021169689Skan      printf ("    case CONSTRAINT_%s: return %lu;\n", c->c_name,
1022169689Skan	      (unsigned long int) c->namelen);
1023169689Skan
1024169689Skan  puts ("    default: break;\n"
1025169689Skan	"    }\n"
1026169689Skan	"  return 1;\n"
1027169689Skan	"}\n");
1028169689Skan}
1029169689Skan
1030169689Skan/* Write out the function which computes the register class corresponding
1031169689Skan   to a register constraint.  */
1032169689Skanstatic void
1033169689Skanwrite_regclass_for_constraint (void)
1034169689Skan{
1035169689Skan  struct constraint_data *c;
1036169689Skan
1037169689Skan  puts ("enum reg_class\n"
1038169689Skan	"regclass_for_constraint (enum constraint_num c)\n"
1039169689Skan	"{\n"
1040169689Skan	"  switch (c)\n"
1041169689Skan	"    {");
1042169689Skan
1043169689Skan  FOR_ALL_CONSTRAINTS (c)
1044169689Skan    if (c->is_register)
1045169689Skan      printf ("    case CONSTRAINT_%s: return %s;\n", c->c_name, c->regclass);
1046169689Skan
1047169689Skan  puts ("    default: break;\n"
1048169689Skan	"    }\n"
1049169689Skan	"  return NO_REGS;\n"
1050169689Skan	"}\n");
1051169689Skan}
1052169689Skan
1053169689Skan/* Write out the functions which compute whether a given value matches
1054169689Skan   a given non-register constraint.  */
1055169689Skanstatic void
1056169689Skanwrite_tm_constrs_h (void)
1057169689Skan{
1058169689Skan  struct constraint_data *c;
1059169689Skan
1060169689Skan  printf ("\
1061169689Skan/* Generated automatically by the program '%s'\n\
1062169689Skan   from the machine description file '%s'.  */\n\n", progname, in_fname);
1063169689Skan
1064169689Skan  puts ("\
1065169689Skan#ifndef GCC_TM_CONSTRS_H\n\
1066169689Skan#define GCC_TM_CONSTRS_H\n");
1067169689Skan
1068169689Skan  FOR_ALL_CONSTRAINTS (c)
1069169689Skan    if (!c->is_register)
1070169689Skan      {
1071169689Skan	bool needs_ival = needs_variable (c->exp, "ival");
1072169689Skan	bool needs_hval = needs_variable (c->exp, "hval");
1073169689Skan	bool needs_lval = needs_variable (c->exp, "lval");
1074169689Skan	bool needs_rval = needs_variable (c->exp, "rval");
1075169689Skan	bool needs_mode = (needs_variable (c->exp, "mode")
1076169689Skan			   || needs_hval || needs_lval || needs_rval);
1077169689Skan	bool needs_op = (needs_variable (c->exp, "op")
1078169689Skan			 || needs_ival || needs_mode);
1079169689Skan
1080169689Skan	printf ("static inline bool\n"
1081169689Skan		"satisfies_constraint_%s (rtx %s)\n"
1082169689Skan		"{\n", c->c_name,
1083169689Skan		needs_op ? "op" : "ARG_UNUSED (op)");
1084169689Skan	if (needs_mode)
1085169689Skan	  puts ("enum machine_mode mode = GET_MODE (op);");
1086169689Skan	if (needs_ival)
1087169689Skan	  puts ("  HOST_WIDE_INT ival = 0;");
1088169689Skan	if (needs_hval)
1089169689Skan	  puts ("  HOST_WIDE_INT hval = 0;");
1090169689Skan	if (needs_lval)
1091169689Skan	  puts ("  unsigned HOST_WIDE_INT lval = 0;");
1092169689Skan	if (needs_rval)
1093169689Skan	  puts ("  const REAL_VALUE_TYPE *rval = 0;");
1094169689Skan
1095169689Skan	if (needs_ival)
1096169689Skan	  puts ("  if (GET_CODE (op) == CONST_INT)\n"
1097169689Skan		"    ival = INTVAL (op);");
1098169689Skan	if (needs_hval)
1099169689Skan	  puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
1100169689Skan		"    hval = CONST_DOUBLE_HIGH (op);");
1101169689Skan	if (needs_lval)
1102169689Skan	  puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
1103169689Skan		"    lval = CONST_DOUBLE_LOW (op);");
1104169689Skan	if (needs_rval)
1105169689Skan	  puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode != VOIDmode)"
1106169689Skan		"    rval = CONST_DOUBLE_REAL_VALUE (op);");
1107169689Skan
1108169689Skan	write_predicate_stmts (c->exp);
1109169689Skan	fputs ("}\n", stdout);
1110169689Skan      }
1111169689Skan  puts ("#endif /* tm-constrs.h */");
1112169689Skan}
1113169689Skan
1114169689Skan/* Write out the wrapper function, constraint_satisfied_p, that maps
1115169689Skan   a CONSTRAINT_xxx constant to one of the predicate functions generated
1116169689Skan   above.  */
1117169689Skanstatic void
1118169689Skanwrite_constraint_satisfied_p (void)
1119169689Skan{
1120169689Skan  struct constraint_data *c;
1121169689Skan
1122169689Skan  puts ("bool\n"
1123169689Skan	"constraint_satisfied_p (rtx op, enum constraint_num c)\n"
1124169689Skan	"{\n"
1125169689Skan	"  switch (c)\n"
1126169689Skan	"    {");
1127169689Skan
1128169689Skan  FOR_ALL_CONSTRAINTS (c)
1129169689Skan    if (!c->is_register)
1130169689Skan      printf ("    case CONSTRAINT_%s: "
1131169689Skan	      "return satisfies_constraint_%s (op);\n",
1132169689Skan	      c->c_name, c->c_name);
1133169689Skan
1134169689Skan  puts ("    default: break;\n"
1135169689Skan	"    }\n"
1136169689Skan	"  return false;\n"
1137169689Skan	"}\n");
1138169689Skan}
1139169689Skan
1140169689Skan/* Write out the function which computes whether a given value matches
1141169689Skan   a given CONST_INT constraint.  This doesn't just forward to
1142169689Skan   constraint_satisfied_p because caller passes the INTVAL, not the RTX.  */
1143169689Skanstatic void
1144169689Skanwrite_insn_const_int_ok_for_constraint (void)
1145169689Skan{
1146169689Skan  struct constraint_data *c;
1147169689Skan
1148169689Skan  puts ("bool\n"
1149169689Skan	"insn_const_int_ok_for_constraint (HOST_WIDE_INT ival, "
1150169689Skan	                                  "enum constraint_num c)\n"
1151169689Skan	"{\n"
1152169689Skan	"  switch (c)\n"
1153169689Skan	"    {");
1154169689Skan
1155169689Skan  FOR_ALL_CONSTRAINTS (c)
1156169689Skan    if (c->is_const_int)
1157169689Skan      {
1158169689Skan	printf ("    case CONSTRAINT_%s:\n      return ", c->c_name);
1159169689Skan	/* c->exp is guaranteed to be (and (match_code "const_int") (...));
1160169689Skan	   we know at this point that we have a const_int, so we need not
1161169689Skan	   bother with that part of the test.  */
1162169689Skan	write_predicate_expr (XEXP (c->exp, 1));
1163169689Skan	fputs (";\n\n", stdout);
1164169689Skan      }
1165169689Skan
1166169689Skan  puts ("    default: break;\n"
1167169689Skan	"    }\n"
1168169689Skan	"  return false;\n"
1169169689Skan	"}\n");
1170169689Skan}
1171169689Skan
1172169689Skan
1173169689Skan/* Write out the function which computes whether a given constraint is
1174169689Skan   a memory constraint.  */
1175169689Skanstatic void
1176169689Skanwrite_insn_extra_memory_constraint (void)
1177169689Skan{
1178169689Skan  struct constraint_data *c;
1179169689Skan
1180169689Skan  puts ("bool\n"
1181169689Skan	"insn_extra_memory_constraint (enum constraint_num c)\n"
1182169689Skan	"{\n"
1183169689Skan	"  switch (c)\n"
1184169689Skan	"    {");
1185169689Skan
1186169689Skan  FOR_ALL_CONSTRAINTS (c)
1187169689Skan    if (c->is_memory)
1188169689Skan      printf ("    case CONSTRAINT_%s:\n      return true;\n\n", c->c_name);
1189169689Skan
1190169689Skan  puts ("    default: break;\n"
1191169689Skan	"    }\n"
1192169689Skan	"  return false;\n"
1193169689Skan	"}\n");
1194169689Skan}
1195169689Skan
1196169689Skan/* Write out the function which computes whether a given constraint is
1197169689Skan   an address constraint.  */
1198169689Skanstatic void
1199169689Skanwrite_insn_extra_address_constraint (void)
1200169689Skan{
1201169689Skan  struct constraint_data *c;
1202169689Skan
1203169689Skan  puts ("bool\n"
1204169689Skan	"insn_extra_address_constraint (enum constraint_num c)\n"
1205169689Skan	"{\n"
1206169689Skan	"  switch (c)\n"
1207169689Skan	"    {");
1208169689Skan
1209169689Skan  FOR_ALL_CONSTRAINTS (c)
1210169689Skan    if (c->is_address)
1211169689Skan      printf ("    case CONSTRAINT_%s:\n      return true;\n\n", c->c_name);
1212169689Skan
1213169689Skan  puts ("    default: break;\n"
1214169689Skan	"    }\n"
1215169689Skan	"  return false;\n"
1216169689Skan	"}\n");
1217169689Skan}
1218169689Skan
1219169689Skan
1220169689Skan/* Write tm-preds.h.  Unfortunately, it is impossible to forward-declare
1221169689Skan   an enumeration in portable C, so we have to condition all these
1222169689Skan   prototypes on HAVE_MACHINE_MODES.  */
1223169689Skanstatic void
1224169689Skanwrite_tm_preds_h (void)
1225169689Skan{
1226169689Skan  struct pred_data *p;
1227169689Skan
1228169689Skan  printf ("\
1229169689Skan/* Generated automatically by the program '%s'\n\
1230169689Skan   from the machine description file '%s'.  */\n\n", progname, in_fname);
1231169689Skan
1232169689Skan  puts ("\
1233169689Skan#ifndef GCC_TM_PREDS_H\n\
1234169689Skan#define GCC_TM_PREDS_H\n\
1235169689Skan\n\
1236169689Skan#ifdef HAVE_MACHINE_MODES");
1237169689Skan
1238169689Skan  FOR_ALL_PREDICATES (p)
1239169689Skan    printf ("extern int %s (rtx, enum machine_mode);\n", p->name);
1240169689Skan
1241169689Skan  puts ("#endif /* HAVE_MACHINE_MODES */\n");
1242169689Skan
1243169689Skan  if (constraint_max_namelen > 0)
1244169689Skan    {
1245169689Skan      write_enum_constraint_num ();
1246169689Skan      puts ("extern enum constraint_num lookup_constraint (const char *);\n"
1247169689Skan	    "extern bool constraint_satisfied_p (rtx, enum constraint_num);\n");
1248169689Skan
1249169689Skan      if (constraint_max_namelen > 1)
1250169689Skan	puts ("extern size_t insn_constraint_len (enum constraint_num);\n"
1251169689Skan	      "#define CONSTRAINT_LEN(c_,s_) "
1252169689Skan	      "insn_constraint_len (lookup_constraint (s_))\n");
1253169689Skan      else
1254169689Skan	puts ("#define CONSTRAINT_LEN(c_,s_) 1\n");
1255169689Skan      if (have_register_constraints)
1256169689Skan	puts ("extern enum reg_class regclass_for_constraint "
1257169689Skan	      "(enum constraint_num);\n"
1258169689Skan	      "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n"
1259169689Skan	      "    regclass_for_constraint (lookup_constraint (s_))\n");
1260169689Skan      else
1261169689Skan	puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS");
1262169689Skan      if (have_const_int_constraints)
1263169689Skan	puts ("extern bool insn_const_int_ok_for_constraint "
1264169689Skan	      "(HOST_WIDE_INT, enum constraint_num);\n"
1265169689Skan	      "#define CONST_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n"
1266169689Skan	      "    insn_const_int_ok_for_constraint (v_, "
1267169689Skan	      "lookup_constraint (s_))\n");
1268169689Skan      if (have_const_dbl_constraints)
1269169689Skan	puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n"
1270169689Skan	      "    constraint_satisfied_p (v_, lookup_constraint (s_))\n");
1271169689Skan      else
1272169689Skan	puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n");
1273169689Skan      if (have_extra_constraints)
1274169689Skan	puts ("#define EXTRA_CONSTRAINT_STR(v_,c_,s_) \\\n"
1275169689Skan	      "    constraint_satisfied_p (v_, lookup_constraint (s_))\n");
1276169689Skan      if (have_memory_constraints)
1277169689Skan	puts ("extern bool "
1278169689Skan	      "insn_extra_memory_constraint (enum constraint_num);\n"
1279169689Skan	      "#define EXTRA_MEMORY_CONSTRAINT(c_,s_) "
1280169689Skan	      "insn_extra_memory_constraint (lookup_constraint (s_))\n");
1281169689Skan      else
1282169689Skan	puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) false\n");
1283169689Skan      if (have_address_constraints)
1284169689Skan	puts ("extern bool "
1285169689Skan	      "insn_extra_address_constraint (enum constraint_num);\n"
1286169689Skan	      "#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) "
1287169689Skan	      "insn_extra_address_constraint (lookup_constraint (s_))\n");
1288169689Skan      else
1289169689Skan	puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n");
1290169689Skan    }
1291169689Skan
1292169689Skan  puts ("#endif /* tm-preds.h */");
1293169689Skan}
1294169689Skan
1295169689Skan/* Write insn-preds.c.
1296169689Skan   N.B. the list of headers to include was copied from genrecog; it
1297169689Skan   may not be ideal.
1298169689Skan
1299169689Skan   FUTURE: Write #line markers referring back to the machine
1300169689Skan   description.  (Can't practically do this now since we don't know
1301169689Skan   the line number of the C block - just the line number of the enclosing
1302169689Skan   expression.)  */
1303169689Skanstatic void
1304169689Skanwrite_insn_preds_c (void)
1305169689Skan{
1306169689Skan  struct pred_data *p;
1307169689Skan
1308169689Skan  printf ("\
1309169689Skan/* Generated automatically by the program '%s'\n\
1310169689Skan   from the machine description file '%s'.  */\n\n", progname, in_fname);
1311169689Skan
1312169689Skan  puts ("\
1313169689Skan#include \"config.h\"\n\
1314169689Skan#include \"system.h\"\n\
1315169689Skan#include \"coretypes.h\"\n\
1316169689Skan#include \"tm.h\"\n\
1317169689Skan#include \"rtl.h\"\n\
1318169689Skan#include \"tree.h\"\n\
1319169689Skan#include \"tm_p.h\"\n\
1320169689Skan#include \"function.h\"\n\
1321169689Skan#include \"insn-config.h\"\n\
1322169689Skan#include \"recog.h\"\n\
1323169689Skan#include \"real.h\"\n\
1324169689Skan#include \"output.h\"\n\
1325169689Skan#include \"flags.h\"\n\
1326169689Skan#include \"hard-reg-set.h\"\n\
1327169689Skan#include \"resource.h\"\n\
1328169689Skan#include \"toplev.h\"\n\
1329169689Skan#include \"reload.h\"\n\
1330169689Skan#include \"regs.h\"\n\
1331169689Skan#include \"tm-constrs.h\"\n");
1332169689Skan
1333169689Skan  FOR_ALL_PREDICATES (p)
1334169689Skan    write_one_predicate_function (p);
1335169689Skan
1336169689Skan  if (constraint_max_namelen > 0)
1337169689Skan    {
1338169689Skan      write_lookup_constraint ();
1339169689Skan      write_regclass_for_constraint ();
1340169689Skan      write_constraint_satisfied_p ();
1341169689Skan
1342169689Skan      if (constraint_max_namelen > 1)
1343169689Skan	write_insn_constraint_len ();
1344169689Skan
1345169689Skan      if (have_const_int_constraints)
1346169689Skan	write_insn_const_int_ok_for_constraint ();
1347169689Skan
1348169689Skan      if (have_memory_constraints)
1349169689Skan	write_insn_extra_memory_constraint ();
1350169689Skan      if (have_address_constraints)
1351169689Skan	write_insn_extra_address_constraint ();
1352169689Skan    }
1353169689Skan}
1354169689Skan
1355169689Skan/* Argument parsing.  */
1356169689Skanstatic bool gen_header;
1357169689Skanstatic bool gen_constrs;
1358169689Skan
1359169689Skanstatic bool
1360169689Skanparse_option (const char *opt)
1361169689Skan{
1362169689Skan  if (!strcmp (opt, "-h"))
1363169689Skan    {
1364169689Skan      gen_header = true;
1365169689Skan      return 1;
1366169689Skan    }
1367169689Skan  else if (!strcmp (opt, "-c"))
1368169689Skan    {
1369169689Skan      gen_constrs = true;
1370169689Skan      return 1;
1371169689Skan    }
1372169689Skan  else
1373169689Skan    return 0;
1374169689Skan}
1375169689Skan
1376169689Skan/* Master control.  */
137790075Sobrienint
1378169689Skanmain (int argc, char **argv)
137990075Sobrien{
1380169689Skan  rtx defn;
1381169689Skan  int pattern_lineno, next_insn_code = 0;
138290075Sobrien
1383169689Skan  progname = argv[0];
1384169689Skan  if (argc <= 1)
1385169689Skan    fatal ("no input file name");
1386169689Skan  if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE)
1387169689Skan    return FATAL_EXIT_CODE;
138890075Sobrien
1389169689Skan  while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
1390169689Skan    switch (GET_CODE (defn))
1391169689Skan      {
1392169689Skan      case DEFINE_PREDICATE:
1393169689Skan      case DEFINE_SPECIAL_PREDICATE:
1394169689Skan	process_define_predicate (defn, pattern_lineno);
1395169689Skan	break;
139690075Sobrien
1397169689Skan      case DEFINE_CONSTRAINT:
1398169689Skan      case DEFINE_MEMORY_CONSTRAINT:
1399169689Skan      case DEFINE_ADDRESS_CONSTRAINT:
1400169689Skan	process_define_constraint (defn, pattern_lineno);
1401169689Skan	break;
1402169689Skan
1403169689Skan      case DEFINE_REGISTER_CONSTRAINT:
1404169689Skan	process_define_register_constraint (defn, pattern_lineno);
1405169689Skan	break;
1406169689Skan
1407169689Skan      default:
1408169689Skan	break;
1409169689Skan      }
1410169689Skan
1411169689Skan  if (gen_header)
1412169689Skan    write_tm_preds_h ();
1413169689Skan  else if (gen_constrs)
1414169689Skan    write_tm_constrs_h ();
1415169689Skan  else
1416169689Skan    write_insn_preds_c ();
1417169689Skan
1418169689Skan  if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
141990075Sobrien    return FATAL_EXIT_CODE;
142090075Sobrien
142190075Sobrien  return SUCCESS_EXIT_CODE;
142290075Sobrien}
1423