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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [igen/] [gen.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1997, 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
 
27
#include "igen.h"
28
#include "ld-insn.h"
29
#include "ld-decode.h"
30
#include "gen.h"
31
 
32
static insn_uint
33
sub_val (insn_uint val,
34
         int val_last_pos,
35
         int first_pos,
36
         int last_pos)
37
{
38
  return ((val >> (val_last_pos - last_pos))
39
          & (((insn_uint)1 << (last_pos - first_pos + 1)) - 1));
40
}
41
 
42
static void
43
update_depth (lf *file,
44
              gen_entry *entry,
45
              int depth,
46
              void *data)
47
{
48
  int *max_depth = (int*)data;
49
  if (*max_depth < depth)
50
    *max_depth = depth;
51
}
52
 
53
 
54
int
55
gen_entry_depth (gen_entry *table)
56
{
57
  int depth = 0;
58
  gen_entry_traverse_tree (NULL,
59
                           table,
60
                           1,
61
                           NULL, /*start*/
62
                           update_depth,
63
                           NULL, /*end*/
64
                           &depth); /* data */
65
  return depth;
66
}
67
 
68
 
69
static void
70
print_gen_entry_path (line_ref *line,
71
                      gen_entry *table,
72
                      error_func *print)
73
{
74
  if (table->parent == NULL)
75
    {
76
      if (table->top->model != NULL)
77
        print (line, "%s", table->top->model->name);
78
      else
79
        print (line, "");
80
    }
81
  else
82
    {
83
      print_gen_entry_path (line, table->parent, print);
84
      print (NULL, ".%d", table->opcode_nr);
85
    }
86
}
87
 
88
static void
89
print_gen_entry_insns (gen_entry *table,
90
                       error_func *print,
91
                       char *first_message,
92
                       char *next_message)
93
{
94
  insn_list *i;
95
  char *message;
96
  message = first_message;
97
  for (i = table->insns; i != NULL; i = i->next)
98
    {
99
      insn_entry *insn = i->insn;
100
      print_gen_entry_path (insn->line, table, print);
101
      print (NULL, ": %s.%s %s\n",
102
             insn->format_name,
103
             insn->name,
104
             message);
105
      if (next_message != NULL)
106
        message = next_message;
107
    }
108
}
109
 
110
/* same as strcmp */
111
static int
112
insn_field_cmp (insn_word_entry *l, insn_word_entry *r)
113
{
114
  while (1)
115
    {
116
      int bit_nr;
117
      if (l == NULL && r == NULL)
118
        return 0; /* all previous fields the same */
119
      if (l == NULL)
120
        return -1; /* left shorter than right */
121
      if (r == NULL)
122
        return +1; /* left longer than right */
123
      for (bit_nr = 0;
124
           bit_nr < options.insn_bit_size;
125
           bit_nr++)
126
        {
127
          if (l->bit[bit_nr]->field->type != insn_field_string)
128
            continue;
129
          if (r->bit[bit_nr]->field->type != insn_field_string)
130
            continue;
131
          if (l->bit[bit_nr]->field->conditions == NULL)
132
            continue;
133
          if (r->bit[bit_nr]->field->conditions == NULL)
134
            continue;
135
          if (0)
136
            printf ("%s%s%s VS %s%s%s\n",
137
                    l->bit[bit_nr]->field->val_string,
138
                    l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!",
139
                    l->bit[bit_nr]->field->conditions->string,
140
                    r->bit[bit_nr]->field->val_string,
141
                    r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!",
142
                    r->bit[bit_nr]->field->conditions->string);
143
          if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq
144
              && r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
145
            {
146
              if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field
147
                  && r->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
148
                /* somewhat arbitrary */
149
                {
150
                  int cmp = strcmp (l->bit[bit_nr]->field->conditions->string,
151
                                    r->bit[bit_nr]->field->conditions->string);
152
                  if (cmp != 0)
153
                    return cmp;
154
                  else
155
                    continue;
156
                }
157
              if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
158
                return +1;
159
              if (r->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
160
                return -1;
161
              /* The case of both fields having constant values should have
162
                 already have been handled because such fields are converted
163
                 into normal constant fields. */
164
              continue;
165
            }
166
          if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
167
            return +1; /* left = only */
168
          if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
169
            return -1; /* right = only */
170
          /* FIXME: Need to some what arbitrarily order conditional lists */
171
          continue;
172
        }
173
      l = l->next;
174
      r = r->next;
175
    }
176
}
177
 
178
/* same as strcmp */
179
static int
180
insn_word_cmp (insn_word_entry *l, insn_word_entry *r)
181
{
182
  while (1)
183
    {
184
      int bit_nr;
185
      if (l == NULL && r == NULL)
186
        return 0; /* all previous fields the same */
187
      if (l == NULL)
188
        return -1; /* left shorter than right */
189
      if (r == NULL)
190
        return +1; /* left longer than right */
191
      for (bit_nr = 0;
192
           bit_nr < options.insn_bit_size;
193
           bit_nr++)
194
        {
195
          if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask)
196
            return -1;
197
          if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask)
198
            return 1;
199
          if (l->bit[bit_nr]->value < r->bit[bit_nr]->value)
200
            return -1;
201
          if (l->bit[bit_nr]->value > r->bit[bit_nr]->value)
202
            return 1;
203
        }
204
      l = l->next;
205
      r = r->next;
206
    }
207
}
208
 
209
/* same as strcmp */
210
static int
211
opcode_bit_cmp (opcode_bits *l,
212
                opcode_bits *r)
213
{
214
  if (l == NULL && r == NULL)
215
    return 0; /* all previous bits the same */
216
  if (l == NULL)
217
    return -1; /* left shorter than right */
218
  if (r == NULL)
219
    return +1; /* left longer than right */
220
  /* most significant word */
221
  if (l->field->word_nr < r->field->word_nr)
222
    return +1; /* left has more significant word */
223
  if (l->field->word_nr > r->field->word_nr)
224
    return -1; /* right has more significant word */
225
  /* most significant bit? */
226
  if (l->first < r->first)
227
    return +1; /* left as more significant bit */
228
  if (l->first > r->first)
229
    return -1; /* right as more significant bit */
230
  /* nr bits? */
231
  if (l->last < r->last)
232
    return +1; /* left as less bits */
233
  if (l->last > r->last)
234
    return -1; /* right as less bits */
235
  /* value? */
236
  if (l->value < r->value)
237
    return -1;
238
  if (l->value > r->value)
239
    return 1;
240
  return 0;
241
}
242
 
243
 
244
/* same as strcmp */
245
static int
246
opcode_bits_cmp (opcode_bits *l,
247
                 opcode_bits *r)
248
{
249
  while (1)
250
    {
251
      int cmp;
252
      if (l == NULL && r == NULL)
253
        return 0; /* all previous bits the same */
254
      cmp = opcode_bit_cmp (l, r);
255
      if (cmp != 0)
256
        return cmp;
257
      l = l->next;
258
      r = r->next;
259
    }
260
}
261
 
