OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [genpreds.c] - Blame information for rev 294

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Generate from machine description:
2
   - prototype declarations for operand predicates (tm-preds.h)
3
   - function definitions of operand predicates, if defined new-style
4
     (insn-preds.c)
5
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007
6
   Free Software Foundation, Inc.
7
 
8
This file is part of GCC.
9
 
10
GCC is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 3, or (at your option)
13
any later version.
14
 
15
GCC is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
GNU General Public License for more details.
19
 
20
You should have received a copy of the GNU General Public License
21
along with GCC; see the file COPYING3.  If not see
22
<http://www.gnu.org/licenses/>.  */
23
 
24
#include "bconfig.h"
25
#include "system.h"
26
#include "coretypes.h"
27
#include "tm.h"
28
#include "rtl.h"
29
#include "errors.h"
30
#include "obstack.h"
31
#include "gensupport.h"
32
 
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.  */
37
static bool
38
validate_exp (rtx exp, const char *name, int lineno)
39
{
40
  if (exp == 0)
41
    {
42
      message_with_line (lineno, "%s: must give a predicate expression", name);
43
      return true;
44
    }
45
 
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);
60
 
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 */
77
 
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
    }
90
}
91
 
92
/* Predicates are defined with (define_predicate) or
93
   (define_special_predicate) expressions in the machine description.  */
94
static void
95
process_define_predicate (rtx defn, int lineno)
96
{
97
  struct pred_data *pred;
98
  const char *p;
99
 
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;
108
 
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);
113
 
114
  if (GET_CODE (defn) == DEFINE_SPECIAL_PREDICATE)
115
    pred->special = true;
116
 
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;
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
154
   an RTL template, so we have to handle "" strings.  */
155
 
156
 
157
static void
158
write_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)");
170
  match_test_str = XOBFINISH (rtl_obstack, const char *);
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);
186
  print_rtx_ptr_loc (p->c_block);
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
 
194
/* Given a predicate expression EXP, from form NAME, determine whether
195
   it refers to the variable given as VAR.  */
196
static bool
197
needs_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
 
247
/* Given an RTL expression EXP, find all subexpressions which we may
248
   assume to perform mode tests.  Normal MATCH_OPERAND does;
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.
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)
259
static void
260
mark_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));
269
        else if (p->special || GET_MODE (exp) != VOIDmode)
270
          NO_MODE_TEST (exp) = 1;
271
      }
272
      break;
273
 
274
    case MATCH_CODE:
275
      if (XSTR (exp, 1)[0] != '\0'
276
          || (!strstr (XSTR (exp, 0), "const_int")
277
              && !strstr (XSTR (exp, 0), "const_double")))
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:
315
      gcc_unreachable ();
316
    }
317
}
318
 
319
/* Determine whether the expression EXP is a MATCH_CODE that should
320
   be written as a switch statement.  */
321
static bool
322
generate_switch_p (rtx exp)
323
{
324
  return GET_CODE (exp) == MATCH_CODE
325
         && strchr (XSTR (exp, 0), ',');
326
}
327
 
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
 
334
static void
335
add_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;
370
 
371
      switch (GET_CODE (subexp))
372
        {
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
376
             push this AND down into the second operand of an existing
377
             AND expression.  */
378
          if (generate_switch_p (XEXP (subexp, 0)))
379
            pos = &XEXP (subexp, 1);
380
          goto break_loop;
381
 
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
408
                 the test.  */
409
              pos = &XEXP (subexp, 1);
410
            else
411
              pos = &XEXP (subexp, 2);
412
          }
413
          break;
414
 
415
        default:
416
          goto break_loop;
417
        }
418
    }
419
 break_loop:
420
  XEXP (and_exp, 0) = *pos;
421
  *pos = and_exp;
422
}
423
 
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.  */
428
static void
429
write_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
443
        gcc_unreachable ();
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
}
458
 
459
/* CODES is a list of RTX codes.  Write out an expression which
460
   determines whether the operand has one of those codes.  */
