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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [ppc/] [ld-insn.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/*  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
void
195
parse_include_entry (table *file,
196
                     table_entry *file_entry,
197
                     filter *filters,
198
                     table_include *includes)
199
{
200
  /* parse the include file_entry */
201
  if (file_entry->nr_fields < 4)
202
    error ("Incorrect nr fields for include record\n");
203
  /* process it */
204
  if (!is_filtered_out(file_entry->fields[include_flags], filters))
205
    {
206
      table_push (file, includes,
207
                file_entry->fields[include_path],
208
                file_entry->nr_fields, file_entry->nr_fields);
209
    }
210
}
211
 
212
static void
213
model_table_insert(insn_table *table,
214
                   table_entry *file_entry)
215
{
216
  int len;
217
 
218
  /* create a new model */
219
  model *new_model = ZALLOC(model);
220
 
221
  new_model->name = file_entry->fields[model_identifer];
222
  new_model->printable_name = file_entry->fields[model_name];
223
  new_model->insn_default = file_entry->fields[model_default];
224
 
225
  while (*new_model->insn_default && isspace(*new_model->insn_default))
226
    new_model->insn_default++;
227
 
228
  len = strlen(new_model->insn_default);
229
  if (max_model_fields_len < len)
230
    max_model_fields_len = len;
231
 
232
  /* append it to the end of the model list */
233
  if (last_model)
234
    last_model->next = new_model;
235
  else
236
    models = new_model;
237
  last_model = new_model;
238
}
239
 
240
static void
241
model_table_insert_specific(insn_table *table,
242
                            table_entry *file_entry,
243
                            insn **start_ptr,
244
                            insn **end_ptr)
245
{
246
  insn *ptr = ZALLOC(insn);
247
  ptr->file_entry = file_entry;
248
  if (*end_ptr)
249
    (*end_ptr)->next = ptr;
250
  else
251
    (*start_ptr) = ptr;
252
  (*end_ptr) = ptr;
253
}
254
 
255
 
256
static void
257
insn_table_insert_function(insn_table *table,
258
                           table_entry *file_entry)
259
{
260
  /* create a new function */
261
  insn *new_function = ZALLOC(insn);
262
  new_function->file_entry = file_entry;
263
 
264
  /* append it to the end of the function list */
265
  if (table->last_function)
266
    table->last_function->next = new_function;
267
  else
268
    table->functions = new_function;
269
  table->last_function = new_function;
270
}
271
 
272
extern void
273
insn_table_insert_insn(insn_table *table,
274
                       table_entry *file_entry,
275
                       insn_fields *fields)
276
{
277
  insn **ptr_to_cur_insn = &table->insns;
278
  insn *cur_insn = *ptr_to_cur_insn;
279
  table_model_entry *insn_model_ptr;
280
  model *model_ptr;
281
 
282
  /* create a new instruction */
283
  insn *new_insn = ZALLOC(insn);
284
  new_insn->file_entry = file_entry;
285
  new_insn->fields = fields;
286
 
287
  /* Check out any model information returned to make sure the model
288
     is correct.  */
289
  for(insn_model_ptr = file_entry->model_first; insn_model_ptr; insn_model_ptr = insn_model_ptr->next) {
290
    char *name = insn_model_ptr->fields[insn_model_name];
291
    int len = strlen (insn_model_ptr->fields[insn_model_fields]);
292
 
293
    while (len > 0 && isspace(*insn_model_ptr->fields[insn_model_fields])) {
294
      len--;
295
      insn_model_ptr->fields[insn_model_fields]++;
296
    }
297
 
298
    if (max_model_fields_len < len)
299
      max_model_fields_len = len;
300
 
301
    for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
302
      if (strcmp(name, model_ptr->printable_name) == 0) {
303
 
304
        /* Replace the name field with that of the global model, so that when we
305
           want to print it out, we can just compare pointers.  */
306
        insn_model_ptr->fields[insn_model_name] = model_ptr->printable_name;
307
        break;
308
      }
309
    }
310
 
311
    if (!model_ptr)
312
      error("%s:%d: machine model `%s' was not known about\n",
313
            file_entry->file_name, file_entry->line_nr, name);
314
  }
315
 
316
  /* insert it according to the order of the fields */
317
  while (cur_insn != NULL
318
         && new_insn->fields->value >= cur_insn->fields->value) {
319
    ptr_to_cur_insn = &cur_insn->next;
320
    cur_insn = *ptr_to_cur_insn;
321
  }
