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