461
static void
462
write_match_code (const char *path, const char *codes)
463
{
464
  const char *code;
465
 
466
  while ((code = scan_comma_elt (&codes)) != 0)
467
    {
468
      fputs ("GET_CODE (", stdout);
469
      write_extract_subexp (path);
470
      fputs (") == ", stdout);
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.  */
484
static void
485
write_predicate_expr (rtx exp)
486
{
487
  switch (GET_CODE (exp))
488
    {
489
    case AND:
490
      putchar ('(');
491
      write_predicate_expr (XEXP (exp, 0));
492
      fputs (") && (", stdout);
493
      write_predicate_expr (XEXP (exp, 1));
494
      putchar (')');
495
      break;
496
 
497
    case IOR:
498
      putchar ('(');
499
      write_predicate_expr (XEXP (exp, 0));
500
      fputs (") || (", stdout);
501
      write_predicate_expr (XEXP (exp, 1));
502
      putchar (')');
503
      break;
504
 
505
    case NOT:
506
      fputs ("!(", stdout);
507
      write_predicate_expr (XEXP (exp, 0));
508
      putchar (')');
509
      break;
510
 
511
    case IF_THEN_ELSE:
512
      putchar ('(');
513
      write_predicate_expr (XEXP (exp, 0));
514
      fputs (") ? (", stdout);
515
      write_predicate_expr (XEXP (exp, 1));
516
      fputs (") : (", stdout);
517
      write_predicate_expr (XEXP (exp, 2));
518
      putchar (')');
519
      break;
520
 
521
    case MATCH_OPERAND:
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)]);
526
      break;
527
 
528
    case MATCH_CODE:
529
      write_match_code (XSTR (exp, 1), XSTR (exp, 0));
530
      break;
531
 
532
    case MATCH_TEST:
533
      print_c_condition (XSTR (exp, 0));
534
      break;
535
 
536
    default:
537
      gcc_unreachable ();
538
    }
539
}
540
 
541
/* Write the MATCH_CODE expression EXP as a switch statement.  */
542
 
543
static void
544
write_match_code_switch (rtx exp)
545
{
546
  const char *codes = XSTR (exp, 0);
547
  const char *path = XSTR (exp, 1);
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
 
566
/* Given a predicate expression EXP, write out a sequence of stmts
567
   to evaluate it.  This is similar to write_predicate_expr but can
568
   generate efficient switch statements.  */
569
 
570
static void
571
write_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
        }
610
      break;
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
 
634
/* Given a predicate, write out a complete C function to compute it.  */
635
static void
636
write_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.  */
646
  printf ("int\n%s (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n{\n",
647
          p->name);
648
  write_predicate_stmts (p->exp);
649
  fputs ("}\n\n", stdout);
650
}
651
 
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.  */
661
struct 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
 
681
static struct constraint_data *
682
constraints_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.  */
686
static struct constraint_data *first_constraint;
687
static 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.  */
694
static 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
 
699
static 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
 
704
static const char const_dbl_constraints[] = "GH";
705
 
706
/* Summary data used to decide whether to output various functions and
707
   macro definitions.  */
