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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [igen/] [gen.c] - Blame information for rev 26

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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