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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [sim/] [igen/] [ld-insn.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
19
    */
20
 
21
 
22
#include "misc.h"
23
#include "lf.h"
24
#include "table.h"
25
#include "filter.h"
26
#include "igen.h"
27
#include "ld-insn.h"
28
 
29
static insn_word_entry *
30
parse_insn_word (line_ref *line,
31
                 char *string,
32
                 int word_nr)
33
{
34
  char *chp;
35
  insn_word_entry *word = ZALLOC (insn_word_entry);
36
 
37
  /* create a leading sentinal */
38
  word->first = ZALLOC (insn_field_entry);
39
  word->first->first = -1;
40
  word->first->last = -1;
41
  word->first->width = 0;
42
 
43
  /* and a trailing sentinal */
44
  word->last = ZALLOC (insn_field_entry);
45
  word->last->first = options.insn_bit_size;
46
  word->last->last = options.insn_bit_size;
47
  word->last->width = 0;
48
 
49
  /* link them together */
50
  word->first->next = word->last;
51
  word->last->prev = word->first;
52
 
53
  /* now work through the formats */
54
  chp = skip_spaces (string);
55
 
56
  while (*chp != '\0') {
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
              chp++;
112
            }
113
            while (isalnum(*chp));
114
          }
115
        strlen_val = chp - start_val;
116
        chp = skip_spaces (chp);
117
      }
118
    if (strlen_val == 0)
119
      error (line, "Empty value field\n");
120
 
121
    /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */
122
    while (*chp == '!' || *chp == '=')
123
      {
124
        char *start;
125
        char *end;
126
        int len;
127
        insn_field_cond *new_cond = ZALLOC (insn_field_cond);
128
 
129
        /* determine the conditional test */
130
        switch (*chp)
131
          {
132
          case '=':
133
            new_cond->test = insn_field_cond_eq;
134
            break;
135
          case '!':
136
            new_cond->test = insn_field_cond_ne;
137
            break;
138
          default:
139
            ASSERT (0);
140
          }
141
 
142
        /* save the value */
143
        chp++;
144
        chp = skip_spaces (chp);
145
        start = chp;
146
        chp = skip_to_separator (chp, "+,:!=");
147
        end = back_spaces (start, chp);
148
        len = end - start;
149
        if (len == 0)
150
          error (line, "Missing or invalid conditional value\n");
151
        new_cond->string = NZALLOC (char, len + 1);
152
        strncpy (new_cond->string, start, len);
153
 
154
        /* determine the conditional type */
155
        if (isdigit (*start))
156
          {
157
            /* [ "!" | "=" ] <value> */
158
            new_cond->type = insn_field_cond_value;
159
            new_cond->value = a2i (new_cond->string);
160
          }
161
        else
162
          {
163
            /* [ "!" | "=" ] <field>  - check field valid */
164
            new_cond->type = insn_field_cond_field;
165
            /* new_cond->field is determined in later */
166
          }
167
 
168
        /* Only a single `=' is permitted. */
169
        if ((new_cond->test == insn_field_cond_eq
170
             && new_field->conditions != NULL)
171
            || (new_field->conditions != NULL
172
                && new_field->conditions->test == insn_field_cond_eq))
173
          error (line, "Only single conditional when `=' allowed\n");
174
 
175
        /* insert it */
176
        {
177
          insn_field_cond **last = &new_field->conditions;
178
          while (*last != NULL)
179
            last = &(*last)->next;
180
          *last = new_cond;
181
        }
182
      }
183
 
184
    /* NOW verify that the field was finished */
185
    if (*chp == ',')
186
      {
187
        chp = skip_spaces (chp + 1);
188
        if (*chp == '\0')
189
          error (line, "empty field\n");
190
      }
191
    else if (*chp != '\0')
192
      {
193
        error (line, "Missing field separator\n");
194
      }
195
 
196
    /* copy the value */
197
    new_field->val_string = NZALLOC (char, strlen_val+1);
198
    strncpy (new_field->val_string, start_val, strlen_val);
199
    if (isdigit (new_field->val_string[0]))
200
      {
201
        if (strlen_pos == 0)
202
          {
203
            /* when the length/pos field is omited, an integer field
204
               is always binary */
205
            unsigned64 val = 0;
206
            int i;
207
            for (i = 0; i < strlen_val; i++)
208
              {
209
                if (new_field->val_string[i] != '0'
210
                    && new_field->val_string[i] != '1')
211
                  error (line, "invalid binary field %s\n",
212
                         new_field->val_string);
213
                val = (val << 1) + (new_field->val_string[i] == '1');
214
              }
215
            new_field->val_int = val;
216
            new_field->type = insn_field_int;
217
          }
218
        else
219
          {
220
            new_field->val_int = a2i (new_field->val_string);
221
            new_field->type = insn_field_int;
222
          }
223
      }
224
    else if (new_field->val_string[0] == '/')
225
      {
226
        new_field->type = insn_field_reserved;
227
      }
228
    else if (new_field->val_string[0] == '*')
229
      {
230
        new_field->type = insn_field_wild;
231
      }
232
    else
233
      {
234
        new_field->type = insn_field_string;
235
        if (filter_is_member (word->field_names, new_field->val_string))
236
          error (line, "Field name %s is duplicated\n", new_field->val_string);
237
        filter_parse (&word->field_names, new_field->val_string);
238
      }
239
    if (new_field->type != insn_field_string
240
        && new_field->conditions != NULL)
241
      error (line, "Conditionals can only be applied to named fields\n");
242
 
243
    /* the copy the position */
244
    new_field->pos_string = NZALLOC (char, strlen_pos + 1);
245
    strncpy (new_field->pos_string, start_pos, strlen_pos);
246
    if (strlen_pos == 0)
247
      {
248
        new_field->first = new_field->prev->last + 1;
249
        if (new_field->first == 0 /* first field */
250
            && *chp == '\0' /* no further fields */
251
            && new_field->type == insn_field_string)
252
          {
253
            /* A single string without any position, assume that it
254
               represents the entire instruction word */
255
            new_field->width = options.insn_bit_size;
256
          }
257
        else
258
          {
259
            /* No explicit width/position, assume value implicitly
260
               supplies the width */
261
            new_field->width = strlen_val;
262
          }
263
        new_field->last = new_field->first + new_field->width - 1;
264
        if (new_field->last >= options.insn_bit_size)
265
          error (line, "Bit position %d exceed instruction bit size (%d)\n",
266
                 new_field->last, options.insn_bit_size);
267
      }