708
static unsigned int constraint_max_namelen;
709
static bool have_register_constraints;
710
static bool have_memory_constraints;
711
static bool have_address_constraints;
712
static bool have_extra_constraints;
713
static bool have_const_int_constraints;
714
static 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.  */
719
static const char *
720
mangle (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
 
746
static void
747
add_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
 
896
 
897
  c = obstack_alloc (rtl_obstack, sizeof (struct constraint_data));
898
  c->name = name;
899
  c->c_name = need_mangled_name ? mangle (name) : name;
900
  c->lineno = lineno;
901
  c->namelen = namelen;
902
  c->regclass = regclass;
903
  c->exp = exp;
904
  c->is_register = regclass != 0;
905
  c->is_const_int = is_const_int;
906
  c->is_const_dbl = is_const_dbl;
907
  c->is_extra = !(regclass || is_const_int || is_const_dbl);
908
  c->is_memory = is_memory;
909
  c->is_address = is_address;
910
 
911
  c->next_this_letter = *slot;
912
  *slot = c;
913
 
914
  /* Insert this constraint in the list of all constraints in textual
915
     order.  */
916
  c->next_textual = 0;
917
  *last_constraint_ptr = c;
918
  last_constraint_ptr = &c->next_textual;
919
 
920
  constraint_max_namelen = MAX (constraint_max_namelen, strlen (name));
921
  have_register_constraints |= c->is_register;
922
  have_const_int_constraints |= c->is_const_int;
923
  have_const_dbl_constraints |= c->is_const_dbl;
924
  have_extra_constraints |= c->is_extra;
925
  have_memory_constraints |= c->is_memory;
926
  have_address_constraints |= c->is_address;
927
}
928
 
929
/* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or
930
   DEFINE_ADDRESS_CONSTRAINT expression, C.  */
931
static void
932
process_define_constraint (rtx c, int lineno)
933
{
934
  add_constraint (XSTR (c, 0), 0, XEXP (c, 2),
935
                  GET_CODE (c) == DEFINE_MEMORY_CONSTRAINT,
936
                  GET_CODE (c) == DEFINE_ADDRESS_CONSTRAINT,
937
                  lineno);
938
}
939
 
940
/* Process a DEFINE_REGISTER_CONSTRAINT expression, C.  */
941
static void
942
process_define_register_constraint (rtx c, int lineno)
943
{
944
  add_constraint (XSTR (c, 0), XSTR (c, 1), 0, false, false, lineno);
945
}
946
 
947
/* Write out an enumeration with one entry per machine-specific
948
   constraint.  */
949
static void
950
write_enum_constraint_num (void)
951
{
952
  struct constraint_data *c;
953
 
954
  fputs ("enum constraint_num\n"
955
         "{\n"
956
         "  CONSTRAINT__UNKNOWN = 0", stdout);
957
  FOR_ALL_CONSTRAINTS (c)
958
    printf (",\n  CONSTRAINT_%s", c->c_name);
959
  puts ("\n};\n");
960
}
961
 
962
/* Write out a function which looks at a string and determines what
963
   constraint name, if any, it begins with.  */
964
static void
965
write_lookup_constraint (void)
966
{
967
  unsigned int i;
968
  puts ("enum constraint_num\n"
969
        "lookup_constraint (const char *str)\n"
970
        "{\n"
971
        "  switch (str[0])\n"
972
        "    {");
973
 
974
  for (i = 0; i < ARRAY_SIZE(constraints_by_letter_table); i++)
975
    {
976
      struct constraint_data *c = constraints_by_letter_table[i];
977
      if (!c)
978
        continue;
979
 
980
      printf ("    case '%c':\n", i);
981
      if (c->namelen == 1)
982
        printf ("      return CONSTRAINT_%s;\n", c->c_name);
983
      else
984
        {
985
          do
986
            {
987
              printf ("      if (!strncmp (str, \"%s\", %lu))\n"
988
                      "        return CONSTRAINT_%s;\n",
989
                      c->name, (unsigned long int) c->namelen, c->c_name);
990
              c = c->next_this_letter;
991
            }
992
          while (c);
993
          puts ("      break;");
994
        }
995
    }
996
 
997
  puts ("    default: break;\n"
998
        "    }\n"
999
        "  return CONSTRAINT__UNKNOWN;\n"
1000
        "}\n");
1001
}
1002
 
1003
/* Write out the function which computes constraint name lengths from
1004
   their enumerators. */