262
/* same as strcmp */
263
static opcode_bits *
264
new_opcode_bits (opcode_bits *old_bits,
265
                 int value,
266
                 int first,
267
                 int last,
268
                 insn_field_entry *field,
269
                 opcode_field *opcode)
270
{
271
  opcode_bits *new_bits = ZALLOC (opcode_bits);
272
  new_bits->field = field;
273
  new_bits->value = value;
274
  new_bits->first = first;
275
  new_bits->last = last;
276
  new_bits->opcode = opcode;
277
 
278
  if (old_bits != NULL)
279
    {
280
      opcode_bits *new_list;
281
      opcode_bits **last = &new_list;
282
      new_list = new_opcode_bits (old_bits->next,
283
                                  old_bits->value,
284
                                  old_bits->first,
285
                                  old_bits->last,
286
                                  old_bits->field,
287
                                  old_bits->opcode);
288
      while (*last != NULL)
289
        {
290
          int cmp = opcode_bit_cmp (new_bits, *last);
291
          if (cmp < 0) /* new < new_list */
292
            {
293
              break;
294
            }
295
          if (cmp == 0)
296
            {
297
              ERROR ("Duplicated insn bits in list");
298
            }
299
          last = &(*last)->next;
300
        }
301
      new_bits->next = *last;
302
      *last = new_bits;
303
      return new_list;
304
    }
305
  else
306
    {
307
      return new_bits;
308
    }
309
}
310
 
311
 
312
 
313
 
314
typedef enum {
315
  merge_duplicate_insns,
316
  report_duplicate_insns,
317
} duplicate_insn_actions;
318
 
319
static insn_list *
320
insn_list_insert (insn_list **cur_insn_ptr,
321
                  int *nr_insns,
322
                  insn_entry *insn,
323
                  opcode_bits *expanded_bits,
324
                  opcode_field *opcodes,
325
                  int nr_prefetched_words,
326
                  duplicate_insn_actions duplicate_action)
327
{
328
  /* insert it according to the order of the fields & bits */
329
  for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next)
330
    {
331
      int cmp;
332
 
333
      /* key#1 sort according to the constant fields of each instruction */
334
      cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words);
335
      if (cmp < 0)
336
        break;
337
      else if (cmp > 0)
338
        continue;
339
 
340
      /* key#2 sort according to the expanded bits of each instruction */
341
      cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits);
342
      if (cmp < 0)
343
        break;
344
      else if (cmp > 0)
345
        continue;
346
 
347
      /* key#3 sort according to the non-constant fields of each instruction */
348
      cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words);
349
      if (cmp < 0)
350
        break;
351
      else if (cmp > 0)
352
        continue;
353
 
354
      /* duplicate keys, report problem */
355
      switch (duplicate_action)
356
        {
357
        case report_duplicate_insns:
358
          /* It would appear that we have two instructions with the
359
             same constant field values across all words and bits.
360
             This error can also occure when insn_field_cmp() is
361
             failing to differentiate between two instructions that
362
             differ only in their conditional fields. */
363
          warning (insn->line,
364
                   "Two instructions with identical constant fields\n");
365
          error ((*cur_insn_ptr)->insn->line,
366
                 "Location of duplicate instruction\n");
367
        case merge_duplicate_insns:
368
          /* Add the opcode path to the instructions list */
369
          if (opcodes != NULL)
370
            {
371
              insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
372
              while (*last != NULL)
373
                {
374
                  last = &(*last)->next;
375
                }
376
              (*last) = ZALLOC (insn_opcodes);
377
              (*last)->opcode = opcodes;
378
            }
379
          /* Use the larger nr_prefetched_words */
380
          if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
381
            (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
382
          return (*cur_insn_ptr);
383
        }
384
 
385
    }
386
 
387
  /* create a new list entry and insert it */
388
  {
389
    insn_list *new_insn = ZALLOC (insn_list);
390
    new_insn->insn = insn;
391
    new_insn->expanded_bits = expanded_bits;
392
    new_insn->next = (*cur_insn_ptr);
393
    new_insn->nr_prefetched_words = nr_prefetched_words;
394
    if (opcodes != NULL)
395
      {
396
        new_insn->opcodes = ZALLOC (insn_opcodes);
397
        new_insn->opcodes->opcode = opcodes;
398
      }
399
    (*cur_insn_ptr) = new_insn;
400
  }
401
 
402
  *nr_insns += 1;
403
 
404
  return (*cur_insn_ptr);
405
}
406
 
407
 
408
extern void
409
gen_entry_traverse_tree (lf *file,
410
                         gen_entry *table,
411
                         int depth,
412
                         gen_entry_handler *start,
413
                         gen_entry_handler *leaf,
414
                         gen_entry_handler *end,
415
                         void *data)
416
{
417
  gen_entry *entry;
418
 
419
  ASSERT (table != NULL);
420
  ASSERT (table->opcode != NULL);
421
  ASSERT (table->nr_entries > 0);
422
  ASSERT (table->entries != 0);
423
 
424
  /* prefix */
425
  if (start != NULL && depth >= 0)
426
    {
427
      start (file, table, depth, data);
428
    }
429
  /* infix leaves */
430
  for (entry = table->entries;
431
       entry != NULL;
432
       entry = entry->sibling)
433
    {
434
      if (entry->entries != NULL && depth != 0)
435
        {
436
          gen_entry_traverse_tree (file, entry, depth + 1,
437
                                   start, leaf, end, data);
438
        }
439
      else if (depth >= 0)
440
        {
441
          if (leaf != NULL)
442
            {
443
              leaf (file, entry, depth, data);
444
            }
445
        }
446
    }
447
  /* postfix */
448
  if (end != NULL && depth >= 0)
449
    {
450
      end (file, table, depth, data);
451
    }
452
}
453
 
454
 
455
 
456
/* create a list element containing a single gen_table entry */
457
 
458
static gen_list *
459
make_table (insn_table *isa,
460
            decode_table *rules,
461
            model_entry *model)
462
{
463
  insn_entry *insn;
464
  gen_list *entry = ZALLOC (gen_list);
465
  entry->table = ZALLOC (gen_entry);
466
  entry->table->top = entry;
467
  entry->model = model;
468
  entry->isa = isa;
469
  for (insn = isa->insns; insn != NULL; insn = insn->next)
470
    {
471
      if (model == NULL
472
          || insn->processors == NULL
473
          || filter_is_member (insn->processors, model->name))
474
        {
475
          insn_list_insert (&entry->table->insns,
476
                            &entry->table->nr_insns,
477
                            insn,
478
                            NULL, /* expanded_bits - none yet */
479
                            NULL, /* opcodes - none yet */
480
                            0, /* nr_prefetched_words - none yet */
481
                            report_duplicate_insns);
482
        }
483
    }
484
  entry->table->opcode_rule = rules;
485
  return entry;
486
}
487
 
488
 
489
gen_table *
490
make_gen_tables (insn_table *isa,
491
                 decode_table *rules)
