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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [ppc/] [ld-insn.c] - Blame information for rev 106

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

Line No. Rev Author Line
1 106 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994,1995,1996, Andrew Cagney <cagney@highland.com.au>
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
19
    */
20
 
21
 
22
#include "misc.h"
23
#include "lf.h"
24
#include "table.h"
25
#include "filter.h"
26
#include "ld-decode.h"
27
#include "ld-cache.h"
28
#include "ld-insn.h"
29
 
30
#include "igen.h"
31
 
32
static void
33
update_depth(insn_table *entry,
34
             lf *file,
35
             void *data,
36
             insn *instruction,
37
             int depth)
38
{
39
  int *max_depth = (int*)data;
40
  if (*max_depth < depth)
41
    *max_depth = depth;
42
}
43
 
44
 
45
int
46
insn_table_depth(insn_table *table)
47
{
48
  int depth = 0;
49
  insn_table_traverse_tree(table,
50
                           NULL,
51
                           &depth,
52
                           1,
53
                           NULL, /*start*/
54
                           update_depth,
55
                           NULL, /*end*/
56
                           NULL); /*padding*/
57
  return depth;
58
}
59
 
60
 
61
static insn_fields *
62
parse_insn_format(table_entry *entry,
63
                  char *format)
64
{
65
  char *chp;
66
  insn_fields *fields = ZALLOC(insn_fields);
67
 
68
  /* create a leading sentinal */
69
  fields->first = ZALLOC(insn_field);
70
  fields->first->first = -1;
71
  fields->first->last = -1;
72
  fields->first->width = 0;
73
 
74
  /* and a trailing sentinal */
75
  fields->last = ZALLOC(insn_field);
76
  fields->last->first = insn_bit_size;
77
  fields->last->last = insn_bit_size;
78
  fields->last->width = 0;
79
 
80
  /* link them together */
81
  fields->first->next = fields->last;
82
  fields->last->prev = fields->first;
83
 
84
  /* now work through the formats */
85
  chp = format;
86
 
87
  while (*chp != '\0') {
88
    char *start_pos;
89
    char *start_val;
90
    int strlen_val;
91
    int strlen_pos;
92
    insn_field *new_field;
93
 
94
    /* sanity check */
95
    if (!isdigit(*chp)) {
96
      error("%s:%d: missing position field at `%s'\n",
97
            entry->file_name, entry->line_nr, chp);
98
    }
99
 
100
    /* break out the bit position */
101
    start_pos = chp;
102
    while (isdigit(*chp))
103
      chp++;
104
    strlen_pos = chp - start_pos;
105
    if (*chp == '.' && strlen_pos > 0)
106
      chp++;
107
    else {
108
      error("%s:%d: missing field value at %s\n",
109
            entry->file_name, entry->line_nr, chp);
110
      break;
111
    }
112
 
113
    /* break out the value */
114
    start_val = chp;
115
    while ((*start_val == '/' && *chp == '/')
116
           || (isdigit(*start_val) && isdigit(*chp))
117
           || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_')))
118
      chp++;
119
    strlen_val = chp - start_val;
120
    if (*chp == ',')
121
      chp++;
122
    else if (*chp != '\0' || strlen_val == 0) {
123
      error("%s:%d: missing field terminator at %s\n",
124
            entry->file_name, entry->line_nr, chp);
125
      break;
126
    }
127
 
128
    /* create a new field and insert it */
129
    new_field = ZALLOC(insn_field);
130
    new_field->next = fields->last;
131
    new_field->prev = fields->last->prev;
132
    new_field->next->prev = new_field;
133
    new_field->prev->next = new_field;
134
 
135
    /* the value */
136
    new_field->val_string = (char*)zalloc(strlen_val+1);
137
    strncpy(new_field->val_string, start_val, strlen_val);
138
    if (isdigit(*new_field->val_string)) {
139
      new_field->val_int = a2i(new_field->val_string);
140
      new_field->is_int = 1;
141
    }
142
    else if (new_field->val_string[0] == '/') {
143
      new_field->is_slash = 1;
144
    }
145
    else {
146
      new_field->is_string = 1;
147
    }
148
 
149
    /* the pos */
150
    new_field->pos_string = (char*)zalloc(strlen_pos+1);
151
    strncpy(new_field->pos_string, start_pos, strlen_pos);
152
    new_field->first = target_a2i(hi_bit_nr, new_field->pos_string);
153
    new_field->last = new_field->next->first - 1; /* guess */
154
    new_field->width = new_field->last - new_field->first + 1; /* guess */
155
    new_field->prev->last = new_field->first-1; /*fix*/
156
    new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
157
  }
158
 
159
  /* fiddle first/last so that the sentinals `disapear' */
160
  ASSERT(fields->first->last < 0);
161
  ASSERT(fields->last->first >= insn_bit_size);
162
  fields->first = fields->first->next;
163
  fields->last = fields->last->prev;
164
 
165
  /* now go over this again, pointing each bit position at a field
166
     record */
167
  {
168
    int i;
169
    insn_field *field;
170
    field = fields->first;
171
    for (i = 0; i < insn_bit_size; i++) {
172
      while (field->last < i)
173
        field = field->next;
174
      fields->bits[i] = field;
175
    }
176
  }
177
 
178
  /* go over each of the fields, and compute a `value' for the insn */
179
  {
180
    insn_field *field;
181
    fields->value = 0;
182
    for (field = fields->first;
183
         field->last < insn_bit_size;
184
         field = field->next) {
185
      fields->value <<= field->width;
186
      if (field->is_int)
187
        fields->value |= field->val_int;
188
    }
189
  }
190
  return fields;
191
}
192
 
193
 
194
static void
195
model_table_insert(insn_table *table,
196
                   table_entry *file_entry)
197
{
198
  int len;
199
 
200
  /* create a new model */
201
  model *new_model = ZALLOC(model);
202
 
203
  new_model->name = file_entry->fields[model_identifer];
204
  new_model->printable_name = file_entry->fields[model_name];
205
  new_model->insn_default = file_entry->fields[model_default];
206
 
207
  while (*new_model->insn_default && isspace(*new_model->insn_default))
208
    new_model->insn_default++;
209
 
210
  len = strlen(new_model->insn_default);
211
  if (max_model_fields_len < len)
212
    max_model_fields_len = len;
213
 
214
  /* append it to the end of the model list */
215
  if (last_model)
216
    last_model->next = new_model;
217
  else
218
    models = new_model;
219
  last_model = new_model;
220
}
221
 
222
static void
223
model_table_insert_specific(insn_table *table,
224
                            table_entry *file_entry,
225
                            insn **start_ptr,
226
                            insn **end_ptr)
227
{
228
  insn *ptr = ZALLOC(insn);
229
  ptr->file_entry = file_entry;
230
  if (*end_ptr)
231
    (*end_ptr)->next = ptr;
232
  else
233
    (*start_ptr) = ptr;
234
  (*end_ptr) = ptr;
235
}
236
 
237
 
238
static void
239
insn_table_insert_function(insn_table *table,
240
                           table_entry *file_entry)
241
{
242
  /* create a new function */
243
  insn *new_function = ZALLOC(insn);
244
  new_function->file_entry = file_entry;
245
 
246
  /* append it to the end of the function list */
247
  if (table->last_function)
248
    table->last_function->next = new_function;
249
  else
250
    table->functions = new_function;
251
  table->last_function = new_function;
252
}
253
 
254
extern void
255
insn_table_insert_insn(insn_table *table,
256
                       table_entry *file_entry,
257
                       insn_fields *fields)
258
{
259
  insn **ptr_to_cur_insn = &table->insns;
260
  insn *cur_insn = *ptr_to_cur_insn;
261
  table_model_entry *insn_model_ptr;
262
  model *model_ptr;
263
 
264
  /* create a new instruction */
265
  insn *new_insn = ZALLOC(insn);
266
  new_insn->file_entry = file_entry;
267
  new_insn->fields = fields;
268
 
269
  /* Check out any model information returned to make sure the model
270
     is correct.  */
271
  for(insn_model_ptr = file_entry->model_first; insn_model_ptr; insn_model_ptr = insn_model_ptr->next) {
272
    char *name = insn_model_ptr->fields[insn_model_name];
273
    int len = strlen (insn_model_ptr->fields[insn_model_fields]);
274
 
275
    while (len > 0 && isspace(*insn_model_ptr->fields[insn_model_fields])) {
276
      len--;
277
      insn_model_ptr->fields[insn_model_fields]++;
278
    }
279
 
280
    if (max_model_fields_len < len)
281
      max_model_fields_len = len;
282
 
283
    for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
284
      if (strcmp(name, model_ptr->printable_name) == 0) {
285
 
286
        /* Replace the name field with that of the global model, so that when we
287
           want to print it out, we can just compare pointers.  */
288
        insn_model_ptr->fields[insn_model_name] = model_ptr->printable_name;
289
        break;
290
      }
291
    }
292
 
293
    if (!model_ptr)
294
      error("%s:%d: machine model `%s' was not known about\n",
295
            file_entry->file_name, file_entry->line_nr, name);
296
  }
297
 
298
  /* insert it according to the order of the fields */
299
  while (cur_insn != NULL
300
         && new_insn->fields->value >= cur_insn->fields->value) {
301
    ptr_to_cur_insn = &cur_insn->next;
302
    cur_insn = *ptr_to_cur_insn;
303
  }
304
 
305
  new_insn->next = cur_insn;
306
  *ptr_to_cur_insn = new_insn;
307
 
308
  table->nr_insn++;
309
}
310
 