268
    else if (options.insn_specifying_widths)
269
      {
270
        new_field->first = new_field->prev->last + 1;
271
        new_field->width = a2i(new_field->pos_string);
272
        new_field->last = new_field->first + new_field->width - 1;
273
        if (new_field->last >= options.insn_bit_size)
274
          error (line, "Bit position %d exceed instruction bit size (%d)\n",
275
                 new_field->last, options.insn_bit_size);
276
      }
277
    else
278
      {
279
        new_field->first = target_a2i(options.hi_bit_nr,
280
                                      new_field->pos_string);
281
        new_field->last = new_field->next->first - 1; /* guess */
282
        new_field->width = new_field->last - new_field->first + 1; /* guess */
283
        new_field->prev->last = new_field->first - 1; /*fix*/
284
        new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
285
      }
286
  }
287
 
288
  /* fiddle first/last so that the sentinals disapear */
289
  ASSERT(word->first->last < 0);
290
  ASSERT(word->last->first >= options.insn_bit_size);
291
  word->first = word->first->next;
292
  word->last = word->last->prev;
293
 
294
  /* check that the last field goes all the way to the last bit */
295
  if (word->last->last != options.insn_bit_size - 1)
296
    {
297
      if (options.warn.width)
298
        options.warning (line, "Instruction format is not %d bits wide\n",
299
                         options.insn_bit_size);
300
      word->last->last = options.insn_bit_size - 1;
301
    }
302
 
303
  /* now go over this again, pointing each bit position at a field
304
     record */
305
  {
306
    insn_field_entry *field;
307
    for (field = word->first;
308
         field->last < options.insn_bit_size;
309
         field = field->next)
310
      {
311
        int i;
312
        for (i = field->first; i <= field->last; i++)
313
          {
314
            word->bit[i] = ZALLOC (insn_bit_entry);
315
            word->bit[i]->field = field;
316
            switch (field->type)
317
              {
318
              case insn_field_invalid:
319
                ASSERT (0);
320
                break;
321
              case insn_field_int:
322
                word->bit[i]->mask = 1;
323
                word->bit[i]->value = ((field->val_int
324
                                        & ((insn_uint)1 << (field->last - i)))
325
                                       != 0);
326
              case insn_field_reserved:
327
              case insn_field_wild:
328
              case insn_field_string:
329
                /* if we encounter a constant conditional, encode
330
                   their bit value. */
331
                if (field->conditions != NULL
332
                    && field->conditions->test == insn_field_cond_eq
333
                    && field->conditions->type == insn_field_cond_value)
334
                  {
335
                    word->bit[i]->mask = 1;
336
                    word->bit[i]->value = ((field->conditions->value
337
                                            & ((insn_uint)1 << (field->last - i)))
338
                                           != 0);
339
                  }
340
                break;
341
              }
342
          }
343
      }
344
  }
345
 
346
  return word;
347
}
348
 
349
 
350
static void
351
parse_insn_words (insn_entry *insn,
352
                  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;
409
         i++, word = word->next)
410
      insn->word[i] = word;
411
  }
412
 
413
  /* Go over all fields that have conditionals refering to other
414
     fields.  Link the fields up.  Verify that the two fields have the
415
     same size. Verify that the two fields are different */
416
  {
417
    int i;
418
    for (i = 0; i < insn->nr_words; i++)
419
      {
420
        insn_word_entry *word = insn->word[i];
421
        insn_field_entry *f;
422
        for (f = word->first;
423
             f->last < options.insn_bit_size;
424
             f = f->next)
425
          {
426
            insn_field_cond *cond;
427
            for (cond = f->conditions;
428
                 cond != NULL;
429
                 cond = cond->next)
430
              {
431
                if (cond->type == insn_field_cond_field)
432
                  {
433
                    int j;
434
                    if (strcmp (cond->string, f->val_string) == 0)
435
                      error (insn->line,
436
                             "Conditional `%s' of field `%s' refers to its self\n",
437
                             cond->string, f->val_string);
438
                    for (j = 0; j <= i && cond->field == NULL; j++)
439
                      {
440
                        insn_word_entry *refered_word = insn->word[j];
441
                        insn_field_entry *refered_field;
442
                        for (refered_field = refered_word->first;
443
                             refered_field != NULL && cond->field == NULL;
444
                             refered_field = refered_field->next)
445
                          {
446
                            if (refered_field->type == insn_field_string
447
                                && strcmp (refered_field->val_string, cond->string) == 0)
448
                              {
449
                                /* found field being refered to by conditonal */
450
                                cond->field = refered_field;
451
                                /* check refered to and this field are
452
                                   the same size */
453
                                if (f->width != refered_field->width)
454
                                  error (insn->line,
455
                                         "Conditional `%s' of field `%s' should be of size %s\n",
456
                                         cond->string, f->val_string, refered_field->width);
457
                              }
458
                          }
459
                      }
460
                    if (cond->field == NULL)
461
                      error (insn->line,
462
                             "Conditional `%s' of field `%s' not yet defined\n",
463
                             cond->string, f->val_string);
464
                  }
465
              }
466
          }
467
      }
468
  }
469
 
470
}
471
 
472
typedef enum {
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
} insn_record_type;
492
 
493
static const name_map insn_type_map[] = {
494
  { "option", option_record },
495
  { "cache", cache_record },
496
  { "compute", compute_record },
497
  { "scratch", scratch_record },
498
  { "define", define_record },
499
  { "include", include_record },
500
  { "%s", string_function_record },
501
  { "function", function_record },
502
  { "internal", internal_record },
503
  { "model", model_processor_record },
504
  { "model-macro", model_macro_record },
505
  { "model-data", model_data_record },
506
  { "model-static", model_static_record },
507
  { "model-internal", model_internal_record },
508
  { "model-function", model_function_record },
509
  { NULL, insn_record },
510
};
511
 
