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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [gensupport.c] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Support routines for the various generation passes.
2
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GCC.
6
 
7
   GCC is free software; you can redistribute it and/or modify it
8
   under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GCC is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GCC; see the file COPYING3.  If not see
19
   <http://www.gnu.org/licenses/>.  */
20
 
21
#include "bconfig.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "rtl.h"
26
#include "obstack.h"
27
#include "errors.h"
28
#include "hashtab.h"
29
#include "gensupport.h"
30
 
31
 
32
/* In case some macros used by files we include need it, define this here.  */
33
int target_flags;
34
 
35
int insn_elision = 1;
36
 
37
const char *in_fname;
38
 
39
/* This callback will be invoked whenever an rtl include directive is
40
   processed.  To be used for creation of the dependency file.  */
41
void (*include_callback) (const char *);
42
 
43
static struct obstack obstack;
44
struct obstack *rtl_obstack = &obstack;
45
 
46
static int sequence_num;
47
static int errors;
48
 
49
static int predicable_default;
50
static const char *predicable_true;
51
static const char *predicable_false;
52
 
53
static htab_t condition_table;
54
 
55
static char *base_dir = NULL;
56
 
57
/* We initially queue all patterns, process the define_insn and
58
   define_cond_exec patterns, then return them one at a time.  */
59
 
60
struct queue_elem
61
{
62
  rtx data;
63
  const char *filename;
64
  int lineno;
65
  struct queue_elem *next;
66
  /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
67
     points to the generated DEFINE_SPLIT.  */
68
  struct queue_elem *split;
69
};
70
 
71
static struct queue_elem *define_attr_queue;
72
static struct queue_elem **define_attr_tail = &define_attr_queue;
73
static struct queue_elem *define_pred_queue;
74
static struct queue_elem **define_pred_tail = &define_pred_queue;
75
static struct queue_elem *define_insn_queue;
76
static struct queue_elem **define_insn_tail = &define_insn_queue;
77
static struct queue_elem *define_cond_exec_queue;
78
static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
79
static struct queue_elem *other_queue;
80
static struct queue_elem **other_tail = &other_queue;
81
 
82
static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
83
                                         const char *, int);
84
 
85
/* Current maximum length of directory names in the search path
86
   for include files.  (Altered as we get more of them.)  */
87
 
88
size_t max_include_len;
89
 
90
struct file_name_list
91
  {
92
    struct file_name_list *next;
93
    const char *fname;
94
  };
95
 
96
struct file_name_list *first_dir_md_include = 0;  /* First dir to search */
97
        /* First dir to search for <file> */
98
struct file_name_list *first_bracket_include = 0;
99
struct file_name_list *last_dir_md_include = 0;        /* Last in chain */
100
 
101
static void remove_constraints (rtx);
102
static void process_rtx (rtx, int);
103
 
104
static int is_predicable (struct queue_elem *);
105
static void identify_predicable_attribute (void);
106
static int n_alternatives (const char *);
107
static void collect_insn_data (rtx, int *, int *);
108
static rtx alter_predicate_for_insn (rtx, int, int, int);
109
static const char *alter_test_for_insn (struct queue_elem *,
110
                                        struct queue_elem *);
111
static char *shift_output_template (char *, const char *, int);
112
static const char *alter_output_for_insn (struct queue_elem *,
113
                                          struct queue_elem *,
114
                                          int, int);
115
static void process_one_cond_exec (struct queue_elem *);
116
static void process_define_cond_exec (void);
117
static void process_include (rtx, int);
118
static char *save_string (const char *, int);
119
static void init_predicate_table (void);
120
static void record_insn_name (int, const char *);
121
 
122
void
123
message_with_line (int lineno, const char *msg, ...)
124
{
125
  va_list ap;
126
 
127
  va_start (ap, msg);
128
 
129
  fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
130
  vfprintf (stderr, msg, ap);
131
  fputc ('\n', stderr);
132
 
133
  va_end (ap);
134
}
135
 
136
/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
137
   the gensupport programs.  */
138
 
139
rtx
140
gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
141
                   HOST_WIDE_INT arg)
142
{
143
  rtx rt = rtx_alloc (CONST_INT);
144
 
145
  XWINT (rt, 0) = arg;
146
  return rt;
147
}
148
 
149
/* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
150
   element.  */
151
 
152
static struct queue_elem *
153
queue_pattern (rtx pattern, struct queue_elem ***list_tail,
154
               const char *filename, int lineno)
155
{
156
  struct queue_elem *e = XNEW(struct queue_elem);
157
  e->data = pattern;
158
  e->filename = filename;
159
  e->lineno = lineno;
160
  e->next = NULL;
161
  e->split = NULL;
162
  **list_tail = e;
163
  *list_tail = &e->next;
164
  return e;
165
}
166
 
167
/* Recursively remove constraints from an rtx.  */
168
 
169
static void
170
remove_constraints (rtx part)
171
{
172
  int i, j;
173
  const char *format_ptr;
174
 
175
  if (part == 0)
176
    return;
177
 
178
  if (GET_CODE (part) == MATCH_OPERAND)
179
    XSTR (part, 2) = "";
180
  else if (GET_CODE (part) == MATCH_SCRATCH)
181
    XSTR (part, 1) = "";
182
 
183
  format_ptr = GET_RTX_FORMAT (GET_CODE (part));
184
 
185
  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
186
    switch (*format_ptr++)
187
      {
188
      case 'e':
189
      case 'u':
190
        remove_constraints (XEXP (part, i));
191
        break;
192
      case 'E':
193
        if (XVEC (part, i) != NULL)
194
          for (j = 0; j < XVECLEN (part, i); j++)
195
            remove_constraints (XVECEXP (part, i, j));
196
        break;
197
      }
198
}
199
 