492
{
493
  gen_table *gen = ZALLOC (gen_table);
494
  gen->isa = isa;
495
  gen->rules = rules;
496
  if (options.gen.multi_sim)
497
    {
498
      gen_list **last = &gen->tables;
499
      model_entry *model;
500
      filter *processors;
501
      if (options.model_filter != NULL)
502
        processors = options.model_filter;
503
      else
504
        processors = isa->model->processors;
505
      for (model = isa->model->models;
506
           model != NULL;
507
           model = model->next)
508
        {
509
          if (filter_is_member (processors, model->name))
510
            {
511
              *last = make_table (isa, rules, model);
512
              last = &(*last)->next;
513
            }
514
        }
515
    }
516
  else
517
    {
518
      gen->tables = make_table (isa, rules, NULL);
519
    }
520
  return gen;
521
}
522
 
523
 
524
/****************************************************************/
525
 
526
#if 0
527
typedef enum {
528
  field_is_not_constant = 0,
529
  field_constant_int = 1,
530
  field_constant_reserved = 2,
531
  field_constant_string = 3
532
} constant_field_types;
533
 
534
static constant_field_types
535
insn_field_is_constant (insn_field *field,
536
                        decode_table *rule)
537
{
538
  switch (field->type)
539
    {
540
    case insn_field_int:
541
      /* field is an integer */
542
      return field_constant_int;
543
    case insn_field_reserved:
544
      /* field is `/' and treating that as a constant */
545
      if (rule->with_zero_reserved)
546
        return field_constant_reserved;
547
      else
548
        return field_is_not_constant;
549
    case insn_field_wild:
550
      return field_is_not_constant; /* never constant */
551
    case insn_field_string:
552
      /* field, though variable, is on the list of forced constants */
553
      if (filter_is_member (rule->constant_field_names, field->val_string))
554
        return field_constant_string;
555
      else
556
        return field_is_not_constant;
557
    }
558
  ERROR ("Internal error");
559
  return field_is_not_constant;
560
}
561
#endif
562
 
563
 
564
/****************************************************************/
565
 
566
 
567
/* Is the bit, according to the decode rule, identical across all the
568
   instructions? */
569
static int
570
insns_bit_useless (insn_list *insns,
571
                   decode_table *rule,
572
                   int bit_nr)
573
{
574
  insn_list *entry;
575
  int value = -1;
576
  int is_useless = 1; /* cleared if something actually found */
577
 
578
  /* check the instructions for some constant value in at least one of
579
     the bit fields */
580
  for (entry = insns; entry != NULL; entry = entry->next)
581
    {
582
      insn_word_entry *word = entry->insn->word[rule->word_nr];
583
      insn_bit_entry *bit = word->bit[bit_nr];
584
      switch (bit->field->type)
585
        {
586
        case insn_field_invalid:
587
          ASSERT (0);
588
          break;
589
        case insn_field_wild:
590
        case insn_field_reserved:
591
          /* neither useless or useful - ignore */
592
          break;
593
        case insn_field_int:
594
          switch (rule->search)
595
            {
596
            case decode_find_strings:
597
              /* an integer isn't a string */
598
              return 1;
599
            case decode_find_constants:
600
            case decode_find_mixed:
601
              /* an integer is useful if its value isn't the same
602
                 between all instructions.  The first time through the
603
                 value is saved, the second time through (if the
604
                 values differ) it is marked as useful. */
605
              if (value < 0)
606
                value = bit->value;
607
              else if (value != bit->value)
608
                is_useless = 0;
609
              break;
610
            }
611
          break;
612
        case insn_field_string:
613
          switch (rule->search)
614
            {
615
            case decode_find_strings:
616
              /* at least one string, keep checking */
617
              is_useless = 0;
618
              break;
619
            case decode_find_constants:
620
            case decode_find_mixed:
621
              if (filter_is_member (rule->constant_field_names,
622
                                    bit->field->val_string))
623
                /* a string field forced to constant? */
624
                is_useless = 0;
625
              else if (rule->search == decode_find_constants)
626
                /* the string field isn't constant */
627
                return 1;
628
              break;
629
            }
630
        }
631
    }
632
 
633
  /* Given only one constant value has been found, check through all
634
     the instructions to see if at least one conditional makes it
635
     usefull */
636
  if (value >= 0 && is_useless)
637
    {
638
      for (entry = insns; entry != NULL; entry = entry->next)
639
        {
640
          insn_word_entry *word = entry->insn->word[rule->word_nr];
641
          insn_bit_entry *bit = word->bit[bit_nr];
642
          switch (bit->field->type)
643
            {
644
            case insn_field_invalid:
645
              ASSERT (0);
646
              break;
647
            case insn_field_wild:
648
            case insn_field_reserved:
649
            case insn_field_int:
650
              /* already processed */
651
              break;
652
            case insn_field_string:
653
              switch (rule->search)
654
                {
655
                case decode_find_strings:
656
                case decode_find_constants:
657
                  /* already processed */
658
                  break;
659
                case decode_find_mixed:
660
                  /* string field with conditions.  If this condition
661
                     eliminates the value then the compare is useful */
662
                  if (bit->field->conditions != NULL)
663
                    {
664
                      insn_field_cond *condition;
665
                      int shift = bit->field->last - bit_nr;
666
                      for (condition = bit->field->conditions;
667
                           condition != NULL;
668
                           condition = condition->next)
669
                        {
670
                          switch (condition->type)
671
                            {
672
                            case insn_field_cond_value:
673
                              switch (condition->test)
674
                                {
675
                                case insn_field_cond_ne:
676
                                  if (((condition->value >> shift) & 1)
677
                                      == (unsigned) value)
678
                                    /* conditional field excludes the
679
                                       current value */
680
                                    is_useless = 0;
681
                                  break;
682
                                case insn_field_cond_eq:
683
                                  if (((condition->value >> shift) & 1)
684
                                      != (unsigned) value)
685
                                    /* conditional field requires the
686
                                       current value */
687
                                    is_useless = 0;
688
                                  break;
689
                                }
690
                              break;
691
                            case insn_field_cond_field:
692
                              /* are these handled separatly? */
693
                              break;
694
                            }
695
                        }
696
                    }
697
                }
698
            }
699
        }
700
    }
701
 
702
  return is_useless;
703
}
704
 
705
 
706
/* go through a gen-table's list of instruction formats looking for a
707
   range of bits that meet the decode table RULEs requirements */
708
 
709
static opcode_field *
710
gen_entry_find_opcode_field (insn_list *insns,
711
                             decode_table *rule,
712
                             int string_only)
713
{
714
  opcode_field curr_opcode;
715
  ASSERT (rule != NULL);
716
 
717
  memset (&curr_opcode, 0, sizeof (curr_opcode));
718
  curr_opcode.word_nr = rule->word_nr;
719
  curr_opcode.first = rule->first;
720
  curr_opcode.last = rule->last;
721
 
722
  /* Try to reduce the size of first..last in accordance with the
723
     decode rules */
724
 
725
  while (curr_opcode.first <= rule->last)
726
    {
727
      if (insns_bit_useless (insns, rule, curr_opcode.first))
728
        curr_opcode.first ++;
729
      else
730
        break;
731
    }
732
  while (curr_opcode.last >= rule->first)
733
    {
734
      if (insns_bit_useless (insns, rule, curr_opcode.last))
735
        curr_opcode.last --;
736
      else
737
        break;
738
    }
739
 
740
 
741
#if 0
742
  for (entry = insns; entry != NULL; entry = entry->next)
743
    {
744
      insn_word_entry *fields = entry->insn->word[rule->word_nr];
745
      opcode_field new_opcode;
746
 
747
      ASSERT (fields != NULL);
748
 
749
      /* find a start point for the opcode field */
750
      new_opcode.first = rule->first;
751
      while (new_opcode.first <= rule->last
752
             && (!string_only
753
                 || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
754
                     != field_constant_string))
755
             && (string_only
756
                 || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
757
                     == field_is_not_constant)))