512
 
513
static int
514
record_is_old (table_entry *entry)
515
{
516
  if (entry->nr_fields > record_type_field
517
      && strlen (entry->field[record_type_field]) == 0)
518
    return 1;
519
  return 0;
520
}
521
 
522
static insn_record_type
523
record_type (table_entry *entry)
524
{
525
  switch (entry->type)
526
    {
527
    case table_code_entry:
528
      return code_record;
529
 
530
    case table_colon_entry:
531
      if (record_is_old (entry))
532
        {
533
          /* old-format? */
534
          if (entry->nr_fields > old_record_type_field)
535
            {
536
              int i = name2i (entry->field[old_record_type_field],
537
                              insn_type_map);
538
              return i;
539
            }
540
          else
541
            {
542
              return unknown_record;
543
            }
544
        }
545
      else if (entry->nr_fields > record_type_field
546
               && entry->field[0][0] == '\0')
547
        {
548
          /* new-format? */
549
          int i = name2i (entry->field[record_type_field],
550
                          insn_type_map);
551
          return i;
552
        }
553
      else
554
        return insn_record; /* default */
555
    }
556
  return unknown_record;
557
}
558
 
559
static int
560
record_prefix_is (table_entry *entry,
561
                  char ch,
562
                  int nr_fields)
563
{
564
  if (entry->type != table_colon_entry)
565
    return 0;
566
  if (entry->nr_fields < nr_fields)
567
    return 0;
568
  if (entry->field[0][0] != ch && ch != '\0')
569
    return 0;
570
  return 1;
571
}
572
 
573
static table_entry *
574
parse_model_data_record (insn_table *isa,
575
                         table *file,
576
                         table_entry *record,
577
                         int nr_fields,
578
                         model_data **list)
579
{
580
  table_entry *model_record = record;
581
  table_entry *code_record = NULL;
582
  model_data *new_data;
583
  if (record->nr_fields < nr_fields)
584
    error (record->line, "Incorrect number of fields\n");
585
  record = table_read (file);
586
  if (record->type == table_code_entry)
587
    {
588
      code_record = record;
589
      record = table_read (file);
590
    }
591
  /* create the new data record */
592
  new_data = ZALLOC (model_data);
593
  new_data->line = model_record->line;
594
  filter_parse (&new_data->flags,
595
                model_record->field[record_filter_flags_field]);
596
  new_data->entry = model_record;
597
  new_data->code = code_record;
598
  /* append it if not filtered out */
599
  if (!is_filtered_out (options.flags_filter,
600
                        model_record->field[record_filter_flags_field])
601
      && !is_filtered_out (options.model_filter,
602
                           model_record->field[record_filter_models_field]))
603
    {
604
      while (*list != NULL)
605
        list = &(*list)->next;
606
      *list = new_data;
607
    }
608
  return record;
609
}
610
 
611
 
612
typedef enum {
613
  insn_bit_size_option = 1,
614
  insn_specifying_widths_option,
615
  hi_bit_nr_option,
616
  flags_filter_option,
617
  model_filter_option,
618
  multi_sim_option,
619
  format_names_option,
620
  gen_delayed_branch,
621
  unknown_option,
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,
638
                      table_entry *record)
639
{
640
  /* parse the include record */
641
  if (record->nr_fields < nr_include_fields)
642
    error (record->line, "Incorrect nr fields for include record\n");
643
  /* process it */
644
  if (!is_filtered_out (options.flags_filter,
645
                        record->field[record_filter_flags_field])
646
      && !is_filtered_out (options.model_filter,
647
                           record->field[record_filter_models_field]))
648
    {
649
      table_push (file, record->line, options.include,
650
                  record->field[include_filename_field]);
651
    }
652
  /* nb: can't read next record until after the file has been pushed */
653
  record = table_read (file);
654
  return record;
655
}
656
 
657
 
658
static table_entry *
659
parse_option_record (table *file,
660
                     table_entry *record)
661
{
662
  table_entry *option_record;
663
  /* parse the option record */
664
  option_record = record;
665
  if (record->nr_fields < nr_option_fields)
666
    error (record->line, "Incorrect nr of fields for option record\n");
667
  record = table_read (file);
668
  /* process it */
669
  if (!is_filtered_out (options.flags_filter,
670
                        option_record->field[record_filter_flags_field])
671
      && !is_filtered_out (options.model_filter,
672
                           option_record->field[record_filter_models_field]))
673
    {
674
      char *name = option_record->field[option_name_field];
675
      option_names option = name2i (name, option_map);
676
      char *value = option_record->field[option_value_field];
677
      switch (option)
678
        {
679
        case insn_bit_size_option:
680
          {
681
            options.insn_bit_size = a2i (value);
682
            if (options.insn_bit_size < 0
683
                || options.insn_bit_size > max_insn_bit_size)
684
              error (option_record->line, "Instruction bit size out of range\n");
685
            if (options.hi_bit_nr != options.insn_bit_size - 1
686
                && options.hi_bit_nr != 0)
687
              error (option_record->line, "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, "hi-bit-nr / insn-bit-size conflict\n");
701
            break;
702
          }
703
        case flags_filter_option:
704
          {
705
            filter_parse (&options.flags_filter, value);
706
            break;
707
          }
708
        case model_filter_option:
709
          {
710
            filter_parse (&options.model_filter, value);
711
            break;
712
          }
713
        case multi_sim_option:
714
          {
715
            options.gen.multi_sim = a2i (value);
716
            break;
717
          }
718
        case format_names_option:
719
          {
720
            filter_parse (&options.format_name_filter, value);
721
            break;
722
          }
723
        case gen_delayed_branch:
724
          {
725
            options.gen.delayed_branch = a2i (value);
726
            break;
727
          }
728
        case unknown_option:
729
          {
730
            error (option_record->line, "Unknown option - %s\n", name);
731
            break;
732
          }
733
        }
734
    }
735
  return record;
736
}
737
 
738
 
739
static table_entry *
740
parse_function_record (table *file,
741
                       table_entry *record,
742
                       function_entry **list,
743
                       function_entry **list_entry,
744
                       int is_internal,
745
                       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, "Discarding function %s - filter models\n",
805
                new_function->name);
806
    }