322
 
323
  new_insn->next = cur_insn;
324
  *ptr_to_cur_insn = new_insn;
325
 
326
  table->nr_insn++;
327
}
328
 
329
 
330
 
331
insn_table *
332
load_insn_table(const char *file_name,
333
                decode_table *decode_rules,
334
                filter *filters,
335
                table_include *includes)
336
{
337
  table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
338
  insn_table *table = ZALLOC(insn_table);
339
  table_entry *file_entry;
340
  table->opcode_rule = decode_rules;
341
 
342
  while ((file_entry = table_entry_read(file)) != NULL) {
343
    if (it_is("function", file_entry->fields[insn_flags])
344
        || it_is("internal", file_entry->fields[insn_flags])) {
345
      insn_table_insert_function(table, file_entry);
346
    }
347
    else if (it_is("model", file_entry->fields[insn_flags])) {
348
      model_table_insert(table, file_entry);
349
    }
350
    else if (it_is("model-macro", file_entry->fields[insn_flags])) {
351
      model_table_insert_specific(table, file_entry, &model_macros, &last_model_macro);
352
    }
353
    else if (it_is("model-function", file_entry->fields[insn_flags])) {
354
      model_table_insert_specific(table, file_entry, &model_functions, &last_model_function);
355
    }
356
    else if (it_is("model-internal", file_entry->fields[insn_flags])) {
357
      model_table_insert_specific(table, file_entry, &model_internal, &last_model_internal);
358
    }
359
    else if (it_is("model-static", file_entry->fields[insn_flags])) {
360
      model_table_insert_specific(table, file_entry, &model_static, &last_model_static);
361
    }
362
    else if (it_is("model-data", file_entry->fields[insn_flags])) {
363
      model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
364
    }
365
    else if (it_is("include", file_entry->fields[insn_form])
366
             && !is_filtered_out(file_entry->fields[insn_flags], filters)) {
367
      parse_include_entry (file, file_entry, filters, includes);
368
    }
369
    else {
370
      insn_fields *fields;
371
      /* skip instructions that aren't relevant to the mode */
372
      if (is_filtered_out(file_entry->fields[insn_flags], filters)) {
373
        fprintf(stderr, "Dropping %s - %s\n",
374
                file_entry->fields[insn_name],
375
                file_entry->fields[insn_flags]);
376
      }
377
      else {
378
        /* create/insert the new instruction */
379
        fields = parse_insn_format(file_entry,
380
                                   file_entry->fields[insn_format]);
381
        insn_table_insert_insn(table, file_entry, fields);
382
      }
383
    }
384
  }
385
  return table;
386
}
387
 
388
 
389
extern void
390
insn_table_traverse_tree(insn_table *table,
391
                         lf *file,
392
                         void *data,
393
                         int depth,
394
                         leaf_handler *start,
395
                         insn_handler *leaf,
396
                         leaf_handler *end,
397
                         padding_handler *padding)
398
{
399
  insn_table *entry;
400
  int entry_nr;
401
 
402
  ASSERT(table != NULL
403
         && table->opcode != NULL
404
         && table->nr_entries > 0
405
         && table->entries != 0);
406
 
407
  if (start != NULL && depth >= 0)
408
    start(table, file, data, depth);
409
 
410
  for (entry_nr = 0, entry = table->entries;
411
       entry_nr < (table->opcode->is_boolean
412
                   ? 2
413
                   : (1 << (table->opcode->last - table->opcode->first + 1)));
414
       entry_nr ++) {
415
    if (entry == NULL
416
        || (!table->opcode->is_boolean
417
            && entry_nr < entry->opcode_nr)) {
418
      if (padding != NULL && depth >= 0)
419
        padding(table, file, data, depth, entry_nr);
420
    }
421
    else {
422
      ASSERT(entry != NULL && (entry->opcode_nr == entry_nr
423
                               || table->opcode->is_boolean));
424
      if (entry->opcode != NULL && depth != 0) {
425
        insn_table_traverse_tree(entry, file, data, depth+1,
426
                                 start, leaf, end, padding);
427
      }
428
      else if (depth >= 0) {
429
        if (leaf != NULL)
430
          leaf(entry, file, data, entry->insns, depth);
431
      }
432
      entry = entry->sibling;
433
    }
434
  }
435
  if (end != NULL && depth >= 0)
436
    end(table, file, data, depth);
437
}
438
 
439
 