758
        {
759
          int new_first = fields->bit[new_opcode.first]->last + 1;
760
          ASSERT (new_first > new_opcode.first);
761
          new_opcode.first = new_first;
762
        }
763
      ASSERT(new_opcode.first > rule->last
764
             || (string_only
765
                 && insn_field_is_constant(fields->bit[new_opcode.first],
766
                                           rule) == field_constant_string)
767
             || (!string_only
768
                 && insn_field_is_constant(fields->bit[new_opcode.first],
769
                                           rule)));
770
 
771
      /* find the end point for the opcode field */
772
      new_opcode.last = rule->last;
773
      while (new_opcode.last >= rule->first
774
             && (!string_only
775
                 || insn_field_is_constant(fields->bit[new_opcode.last],
776
                                           rule) != field_constant_string)
777
             && (string_only
778
                 || !insn_field_is_constant(fields->bit[new_opcode.last],
779
                                            rule)))
780
        {
781
          int new_last = fields->bit[new_opcode.last]->first - 1;
782
          ASSERT (new_last < new_opcode.last);
783
          new_opcode.last = new_last;
784
        }
785
      ASSERT(new_opcode.last < rule->first
786
             || (string_only
787
                 && insn_field_is_constant(fields->bit[new_opcode.last],
788
                                           rule) == field_constant_string)
789
             || (!string_only
790
                 && insn_field_is_constant(fields->bit[new_opcode.last],
791
                                           rule)));
792
 
793
      /* now see if our current opcode needs expanding to include the
794
         interesting fields within this instruction */
795
      if (new_opcode.first <= rule->last
796
          && curr_opcode.first > new_opcode.first)
797
        curr_opcode.first = new_opcode.first;
798
      if (new_opcode.last >= rule->first
799
          && curr_opcode.last < new_opcode.last)
800
        curr_opcode.last = new_opcode.last;
801
 
802
    }
803
#endif
804
 
805
  /* did the final opcode field end up being empty? */
806
  if (curr_opcode.first > curr_opcode.last)
807
    {
808
      return NULL;
809
    }
810
  ASSERT (curr_opcode.last >= rule->first);
811
  ASSERT (curr_opcode.first <= rule->last);
812
  ASSERT (curr_opcode.first <= curr_opcode.last);
813
 
814
  /* Ensure that, for the non string only case, the opcode includes
815
     the range forced_first .. forced_last */
816
  if (!string_only
817
      && curr_opcode.first > rule->force_first)
818
    {
819
      curr_opcode.first = rule->force_first;
820
    }
821
  if (!string_only
822
      && curr_opcode.last < rule->force_last)
823
    {
824
      curr_opcode.last = rule->force_last;
825
    }
826
 
827
  /* For the string only case, force just the lower bound (so that the
828
     shift can be eliminated) */
829
  if (string_only
830
      && rule->force_last == options.insn_bit_size - 1)
831
    {
832
      curr_opcode.last = options.insn_bit_size - 1;
833
    }
834
 
835
  /* handle any special cases */
836
  switch (rule->type)
837
    {
838
    case normal_decode_rule:
839
      /* let the above apply */
840
      curr_opcode.nr_opcodes =
841
        (1 << (curr_opcode.last - curr_opcode.first + 1));
842
      break;
843
    case boolean_rule:
844
      curr_opcode.is_boolean = 1;
845
      curr_opcode.boolean_constant = rule->constant;
846
      curr_opcode.nr_opcodes = 2;
847
      break;
848
    }
849
 
850
  {
851
    opcode_field *new_field = ZALLOC (opcode_field);
852
    memcpy (new_field, &curr_opcode, sizeof (opcode_field));
853
    return new_field;
854
  }
855
}
856
 
857
 
858
static void
859
gen_entry_insert_insn (gen_entry *table,
860
                       insn_entry *old_insn,
861
                       int new_word_nr,
862
                       int new_nr_prefetched_words,
863
                       int new_opcode_nr,
864
                       opcode_bits *new_bits)
865
{
866
  gen_entry **entry = &table->entries;
867
 
868
  /* find the new table for this entry */
869
  while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr)
870
    {
871
      entry = &(*entry)->sibling;
872
    }
873
 
874
  if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr)
875
    {
876
      /* insert the missing entry */
877
      gen_entry *new_entry = ZALLOC (gen_entry);
878
      new_entry->sibling = (*entry);
879
      (*entry) = new_entry;
880
      table->nr_entries++;
881
      /* fill it in */
882
      new_entry->top = table->top;
883
      new_entry->opcode_nr = new_opcode_nr;
884
      new_entry->word_nr = new_word_nr;
885
      new_entry->expanded_bits = new_bits;
886
      new_entry->opcode_rule = table->opcode_rule->next;
887
      new_entry->parent = table;
888
      new_entry->nr_prefetched_words = new_nr_prefetched_words;
889
    }
890
  /* ASSERT new_bits == cur_entry bits */
891
  ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr);
892
  insn_list_insert (&(*entry)->insns,
893
                    &(*entry)->nr_insns,
894
                    old_insn,
895
                    NULL, /* expanded_bits - only in final list */
896
                    NULL, /* opcodes - only in final list */
897
                    new_nr_prefetched_words, /* for this table */
898
                    report_duplicate_insns);
899
}
900
 
901
 
902
static void
903
gen_entry_expand_opcode (gen_entry *table,
904
                         insn_entry *instruction,
905
                         int bit_nr,
906
                         int opcode_nr,
907
                         opcode_bits *bits)