807
  else
808
    {
809
      while (*list != NULL)
810
        list = &(*list)->next;
811
      *list = new_function;
812
      if (list_entry != NULL)
813
        *list_entry = new_function;
814
    }
815
  /* done */
816
  return record;
817
}
818
 
819
static void
820
parse_insn_model_record (table *file,
821
                         table_entry *record,
822
                         insn_entry *insn,
823
                         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) break;
859
          index = filter_is_member (model->processors, name) - 1;
860
          if (index < 0)
861
            {
862
              error (new_insn_model->line,
863
                     "machine model `%s' undefined\n", name);
864
            }
865
          /* store it in the corresponding model array entry */
866
          if (insn->model[index] != NULL
867
              && 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,
897
                            insn_entry *insn)
898
{
899
  insn_mnemonic_entry **last_insn_mnemonic;
900
  insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry);
901
  /* parse it */
902
  new_insn_mnemonic->line = record->line;
903
  ASSERT (record->nr_fields > insn_mnemonic_format_field);
904
  new_insn_mnemonic->format = record->field[insn_mnemonic_format_field];
905
  ASSERT (new_insn_mnemonic->format[0] == '"');
906
  if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] != '"')
907
    error (new_insn_mnemonic->line, "Missing closing double quote in mnemonic field\n");
908
  if (record->nr_fields > insn_mnemonic_condition_field)
909
    new_insn_mnemonic->condition = 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,
922
                    table_entry *record)
923
{
924
#if 1
925
  error (record->line, "Macros are not implemented");
926
#else
927
  /* parse the define record */
928
  if (record->nr_fields < nr_define_fields)
929
    error (record->line, "Incorrect nr fields for define record\n");
930
  /* process it */
931
  if (!is_filtered_out (options.flags_filter,
932
                        record->field[record_filter_flags_field])
933
      && !is_filtered_out (options.model_filter,
934
                           record->field[record_filter_models_field]))
935
    {
936
      table_define (file,
937
                    record->line,
938
                    record->field[macro_name_field],
939
                    record->field[macro_args_field],
940
                    record->field[macro_expr_field]);
941
    }
942
  record = table_read (file);
943
#endif
944
  return record;
945
}
946
 
947
 
948
insn_table *
949
load_insn_table (char *file_name,
950
                 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,
987
                                            0/*is-internal*/,
988
                                            model);
989
            /* convert a string function record into an internal function */
990
            if (function != NULL)
991
              {
992
                char *name = NZALLOC (char,
993
                                      (strlen ("str_")
994
                                       + strlen (function->name)
995
                                       + 1));
996
                strcat (name, "str_");
997
                strcat (name, function->name);
998
                function->name = name;
999
                function->type = "const char *";
1000
              }
1001
            break;
1002
          }
1003
 
1004
        case function_record: /* function record */
1005
          {
1006
            record = parse_function_record (file, record,
1007
                                            &isa->functions,
1008
                                            NULL,
1009
                                            0/*is-internal*/,
1010
                                            model);
1011
            break;
1012
          }
1013
 
1014
        case internal_record:
1015
          {
1016
            /* only insert it into the function list if it is unknown */
1017
            function_entry *function = NULL;
1018
            record = parse_function_record (file, record,
1019
                                            &isa->functions,
1020
                                            &function,
1021
                                            1/*is-internal*/,
1022
                                            model);
1023
            /* check what was inserted to see if a pseudo-instruction
1024
               entry also needs to be created */
1025
            if (function != NULL)
1026
              {
1027
                insn_entry **insn = NULL;
1028
                if (strcmp (function->name, "illegal") == 0)
1029
                  {
1030
                    /* illegal function save it away */
1031
                    if (isa->illegal_insn != NULL)
1032
                      {
1033
                        warning (function->line,
1034
                                 "Multiple illegal instruction definitions\n");
1035
                        error (isa->illegal_insn->line,
1036
                               "Location of first illegal instruction\n");
1037
                      }
1038
                    else
1039
                      insn = &isa->illegal_insn;
1040
                  }
1041
                if (insn != NULL)
1042
                  {
1043
                    *insn = ZALLOC (insn_entry);
1044
                    (*insn)->line = function->line;
1045
                    (*insn)->name = function->name;
1046
                    (*insn)->code = function->code;
1047
                  }
1048
              }
1049
            break;
1050
          }
1051
 
1052
        case scratch_record: /* cache macro records */
1053
        case cache_record:
1054
        case compute_record:
1055
          {
1056
            cache_entry *new_cache;
1057
            /* parse the cache record */
1058
            if (record->nr_fields < nr_cache_fields)
1059
              error (record->line,
1060
                     "Incorrect nr of fields for scratch/cache/compute record\n");
1061
            /* create it */
1062
            new_cache = ZALLOC (cache_entry);
1063
            new_cache->line = record->line;
1064
            filter_parse (&new_cache->flags,
1065
                          record->field[record_filter_flags_field]);
1066
            filter_parse (&new_cache->models,
1067
                          record->field[record_filter_models_field]);
1068
            new_cache->type = record->field[cache_typedef_field];
1069
            new_cache->name = record->field[cache_name_field];
1070
            filter_parse (&new_cache->original_fields,
1071
                          record->field[cache_original_fields_field]);
1072
            new_cache->expression = record->field[cache_expression_field];
1073
            /* insert it but only if not filtered out */
1074
            if (!filter_is_subset (options.flags_filter, new_cache->flags))
1075
              {
1076
                notify (new_cache->line, "Discarding cache entry %s - filter flags\n",
1077
                        new_cache->name);
1078
              }
1079
            else if (is_filtered_out (options.model_filter,
1080
                                      record->field[record_filter_models_field]))
1081
              {
1082
                notify (new_cache->line, "Discarding cache entry %s - filter models\n",
1083
                        new_cache->name);
1084
              }
1085
            else
1086
              {
1087
                cache_entry **last;
1088
                last = &isa->caches;
1089
                while (*last != NULL)
1090
                  last = &(*last)->next;
1091
                *last = new_cache;
1092
              }
1093
            /* advance things */
1094
            record = table_read (file);
1095
            break;
1096
          }