311
 
312
 
313
insn_table *
314
load_insn_table(const char *file_name,
315
                decode_table *decode_rules,
316
                filter *filters)
317
{
318
  table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
319
  insn_table *table = ZALLOC(insn_table);
320
  table_entry *file_entry;
321
  table->opcode_rule = decode_rules;
322
 
323
  while ((file_entry = table_entry_read(file)) != NULL) {
324
    if (it_is("function", file_entry->fields[insn_flags])
325
        || it_is("internal", file_entry->fields[insn_flags])) {
326
      insn_table_insert_function(table, file_entry);
327
    }
328
    else if (it_is("model", file_entry->fields[insn_flags])) {
329
      model_table_insert(table, file_entry);
330
    }
331
    else if (it_is("model-macro", file_entry->fields[insn_flags])) {
332
      model_table_insert_specific(table, file_entry, &model_macros, &last_model_macro);
333
    }
334
    else if (it_is("model-function", file_entry->fields[insn_flags])) {
335
      model_table_insert_specific(table, file_entry, &model_functions, &last_model_function);
336
    }
337
    else if (it_is("model-internal", file_entry->fields[insn_flags])) {
338
      model_table_insert_specific(table, file_entry, &model_internal, &last_model_internal);
339
    }
340
    else if (it_is("model-static", file_entry->fields[insn_flags])) {
341
      model_table_insert_specific(table, file_entry, &model_static, &last_model_static);
342
    }
343
    else if (it_is("model-data", file_entry->fields[insn_flags])) {
344
      model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
345
    }
346
    else {
347
      insn_fields *fields;
348
      /* skip instructions that aren't relevant to the mode */
349
      if (is_filtered_out(file_entry->fields[insn_flags], filters)) {
350
        fprintf(stderr, "Dropping %s - %s\n",
351
                file_entry->fields[insn_name],
352
                file_entry->fields[insn_flags]);
353
      }
354
      else {
355
        /* create/insert the new instruction */
356
        fields = parse_insn_format(file_entry,
357
                                   file_entry->fields[insn_format]);
358
        insn_table_insert_insn(table, file_entry, fields);
359
      }
360
    }
361
  }
362
  return table;
363
}
364
 