908
{
909
  if (bit_nr > table->opcode->last)
910
    {
911
      /* Only include the hardwired bit information with an entry IF
912
         that entry (and hence its functions) are being duplicated.  */
913
      if (options.trace.insn_expansion)
914
        {
915
          print_gen_entry_path (table->opcode_rule->line, table, notify);
916
          notify (NULL, ": insert %d - %s.%s%s\n",
917
                  opcode_nr,
918
                  instruction->format_name,
919
                  instruction->name,
920
                  (table->opcode_rule->with_duplicates ? " (duplicated)" : ""));
921
        }
922
      if (table->opcode_rule->with_duplicates)
923
        {
924
          gen_entry_insert_insn (table, instruction,
925
                                 table->opcode->word_nr,
926
                                 table->nr_prefetched_words,
927
                                 opcode_nr, bits);
928
        }
929
      else
930
        {
931
          gen_entry_insert_insn (table, instruction,
932
                                 table->opcode->word_nr,
933
                                 table->nr_prefetched_words,
934
                                 opcode_nr, NULL);
935
        }
936
    }
937
  else
938
    {
939
      insn_word_entry *word = instruction->word[table->opcode->word_nr];
940
      insn_field_entry *field = word->bit[bit_nr]->field;
941
      int last_pos = ((field->last < table->opcode->last)
942
                      ? field->last
943
                      : table->opcode->last);
944
      int first_pos = ((field->first > table->opcode->first)
945
                       ? field->first
946
                       : table->opcode->first);
947
      int width = last_pos - first_pos + 1;
948
      switch (field->type)
949
        {
950
        case insn_field_int:
951
          {
952
            int val;
953
            val = sub_val (field->val_int, field->last,
954
                           first_pos, last_pos);
955
            gen_entry_expand_opcode (table, instruction,
956
                                     last_pos + 1,
957
                                     ((opcode_nr << width) | val),
958
                                     bits);
959
            break;
960
          }
961
        default:
962
          {
963
            if (field->type == insn_field_reserved)
964
              gen_entry_expand_opcode (table, instruction,
965
                                       last_pos + 1,
966
                                       ((opcode_nr << width)),
967
                                       bits);
968
            else
969
              {
970
                int val;
971
                int last_val = (table->opcode->is_boolean
972
                                ? 2
973
                                : (1 << width));
974
                for (val = 0; val < last_val; val++)
975
                  {
976
                    /* check to see if the value has been precluded
977
                       (by a conditional) in some way */
978
                    int is_precluded;
979
                    insn_field_cond *condition;
980
                    for (condition = field->conditions, is_precluded = 0;
981
                         condition != NULL && !is_precluded;
982
                         condition = condition->next)
983
                      {
984
                        switch (condition->type)
985
                          {
986
                          case insn_field_cond_value:
987
                            {
988
                              int value = sub_val (condition->value, field->last,
989
                                                   first_pos, last_pos);
990
                              switch (condition->test)
991
                                {
992
                                case insn_field_cond_ne:
993
                                  if (value == val)
994
                                    is_precluded = 1;
995
                                  break;
996
                                case insn_field_cond_eq:
997
                                  if (value != val)
998
                                    is_precluded = 1;
999
                                  break;
1000
                                }
1001
                              break;
1002
                            }
1003
                          case insn_field_cond_field:
1004
                            {
1005
                              int value;
1006
                              opcode_bits *bit;
1007
                              gen_entry *t;
1008
                              /* Try to find a value for the
1009
                                 conditional by looking back through
1010
                                 the previously defined bits for one
1011
                                 that covers the designated
1012
                                 conditional field */
1013
                              for (bit = bits;
1014
                                   bit != NULL;
1015
                                   bit = bit->next)
1016
                                {
1017
                                  if (bit->field->word_nr == condition->field->word_nr
1018
                                      && bit->first <= condition->field->first
1019
                                      && bit->last >= condition->field->last)
1020
                                    {
1021
                                      /* the bit field fully specified
1022
                                         the conditional field's value */
1023
                                      value = sub_val (bit->value, bit->last,
1024
                                                       condition->field->first,
1025
                                                       condition->field->last);
1026
                                    }
1027
                                }
1028
                              /* Try to find a value by looking
1029
                                 through this and previous tables */
1030
                              if (bit == NULL)
1031
                                {
1032
                                  for (t = table;
1033
                                       t->parent != NULL;
1034
                                       t = t->parent)
1035
                                    {
1036
                                      if (t->parent->opcode->word_nr == condition->field->word_nr
1037
                                          && t->parent->opcode->first <= condition->field->first
1038
                                          && t->parent->opcode->last >= condition->field->last)
1039
                                        {
1040
                                          /* the table entry fully
1041
                                             specified the condition
1042
                                             field's value */
1043
                                          /* extract the field's value
1044
                                             from the opcode */
1045
                                          value = sub_val (t->opcode_nr, t->parent->opcode->last,
1046
                                                           condition->field->first, condition->field->last);
1047
                                          /* this is a requirement of
1048
                                             a conditonal field
1049
                                             refering to another field */
1050
                                          ASSERT ((condition->field->first - condition->field->last)
1051
                                                  == (first_pos - last_pos));
1052
printf ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
1053
        value, t->opcode_nr, t->parent->opcode->last, condition->field->first, condition->field->last);
1054
                                        }
1055
                                    }
1056
                                }
1057
                              if (bit == NULL && t == NULL)
1058
                                error (instruction->line,
1059
                                       "Conditional `%s' of field `%s' isn't expanded",
1060
                                       condition->string, field->val_string);
1061
                              switch (condition->test)
1062
                                {
1063
                                case insn_field_cond_ne:
1064
                                  if (value == val)
1065
                                    is_precluded = 1;
1066
                                  break;
1067
                                case insn_field_cond_eq:
1068
                                  if (value != val)
1069
                                    is_precluded = 1;
1070
                                  break;
1071
                                }
1072
                              break;
1073
                            }
1074
                          }
1075
                      }
1076
                    if (!is_precluded)
1077
                      {
1078
                        /* Only add additional hardwired bit
1079
                           information if the entry is not going to
1080
                           later be combined */
1081
                        if (table->opcode_rule->with_combine)
1082
                          {
1083
                            gen_entry_expand_opcode (table, instruction,
1084
                                                     last_pos + 1,
1085
                                                     ((opcode_nr << width) | val),
1086
                                                     bits);
1087
                          }
1088
                        else
1089
                          {
1090
                            opcode_bits *new_bits = new_opcode_bits (bits, val,
1091
                                                                     first_pos, last_pos,
1092
                                                                     field,
1093
                                                                     table->opcode);
1094
                            gen_entry_expand_opcode (table, instruction,
1095
                                                     last_pos + 1,
1096
                                                     ((opcode_nr << width) | val),
1097
                                                     new_bits);
1098
                          }
1099
                      }
1100
                  }
1101
              }
1102
          }
1103
        }
1104
    }
1105
}
1106
 
1107
static void
1108
gen_entry_insert_expanding (gen_entry *table,
1109
                            insn_entry *instruction)
1110
{
1111
  gen_entry_expand_opcode (table,
1112
                           instruction,
1113
                           table->opcode->first,
1114
                           0,
1115
                           table->expanded_bits);
1116
}
1117
 
1118
 
1119
static int
1120
insns_match_format_names (insn_list *insns,
1121
                          filter *format_names)
1122
{
1123
  if (format_names != NULL)
1124
    {
1125
      insn_list *i;
1126
      for (i = insns; i != NULL; i = i->next)
1127
        {
1128
          if ( i->insn->format_name != NULL
1129
               && !filter_is_member (format_names, i->insn->format_name))
1130
            return 0;
1131
        }
1132
    }
1133
  return 1;
1134
}
1135
 
1136
static int
1137
table_matches_path (gen_entry *table,
1138
                    decode_path_list *paths)
