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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [gensupport.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Support routines for the various generation passes.
2
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3
   2010, 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 "read-md.h"
30
#include "gensupport.h"
31
 
32
 
33
/* In case some macros used by files we include need it, define this here.  */
34
int target_flags;
35
 
36
int insn_elision = 1;
37
 
38
static struct obstack obstack;
39
struct obstack *rtl_obstack = &obstack;
40
 
41
static int sequence_num;
42
 
43
static int predicable_default;
44
static const char *predicable_true;
45
static const char *predicable_false;
46
 
47
static htab_t condition_table;
48
 
49
/* We initially queue all patterns, process the define_insn and
50
   define_cond_exec patterns, then return them one at a time.  */
51
 
52
struct queue_elem
53
{
54
  rtx data;
55
  const char *filename;
56
  int lineno;
57
  struct queue_elem *next;
58
  /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
59
     points to the generated DEFINE_SPLIT.  */
60
  struct queue_elem *split;
61
};
62
 
63
#define MNEMONIC_ATTR_NAME "mnemonic"
64
#define MNEMONIC_HTAB_SIZE 1024
65
 
66
static struct queue_elem *define_attr_queue;
67
static struct queue_elem **define_attr_tail = &define_attr_queue;
68
static struct queue_elem *define_pred_queue;
69
static struct queue_elem **define_pred_tail = &define_pred_queue;
70
static struct queue_elem *define_insn_queue;
71
static struct queue_elem **define_insn_tail = &define_insn_queue;
72
static struct queue_elem *define_cond_exec_queue;
73
static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
74
static struct queue_elem *other_queue;
75
static struct queue_elem **other_tail = &other_queue;
76
 
77
static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
78
                                         const char *, int);
79
 
80
static void remove_constraints (rtx);
81
static void process_rtx (rtx, int);
82
 
83
static int is_predicable (struct queue_elem *);
84
static void identify_predicable_attribute (void);
85
static int n_alternatives (const char *);
86
static void collect_insn_data (rtx, int *, int *);
87
static rtx alter_predicate_for_insn (rtx, int, int, int);
88
static const char *alter_test_for_insn (struct queue_elem *,
89
                                        struct queue_elem *);
90
static char *shift_output_template (char *, const char *, int);
91
static const char *alter_output_for_insn (struct queue_elem *,
92
                                          struct queue_elem *,
93
                                          int, int);
94
static void process_one_cond_exec (struct queue_elem *);
95
static void process_define_cond_exec (void);
96
static void init_predicate_table (void);
97
static void record_insn_name (int, const char *);
98
 
99
/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
100
   the gensupport programs.  */
101
 
102
rtx
103
gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
104
                   HOST_WIDE_INT arg)
105
{
106
  rtx rt = rtx_alloc (CONST_INT);
107
 
108
  XWINT (rt, 0) = arg;
109
  return rt;
110
}
111
 
112
/* Predicate handling.
113
 
114
   We construct from the machine description a table mapping each
115
   predicate to a list of the rtl codes it can possibly match.  The
116
   function 'maybe_both_true' uses it to deduce that there are no
117
   expressions that can be matches by certain pairs of tree nodes.
118
   Also, if a predicate can match only one code, we can hardwire that
119
   code into the node testing the predicate.
120
 
121
   Some predicates are flagged as special.  validate_pattern will not
122
   warn about modeless match_operand expressions if they have a
123
   special predicate.  Predicates that allow only constants are also
124
   treated as special, for this purpose.
125
 
126
   validate_pattern will warn about predicates that allow non-lvalues
127
   when they appear in destination operands.
128
 
129
   Calculating the set of rtx codes that can possibly be accepted by a
130
   predicate expression EXP requires a three-state logic: any given
131
   subexpression may definitively accept a code C (Y), definitively
132
   reject a code C (N), or may have an indeterminate effect (I).  N
133
   and I is N; Y or I is Y; Y and I, N or I are both I.  Here are full
134
   truth tables.
135
 
136
     a b  a&b  a|b
137
     Y Y   Y    Y
138
     N Y   N    Y
139
     N N   N    N
140
     I Y   I    Y
141
     I N   N    I
142
     I I   I    I
143
 
144
   We represent Y with 1, N with 0, I with 2.  If any code is left in
145
   an I state by the complete expression, we must assume that that
146
   code can be accepted.  */
147
 
148
#define N 0
149
#define Y 1
150
#define I 2
151
 
152
#define TRISTATE_AND(a,b)                       \
153
  ((a) == I ? ((b) == N ? N : I) :              \
154
   (b) == I ? ((a) == N ? N : I) :              \
155
   (a) && (b))
156
 
157
#define TRISTATE_OR(a,b)                        \
158
  ((a) == I ? ((b) == Y ? Y : I) :              \
159
   (b) == I ? ((a) == Y ? Y : I) :              \
160
   (a) || (b))
161
 
162
#define TRISTATE_NOT(a)                         \
163
  ((a) == I ? I : !(a))
164
 
165
/* 0 means no warning about that code yet, 1 means warned.  */
166
static char did_you_mean_codes[NUM_RTX_CODE];
167
 
168
/* Recursively calculate the set of rtx codes accepted by the
169
   predicate expression EXP, writing the result to CODES.  LINENO is
170
   the line number on which the directive containing EXP appeared.  */
171
 
172
static void
173
compute_predicate_codes (rtx exp, int lineno, char codes[NUM_RTX_CODE])
174
{
175
  char op0_codes[NUM_RTX_CODE];
176
  char op1_codes[NUM_RTX_CODE];
177
  char op2_codes[NUM_RTX_CODE];
178
  int i;
179
 
180
  switch (GET_CODE (exp))
181
    {
182
    case AND:
183
      compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
184
      compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes);
185
      for (i = 0; i < NUM_RTX_CODE; i++)
186
        codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]);
187
      break;
188
 
189
    case IOR:
190
      compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
191
      compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes);
192
      for (i = 0; i < NUM_RTX_CODE; i++)
193
        codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]);
194
      break;
195
    case NOT:
196
      compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
197
      for (i = 0; i < NUM_RTX_CODE; i++)
198
        codes[i] = TRISTATE_NOT (op0_codes[i]);
199
      break;
200
 
201
    case IF_THEN_ELSE:
202
      /* a ? b : c  accepts the same codes as (a & b) | (!a & c).  */
203
      compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
204
      compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes);
205
      compute_predicate_codes (XEXP (exp, 2), lineno, op2_codes);
206
      for (i = 0; i < NUM_RTX_CODE; i++)
207
        codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]),
208
                                TRISTATE_AND (TRISTATE_NOT (op0_codes[i]),
209
                                              op2_codes[i]));
210
      break;
211
 
212
    case MATCH_CODE:
213
      /* MATCH_CODE allows a specified list of codes.  However, if it
214
         does not apply to the top level of the expression, it does not
215
         constrain the set of codes for the top level.  */
216
      if (XSTR (exp, 1)[0] != '\0')
217
        {
218
          memset (codes, Y, NUM_RTX_CODE);
219
          break;
220
        }
221
 
222
      memset (codes, N, NUM_RTX_CODE);