200
/* Process an include file assuming that it lives in gcc/config/{target}/
201
   if the include looks like (include "file").  */
202
 
203
static void
204
process_include (rtx desc, int lineno)
205
{
206
  const char *filename = XSTR (desc, 0);
207
  const char *old_filename;
208
  int old_lineno;
209
  char *pathname;
210
  FILE *input_file;
211
 
212
  /* If specified file name is absolute, skip the include stack.  */
213
  if (! IS_ABSOLUTE_PATH (filename))
214
    {
215
      struct file_name_list *stackp;
216
 
217
      /* Search directory path, trying to open the file.  */
218
      for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
219
        {
220
          static const char sep[2] = { DIR_SEPARATOR, '\0' };
221
 
222
          pathname = concat (stackp->fname, sep, filename, NULL);
223
          input_file = fopen (pathname, "r");
224
          if (input_file != NULL)
225
            goto success;
226
          free (pathname);
227
        }
228
    }
229
 
230
  if (base_dir)
231
    pathname = concat (base_dir, filename, NULL);
232
  else
233
    pathname = xstrdup (filename);
234
  input_file = fopen (pathname, "r");
235
  if (input_file == NULL)
236
    {
237
      free (pathname);
238
      message_with_line (lineno, "include file `%s' not found", filename);
239
      errors = 1;
240
      return;
241
    }
242
 success:
243
 
244
  /* Save old cursor; setup new for the new file.  Note that "lineno" the
245
     argument to this function is the beginning of the include statement,
246
     while read_rtx_lineno has already been advanced.  */
247
  old_filename = read_rtx_filename;
248
  old_lineno = read_rtx_lineno;
249
  read_rtx_filename = pathname;
250
  read_rtx_lineno = 1;
251
 
252
  if (include_callback)
253
    include_callback (pathname);
254
 
255
  /* Read the entire file.  */
256
  while (read_rtx (input_file, &desc, &lineno))
257
    process_rtx (desc, lineno);
258
 
259
  /* Do not free pathname.  It is attached to the various rtx queue
260
     elements.  */
261
 
262
  read_rtx_filename = old_filename;
263
  read_rtx_lineno = old_lineno;
264
 
265
  fclose (input_file);
266
}
267
 
268
/* Process a top level rtx in some way, queuing as appropriate.  */
269
 
270
static void
271
process_rtx (rtx desc, int lineno)
272
{
273
  switch (GET_CODE (desc))
274
    {
275
    case DEFINE_INSN:
276
      queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
277
      break;
278
 
279
    case DEFINE_COND_EXEC:
280
      queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
281
      break;
282
 
283
    case DEFINE_ATTR:
284
      queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
285
      break;
286
 
287
    case DEFINE_PREDICATE:
288
    case DEFINE_SPECIAL_PREDICATE:
289
    case DEFINE_CONSTRAINT:
290
    case DEFINE_REGISTER_CONSTRAINT:
291
    case DEFINE_MEMORY_CONSTRAINT:
292
    case DEFINE_ADDRESS_CONSTRAINT:
293
      queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
294
      break;
295
 
296
    case INCLUDE:
297
      process_include (desc, lineno);
298
      break;
299
 
300
    case DEFINE_INSN_AND_SPLIT:
301
      {
302
        const char *split_cond;
303
        rtx split;
304
        rtvec attr;
305
        int i;
306
        struct queue_elem *insn_elem;
307
        struct queue_elem *split_elem;
308
 
309
        /* Create a split with values from the insn_and_split.  */
310
        split = rtx_alloc (DEFINE_SPLIT);
311
 
312
        i = XVECLEN (desc, 1);
313
        XVEC (split, 0) = rtvec_alloc (i);
314
        while (--i >= 0)
315
          {
316
            XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
317
            remove_constraints (XVECEXP (split, 0, i));
318
          }
319
 
320
        /* If the split condition starts with "&&", append it to the
321
           insn condition to create the new split condition.  */
322
        split_cond = XSTR (desc, 4);
323
        if (split_cond[0] == '&' && split_cond[1] == '&')
324
          {
325
            copy_rtx_ptr_loc (split_cond + 2, split_cond);
326
            split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
327
          }
328
        XSTR (split, 1) = split_cond;
329
        XVEC (split, 2) = XVEC (desc, 5);
330
        XSTR (split, 3) = XSTR (desc, 6);
331
 
332
        /* Fix up the DEFINE_INSN.  */
333
        attr = XVEC (desc, 7);
334
        PUT_CODE (desc, DEFINE_INSN);
335
        XVEC (desc, 4) = attr;
336
 
337
        /* Queue them.  */
338
        insn_elem
339
          = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
340
                           lineno);
341
        split_elem
342
          = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
343
        insn_elem->split = split_elem;
344
        break;
345
      }
346
 
347
    default:
348
      queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
349
      break;
350
    }
351
}
352
 
353
/* Return true if attribute PREDICABLE is true for ELEM, which holds
354
   a DEFINE_INSN.  */
355
 