1139
{
1140
  if (paths == NULL)
1141
    return 1;
1142
  while (paths != NULL)
1143
    {
1144
      gen_entry *entry = table;
1145
      decode_path *path = paths->path;
1146
      while (1)
1147
        {
1148
          if (entry == NULL && path == NULL)
1149
            return 1;
1150
          if (entry == NULL || path == NULL)
1151
            break;
1152
          if (entry->opcode_nr != path->opcode_nr)
1153
            break;
1154
          entry = entry->parent;
1155
          path = path->parent;
1156
        }
1157
      paths = paths->next;
1158
    }
1159
  return 0;
1160
}
1161
 
1162
 
1163
static int
1164
insns_match_conditions (insn_list *insns,
1165
                        decode_cond *conditions)
1166
{
1167
  if (conditions != NULL)
1168
    {
1169
      insn_list *i;
1170
      for (i = insns; i != NULL; i = i->next)
1171
        {
1172
          decode_cond *cond;
1173
          for (cond = conditions; cond != NULL; cond = cond->next)
1174
            {
1175
              int bit_nr;
1176
              if (i->insn->nr_words <= cond->word_nr)
1177
                return 0;
1178
              for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1179
                {
1180
                  if (!cond->mask[bit_nr])
1181
                    continue;
1182
                  if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask)
1183
                    return 0;
1184
                  if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value
1185
                       == cond->value[bit_nr])
1186
                      == !cond->is_equal)
1187
                    return 0;
1188
                }
1189
            }
1190
        }
1191
    }
1192
  return 1;
1193
}
1194
 
1195
static int
1196
insns_match_nr_words (insn_list *insns,
1197
                      int nr_words)
1198
{
1199
  insn_list *i;
1200
  for (i = insns; i != NULL; i = i->next)
1201
    {
1202
      if (i->insn->nr_words < nr_words)
1203
        return 0;
1204
    }
1205
  return 1;
1206
}
1207
 
1208
static int
1209
insn_list_cmp (insn_list *l,
1210
               insn_list *r)
1211
{
1212
  while (1)
1213
    {
1214
      insn_entry *insn;
1215
      if (l == NULL && r == NULL)
1216
        return 0;
1217
      if (l == NULL)
1218
        return -1;
1219
      if (r == NULL)
1220
        return 1;
1221
      if (l->insn != r->insn)
1222
        return -1; /* somewhat arbitrary at present */
1223
      /* skip this insn */
1224
      insn = l->insn;
1225
      while (l != NULL && l->insn == insn)
1226
        l = l->next;
1227
      while (r != NULL && r->insn == insn)
1228
        r = r->next;
1229
    }
1230
}
1231
 
1232
 
1233
 
1234
static void
1235
gen_entry_expand_insns (gen_entry *table)
1236
{
1237
  decode_table *opcode_rule;
1238
 
1239
  ASSERT(table->nr_insns >= 1);
1240
 
1241
  /* determine a valid opcode */
1242
  for (opcode_rule = table->opcode_rule;
1243
       opcode_rule != NULL;
1244
       opcode_rule = opcode_rule->next)
1245
    {
1246
      char *discard_reason;
1247
      if (table->top->model != NULL
1248
          && opcode_rule->model_names != NULL
1249
          && !filter_is_member (opcode_rule->model_names,
1250
                                table->top->model->name))
1251
        {
1252
          /* the rule isn't applicable to this processor */
1253
          discard_reason = "wrong model";
1254
        }
1255
      else if (table->nr_insns == 1 && opcode_rule->conditions == NULL)
1256
        {
1257
          /* for safety, require a pre-codition when attempting to
1258
             apply a rule to a single instruction */
1259
          discard_reason = "need pre-condition when nr-insn == 1";
1260
        }
1261
      else if (table->nr_insns == 1 && !opcode_rule->with_duplicates)
1262
        {
1263
          /* Little point in expanding a single instruction when we're
1264
             not duplicating the semantic functions that this table
1265
             calls */
1266
          discard_reason = "need duplication with nr-insns == 1";
1267
        }
1268
      else if (!insns_match_format_names (table->insns, opcode_rule->format_names))
1269
        {
1270
          discard_reason = "wrong format name";
1271
        }
1272
      else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1))
1273
        {
1274
          discard_reason = "wrong nr words";
1275
        }
1276
      else if (!table_matches_path (table, opcode_rule->paths))
1277
        {
1278
          discard_reason = "path failed";
1279
        }
1280
      else if (!insns_match_conditions (table->insns, opcode_rule->conditions))
1281
        {
1282
          discard_reason = "condition failed";
1283
        }
1284
      else
1285
        {
1286
          discard_reason = "no opcode field";
1287
          table->opcode =
1288
            gen_entry_find_opcode_field (table->insns,
1289
                                         opcode_rule,
1290
                                         table->nr_insns == 1/*string-only*/
1291
                                         );
1292
          if (table->opcode != NULL)
1293
            {
1294
              table->opcode_rule = opcode_rule;
1295
              break;
1296
            }
1297
        }
1298
 
1299
      if (options.trace.rule_rejection)
1300
        {
1301
          print_gen_entry_path (opcode_rule->line, table, notify);
1302
          notify (NULL, ": rule discarded - %s\n", discard_reason);
1303
        }
1304
    }
1305
 
1306
  /* did we find anything */
1307
  if (opcode_rule == NULL)
1308
    {
1309
      /* the decode table failed, this set of instructions haven't
1310
         been uniquely identified */
1311
      if (table->nr_insns > 1)
1312
        {
1313
          print_gen_entry_insns (table, warning,
1314
                                 "was not uniquely decoded",
1315
                                 "decodes to the same entry");
1316
          error (NULL, "");
1317
        }
1318
      return;
1319
    }
1320
 
1321
  /* Determine the number of words that must have been prefetched for
1322
     this table to function */
1323
  if (table->parent == NULL)
1324
    table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
1325
  else if (table->opcode_rule->word_nr + 1 > table->parent->nr_prefetched_words)
1326
    table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
1327
  else
1328
    table->nr_prefetched_words = table->parent->nr_prefetched_words;
1329
 
1330
  /* back link what we found to its parent */
1331
  if (table->parent != NULL)
1332
    {
1333
      ASSERT(table->parent->opcode != NULL);
1334
      table->opcode->parent = table->parent->opcode;
1335
    }
1336
 
1337
  /* report the rule being used to expand the instructions */
1338
  if (options.trace.rule_selection)
1339
    {
1340
      print_gen_entry_path (table->opcode_rule->line, table, notify);
1341
      notify (NULL,
1342
              ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
1343
              table->opcode->word_nr,
1344
              i2target (options.hi_bit_nr, table->opcode->first),
1345
              i2target (options.hi_bit_nr, table->opcode->last),
1346
              i2target (options.hi_bit_nr, table->opcode_rule->first),
1347
              i2target (options.hi_bit_nr, table->opcode_rule->last),
1348
              table->opcode->nr_opcodes,
1349
              table->nr_entries);
1350
    }
1351
 
1352
  /* expand the raw instructions according to the opcode */