365
 
366
extern void
367
insn_table_traverse_tree(insn_table *table,
368
                         lf *file,
369
                         void *data,
370
                         int depth,
371
                         leaf_handler *start,
372
                         insn_handler *leaf,
373
                         leaf_handler *end,
374
                         padding_handler *padding)
375
{
376
  insn_table *entry;
377
  int entry_nr;
378
 
379
  ASSERT(table != NULL
380
         && table->opcode != NULL
381
         && table->nr_entries > 0
382
         && table->entries != 0);
383
 
384
  if (start != NULL && depth >= 0)
385
    start(table, file, data, depth);
386
 
387
  for (entry_nr = 0, entry = table->entries;
388
       entry_nr < (table->opcode->is_boolean
389
                   ? 2
390
                   : (1 << (table->opcode->last - table->opcode->first + 1)));
391
       entry_nr ++) {
392
    if (entry == NULL
393
        || (!table->opcode->is_boolean
394
            && entry_nr < entry->opcode_nr)) {
395
      if (padding != NULL && depth >= 0)
396
        padding(table, file, data, depth, entry_nr);
397
    }
398
    else {
399
      ASSERT(entry != NULL && (entry->opcode_nr == entry_nr
400
                               || table->opcode->is_boolean));
401
      if (entry->opcode != NULL && depth != 0) {
402
        insn_table_traverse_tree(entry, file, data, depth+1,
403
                                 start, leaf, end, padding);
404
      }
405
      else if (depth >= 0) {
406
        if (leaf != NULL)
407
          leaf(entry, file, data, entry->insns, depth);
408
      }
409
      entry = entry->sibling;
410
    }
411
  }
412
  if (end != NULL && depth >= 0)
413
    end(table, file, data, depth);
414
}
415
 