356
static int
357
is_predicable (struct queue_elem *elem)
358
{
359
  rtvec vec = XVEC (elem->data, 4);
360
  const char *value;
361
  int i;
362
 
363
  if (! vec)
364
    return predicable_default;
365
 
366
  for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
367
    {
368
      rtx sub = RTVEC_ELT (vec, i);
369
      switch (GET_CODE (sub))
370
        {
371
        case SET_ATTR:
372
          if (strcmp (XSTR (sub, 0), "predicable") == 0)
373
            {
374
              value = XSTR (sub, 1);
375
              goto found;
376
            }
377
          break;
378
 
379
        case SET_ATTR_ALTERNATIVE:
380
          if (strcmp (XSTR (sub, 0), "predicable") == 0)
381
            {
382
              message_with_line (elem->lineno,
383
                                 "multiple alternatives for `predicable'");
384
              errors = 1;
385
              return 0;
386
            }
387
          break;
388
 
389
        case SET:
390
          if (GET_CODE (SET_DEST (sub)) != ATTR
391
              || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
392
            break;
393
          sub = SET_SRC (sub);
394
          if (GET_CODE (sub) == CONST_STRING)
395
            {
396
              value = XSTR (sub, 0);
397
              goto found;
398
            }
399
 
400
          /* ??? It would be possible to handle this if we really tried.
401
             It's not easy though, and I'm not going to bother until it
402
             really proves necessary.  */
403
          message_with_line (elem->lineno,
404
                             "non-constant value for `predicable'");
405
          errors = 1;
406
          return 0;
407
 
408
        default:
409
          gcc_unreachable ();
410
        }
411
    }
412
 
413
  return predicable_default;
414
 
415
 found:
416
  /* Verify that predicability does not vary on the alternative.  */
417
  /* ??? It should be possible to handle this by simply eliminating
418
     the non-predicable alternatives from the insn.  FRV would like
419
     to do this.  Delay this until we've got the basics solid.  */
420
  if (strchr (value, ',') != NULL)
421
    {
422
      message_with_line (elem->lineno,
423
                         "multiple alternatives for `predicable'");
424
      errors = 1;
425
      return 0;
426
    }
427
 
428
  /* Find out which value we're looking at.  */
429
  if (strcmp (value, predicable_true) == 0)
430
    return 1;
431
  if (strcmp (value, predicable_false) == 0)
432
    return 0;
433
 
434
  message_with_line (elem->lineno,
435
                     "unknown value `%s' for `predicable' attribute",
436
                     value);
437
  errors = 1;
438
  return 0;
439
}
440
 
441
/* Examine the attribute "predicable"; discover its boolean values
442
   and its default.  */
443
 
444
static void
445
identify_predicable_attribute (void)
446
{
447
  struct queue_elem *elem;
448
  char *p_true, *p_false;
449
  const char *value;
450
 
451
  /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
452
  for (elem = define_attr_queue; elem ; elem = elem->next)
453
    if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
454
      goto found;
455
 
456
  message_with_line (define_cond_exec_queue->lineno,
457
                     "attribute `predicable' not defined");
458
  errors = 1;
459
  return;
460
 
461
 found:
462
  value = XSTR (elem->data, 1);
463
  p_false = xstrdup (value);
464
  p_true = strchr (p_false, ',');
465
  if (p_true == NULL || strchr (++p_true, ',') != NULL)
466
    {
467
      message_with_line (elem->lineno,
468
                         "attribute `predicable' is not a boolean");
469
      errors = 1;
470
      if (p_false)
471
        free (p_false);
472
      return;
473
    }
474
  p_true[-1] = '\0';
475
 
476
  predicable_true = p_true;
477
  predicable_false = p_false;
478
 
479
  switch (GET_CODE (XEXP (elem->data, 2)))
480
    {
481
    case CONST_STRING:
482
      value = XSTR (XEXP (elem->data, 2), 0);
483
      break;
484
 
485
    case CONST:
486
      message_with_line (elem->lineno,
487
                         "attribute `predicable' cannot be const");
488
      errors = 1;
489
      if (p_false)
490
        free (p_false);
491
      return;
492
 
493
    default:
494
      message_with_line (elem->lineno,
495
                         "attribute `predicable' must have a constant default");
496
      errors = 1;
497
      if (p_false)
498
        free (p_false);
499
      return;
500
    }
501
 
502
  if (strcmp (value, p_true) == 0)
503
    predicable_default = 1;
504
  else if (strcmp (value, p_false) == 0)
505
    predicable_default = 0;
506
  else
507
    {
508
      message_with_line (elem->lineno,
509
                         "unknown value `%s' for `predicable' attribute",
510
                         value);
511
      errors = 1;
512
      if (p_false)
513
        free (p_false);
514
    }
515
}
516
 
517
/* Return the number of alternatives in constraint S.  */
518
 
519
static int
520
n_alternatives (const char *s)
521
{
522
  int n = 1;
523
 
524
  if (s)
525
    while (*s)
526
      n += (*s++ == ',');
527
 
528
  return n;
529
}
530
 
531
/* Determine how many alternatives there are in INSN, and how many
532
   operands.  */
533
 
534
static void
535
collect_insn_data (rtx pattern, int *palt, int *pmax)
536
{
537
  const char *fmt;
538
  enum rtx_code code;
539
  int i, j, len;
540
 
541
  code = GET_CODE (pattern);
542
  switch (code)
543
    {
544
    case MATCH_OPERAND:
545
      i = n_alternatives (XSTR (pattern, 2));
546
      *palt = (i > *palt ? i : *palt);
547
      /* Fall through.  */
548
 
549
    case MATCH_OPERATOR:
550
    case MATCH_SCRATCH:
551
    case MATCH_PARALLEL:
552
      i = XINT (pattern, 0);
553
      if (i > *pmax)
554
        *pmax = i;
555
      break;
556
 
557
    default:
558
      break;
559
    }
560
 
561
  fmt = GET_RTX_FORMAT (code);
562
  len = GET_RTX_LENGTH (code);
563
  for (i = 0; i < len; i++)
564
    {
565
      switch (fmt[i])
566
        {
567
        case 'e': case 'u':
568
          collect_insn_data (XEXP (pattern, i), palt, pmax);
569
          break;
570
 
571
        case 'V':
572
          if (XVEC (pattern, i) == NULL)
573
            break;
574
          /* Fall through.  */
575
        case 'E':
576
          for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
577
            collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
578
          break;
579
 
580
        case 'i': case 'w': case '0': case 's': case 'S': case 'T':
581
          break;
582
 
583
        default:
584
          gcc_unreachable ();
585
        }
586
    }
587
}
588
 
589
static rtx
590
alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
591
{
592
  const char *fmt;
593
  enum rtx_code code;
594
  int i, j, len;
595
 
596
  code = GET_CODE (pattern);
597
  switch (code)
598
    {
599
    case MATCH_OPERAND:
600
      {
601
        const char *c = XSTR (pattern, 2);
602
 
603
        if (n_alternatives (c) != 1)
604
          {
605
            message_with_line (lineno,
606
                               "too many alternatives for operand %d",
607
                               XINT (pattern, 0));
608
            errors = 1;
609
            return NULL;
610
          }
611
 
612
        /* Replicate C as needed to fill out ALT alternatives.  */
613
        if (c && *c && alt > 1)
614
          {
615
            size_t c_len = strlen (c);
616
            size_t len = alt * (c_len + 1);
617
            char *new_c = XNEWVEC(char, len);
618
 
619
            memcpy (new_c, c, c_len);
620
            for (i = 1; i < alt; ++i)
621
              {
622
                new_c[i * (c_len + 1) - 1] = ',';
623
                memcpy (&new_c[i * (c_len + 1)], c, c_len);
624
              }
625
            new_c[len - 1] = '\0';
626
            XSTR (pattern, 2) = new_c;
627
          }
628
      }
629
      /* Fall through.  */
630
 
631
    case MATCH_OPERATOR:
632
    case MATCH_SCRATCH:
633
    case MATCH_PARALLEL:
634
      XINT (pattern, 0) += max_op;
635
      break;
636
 
637
    default:
638
      break;
639
    }
640
 
641
  fmt = GET_RTX_FORMAT (code);
642
  len = GET_RTX_LENGTH (code);
643
  for (i = 0; i < len; i++)
644
    {
645
      rtx r;
646
 
647
      switch (fmt[i])
648
        {
649
        case 'e': case 'u':
650
          r = alter_predicate_for_insn (XEXP (pattern, i), alt,
651
                                        max_op, lineno);
652
          if (r == NULL)
653
            return r;
654
          break;
655
 
656
        case 'E':
657
          for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
658
            {
659
              r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
660
                                            alt, max_op, lineno);
661
              if (r == NULL)
662
                return r;
663
            }
664
          break;
665
 
666
        case 'i': case 'w': case '0': case 's':
667
          break;
668
 
669
        default:
670
          gcc_unreachable ();
671
        }
672
    }
673
 
674
  return pattern;
675
}
676
 