223
      {
224
        const char *next_code = XSTR (exp, 0);
225
        const char *code;
226
 
227
        if (*next_code == '\0')
228
          {
229
            error_with_line (lineno, "empty match_code expression");
230
            break;
231
          }
232
 
233
        while ((code = scan_comma_elt (&next_code)) != 0)
234
          {
235
            size_t n = next_code - code;
236
            int found_it = 0;
237
 
238
            for (i = 0; i < NUM_RTX_CODE; i++)
239
              if (!strncmp (code, GET_RTX_NAME (i), n)
240
                  && GET_RTX_NAME (i)[n] == '\0')
241
                {
242
                  codes[i] = Y;
243
                  found_it = 1;
244
                  break;
245
                }
246
            if (!found_it)
247
              {
248
                error_with_line (lineno,
249
                                 "match_code \"%.*s\" matches nothing",
250
                                 (int) n, code);
251
                for (i = 0; i < NUM_RTX_CODE; i++)
252
                  if (!strncasecmp (code, GET_RTX_NAME (i), n)
253
                      && GET_RTX_NAME (i)[n] == '\0'
254
                      && !did_you_mean_codes[i])
255
                    {
256
                      did_you_mean_codes[i] = 1;
257
                      message_with_line (lineno, "(did you mean \"%s\"?)",
258
                                         GET_RTX_NAME (i));
259
                    }
260
              }
261
          }
262
      }
263
      break;
264
 
265
    case MATCH_OPERAND:
266
      /* MATCH_OPERAND disallows the set of codes that the named predicate
267
         disallows, and is indeterminate for the codes that it does allow.  */
268
      {
269
        struct pred_data *p = lookup_predicate (XSTR (exp, 1));
270
        if (!p)
271
          {
272
            error_with_line (lineno, "reference to unknown predicate '%s'",
273
                             XSTR (exp, 1));
274
            break;
275
          }
276
        for (i = 0; i < NUM_RTX_CODE; i++)
277
          codes[i] = p->codes[i] ? I : N;
278
      }
279
      break;
280
 
281
 
282
    case MATCH_TEST:
283
      /* (match_test WHATEVER) is completely indeterminate.  */
284
      memset (codes, I, NUM_RTX_CODE);
285
      break;
286
 
287
    default:
288
      error_with_line (lineno,
289
                       "'%s' cannot be used in a define_predicate expression",
290
                       GET_RTX_NAME (GET_CODE (exp)));
291
      memset (codes, I, NUM_RTX_CODE);
292
      break;
293
    }
294
}
295
 
296
#undef TRISTATE_OR
297
#undef TRISTATE_AND
298
#undef TRISTATE_NOT
299
 
300
/* Return true if NAME is a valid predicate name.  */
301
 
302
static bool
303
valid_predicate_name_p (const char *name)
304
{
305
  const char *p;
306
 
307
  if (!ISALPHA (name[0]) && name[0] != '_')
308
    return false;
309
  for (p = name + 1; *p; p++)
310
    if (!ISALNUM (*p) && *p != '_')
311
      return false;
312
  return true;
313
}
314
 
315
/* Process define_predicate directive DESC, which appears on line number
316
   LINENO.  Compute the set of codes that can be matched, and record this
317
   as a known predicate.  */
318
 
319
static void
320
process_define_predicate (rtx desc, int lineno)
321
{
322
  struct pred_data *pred;
323
  char codes[NUM_RTX_CODE];
324
  int i;
325
 
326
  if (!valid_predicate_name_p (XSTR (desc, 0)))
327
    {
328
      error_with_line (lineno,
329
                       "%s: predicate name must be a valid C function name",
330
                       XSTR (desc, 0));
331
      return;
332
    }
333
 
334
  pred = XCNEW (struct pred_data);
335
  pred->name = XSTR (desc, 0);
336
  pred->exp = XEXP (desc, 1);
337
  pred->c_block = XSTR (desc, 2);
338
  if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE)
339
    pred->special = true;
340
 
341
  compute_predicate_codes (XEXP (desc, 1), lineno, codes);
342
 
343
  for (i = 0; i < NUM_RTX_CODE; i++)
344
    if (codes[i] != N)
345
      add_predicate_code (pred, (enum rtx_code) i);
346
 
347
  add_predicate (pred);
348
}
349
#undef I
350
#undef N
351
#undef Y
352
 
353
/* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
354
   element.  */
355
 
356
static struct queue_elem *
357
queue_pattern (rtx pattern, struct queue_elem ***list_tail,
358
               const char *filename, int lineno)
359
{
360
  struct queue_elem *e = XNEW(struct queue_elem);
361
  e->data = pattern;
362
  e->filename = filename;
363
  e->lineno = lineno;
364
  e->next = NULL;
365
  e->split = NULL;
366
  **list_tail = e;
367
  *list_tail = &e->next;
368
  return e;
369
}
370
 
371
/* Build a define_attr for an binary attribute with name NAME and
372
   possible values "yes" and "no", and queue it.  */
373
static void
374
add_define_attr (const char *name)
375
{
376
  struct queue_elem *e = XNEW(struct queue_elem);
377
  rtx t1 = rtx_alloc (DEFINE_ATTR);
378
  XSTR (t1, 0) = name;
379
  XSTR (t1, 1) = "no,yes";
380
  XEXP (t1, 2) = rtx_alloc (CONST_STRING);
381
  XSTR (XEXP (t1, 2), 0) = "yes";
382
  e->data = t1;
383
  e->filename = "built-in";
384
  e->lineno = -1;
385
  e->next = define_attr_queue;
386
  define_attr_queue = e;
387
 
388
}
389
 
390
/* Recursively remove constraints from an rtx.  */
391
 
392
static void
393
remove_constraints (rtx part)
394
{
395
  int i, j;
396
  const char *format_ptr;
397
 
398
  if (part == 0)
399
    return;
400
 
401
  if (GET_CODE (part) == MATCH_OPERAND)
402
    XSTR (part, 2) = "";
403
  else if (GET_CODE (part) == MATCH_SCRATCH)
404
    XSTR (part, 1) = "";
405
 
406
  format_ptr = GET_RTX_FORMAT (GET_CODE (part));
407
 
408
  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
409
    switch (*format_ptr++)
410
      {
411
      case 'e':
412
      case 'u':
413
        remove_constraints (XEXP (part, i));
414
        break;
415
      case 'E':
416
        if (XVEC (part, i) != NULL)
417
          for (j = 0; j < XVECLEN (part, i); j++)
418
            remove_constraints (XVECEXP (part, i, j));
419
        break;
420
      }
421
}
422
 
423
/* Process a top level rtx in some way, queuing as appropriate.  */
424
 