1353
  {
1354
    insn_list *entry;
1355
    for (entry = table->insns; entry != NULL; entry = entry->next)
1356
      {
1357
        if (options.trace.insn_expansion)
1358
          {
1359
            print_gen_entry_path (table->opcode_rule->line, table, notify);
1360
            notify (NULL, ": expand - %s.%s\n",
1361
                    entry->insn->format_name,
1362
                    entry->insn->name);
1363
          }
1364
        gen_entry_insert_expanding (table, entry->insn);
1365
      }
1366
  }
1367
 
1368
  /* dump the results */
1369
  if (options.trace.entries)
1370
    {
1371
      gen_entry *entry;
1372
      for (entry = table->entries; entry != NULL; entry = entry->sibling)
1373
        {
1374
          insn_list *l;
1375
          print_gen_entry_path (table->opcode_rule->line, entry, notify);
1376
          notify (NULL, ": %d - entries %d -",
1377
                  entry->opcode_nr,
1378
                  entry->nr_insns);
1379
          for (l = entry->insns; l != NULL; l = l->next)
1380
            notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);
1381
          notify (NULL, "\n");
1382
        }
1383
    }
1384
 
1385
  /* perform a combine pass if needed */
1386
  if (table->opcode_rule->with_combine)
1387
    {
1388
      gen_entry *entry;
1389
      for (entry = table->entries; entry != NULL; entry = entry->sibling)
1390
        {
1391
          if (entry->combined_parent == NULL)
1392
            {
1393
              gen_entry **last = &entry->combined_next;
1394
              gen_entry *alt;
1395
              for (alt = entry->sibling; alt != NULL; alt = alt->sibling)
1396
                {
1397
                  if (alt->combined_parent == NULL
1398
                      && insn_list_cmp (entry->insns, alt->insns) == 0)
1399
                    {
1400
                      alt->combined_parent = entry;
1401
                      *last = alt;
1402
                      last = &alt->combined_next;
1403
                    }
1404
                }
1405
            }
1406
        }
1407
      if (options.trace.combine)
1408
        {
1409
          int nr_unique = 0;
1410
          gen_entry *entry;
1411
          for (entry = table->entries; entry != NULL; entry = entry->sibling)
1412
            {
1413
              if (entry->combined_parent == NULL)
1414
                {
1415
                  insn_list *l;
1416
                  gen_entry *duplicate;
1417
                  nr_unique++;
1418
                  print_gen_entry_path (table->opcode_rule->line, entry, notify);
1419
                  for (duplicate = entry->combined_next;
1420
                       duplicate != NULL;
1421
                       duplicate = duplicate->combined_next)
1422
                    {
1423
                      notify (NULL, "+%d", duplicate->opcode_nr);
1424
                    }
1425
                  notify (NULL, ": entries %d -", entry->nr_insns);
1426
                  for (l = entry->insns; l != NULL; l = l->next)
1427
                    {
1428
                      notify (NULL, " %s.%s",
1429
                              l->insn->format_name,
1430
                              l->insn->name);
1431
                    }
1432
                  notify (NULL, "\n");
1433
                }
1434
            }
1435
          print_gen_entry_path (table->opcode_rule->line, table, notify);
1436
          notify (NULL, ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
1437
                  table->opcode->word_nr,
1438
                  i2target (options.hi_bit_nr, table->opcode->first),
1439
                  i2target (options.hi_bit_nr, table->opcode->last),
1440
                  i2target (options.hi_bit_nr, table->opcode_rule->first),
1441
                  i2target (options.hi_bit_nr, table->opcode_rule->last),
1442
                  table->opcode->nr_opcodes,
1443
                  table->nr_entries,
1444
                  nr_unique);
1445
        }
1446
    }
1447
 
1448
  /* Check that the rule did more than re-arange the order of the
1449
     instructions */
1450
  {
1451
      gen_entry *entry;
1452
      for (entry = table->entries; entry != NULL; entry = entry->sibling)
1453
        {
1454
          if (entry->combined_parent == NULL)
1455
            {
1456
              if (insn_list_cmp (table->insns, entry->insns) == 0)
1457
                {
1458
                  print_gen_entry_path (table->opcode_rule->line, table, warning);
1459
                  warning (NULL, ": Applying rule just copied all instructions\n");
1460
                  print_gen_entry_insns (entry, warning, "Copied", NULL);
1461
                  error (NULL, "");
1462
                }
1463
            }
1464
        }
1465
  }
1466
 
1467
  /* if some form of expanded table, fill in the missing dots */
1468
  switch (table->opcode_rule->gen)
1469
    {
1470
    case padded_switch_gen:
1471
    case array_gen:
1472
    case goto_switch_gen:
1473
      if (!table->opcode->is_boolean)
1474
        {
1475
          gen_entry **entry = &table->entries;
1476
          gen_entry *illegals = NULL;
1477
          gen_entry **last_illegal = &illegals;
1478
          int opcode_nr = 0;
1479
          while (opcode_nr < table->opcode->nr_opcodes)
1480
            {
1481
              if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)
1482
                {
1483
                  /* missing - insert it under our feet at *entry */
1484
                  gen_entry_insert_insn (table,
1485
                                         table->top->isa->illegal_insn,
1486
                                         table->opcode->word_nr,
1487
                                         0, /* nr_prefetched_words == 0 for invalid */
1488
                                         opcode_nr, NULL);
1489
                  ASSERT ((*entry) != NULL);
1490
                  ASSERT ((*entry)->opcode_nr == opcode_nr);
1491
                  (*last_illegal) = *entry;
1492
                  (*last_illegal)->combined_parent = illegals;
1493
                  last_illegal = &(*last_illegal)->combined_next;
1494
                }
1495
              entry = &(*entry)->sibling;
1496
              opcode_nr++;
1497
            }
1498
          /* oops, will have pointed the first illegal insn back to
1499
             its self.  Fix this */
1500
          if (illegals != NULL)
1501
            illegals->combined_parent = NULL;
1502
        }
1503
      break;
1504
    case switch_gen:
1505
    case invalid_gen:
1506
      /* ignore */
1507
      break;
1508
    }
1509
 
1510
  /* and do the same for the newly created sub entries but *only*
1511
     expand entries that haven't been combined. */
1512
  {
1513
    gen_entry *entry;
1514
    for (entry = table->entries; entry != NULL; entry =  entry->sibling)
1515
      {
1516
        if (entry->combined_parent == NULL)
1517
          {
1518
            gen_entry_expand_insns (entry);
1519
          }
1520
      }
1521
  }
1522
}
1523
 
1524
void
1525
gen_tables_expand_insns (gen_table *gen)
1526
{
1527
  gen_list *entry;
1528
  for (entry = gen->tables; entry != NULL; entry = entry->next)
1529
    {
1530
      gen_entry_expand_insns (entry->table);
1531
    }
1532
}
1533
 
1534
 
1535
/* create a list of all the semantic functions that need to be
1536
   generated.  Eliminate any duplicates. Verify that the decode stage
1537
   worked. */
1538
 
1539
static void
1540
make_gen_semantics_list (lf *file,
1541
                         gen_entry *entry,
1542
                         int depth,
1543
                         void *data)