677
static const char *
678
alter_test_for_insn (struct queue_elem *ce_elem,
679
                     struct queue_elem *insn_elem)
680
{
681
  return join_c_conditions (XSTR (ce_elem->data, 1),
682
                            XSTR (insn_elem->data, 2));
683
}
684
 
685
/* Adjust all of the operand numbers in SRC to match the shift they'll
686
   get from an operand displacement of DISP.  Return a pointer after the
687
   adjusted string.  */
688
 
689
static char *
690
shift_output_template (char *dest, const char *src, int disp)
691
{
692
  while (*src)
693
    {
694
      char c = *src++;
695
      *dest++ = c;
696
      if (c == '%')
697
        {
698
          c = *src++;
699
          if (ISDIGIT ((unsigned char) c))
700
            c += disp;
701
          else if (ISALPHA (c))
702
            {
703
              *dest++ = c;
704
              c = *src++ + disp;
705
            }
706
          *dest++ = c;
707
        }
708
    }
709
 
710
  return dest;
711
}
712
 
713
static const char *
714
alter_output_for_insn (struct queue_elem *ce_elem,
715
                       struct queue_elem *insn_elem,
716
                       int alt, int max_op)
717
{
718
  const char *ce_out, *insn_out;
719
  char *result, *p;
720
  size_t len, ce_len, insn_len;
721
 
722
  /* ??? Could coordinate with genoutput to not duplicate code here.  */
723
 
724
  ce_out = XSTR (ce_elem->data, 2);
725
  insn_out = XTMPL (insn_elem->data, 3);
726
  if (!ce_out || *ce_out == '\0')
727
    return insn_out;
728
 
729
  ce_len = strlen (ce_out);
730
  insn_len = strlen (insn_out);
731
 
732
  if (*insn_out == '*')
733
    /* You must take care of the predicate yourself.  */
734
    return insn_out;
735
 
736
  if (*insn_out == '@')
737
    {
738
      len = (ce_len + 1) * alt + insn_len + 1;
739
      p = result = XNEWVEC(char, len);
740
 
741
      do
742
        {
743
          do
744
            *p++ = *insn_out++;
745
          while (ISSPACE ((unsigned char) *insn_out));
746
 
747
          if (*insn_out != '#')
748
            {
749
              p = shift_output_template (p, ce_out, max_op);
750
              *p++ = ' ';
751
            }
752
 
753
          do
754
            *p++ = *insn_out++;
755
          while (*insn_out && *insn_out != '\n');
756
        }
757
      while (*insn_out);
758
      *p = '\0';
759
    }
760
  else
761
    {
762
      len = ce_len + 1 + insn_len + 1;
763
      result = XNEWVEC (char, len);
764
 
765
      p = shift_output_template (result, ce_out, max_op);
766
      *p++ = ' ';
767
      memcpy (p, insn_out, insn_len + 1);
768
    }
769
 
770
  return result;
771
}
772
 