425
static void
426
process_rtx (rtx desc, int lineno)
427
{
428
  switch (GET_CODE (desc))
429
    {
430
    case DEFINE_INSN:
431
      queue_pattern (desc, &define_insn_tail, read_md_filename, lineno);
432
      break;
433
 
434
    case DEFINE_COND_EXEC:
435
      queue_pattern (desc, &define_cond_exec_tail, read_md_filename, lineno);
436
      break;
437
 
438
    case DEFINE_ATTR:
439
    case DEFINE_ENUM_ATTR:
440
      queue_pattern (desc, &define_attr_tail, read_md_filename, lineno);
441
      break;
442
 
443
    case DEFINE_PREDICATE:
444
    case DEFINE_SPECIAL_PREDICATE:
445
      process_define_predicate (desc, lineno);
446
      /* Fall through.  */
447
 
448
    case DEFINE_CONSTRAINT:
449
    case DEFINE_REGISTER_CONSTRAINT:
450
    case DEFINE_MEMORY_CONSTRAINT:
451
    case DEFINE_ADDRESS_CONSTRAINT:
452
      queue_pattern (desc, &define_pred_tail, read_md_filename, lineno);
453
      break;
454
 
455
    case DEFINE_INSN_AND_SPLIT:
456
      {
457
        const char *split_cond;
458
        rtx split;
459
        rtvec attr;
460
        int i;
461
        struct queue_elem *insn_elem;
462
        struct queue_elem *split_elem;
463
 
464
        /* Create a split with values from the insn_and_split.  */
465
        split = rtx_alloc (DEFINE_SPLIT);
466
 
467
        i = XVECLEN (desc, 1);
468
        XVEC (split, 0) = rtvec_alloc (i);
469
        while (--i >= 0)
470
          {
471
            XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
472
            remove_constraints (XVECEXP (split, 0, i));
473
          }
474
 
475
        /* If the split condition starts with "&&", append it to the
476
           insn condition to create the new split condition.  */
477
        split_cond = XSTR (desc, 4);
478
        if (split_cond[0] == '&' && split_cond[1] == '&')
479
          {
480
            copy_md_ptr_loc (split_cond + 2, split_cond);
481
            split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
482
          }
483
        XSTR (split, 1) = split_cond;
484
        XVEC (split, 2) = XVEC (desc, 5);
485
        XSTR (split, 3) = XSTR (desc, 6);
486
 
487
        /* Fix up the DEFINE_INSN.  */
488
        attr = XVEC (desc, 7);
489
        PUT_CODE (desc, DEFINE_INSN);
490
        XVEC (desc, 4) = attr;
491
 
492
        /* Queue them.  */
493
        insn_elem
494
          = queue_pattern (desc, &define_insn_tail, read_md_filename,
495
                           lineno);
496
        split_elem
497
          = queue_pattern (split, &other_tail, read_md_filename, lineno);
498
        insn_elem->split = split_elem;
499
        break;
500
      }
501
 
502
    default:
503
      queue_pattern (desc, &other_tail, read_md_filename, lineno);
504
      break;
505
    }
506
}
507
 
508
/* Return true if attribute PREDICABLE is true for ELEM, which holds
509
   a DEFINE_INSN.  */
510
 
511
static int
512
is_predicable (struct queue_elem *elem)
513
{
514
  rtvec vec = XVEC (elem->data, 4);
515
  const char *value;
516
  int i;
517
 
518
  if (! vec)
519
    return predicable_default;
520
 
521
  for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
522
    {
523
      rtx sub = RTVEC_ELT (vec, i);
524
      switch (GET_CODE (sub))
525
        {
526
        case SET_ATTR:
527
          if (strcmp (XSTR (sub, 0), "predicable") == 0)
528
            {
529
              value = XSTR (sub, 1);
530
              goto found;
531
            }
532
          break;
533
 
534
        case SET_ATTR_ALTERNATIVE:
535
          if (strcmp (XSTR (sub, 0), "predicable") == 0)
536
            {
537
              error_with_line (elem->lineno,
538
                               "multiple alternatives for `predicable'");
539
              return 0;
540
            }
541
          break;
542
 
543
        case SET:
544
          if (GET_CODE (SET_DEST (sub)) != ATTR
545
              || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
546
            break;
547
          sub = SET_SRC (sub);
548
          if (GET_CODE (sub) == CONST_STRING)
549
            {
550
              value = XSTR (sub, 0);
551
              goto found;
552
            }
553
 
554
          /* ??? It would be possible to handle this if we really tried.
555
             It's not easy though, and I'm not going to bother until it
556
             really proves necessary.  */
557
          error_with_line (elem->lineno,
558
                           "non-constant value for `predicable'");
559
          return 0;
560
 
561
        default:
562
          gcc_unreachable ();
563
        }
564
    }
565
 
566
  return predicable_default;
567
 
568
 found:
569
  /* Find out which value we're looking at.  Multiple alternatives means at
570
     least one is predicable.  */
571
  if (strchr (value, ',') != NULL)
572
    return 1;
573
  if (strcmp (value, predicable_true) == 0)
574
    return 1;
575
  if (strcmp (value, predicable_false) == 0)
576
    return 0;
577
 
578
  error_with_line (elem->lineno,
579
                   "unknown value `%s' for `predicable' attribute", value);
580
  return 0;
581
}
582
 
583
/* Examine the attribute "predicable"; discover its boolean values
584
   and its default.  */
585
 
586
static void
587
identify_predicable_attribute (void)
588
{
589
  struct queue_elem *elem;
590
  char *p_true, *p_false;
591
  const char *value;
592
 
593
  /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
594
  for (elem = define_attr_queue; elem ; elem = elem->next)
595
    if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
596
      goto found;
597
 
598
  error_with_line (define_cond_exec_queue->lineno,
599
                   "attribute `predicable' not defined");
600
  return;
601
 
602
 found:
603
  value = XSTR (elem->data, 1);
604
  p_false = xstrdup (value);
605
  p_true = strchr (p_false, ',');
606
  if (p_true == NULL || strchr (++p_true, ',') != NULL)
607
    {
608
      error_with_line (elem->lineno, "attribute `predicable' is not a boolean");
609
      free (p_false);
610
      return;
611
    }
612
  p_true[-1] = '\0';
613
 
614
  predicable_true = p_true;
615
  predicable_false = p_false;
616
 
617
  switch (GET_CODE (XEXP (elem->data, 2)))
618
    {
619
    case CONST_STRING:
620
      value = XSTR (XEXP (elem->data, 2), 0);
621
      break;
622
 
623
    case CONST:
624
      error_with_line (elem->lineno, "attribute `predicable' cannot be const");
625
      free (p_false);
626
      return;
627
 
628
    default:
629
      error_with_line (elem->lineno,
630
                       "attribute `predicable' must have a constant default");
631
      free (p_false);
632
      return;
633
    }
634
 
635
  if (strcmp (value, p_true) == 0)
636
    predicable_default = 1;
637
  else if (strcmp (value, p_false) == 0)
638
    predicable_default = 0;
639
  else
640
    {
641
      error_with_line (elem->lineno,
642
                       "unknown value `%s' for `predicable' attribute", value);
643
      free (p_false);
644
    }
645
}
646
 
647
/* Return the number of alternatives in constraint S.  */
648
 
649
static int
650
n_alternatives (const char *s)
651
{
652
  int n = 1;
653
 
654
  if (s)
655
    while (*s)
656
      n += (*s++ == ',');
657
 
658
  return n;
659
}
660
 
661
/* Determine how many alternatives there are in INSN, and how many
662
   operands.  */
663
 
664
static void
665
collect_insn_data (rtx pattern, int *palt, int *pmax)
666
{
667
  const char *fmt;
668
  enum rtx_code code;
669
  int i, j, len;
670
 
671
  code = GET_CODE (pattern);
672
  switch (code)
673
    {
674
    case MATCH_OPERAND:
675
      i = n_alternatives (XSTR (pattern, 2));
676
      *palt = (i > *palt ? i : *palt);
677
      /* Fall through.  */
678
 
679
    case MATCH_OPERATOR:
680
    case MATCH_SCRATCH:
681
    case MATCH_PARALLEL:
682
      i = XINT (pattern, 0);
683
      if (i > *pmax)
684
        *pmax = i;
685
      break;
686
 
687
    default:
688
      break;
689
    }
690
 
691
  fmt = GET_RTX_FORMAT (code);
692
  len = GET_RTX_LENGTH (code);
693
  for (i = 0; i < len; i++)
694
    {
695
      switch (fmt[i])
696
        {
697
        case 'e': case 'u':
698
          collect_insn_data (XEXP (pattern, i), palt, pmax);
699
          break;
700
 
701
        case 'V':
702
          if (XVEC (pattern, i) == NULL)
703
            break;
704
          /* Fall through.  */
705
        case 'E':
706
          for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
707
            collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
708
          break;
709
 
710
        case 'i': case 'w': case '0': case 's': case 'S': case 'T':
711
          break;
712
 
713
        default:
714
          gcc_unreachable ();
715
        }
716
    }
717
}
718
 
719
static rtx
720
alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
721
{
722
  const char *fmt;
723
  enum rtx_code code;
724
  int i, j, len;
725
 
726
  code = GET_CODE (pattern);
727
  switch (code)
728
    {
729
    case MATCH_OPERAND:
730
      {
731
        const char *c = XSTR (pattern, 2);
732
 
733
        if (n_alternatives (c) != 1)
734
          {
735
            error_with_line (lineno, "too many alternatives for operand %d",
736
                             XINT (pattern, 0));
737
            return NULL;
738
          }
739
 
740
        /* Replicate C as needed to fill out ALT alternatives.  */
741
        if (c && *c && alt > 1)
742
          {
743
            size_t c_len = strlen (c);
744
            size_t len = alt * (c_len + 1);
745
            char *new_c = XNEWVEC(char, len);
746
 
747
            memcpy (new_c, c, c_len);
748
            for (i = 1; i < alt; ++i)
749
              {
750
                new_c[i * (c_len + 1) - 1] = ',';
751
                memcpy (&new_c[i * (c_len + 1)], c, c_len);
752
              }
753
            new_c[len - 1] = '\0';
754
            XSTR (pattern, 2) = new_c;
755
          }
756
      }
757
      /* Fall through.  */
758
 
759
    case MATCH_OPERATOR:
760
    case MATCH_SCRATCH:
761
    case MATCH_PARALLEL:
762
      XINT (pattern, 0) += max_op;
763
      break;
764
 
765
    default:
766
      break;
767
    }
768
 
769
  fmt = GET_RTX_FORMAT (code);
770
  len = GET_RTX_LENGTH (code);
771
  for (i = 0; i < len; i++)
772
    {
773
      rtx r;
774
 
775
      switch (fmt[i])
776
        {
777
        case 'e': case 'u':
778
          r = alter_predicate_for_insn (XEXP (pattern, i), alt,
779
                                        max_op, lineno);
780
          if (r == NULL)
781
            return r;
782
          break;
783
 
784
        case 'E':
785
          for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
786
            {
787
              r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
788
                                            alt, max_op, lineno);
789
              if (r == NULL)
790
                return r;
791
            }
792
          break;
793
 
794
        case 'i': case 'w': case '0': case 's':
795
          break;
796
 
797
        default:
798
          gcc_unreachable ();
799
        }
800
    }
801
 
802
  return pattern;
803
}
804
 