416
 
417
extern void
418
insn_table_traverse_function(insn_table *table,
419
                             lf *file,
420
                             void *data,
421
                             function_handler *leaf)
422
{
423
  insn *function;
424
  for (function = table->functions;
425
       function != NULL;
426
       function = function->next) {
427
    leaf(table, file, data, function->file_entry);
428
  }
429
}
430
 
431
extern void
432
insn_table_traverse_insn(insn_table *table,
433
                         lf *file,
434
                         void *data,
435
                         insn_handler *handler)
436
{
437
  insn *instruction;
438
  for (instruction = table->insns;
439
       instruction != NULL;
440
       instruction = instruction->next) {
441
    handler(table, file, data, instruction, 0);
442
  }
443
}
444
 
445
 
446
/****************************************************************/
447
 
448
typedef enum {
449
  field_constant_int = 1,
450
  field_constant_slash = 2,
451
  field_constant_string = 3
452
} constant_field_types;
453
 
454
 
455
static int
456
insn_field_is_constant(insn_field *field,
457
                       decode_table *rule)
458
{
459
  /* field is an integer */
460
  if (field->is_int)
461
    return field_constant_int;
462
  /* field is `/' and treating that as a constant */
463
  if (field->is_slash && rule->force_slash)
464
    return field_constant_slash;
465
  /* field, though variable is on the list */
466
  if (field->is_string && rule->force_expansion != NULL) {
467
    char *forced_fields = rule->force_expansion;
468
    while (*forced_fields != '\0') {
469
      int field_len;
470
      char *end = strchr(forced_fields, ',');
471
      if (end == NULL)
472
        field_len = strlen(forced_fields);
473
      else
474
        field_len = end-forced_fields;
475
      if (strncmp(forced_fields, field->val_string, field_len) == 0
476
          && field->val_string[field_len] == '\0')
477
        return field_constant_string;
478
      forced_fields += field_len;
479
      if (*forced_fields == ',')
480
        forced_fields++;
481
    }
482
  }
483
  return 0;
484
}
485
 
486
 