773
/* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
774
 
775
static void
776
process_one_cond_exec (struct queue_elem *ce_elem)
777
{
778
  struct queue_elem *insn_elem;
779
  for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
780
    {
781
      int alternatives, max_operand;
782
      rtx pred, insn, pattern, split;
783
      int i;
784
 
785
      if (! is_predicable (insn_elem))
786
        continue;
787
 
788
      alternatives = 1;
789
      max_operand = -1;
790
      collect_insn_data (insn_elem->data, &alternatives, &max_operand);
791
      max_operand += 1;
792
 
793
      if (XVECLEN (ce_elem->data, 0) != 1)
794
        {
795
          message_with_line (ce_elem->lineno,
796
                             "too many patterns in predicate");
797
          errors = 1;
798
          return;
799
        }
800
 
801
      pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
802
      pred = alter_predicate_for_insn (pred, alternatives, max_operand,
803
                                       ce_elem->lineno);
804
      if (pred == NULL)
805
        return;
806
 
807
      /* Construct a new pattern for the new insn.  */
808
      insn = copy_rtx (insn_elem->data);
809
      XSTR (insn, 0) = "";
810
      pattern = rtx_alloc (COND_EXEC);
811
      XEXP (pattern, 0) = pred;
812
      if (XVECLEN (insn, 1) == 1)
813
        {
814
          XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
815
          XVECEXP (insn, 1, 0) = pattern;
816
          PUT_NUM_ELEM (XVEC (insn, 1), 1);
817
        }
818
      else
819
        {
820
          XEXP (pattern, 1) = rtx_alloc (PARALLEL);
821
          XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
822
          XVEC (insn, 1) = rtvec_alloc (1);
823
          XVECEXP (insn, 1, 0) = pattern;
824
        }
825
 
826
      XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
827
      XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
828
                                              alternatives, max_operand);
829
 
830
      /* ??? Set `predicable' to false.  Not crucial since it's really
831
         only used here, and we won't reprocess this new pattern.  */
832
 
833
      /* Put the new pattern on the `other' list so that it
834
         (a) is not reprocessed by other define_cond_exec patterns
835
         (b) appears after all normal define_insn patterns.
836
 
837
         ??? B is debatable.  If one has normal insns that match
838
         cond_exec patterns, they will be preferred over these
839
         generated patterns.  Whether this matters in practice, or if
840
         it's a good thing, or whether we should thread these new
841
         patterns into the define_insn chain just after their generator
842
         is something we'll have to experiment with.  */
843
 
844
      queue_pattern (insn, &other_tail, insn_elem->filename,
845
                     insn_elem->lineno);
846
 
847
      if (!insn_elem->split)
848
        continue;
849
 
850
      /* If the original insn came from a define_insn_and_split,
851
         generate a new split to handle the predicated insn.  */
852
      split = copy_rtx (insn_elem->split->data);
853
      /* Predicate the pattern matched by the split.  */
854
      pattern = rtx_alloc (COND_EXEC);
855
      XEXP (pattern, 0) = pred;
856
      if (XVECLEN (split, 0) == 1)
857
        {
858
          XEXP (pattern, 1) = XVECEXP (split, 0, 0);
859
          XVECEXP (split, 0, 0) = pattern;
860
          PUT_NUM_ELEM (XVEC (split, 0), 1);
861
        }
862
      else
863
        {
864
          XEXP (pattern, 1) = rtx_alloc (PARALLEL);
865
          XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
866
          XVEC (split, 0) = rtvec_alloc (1);
867
          XVECEXP (split, 0, 0) = pattern;
868
        }
869
      /* Predicate all of the insns generated by the split.  */
870
      for (i = 0; i < XVECLEN (split, 2); i++)
871
        {
872
          pattern = rtx_alloc (COND_EXEC);
873
          XEXP (pattern, 0) = pred;
874
          XEXP (pattern, 1) = XVECEXP (split, 2, i);
875
          XVECEXP (split, 2, i) = pattern;
876
        }
877
      /* Add the new split to the queue.  */
878
      queue_pattern (split, &other_tail, read_rtx_filename,
879
                     insn_elem->split->lineno);
880
    }
881
}
882
 
883
/* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
884
   patterns appropriately.  */
885
 
886
static void
887
process_define_cond_exec (void)
888
{
889
  struct queue_elem *elem;
890
 
891
  identify_predicable_attribute ();
892
  if (errors)
893
    return;
894
 
895
  for (elem = define_cond_exec_queue; elem ; elem = elem->next)
896
    process_one_cond_exec (elem);
897
}
898
 
899
static char *
900
save_string (const char *s, int len)
901
{
902
  char *result = XNEWVEC (char, len + 1);
903
 
904
  memcpy (result, s, len);
905
  result[len] = 0;
906
  return result;
907
}
908
 
909
 
910
/* The entry point for initializing the reader.  */
911
 