805
static const char *
806
alter_test_for_insn (struct queue_elem *ce_elem,
807
                     struct queue_elem *insn_elem)
808
{
809
  return join_c_conditions (XSTR (ce_elem->data, 1),
810
                            XSTR (insn_elem->data, 2));
811
}
812
 
813
/* Modify VAL, which is an attribute expression for the "enabled" attribute,
814
   to take "ce_enabled" into account.  Return the new expression.  */
815
static rtx
816
modify_attr_enabled_ce (rtx val)
817
{
818
  rtx eq_attr, str;
819
  rtx ite;
820
  eq_attr = rtx_alloc (EQ_ATTR);
821
  ite = rtx_alloc (IF_THEN_ELSE);
822
  str = rtx_alloc (CONST_STRING);
823
 
824
  XSTR (eq_attr, 0) = "ce_enabled";
825
  XSTR (eq_attr, 1) = "yes";
826
  XSTR (str, 0) = "no";
827
  XEXP (ite, 0) = eq_attr;
828
  XEXP (ite, 1) = val;
829
  XEXP (ite, 2) = str;
830
 
831
  return ite;
832
}
833
 
834
/* Alter the attribute vector of INSN, which is a COND_EXEC variant created
835
   from a define_insn pattern.  We must modify the "predicable" attribute
836
   to be named "ce_enabled", and also change any "enabled" attribute that's
837
   present so that it takes ce_enabled into account.
838
   We rely on the fact that INSN was created with copy_rtx, and modify data
839
   in-place.  */
840
 
841
static void
842
alter_attrs_for_insn (rtx insn)
843
{
844
  static bool global_changes_made = false;
845
  rtvec vec = XVEC (insn, 4);
846
  rtvec new_vec;
847
  rtx val, set;
848
  int num_elem;
849
  int predicable_idx = -1;
850
  int enabled_idx = -1;
851
  int i;
852
 
853
  if (! vec)
854
    return;
855
 
856
  num_elem = GET_NUM_ELEM (vec);
857
  for (i = num_elem - 1; i >= 0; --i)
858
    {
859
      rtx sub = RTVEC_ELT (vec, i);
860
      switch (GET_CODE (sub))
861
        {
862
        case SET_ATTR:
863
          if (strcmp (XSTR (sub, 0), "predicable") == 0)
864
            {
865
              predicable_idx = i;
866
              XSTR (sub, 0) = "ce_enabled";
867
            }
868
          else if (strcmp (XSTR (sub, 0), "enabled") == 0)
869
            {
870
              enabled_idx = i;
871
              XSTR (sub, 0) = "nonce_enabled";
872
            }
873
          break;
874
 
875
        case SET_ATTR_ALTERNATIVE:
876
          if (strcmp (XSTR (sub, 0), "predicable") == 0)
877
            /* We already give an error elsewhere.  */
878
            return;
879
          else if (strcmp (XSTR (sub, 0), "enabled") == 0)
880
            {
881
              enabled_idx = i;
882
              XSTR (sub, 0) = "nonce_enabled";
883
            }
884
          break;
885
 
886
        case SET:
887
          if (GET_CODE (SET_DEST (sub)) != ATTR)
888
            break;
889
          if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
890
            {
891
              sub = SET_SRC (sub);
892
              if (GET_CODE (sub) == CONST_STRING)
893
                {
894
                  predicable_idx = i;
895
                  XSTR (sub, 0) = "ce_enabled";
896
                }
897
              else
898
                /* We already give an error elsewhere.  */
899
                return;
900
              break;
901
            }
902
          if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
903
            {
904
              enabled_idx = i;
905
              XSTR (SET_DEST (sub), 0) = "nonce_enabled";
906
            }
907
          break;
908
 
909
        default:
910
          gcc_unreachable ();
911
        }
912
    }
913
  if (predicable_idx == -1)
914
    return;
915
 
916
  if (!global_changes_made)
917
    {
918
      struct queue_elem *elem;
919
 
920
      global_changes_made = true;
921
      add_define_attr ("ce_enabled");
922
      add_define_attr ("nonce_enabled");
923
 
924
      for (elem = define_attr_queue; elem ; elem = elem->next)
925
        if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
926
          {
927
            XEXP (elem->data, 2)
928
              = modify_attr_enabled_ce (XEXP (elem->data, 2));
929
          }
930
    }
931
  if (enabled_idx == -1)
932
    return;
933
 
934
  new_vec = rtvec_alloc (num_elem + 1);
935
  for (i = 0; i < num_elem; i++)
936
    RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
937
  val = rtx_alloc (IF_THEN_ELSE);
938
  XEXP (val, 0) = rtx_alloc (EQ_ATTR);
939
  XEXP (val, 1) = rtx_alloc (CONST_STRING);
940
  XEXP (val, 2) = rtx_alloc (CONST_STRING);
941
  XSTR (XEXP (val, 0), 0) = "nonce_enabled";
942
  XSTR (XEXP (val, 0), 1) = "yes";
943
  XSTR (XEXP (val, 1), 0) = "yes";
944
  XSTR (XEXP (val, 2), 0) = "no";
945
  set = rtx_alloc (SET);
946
  SET_DEST (set) = rtx_alloc (ATTR);
947
  XSTR (SET_DEST (set), 0) = "enabled";
948
  SET_SRC (set) = modify_attr_enabled_ce (val);
949
  RTVEC_ELT (new_vec, i) = set;
950
  XVEC (insn, 4) = new_vec;
951
}
952
 