440
extern void
441
insn_table_traverse_function(insn_table *table,
442
                             lf *file,
443
                             void *data,
444
                             function_handler *leaf)
445
{
446
  insn *function;
447
  for (function = table->functions;
448
       function != NULL;
449
       function = function->next) {
450
    leaf(table, file, data, function->file_entry);
451
  }
452
}
453
 
454
extern void
455
insn_table_traverse_insn(insn_table *table,
456
                         lf *file,
457
                         void *data,
458
                         insn_handler *handler)
459
{
460
  insn *instruction;
461
  for (instruction = table->insns;
462
       instruction != NULL;
463
       instruction = instruction->next) {
464
    handler(table, file, data, instruction, 0);
465
  }
466
}
467
 
468
 
469
/****************************************************************/
470
 
471
typedef enum {
472
  field_constant_int = 1,
473
  field_constant_slash = 2,
474
  field_constant_string = 3
475
} constant_field_types;
476
 
477
 
478
static int
479
insn_field_is_constant(insn_field *field,
480
                       decode_table *rule)
481
{
482
  /* field is an integer */
483
  if (field->is_int)
484
    return field_constant_int;
485
  /* field is `/' and treating that as a constant */
486
  if (field->is_slash && rule->force_slash)
487
    return field_constant_slash;
488
  /* field, though variable is on the list */
489
  if (field->is_string && rule->force_expansion != NULL) {
490
    char *forced_fields = rule->force_expansion;
491
    while (*forced_fields != '\0') {
492
      int field_len;
493
      char *end = strchr(forced_fields, ',');
494
      if (end == NULL)
495
        field_len = strlen(forced_fields);
496
      else
497
        field_len = end-forced_fields;
498
      if (strncmp(forced_fields, field->val_string, field_len) == 0
499
          && field->val_string[field_len] == '\0')
500
        return field_constant_string;
501
      forced_fields += field_len;
502
      if (*forced_fields == ',')
503
        forced_fields++;
504
    }
505
  }
506
  return 0;
507
}
508
 
509
 
510
static opcode_field *
511
insn_table_find_opcode_field(insn *insns,
512
                             decode_table *rule,
513
                             int string_only)
514
{
515
  opcode_field *curr_opcode = ZALLOC(opcode_field);
516
  insn *entry;
517
  ASSERT(rule);
518
 
519
  curr_opcode->first = insn_bit_size;
520
  curr_opcode->last = -1;
521
  for (entry = insns; entry != NULL; entry = entry->next) {
522
    insn_fields *fields = entry->fields;
523
    opcode_field new_opcode;
524
 
525
    /* find a start point for the opcode field */
526
    new_opcode.first = rule->first;
527
    while (new_opcode.first <= rule->last
528
           && (!string_only
529
               || insn_field_is_constant(fields->bits[new_opcode.first],
530
                                         rule) != field_constant_string)
531
           && (string_only
532
               || !insn_field_is_constant(fields->bits[new_opcode.first],
533
                                          rule)))
534
      new_opcode.first = fields->bits[new_opcode.first]->last + 1;
535
    ASSERT(new_opcode.first > rule->last
536
           || (string_only
537
               && insn_field_is_constant(fields->bits[new_opcode.first],
538
                                         rule) == field_constant_string)
539
           || (!string_only
540
               && insn_field_is_constant(fields->bits[new_opcode.first],
541
                                         rule)));
542
 
543
    /* find the end point for the opcode field */
544
    new_opcode.last = rule->last;
545
    while (new_opcode.last >= rule->first
546
           && (!string_only
547
               || insn_field_is_constant(fields->bits[new_opcode.last],
548
                                         rule) != field_constant_string)
549
           && (string_only
550
               || !insn_field_is_constant(fields->bits[new_opcode.last],
551
                                          rule)))
552
      new_opcode.last = fields->bits[new_opcode.last]->first - 1;
553
    ASSERT(new_opcode.last < rule->first
554
           || (string_only
555
               && insn_field_is_constant(fields->bits[new_opcode.last],
556
                                         rule) == field_constant_string)
557
           || (!string_only
558
               && insn_field_is_constant(fields->bits[new_opcode.last],
559
                                         rule)));
560
 
561
    /* now see if our current opcode needs expanding */
562
    if (new_opcode.first <= rule->last
563
        && curr_opcode->first > new_opcode.first)
564
      curr_opcode->first = new_opcode.first;
565
    if (new_opcode.last >= rule->first
566
        && curr_opcode->last < new_opcode.last)
567
      curr_opcode->last = new_opcode.last;
568
 
569
  }
570
 
571
  /* was any thing interesting found? */
572
  if (curr_opcode->first > rule->last) {
573
    ASSERT(curr_opcode->last < rule->first);
574
    return NULL;
575
  }
576
  ASSERT(curr_opcode->last >= rule->first);
577
  ASSERT(curr_opcode->first <= rule->last);
578
 
579
  /* if something was found, check it includes the forced field range */
580
  if (!string_only
581
      && curr_opcode->first > rule->force_first) {
582
    curr_opcode->first = rule->force_first;
583
  }
584
  if (!string_only
585
      && curr_opcode->last < rule->force_last) {
586
    curr_opcode->last = rule->force_last;
587
  }
588
  /* handle special case elminating any need to do shift after mask */
589
  if (string_only
590
      && rule->force_last == insn_bit_size-1) {
591
    curr_opcode->last = insn_bit_size-1;
592
  }
593
 
594
  /* handle any special cases */
595
  switch (rule->type) {
596
  case normal_decode_rule:
597
    /* let the above apply */
598
    break;
599
  case expand_forced_rule:
600
    /* expand a limited nr of bits, ignoring the rest */
601
    curr_opcode->first = rule->force_first;
602
    curr_opcode->last = rule->force_last;
603
    break;
604
  case boolean_rule:
605
    curr_opcode->is_boolean = 1;
606
    curr_opcode->boolean_constant = rule->special_constant;
607
    break;
608
  default:
609
    error("Something is going wrong\n");
610
  }
611
 
612
  return curr_opcode;
613
}
614
 
