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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [igen/] [ld-insn.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* The IGEN simulator generator for GDB, the GNU Debugger.
2
 
3
   Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4
 
5
   Contributed by Andrew Cagney.
6
 
7
   This file is part of GDB.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
 
22
 
23
#include "misc.h"
24
#include "lf.h"
25
#include "table.h"
26
#include "filter.h"
27
#include "igen.h"
28
#include "ld-insn.h"
29
 
30
static insn_word_entry *
31
parse_insn_word (line_ref *line, char *string, int word_nr)
32
{
33
  char *chp;
34
  insn_word_entry *word = ZALLOC (insn_word_entry);
35
 
36
  /* create a leading sentinal */
37
  word->first = ZALLOC (insn_field_entry);
38
  word->first->first = -1;
39
  word->first->last = -1;
40
  word->first->width = 0;
41
 
42
  /* and a trailing sentinal */
43
  word->last = ZALLOC (insn_field_entry);
44
  word->last->first = options.insn_bit_size;
45
  word->last->last = options.insn_bit_size;
46
  word->last->width = 0;
47
 
48
  /* link them together */
49
  word->first->next = word->last;
50
  word->last->prev = word->first;
51
 
52
  /* now work through the formats */
53
  chp = skip_spaces (string);
54
 
55
  while (*chp != '\0')
56
    {
57
      char *start_pos;
58
      int strlen_pos;
59
      char *start_val;
60
      int strlen_val;
61
      insn_field_entry *new_field;
62
 
63
      /* create / link in the new field */
64
      new_field = ZALLOC (insn_field_entry);
65
      new_field->next = word->last;
66
      new_field->prev = word->last->prev;
67
      new_field->next->prev = new_field;
68
      new_field->prev->next = new_field;
69
      new_field->word_nr = word_nr;
70
 
71
      /* break out the first field (if present) */
72
      start_pos = chp;
73
      chp = skip_to_separator (chp, ".,!");
74
      strlen_pos = back_spaces (start_pos, chp) - start_pos;
75
 
76
      /* break out the second field (if present) */
77
      if (*chp != '.')
78
        {
79
          /* assume what was specified was the value (and not the start
80
             position).  Assume the value length implicitly specifies
81
             the number of bits */
82
          start_val = start_pos;
83
          strlen_val = strlen_pos;
84
          start_pos = "";
85
          strlen_pos = 0;
86
        }
87
      else
88
        {
89
          chp++;                /* skip `.' */
90
          chp = skip_spaces (chp);
91
          start_val = chp;
92
          if (*chp == '/' || *chp == '*')
93
            {
94
              do
95
                {
96
                  chp++;
97
                }
98
              while (*chp == '/' || *chp == '*');
99
            }
100
          else if (isalpha (*start_val))
101
            {
102
              do
103
                {
104
                  chp++;
105
                }
106
              while (isalnum (*chp) || *chp == '_');
107
            }
108
          else if (isdigit (*start_val))
109
            {
110
              do
111
                {
112
                  chp++;
113
                }
114
              while (isalnum (*chp));
115
            }
116
          strlen_val = chp - start_val;
117
          chp = skip_spaces (chp);
118
        }
119
      if (strlen_val == 0)
120
        error (line, "Empty value field\n");
121
 
122
      /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */
123
      while (*chp == '!' || *chp == '=')
124
        {
125
          char *start;
126
          char *end;
127
          int len;
128
          insn_field_cond *new_cond = ZALLOC (insn_field_cond);
129
 
130
          /* determine the conditional test */
131
          switch (*chp)
132
            {
133
            case '=':
134
              new_cond->test = insn_field_cond_eq;
135
              break;
136
            case '!':
137
              new_cond->test = insn_field_cond_ne;
138
              break;
139
            default:
140
              ASSERT (0);
141
            }
142
 
143
          /* save the value */
144
          chp++;
145
          chp = skip_spaces (chp);
146
          start = chp;
147
          chp = skip_to_separator (chp, "+,:!=");
148
          end = back_spaces (start, chp);
149
          len = end - start;
150
          if (len == 0)
151
            error (line, "Missing or invalid conditional value\n");
152
          new_cond->string = NZALLOC (char, len + 1);
153
          strncpy (new_cond->string, start, len);
154
 
155
          /* determine the conditional type */
156
          if (isdigit (*start))
157
            {
158
              /* [ "!" | "=" ] <value> */
159
              new_cond->type = insn_field_cond_value;
160
              new_cond->value = a2i (new_cond->string);
161
            }
162
          else
163
            {
164
              /* [ "!" | "=" ] <field>  - check field valid */
165
              new_cond->type = insn_field_cond_field;
166
              /* new_cond->field is determined in later */
167
            }
168
 
169
          /* Only a single `=' is permitted. */
170
          if ((new_cond->test == insn_field_cond_eq
171
               && new_field->conditions != NULL)
172
              || (new_field->conditions != NULL
173
                  && new_field->conditions->test == insn_field_cond_eq))
174
            error (line, "Only single conditional when `=' allowed\n");
175
 
176
          /* insert it */
177
          {
178
            insn_field_cond **last = &new_field->conditions;
179
            while (*last != NULL)
180
              last = &(*last)->next;
181
            *last = new_cond;
182
          }
183
        }
184
 
185
      /* NOW verify that the field was finished */
186
      if (*chp == ',')
187
        {
188
          chp = skip_spaces (chp + 1);
189
          if (*chp == '\0')
190
            error (line, "empty field\n");
191
        }
192
      else if (*chp != '\0')
193
        {
194
          error (line, "Missing field separator\n");
195
        }
196
 
197
      /* copy the value */
198
      new_field->val_string = NZALLOC (char, strlen_val + 1);
199
      strncpy (new_field->val_string, start_val, strlen_val);
200
      if (isdigit (new_field->val_string[0]))
201
        {
202
          if (strlen_pos == 0)
203
            {
204
              /* when the length/pos field is omited, an integer field
205
                 is always binary */
206
              unsigned64 val = 0;
207
              int i;
208
              for (i = 0; i < strlen_val; i++)
209
                {
210
                  if (new_field->val_string[i] != '0'
211
                      && new_field->val_string[i] != '1')
212
                    error (line, "invalid binary field %s\n",
213
                           new_field->val_string);
214
                  val = (val << 1) + (new_field->val_string[i] == '1');
215
                }
216
              new_field->val_int = val;
217
              new_field->type = insn_field_int;
218
            }
219
          else
220
            {
221
              new_field->val_int = a2i (new_field->val_string);
222
              new_field->type = insn_field_int;
223
            }
224
        }
225
      else if (new_field->val_string[0] == '/')
226
        {
227
          new_field->type = insn_field_reserved;
228
        }
229
      else if (new_field->val_string[0] == '*')
230
        {
231
          new_field->type = insn_field_wild;
232
        }
233
      else
234
        {
235
          new_field->type = insn_field_string;
236
          if (filter_is_member (word->field_names, new_field->val_string))
237
            error (line, "Field name %s is duplicated\n",
238
                   new_field->val_string);
239
          filter_parse (&word->field_names, new_field->val_string);
240
        }
241
      if (new_field->type != insn_field_string
242
          && new_field->conditions != NULL)
243
        error (line, "Conditionals can only be applied to named fields\n");
244
 
245
      /* the copy the position */
246
      new_field->pos_string = NZALLOC (char, strlen_pos + 1);
247
      strncpy (new_field->pos_string, start_pos, strlen_pos);
248
      if (strlen_pos == 0)
249
        {
250
          new_field->first = new_field->prev->last + 1;
251
          if (new_field->first == 0      /* first field */
252
              && *chp == '\0'   /* no further fields */
253
              && new_field->type == insn_field_string)
254
            {
255
              /* A single string without any position, assume that it
256
                 represents the entire instruction word */
257
              new_field->width = options.insn_bit_size;
258
            }
259
          else
260
            {
261
              /* No explicit width/position, assume value implicitly
262
                 supplies the width */
263
              new_field->width = strlen_val;
264
            }
265
          new_field->last = new_field->first + new_field->width - 1;
266
          if (new_field->last >= options.insn_bit_size)
267
            error (line, "Bit position %d exceed instruction bit size (%d)\n",
268
                   new_field->last, options.insn_bit_size);
269
        }
270
      else if (options.insn_specifying_widths)
271
        {
272
          new_field->first = new_field->prev->last + 1;
273
          new_field->width = a2i (new_field->pos_string);
274
          new_field->last = new_field->first + new_field->width - 1;
275
          if (new_field->last >= options.insn_bit_size)
276
            error (line, "Bit position %d exceed instruction bit size (%d)\n",
277
                   new_field->last, options.insn_bit_size);
278
        }
279
      else
280
        {
281
          new_field->first = target_a2i (options.hi_bit_nr,
282
                                         new_field->pos_string);
283
          new_field->last = new_field->next->first - 1; /* guess */
284
          new_field->width = new_field->last - new_field->first + 1;    /* guess */
285
          new_field->prev->last = new_field->first - 1; /*fix */
286
          new_field->prev->width = new_field->first - new_field->prev->first;   /*fix */
287
        }
288
    }
289
 
290
  /* fiddle first/last so that the sentinals disapear */
291
  ASSERT (word->first->last < 0);
292
  ASSERT (word->last->first >= options.insn_bit_size);
293
  word->first = word->first->next;
294
  word->last = word->last->prev;
295
 
296
  /* check that the last field goes all the way to the last bit */
297
  if (word->last->last != options.insn_bit_size - 1)
298
    {
299
      if (options.warn.width)
300
        options.warning (line, "Instruction format is not %d bits wide\n",
301
                         options.insn_bit_size);
302
      word->last->last = options.insn_bit_size - 1;
303
    }
304
 
305
  /* now go over this again, pointing each bit position at a field
306
     record */
307
  {
308
    insn_field_entry *field;
309
    for (field = word->first;
310
         field->last < options.insn_bit_size; field = field->next)
311
      {
312
        int i;
313
        for (i = field->first; i <= field->last; i++)
314
          {
315
            word->bit[i] = ZALLOC (insn_bit_entry);
316
            word->bit[i]->field = field;
317
            switch (field->type)
318
              {
319
              case insn_field_invalid:
320
                ASSERT (0);
321
                break;
322
              case insn_field_int:
323
                word->bit[i]->mask = 1;
324
                word->bit[i]->value = ((field->val_int
325
                                        & ((insn_uint) 1 <<
326
                                           (field->last - i))) != 0);
327
              case insn_field_reserved:
328
              case insn_field_wild:
329
              case insn_field_string:
330
                /* if we encounter a constant conditional, encode
331
                   their bit value. */
332
                if (field->conditions != NULL
333
                    && field->conditions->test == insn_field_cond_eq
334
                    && field->conditions->type == insn_field_cond_value)
335
                  {
336
                    word->bit[i]->mask = 1;
337
                    word->bit[i]->value = ((field->conditions->value
338
                                            & ((insn_uint) 1 <<
339
                                               (field->last - i))) != 0);
340
                  }
341
                break;
342
              }
343
          }
344
      }
345
  }
346
 
347
  return word;
348
}
349
 
350
 
351
static void
352
parse_insn_words (insn_entry * insn, char *formats)
353
{
354
  insn_word_entry **last_word = &insn->words;
355
  char *chp;
356
 
357
  /* now work through the formats */
358
  insn->nr_words = 0;
359
  chp = formats;
360
 
361
  while (1)
362
    {
363
      char *start_pos;
364
      char *end_pos;
365
      int strlen_pos;
366
      char *format;
367
      insn_word_entry *new_word;
368
 
369
      /* skip leading spaces */
370
      chp = skip_spaces (chp);
371
 
372
      /* break out the format */
373
      start_pos = chp;
374
      chp = skip_to_separator (chp, "+");
375
      end_pos = back_spaces (start_pos, chp);
376
      strlen_pos = end_pos - start_pos;
377
 
378
      /* check that something was there */
379
      if (strlen_pos == 0)
380
        error (insn->line, "missing or empty instruction format\n");
381
 
382
      /* parse the field */
383
      format = NZALLOC (char, strlen_pos + 1);
384
      strncpy (format, start_pos, strlen_pos);
385
      new_word = parse_insn_word (insn->line, format, insn->nr_words);
386
      insn->nr_words++;
387
      if (filter_is_common (insn->field_names, new_word->field_names))
388
        error (insn->line, "Field name duplicated between two words\n");
389
      filter_add (&insn->field_names, new_word->field_names);
390
 
391
      /* insert it */
392
      *last_word = new_word;
393
      last_word = &new_word->next;
394
 
395
      /* last format? */
396
      if (*chp == '\0')
397
        break;
398
      ASSERT (*chp == '+');
399
      chp++;
400
    }
401
 
402
  /* create a quick access array (indexed by word) of the same structure */
403
  {
404
    int i;
405
    insn_word_entry *word;
406
    insn->word = NZALLOC (insn_word_entry *, insn->nr_words + 1);
407
    for (i = 0, word = insn->words;
408
         i < insn->nr_words; i++, word = word->next)
409
      insn->word[i] = word;
410
  }
411
 
412
  /* Go over all fields that have conditionals refering to other
413
     fields.  Link the fields up.  Verify that the two fields have the
414
     same size. Verify that the two fields are different */
415
  {
416
    int i;
417
    for (i = 0; i < insn->nr_words; i++)
418
      {
419
        insn_word_entry *word = insn->word[i];
420
        insn_field_entry *f;
421
        for (f = word->first; f->last < options.insn_bit_size; f = f->next)
422
          {
423
            insn_field_cond *cond;
424
            for (cond = f->conditions; cond != NULL; cond = cond->next)
425
              {
426
                if (cond->type == insn_field_cond_field)
427
                  {
428
                    int j;
429
                    if (strcmp (cond->string, f->val_string) == 0)
430
                      error (insn->line,
431
                             "Conditional `%s' of field `%s' refers to its self\n",
432
                             cond->string, f->val_string);
433
                    for (j = 0; j <= i && cond->field == NULL; j++)
434
                      {
435
                        insn_word_entry *refered_word = insn->word[j];
436
                        insn_field_entry *refered_field;
437
                        for (refered_field = refered_word->first;
438
                             refered_field != NULL && cond->field == NULL;
439
                             refered_field = refered_field->next)
440
                          {
441
                            if (refered_field->type == insn_field_string
442
                                && strcmp (refered_field->val_string,
443
                                           cond->string) == 0)
444
                              {
445
                                /* found field being refered to by conditonal */
446
                                cond->field = refered_field;
447
                                /* check refered to and this field are
448
                                   the same size */
449
                                if (f->width != refered_field->width)
450
                                  error (insn->line,
451
                                         "Conditional `%s' of field `%s' should be of size %s\n",
452
                                         cond->string, f->val_string,
453
                                         refered_field->width);
454
                              }
455
                          }
456
                      }
457
                    if (cond->field == NULL)
458
                      error (insn->line,
459
                             "Conditional `%s' of field `%s' not yet defined\n",
460
                             cond->string, f->val_string);
461
                  }
462
              }
463
          }
464
      }
465
  }
466
 
467
}
468
 
469
typedef enum
470
{
471
  unknown_record = 0,
472
  insn_record,                  /* default */
473
  code_record,
474
  cache_record,
475
  compute_record,
476
  scratch_record,
477
  option_record,
478
  string_function_record,
479
  function_record,
480
  internal_record,
481
  define_record,
482
  include_record,
483
  model_processor_record,
484
  model_macro_record,
485
  model_data_record,
486
  model_static_record,
487
  model_function_record,
488
  model_internal_record,
489
}
490
insn_record_type;
491
 
492
static const name_map insn_type_map[] = {
493
  {"option", option_record},
494
  {"cache", cache_record},
495
  {"compute", compute_record},
496
  {"scratch", scratch_record},
497
  {"define", define_record},
498
  {"include", include_record},
499
  {"%s", string_function_record},
500
  {"function", function_record},
501
  {"internal", internal_record},
502
  {"model", model_processor_record},
503
  {"model-macro", model_macro_record},
504
  {"model-data", model_data_record},
505
  {"model-static", model_static_record},
506
  {"model-internal", model_internal_record},
507
  {"model-function", model_function_record},
508
  {NULL, insn_record},
509
};
510
 
511
 
512
static int
513
record_is_old (table_entry *entry)
514
{
515
  if (entry->nr_fields > record_type_field
516
      && strlen (entry->field[record_type_field]) == 0)
517
    return 1;
518
  return 0;
519
}
520
 
521
static insn_record_type
522
record_type (table_entry *entry)
523
{
524
  switch (entry->type)
525
    {
526
    case table_code_entry:
527
      return code_record;
528
 
529
    case table_colon_entry:
530
      if (record_is_old (entry))
531
        {
532
          /* old-format? */
533
          if (entry->nr_fields > old_record_type_field)
534
            {
535
              int i = name2i (entry->field[old_record_type_field],
536
                              insn_type_map);
537
              return i;
538
            }
539
          else
540
            {
541
              return unknown_record;
542
            }
543
        }
544
      else if (entry->nr_fields > record_type_field
545
               && entry->field[0][0] == '\0')
546
        {
547
          /* new-format? */
548
          int i = name2i (entry->field[record_type_field],
549
                          insn_type_map);
550
          return i;
551
        }
552
      else
553
        return insn_record;     /* default */
554
    }
555
  return unknown_record;
556
}
557
 
558
static int
559
record_prefix_is (table_entry *entry, char ch, int nr_fields)
560
{
561
  if (entry->type != table_colon_entry)
562
    return 0;
563
  if (entry->nr_fields < nr_fields)
564
    return 0;
565
  if (entry->field[0][0] != ch && ch != '\0')
566
    return 0;
567
  return 1;
568
}
569
 
570
static table_entry *
571
parse_model_data_record (insn_table *isa,
572
                         table *file,
573
                         table_entry *record,
574
                         int nr_fields, model_data **list)
575
{
576
  table_entry *model_record = record;
577
  table_entry *code_record = NULL;
578
  model_data *new_data;
579
  if (record->nr_fields < nr_fields)
580
    error (record->line, "Incorrect number of fields\n");
581
  record = table_read (file);
582
  if (record->type == table_code_entry)
583
    {
584
      code_record = record;
585
      record = table_read (file);
586
    }
587
  /* create the new data record */
588
  new_data = ZALLOC (model_data);
589
  new_data->line = model_record->line;
590
  filter_parse (&new_data->flags,
591
                model_record->field[record_filter_flags_field]);
592
  new_data->entry = model_record;
593
  new_data->code = code_record;
594
  /* append it if not filtered out */
595
  if (!is_filtered_out (options.flags_filter,
596
                        model_record->field[record_filter_flags_field])
597
      && !is_filtered_out (options.model_filter,
598
                           model_record->field[record_filter_models_field]))
599
    {
600
      while (*list != NULL)
601
        list = &(*list)->next;
602
      *list = new_data;
603
    }
604
  return record;
605
}
606
 
607
 
608
typedef enum
609
{
610
  insn_bit_size_option = 1,
611
  insn_specifying_widths_option,
612
  hi_bit_nr_option,
613
  flags_filter_option,
614
  model_filter_option,
615
  multi_sim_option,
616
  format_names_option,
617
  gen_delayed_branch,
618
  unknown_option,
619
}
620
option_names;
621
 
622
static const name_map option_map[] = {
623
  {"insn-bit-size", insn_bit_size_option},
624
  {"insn-specifying-widths", insn_specifying_widths_option},
625
  {"hi-bit-nr", hi_bit_nr_option},
626
  {"flags-filter", flags_filter_option},
627
  {"model-filter", model_filter_option},
628
  {"multi-sim", multi_sim_option},
629
  {"format-names", format_names_option},
630
  {"gen-delayed-branch", gen_delayed_branch},
631
  {NULL, unknown_option},
632
};
633
 
634
static table_entry *
635
parse_include_record (table *file, table_entry *record)
636
{
637
  /* parse the include record */
638
  if (record->nr_fields < nr_include_fields)
639
    error (record->line, "Incorrect nr fields for include record\n");
640
  /* process it */
641
  if (!is_filtered_out (options.flags_filter,
642
                        record->field[record_filter_flags_field])
643
      && !is_filtered_out (options.model_filter,
644
                           record->field[record_filter_models_field]))
645
    {
646
      table_push (file, record->line, options.include,
647
                  record->field[include_filename_field]);
648
    }
649
  /* nb: can't read next record until after the file has been pushed */
650
  record = table_read (file);
651
  return record;
652
}
653
 
654
 
655
static table_entry *
656
parse_option_record (table *file, table_entry *record)
657
{
658
  table_entry *option_record;
659
  /* parse the option record */
660
  option_record = record;
661
  if (record->nr_fields < nr_option_fields)
662
    error (record->line, "Incorrect nr of fields for option record\n");
663
  record = table_read (file);
664
  /* process it */
665
  if (!is_filtered_out (options.flags_filter,
666
                        option_record->field[record_filter_flags_field])
667
      && !is_filtered_out (options.model_filter,
668
                           option_record->field[record_filter_models_field]))
669
    {
670
      char *name = option_record->field[option_name_field];
671
      option_names option = name2i (name, option_map);
672
      char *value = option_record->field[option_value_field];
673
      switch (option)
674
        {
675
        case insn_bit_size_option:
676
          {
677
            options.insn_bit_size = a2i (value);
678
            if (options.insn_bit_size < 0
679
                || options.insn_bit_size > max_insn_bit_size)
680
              error (option_record->line,
681
                     "Instruction bit size out of range\n");
682
            if (options.hi_bit_nr != options.insn_bit_size - 1
683
                && options.hi_bit_nr != 0)
684
              error (option_record->line,
685
                     "insn-bit-size / hi-bit-nr conflict\n");
686
            break;
687
          }
688
        case insn_specifying_widths_option:
689
          {
690
            options.insn_specifying_widths = a2i (value);
691
            break;
692
          }
693
        case hi_bit_nr_option:
694
          {
695
            options.hi_bit_nr = a2i (value);
696
            if (options.hi_bit_nr != 0
697
                && options.hi_bit_nr != options.insn_bit_size - 1)
698
              error (option_record->line,
699
                     "hi-bit-nr / insn-bit-size conflict\n");
700
            break;
701
          }
702
        case flags_filter_option:
703
          {
704
            filter_parse (&options.flags_filter, value);
705
            break;
706
          }
707
        case model_filter_option:
708
          {
709
            filter_parse (&options.model_filter, value);
710
            break;
711
          }
712
        case multi_sim_option:
713
          {
714
            options.gen.multi_sim = a2i (value);
715
            break;
716
          }
717
        case format_names_option:
718
          {
719
            filter_parse (&options.format_name_filter, value);
720
            break;
721
          }
722
        case gen_delayed_branch:
723
          {
724
            options.gen.delayed_branch = a2i (value);
725
            break;
726
          }
727
        case unknown_option:
728
          {
729
            error (option_record->line, "Unknown option - %s\n", name);
730
            break;
731
          }
732
        }
733
    }
734
  return record;
735
}
736
 
737
 
738
static table_entry *
739
parse_function_record (table *file,
740
                       table_entry *record,
741
                       function_entry ** list,
742
                       function_entry ** list_entry,
743
                       int is_internal, model_table *model)
744
{
745
  function_entry *new_function;
746
  new_function = ZALLOC (function_entry);
747
  new_function->line = record->line;
748
  new_function->is_internal = is_internal;
749
  /* parse the function header */
750
  if (record_is_old (record))
751
    {
752
      if (record->nr_fields < nr_old_function_fields)
753
        error (record->line, "Missing fields from (old) function record\n");
754
      new_function->type = record->field[old_function_typedef_field];
755
      new_function->type = record->field[old_function_typedef_field];
756
      if (record->nr_fields > old_function_param_field)
757
        new_function->param = record->field[old_function_param_field];
758
      new_function->name = record->field[old_function_name_field];
759
    }
760
  else
761
    {
762
      if (record->nr_fields < nr_function_fields)
763
        error (record->line, "Missing fields from function record\n");
764
      filter_parse (&new_function->flags,
765
                    record->field[record_filter_flags_field]);
766
      filter_parse (&new_function->models,
767
                    record->field[record_filter_models_field]);
768
      new_function->type = record->field[function_typedef_field];
769
      new_function->param = record->field[function_param_field];
770
      new_function->name = record->field[function_name_field];
771
    }
772
  record = table_read (file);
773
  /* parse any function-model records */
774
  while (record != NULL
775
         && record_prefix_is (record, '*', nr_function_model_fields))
776
    {
777
      char *model_name = record->field[function_model_name_field] + 1;  /*skip `*' */
778
      filter_parse (&new_function->models, model_name);
779
      if (!filter_is_subset (model->processors, new_function->models))
780
        {
781
          error (record->line, "machine model `%s' undefined\n", model_name);
782
        }
783
      record = table_read (file);
784
    }
785
  /* parse the function body */
786
  if (record->type == table_code_entry)
787
    {
788
      new_function->code = record;
789
      record = table_read (file);
790
    }
791
  /* insert it */
792
  if (!filter_is_subset (options.flags_filter, new_function->flags))
793
    {
794
      if (options.warn.discard)
795
        notify (new_function->line, "Discarding function %s - filter flags\n",
796
                new_function->name);
797
    }
798
  else if (new_function->models != NULL
799
           && !filter_is_common (options.model_filter, new_function->models))
800
    {
801
      if (options.warn.discard)
802
        notify (new_function->line,
803
                "Discarding function %s - filter models\n",
804
                new_function->name);
805
    }
806
  else
807
    {
808
      while (*list != NULL)
809
        list = &(*list)->next;
810
      *list = new_function;
811
      if (list_entry != NULL)
812
        *list_entry = new_function;
813
    }
814
  /* done */
815
  return record;
816
}
817
 
818
static void
819
parse_insn_model_record (table *file,
820
                         table_entry *record,
821
                         insn_entry * insn, model_table *model)
822
{
823
  insn_model_entry **last_insn_model;
824
  insn_model_entry *new_insn_model = ZALLOC (insn_model_entry);
825
  /* parse it */
826
  new_insn_model->line = record->line;
827
  if (record->nr_fields > insn_model_unit_data_field)
828
    new_insn_model->unit_data = record->field[insn_model_unit_data_field];
829
  new_insn_model->insn = insn;
830
  /* parse the model names, verify that all were defined */
831
  new_insn_model->names = NULL;
832
  filter_parse (&new_insn_model->names,
833
                record->field[insn_model_name_field] + 1 /*skip `*' */ );
834
  if (new_insn_model->names == NULL)
835
    {
836
      /* No processor names - a generic model entry, enter it into all
837
         the non-empty fields */
838
      int index;
839
      for (index = 0; index < model->nr_models; index++)
840
        if (insn->model[index] == 0)
841
          {
842
            insn->model[index] = new_insn_model;
843
          }
844
      /* also add the complete processor set to this processor's set */
845
      filter_add (&insn->processors, model->processors);
846
    }
847
  else
848
    {
849
      /* Find the corresponding master model record for each name so
850
         that they can be linked in. */
851
      int index;
852
      char *name = "";
853
      while (1)
854
        {
855
          name = filter_next (new_insn_model->names, name);
856
          if (name == NULL)
857
            break;
858
          index = filter_is_member (model->processors, name) - 1;
859
          if (index < 0)
860
            {
861
              error (new_insn_model->line,
862
                     "machine model `%s' undefined\n", name);
863
            }
864
          /* store it in the corresponding model array entry */
865
          if (insn->model[index] != NULL && insn->model[index]->names != NULL)
866
            {
867
              warning (new_insn_model->line,
868
                       "machine model `%s' previously defined\n", name);
869
              error (insn->model[index]->line, "earlier definition\n");
870
            }
871
          insn->model[index] = new_insn_model;
872
          /* also add the name to the instructions processor set as an
873
             alternative lookup mechanism */
874
          filter_parse (&insn->processors, name);
875
        }
876
    }
877
#if 0
878
  /* for some reason record the max length of any
879
     function unit field */
880
  int len = strlen (insn_model_ptr->field[insn_model_fields]);
881
  if (model->max_model_fields_len < len)
882
    model->max_model_fields_len = len;
883
#endif
884
  /* link it in */
885
  last_insn_model = &insn->models;
886
  while ((*last_insn_model) != NULL)
887
    last_insn_model = &(*last_insn_model)->next;
888
  *last_insn_model = new_insn_model;
889
}
890
 
891
 
892
static void
893
parse_insn_mnemonic_record (table *file,
894
                            table_entry *record, insn_entry * insn)
895
{
896
  insn_mnemonic_entry **last_insn_mnemonic;
897
  insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry);
898
  /* parse it */
899
  new_insn_mnemonic->line = record->line;
900
  ASSERT (record->nr_fields > insn_mnemonic_format_field);
901
  new_insn_mnemonic->format = record->field[insn_mnemonic_format_field];
902
  ASSERT (new_insn_mnemonic->format[0] == '"');
903
  if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] !=