1544
{
1545
  gen_table *gen = (gen_table*) data;
1546
  insn_list *insn;
1547
  /* Not interested in an entrie that have been combined into some
1548
     other entry at the same level */
1549
  if (entry->combined_parent != NULL)
1550
    return;
1551
 
1552
  /* a leaf should contain exactly one instruction. If not the decode
1553
     stage failed. */
1554
  ASSERT (entry->nr_insns == 1);
1555
 
1556
  /* Enter this instruction into the list of semantic functions. */
1557
  insn = insn_list_insert (&gen->semantics, &gen->nr_semantics,
1558
                           entry->insns->insn,
1559
                           entry->expanded_bits,
1560
                           entry->parent->opcode,
1561
                           entry->insns->nr_prefetched_words,
1562
                           merge_duplicate_insns);
1563
  /* point the table entry at the real semantic function */
1564
  ASSERT (insn != NULL);
1565
  entry->insns->semantic = insn;
1566
}
1567
 
1568
 
1569
void
1570
gen_tables_expand_semantics (gen_table *gen)
1571
{
1572
  gen_list *entry;
1573
  for (entry = gen->tables; entry != NULL; entry = entry->next)
1574
    {
1575
      gen_entry_traverse_tree (NULL,
1576
                               entry->table,
1577
                               1, /* depth */
1578
                               NULL, /* start-handler */
1579
                               make_gen_semantics_list, /* leaf-handler */
1580
                               NULL, /* end-handler */
1581
                               gen); /* data */
1582
  }
1583
}
1584
 
1585
 
1586
 
1587
#ifdef MAIN
1588
 
1589
 
1590
static void
1591
dump_opcode_field (lf *file,
1592
                   char *prefix,
1593
                   opcode_field *field,
1594
                   char *suffix,
1595
                   int levels)
1596
{
1597
  lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field);
1598
  if (levels && field != NULL) {
1599
    lf_indent (file, +1);
1600
    lf_printf (file, "\n(first %d)", field->first);
1601
    lf_printf (file, "\n(last %d)", field->last);
1602
    lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
1603
    lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
1604
    lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
1605
    dump_opcode_field(file, "\n(parent ", field->parent, ")", levels - 1);
1606
    lf_indent (file, -1);
1607
  }
1608
  lf_printf (file, "%s", suffix);
1609
}
1610
 
1611
 
1612
static void
1613
dump_opcode_bits (lf *file,
1614
                  char *prefix,
1615
                  opcode_bits *bits,
1616
                  char *suffix,
1617
                  int levels)
1618
{
1619
  lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits);
1620
 
1621
  if (levels && bits != NULL)
1622
    {
1623
      lf_indent (file, +1);
1624
      lf_printf (file, "\n(value %d)", bits->value);
1625
      dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0);
1626
      dump_insn_field (file, "\n(field ", bits->field, ")");
1627
      dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1);
1628
      lf_indent (file, -1);
1629
    }
1630
  lf_printf (file, "%s", suffix);
1631
}
1632
 
1633
 
1634
 
1635
static void
1636
dump_insn_list (lf *file,
1637
                char *prefix,
1638
                insn_list *entry,
1639
                char *suffix)
1640
{
1641
  lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry);
1642
 
1643
  if (entry != NULL) {
1644
    lf_indent (file, +1);
1645
    dump_insn_entry (file, "\n(insn ", entry->insn, ")");
1646
    lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1647
    lf_indent (file, -1);
1648
  }
1649
  lf_printf (file, "%s", suffix);
1650
}
1651
 
1652
 
1653
static void
1654
dump_insn_word_entry_list_entries (lf *file,
1655
                               char *prefix,
1656
                               insn_list *entry,
1657
                               char *suffix)
1658
{
1659
  lf_printf (file, "%s", prefix);
1660
  while (entry != NULL)
1661
    {
1662
      dump_insn_list (file, "\n(", entry, ")");
1663
      entry = entry->next;
1664
    }
1665
  lf_printf (file, "%s", suffix);
1666
}
1667
 
1668
 
1669
static void
1670
dump_gen_entry (lf *file,
1671
                char *prefix,
1672
                gen_entry *table,
1673
                char *suffix,
1674
                int levels)
1675
{
1676
 
1677
  lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table);
1678
 
1679
  if (levels && table != NULL) {
1680
 
1681
    lf_indent (file, +1);
1682
    lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
1683
    lf_printf (file, "\n(word_nr %d)", table->word_nr);
1684
    dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", -1);
1685
    lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
1686
    dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, ")");
1687
    dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
1688
    dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
1689
    lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
1690
    dump_gen_entry (file, "\n(entries ", table->entries, ")", table->nr_entries);
1691
    dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
1692
    dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
1693
    lf_indent (file, -1);
1694
  }
1695
  lf_printf (file, "%s", suffix);
1696
}
1697
 
1698
static void
1699
dump_gen_list (lf *file,
1700
               char *prefix,
1701
               gen_list *entry,
1702
               char *suffix,
1703
               int levels)
1704
{
1705
  while (entry != NULL)
1706
    {
1707
      lf_printf (file, "%s(gen_list *) 0x%lx", prefix, (long) entry);
1708
      dump_gen_entry (file, "\n(", entry->table, ")", levels);
1709
      lf_printf (file, "\n(next (gen_list *) 0x%lx)", (long) entry->next);
1710
      lf_printf (file, "%s", suffix);
1711
    }
1712
}
1713
 
1714
 
1715
static void
1716
dump_gen_table (lf *file,
1717
                char *prefix,
1718
                gen_table *gen,
1719
                char *suffix,
1720
                int levels)
1721
{
1722
  lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen);
1723
  lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa);
1724
  lf_printf (file, "\n(rules (decode_table *) 0x%lx)", (long) gen->rules);
1725
  dump_gen_list (file, "\n(", gen->tables, ")", levels);
1726
  lf_printf (file, "%s", suffix);
1727
}
1728
 
1729
 
1730
igen_options options;
1731
 
1732
int
1733
main (int argc,
1734
      char **argv)
1735
{
1736
  decode_table *decode_rules;
1737
  insn_table *instructions;
1738
  gen_table *gen;
1739
  lf *l;
1740
 
1741
  if (argc != 7)
1742
    error (NULL, "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
1743
 
1744
  INIT_OPTIONS (options);
1745
 
1746
  filter_parse (&options.flags_filter, argv[1]);
1747
 
1748
  options.hi_bit_nr = a2i(argv[2]);
1749
  options.insn_bit_size = a2i(argv[3]);
1750
  options.insn_specifying_widths = a2i(argv[4]);
1751
  ASSERT(options.hi_bit_nr < options.insn_bit_size);
1752
 
1753
  instructions = load_insn_table (argv[6], NULL);
1754
  decode_rules = load_decode_table (argv[5]);
1755
  gen = make_gen_tables (instructions, decode_rules);
1756
 
1757
  gen_tables_expand_insns (gen);
1758
 
1759
  l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1760
 
1761
  dump_gen_table (l, "(", gen, ")\n", -1);
1762
  return 0;
1763
}
1764
 
1765
#endif

powered by: WebSVN 2.1.0

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