1005
static void
1006
write_insn_constraint_len (void)
1007
{
1008
  struct constraint_data *c;
1009
 
1010
  if (constraint_max_namelen == 1)
1011
    return;
1012
 
1013
  puts ("size_t\n"
1014
        "insn_constraint_len (enum constraint_num c)\n"
1015
        "{\n"
1016
        "  switch (c)\n"
1017
        "    {");
1018
 
1019
  FOR_ALL_CONSTRAINTS (c)
1020
    if (c->namelen > 1)
1021
      printf ("    case CONSTRAINT_%s: return %lu;\n", c->c_name,
1022
              (unsigned long int) c->namelen);
1023
 
1024
  puts ("    default: break;\n"
1025
        "    }\n"
1026
        "  return 1;\n"
1027
        "}\n");
1028
}
1029
 
1030
/* Write out the function which computes the register class corresponding
1031
   to a register constraint.  */
1032
static void
1033
write_regclass_for_constraint (void)
1034
{
1035
  struct constraint_data *c;
1036
 
1037
  puts ("enum reg_class\n"
1038
        "regclass_for_constraint (enum constraint_num c)\n"
1039
        "{\n"
1040
        "  switch (c)\n"
1041
        "    {");
1042
 
1043
  FOR_ALL_CONSTRAINTS (c)
1044
    if (c->is_register)
1045
      printf ("    case CONSTRAINT_%s: return %s;\n", c->c_name, c->regclass);
1046
 
1047
  puts ("    default: break;\n"
1048
        "    }\n"
1049
        "  return NO_REGS;\n"
1050
        "}\n");
1051
}
1052
 
1053
/* Write out the functions which compute whether a given value matches
1054
   a given non-register constraint.  */
1055
static void
1056
write_tm_constrs_h (void)
1057
{
1058
  struct constraint_data *c;
1059
 
1060
  printf ("\
1061
/* Generated automatically by the program '%s'\n\
1062
   from the machine description file '%s'.  */\n\n", progname, in_fname);
1063
 
1064
  puts ("\
1065
#ifndef GCC_TM_CONSTRS_H\n\
1066
#define GCC_TM_CONSTRS_H\n");
1067
 
1068
  FOR_ALL_CONSTRAINTS (c)
1069
    if (!c->is_register)
1070
      {
1071
        bool needs_ival = needs_variable (c->exp, "ival");
1072
        bool needs_hval = needs_variable (c->exp, "hval");
1073
        bool needs_lval = needs_variable (c->exp, "lval");
1074
        bool needs_rval = needs_variable (c->exp, "rval");
1075
        bool needs_mode = (needs_variable (c->exp, "mode")
1076
                           || needs_hval || needs_lval || needs_rval);
1077
        bool needs_op = (needs_variable (c->exp, "op")
1078
                         || needs_ival || needs_mode);
1079
 
1080
        printf ("static inline bool\n"
1081
                "satisfies_constraint_%s (rtx %s)\n"
1082
                "{\n", c->c_name,
1083
                needs_op ? "op" : "ARG_UNUSED (op)");
1084
        if (needs_mode)
1085
          puts ("enum machine_mode mode = GET_MODE (op);");
1086
        if (needs_ival)
1087
          puts ("  HOST_WIDE_INT ival = 0;");
1088
        if (needs_hval)
1089
          puts ("  HOST_WIDE_INT hval = 0;");
1090
        if (needs_lval)
1091
          puts ("  unsigned HOST_WIDE_INT lval = 0;");
1092
        if (needs_rval)
1093
          puts ("  const REAL_VALUE_TYPE *rval = 0;");
1094
 
1095
        if (needs_ival)
1096
          puts ("  if (GET_CODE (op) == CONST_INT)\n"
1097
                "    ival = INTVAL (op);");
1098
        if (needs_hval)
1099
          puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
1100
                "    hval = CONST_DOUBLE_HIGH (op);");
1101
        if (needs_lval)
1102
          puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
1103
                "    lval = CONST_DOUBLE_LOW (op);");
1104
        if (needs_rval)
1105
          puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode != VOIDmode)"
1106
                "    rval = CONST_DOUBLE_REAL_VALUE (op);");
1107
 
1108
        write_predicate_stmts (c->exp);
1109
        fputs ("}\n", stdout);
1110
      }