904
      '"')
905
    error (new_insn_mnemonic->line,
906
           "Missing closing double quote in mnemonic field\n");
907
  if (record->nr_fields > insn_mnemonic_condition_field)
908
    new_insn_mnemonic->condition =
909
      record->field[insn_mnemonic_condition_field];
910
  new_insn_mnemonic->insn = insn;
911
  /* insert it */
912
  last_insn_mnemonic = &insn->mnemonics;
913
  while ((*last_insn_mnemonic) != NULL)
914
    last_insn_mnemonic = &(*last_insn_mnemonic)->next;
915
  insn->nr_mnemonics++;
916
  *last_insn_mnemonic = new_insn_mnemonic;
917
}
918
 
919
 
920
static table_entry *
921
parse_macro_record (table *file, table_entry *record)
922
{
923
#if 1
924
  error (record->line, "Macros are not implemented");
925
#else
926
  /* parse the define record */
927
  if (record->nr_fields < nr_define_fields)
928
    error (record->line, "Incorrect nr fields for define record\n");
929
  /* process it */
930
  if (!is_filtered_out (options.flags_filter,
931
                        record->field[record_filter_flags_field])
932
      && !is_filtered_out (options.model_filter,
933
                           record->field[record_filter_models_field]))
934
    {
935
      table_define (file,
936
                    record->line,
937
                    record->field[macro_name_field],
938
                    record->field[macro_args_field],
939
                    record->field[macro_expr_field]);
940
    }
941
  record = table_read (file);
942
#endif
943
  return record;
944
}
945
 