912
int
913
init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
914
{
915
  FILE *input_file;
916
  int c, i, lineno;
917
  char *lastsl;
918
  rtx desc;
919
  bool no_more_options;
920
  bool already_read_stdin;
921
 
922
  /* Unlock the stdio streams.  */
923
  unlock_std_streams ();
924
 
925
  /* First we loop over all the options.  */
926
  for (i = 1; i < argc; i++)
927
    {
928
      if (argv[i][0] != '-')
929
        continue;
930
 
931
      c = argv[i][1];
932
      switch (c)
933
        {
934
        case 'I':               /* Add directory to path for includes.  */
935
          {
936
            struct file_name_list *dirtmp;
937
 
938
            dirtmp = XNEW (struct file_name_list);
939
            dirtmp->next = 0;    /* New one goes on the end */
940
            if (first_dir_md_include == 0)
941
              first_dir_md_include = dirtmp;
942
            else
943
              last_dir_md_include->next = dirtmp;
944
            last_dir_md_include = dirtmp;       /* Tail follows the last one */
945
            if (argv[i][1] == 'I' && argv[i][2] != 0)
946
              dirtmp->fname = argv[i] + 2;
947
            else if (i + 1 == argc)
948
              fatal ("directory name missing after -I option");
949
            else
950
              dirtmp->fname = argv[++i];
951
            if (strlen (dirtmp->fname) > max_include_len)
952
              max_include_len = strlen (dirtmp->fname);
953
          }
954
          break;
955
 
956
        case '\0':
957
          /* An argument consisting of exactly one dash is a request to
958
             read stdin.  This will be handled in the second loop.  */
959
          continue;
960
 
961
        case '-':
962
          /* An argument consisting of just two dashes causes option
963
             parsing to cease.  */
964
          if (argv[i][2] == '\0')
965
            goto stop_parsing_options;
966
 
967
        default:
968
          /* The program may have provided a callback so it can
969
             accept its own options.  */
970
          if (parse_opt && parse_opt (argv[i]))
971
            break;
972
 
973
          fatal ("invalid option `%s'", argv[i]);
974
        }
975
    }
976
 
977
 stop_parsing_options:
978
 
979
  /* Prepare to read input.  */
980
  condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
981
  init_predicate_table ();
982
  obstack_init (rtl_obstack);
983
  errors = 0;
984
  sequence_num = 0;
985
  no_more_options = false;
986
  already_read_stdin = false;
987
 
988
 
989
  /* Now loop over all input files.  */
990
  for (i = 1; i < argc; i++)
991
    {
992
      if (argv[i][0] == '-')
993
        {
994
          if (argv[i][1] == '\0')
995
            {
996
              /* Read stdin.  */
997
              if (already_read_stdin)
998
                fatal ("cannot read standard input twice");
999
 
1000
              base_dir = NULL;
1001
              read_rtx_filename = in_fname = "<stdin>";
1002
              read_rtx_lineno = 1;
1003
              input_file = stdin;
1004
              already_read_stdin = true;
1005
 
1006
              while (read_rtx (input_file, &desc, &lineno))
1007
                process_rtx (desc, lineno);
1008
              fclose (input_file);
1009
              continue;
1010
            }
1011
          else if (argv[i][1] == '-' && argv[i][2] == '\0')
1012
            {
1013
              /* No further arguments are to be treated as options.  */
1014
              no_more_options = true;
1015
              continue;
1016
            }
1017
          else if (!no_more_options)
1018
            continue;
1019
        }
1020
 
1021
      /* If we get here we are looking at a non-option argument, i.e.
1022
         a file to be processed.  */
1023
 
1024
      in_fname = argv[i];
1025
      lastsl = strrchr (in_fname, '/');
1026
      if (lastsl != NULL)
1027
        base_dir = save_string (in_fname, lastsl - in_fname + 1 );
1028
      else
1029
        base_dir = NULL;
1030
 
1031
      read_rtx_filename = in_fname;
1032
      read_rtx_lineno = 1;
1033
      input_file = fopen (in_fname, "r");
1034
      if (input_file == 0)
1035
        {
1036
          perror (in_fname);
1037
          return FATAL_EXIT_CODE;
1038
        }
1039
 
1040
      while (read_rtx (input_file, &desc, &lineno))
1041
        process_rtx (desc, lineno);
1042
      fclose (input_file);
1043
    }
1044
 
1045
  /* If we get to this point without having seen any files to process,
1046
     read standard input now.  */
1047
  if (!in_fname)
1048
    {
1049
      base_dir = NULL;
1050
      read_rtx_filename = in_fname = "<stdin>";
1051
      read_rtx_lineno = 1;
1052
      input_file = stdin;
1053
 
1054
      while (read_rtx (input_file, &desc, &lineno))
1055
        process_rtx (desc, lineno);
1056
      fclose (input_file);
1057
    }
1058
 
1059
  /* Process define_cond_exec patterns.  */
1060
  if (define_cond_exec_queue != NULL)
1061
    process_define_cond_exec ();
1062
 
1063
  return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
1064
}
1065
 
1066
/* Programs that don't have their own options can use this entry point
1067
   instead.  */
1068
int
1069
init_md_reader_args (int argc, char **argv)
1070
{
1071
  return init_md_reader_args_cb (argc, argv, 0);
1072
}
1073
 
1074
/* The entry point for reading a single rtx from an md file.  */
1075
 