1111
  puts ("#endif /* tm-constrs.h */");
1112
}
1113
 
1114
/* Write out the wrapper function, constraint_satisfied_p, that maps
1115
   a CONSTRAINT_xxx constant to one of the predicate functions generated
1116
   above.  */
1117
static void
1118
write_constraint_satisfied_p (void)
1119
{
1120
  struct constraint_data *c;
1121
 
1122
  puts ("bool\n"
1123
        "constraint_satisfied_p (rtx op, enum constraint_num c)\n"
1124
        "{\n"
1125
        "  switch (c)\n"
1126
        "    {");
1127
 
1128
  FOR_ALL_CONSTRAINTS (c)
1129
    if (!c->is_register)
1130
      printf ("    case CONSTRAINT_%s: "
1131
              "return satisfies_constraint_%s (op);\n",
1132
              c->c_name, c->c_name);
1133
 
1134
  puts ("    default: break;\n"
1135
        "    }\n"
1136
        "  return false;\n"
1137
        "}\n");
1138
}
1139
 
1140
/* Write out the function which computes whether a given value matches
1141
   a given CONST_INT constraint.  This doesn't just forward to
1142
   constraint_satisfied_p because caller passes the INTVAL, not the RTX.  */
1143
static void
1144
write_insn_const_int_ok_for_constraint (void)
1145
{
1146
  struct constraint_data *c;
1147
 
1148
  puts ("bool\n"
1149
        "insn_const_int_ok_for_constraint (HOST_WIDE_INT ival, "
1150
                                          "enum constraint_num c)\n"
1151
        "{\n"
1152
        "  switch (c)\n"
1153
        "    {");
1154
 
1155
  FOR_ALL_CONSTRAINTS (c)
1156
    if (c->is_const_int)
1157
      {
1158
        printf ("    case CONSTRAINT_%s:\n      return ", c->c_name);
1159
        /* c->exp is guaranteed to be (and (match_code "const_int") (...));
1160
           we know at this point that we have a const_int, so we need not
1161
           bother with that part of the test.  */
1162
        write_predicate_expr (XEXP (c->exp, 1));
1163
        fputs (";\n\n", stdout);
1164
      }
1165
 
1166
  puts ("    default: break;\n"
1167
        "    }\n"
1168
        "  return false;\n"
1169
        "}\n");
1170
}
1171
 
1172
 
1173
/* Write out the function which computes whether a given constraint is
1174
   a memory constraint.  */
1175
static void
1176
write_insn_extra_memory_constraint (void)
1177
{
1178
  struct constraint_data *c;
1179
 
1180
  puts ("bool\n"
1181
        "insn_extra_memory_constraint (enum constraint_num c)\n"
1182
        "{\n"
1183
        "  switch (c)\n"
1184
        "    {");
1185
 
1186
  FOR_ALL_CONSTRAINTS (c)
1187
    if (c->is_memory)
1188
      printf ("    case CONSTRAINT_%s:\n      return true;\n\n", c->c_name);
1189
 
1190
  puts ("    default: break;\n"
1191
        "    }\n"
1192
        "  return false;\n"
1193
        "}\n");
1194
}
1195
 
1196
/* Write out the function which computes whether a given constraint is
1197
   an address constraint.  */
1198
static void
1199
write_insn_extra_address_constraint (void)
1200
{
1201
  struct constraint_data *c;
1202
 
1203
  puts ("bool\n"
1204
        "insn_extra_address_constraint (enum constraint_num c)\n"
1205
        "{\n"
1206
        "  switch (c)\n"
1207
        "    {");
1208
 
1209
  FOR_ALL_CONSTRAINTS (c)
1210
    if (c->is_address)
1211
      printf ("    case CONSTRAINT_%s:\n      return true;\n\n", c->c_name);
1212
 
1213
  puts ("    default: break;\n"
1214
        "    }\n"
1215
        "  return false;\n"
1216
        "}\n");
1217
}
1218
 
1219
 