946
 
947
insn_table *
948
load_insn_table (char *file_name, cache_entry *cache)
949
{
950
  table *file = table_open (file_name);
951
  table_entry *record = table_read (file);
952
 
953
  insn_table *isa = ZALLOC (insn_table);
954
  model_table *model = ZALLOC (model_table);
955
 
956
  isa->model = model;
957
  isa->caches = cache;
958
 
959
  while (record != NULL)
960
    {
961
 
962
      switch (record_type (record))
963
        {
964
 
965
        case include_record:
966
          {
967
            record = parse_include_record (file, record);
968
            break;
969
          }
970
 
971
        case option_record:
972
          {
973
            if (isa->insns != NULL)
974
              error (record->line, "Option after first instruction\n");
975
            record = parse_option_record (file, record);
976
            break;
977
          }
978
 
979
        case string_function_record:
980
          {
981
            function_entry *function = NULL;
982
            record = parse_function_record (file, record,
983
                                            &isa->functions,
984
                                            &function, 0 /*is-internal */ ,
985
                                            model);
986
            /* convert a string function record into an internal function */
987
            if (function != NULL)
988
              {
989
                char *name = NZALLOC (char,
990
                                      (strlen ("str_")
991
                                       + strlen (function->name) + 1));
992
                strcat (name, "str_");
993
                strcat (name, function->name);
994
                function->name = name;
995
                function->type = "const char *";
996
              }
997
            break;
998
          }
999
 
1000
        case function_record:   /* function record */
1001
          {
1002
            record = parse_function_record (file, record,
1003
                                            &isa->functions,
1004
                                            NULL, 0 /*is-internal */ ,
1005
                                            model);
1006
            break;
1007
          }
1008
 
1009
        case internal_record:
1010
          {
1011
            /* only insert it into the function list if it is unknown */
1012
            function_entry *function = NULL;
1013
            record = parse_function_record (file, record,
1014
                                            &isa->functions,
1015
                                            &function, 1 /*is-internal */ ,
1016
                                            model);
1017
            /* check what was inserted to see if a pseudo-instruction
1018
               entry also needs to be created */
1019
            if (function != NULL)
1020
              {
1021
                insn_entry **insn = NULL;
1022
                if (strcmp (function->name, "illegal") == 0)
1023
                  {
1024
                    /* illegal function save it away */
1025
                    if (isa->illegal_insn != NULL)
1026
                      {
1027
                        warning (function->line,
1028
                                 "Multiple illegal instruction definitions\n");
1029
                        error (isa->illegal_insn->line,
1030
                               "Location of first illegal instruction\n");
1031
                      }
1032
                    else
1033
                      insn = &isa->illegal_insn;
1034
                  }
1035
                if (insn != NULL)
1036
                  {
1037
                    *insn = ZALLOC (insn_entry);
1038
                    (*insn)->line = function->line;
1039
                    (*insn)->name = function->name;
1040
                    (*insn)->code = function->code;
1041
                  }
1042
              }
1043
            break;
1044
          }
1045
 
1046
        case scratch_record:    /* cache macro records */
1047
        case cache_record:
1048
        case compute_record:
1049
          {
1050
            cache_entry *new_cache;
1051
            /* parse the cache record */
1052
            if (record->nr_fields < nr_cache_fields)
1053
              error (record->line,
1054
                     "Incorrect nr of fields for scratch/cache/compute record\n");
1055
            /* create it */
1056
            new_cache = ZALLOC (cache_entry);
1057
            new_cache->line = record->line;
1058
            filter_parse (&new_cache->flags,
1059
                          record->field[record_filter_flags_field]);
1060
            filter_parse (&new_cache->models,
1061
                          record->field[record_filter_models_field]);
1062
            new_cache->type = record->field[cache_typedef_field];
1063
            new_cache->name = record->field[cache_name_field];
1064
            filter_parse (&new_cache->original_fields,
1065
                          record->field[cache_original_fields_field]);
1066
            new_cache->expression = record->field[cache_expression_field];
1067
            /* insert it but only if not filtered out */
1068
            if (!filter_is_subset (options.flags_filter, new_cache->flags))
1069
              {
1070
                notify (new_cache->line,
1071
                        "Discarding cache entry %s - filter flags\n",
1072
                        new_cache->name);
1073
              }
1074
            else if (is_filtered_out (options.model_filter,
1075
                                      record->
1076
                                      field[record_filter_models_field]))
1077
              {
1078
                notify (new_cache->line,
1079
                        "Discarding cache entry %s - filter models\n",
1080
                        new_cache->name);
1081
              }
1082
            else
1083
              {
1084
                cache_entry **last;
1085
                last = &isa->caches;
1086
                while (*last != NULL)
1087
                  last = &(*last)->next;
1088
                *last = new_cache;
1089
              }
1090
            /* advance things */
1091
            record = table_read (file);
1092
            break;
1093
          }
1094
 
1095
          /* model records */
1096
        case model_processor_record:
1097
          {
1098
            model_entry *new_model;
1099
            /* parse the model */
1100
            if (record->nr_fields < nr_model_processor_fields)
1101
              error (record->line,
1102
                     "Incorrect nr of fields for model record\n");
1103
            if (isa->insns != NULL)
1104
              error (record->line, "Model appears after first instruction\n");
1105
            new_model = ZALLOC (model_entry);
1106
            filter_parse (&new_model->flags,
1107
                          record->field[record_filter_flags_field]);
1108
            new_model->line = record->line;
1109
            new_model->name = record->field[model_name_field];
1110
            new_model->full_name = record->field[model_full_name_field];
1111
            new_model->unit_data = record->field[model_unit_data_field];
1112
            /* only insert it if not filtered out */
1113
            if (!filter_is_subset (options.flags_filter, new_model->flags))
1114
              {
1115
                notify (new_model->line,
1116
                        "Discarding processor model %s - filter flags\n",
1117
                        new_model->name);
1118
              }
1119
            else if (is_filtered_out (options.model_filter,
1120
                                      record->
1121
                                      field[record_filter_models_field]))
1122
              {
1123
                notify (new_model->line,
1124
                        "Discarding processor model %s - filter models\n",
1125
                        new_model->name);
1126
              }
1127
            else if (filter_is_member (model->processors, new_model->name))
1128
              {
1129
                error (new_model->line, "Duplicate processor model %s\n",
1130
                       new_model->name);
1131
              }
1132
            else
1133
              {
1134
                model_entry **last;
1135
                last = &model->models;
1136
                while (*last != NULL)
1137
                  last = &(*last)->next;
1138
                *last = new_model;
1139
                /* count it */
1140
                model->nr_models++;
1141
                filter_parse (&model->processors, new_model->name);
1142
              }
1143
            /* advance things */
1144
            record = table_read (file);
1145
          }
1146
          break;
1147
 
1148
        case model_macro_record:
1149
          record = parse_model_data_record (isa, file, record,
1150
                                            nr_model_macro_fields,
1151
                                            &model->macros);
1152
          break;
1153
 
1154
        case model_data_record:
1155
          record = parse_model_data_record (isa, file, record,
1156
                                            nr_model_data_fields,
1157
                                            &model->data);
1158
          break;
1159
 
1160
        case model_static_record:
1161
          record = parse_function_record (file, record,
1162
                                          &model->statics,
1163
                                          NULL, 0 /*is internal */ ,
1164
                                          model);
1165
          break;
1166
 
1167
        case model_internal_record:
1168
          record = parse_function_record (file, record,
1169
                                          &model->internals,
1170
                                          NULL, 1 /*is internal */ ,
1171
                                          model);
1172
          break;
1173
 
1174
        case model_function_record:
1175
          record = parse_function_record (file, record,
1176
                                          &model->functions,
1177
                                          NULL, 0 /*is internal */ ,
1178
                                          model);
1179
          break;
1180
 
1181
        case insn_record:       /* instruction records */
1182
          {
1183
            insn_entry *new_insn;
1184
            char *format;
1185
            /* parse the instruction */
1186
            if (record->nr_fields < nr_insn_fields)
1187
              error (record->line,
1188
                     "Incorrect nr of fields for insn record\n");
1189
            new_insn = ZALLOC (insn_entry);
1190
            new_insn->line = record->line;
1191
            filter_parse (&new_insn->flags,
1192
                          record->field[record_filter_flags_field]);
1193
            /* save the format field.  Can't parse it until after the
1194
               filter-out checks.  Could be filtered out because the
1195
               format is invalid */
1196
            format = record->field[insn_word_field];
1197
            new_insn->format_name = record->field[insn_format_name_field];
1198
            if (options.format_name_filter != NULL
1199
                && !filter_is_member (options.format_name_filter,
1200
                                      new_insn->format_name))
1201
              error (new_insn->line,
1202
                     "Unreconized instruction format name `%s'\n",
1203
                     new_insn->format_name);
1204
            filter_parse (&new_insn->options,
1205
                          record->field[insn_options_field]);
1206
            new_insn->name = record->field[insn_name_field];
1207
            record = table_read (file);
1208
            /* Parse any model/assember records */
1209
            new_insn->nr_models = model->nr_models;
1210
            new_insn->model =
1211
              NZALLOC (insn_model_entry *, model->nr_models + 1);
1212
            while (record != NULL)
1213
              {
1214
                if (record_prefix_is (record, '*', nr_insn_model_fields))
1215
                  parse_insn_model_record (file, record, new_insn, model);
1216
                else
1217
                  if (record_prefix_is (record, '"', nr_insn_mnemonic_fields))
1218
                  parse_insn_mnemonic_record (file, record, new_insn);
1219
                else
1220
                  break;
1221
                /* advance */
1222
                record = table_read (file);
1223
              }
1224
            /* Parse the code record */
1225
            if (record != NULL && record->type == table_code_entry)
1226
              {
1227
                new_insn->code = record;
1228
                record = table_read (file);
1229
              }
1230
            else if (options.warn.unimplemented)
1231
              notify (new_insn->line, "unimplemented\n");
1232
            /* insert it */
1233
            if (!filter_is_subset (options.flags_filter, new_insn->flags))
1234
              {
1235
                if (options.warn.discard)
1236
                  notify (new_insn->line,
1237
                          "Discarding instruction %s (flags-filter)\n",
1238
                          new_insn->name);
1239
              }
1240
            else if (new_insn->processors != NULL
1241
                     && options.model_filter != NULL
1242
                     && !filter_is_common (options.model_filter,
1243
                                           new_insn->processors))
1244
              {
1245
                /* only discard an instruction based in the processor
1246
                   model when both the instruction and the options are
1247
                   nonempty */
1248
                if (options.warn.discard)
1249
                  notify (new_insn->line,
1250
                          "Discarding instruction %s (processor-model)\n",
1251
                          new_insn->name);
1252
              }
1253
            else
1254
              {
1255
                insn_entry **last;
1256
                /* finish the parsing */
1257
                parse_insn_words (new_insn, format);
1258
                /* append it */
1259
                last = &isa->insns;
1260
                while (*last)
1261
                  last = &(*last)->next;
1262
                *last = new_insn;
1263
                /* update global isa counters */
1264
                isa->nr_insns++;
1265
                if (isa->max_nr_words < new_insn->nr_words)
1266
                  isa->max_nr_words = new_insn->nr_words;
1267
                filter_add (&isa->flags, new_insn->flags);
1268
                filter_add (&isa->options, new_insn->options);
1269
              }
1270
            break;
1271
          }
1272
 
1273
        case define_record:
1274
          record = parse_macro_record (file, record);
1275
          break;
1276
 
1277
        case unknown_record:
1278
        case code_record:
1279
          error (record->line, "Unknown or unexpected entry\n");
1280
 
1281
 
1282
        }
1283
    }
1284
  return isa;
1285
}
1286
 