615
 
616
static void
617
insn_table_insert_expanded(insn_table *table,
618
                           insn *old_insn,
619
                           int new_opcode_nr,
620
                           insn_bits *new_bits)
621
{
622
  insn_table **ptr_to_cur_entry = &table->entries;
623
  insn_table *cur_entry = *ptr_to_cur_entry;
624
 
625
  /* find the new table for this entry */
626
  while (cur_entry != NULL
627
         && cur_entry->opcode_nr < new_opcode_nr) {
628
    ptr_to_cur_entry = &cur_entry->sibling;
629
    cur_entry = *ptr_to_cur_entry;
630
  }
631
 
632
  if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {
633
    insn_table *new_entry = ZALLOC(insn_table);
634
    new_entry->opcode_nr = new_opcode_nr;
635
    new_entry->expanded_bits = new_bits;
636
    new_entry->opcode_rule = table->opcode_rule->next;
637
    new_entry->sibling = cur_entry;
638
    new_entry->parent = table;
639
    *ptr_to_cur_entry = new_entry;
640
    cur_entry = new_entry;
641
    table->nr_entries++;
642
  }
643
  /* ASSERT new_bits == cur_entry bits */
644
  ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);
645
  insn_table_insert_insn(cur_entry,
646
                         old_insn->file_entry,
647
                         old_insn->fields);
648
}
649
 
650
static void
651
insn_table_expand_opcode(insn_table *table,
652
                         insn *instruction,
653
                         int field_nr,
654
                         int opcode_nr,
655
                         insn_bits *bits)
656
{
657
 
658
  if (field_nr > table->opcode->last) {
659
    insn_table_insert_expanded(table, instruction, opcode_nr, bits);
660
  }
661
  else {
662
    insn_field *field = instruction->fields->bits[field_nr];
663
    if (field->is_int || field->is_slash) {
664
      ASSERT(field->first >= table->opcode->first
665
             && field->last <= table->opcode->last);
666
      insn_table_expand_opcode(table, instruction, field->last+1,
667
                               ((opcode_nr << field->width) + field->val_int),
668
                               bits);
669
    }
670
    else {
671
      int val;
672
      int last_pos = ((field->last < table->opcode->last)
673
                        ? field->last : table->opcode->last);
674
      int first_pos = ((field->first > table->opcode->first)
675
                         ? field->first : table->opcode->first);
676
      int width = last_pos - first_pos + 1;
677
      int last_val = (table->opcode->is_boolean
678
                      ? 2 : (1 << width));
679
      for (val = 0; val < last_val; val++) {
680
        insn_bits *new_bits = ZALLOC(insn_bits);
681
        new_bits->field = field;
682
        new_bits->value = val;
683
        new_bits->last = bits;
684
        new_bits->opcode = table->opcode;
685
        insn_table_expand_opcode(table, instruction, last_pos+1,
686
                                 ((opcode_nr << width) | val),
687
                                 new_bits);
688
      }
689
    }
690
  }
691
}
692
 