953
/* Adjust all of the operand numbers in SRC to match the shift they'll
954
   get from an operand displacement of DISP.  Return a pointer after the
955
   adjusted string.  */
956
 
957
static char *
958
shift_output_template (char *dest, const char *src, int disp)
959
{
960
  while (*src)
961
    {
962
      char c = *src++;
963
      *dest++ = c;
964
      if (c == '%')
965
        {
966
          c = *src++;
967
          if (ISDIGIT ((unsigned char) c))
968
            c += disp;
969
          else if (ISALPHA (c))
970
            {
971
              *dest++ = c;
972
              c = *src++ + disp;
973
            }
974
          *dest++ = c;
975
        }
976
    }
977
 
978
  return dest;
979
}
980
 
981
static const char *
982
alter_output_for_insn (struct queue_elem *ce_elem,
983
                       struct queue_elem *insn_elem,
984
                       int alt, int max_op)
985
{
986
  const char *ce_out, *insn_out;
987
  char *result, *p;
988
  size_t len, ce_len, insn_len;
989
 
990
  /* ??? Could coordinate with genoutput to not duplicate code here.  */
991
 
992
  ce_out = XSTR (ce_elem->data, 2);
993
  insn_out = XTMPL (insn_elem->data, 3);
994
  if (!ce_out || *ce_out == '\0')
995
    return insn_out;
996
 
997
  ce_len = strlen (ce_out);
998
  insn_len = strlen (insn_out);
999
 
1000
  if (*insn_out == '*')
1001
    /* You must take care of the predicate yourself.  */
1002
    return insn_out;
1003
 
1004
  if (*insn_out == '@')
1005
    {
1006
      len = (ce_len + 1) * alt + insn_len + 1;
1007
      p = result = XNEWVEC(char, len);
1008
 
1009
      do
1010
        {
1011
          do
1012
            *p++ = *insn_out++;
1013
          while (ISSPACE ((unsigned char) *insn_out));
1014
 
1015
          if (*insn_out != '#')
1016
            {
1017
              p = shift_output_template (p, ce_out, max_op);
1018
              *p++ = ' ';
1019
            }
1020
 
1021
          do
1022
            *p++ = *insn_out++;
1023
          while (*insn_out && *insn_out != '\n');
1024
        }
1025
      while (*insn_out);
1026
      *p = '\0';
1027
    }
1028
  else
1029
    {
1030
      len = ce_len + 1 + insn_len + 1;
1031
      result = XNEWVEC (char, len);
1032
 
1033
      p = shift_output_template (result, ce_out, max_op);
1034
      *p++ = ' ';
1035
      memcpy (p, insn_out, insn_len + 1);
1036
    }
1037
 
1038
  return result;
1039
}
1040
 
1041
/* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
1042
 
1043
static void
1044
process_one_cond_exec (struct queue_elem *ce_elem)
1045
{
1046
  struct queue_elem *insn_elem;
1047
  for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
1048
    {
1049
      int alternatives, max_operand;
1050
      rtx pred, insn, pattern, split;
1051
      char *new_name;
1052
      int i;
1053
 
1054
      if (! is_predicable (insn_elem))
1055
        continue;
1056
 
1057
      alternatives = 1;
1058
      max_operand = -1;
1059
      collect_insn_data (insn_elem->data, &alternatives, &max_operand);
1060
      max_operand += 1;
1061
 
1062
      if (XVECLEN (ce_elem->data, 0) != 1)
1063
        {
1064
          error_with_line (ce_elem->lineno, "too many patterns in predicate");
1065
          return;
1066
        }
1067
 
1068
      pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
1069
      pred = alter_predicate_for_insn (pred, alternatives, max_operand,
1070
                                       ce_elem->lineno);
1071
      if (pred == NULL)
1072
        return;
1073
 
1074
      /* Construct a new pattern for the new insn.  */
1075
      insn = copy_rtx (insn_elem->data);
1076
      new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
1077
      sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
1078
      XSTR (insn, 0) = new_name;
1079
      pattern = rtx_alloc (COND_EXEC);
1080
      XEXP (pattern, 0) = pred;
1081
      if (XVECLEN (insn, 1) == 1)
1082
        {
1083
          XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
1084
          XVECEXP (insn, 1, 0) = pattern;
1085
          PUT_NUM_ELEM (XVEC (insn, 1), 1);
1086
        }
1087
      else
1088
        {
1089
          XEXP (pattern, 1) = rtx_alloc (PARALLEL);
1090
          XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
1091
          XVEC (insn, 1) = rtvec_alloc (1);
1092
          XVECEXP (insn, 1, 0) = pattern;
1093
        }
1094
 
1095
      XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
1096
      XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
1097
                                              alternatives, max_operand);
1098
      alter_attrs_for_insn (insn);
1099
 
1100
      /* Put the new pattern on the `other' list so that it
1101
         (a) is not reprocessed by other define_cond_exec patterns
1102
         (b) appears after all normal define_insn patterns.
1103
 
1104
         ??? B is debatable.  If one has normal insns that match
1105
         cond_exec patterns, they will be preferred over these
1106
         generated patterns.  Whether this matters in practice, or if
1107
         it's a good thing, or whether we should thread these new
1108
         patterns into the define_insn chain just after their generator
1109
         is something we'll have to experiment with.  */
1110
 
1111
      queue_pattern (insn, &other_tail, insn_elem->filename,
1112
                     insn_elem->lineno);
1113
 
1114
      if (!insn_elem->split)
1115
        continue;
1116
 
1117
      /* If the original insn came from a define_insn_and_split,
1118
         generate a new split to handle the predicated insn.  */
1119
      split = copy_rtx (insn_elem->split->data);
1120
      /* Predicate the pattern matched by the split.  */
1121
      pattern = rtx_alloc (COND_EXEC);
1122
      XEXP (pattern, 0) = pred;
1123
      if (XVECLEN (split, 0) == 1)
1124
        {
1125
          XEXP (pattern, 1) = XVECEXP (split, 0, 0);
1126
          XVECEXP (split, 0, 0) = pattern;
1127
          PUT_NUM_ELEM (XVEC (split, 0), 1);
1128
        }
1129
      else
1130
        {
1131
          XEXP (pattern, 1) = rtx_alloc (PARALLEL);
1132
          XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
1133
          XVEC (split, 0) = rtvec_alloc (1);
1134
          XVECEXP (split, 0, 0) = pattern;
1135
        }
1136
      /* Predicate all of the insns generated by the split.  */
1137
      for (i = 0; i < XVECLEN (split, 2); i++)
1138
        {
1139
          pattern = rtx_alloc (COND_EXEC);
1140
          XEXP (pattern, 0) = pred;
1141
          XEXP (pattern, 1) = XVECEXP (split, 2, i);
1142
          XVECEXP (split, 2, i) = pattern;
1143
        }
1144
      /* Add the new split to the queue.  */
1145
      queue_pattern (split, &other_tail, read_md_filename,
1146
                     insn_elem->split->lineno);
1147
    }
1148
}
1149
 
1150
/* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
1151
   patterns appropriately.  */
1152
 
1153
static void
1154
process_define_cond_exec (void)
1155
{
1156
  struct queue_elem *elem;
1157
 
1158
  identify_predicable_attribute ();
1159
  if (have_error)
1160
    return;
1161
 
1162
  for (elem = define_cond_exec_queue; elem ; elem = elem->next)
1163
    process_one_cond_exec (elem);
1164
}
1165
 
1166
/* A read_md_files callback for reading an rtx.  */
1167
 