1287
 
1288
void
1289
print_insn_words (lf *file, insn_entry * insn)
1290
{
1291
  insn_word_entry *word = insn->words;
1292
  if (word != NULL)
1293
    {
1294
      while (1)
1295
        {
1296
          insn_field_entry *field = word->first;
1297
          while (1)
1298
            {
1299
              if (options.insn_specifying_widths)
1300
                lf_printf (file, "%d.", field->width);
1301
              else
1302
                lf_printf (file, "%d.",
1303
                           i2target (options.hi_bit_nr, field->first));
1304
              switch (field->type)
1305
                {
1306
                case insn_field_invalid:
1307
                  ASSERT (0);
1308
                  break;
1309
                case insn_field_int:
1310
                  lf_printf (file, "0x%lx", (long) field->val_int);
1311
                  break;
1312
                case insn_field_reserved:
1313
                  lf_printf (file, "/");
1314
                  break;
1315
                case insn_field_wild:
1316
                  lf_printf (file, "*");
1317
                  break;
1318
                case insn_field_string:
1319
                  lf_printf (file, "%s", field->val_string);
1320
                  break;
1321
                }
1322
              if (field == word->last)
1323
                break;
1324
              field = field->next;
1325
              lf_printf (file, ",");
1326
            }
1327
          word = word->next;
1328
          if (word == NULL)
1329
            break;
1330
          lf_printf (file, "+");
1331
        }
1332
    }
1333
}
1334
 