1097
 
1098
        /* model records */
1099
        case model_processor_record:
1100
          {
1101
            model_entry *new_model;
1102
            /* parse the model */
1103
            if (record->nr_fields < nr_model_processor_fields)
1104
              error (record->line, "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, "Discarding processor model %s - filter flags\n",
1118
                        new_model->name);
1119
              }
1120
            else if (is_filtered_out (options.model_filter,
1121
                                      record->field[record_filter_models_field]))
1122
              {
1123
                notify (new_model->line, "Discarding processor model %s - filter models\n",
1124
                        new_model->name);
1125
              }
1126
            else if (filter_is_member (model->processors, new_model->name))
1127
              {
1128
                error (new_model->line, "Duplicate processor model %s\n",
1129
                       new_model->name);
1130
              }
1131
            else
1132
              {
1133
                model_entry **last;
1134
                last = &model->models;
1135
                while (*last != NULL)
1136
                  last = &(*last)->next;
1137
                *last = new_model;
1138
                /* count it */
1139
                model->nr_models ++;
1140
                filter_parse (&model->processors, new_model->name);
1141
              }
1142
            /* advance things */
1143
            record = table_read (file);
1144
          }
1145
          break;
1146
 
1147
        case model_macro_record:
1148
          record = parse_model_data_record (isa, file, record,
1149
                                            nr_model_macro_fields,
1150
                                            &model->macros);
1151
          break;
1152
 
1153
        case model_data_record:
1154
          record = parse_model_data_record (isa, file, record,
1155
                                            nr_model_data_fields,
1156
                                            &model->data);
1157
          break;
1158
 
1159
        case model_static_record:
1160
          record = parse_function_record (file, record,
1161
                                          &model->statics,
1162
                                          NULL,
1163
                                          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,
1171
                                          1/*is internal*/,
1172
                                          model);
1173
          break;
1174
 
1175
        case model_function_record:
1176
          record = parse_function_record (file, record,
1177
                                          &model->functions,
1178
                                          NULL,
1179
                                          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, "Incorrect nr of fields for insn record\n");
1190
            new_insn = ZALLOC (insn_entry);
1191
            new_insn->line = record->line;
1192
            filter_parse (&new_insn->flags,
1193
                          record->field[record_filter_flags_field]);
1194
            /* save the format field.  Can't parse it until after the
1195
               filter-out checks.  Could be filtered out because the
1196
               format is invalid */
1197
            format = record->field[insn_word_field];
1198
            new_insn->format_name = record->field[insn_format_name_field];
1199
            if (options.format_name_filter != NULL
1200
                && !filter_is_member (options.format_name_filter,
1201
                                      new_insn->format_name))
1202
              error (new_insn->line, "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 = NZALLOC (insn_model_entry*, model->nr_models + 1);
1211
            while (record != NULL)
1212
              {
1213
                if (record_prefix_is (record, '*', nr_insn_model_fields))
1214
                  parse_insn_model_record (file, record, new_insn, model);
1215
                else if (record_prefix_is (record, '"', nr_insn_mnemonic_fields))
1216
                  parse_insn_mnemonic_record (file, record, new_insn);
1217
                else
1218
                  break;
1219
                /* advance */
1220
                record = table_read (file);
1221
              }
1222
            /* Parse the code record */
1223
            if (record != NULL && record->type == table_code_entry)
1224
              {
1225
                new_insn->code = record;
1226
                record = table_read (file);
1227
              }
1228
            else if (options.warn.unimplemented)
1229
              notify (new_insn->line, "unimplemented\n");
1230
            /* insert it */
1231
            if (!filter_is_subset (options.flags_filter, new_insn->flags))
1232
              {
1233
                if (options.warn.discard)
1234
                  notify (new_insn->line,
1235
                          "Discarding instruction %s (flags-filter)\n",
1236
                          new_insn->name);
1237
              }
1238
            else if (new_insn->processors != NULL
1239
                     && options.model_filter != NULL
1240
                     && !filter_is_common (options.model_filter,
1241
                                           new_insn->processors))
1242
              {
1243
                /* only discard an instruction based in the processor
1244
                   model when both the instruction and the options are
1245
                   nonempty */
1246
                if (options.warn.discard)
1247
                  notify (new_insn->line,
1248
                          "Discarding instruction %s (processor-model)\n",
1249
                          new_insn->name);
1250
              }
1251
            else
1252
              {
1253
                insn_entry **last;
1254
                /* finish the parsing */
1255
                parse_insn_words (new_insn, format);
1256
                /* append it */
1257
                last = &isa->insns;
1258
                while (*last)
1259
                  last = &(*last)->next;
1260
                *last = new_insn;
1261
                /* update global isa counters */
1262
                isa->nr_insns ++;
1263
                if (isa->max_nr_words < new_insn->nr_words)
1264
                  isa->max_nr_words = new_insn->nr_words;
1265
                filter_add (&isa->flags, new_insn->flags);
1266
                filter_add (&isa->options, new_insn->options);
1267
              }
1268
            break;
1269
          }
1270
 
1271
        case define_record:
1272
          record = parse_macro_record (file, record);
1273
          break;
1274
 
1275
        case unknown_record:
1276
        case code_record:
1277
          error (record->line, "Unknown or unexpected entry\n");
1278
 
1279
 
1280
        }
1281
    }
1282
  return isa;
1283
}
1284
 
1285
 
1286
void
1287
print_insn_words (lf *file,
1288
                  insn_entry *insn)