1168
static void
1169
rtx_handle_directive (int lineno, const char *rtx_name)
1170
{
1171
  rtx queue, x;
1172
 
1173
  if (read_rtx (rtx_name, &queue))
1174
    for (x = queue; x; x = XEXP (x, 1))
1175
      process_rtx (XEXP (x, 0), lineno);
1176
}
1177
 
1178
/* Comparison function for the mnemonic hash table.  */
1179
 
1180
static int
1181
htab_eq_string (const void *s1, const void *s2)
1182
{
1183
  return strcmp ((const char*)s1, (const char*)s2) == 0;
1184
}
1185
 
1186
/* Add mnemonic STR with length LEN to the mnemonic hash table
1187
   MNEMONIC_HTAB.  A trailing zero end character is appendend to STR
1188
   and a permanent heap copy of STR is created.  */
1189
 
1190
static void
1191
add_mnemonic_string (htab_t mnemonic_htab, const char *str, int len)
1192
{
1193
  char *new_str;
1194
  void **slot;
1195
  char *str_zero = (char*)alloca (len + 1);
1196
 
1197
  memcpy (str_zero, str, len);
1198
  str_zero[len] = '\0';
1199
 
1200
  slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
1201
 
1202
  if (*slot)
1203
    return;
1204
 
1205
  /* Not found; create a permanent copy and add it to the hash table.  */
1206
  new_str = XNEWVAR (char, len + 1);
1207
  memcpy (new_str, str_zero, len + 1);
1208
  *slot = new_str;
1209
}
1210
 
1211
/* Scan INSN for mnemonic strings and add them to the mnemonic hash
1212
   table in MNEMONIC_HTAB.
1213
 
1214
   The mnemonics cannot be found if they are emitted using C code.
1215
 
1216
   If a mnemonic string contains ';' or a newline the string assumed
1217
   to consist of more than a single instruction.  The attribute value
1218
   will then be set to the user defined default value.  */
1219
 
1220
static void
1221
gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
1222
{
1223
  const char *template_code, *cp;
1224
  int i;
1225
  int vec_len;
1226
  rtx set_attr;
1227
  char *attr_name;
1228
  rtvec new_vec;
1229
 
1230
  template_code = XTMPL (insn, 3);
1231
 
1232
  /* Skip patterns which use C code to emit the template.  */
1233
  if (template_code[0] == '*')
1234
    return;
1235
 
1236
  if (template_code[0] == '@')
1237
    cp = &template_code[1];
1238
  else
1239
    cp = &template_code[0];
1240
 
1241
  for (i = 0; *cp; )
1242
    {
1243
      const char *ep, *sp;
1244
      int size = 0;
1245
 
1246
      while (ISSPACE (*cp))
1247
        cp++;
1248
 
1249
      for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
1250
        if (!ISSPACE (*ep))
1251
          sp = ep + 1;
1252
 
1253
      if (i > 0)
1254
        obstack_1grow (&string_obstack, ',');
1255
 
1256
      while (cp < sp && ((*cp >= '0' && *cp <= '9')
1257
                         || (*cp >= 'a' && *cp <= 'z')))
1258
 
1259
        {
1260
          obstack_1grow (&string_obstack, *cp);
1261
          cp++;
1262
          size++;
1263
        }
1264
 
1265
      while (cp < sp)
1266
        {
1267
          if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
1268
            {
1269
              /* Don't set a value if there are more than one
1270
                 instruction in the string.  */
1271
              obstack_next_free (&string_obstack) =
1272
                obstack_next_free (&string_obstack) - size;
1273
              size = 0;
1274
 
1275
              cp = sp;
1276
              break;
1277
            }
1278
          cp++;
1279
        }
1280
      if (size == 0)
1281
        obstack_1grow (&string_obstack, '*');
1282
      else
1283
        add_mnemonic_string (mnemonic_htab,
1284
                             obstack_next_free (&string_obstack) - size,
1285
                             size);
1286
      i++;
1287
    }
1288
 
1289
  /* An insn definition might emit an empty string.  */
1290
  if (obstack_object_size (&string_obstack) == 0)
1291
    return;
1292
 
1293
  obstack_1grow (&string_obstack, '\0');
1294
 
1295
  set_attr = rtx_alloc (SET_ATTR);
1296
  XSTR (set_attr, 1) = XOBFINISH (&string_obstack, char *);
1297
  attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
1298
  strcpy (attr_name, MNEMONIC_ATTR_NAME);
1299
  XSTR (set_attr, 0) = attr_name;
1300
 
1301
  if (!XVEC (insn, 4))
1302
    vec_len = 0;
1303
  else
1304
    vec_len = XVECLEN (insn, 4);
1305
 
1306
  new_vec = rtvec_alloc (vec_len + 1);
1307
  for (i = 0; i < vec_len; i++)
1308
    RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
1309
  RTVEC_ELT (new_vec, vec_len) = set_attr;
1310
  XVEC (insn, 4) = new_vec;
1311
}
1312
 
1313
/* This function is called for the elements in the mnemonic hashtable
1314
   and generates a comma separated list of the mnemonics.  */
1315
 
1316
static int
1317
mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
1318
{
1319
  obstack_grow (&string_obstack, (char*)*slot, strlen ((char*)*slot));
1320
  obstack_1grow (&string_obstack, ',');
1321
  return 1;
1322
}
1323
 
1324
/* Generate (set_attr "mnemonic" "..") RTXs and append them to every
1325
   insn definition in case the back end requests it by defining the
1326
   mnemonic attribute.  The values for the attribute will be extracted
1327
   from the output patterns of the insn definitions as far as
1328
   possible.  */
1329
 
1330
static void
1331
gen_mnemonic_attr (void)
1332
{
1333
  struct queue_elem *elem;
1334
  rtx mnemonic_attr = NULL;
1335
  htab_t mnemonic_htab;
1336
  const char *str, *p;
1337
  int i;
1338
 
1339
  if (have_error)
1340
    return;
1341
 
1342
  /* Look for the DEFINE_ATTR for `mnemonic'.  */
1343
  for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
1344
    if (GET_CODE (elem->data) == DEFINE_ATTR
1345
        && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
1346
      {
1347
        mnemonic_attr = elem->data;
1348
        break;
1349
      }
1350
 
1351
  /* A (define_attr "mnemonic" "...") indicates that the back-end
1352
     wants a mnemonic attribute to be generated.  */
1353
  if (!mnemonic_attr)
1354
    return;
1355
 
1356
  mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
1357
                                     htab_eq_string, 0, xcalloc, free);
1358
 
1359
  for (elem = define_insn_queue; elem; elem = elem->next)
1360
    {
1361
      rtx insn = elem->data;
1362
      bool found = false;
1363
 
1364
      /* Check if the insn definition already has
1365
         (set_attr "mnemonic" ...).  */
1366
      if (XVEC (insn, 4))
1367
        for (i = 0; i < XVECLEN (insn, 4); i++)
1368
          if (strcmp (XSTR (XVECEXP (insn, 4, i), 0), MNEMONIC_ATTR_NAME) == 0)
1369
            {
1370
              found = true;
1371
              break;
1372
            }
1373
 
1374
      if (!found)
1375
        gen_mnemonic_setattr (mnemonic_htab, insn);
1376
    }
1377
 
1378
  /* Add the user defined values to the hash table.  */
1379
  str = XSTR (mnemonic_attr, 1);
1380
  while ((p = scan_comma_elt (&str)) != NULL)
1381
    add_mnemonic_string (mnemonic_htab, p, str - p);
1382
 
1383
  htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
1384
 
1385
  /* Replace the last ',' with the zero end character.  */
1386
  *((char *)obstack_next_free (&string_obstack) - 1) = '\0';
1387
  XSTR (mnemonic_attr, 1) = XOBFINISH (&string_obstack, char *);
1388
}
1389
 