1335
 
1336
 
1337
void
1338
function_entry_traverse (lf *file,
1339
                         function_entry * functions,
1340
                         function_entry_handler * handler, void *data)
1341
{
1342
  function_entry *function;
1343
  for (function = functions; function != NULL; function = function->next)
1344
    {
1345
      handler (file, function, data);
1346
    }
1347
}
1348
 
1349
void
1350
insn_table_traverse_insn (lf *file,
1351
                          insn_table *isa,
1352
                          insn_entry_handler * handler, void *data)
1353
{
1354
  insn_entry *insn;
1355
  for (insn = isa->insns; insn != NULL; insn = insn->next)
1356
    {
1357
      handler (file, isa, insn, data);
1358
    }
1359
}
1360
 
1361
 
1362
static void
1363
dump_function_entry (lf *file,
1364
                     char *prefix, function_entry * entry, char *suffix)
1365
{
1366
  lf_printf (file, "%s(function_entry *) 0x%lx", prefix, (long) entry);
1367
  if (entry != NULL)
1368
    {
1369
      dump_line_ref (file, "\n(line ", entry->line, ")");
1370
      dump_filter (file, "\n(flags ", entry->flags, ")");
1371
      lf_printf (file, "\n(type \"%s\")", entry->type);
1372
      lf_printf (file, "\n(name \"%s\")", entry->name);
1373
      lf_printf (file, "\n(param \"%s\")", entry->param);
1374
      dump_table_entry (file, "\n(code ", entry->code, ")");
1375
      lf_printf (file, "\n(is_internal %d)", entry->is_internal);
1376
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1377
    }
1378
  lf_printf (file, "%s", suffix);
1379
}
1380
 