1289
{
1290
  insn_word_entry *word = insn->words;
1291
  if (word != NULL)
1292
    {
1293
      while (1)
1294
        {
1295
          insn_field_entry *field = word->first;
1296
          while (1)
1297
            {
1298
              if (options.insn_specifying_widths)
1299
                lf_printf (file, "%d.", field->width);
1300
              else
1301
                lf_printf (file, "%d.", i2target (options.hi_bit_nr, field->first));
1302
              switch (field->type)
1303
                {
1304
                case insn_field_invalid:
1305
                  ASSERT (0);
1306
                  break;
1307
                case insn_field_int:
1308
                  lf_printf (file, "0x%lx", (long) field->val_int);
1309
                  break;
1310
                case insn_field_reserved:
1311
                  lf_printf (file, "/");
1312
                  break;
1313
                case insn_field_wild:
1314
                  lf_printf (file, "*");
1315
                  break;
1316
                case insn_field_string:
1317
                  lf_printf (file, "%s", field->val_string);
1318
                  break;
1319
                }
1320
              if (field == word->last)
1321
                break;
1322
              field = field->next;
1323
              lf_printf (file, ",");
1324
            }
1325
          word = word->next;
1326
          if (word == NULL)
1327
            break;
1328
          lf_printf (file, "+");
1329
        }
1330
    }
1331
}
1332
 
1333
 
1334
 
1335
void
1336
function_entry_traverse (lf *file,
1337
                         function_entry *functions,
1338
                         function_entry_handler *handler,
1339
                         void *data)
1340
{
1341
  function_entry *function;
1342
  for (function = functions; function != NULL; function = function->next)
1343
    {
1344
      handler (file, function, data);
1345
    }
1346
}
1347
 
1348
void
1349
insn_table_traverse_insn (lf *file,
1350
                          insn_table *isa,
1351
                          insn_entry_handler *handler,
1352
                          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,
1365
                     function_entry *entry,
1366
                     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,
1386
                       function_entry *entry,
1387
                       char *suffix)
1388
{
1389
  lf_printf (file, "%s", prefix);
1390
  lf_indent (file, +1);
1391
  while (entry != NULL)
1392
    {
1393
      dump_function_entry (file, "\n(", entry, ")");
1394
      entry = entry->next;
1395
    }
1396
  lf_indent (file, -1);
1397
  lf_printf (file, "%s", suffix);
1398
}
1399
 
1400
static char *
1401
cache_entry_type_to_str (cache_entry_type type)
1402
{
1403
  switch (type)
1404
    {
1405
    case scratch_value: return "scratch";
1406
    case cache_value: return "cache";
1407
    case compute_value: return "compute";
1408
    }
1409
  ERROR ("Bad switch");
1410
  return 0;
1411
}
1412
 
1413
static void
1414
dump_cache_entry (lf *file,
1415
                  char *prefix,
1416
                  cache_entry *entry,
1417
                  char *suffix)
1418
{
1419
  lf_printf (file, "%s(cache_entry *) 0x%lx", prefix, (long) entry);
1420
  if (entry != NULL)
1421
    {
1422
      dump_line_ref (file, "\n(line ", entry->line, ")");
1423
      dump_filter (file, "\n(flags ", entry->flags, ")");
1424
      lf_printf (file, "\n(entry_type \"%s\")", cache_entry_type_to_str (entry->entry_type));
1425
      lf_printf (file, "\n(name \"%s\")", entry->name);
1426
      dump_filter (file, "\n(original_fields ", entry->original_fields, ")");
1427
      lf_printf (file, "\n(type \"%s\")", entry->type);
1428
      lf_printf (file, "\n(expression \"%s\")", entry->expression);
1429
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1430
    }
1431
  lf_printf (file, "%s", suffix);
1432
}
1433
 
1434
void
1435
dump_cache_entries (lf *file,
1436
                    char *prefix,
1437
                    cache_entry *entry,
1438
                    char *suffix)
1439
{
1440
  lf_printf (file, "%s", prefix);
1441
  lf_indent (file, +1);
1442
  while (entry != NULL)
1443
    {
1444
      dump_cache_entry (file, "\n(", entry, ")");
1445
      entry = entry->next;
1446
    }
1447
  lf_indent (file, -1);
1448
  lf_printf (file, "%s", suffix);
1449
}
1450
 
1451
static void
1452
dump_model_data (lf *file,
1453
                 char *prefix,
1454
                 model_data *entry,
1455
                 char *suffix)
1456
{
1457
  lf_printf (file, "%s(model_data *) 0x%lx", prefix, (long) entry);
1458
  if (entry != NULL)
1459
    {
1460
      lf_indent (file, +1);
1461
      dump_line_ref (file, "\n(line ", entry->line, ")");
1462
      dump_filter (file, "\n(flags ", entry->flags, ")");
1463
      dump_table_entry (file, "\n(entry ", entry->entry, ")");
1464
      dump_table_entry (file, "\n(code ", entry->code, ")");
1465
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1466
      lf_indent (file, -1);
1467
    }
1468
  lf_printf (file, "%s", prefix);
1469
}
1470
 
1471
static void
1472
dump_model_datas (lf *file,
1473
                  char *prefix,
1474
                  model_data *entry,
1475
                  char *suffix)
1476
{
1477
  lf_printf (file, "%s", prefix);
1478
  lf_indent (file, +1);
1479
  while (entry != NULL)
1480
    {
1481
      dump_model_data (file, "\n(", entry, ")");
1482
      entry = entry->next;
1483
    }
1484
  lf_indent (file, -1);
1485
  lf_printf (file, "%s", suffix);
1486
}
1487
 
1488
static void
1489
dump_model_entry (lf *file,
1490
                  char *prefix,
1491
                  model_entry *entry,
1492
                  char *suffix)
1493
{
1494
  lf_printf (file, "%s(model_entry *) 0x%lx", prefix, (long) entry);
1495
  if (entry != NULL)
1496
    {
1497
      lf_indent (file, +1);
1498
      dump_line_ref (file, "\n(line ", entry->line, ")");
1499
      dump_filter (file, "\n(flags ", entry->flags, ")");
1500
      lf_printf (file, "\n(name \"%s\")", entry->name);
1501
      lf_printf (file, "\n(full_name \"%s\")", entry->full_name);
1502
      lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data);
1503
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1504
      lf_indent (file, -1);
1505
    }
1506
  lf_printf (file, "%s", prefix);
1507
}
1508
 
1509
static void
1510
dump_model_entries (lf *file,
1511
                    char *prefix,
1512
                    model_entry *entry,
1513
                    char *suffix)