1390
/* The entry point for initializing the reader.  */
1391
 
1392
bool
1393
init_rtx_reader_args_cb (int argc, char **argv,
1394
                         bool (*parse_opt) (const char *))
1395
{
1396
  /* Prepare to read input.  */
1397
  condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
1398
  init_predicate_table ();
1399
  obstack_init (rtl_obstack);
1400
  sequence_num = 0;
1401
 
1402
  read_md_files (argc, argv, parse_opt, rtx_handle_directive);
1403
 
1404
  /* Process define_cond_exec patterns.  */
1405
  if (define_cond_exec_queue != NULL)
1406
    process_define_cond_exec ();
1407
 
1408
  if (define_attr_queue != NULL)
1409
    gen_mnemonic_attr ();
1410
 
1411
  return !have_error;
1412
}
1413
 
1414
/* Programs that don't have their own options can use this entry point
1415
   instead.  */
1416
bool
1417
init_rtx_reader_args (int argc, char **argv)
1418
{
1419
  return init_rtx_reader_args_cb (argc, argv, 0);
1420
}
1421
 
1422
/* The entry point for reading a single rtx from an md file.  */
1423
 
1424
rtx
1425
read_md_rtx (int *lineno, int *seqnr)
1426
{
1427
  struct queue_elem **queue, *elem;
1428
  rtx desc;
1429
 
1430
 discard:
1431
 
1432
  /* Read all patterns from a given queue before moving on to the next.  */
1433
  if (define_attr_queue != NULL)
1434
    queue = &define_attr_queue;
1435
  else if (define_pred_queue != NULL)
1436
    queue = &define_pred_queue;
1437
  else if (define_insn_queue != NULL)
1438
    queue = &define_insn_queue;
1439
  else if (other_queue != NULL)
1440
    queue = &other_queue;
1441
  else
1442
    return NULL_RTX;
1443
 
1444
  elem = *queue;
1445
  *queue = elem->next;
1446
  desc = elem->data;
1447
  read_md_filename = elem->filename;
1448
  *lineno = elem->lineno;
1449
  *seqnr = sequence_num;
1450
 
1451
  free (elem);
1452
 
1453
  /* Discard insn patterns which we know can never match (because
1454
     their C test is provably always false).  If insn_elision is
1455
     false, our caller needs to see all the patterns.  Note that the
1456
     elided patterns are never counted by the sequence numbering; it
1457
     is the caller's responsibility, when insn_elision is false, not
1458
     to use elided pattern numbers for anything.  */
1459
  switch (GET_CODE (desc))
1460
    {
1461
    case DEFINE_INSN:
1462
    case DEFINE_EXPAND:
1463
      if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1464
        sequence_num++;
1465
      else if (insn_elision)
1466
        goto discard;
1467
 
1468
      /* *seqnr is used here so the name table will match caller's
1469
         idea of insn numbering, whether or not elision is active.  */
1470
      record_insn_name (*seqnr, XSTR (desc, 0));
1471
      break;
1472
 
1473
    case DEFINE_SPLIT:
1474
    case DEFINE_PEEPHOLE:
1475
    case DEFINE_PEEPHOLE2:
1476
      if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1477
        sequence_num++;
1478
      else if (insn_elision)
1479
            goto discard;
1480
      break;
1481
 
1482
    default:
1483
      break;
1484
    }
1485
 
1486
  return desc;
1487
}
1488
 
1489
/* Helper functions for insn elision.  */
1490
 
1491
/* Compute a hash function of a c_test structure, which is keyed
1492
   by its ->expr field.  */
1493
hashval_t
1494
hash_c_test (const void *x)
1495
{
1496
  const struct c_test *a = (const struct c_test *) x;
1497
  const unsigned char *base, *s = (const unsigned char *) a->expr;
1498
  hashval_t hash;
1499
  unsigned char c;
1500
  unsigned int len;
1501
 
1502
  base = s;
1503
  hash = 0;
1504
 
1505
  while ((c = *s++) != '\0')
1506
    {
1507
      hash += c + (c << 17);
1508
      hash ^= hash >> 2;
1509
    }
1510
 
1511
  len = s - base;
1512
  hash += len + (len << 17);
1513
  hash ^= hash >> 2;
1514
 
1515
  return hash;
1516
}
1517
 
1518
/* Compare two c_test expression structures.  */
1519
int
1520
cmp_c_test (const void *x, const void *y)
1521
{
1522
  const struct c_test *a = (const struct c_test *) x;
1523
  const struct c_test *b = (const struct c_test *) y;
1524
 
1525
  return !strcmp (a->expr, b->expr);
1526
}
1527
 
1528
/* Given a string representing a C test expression, look it up in the
1529
   condition_table and report whether or not its value is known
1530
   at compile time.  Returns a tristate: 1 for known true, 0 for
1531
   known false, -1 for unknown.  */
1532
int
1533
maybe_eval_c_test (const char *expr)
1534
{
1535
  const struct c_test *test;
1536
  struct c_test dummy;
1537
 
1538
  if (expr[0] == 0)
1539
    return 1;
1540
 
1541
  dummy.expr = expr;
1542
  test = (const struct c_test *)htab_find (condition_table, &dummy);
1543
  if (!test)
1544
    return -1;
1545
  return test->value;
1546
}
1547
 
1548
/* Record the C test expression EXPR in the condition_table, with
1549
   value VAL.  Duplicates clobber previous entries.  */
1550
 
1551
void
1552
add_c_test (const char *expr, int value)
1553
{
1554
  struct c_test *test;
1555
 
1556
  if (expr[0] == 0)
1557
    return;
1558
 
1559
  test = XNEW (struct c_test);
1560
  test->expr = expr;
1561
  test->value = value;
1562
 
1563
  *(htab_find_slot (condition_table, test, INSERT)) = test;
1564
}
1565
 
1566
/* For every C test, call CALLBACK with two arguments: a pointer to
1567
   the condition structure and INFO.  Stops when CALLBACK returns zero.  */
1568
void
1569
traverse_c_tests (htab_trav callback, void *info)
1570
{
1571
  if (condition_table)
1572
    htab_traverse (condition_table, callback, info);
1573
}
1574
 
1575
/* Helper functions for define_predicate and define_special_predicate
1576
   processing.  Shared between genrecog.c and genpreds.c.  */
1577
 
1578
static htab_t predicate_table;
1579
struct pred_data *first_predicate;
1580
static struct pred_data **last_predicate = &first_predicate;
1581
 
1582
static hashval_t
1583
hash_struct_pred_data (const void *ptr)
1584
{
1585
  return htab_hash_string (((const struct pred_data *)ptr)->name);
1586
}
1587
 
1588
static int
1589
eq_struct_pred_data (const void *a, const void *b)
1590
{
1591
  return !strcmp (((const struct pred_data *)a)->name,
1592
                  ((const struct pred_data *)b)->name);
1593
}
1594
 
1595
struct pred_data *
1596
lookup_predicate (const char *name)
1597
{
1598
  struct pred_data key;
1599
  key.name = name;
1600
  return (struct pred_data *) htab_find (predicate_table, &key);
1601
}
1602
 
1603
/* Record that predicate PRED can accept CODE.  */
1604
 