1220
/* Write tm-preds.h.  Unfortunately, it is impossible to forward-declare
1221
   an enumeration in portable C, so we have to condition all these
1222
   prototypes on HAVE_MACHINE_MODES.  */
1223
static void
1224
write_tm_preds_h (void)
1225
{
1226
  struct pred_data *p;
1227
 
1228
  printf ("\
1229
/* Generated automatically by the program '%s'\n\
1230
   from the machine description file '%s'.  */\n\n", progname, in_fname);
1231
 
1232
  puts ("\
1233
#ifndef GCC_TM_PREDS_H\n\
1234
#define GCC_TM_PREDS_H\n\
1235
\n\
1236
#ifdef HAVE_MACHINE_MODES");
1237
 
1238
  FOR_ALL_PREDICATES (p)
1239
    printf ("extern int %s (rtx, enum machine_mode);\n", p->name);
1240
 
1241
  puts ("#endif /* HAVE_MACHINE_MODES */\n");
1242
 
1243
  if (constraint_max_namelen > 0)
1244
    {
1245
      write_enum_constraint_num ();
1246
      puts ("extern enum constraint_num lookup_constraint (const char *);\n"
1247
            "extern bool constraint_satisfied_p (rtx, enum constraint_num);\n");
1248
 
1249
      if (constraint_max_namelen > 1)
1250
        puts ("extern size_t insn_constraint_len (enum constraint_num);\n"
1251
              "#define CONSTRAINT_LEN(c_,s_) "
1252
              "insn_constraint_len (lookup_constraint (s_))\n");
1253
      else
1254
        puts ("#define CONSTRAINT_LEN(c_,s_) 1\n");
1255
      if (have_register_constraints)
1256
        puts ("extern enum reg_class regclass_for_constraint "
1257
              "(enum constraint_num);\n"
1258
              "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n"
1259
              "    regclass_for_constraint (lookup_constraint (s_))\n");
1260
      else
1261
        puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS");
1262
      if (have_const_int_constraints)
1263
        puts ("extern bool insn_const_int_ok_for_constraint "
1264
              "(HOST_WIDE_INT, enum constraint_num);\n"
1265
              "#define CONST_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n"
1266
              "    insn_const_int_ok_for_constraint (v_, "
1267
              "lookup_constraint (s_))\n");
1268
      if (have_const_dbl_constraints)
1269
        puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n"
1270
              "    constraint_satisfied_p (v_, lookup_constraint (s_))\n");
1271
      else
1272
        puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n");
1273
      if (have_extra_constraints)
1274
        puts ("#define EXTRA_CONSTRAINT_STR(v_,c_,s_) \\\n"
1275
              "    constraint_satisfied_p (v_, lookup_constraint (s_))\n");
1276
      if (have_memory_constraints)
1277
        puts ("extern bool "
1278
              "insn_extra_memory_constraint (enum constraint_num);\n"
1279
              "#define EXTRA_MEMORY_CONSTRAINT(c_,s_) "
1280
              "insn_extra_memory_constraint (lookup_constraint (s_))\n");
1281
      else
1282
        puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) false\n");
1283
      if (have_address_constraints)
1284
        puts ("extern bool "
1285
              "insn_extra_address_constraint (enum constraint_num);\n"
1286
              "#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) "
1287
              "insn_extra_address_constraint (lookup_constraint (s_))\n");
1288
      else
1289
        puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n");
1290
    }
1291
 
1292
  puts ("#endif /* tm-preds.h */");
1293
}
1294
 
1295
/* Write insn-preds.c.
1296
   N.B. the list of headers to include was copied from genrecog; it
1297
   may not be ideal.
1298
 
1299
   FUTURE: Write #line markers referring back to the machine
1300
   description.  (Can't practically do this now since we don't know
1301
   the line number of the C block - just the line number of the enclosing
1302
   expression.)  */