1381
static void
1382
dump_function_entries (lf *file,
1383
                       char *prefix, function_entry * entry, char *suffix)
1384
{
1385
  lf_printf (file, "%s", prefix);
1386
  lf_indent (file, +1);
1387
  while (entry != NULL)
1388
    {
1389
      dump_function_entry (file, "\n(", entry, ")");
1390
      entry = entry->next;
1391
    }
1392
  lf_indent (file, -1);
1393
  lf_printf (file, "%s", suffix);
1394
}
1395
 
1396
static char *
1397
cache_entry_type_to_str (cache_entry_type type)
1398
{
1399
  switch (type)
1400
    {
1401
    case scratch_value:
1402
      return "scratch";
1403
    case cache_value:
1404
      return "cache";
1405
    case compute_value:
1406
      return "compute";
1407
    }
1408
  ERROR ("Bad switch");
1409
  return 0;
1410
}
1411
 
1412
static void
1413
dump_cache_entry (lf *file, char *prefix, cache_entry *entry, char *suffix)
1414
{
1415
  lf_printf (file, "%s(cache_entry *) 0x%lx", prefix, (long) entry);
1416
  if (entry != NULL)
1417
    {
1418
      dump_line_ref (file, "\n(line ", entry->line, ")");
1419
      dump_filter (file, "\n(flags ", entry->flags, ")");
1420
      lf_printf (file, "\n(entry_type \"%s\")",
1421
                 cache_entry_type_to_str (entry->entry_type));
1422
      lf_printf (file, "\n(name \"%s\")", entry->name);
1423
      dump_filter (file, "\n(original_fields ", entry->original_fields, ")");
1424
      lf_printf (file, "\n(type \"%s\")", entry->type);
1425
      lf_printf (file, "\n(expression \"%s\")", entry->expression);
1426
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1427
    }
1428
  lf_printf (file, "%s", suffix);
1429
}
1430
 