1514
{
1515
  lf_printf (file, "%s", prefix);
1516
  lf_indent (file, +1);
1517
  while (entry != NULL)
1518
    {
1519
      dump_model_entry (file, "\n(", entry, ")");
1520
      entry = entry->next;
1521
    }
1522
  lf_indent (file, -1);
1523
  lf_printf (file, "%s", suffix);
1524
}
1525
 
1526
 
1527
static void
1528
dump_model_table (lf *file,
1529
                  char *prefix,
1530
                  model_table *entry,
1531
                  char *suffix)
1532
{
1533
  lf_printf (file, "%s(model_table *) 0x%lx", prefix, (long) entry);
1534
  if (entry != NULL)
1535
    {
1536
      lf_indent (file, +1);
1537
      dump_filter (file, "\n(processors ", entry->processors, ")");
1538
      lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1539
      dump_model_entries (file, "\n(models ", entry->models, ")");
1540
      dump_model_datas (file, "\n(macros ", entry->macros, ")");
1541
      dump_model_datas (file, "\n(data ", entry->data, ")");
1542
      dump_function_entries (file, "\n(statics ", entry->statics, ")");
1543
      dump_function_entries (file, "\n(internals ", entry->functions, ")");
1544
      dump_function_entries (file, "\n(functions ", entry->functions, ")");
1545
      lf_indent (file, -1);
1546
    }
1547
  lf_printf (file, "%s", suffix);
1548
}
1549
 
1550
 
1551
static char *
1552
insn_field_type_to_str (insn_field_type type)
1553
{
1554
  switch (type)
1555
    {
1556
    case insn_field_invalid: ASSERT (0); return "(invalid)";
1557
    case insn_field_int: return "int";
1558
    case insn_field_reserved: return "reserved";
1559
    case insn_field_wild: return "wild";
1560
    case insn_field_string: return "string";
1561
    }
1562
  ERROR ("bad switch");
1563
  return 0;
1564
}
1565
 
1566
void
1567
dump_insn_field (lf *file,
1568
                 char *prefix,
1569
                 insn_field_entry *field,
1570
                 char *suffix)
1571
{
1572
  char *sep = " ";
1573
  lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field);
1574
  if (field != NULL)
1575
    {
1576
      lf_indent (file, +1);
1577
      lf_printf (file, "%s(first %d)", sep, field->first);
1578
      lf_printf (file, "%s(last %d)", sep, field->last);
1579
      lf_printf (file, "%s(width %d)", sep, field->width);
1580
      lf_printf (file, "%s(type %s)", sep, insn_field_type_to_str (field->type));
1581
      switch (field->type)
1582
        {
1583
        case insn_field_invalid:
1584
          ASSERT (0);
1585
          break;
1586
        case insn_field_int:
1587
          lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int);
1588
          break;
1589
        case insn_field_reserved:
1590
          /* nothing output */
1591
          break;
1592
        case insn_field_wild:
1593
          /* nothing output */
1594
          break;
1595
        case insn_field_string:
1596
          lf_printf (file, "%s(val \"%s\")", sep, field->val_string);
1597
          break;
1598
        }
1599
      lf_printf (file, "%s(next 0x%lx)", sep, (long) field->next);
1600
      lf_printf (file, "%s(prev 0x%lx)", sep, (long) field->prev);
1601
      lf_indent (file, -1);
1602
    }
1603
  lf_printf (file, "%s", suffix);
1604
}
1605
 
1606
void
1607
dump_insn_word_entry (lf *file,
1608
                      char *prefix,
1609
                      insn_word_entry *word,
1610
                      char *suffix)
1611
{
1612
  lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word);
1613
  if (word != NULL)
1614
    {
1615
      int i;
1616
      insn_field_entry *field;
1617
      lf_indent (file, +1);
1618
      lf_printf (file, "\n(first 0x%lx)", (long) word->first);
1619
      lf_printf (file, "\n(last 0x%lx)", (long) word->last);
1620
      lf_printf (file, "\n(bit");
1621
      for (i = 0; i < options.insn_bit_size; i++)
1622
        lf_printf (file, "\n ((value %d) (mask %d) (field 0x%lx))",
1623
                   word->bit[i]->value, word->bit[i]->mask, (long) word->bit[i]->field);
1624
      lf_printf (file, ")");
1625
      for (field = word->first; field != NULL; field = field->next)
1626
        dump_insn_field (file, "\n(", field, ")");
1627
      dump_filter (file, "\n(field_names ", word->field_names, ")");
1628
      lf_printf (file, "\n(next 0x%lx)", (long) word->next);
1629
      lf_indent (file, -1);
1630
    }
1631
  lf_printf (file, "%s", suffix);
1632
}
1633
 
1634
static void
1635
dump_insn_word_entries (lf *file,
1636
                        char *prefix,
1637
                        insn_word_entry *word,
1638
                        char *suffix)
1639
{
1640
  lf_printf (file, "%s", prefix);
1641
  while (word != NULL)
1642
    {
1643
      dump_insn_word_entry (file, "\n(", word, ")");
1644
      word = word->next;
1645
    }
1646
  lf_printf (file, "%s", suffix);
1647
}
1648
 
1649
static void
1650
dump_insn_model_entry (lf *file,
1651
                       char *prefix,
1652
                       insn_model_entry *model,
1653
                       char *suffix)
1654
{
1655
  lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model);
1656
  if (model != NULL)
1657
    {
1658
      lf_indent (file, +1);
1659
      dump_line_ref (file, "\n(line ", model->line, ")");
1660
      dump_filter (file, "\n(names ", model->names, ")");
1661
      lf_printf (file, "\n(full_name \"%s\")", model->full_name);
1662
      lf_printf (file, "\n(unit_data \"%s\")", model->unit_data);
1663
      lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", (long) model->insn);
1664
      lf_printf (file, "\n(next (insn_model_entry *) 0x%lx)",
1665
                 (long) model->next);
1666
      lf_indent (file, -1);
1667
    }
1668
  lf_printf (file, "%s", suffix);
1669
}
1670
 
1671
static void
1672
dump_insn_model_entries (lf *file,
1673
                         char *prefix,
1674
                         insn_model_entry *model,
1675
                         char *suffix)