693
static void
694
insn_table_insert_expanding(insn_table *table,
695
                            insn *entry)
696
{
697
  insn_table_expand_opcode(table,
698
                           entry,
699
                           table->opcode->first,
700
                           0,
701
                           table->expanded_bits);
702
}
703
 
704
 
705
extern void
706
insn_table_expand_insns(insn_table *table)
707
{
708
 
709
  ASSERT(table->nr_insn >= 1);
710
 
711
  /* determine a valid opcode */
712
  while (table->opcode_rule) {
713
    /* specials only for single instructions */
714
    if ((table->nr_insn > 1
715
         && table->opcode_rule->special_mask == 0
716
         && table->opcode_rule->type == normal_decode_rule)
717
        || (table->nr_insn == 1
718
            && table->opcode_rule->special_mask != 0
719
            && ((table->insns->fields->value
720
                 & table->opcode_rule->special_mask)
721
                == table->opcode_rule->special_value))
722
        || (generate_expanded_instructions
723
            && table->opcode_rule->special_mask == 0
724
            && table->opcode_rule->type == normal_decode_rule))
725
      table->opcode =
726
        insn_table_find_opcode_field(table->insns,
727
                                     table->opcode_rule,
728
                                     table->nr_insn == 1/*string*/
729
                                     );
730
    if (table->opcode != NULL)
731
      break;
732
    table->opcode_rule = table->opcode_rule->next;
733
  }
734
 
735
  /* did we find anything */
736
  if (table->opcode == NULL) {
737
    return;
738
  }
739
  ASSERT(table->opcode != NULL);
740
 
741
  /* back link what we found to its parent */
742
  if (table->parent != NULL) {
743
    ASSERT(table->parent->opcode != NULL);
744
    table->opcode->parent = table->parent->opcode;
745
  }
746
 
747
  /* expand the raw instructions according to the opcode */
748
  {
749
    insn *entry;
750
    for (entry = table->insns; entry != NULL; entry = entry->next) {
751
      insn_table_insert_expanding(table, entry);
752
    }
753
  }
754
 
755
  /* and do the same for the sub entries */
756
  {
757
    insn_table *entry;
758
    for (entry = table->entries; entry != NULL; entry =  entry->sibling) {
759
      insn_table_expand_insns(entry);
760
    }
761
  }
762
}
763
 
764
 
765
 
766
 
767
#ifdef MAIN
768
 
769
static void
770
dump_insn_field(insn_field *field,
771
                int indent)
772
{
773
 
774
  printf("(insn_field*)0x%x\n", (unsigned)field);
775
 
776
  dumpf(indent, "(first %d)\n", field->first);
777
 
778
  dumpf(indent, "(last %d)\n", field->last);
779
 
780
  dumpf(indent, "(width %d)\n", field->width);
781
 
782
  if (field->is_int)
783
    dumpf(indent, "(is_int %d)\n", field->val_int);
784
 
785
  if (field->is_slash)
786
    dumpf(indent, "(is_slash)\n");
787
 
788
  if (field->is_string)
789
    dumpf(indent, "(is_string `%s')\n", field->val_string);
790
 
791
  dumpf(indent, "(next 0x%x)\n", field->next);
792
 
793
  dumpf(indent, "(prev 0x%x)\n", field->prev);
794
 
795
 
796
}
797
 
798
static void
799
dump_insn_fields(insn_fields *fields,
800
                 int indent)
801
{
802
  int i;
803
 
804
  printf("(insn_fields*)%p\n", fields);
805
 
806
  dumpf(indent, "(first 0x%x)\n", fields->first);
807
  dumpf(indent, "(last 0x%x)\n", fields->last);
808
 
809
  dumpf(indent, "(value 0x%x)\n", fields->value);
810
 
811
  for (i = 0; i < insn_bit_size; i++) {
812
    dumpf(indent, "(bits[%d] ", i, fields->bits[i]);
813
    dump_insn_field(fields->bits[i], indent+1);
814
    dumpf(indent, " )\n");
815
  }
816
 
817
}
818
 
819
 