487
static opcode_field *
488
insn_table_find_opcode_field(insn *insns,
489
                             decode_table *rule,
490
                             int string_only)
491
{
492
  opcode_field *curr_opcode = ZALLOC(opcode_field);
493
  insn *entry;
494
  ASSERT(rule);
495
 
496
  curr_opcode->first = insn_bit_size;
497
  curr_opcode->last = -1;
498
  for (entry = insns; entry != NULL; entry = entry->next) {
499
    insn_fields *fields = entry->fields;
500
    opcode_field new_opcode;
501
 
502
    /* find a start point for the opcode field */
503
    new_opcode.first = rule->first;
504
    while (new_opcode.first <= rule->last
505
           && (!string_only
506
               || insn_field_is_constant(fields->bits[new_opcode.first],
507
                                         rule) != field_constant_string)
508
           && (string_only
509
               || !insn_field_is_constant(fields->bits[new_opcode.first],
510
                                          rule)))
511
      new_opcode.first = fields->bits[new_opcode.first]->last + 1;
512
    ASSERT(new_opcode.first > rule->last
513
           || (string_only
514
               && insn_field_is_constant(fields->bits[new_opcode.first],
515
                                         rule) == field_constant_string)
516
           || (!string_only
517
               && insn_field_is_constant(fields->bits[new_opcode.first],
518
                                         rule)));
519
 
520
    /* find the end point for the opcode field */
521
    new_opcode.last = rule->last;
522
    while (new_opcode.last >= rule->first
523
           && (!string_only
524
               || insn_field_is_constant(fields->bits[new_opcode.last],
525
                                         rule) != field_constant_string)
526
           && (string_only
527
               || !insn_field_is_constant(fields->bits[new_opcode.last],
528
                                          rule)))
529
      new_opcode.last = fields->bits[new_opcode.last]->first - 1;
530
    ASSERT(new_opcode.last < rule->first
531
           || (string_only
532
               && insn_field_is_constant(fields->bits[new_opcode.last],
533
                                         rule) == field_constant_string)
534
           || (!string_only
535
               && insn_field_is_constant(fields->bits[new_opcode.last],
536
                                         rule)));
537
 
538
    /* now see if our current opcode needs expanding */
539
    if (new_opcode.first <= rule->last
540
        && curr_opcode->first > new_opcode.first)
541
      curr_opcode->first = new_opcode.first;
542
    if (new_opcode.last >= rule->first
543
        && curr_opcode->last < new_opcode.last)
544
      curr_opcode->last = new_opcode.last;
545
 
546
  }
547
 
548
  /* was any thing interesting found? */
549
  if (curr_opcode->first > rule->last) {
550
    ASSERT(curr_opcode->last < rule->first);
551
    return NULL;
552
  }
553
  ASSERT(curr_opcode->last >= rule->first);
554
  ASSERT(curr_opcode->first <= rule->last);
555
 
556
  /* if something was found, check it includes the forced field range */
557
  if (!string_only
558
      && curr_opcode->first > rule->force_first) {
559
    curr_opcode->first = rule->force_first;
560
  }
561
  if (!string_only
562
      && curr_opcode->last < rule->force_last) {
563
    curr_opcode->last = rule->force_last;
564
  }
565
  /* handle special case elminating any need to do shift after mask */
566
  if (string_only
567
      && rule->force_last == insn_bit_size-1) {
568
    curr_opcode->last = insn_bit_size-1;
569
  }
570
 
571
  /* handle any special cases */
572
  switch (rule->type) {
573
  case normal_decode_rule:
574
    /* let the above apply */
575
    break;
576
  case expand_forced_rule:
577
    /* expand a limited nr of bits, ignoring the rest */
578
    curr_opcode->first = rule->force_first;
579
    curr_opcode->last = rule->force_last;
580
    break;
581
  case boolean_rule:
582
    curr_opcode->is_boolean = 1;
583
    curr_opcode->boolean_constant = rule->special_constant;
584
    break;
585
  default:
586
    error("Something is going wrong\n");
587
  }
588
 
589
  return curr_opcode;
590
}
591
 