1076
rtx
1077
read_md_rtx (int *lineno, int *seqnr)
1078
{
1079
  struct queue_elem **queue, *elem;
1080
  rtx desc;
1081
 
1082
 discard:
1083
 
1084
  /* Read all patterns from a given queue before moving on to the next.  */
1085
  if (define_attr_queue != NULL)
1086
    queue = &define_attr_queue;
1087
  else if (define_pred_queue != NULL)
1088
    queue = &define_pred_queue;
1089
  else if (define_insn_queue != NULL)
1090
    queue = &define_insn_queue;
1091
  else if (other_queue != NULL)
1092
    queue = &other_queue;
1093
  else
1094
    return NULL_RTX;
1095
 
1096
  elem = *queue;
1097
  *queue = elem->next;
1098
  desc = elem->data;
1099
  read_rtx_filename = elem->filename;
1100
  *lineno = elem->lineno;
1101
  *seqnr = sequence_num;
1102
 
1103
  free (elem);
1104
 
1105
  /* Discard insn patterns which we know can never match (because
1106
     their C test is provably always false).  If insn_elision is
1107
     false, our caller needs to see all the patterns.  Note that the
1108
     elided patterns are never counted by the sequence numbering; it
1109
     it is the caller's responsibility, when insn_elision is false, not
1110
     to use elided pattern numbers for anything.  */
1111
  switch (GET_CODE (desc))
1112
    {
1113
    case DEFINE_INSN:
1114
    case DEFINE_EXPAND:
1115
      if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1116
        sequence_num++;
1117
      else if (insn_elision)
1118
        goto discard;
1119
 
1120
      /* *seqnr is used here so the name table will match caller's
1121
         idea of insn numbering, whether or not elision is active.  */
1122
      record_insn_name (*seqnr, XSTR (desc, 0));
1123
      break;
1124
 
1125
    case DEFINE_SPLIT:
1126
    case DEFINE_PEEPHOLE:
1127
    case DEFINE_PEEPHOLE2:
1128
      if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1129
        sequence_num++;
1130
      else if (insn_elision)
1131
            goto discard;
1132
      break;
1133
 
1134
    default:
1135
      break;
1136
    }
1137
 
1138
  return desc;
1139
}
1140
 
1141
/* Helper functions for insn elision.  */
1142
 
1143
/* Compute a hash function of a c_test structure, which is keyed
1144
   by its ->expr field.  */
1145
hashval_t
1146
hash_c_test (const void *x)
1147
{
1148
  const struct c_test *a = (const struct c_test *) x;
1149
  const unsigned char *base, *s = (const unsigned char *) a->expr;
1150
  hashval_t hash;
1151
  unsigned char c;
1152
  unsigned int len;
1153
 
1154
  base = s;
1155
  hash = 0;
1156
 
1157
  while ((c = *s++) != '\0')
1158
    {
1159
      hash += c + (c << 17);
1160
      hash ^= hash >> 2;
1161
    }
1162
 
1163
  len = s - base;
1164
  hash += len + (len << 17);
1165
  hash ^= hash >> 2;
1166
 
1167
  return hash;
1168
}
1169
 
1170
/* Compare two c_test expression structures.  */
1171
int
1172
cmp_c_test (const void *x, const void *y)
1173
{
1174
  const struct c_test *a = (const struct c_test *) x;
1175
  const struct c_test *b = (const struct c_test *) y;
1176
 
1177
  return !strcmp (a->expr, b->expr);
1178
}
1179
 
1180
/* Given a string representing a C test expression, look it up in the
1181
   condition_table and report whether or not its value is known
1182
   at compile time.  Returns a tristate: 1 for known true, 0 for
1183
   known false, -1 for unknown.  */
1184
int
1185
maybe_eval_c_test (const char *expr)
1186
{
1187
  const struct c_test *test;
1188
  struct c_test dummy;
1189
 
1190
  if (expr[0] == 0)
1191
    return 1;
1192
 
1193
  dummy.expr = expr;
1194
  test = (const struct c_test *)htab_find (condition_table, &dummy);
1195
  if (!test)
1196
    return -1;
1197
  return test->value;
1198
}
1199
 
1200
/* Record the C test expression EXPR in the condition_table, with
1201
   value VAL.  Duplicates clobber previous entries.  */
1202
 
1203
void
1204
add_c_test (const char *expr, int value)
1205
{
1206
  struct c_test *test;
1207
 
1208
  if (expr[0] == 0)
1209
    return;
1210
 
1211
  test = XNEW (struct c_test);
1212
  test->expr = expr;
1213
  test->value = value;
1214
 
1215
  *(htab_find_slot (condition_table, test, INSERT)) = test;
1216
}
1217
 
1218
/* For every C test, call CALLBACK with two arguments: a pointer to
1219
   the condition structure and INFO.  Stops when CALLBACK returns zero.  */
1220
void
1221
traverse_c_tests (htab_trav callback, void *info)
1222
{
1223
  if (condition_table)
1224
    htab_traverse (condition_table, callback, info);
1225
}
1226
 
1227
 
1228
/* Given a string, return the number of comma-separated elements in it.
1229
   Return 0 for the null string.  */
1230
int
1231
n_comma_elts (const char *s)
1232
{
1233
  int n;
1234
 
1235
  if (*s == '\0')
1236
    return 0;
1237
 
1238
  for (n = 1; *s; s++)
1239
    if (*s == ',')
1240
      n++;
1241
 
1242
  return n;
1243
}
1244
 
1245
/* Given a pointer to a (char *), return a pointer to the beginning of the
1246
   next comma-separated element in the string.  Advance the pointer given
1247
   to the end of that element.  Return NULL if at end of string.  Caller
1248
   is responsible for copying the string if necessary.  White space between
1249
   a comma and an element is ignored.  */
1250
 
1251
const char *
1252
scan_comma_elt (const char **pstr)
1253
{
1254
  const char *start;
1255
  const char *p = *pstr;
1256
 
1257
  if (*p == ',')
1258
    p++;
1259
  while (ISSPACE(*p))
1260
    p++;
1261
 
1262
  if (*p == '\0')
1263
    return NULL;
1264
 
1265
  start = p;
1266
 
1267
  while (*p != ',' && *p != '\0')
1268
    p++;
1269
 
1270
  *pstr = p;
1271
  return start;
1272
}
1273
 
1274
/* Helper functions for define_predicate and define_special_predicate
1275
   processing.  Shared between genrecog.c and genpreds.c.  */
1276
 