1431
void
1432
dump_cache_entries (lf *file, char *prefix, cache_entry *entry, char *suffix)
1433
{
1434
  lf_printf (file, "%s", prefix);
1435
  lf_indent (file, +1);
1436
  while (entry != NULL)
1437
    {
1438
      dump_cache_entry (file, "\n(", entry, ")");
1439
      entry = entry->next;
1440
    }
1441
  lf_indent (file, -1);
1442
  lf_printf (file, "%s", suffix);
1443
}
1444
 
1445
static void
1446
dump_model_data (lf *file, char *prefix, model_data *entry, char *suffix)
1447
{
1448
  lf_printf (file, "%s(model_data *) 0x%lx", prefix, (long) entry);
1449
  if (entry != NULL)
1450
    {
1451
      lf_indent (file, +1);
1452
      dump_line_ref (file, "\n(line ", entry->line, ")");
1453
      dump_filter (file, "\n(flags ", entry->flags, ")");
1454
      dump_table_entry (file, "\n(entry ", entry->entry, ")");
1455
      dump_table_entry (file, "\n(code ", entry->code, ")");
1456
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1457
      lf_indent (file, -1);
1458
    }
1459
  lf_printf (file, "%s", prefix);
1460
}
1461
 
1462
static void
1463
dump_model_datas (lf *file, char *prefix, model_data *entry, char *suffix)
1464
{
1465
  lf_printf (file, "%s", prefix);
1466
  lf_indent (file, +1);
1467
  while (entry != NULL)
1468
    {
1469
      dump_model_data (file, "\n(", entry, ")");
1470
      entry = entry->next;
1471
    }
1472
  lf_indent (file, -1);
1473
  lf_printf (file, "%s", suffix);
1474
}
1475
 
1476
static void
1477
dump_model_entry (lf *file, char *prefix, model_entry *entry, char *suffix)
1478
{
1479
  lf_printf (file, "%s(model_entry *) 0x%lx", prefix, (long) entry);
1480
  if (entry != NULL)
1481
    {
1482
      lf_indent (file, +1);
1483
      dump_line_ref (file, "\n(line ", entry->line, ")");
1484
      dump_filter (file, "\n(flags ", entry->flags, ")");
1485
      lf_printf (file, "\n(name \"%s\")", entry->name);
1486
      lf_printf (file, "\n(full_name \"%s\")", entry->full_name);
1487
      lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data);
1488
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1489
      lf_indent (file, -1);
1490
    }
1491
  lf_printf (file, "%s", prefix);
1492
}
1493
 
1494
static void
1495
dump_model_entries (lf *file, char *prefix, model_entry *entry, char *suffix)
1496
{
1497
  lf_printf (file, "%s", prefix);
1498
  lf_indent (file, +1);
1499
  while (entry != NULL)
1500
    {
1501
      dump_model_entry (file, "\n(", entry, ")");
1502
      entry = entry->next;
1503
    }
1504
  lf_indent (file, -1);
1505
  lf_printf (file, "%s", suffix);
1506
}
1507
 
1508
 
1509
static void
1510
dump_model_table (lf *file, char *prefix, model_table *entry, char *suffix)
1511
{
1512
  lf_printf (file, "%s(model_table *) 0x%lx", prefix, (long) entry);
1513
  if (entry != NULL)
1514
    {
1515
      lf_indent (file, +1);
1516
      dump_filter (file, "\n(processors ", entry->processors, ")");
1517
      lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1518
      dump_model_entries (file, "\n(models ", entry->models, ")");
1519
      dump_model_datas (file, "\n(macros ", entry->macros, ")");
1520
      dump_model_datas (file, "\n(data ", entry->data, ")");
1521
      dump_function_entries (file, "\n(statics ", entry->statics, ")");
1522
      dump_function_entries (file, "\n(internals ", entry->functions, ")");
1523
      dump_function_entries (file, "\n(functions ", entry->functions, ")");
1524
      lf_indent (file, -1);
1525
    }
1526
  lf_printf (file, "%s", suffix);
1527
}
1528
 
1529
 
1530
static char *
1531
insn_field_type_to_str (insn_field_type type)
1532
{
1533
  switch (type)
1534
    {
1535
    case insn_field_invalid:
1536
      ASSERT (0);
1537
      return "(invalid)";
1538
    case insn_field_int:
1539
      return "int";
1540
    case insn_field_reserved:
1541
      return "reserved";
1542
    case insn_field_wild:
1543
      return "wild";
1544
    case insn_field_string:
1545
      return "string";
1546
    }
1547
  ERROR ("bad switch");
1548
  return 0;
1549
}
1550
 
1551
void
1552
dump_insn_field (lf *file,
1553
                 char *prefix, insn_field_entry *field, char *suffix)
1554
{
1555
  char *sep = " ";
1556
  lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field);
1557
  if (field != NULL)
1558
    {
1559
      lf_indent (file, +1);
1560
      lf_printf (file, "%s(first %d)", sep, field->first);
1561
      lf_printf (file, "%s(last %d)", sep, field->last);
1562
      lf_printf (file, "%s(width %d)", sep, field->width);
1563
      lf_printf (file, "%s(type %s)", sep,
1564
                 insn_field_type_to_str (field->type));
1565
      switch (field->type)
1566
        {
1567
        case insn_field_invalid:
1568
          ASSERT (0);
1569
          break;
1570
        case insn_field_int:
1571
          lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int);
1572
          break;
1573
        case insn_field_reserved:
1574
          /* nothing output */
1575
          break;
1576
        case insn_field_wild:
1577
          /* nothing output */
1578
          break;
1579
        case insn_field_string:
1580
          lf_printf (file, "%s(val \"%s\")", sep, field->val_string);
1581
          break;
1582
        }
1583
      lf_printf (file, "%s(next 0x%lx)", sep, (long) field->next);
1584
      lf_printf (file, "%s(prev 0x%lx)", sep, (long) field->prev);
1585
      lf_indent (file, -1);
1586
    }
1587
  lf_printf (file, "%s", suffix);
1588
}
1589
 
1590
void
1591
dump_insn_word_entry (lf *file,
1592
                      char *prefix, insn_word_entry *word, char *suffix)
1593
{
1594
  lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word);
1595
  if (word != NULL)
1596
    {
1597
      int i;
1598
      insn_field_entry *field;
1599
      lf_indent (file, +1);
1600
      lf_printf (file, "\n(first 0x%lx)", (long) word->first);
1601
      lf_printf (file, "\n(last 0x%lx)", (long) word->last);
1602
      lf_printf (file, "\n(bit");
1603
      for (i = 0; i < options.insn_bit_size; i++)
1604
        lf_printf (file, "\n ((value %d) (mask %d) (field 0x%lx))",
1605
                   word->bit[i]->value, word->bit[i]->mask,
1606
                   (long) word->bit[i]->field);
1607
      lf_printf (file, ")");
1608
      for (field = word->first; field != NULL; field = field->next)
1609
        dump_insn_field (file, "\n(", field, ")");
1610
      dump_filter (file, "\n(field_names ", word->field_names, ")");
1611
      lf_printf (file, "\n(next 0x%lx)", (long) word->next);
1612
      lf_indent (file, -1);
1613
    }