592
 
593
static void
594
insn_table_insert_expanded(insn_table *table,
595
                           insn *old_insn,
596
                           int new_opcode_nr,
597
                           insn_bits *new_bits)
598
{
599
  insn_table **ptr_to_cur_entry = &table->entries;
600
  insn_table *cur_entry = *ptr_to_cur_entry;
601
 
602
  /* find the new table for this entry */
603
  while (cur_entry != NULL
604
         && cur_entry->opcode_nr < new_opcode_nr) {
605
    ptr_to_cur_entry = &cur_entry->sibling;
606
    cur_entry = *ptr_to_cur_entry;
607
  }
608
 
609
  if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {
610
    insn_table *new_entry = ZALLOC(insn_table);
611
    new_entry->opcode_nr = new_opcode_nr;
612
    new_entry->expanded_bits = new_bits;
613
    new_entry->opcode_rule = table->opcode_rule->next;
614
    new_entry->sibling = cur_entry;
615
    new_entry->parent = table;
616
    *ptr_to_cur_entry = new_entry;
617
    cur_entry = new_entry;
618
    table->nr_entries++;
619
  }
620
  /* ASSERT new_bits == cur_entry bits */
621
  ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);
622
  insn_table_insert_insn(cur_entry,
623
                         old_insn->file_entry,
624
                         old_insn->fields);
625
}
626
 
627
static void
628
insn_table_expand_opcode(insn_table *table,
629
                         insn *instruction,
630
                         int field_nr,
631
                         int opcode_nr,
632
                         insn_bits *bits)
633
{
634
 
635
  if (field_nr > table->opcode->last) {
636
    insn_table_insert_expanded(table, instruction, opcode_nr, bits);
637
  }
638
  else {
639
    insn_field *field = instruction->fields->bits[field_nr];
640
    if (field->is_int || field->is_slash) {
641
      ASSERT(field->first >= table->opcode->first
642
             && field->last <= table->opcode->last);
643
      insn_table_expand_opcode(table, instruction, field->last+1,
644
                               ((opcode_nr << field->width) + field->val_int),
645
                               bits);
646
    }
647
    else {
648
      int val;
649
      int last_pos = ((field->last < table->opcode->last)
650
                        ? field->last : table->opcode->last);
651
      int first_pos = ((field->first > table->opcode->first)
652
                         ? field->first : table->opcode->first);
653
      int width = last_pos - first_pos + 1;
654
      int last_val = (table->opcode->is_boolean
655
                      ? 2 : (1 << width));
656
      for (val = 0; val < last_val; val++) {
657
        insn_bits *new_bits = ZALLOC(insn_bits);
658
        new_bits->field = field;
659
        new_bits->value = val;
660
        new_bits->last = bits;
661
        new_bits->opcode = table->opcode;
662
        insn_table_expand_opcode(table, instruction, last_pos+1,
663
                                 ((opcode_nr << width) | val),
664
                                 new_bits);
665
      }
666
    }
667
  }
668
}
669
 
670
static void
671
insn_table_insert_expanding(insn_table *table,
672
                            insn *entry)
673
{
674
  insn_table_expand_opcode(table,
675
                           entry,
676
                           table->opcode->first,
677
                           0,
678
                           table->expanded_bits);
679
}
680
 
681
 