1676
{
1677
  lf_printf (file, "%s", prefix);
1678
  while (model != NULL)
1679
    {
1680
      dump_insn_model_entry (file, "\n", model, "");
1681
      model = model->next;
1682
    }
1683
  lf_printf (file, "%s", suffix);
1684
}
1685
 
1686
 
1687
static void
1688
dump_insn_mnemonic_entry (lf *file,
1689
                          char *prefix,
1690
                          insn_mnemonic_entry *mnemonic,
1691
                          char *suffix)
1692
{
1693
  lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix, (long) mnemonic);
1694
  if (mnemonic != NULL)
1695
    {
1696
      lf_indent (file, +1);
1697
      dump_line_ref (file, "\n(line ", mnemonic->line, ")");
1698
      lf_printf (file, "\n(format \"%s\")", mnemonic->format);
1699
      lf_printf (file, "\n(condition \"%s\")", mnemonic->condition);
1700
      lf_printf (file, "\n(insn (insn_entry *) 0x%lx)",
1701
                 (long) mnemonic->insn);
1702
      lf_printf (file, "\n(next (insn_mnemonic_entry *) 0x%lx)",
1703
                 (long) mnemonic->next);
1704
      lf_indent (file, -1);
1705
    }
1706
  lf_printf (file, "%s", suffix);
1707
}
1708
 
1709
static void
1710
dump_insn_mnemonic_entries (lf *file,
1711
                            char *prefix,
1712
                            insn_mnemonic_entry *mnemonic,
1713
                            char *suffix)
1714
{
1715
  lf_printf (file, "%s", prefix);
1716
  while (mnemonic != NULL)
1717
    {
1718
      dump_insn_mnemonic_entry (file, "\n", mnemonic, "");
1719
      mnemonic = mnemonic->next;
1720
    }
1721
  lf_printf (file, "%s", suffix);
1722
}
1723
 
1724
void
1725
dump_insn_entry (lf *file,
1726
                 char *prefix,
1727
                 insn_entry *entry,
1728
                 char *suffix)
1729
{
1730
  lf_printf (file, "%s(insn_entry *) 0x%lx", prefix, (long) entry);
1731
  if (entry != NULL)
1732
    {
1733
      int i;
1734
      lf_indent (file, +1);
1735
      dump_line_ref (file, "\n(line ", entry->line, ")");
1736
      dump_filter (file, "\n(flags ", entry->flags, ")");
1737
      lf_printf (file, "\n(nr_words %d)", entry->nr_words);
1738
      dump_insn_word_entries (file, "\n(words ", entry->words, ")");
1739
      lf_printf (file, "\n(word");
1740
      for (i = 0; i < entry->nr_models; i++)
1741
        lf_printf (file, " 0x%lx", (long) entry->word[i]);
1742
      lf_printf (file, ")");
1743
      dump_filter (file, "\n(field_names ", entry->field_names, ")");
1744
      lf_printf (file, "\n(format_name \"%s\")", entry->format_name);
1745
      dump_filter (file, "\n(options ", entry->options, ")");
1746
      lf_printf (file, "\n(name \"%s\")", entry->name);
1747
      lf_printf (file, "\n(nr_models %d)", entry->nr_models);
1748
      dump_insn_model_entries (file, "\n(models ", entry->models, ")");
1749
      lf_printf (file, "\n(model");
1750
      for (i = 0; i < entry->nr_models; i++)
1751
        lf_printf (file, " 0x%lx", (long) entry->model[i]);
1752
      lf_printf (file, ")");
1753
      dump_filter (file, "\n(processors ", entry->processors, ")");
1754
      dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics, ")");
1755
      dump_table_entry (file, "\n(code ", entry->code, ")");
1756
      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1757
      lf_indent (file, -1);
1758
  }
1759
  lf_printf (file, "%s", suffix);
1760
}
1761
 
1762
static void
1763
dump_insn_entries (lf *file,
1764
                   char *prefix,
1765
                   insn_entry *entry,
1766
                   char *suffix)
1767
{
1768
  lf_printf (file, "%s", prefix);
1769
  lf_indent (file, +1);
1770
  while (entry != NULL)
1771
    {
1772
      dump_insn_entry (file, "\n(", entry, ")");
1773
      entry = entry->next;
1774
    }
1775
  lf_indent (file, -1);
1776
  lf_printf (file, "%s", suffix);
1777
}
1778
 
1779
 
1780
 
1781
void
1782
dump_insn_table (lf *file,
1783
                 char *prefix,
1784
                 insn_table *isa,
1785
                 char *suffix)
1786
{
1787
  lf_printf (file, "%s(insn_table *) 0x%lx", prefix, (long) isa);
1788
  if (isa != NULL)
1789
    {
1790
      lf_indent (file, +1);
1791
      dump_cache_entries (file, "\n(caches ", isa->caches, ")");
1792
      lf_printf (file, "\n(nr_insns %d)", isa->nr_insns);
1793
      lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words);
1794
      dump_insn_entries (file, "\n(insns ", isa->insns, ")");
1795
      dump_function_entries (file, "\n(functions ", isa->functions, ")");
1796
      dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")");
1797
      dump_model_table (file, "\n(model ", isa->model, ")");
1798
      dump_filter (file, "\n(flags ", isa->flags, ")");
1799
      dump_filter (file, "\n(options ", isa->options, ")");
1800
      lf_indent (file, -1);
1801
    }
1802
  lf_printf (file, "%s", suffix);
1803
}
1804
 
1805
#ifdef MAIN
1806
 
1807
igen_options options;
1808
 
1809
int
1810
main (int argc, char **argv)
1811
{
1812
  insn_table *isa;
1813
  lf *l;
1814
 
1815
  INIT_OPTIONS (options);
1816
 
1817
  if (argc == 3)
1818
    filter_parse (&options.flags_filter, argv[2]);
1819
  else if (argc != 2)
1820
    error (NULL, "Usage: insn <insn-table> [ <filter-in> ]\n");
1821
 
1822
  isa = load_insn_table (argv[1], NULL);
1823
  l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1824
  dump_insn_table (l, "(isa ", isa, ")\n");
1825
 
1826
  return 0;
1827
}
1828
 
1829
#endif

powered by: WebSVN 2.1.0

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