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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [sim/] [igen/] [ld-insn.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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