682
extern void
683
insn_table_expand_insns(insn_table *table)
684
{
685
 
686
  ASSERT(table->nr_insn >= 1);
687
 
688
  /* determine a valid opcode */
689
  while (table->opcode_rule) {
690
    /* specials only for single instructions */
691
    if ((table->nr_insn > 1
692
         && table->opcode_rule->special_mask == 0
693
         && table->opcode_rule->type == normal_decode_rule)
694
        || (table->nr_insn == 1
695
            && table->opcode_rule->special_mask != 0
696
            && ((table->insns->fields->value
697
                 & table->opcode_rule->special_mask)
698
                == table->opcode_rule->special_value))
699
        || (generate_expanded_instructions
700
            && table->opcode_rule->special_mask == 0
701
            && table->opcode_rule->type == normal_decode_rule))
702
      table->opcode =
703
        insn_table_find_opcode_field(table->insns,
704
                                     table->opcode_rule,
705
                                     table->nr_insn == 1/*string*/
706
                                     );
707
    if (table->opcode != NULL)
708
      break;
709
    table->opcode_rule = table->opcode_rule->next;
710
  }
711
 
712
  /* did we find anything */
713
  if (table->opcode == NULL) {
714
    return;
715
  }
716
  ASSERT(table->opcode != NULL);
717
 
718
  /* back link what we found to its parent */
719
  if (table->parent != NULL) {
720
    ASSERT(table->parent->opcode != NULL);
721
    table->opcode->parent = table->parent->opcode;
722
  }
723
 
724
  /* expand the raw instructions according to the opcode */
725
  {
726
    insn *entry;
727
    for (entry = table->insns; entry != NULL; entry = entry->next) {
728
      insn_table_insert_expanding(table, entry);
729
    }
730
  }
731
 
732
  /* and do the same for the sub entries */
733
  {
734
    insn_table *entry;
735
    for (entry = table->entries; entry != NULL; entry =  entry->sibling) {
736
      insn_table_expand_insns(entry);
737
    }
738
  }
739
}
740
 
741
 
742
 
743
 
744
#ifdef MAIN
745
 
746
static void
747
dump_insn_field(insn_field *field,
748
                int indent)
749
{
750
 
751
  printf("(insn_field*)0x%x\n", (unsigned)field);
752
 
753
  dumpf(indent, "(first %d)\n", field->first);
754
 
755
  dumpf(indent, "(last %d)\n", field->last);
756
 
757
  dumpf(indent, "(width %d)\n", field->width);
758
 
759
  if (field->is_int)
760
    dumpf(indent, "(is_int %d)\n", field->val_int);
761
 
762
  if (field->is_slash)
763
    dumpf(indent, "(is_slash)\n");
764
 
765
  if (field->is_string)
766
    dumpf(indent, "(is_string `%s')\n", field->val_string);
767
 
768
  dumpf(indent, "(next 0x%x)\n", field->next);
769
 
770
  dumpf(indent, "(prev 0x%x)\n", field->prev);
771
 
772
 
773
}
774
 
775
static void
776
dump_insn_fields(insn_fields *fields,
777
                 int indent)
778
{
779
  int i;
780
 
781
  printf("(insn_fields*)%p\n", fields);
782
 
783
  dumpf(indent, "(first 0x%x)\n", fields->first);
784
  dumpf(indent, "(last 0x%x)\n", fields->last);
785
 
786
  dumpf(indent, "(value 0x%x)\n", fields->value);
787
 
788
  for (i = 0; i < insn_bit_size; i++) {
789
    dumpf(indent, "(bits[%d] ", i, fields->bits[i]);
790
    dump_insn_field(fields->bits[i], indent+1);
791
    dumpf(indent, " )\n");
792
  }
793
 
794
}
795
 
796
 
797
static void
798
dump_opcode_field(opcode_field *field, int indent, int levels)
799
{
800
  printf("(opcode_field*)%p\n", field);
801
  if (levels && field != NULL) {
802
    dumpf(indent, "(first %d)\n", field->first);
803
    dumpf(indent, "(last %d)\n", field->last);
804
    dumpf(indent, "(is_boolean %d)\n", field->is_boolean);
805
    dumpf(indent, "(parent ");
806
    dump_opcode_field(field->parent, indent, levels-1);
807
  }
808
}
809
 
810
 