1614
  lf_printf (file, "%s", suffix);
1615
}
1616
 
1617
static void
1618
dump_insn_word_entries (lf *file,
1619
                        char *prefix, insn_word_entry *word, char *suffix)
1620
{
1621
  lf_printf (file, "%s", prefix);
1622
  while (word != NULL)
1623
    {
1624
      dump_insn_word_entry (file, "\n(", word, ")");
1625
      word = word->next;
1626
    }
1627
  lf_printf (file, "%s", suffix);
1628
}
1629
 
1630
static void
1631
dump_insn_model_entry (lf *file,
1632
                       char *prefix, insn_model_entry *model, char *suffix)
1633
{
1634
  lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model);
1635
  if (model != NULL)
1636
    {
1637
      lf_indent (file, +1);
1638
      dump_line_ref (file, "\n(line ", model->line, ")");
1639
      dump_filter (file, "\n(names ", model->names, ")");
1640
      lf_printf (file, "\n(full_name \"%s\")", model->full_name);
1641
      lf_printf (file, "\n(unit_data \"%s\")", model->unit_data);
1642
      lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", (long) model->insn);
1643
      lf_printf (file, "\n(next (insn_model_entry *) 0x%lx)",
1644
                 (long) model->next);
1645
      lf_indent (file, -1);
1646
    }
1647
  lf_printf (file, "%s", suffix);
1648
}
1649
 
1650
static void
1651
dump_insn_model_entries (lf *file,
1652
                         char *prefix, insn_model_entry *model, char *suffix)
1653
{
1654
  lf_printf (file, "%s", prefix);
1655
  while (model != NULL)
1656
    {
1657
      dump_insn_model_entry (file, "\n", model, "");
1658
      model = model->next;
1659
    }
1660
  lf_printf (file, "%s", suffix);
1661
}
1662
 
1663
 
1664
static void
1665
dump_insn_mnemonic_entry (lf *file,
1666
                          char *prefix,
1667
                          insn_mnemonic_entry *mnemonic, char *suffix)
1668
{
1669
  lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix,
1670
             (long) mnemonic);
1671
  if (mnemonic != NULL)
1672
    {
1673
      lf_indent (file, +1);
1674
      dump_line_ref (file, "\n(line ", mnemonic->line, ")");
1675
      lf_printf (file, "\n(format \"%s\")", mnemonic->format);
1676
      lf_printf (file, "\n(condition \"%s\")", mnemonic->condition);
1677
      lf_printf (file, "\n(insn (insn_entry *) 0x%lx)",
1678
                 (long) mnemonic->insn);
1679
      lf_printf (file, "\n(next (insn_mnemonic_entry *) 0x%lx)",
1680
                 (long) mnemonic->next);
1681
      lf_indent (file, -1);
1682
    }
1683
  lf_printf (file, "%s", suffix);
1684
}
1685
 
1686
static void
1687
dump_insn_mnemonic_entries (lf *file,
1688
                            char *prefix,
1689
                            insn_mnemonic_entry *mnemonic, char *suffix)
1690
{
1691
  lf_printf (file, "%s", prefix);
1692
  while (mnemonic != NULL)
1693
    {
1694
      dump_insn_mnemonic_entry (file, "\n", mnemonic, "");
1695
      mnemonic = mnemonic->next;
1696
    }
1697
  lf_printf (file, "%s", suffix);
1698
}
1699
 
1700
void
1701
dump_insn_entry (lf *file, char *prefix, insn_entry * entry, char *suffix)
1702
{
1703
  lf_printf (file, "%s(insn_entry *) 0x%lx", prefix, (long) entry);
1704
  if (entry != NULL)
1705
    {
1706
      int i;
1707
      lf_indent (file, +1);
1708
      dump_line_ref (file, "\n(line ", entry->line, ")");
1709
      dump_filter (file, "\n(flags ", entry->flags, ")");
1710
      lf_printf (file, "\n(nr_words %d)", entry->nr_words);
1711
      dump_insn_word_entries (file, "\n(words ", entry->words, ")");
1712
      lf_printf (file, "\n(word");
1713
      for (i = 0; i < entry->nr_models; i++)
1714
        lf_printf (file, " 0x%lx", (long) entry->word[i]);
1715
      lf_printf (file, ")");
1716
      dump_filter (file, "\n(field_names ", entry->field_names, ")");
1717
      lf_printf (file, "\n(format_name \"%s\")", entry->format_name);
1718
      dump_filter (file, "\n(options ", entry->options, ")");
1719
      lf_printf (file, "\n(name \"%s\")", entry->name);
1720
      lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1721
      dump_insn_model_entries (file, "\n(models ", entry->models, ")");
1722
      lf_printf (file, "\n(model");
1723
      for (i = 0; i < entry->nr_models; i++)
1724
        lf_printf (file, " 0x%lx", (long) entry->model[i]);
1725
      lf_printf (file, ")");
1726
      dump_filter (file, "\n(processors ", entry->processors, ")");
1727
      dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics,
1728
                                  ")");
1729
      dump_table_entry (file, "\n(code ", entry->code, ")");
1730
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1731
      lf_indent (file, -1);
1732
    }
1733
  lf_printf (file, "%s", suffix);
1734
}
1735
 
1736
static void
1737
dump_insn_entries (lf *file, char *prefix, insn_entry * entry, char *suffix)
1738
{
1739
  lf_printf (file, "%s", prefix);
1740
  lf_indent (file, +1);
1741
  while (entry != NULL)
1742
    {
1743
      dump_insn_entry (file, "\n(", entry, ")");
1744
      entry = entry->next;
1745
    }
1746
  lf_indent (file, -1);
1747
  lf_printf (file, "%s", suffix);
1748
}
1749
 
1750
 
1751
 
1752
void
1753
dump_insn_table (lf *file, char *prefix, insn_table *isa, char *suffix)
1754
{
1755
  lf_printf (file, "%s(insn_table *) 0x%lx", prefix, (long) isa);
1756
  if (isa != NULL)
1757
    {
1758
      lf_indent (file, +1);
1759
      dump_cache_entries (file, "\n(caches ", isa->caches, ")");
1760
      lf_printf (file, "\n(nr_insns %d)", isa->nr_insns);
1761
      lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words);
1762
      dump_insn_entries (file, "\n(insns ", isa->insns, ")");
1763
      dump_function_entries (file, "\n(functions ", isa->functions, ")");
1764
      dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")");
1765
      dump_model_table (file, "\n(model ", isa->model, ")");
1766
      dump_filter (file, "\n(flags ", isa->flags, ")");
1767
      dump_filter (file, "\n(options ", isa->options, ")");
1768
      lf_indent (file, -1);
1769
    }
1770
  lf_printf (file, "%s", suffix);
1771
}
1772
 
1773
#ifdef MAIN
1774
 
1775
igen_options options;
1776
 
1777
int
1778
main (int argc, char **argv)
1779
{
1780
  insn_table *isa;
1781
  lf *l;
1782
 
1783
  INIT_OPTIONS (options);
1784
 
1785
  if (argc == 3)
1786
    filter_parse (&options.flags_filter, argv[2]);
1787
  else if (argc != 2)
1788
    error (NULL, "Usage: insn <insn-table> [ <filter-in> ]\n");
1789
 
1790
  isa = load_insn_table (argv[1], NULL);
1791
  l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1792
  dump_insn_table (l, "(isa ", isa, ")\n");
1793
 
1794
  return 0;
1795
}
1796
 
1797
#endif

powered by: WebSVN 2.1.0

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