1303
static void
1304
write_insn_preds_c (void)
1305
{
1306
  struct pred_data *p;
1307
 
1308
  printf ("\
1309
/* Generated automatically by the program '%s'\n\
1310
   from the machine description file '%s'.  */\n\n", progname, in_fname);
1311
 
1312
  puts ("\
1313
#include \"config.h\"\n\
1314
#include \"system.h\"\n\
1315
#include \"coretypes.h\"\n\
1316
#include \"tm.h\"\n\
1317
#include \"rtl.h\"\n\
1318
#include \"tree.h\"\n\
1319
#include \"tm_p.h\"\n\
1320
#include \"function.h\"\n\
1321
#include \"insn-config.h\"\n\
1322
#include \"recog.h\"\n\
1323
#include \"real.h\"\n\
1324
#include \"output.h\"\n\
1325
#include \"flags.h\"\n\
1326
#include \"hard-reg-set.h\"\n\
1327
#include \"resource.h\"\n\
1328
#include \"toplev.h\"\n\
1329
#include \"reload.h\"\n\
1330
#include \"regs.h\"\n\
1331
#include \"tm-constrs.h\"\n");
1332
 
1333
  FOR_ALL_PREDICATES (p)
1334
    write_one_predicate_function (p);
1335
 
1336
  if (constraint_max_namelen > 0)
1337
    {
1338
      write_lookup_constraint ();
1339
      write_regclass_for_constraint ();
1340
      write_constraint_satisfied_p ();
1341
 
1342
      if (constraint_max_namelen > 1)
1343
        write_insn_constraint_len ();
1344
 
1345
      if (have_const_int_constraints)
1346
        write_insn_const_int_ok_for_constraint ();
1347
 
1348
      if (have_memory_constraints)
1349
        write_insn_extra_memory_constraint ();
1350
      if (have_address_constraints)
1351
        write_insn_extra_address_constraint ();
1352
    }
1353
}
1354
 
1355
/* Argument parsing.  */
1356
static bool gen_header;
1357
static bool gen_constrs;
1358
 
1359
static bool
1360
parse_option (const char *opt)
1361
{
1362
  if (!strcmp (opt, "-h"))
1363
    {
1364
      gen_header = true;
1365
      return 1;
1366
    }
1367
  else if (!strcmp (opt, "-c"))
1368
    {
1369
      gen_constrs = true;
1370
      return 1;
1371
    }
1372
  else
1373
    return 0;
1374
}
1375
 
1376
/* Master control.  */
1377
int
1378
main (int argc, char **argv)
1379
{
1380
  rtx defn;
1381
  int pattern_lineno, next_insn_code = 0;
1382
 
1383
  progname = argv[0];
1384
  if (argc <= 1)
1385
    fatal ("no input file name");
1386
  if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE)
1387
    return FATAL_EXIT_CODE;
1388
 
1389
  while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
1390
    switch (GET_CODE (defn))
1391
      {
1392
      case DEFINE_PREDICATE:
1393
      case DEFINE_SPECIAL_PREDICATE:
1394
        process_define_predicate (defn, pattern_lineno);
1395
        break;
1396
 
1397
      case DEFINE_CONSTRAINT:
1398
      case DEFINE_MEMORY_CONSTRAINT:
1399
      case DEFINE_ADDRESS_CONSTRAINT:
1400
        process_define_constraint (defn, pattern_lineno);
1401
        break;
1402
 
1403
      case DEFINE_REGISTER_CONSTRAINT:
1404
        process_define_register_constraint (defn, pattern_lineno);
1405
        break;
1406
 
1407
      default:
1408
        break;
1409
      }
1410
 
1411
  if (gen_header)
1412
    write_tm_preds_h ();
1413
  else if (gen_constrs)
1414
    write_tm_constrs_h ();
1415
  else
1416
    write_insn_preds_c ();
1417
 
1418
  if (have_error || ferror (stdout) || fflush (stdout) || fclose (stdout))
1419
    return FATAL_EXIT_CODE;
1420
 
1421
  return SUCCESS_EXIT_CODE;
1422
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.