1277
static htab_t predicate_table;
1278
struct pred_data *first_predicate;
1279
static struct pred_data **last_predicate = &first_predicate;
1280
 
1281
static hashval_t
1282
hash_struct_pred_data (const void *ptr)
1283
{
1284
  return htab_hash_string (((const struct pred_data *)ptr)->name);
1285
}
1286
 
1287
static int
1288
eq_struct_pred_data (const void *a, const void *b)
1289
{
1290
  return !strcmp (((const struct pred_data *)a)->name,
1291
                  ((const struct pred_data *)b)->name);
1292
}
1293
 
1294
struct pred_data *
1295
lookup_predicate (const char *name)
1296
{
1297
  struct pred_data key;
1298
  key.name = name;
1299
  return (struct pred_data *) htab_find (predicate_table, &key);
1300
}
1301
 
1302
void
1303
add_predicate (struct pred_data *pred)
1304
{
1305
  void **slot = htab_find_slot (predicate_table, pred, INSERT);
1306
  if (*slot)
1307
    {
1308
      error ("duplicate predicate definition for '%s'", pred->name);
1309
      return;
1310
    }
1311
  *slot = pred;
1312
  *last_predicate = pred;
1313
  last_predicate = &pred->next;
1314
}
1315
 
1316
/* This array gives the initial content of the predicate table.  It
1317
   has entries for all predicates defined in recog.c.  */
1318
 
1319
struct std_pred_table
1320
{
1321
  const char *name;
1322
  bool special;
1323
  RTX_CODE codes[NUM_RTX_CODE];
1324
};
1325
 
1326
static const struct std_pred_table std_preds[] = {
1327
  {"general_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1328
                              LABEL_REF, SUBREG, REG, MEM }},
1329
  {"address_operand", true, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1330
                             LABEL_REF, SUBREG, REG, MEM,
1331
                             PLUS, MINUS, MULT}},
1332
  {"register_operand", false, {SUBREG, REG}},
1333
  {"pmode_register_operand", true, {SUBREG, REG}},
1334
  {"scratch_operand", false, {SCRATCH, REG}},
1335
  {"immediate_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1336
                                LABEL_REF}},
1337
  {"const_int_operand", false, {CONST_INT}},
1338
  {"const_double_operand", false, {CONST_INT, CONST_DOUBLE}},
1339
  {"nonimmediate_operand", false, {SUBREG, REG, MEM}},
1340
  {"nonmemory_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1341
                                LABEL_REF, SUBREG, REG}},
1342
  {"push_operand", false, {MEM}},
1343
  {"pop_operand", false, {MEM}},
1344
  {"memory_operand", false, {SUBREG, MEM}},
1345
  {"indirect_operand", false, {SUBREG, MEM}},
1346
  {"comparison_operator", false, {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
1347
                                  UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
1348
                                  UNLT, LTGT}}
1349
};
1350
#define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1351
 
1352
/* Initialize the table of predicate definitions, starting with
1353
   the information we have on generic predicates.  */
1354
 
1355
static void
1356
init_predicate_table (void)
1357
{
1358
  size_t i, j;
1359
  struct pred_data *pred;
1360
 
1361
  predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1362
                                       eq_struct_pred_data, 0,
1363
                                       xcalloc, free);
1364
 
1365
  for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
1366
    {
1367
      pred = XCNEW (struct pred_data);
1368
      pred->name = std_preds[i].name;
1369
      pred->special = std_preds[i].special;
1370
 
1371
      for (j = 0; std_preds[i].codes[j] != 0; j++)
1372
        {
1373
          enum rtx_code code = std_preds[i].codes[j];
1374
 
1375
          pred->codes[code] = true;
1376
          if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
1377
            pred->allows_non_const = true;
1378
          if (code != REG
1379
              && code != SUBREG
1380
              && code != MEM
1381
              && code != CONCAT
1382
              && code != PARALLEL
1383
              && code != STRICT_LOW_PART)
1384
            pred->allows_non_lvalue = true;
1385
        }
1386
      if (j == 1)
1387
        pred->singleton = std_preds[i].codes[0];
1388
 
1389
      add_predicate (pred);
1390
    }
1391
}
1392
 
1393
/* These functions allow linkage with print-rtl.c.  Also, some generators
1394
   like to annotate their output with insn names.  */
1395
 
1396
/* Holds an array of names indexed by insn_code_number.  */
1397
static char **insn_name_ptr = 0;
1398
static int insn_name_ptr_size = 0;
1399
 
1400
const char *
1401
get_insn_name (int code)
1402
{
1403
  if (code < insn_name_ptr_size)
1404
    return insn_name_ptr[code];
1405
  else
1406
    return NULL;
1407
}
1408
 
1409
static void
1410
record_insn_name (int code, const char *name)
1411
{
1412
  static const char *last_real_name = "insn";
1413
  static int last_real_code = 0;
1414
  char *new;
1415
 
1416
  if (insn_name_ptr_size <= code)
1417
    {
1418
      int new_size;
1419
      new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
1420
      insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
1421
      memset (insn_name_ptr + insn_name_ptr_size, 0,
1422
              sizeof(char *) * (new_size - insn_name_ptr_size));
1423
      insn_name_ptr_size = new_size;
1424
    }
1425
 
1426
  if (!name || name[0] == '\0')
1427
    {
1428
      new = xmalloc (strlen (last_real_name) + 10);
1429
      sprintf (new, "%s+%d", last_real_name, code - last_real_code);
1430
    }
1431
  else
1432
    {
1433
      last_real_name = new = xstrdup (name);
1434
      last_real_code = code;
1435
    }
1436
 
1437
  insn_name_ptr[code] = new;
1438
}

powered by: WebSVN 2.1.0

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