1605
void
1606
add_predicate_code (struct pred_data *pred, enum rtx_code code)
1607
{
1608
  if (!pred->codes[code])
1609
    {
1610
      pred->num_codes++;
1611
      pred->codes[code] = true;
1612
 
1613
      if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
1614
        pred->allows_non_const = true;
1615
 
1616
      if (code != REG
1617
          && code != SUBREG
1618
          && code != MEM
1619
          && code != CONCAT
1620
          && code != PARALLEL
1621
          && code != STRICT_LOW_PART)
1622
        pred->allows_non_lvalue = true;
1623
 
1624
      if (pred->num_codes == 1)
1625
        pred->singleton = code;
1626
      else if (pred->num_codes == 2)
1627
        pred->singleton = UNKNOWN;
1628
    }
1629
}
1630
 
1631
void
1632
add_predicate (struct pred_data *pred)
1633
{
1634
  void **slot = htab_find_slot (predicate_table, pred, INSERT);
1635
  if (*slot)
1636
    {
1637
      error ("duplicate predicate definition for '%s'", pred->name);
1638
      return;
1639
    }
1640
  *slot = pred;
1641
  *last_predicate = pred;
1642
  last_predicate = &pred->next;
1643
}
1644
 
1645
/* This array gives the initial content of the predicate table.  It
1646
   has entries for all predicates defined in recog.c.  */
1647
 
1648
struct std_pred_table
1649
{
1650
  const char *name;
1651
  bool special;
1652
  bool allows_const_p;
1653
  RTX_CODE codes[NUM_RTX_CODE];
1654
};
1655
 
1656
static const struct std_pred_table std_preds[] = {
1657
  {"general_operand", false, true, {SUBREG, REG, MEM}},
1658
  {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT}},
1659
  {"register_operand", false, false, {SUBREG, REG}},
1660
  {"pmode_register_operand", true, false, {SUBREG, REG}},
1661
  {"scratch_operand", false, false, {SCRATCH, REG}},
1662
  {"immediate_operand", false, true, {UNKNOWN}},
1663
  {"const_int_operand", false, false, {CONST_INT}},
1664
  {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
1665
  {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
1666
  {"nonmemory_operand", false, true, {SUBREG, REG}},
1667
  {"push_operand", false, false, {MEM}},
1668
  {"pop_operand", false, false, {MEM}},
1669
  {"memory_operand", false, false, {SUBREG, MEM}},
1670
  {"indirect_operand", false, false, {SUBREG, MEM}},
1671
  {"ordered_comparison_operator", false, false, {EQ, NE,
1672
                                                 LE, LT, GE, GT,
1673
                                                 LEU, LTU, GEU, GTU}},
1674
  {"comparison_operator", false, false, {EQ, NE,
1675
                                         LE, LT, GE, GT,
1676
                                         LEU, LTU, GEU, GTU,
1677
                                         UNORDERED, ORDERED,
1678
                                         UNEQ, UNGE, UNGT,
1679
                                         UNLE, UNLT, LTGT}}
1680
};
1681
#define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1682
 
1683
/* Initialize the table of predicate definitions, starting with
1684
   the information we have on generic predicates.  */
1685
 
1686
static void
1687
init_predicate_table (void)
1688
{
1689
  size_t i, j;
1690
  struct pred_data *pred;
1691
 
1692
  predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1693
                                       eq_struct_pred_data, 0,
1694
                                       xcalloc, free);
1695
 
1696
  for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
1697
    {
1698
      pred = XCNEW (struct pred_data);
1699
      pred->name = std_preds[i].name;
1700
      pred->special = std_preds[i].special;
1701
 
1702
      for (j = 0; std_preds[i].codes[j] != 0; j++)
1703
        add_predicate_code (pred, std_preds[i].codes[j]);
1704
 
1705
      if (std_preds[i].allows_const_p)
1706
        for (j = 0; j < NUM_RTX_CODE; j++)
1707
          if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
1708
            add_predicate_code (pred, (enum rtx_code) j);
1709
 
1710
      add_predicate (pred);
1711
    }
1712
}
1713
 
1714
/* These functions allow linkage with print-rtl.c.  Also, some generators
1715
   like to annotate their output with insn names.  */
1716
 
1717
/* Holds an array of names indexed by insn_code_number.  */
1718
static char **insn_name_ptr = 0;
1719
static int insn_name_ptr_size = 0;
1720
 
1721
const char *
1722
get_insn_name (int code)
1723
{
1724
  if (code < insn_name_ptr_size)
1725
    return insn_name_ptr[code];
1726
  else
1727
    return NULL;
1728
}
1729
 
1730
static void
1731
record_insn_name (int code, const char *name)
1732
{
1733
  static const char *last_real_name = "insn";
1734
  static int last_real_code = 0;
1735
  char *new_name;
1736
 
1737
  if (insn_name_ptr_size <= code)
1738
    {
1739
      int new_size;
1740
      new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
1741
      insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
1742
      memset (insn_name_ptr + insn_name_ptr_size, 0,
1743
              sizeof(char *) * (new_size - insn_name_ptr_size));
1744
      insn_name_ptr_size = new_size;
1745
    }
1746
 
1747
  if (!name || name[0] == '\0')
1748
    {
1749
      new_name = XNEWVAR (char, strlen (last_real_name) + 10);
1750
      sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
1751
    }
1752
  else
1753
    {
1754
      last_real_name = new_name = xstrdup (name);
1755
      last_real_code = code;
1756
    }
1757
 
1758
  insn_name_ptr[code] = new_name;
1759
}
1760
 
1761
/* Make STATS describe the operands that appear in rtx X.  */
1762
 
1763
static void
1764
get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
1765
{
1766
  RTX_CODE code;
1767
  int i;
1768
  int len;
1769
  const char *fmt;
1770
 
1771
  if (x == NULL_RTX)
1772
    return;
1773
 
1774
  code = GET_CODE (x);
1775
  switch (code)
1776
    {
1777
    case MATCH_OPERAND:
1778
    case MATCH_OPERATOR:
1779
    case MATCH_PARALLEL:
1780
      stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
1781
      break;
1782
 
1783
    case MATCH_DUP:
1784
    case MATCH_OP_DUP:
1785
    case MATCH_PAR_DUP:
1786
      stats->num_dups++;
1787
      stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
1788
      break;
1789
 
1790
    case MATCH_SCRATCH:
1791
      stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
1792
      break;
1793
 
1794
    default:
1795
      break;
1796
    }
1797
 
1798
  fmt = GET_RTX_FORMAT (code);
1799
  len = GET_RTX_LENGTH (code);
1800
  for (i = 0; i < len; i++)
1801
    {
1802
      if (fmt[i] == 'e' || fmt[i] == 'u')
1803
        get_pattern_stats_1 (stats, XEXP (x, i));
1804
      else if (fmt[i] == 'E')
1805
        {
1806
          int j;
1807
          for (j = 0; j < XVECLEN (x, i); j++)
1808
            get_pattern_stats_1 (stats, XVECEXP (x, i, j));
1809
        }
1810
    }
1811
}
1812
 
1813
/* Make STATS describe the operands that appear in instruction pattern
1814
   PATTERN.  */
1815
 
1816
void
1817
get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
1818
{
1819
  int i, len;
1820
 
1821
  stats->max_opno = -1;
1822
  stats->max_dup_opno = -1;
1823
  stats->max_scratch_opno = -1;
1824
  stats->num_dups = 0;
1825
 
1826
  len = GET_NUM_ELEM (pattern);
1827
  for (i = 0; i < len; i++)
1828
    get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
1829
 
1830
  stats->num_generator_args = stats->max_opno + 1;
1831
  stats->num_insn_operands = MAX (stats->max_opno,
1832
                                  stats->max_scratch_opno) + 1;
1833
  stats->num_operand_vars = MAX (stats->max_opno,
1834
                                  MAX (stats->max_dup_opno,
1835
                                       stats->max_scratch_opno)) + 1;
1836
}

powered by: WebSVN 2.1.0

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