811
static void
812
dump_insn_bits(insn_bits *bits, int indent, int levels)
813
{
814
  printf("(insn_bits*)%p\n", bits);
815
 
816
  if (levels && bits != NULL) {
817
    dumpf(indent, "(value %d)\n", bits->value);
818
    dumpf(indent, "(opcode ");
819
    dump_opcode_field(bits->opcode, indent+1, 0);
820
    dumpf(indent, " )\n");
821
    dumpf(indent, "(field ");
822
    dump_insn_field(bits->field, indent+1);
823
    dumpf(indent, " )\n");
824
    dumpf(indent, "(last ");
825
    dump_insn_bits(bits->last, indent+1, levels-1);
826
  }
827
}
828
 
829
 
830
 
831
static void
832
dump_insn(insn *entry, int indent, int levels)
833
{
834
  printf("(insn*)%p\n", entry);
835
 
836
  if (levels && entry != NULL) {
837
 
838
    dumpf(indent, "(file_entry ");
839
    dump_table_entry(entry->file_entry, indent+1);
840
    dumpf(indent, " )\n");
841
 
842
    dumpf(indent, "(fields ");
843
    dump_insn_fields(entry->fields, indent+1);
844
    dumpf(indent, " )\n");
845
 
846
    dumpf(indent, "(next ");
847
    dump_insn(entry->next, indent+1, levels-1);
848
    dumpf(indent, " )\n");
849
 
850
  }
851
 
852
}
853
 
854
 
855
static void
856
dump_insn_table(insn_table *table,
857
                int indent, int levels)
858
{
859
 
860
  printf("(insn_table*)%p\n", table);
861
 
862
  if (levels && table != NULL) {
863
 
864
    dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);
865
 
866
    dumpf(indent, "(expanded_bits ");
867
    dump_insn_bits(table->expanded_bits, indent+1, -1);
868
    dumpf(indent, " )\n");
869
 
870
    dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);
871
 
872
    dumpf(indent, "(insns ");
873
    dump_insn(table->insns, indent+1, table->nr_insn);
874
    dumpf(indent, " )\n");
875
 
876
    dumpf(indent, "(opcode_rule ");
877
    dump_decode_rule(table->opcode_rule, indent+1);
878
    dumpf(indent, " )\n");
879
 
880
    dumpf(indent, "(opcode ");
881
    dump_opcode_field(table->opcode, indent+1, 1);
882
    dumpf(indent, " )\n");
883
 
884
    dumpf(indent, "(nr_entries %d)\n", table->entries);
885
    dumpf(indent, "(entries ");
886
    dump_insn_table(table->entries, indent+1, table->nr_entries);
887
    dumpf(indent, " )\n");
888
 
889
    dumpf(indent, "(sibling ", table->sibling);
890
    dump_insn_table(table->sibling, indent+1, levels-1);
891
    dumpf(indent, " )\n");
892
 
893
    dumpf(indent, "(parent ", table->parent);
894
    dump_insn_table(table->parent, indent+1, 0);
895
    dumpf(indent, " )\n");
896
 
897
  }
898
}
899
 
900
int insn_bit_size = max_insn_bit_size;
901
int hi_bit_nr;
902
int generate_expanded_instructions;
903
 
904
int
905
main(int argc, char **argv)
906
{
907
  filter *filters = NULL;
908
  decode_table *decode_rules = NULL;
909
  insn_table *instructions = NULL;
910
 
911
  if (argc != 5)
912
    error("Usage: insn <filter> <hi-bit-nr> <decode-table> <insn-table>\n");
913
 
914
  filters = new_filter(argv[1], filters);
915
  hi_bit_nr = a2i(argv[2]);
916
  ASSERT(hi_bit_nr < insn_bit_size);
917
  decode_rules = load_decode_table(argv[3], hi_bit_nr);
918
  instructions = load_insn_table(argv[4], decode_rules, filters);
919
  insn_table_expand_insns(instructions);
920
 
921
  dump_insn_table(instructions, 0, -1);
922
  return 0;
923
}
924
 
925
#endif

powered by: WebSVN 2.1.0

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