820
static void
821
dump_opcode_field(opcode_field *field, int indent, int levels)
822
{
823
  printf("(opcode_field*)%p\n", field);
824
  if (levels && field != NULL) {
825
    dumpf(indent, "(first %d)\n", field->first);
826
    dumpf(indent, "(last %d)\n", field->last);
827
    dumpf(indent, "(is_boolean %d)\n", field->is_boolean);
828
    dumpf(indent, "(parent ");
829
    dump_opcode_field(field->parent, indent, levels-1);
830
  }
831
}
832
 
833
 
834
static void
835
dump_insn_bits(insn_bits *bits, int indent, int levels)
836
{
837
  printf("(insn_bits*)%p\n", bits);
838
 
839
  if (levels && bits != NULL) {
840
    dumpf(indent, "(value %d)\n", bits->value);
841
    dumpf(indent, "(opcode ");
842
    dump_opcode_field(bits->opcode, indent+1, 0);
843
    dumpf(indent, " )\n");
844
    dumpf(indent, "(field ");
845
    dump_insn_field(bits->field, indent+1);
846
    dumpf(indent, " )\n");
847
    dumpf(indent, "(last ");
848
    dump_insn_bits(bits->last, indent+1, levels-1);
849
  }
850
}
851
 
852
 
853
 
854
static void
855
dump_insn(insn *entry, int indent, int levels)
856
{
857
  printf("(insn*)%p\n", entry);
858
 
859
  if (levels && entry != NULL) {
860
 
861
    dumpf(indent, "(file_entry ");
862
    dump_table_entry(entry->file_entry, indent+1);
863
    dumpf(indent, " )\n");
864
 
865
    dumpf(indent, "(fields ");
866
    dump_insn_fields(entry->fields, indent+1);
867
    dumpf(indent, " )\n");
868
 
869
    dumpf(indent, "(next ");
870
    dump_insn(entry->next, indent+1, levels-1);
871
    dumpf(indent, " )\n");
872
 
873
  }
874
 
875
}
876
 
877
 
878
static void
879
dump_insn_table(insn_table *table,
880
                int indent, int levels)
881
{
882
 
883
  printf("(insn_table*)%p\n", table);
884
 
885
  if (levels && table != NULL) {
886
 
887
    dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);
888
 
889
    dumpf(indent, "(expanded_bits ");
890
    dump_insn_bits(table->expanded_bits, indent+1, -1);
891
    dumpf(indent, " )\n");
892
 
893
    dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);
894
 
895
    dumpf(indent, "(insns ");
896
    dump_insn(table->insns, indent+1, table->nr_insn);
897
    dumpf(indent, " )\n");
898
 
899
    dumpf(indent, "(opcode_rule ");
900
    dump_decode_rule(table->opcode_rule, indent+1);
901
    dumpf(indent, " )\n");
902
 
903
    dumpf(indent, "(opcode ");
904
    dump_opcode_field(table->opcode, indent+1, 1);
905
    dumpf(indent, " )\n");
906
 
907
    dumpf(indent, "(nr_entries %d)\n", table->entries);
908
    dumpf(indent, "(entries ");
909
    dump_insn_table(table->entries, indent+1, table->nr_entries);
910
    dumpf(indent, " )\n");
911
 
912
    dumpf(indent, "(sibling ", table->sibling);
913
    dump_insn_table(table->sibling, indent+1, levels-1);
914
    dumpf(indent, " )\n");
915
 
916
    dumpf(indent, "(parent ", table->parent);
917
    dump_insn_table(table->parent, indent+1, 0);
918
    dumpf(indent, " )\n");
919
 
920
  }
921
}
922
 
923
int insn_bit_size = max_insn_bit_size;
924
int hi_bit_nr;
925
int generate_expanded_instructions;
926
 
927
int
928
main(int argc, char **argv)
929
{
930
  filter *filters = NULL;
931
  decode_table *decode_rules = NULL;
932
  insn_table *instructions = NULL;
933
 
934
  if (argc != 5)
935
    error("Usage: insn <filter> <hi-bit-nr> <decode-table> <insn-table>\n");
936
 
937
  filters = new_filter(argv[1], filters);
938
  hi_bit_nr = a2i(argv[2]);
939
  ASSERT(hi_bit_nr < insn_bit_size);
940
  decode_rules = load_decode_table(argv[3], hi_bit_nr);
941
  instructions = load_insn_table(argv[4], decode_rules, filters, NULL);
942
  insn_table_expand_insns(instructions);
943
 
944
  dump_insn_table(instructions, 0, -1);
945
  return 0;
946
}
947
 
948
#endif

powered by: WebSVN 2.1.0

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