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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [igen/] [gen-idecode.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* The IGEN simulator generator for GDB, the GNU Debugger.
2
 
3
   Copyright 2002 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 2 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, write to the Free Software
21
   Foundation, Inc., 59 Temple Place - Suite 330,
22
   Boston, MA 02111-1307, USA.  */
23
 
24
 
25
#include "misc.h"
26
#include "lf.h"
27
#include "table.h"
28
#include "filter.h"
29
#include "igen.h"
30
 
31
#include "ld-insn.h"
32
#include "ld-decode.h"
33
 
34
#include "gen.h"
35
 
36
#include "gen-idecode.h"
37
#include "gen-icache.h"
38
#include "gen-semantics.h"
39
 
40
 
41
 
42
static void
43
lf_print_opcodes (lf *file, gen_entry *table)
44
{
45
  if (table !=NULL)
46
    {
47
      while (1)
48
        {
49
          ASSERT (table->opcode != NULL);
50
          lf_printf (file, "_%d_%d",
51
                     table->opcode->first, table->opcode->last);
52
          if (table->parent == NULL)
53
            break;
54
          lf_printf (file, "__%d", table->opcode_nr);
55
          table = table->parent;
56
        }
57
    }
58
}
59
 
60
 
61
 
62
 
63
static void
64
print_idecode_ifetch (lf *file,
65
                      int previous_nr_prefetched_words,
66
                      int current_nr_prefetched_words)
67
{
68
  int word_nr;
69
  for (word_nr = previous_nr_prefetched_words;
70
       word_nr < current_nr_prefetched_words; word_nr++)
71
    {
72
      lf_printf (file,
73
                 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
74
                 word_nr, options.insn_bit_size, word_nr);
75
 
76
    }
77
}
78
 
79
 
80
 
81
/****************************************************************/
82
 
83
 
84
static void
85
lf_print_table_name (lf *file, gen_entry *table)
86
{
87
  lf_printf (file, "idecode_table");
88
  lf_print_opcodes (file, table);
89
}
90
 
91
 
92
 
93
static void
94
print_idecode_table (lf *file, gen_entry *entry, const char *result)
95
{
96
  lf_printf (file, "/* prime the search */\n");
97
  lf_printf (file, "idecode_table_entry *table = ");
98
  lf_print_table_name (file, entry);
99
  lf_printf (file, ";\n");
100
  lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n",
101
             options.insn_bit_size,
102
             i2target (options.hi_bit_nr, entry->opcode->first),
103
             i2target (options.hi_bit_nr, entry->opcode->last));
104
  lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");
105
 
106
  lf_printf (file, "\n");
107
  lf_printf (file, "/* iterate until a leaf */\n");
108
  lf_printf (file, "while (1) {\n");
109
  lf_printf (file, "  signed shift = table_entry->shift;\n");
110
  lf_printf (file, "if (shift == function_entry) break;\n");
111
  lf_printf (file, "  if (shift >= 0) {\n");
112
  lf_printf (file, "    table = ((idecode_table_entry*)\n");
113
  lf_printf (file, "             table_entry->function_or_table);\n");
114
  lf_printf (file, "    opcode = ((instruction & table_entry->mask)\n");
115
  lf_printf (file, "              >> shift);\n");
116
  lf_printf (file, "    table_entry = table + opcode;\n");
117
  lf_printf (file, "  }\n");
118
  lf_printf (file, "  else {\n");
119
  lf_printf (file, "    /* must be a boolean */\n");
120
  lf_printf (file, "    ASSERT(table_entry->shift == boolean_entry);\n");
121
  lf_printf (file, "    opcode = ((instruction & table_entry->mask)\n");
122
  lf_printf (file, "              != table_entry->value);\n");
123
  lf_printf (file, "    table = ((idecode_table_entry*)\n");
124
  lf_printf (file, "             table_entry->function_or_table);\n");
125
  lf_printf (file, "    table_entry = table + opcode;\n");
126
  lf_printf (file, "  }\n");
127
  lf_printf (file, "}\n");
128
 
129
  lf_printf (file, "\n");
130
  lf_printf (file, "/* call the leaf code */\n");
131
  if (options.gen.code == generate_jumps)
132
    {
133
      lf_printf (file, "goto *table_entry->function_or_table;\n");
134
    }
135
  else
136
    {
137
      lf_printf (file, "%s ", result);
138
      if (options.gen.icache)
139
        {
140
          lf_printf (file,
141
                     "(((idecode_icache*)table_entry->function_or_table)\n");
142
          lf_printf (file, "  (");
143
          print_icache_function_actual (file, 1);
144
          lf_printf (file, "));\n");
145
        }
146
      else
147
        {
148
          lf_printf (file,
149
                     "((idecode_semantic*)table_entry->function_or_table)\n");
150
          lf_printf (file, "  (");
151
          print_semantic_function_actual (file, 1);
152
          lf_printf (file, ");\n");
153
        }
154
    }
155
}
156
 
157
 
158
static void
159
print_idecode_table_start (lf *file, gen_entry *table, int depth, void *data)
160
{
161
  ASSERT (depth == 0);
162
  /* start of the table */
163
  if (table->opcode_rule->gen == array_gen)
164
    {
165
      lf_printf (file, "\n");
166
      lf_printf (file, "static idecode_table_entry ");
167
      lf_print_table_name (file, table);
168
      lf_printf (file, "[] = {\n");
169
    }
170
}
171
 
172
static void
173
print_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data)
174
{
175
  gen_entry *master_entry;
176
  ASSERT (entry->parent != NULL);
177
  ASSERT (depth == 0);
178
  if (entry->combined_parent == NULL)
179
    master_entry = entry;
180
  else
181
    master_entry = entry->combined_parent;
182
 
183
  /* add an entry to the table */
184
  if (entry->parent->opcode_rule->gen == array_gen)
185
    {
186
      lf_printf (file, "  /*%d*/ { ", entry->opcode_nr);
187
      if (entry->opcode == NULL)
188
        {
189
          ASSERT (entry->nr_insns == 1);
190
          /* table leaf entry */
191
          lf_printf (file, "function_entry, 0, 0, ");
192
          if (options.gen.code == generate_jumps)
193
            {
194
              lf_printf (file, "&&");
195
            }
196
          print_function_name (file,
197
                               entry->insns->insn->name,
198
                               entry->insns->insn->format_name,
199
                               NULL,
200
                               master_entry->expanded_bits,
201
                               (options.gen.icache
202
                                ? function_name_prefix_icache
203
                                : function_name_prefix_semantics));
204
        }
205
      else if (entry->opcode_rule->gen == switch_gen
206
               || entry->opcode_rule->gen == goto_switch_gen
207
               || entry->opcode_rule->gen == padded_switch_gen)
208
        {
209
          /* table calling switch statement */
210
          lf_printf (file, "function_entry, 0, 0, ");
211
          if (options.gen.code == generate_jumps)
212
            {
213
              lf_printf (file, "&&");
214
            }
215
          lf_print_table_name (file, entry);
216
        }
217
      else if (entry->opcode->is_boolean)
218
        {
219
          /* table `calling' boolean table */
220
          lf_printf (file, "boolean_entry, ");
221
          lf_printf (file, "MASK32(%d, %d), ",
222
                     i2target (options.hi_bit_nr, entry->opcode->first),
223
                     i2target (options.hi_bit_nr, entry->opcode->last));
224
          lf_printf (file, "INSERTED32(%d, %d, %d), ",
225
                     entry->opcode->boolean_constant,
226
                     i2target (options.hi_bit_nr, entry->opcode->first),
227
                     i2target (options.hi_bit_nr, entry->opcode->last));
228
          lf_print_table_name (file, entry);
229
        }
230
      else
231
        {
232
          /* table `calling' another table */
233
          lf_printf (file, "%d, ",
234
                     options.insn_bit_size - entry->opcode->last - 1);
235
          lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size,
236
                     i2target (options.hi_bit_nr, entry->opcode->first),
237
                     i2target (options.hi_bit_nr, entry->opcode->last));
238
          lf_printf (file, "0, ");
239
          lf_print_table_name (file, entry);
240
        }
241
      lf_printf (file, " },\n");
242
    }
243
}
244
 
245
static void
246
print_idecode_table_end (lf *file, gen_entry *table, int depth, void *data)
247
{
248
  ASSERT (depth == 0);
249
  if (table->opcode_rule->gen == array_gen)
250
    {
251
      lf_printf (file, "};\n");
252
    }
253
}
254
 
255
/****************************************************************/
256
 
257
 
258
static void
259
print_goto_switch_name (lf *file, gen_entry *entry)
260
{
261
  lf_printf (file, "case_");
262
  if (entry->opcode == NULL)
263
    {
264
      print_function_name (file,
265
                           entry->insns->insn->name,
266
                           entry->insns->insn->format_name,
267
                           NULL,
268
                           entry->expanded_bits,
269
                           (options.gen.icache
270
                            ? function_name_prefix_icache
271
                            : function_name_prefix_semantics));
272
    }
273
  else
274
    {
275
      lf_print_table_name (file, entry);
276
    }
277
}
278
 
279
static void
280
print_goto_switch_table_leaf (lf *file,
281
                              gen_entry *entry, int depth, void *data)
282
{
283
  ASSERT (entry->parent != NULL);
284
  ASSERT (depth == 0);
285
  ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);
286
  ASSERT (entry->parent->opcode);
287
 
288
  lf_printf (file, "/* %d */ &&", entry->opcode_nr);
289
  if (entry->combined_parent != NULL)
290
    print_goto_switch_name (file, entry->combined_parent);
291
  else
292
    print_goto_switch_name (file, entry);
293
  lf_printf (file, ",\n");
294
}
295
 
296
static void
297
print_goto_switch_break (lf *file, gen_entry *entry)
298
{
299
  lf_printf (file, "goto break_");
300
  lf_print_table_name (file, entry->parent);
301
  lf_printf (file, ";\n");
302
}
303
 
304
 
305
static void
306
print_goto_switch_table (lf *file, gen_entry *table)
307
{
308
  lf_printf (file, "const static void *");
309
  lf_print_table_name (file, table);
310
  lf_printf (file, "[] = {\n");
311
  lf_indent (file, +2);
312
  gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,
313
                           print_goto_switch_table_leaf, NULL /*end */ ,
314
                           NULL /*data */ );
315
  lf_indent (file, -2);
316
  lf_printf (file, "};\n");
317
}
318
 
319
 
320
void print_idecode_switch (lf *file, gen_entry *table, const char *result);
321
 
322
static void
323
print_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data)
324
{
325
  /* const char *result = data; */
326
  ASSERT (depth == 0);
327
  ASSERT (table->opcode_rule->gen == switch_gen
328
          || table->opcode_rule->gen == goto_switch_gen
329
          || table->opcode_rule->gen == padded_switch_gen);
330
 
331
  if (table->opcode->is_boolean
332
      || table->opcode_rule->gen == switch_gen
333
      || table->opcode_rule->gen == padded_switch_gen)
334
    {
335
      lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n",
336
                 options.insn_bit_size,
337
                 table->opcode_rule->word_nr,
338
                 i2target (options.hi_bit_nr, table->opcode->first),
339
                 i2target (options.hi_bit_nr, table->opcode->last));
340
      lf_indent (file, +2);
341
      lf_printf (file, "{\n");
342
    }
343
  else if (table->opcode_rule->gen == goto_switch_gen)
344
    {
345
      if (table->parent != NULL
346
          && (table->parent->opcode_rule->gen == switch_gen
347
              || table->parent->opcode_rule->gen == goto_switch_gen
348
              || table->parent->opcode_rule->gen == padded_switch_gen))
349
        {
350
          lf_printf (file, "{\n");
351
          lf_indent (file, +2);
352
        }
353
      print_goto_switch_table (file, table);
354
      lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n",
355
                 options.insn_bit_size,
356
                 table->opcode->word_nr,
357
                 i2target (options.hi_bit_nr, table->opcode->first),
358
                 i2target (options.hi_bit_nr, table->opcode->last));
359
      lf_printf (file, "        < (sizeof (");
360
      lf_print_table_name (file, table);
361
      lf_printf (file, ") / sizeof(void*)));\n");
362
      lf_printf (file, "goto *");
363
      lf_print_table_name (file, table);
364
      lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n",
365
                 options.insn_bit_size,
366
                 table->opcode->word_nr,
367
                 i2target (options.hi_bit_nr, table->opcode->first),
368
                 i2target (options.hi_bit_nr, table->opcode->last));
369
    }
370
  else
371
    {
372
      ASSERT ("bad switch" == NULL);
373
    }
374
}
375
 
376
 
377
static void
378
print_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data)
379
{
380
  const char *result = data;
381
  ASSERT (entry->parent != NULL);
382
  ASSERT (depth == 0);
383
  ASSERT (entry->parent->opcode_rule->gen == switch_gen
384
          || entry->parent->opcode_rule->gen == goto_switch_gen
385
          || entry->parent->opcode_rule->gen == padded_switch_gen);
386
  ASSERT (entry->parent->opcode);
387
 
388
  /* skip over any instructions combined into another entry */
389
  if (entry->combined_parent != NULL)
390
    return;
391
 
392
  if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)
393
    {
394
      /* case: boolean false target */
395
      lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
396
    }
397
  else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)
398
    {
399
      /* case: boolean true case */
400
      lf_printf (file, "default:\n");
401
    }
402
  else if (entry->parent->opcode_rule->gen == switch_gen
403
           || entry->parent->opcode_rule->gen == padded_switch_gen)
404
    {
405
      /* case: <opcode-nr> - switch */
406
      gen_entry *cob;
407
      for (cob = entry; cob != NULL; cob = cob->combined_next)
408
        lf_printf (file, "case %d:\n", cob->opcode_nr);
409
    }
410
  else if (entry->parent->opcode_rule->gen == goto_switch_gen)
411
    {
412
      /* case: <opcode-nr> - goto-switch */
413
      print_goto_switch_name (file, entry);
414
      lf_printf (file, ":\n");
415
    }
416
  else
417
    {
418
      ERROR ("bad switch");
419
    }
420
  lf_printf (file, "  {\n");
421
  lf_indent (file, +4);
422
  {
423
    if (entry->opcode == NULL)
424
      {
425
        /* switch calling leaf */
426
        ASSERT (entry->nr_insns == 1);
427
        print_idecode_ifetch (file, entry->nr_prefetched_words,
428
                              entry->insns->semantic->nr_prefetched_words);
429
        switch (options.gen.code)
430
          {
431
          case generate_jumps:
432
            lf_printf (file, "goto ");
433
            break;
434
          case generate_calls:
435
            lf_printf (file, "%s", result);
436
            break;
437
          }
438
        print_function_name (file,
439
                             entry->insns->insn->name,
440
                             entry->insns->insn->format_name,
441
                             NULL,
442
                             entry->expanded_bits,
443
                             (options.gen.icache
444
                              ? function_name_prefix_icache
445
                              : function_name_prefix_semantics));
446
        if (options.gen.code == generate_calls)
447
          {
448
            lf_printf (file, " (");
449
            print_semantic_function_actual (file,
450
                                            entry->insns->semantic->
451
                                            nr_prefetched_words);
452
            lf_printf (file, ")");
453
          }
454
        lf_printf (file, ";\n");
455
      }
456
    else if (entry->opcode_rule->gen == switch_gen
457
             || entry->opcode_rule->gen == goto_switch_gen
458
             || entry->opcode_rule->gen == padded_switch_gen)
459
      {
460
        /* switch calling switch */
461
        lf_printf (file, "{\n");
462
        lf_indent (file, +2);
463
        print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
464
                              entry->nr_prefetched_words);
465
        print_idecode_switch (file, entry, result);
466
        lf_indent (file, -2);
467
        lf_printf (file, "}\n");
468
      }
469
    else
470
      {
471
        /* switch looking up a table */
472
        lf_printf (file, "{\n");
473
        lf_indent (file, +2);
474
        print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
475
                              entry->nr_prefetched_words);
476
        print_idecode_table (file, entry, result);
477
        lf_indent (file, -2);
478
        lf_printf (file, "}\n");
479
      }
480
    if (entry->parent->opcode->is_boolean
481
        || entry->parent->opcode_rule->gen == switch_gen
482
        || entry->parent->opcode_rule->gen == padded_switch_gen)
483
      {
484
        lf_printf (file, "break;\n");
485
      }
486
    else if (entry->parent->opcode_rule->gen == goto_switch_gen)
487
      {
488
        print_goto_switch_break (file, entry);
489
      }
490
    else
491
      {
492
        ERROR ("bad switch");
493
      }
494
  }
495
  lf_indent (file, -4);
496
  lf_printf (file, "  }\n");
497
}
498
 
499
 
500
static void
501
print_idecode_switch_illegal (lf *file, const char *result)
502
{
503
  lf_indent (file, +2);
504
  print_idecode_invalid (file, result, invalid_illegal);
505
  lf_printf (file, "break;\n");
506
  lf_indent (file, -2);
507
}
508
 
509
static void
510
print_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data)
511
{
512
  const char *result = data;
513
  ASSERT (depth == 0);
514
  ASSERT (table->opcode_rule->gen == switch_gen
515
          || table->opcode_rule->gen == goto_switch_gen
516
          || table->opcode_rule->gen == padded_switch_gen);
517
  ASSERT (table->opcode);
518
 
519
  if (table->opcode->is_boolean)
520
    {
521
      lf_printf (file, "}\n");
522
      lf_indent (file, -2);
523
    }
524
  else if (table->opcode_rule->gen == switch_gen
525
           || table->opcode_rule->gen == padded_switch_gen)
526
    {
527
      lf_printf (file, "default:\n");
528
      lf_indent (file, +2);
529
      if (table->nr_entries == table->opcode->nr_opcodes)
530
        {
531
          print_sim_engine_abort (file,
532
                                  "Internal error - bad switch generated");
533
          lf_printf (file, "%sNULL_CIA;\n", result);
534
          lf_printf (file, "break;\n");
535
        }
536
      else
537
        {
538
          print_idecode_switch_illegal (file, result);
539
        }
540
      lf_indent (file, -2);
541
      lf_printf (file, "}\n");
542
      lf_indent (file, -2);
543
    }
544
  else if (table->opcode_rule->gen == goto_switch_gen)
545
    {
546
      lf_printf (file, "illegal_");
547
      lf_print_table_name (file, table);
548
      lf_printf (file, ":\n");
549
      print_idecode_invalid (file, result, invalid_illegal);
550
      lf_printf (file, "break_");
551
      lf_print_table_name (file, table);
552
      lf_printf (file, ":;\n");
553
      if (table->parent != NULL
554
          && (table->parent->opcode_rule->gen == switch_gen
555
              || table->parent->opcode_rule->gen == goto_switch_gen
556
              || table->parent->opcode_rule->gen == padded_switch_gen))
557
        {
558
          lf_indent (file, -2);
559
          lf_printf (file, "}\n");
560
        }
561
    }
562
  else
563
    {
564
      ERROR ("bad switch");
565
    }
566
}
567
 
568
 
569
void
570
print_idecode_switch (lf *file, gen_entry *table, const char *result)
571
{
572
  gen_entry_traverse_tree (file, table,
573
                           0,
574
                           print_idecode_switch_start,
575
                           print_idecode_switch_leaf,
576
                           print_idecode_switch_end, (void *) result);
577
}
578
 
579
 
580
static void
581
print_idecode_switch_function_header (lf *file,
582
                                      gen_entry *table,
583
                                      int is_function_definition,
584
                                      int nr_prefetched_words)
585
{
586
  lf_printf (file, "\n");
587
  if (options.gen.code == generate_calls)
588
    {
589
      lf_printf (file, "static ");
590
      if (options.gen.icache)
591
        {
592
          lf_printf (file, "idecode_semantic *");
593
        }
594
      else
595
        {
596
          lf_printf (file, "unsigned_word");
597
        }
598
      if (is_function_definition)
599
        {
600
          lf_printf (file, "\n");
601
        }
602
      else
603
        {
604
          lf_printf (file, " ");
605
        }
606
      lf_print_table_name (file, table);
607
      lf_printf (file, "\n(");
608
      print_icache_function_formal (file, nr_prefetched_words);
609
      lf_printf (file, ")");
610
      if (!is_function_definition)
611
        {
612
          lf_printf (file, ";");
613
        }
614
      lf_printf (file, "\n");
615
    }
616
  if (options.gen.code == generate_jumps && is_function_definition)
617
    {
618
      lf_indent (file, -1);
619
      lf_print_table_name (file, table);
620
      lf_printf (file, ":\n");
621
      lf_indent (file, +1);
622
    }
623
}
624
 
625
 
626
static void
627
idecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data)
628
{
629
  if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL     /* don't declare the top one yet */
630
      && table->parent->opcode_rule->gen == array_gen)
631
    {
632
      print_idecode_switch_function_header (file,
633
                                            table,
634
 
635
                                            0);
636
    }
637
}
638
 
639
 
640
static void
641
idecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data)
642
{
643
  if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL     /* don't expand the top one yet */
644
      && table->parent->opcode_rule->gen == array_gen)
645
    {
646
      print_idecode_switch_function_header (file,
647
                                            table,
648
                                            1 /*is function definition */ ,
649
                                            0);
650
      if (options.gen.code == generate_calls)
651
        {
652
          lf_printf (file, "{\n");
653
          lf_indent (file, +2);
654
        }
655
      print_idecode_switch (file, table, "return");
656
      if (options.gen.code == generate_calls)
657
        {
658
          lf_indent (file, -2);
659
          lf_printf (file, "}\n");
660
        }
661
    }
662
}
663
 
664
 
665
/****************************************************************/
666
 
667
 
668
void
669
print_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules)
670
{
671
  int depth;
672
 
673
  /* output switch function declarations where needed by tables */
674
  gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch,   /* START */
675
                           NULL, NULL, NULL);
676
 
677
  /* output tables where needed */
678
  for (depth = gen_entry_depth (table); depth > 0; depth--)
679
    {
680
      gen_entry_traverse_tree (file, table,
681
                               1 - depth,
682
                               print_idecode_table_start,
683
                               print_idecode_table_leaf,
684
                               print_idecode_table_end, NULL);
685
    }
686
 
687
  /* output switch functions where needed */
688
  gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch,    /* START */
689
                           NULL, NULL, NULL);
690
}
691
 
692
 
693
void
694
print_idecode_body (lf *file, gen_entry *table, const char *result)
695
{
696
  if (table->opcode_rule->gen == switch_gen
697
      || table->opcode_rule->gen == goto_switch_gen
698
      || table->opcode_rule->gen == padded_switch_gen)
699
    {
700
      print_idecode_switch (file, table, result);
701
    }
702
  else
703
    {
704
      print_idecode_table (file, table, result);
705
    }
706
}
707
 
708
 
709
/****************************************************************/
710
 
711
#if 0
712
static void
713
print_jump (lf *file, int is_tail)
714
{
715
  if (is_tail)
716
    {
717
      lf_putstr (file, "if (keep_running != NULL && !*keep_running)\n");
718
      lf_putstr (file, "  cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n");
719
    }
720
 
721
  if (!options.generate_smp)
722
    {
723
      lf_putstr (file, "if (WITH_EVENTS) {\n");
724
      lf_putstr (file, "  if (event_queue_tick(events)) {\n");
725
      lf_putstr (file, "    cpu_set_program_counter(cpu, nia);\n");
726
      lf_putstr (file, "    event_queue_process(events);\n");
727
      lf_putstr (file, "    nia = cpu_get_program_counter(cpu);\n");
728
      lf_putstr (file, "  }\n");
729
      lf_putstr (file, "}\n");
730
    }
731
 
732
  if (options.generate_smp)
733
    {
734
      if (is_tail)
735
        {
736
          lf_putstr (file, "cpu_set_program_counter(cpu, nia);\n");
737
        }
738
      lf_putstr (file, "if (WITH_EVENTS) {\n");
739
      lf_putstr (file, "  current_cpu += 1;\n");
740
      lf_putstr (file, "  if (current_cpu >= nr_cpus) {\n");
741
      lf_putstr (file, "    if (event_queue_tick(events)) {\n");
742
      lf_putstr (file, "      event_queue_process(events);\n");
743
      lf_putstr (file, "    }\n");
744
      lf_putstr (file, "    current_cpu = 0;\n");
745
      lf_putstr (file, "  }\n");
746
      lf_putstr (file, "}\n");
747
      lf_putstr (file, "else {\n");
748
      lf_putstr (file, "  current_cpu = (current_cpu + 1) % nr_cpus;\n");
749
      lf_putstr (file, "}\n");
750
      lf_putstr (file, "cpu = cpus[current_cpu];\n");
751
      lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
752
    }
753
 
754
  if (options.gen.icache)
755
    {
756
      lf_putstr (file, "cache_entry = cpu_icache_entry(cpu, nia);\n");
757
      lf_putstr (file, "if (cache_entry->address == nia) {\n");
758
      lf_putstr (file, "  /* cache hit */\n");
759
      lf_putstr (file, "  goto *cache_entry->semantic;\n");
760
      lf_putstr (file, "}\n");
761
      if (is_tail)
762
        {
763
          lf_putstr (file, "goto cache_miss;\n");
764
        }
765
    }
766
 
767
  if (!options.gen.icache && is_tail)
768
    {
769
      lf_printf (file, "goto idecode;\n");
770
    }
771
 
772
}
773
#endif
774
 
775
 
776
 
777
#if 0
778
static void
779
print_jump_insn (lf *file,
780
                 insn_entry * instruction,
781
                 insn_bits * expanded_bits,
782
                 opcode_field *opcodes, cache_entry *cache_rules)
783
{
784
 
785
  /* what we are for the moment */
786
  lf_printf (file, "\n");
787
  print_my_defines (file, expanded_bits, instruction->name);
788
 
789
  /* output the icache entry */
790
  if (options.gen.icache)
791
    {
792
      lf_printf (file, "\n");
793
      lf_indent (file, -1);
794
      print_function_name (file,
795
                           instruction->name,
796
                           expanded_bits, function_name_prefix_icache);
797
      lf_printf (file, ":\n");
798
      lf_indent (file, +1);
799
      lf_printf (file, "{\n");
800
      lf_indent (file, +2);
801
      lf_putstr (file, "const unsigned_word cia = nia;\n");
802
      print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
803
      print_idecode_validate (file, instruction, opcodes);
804
      lf_printf (file, "\n");
805
      lf_printf (file, "{\n");
806
      lf_indent (file, +2);
807
      print_icache_body (file, instruction, expanded_bits, cache_rules, 0,       /*use_defines */
808
                         put_values_in_icache);
809
      lf_printf (file, "cache_entry->address = nia;\n");
810
      lf_printf (file, "cache_entry->semantic = &&");
811
      print_function_name (file,
812
                           instruction->name,
813
                           expanded_bits, function_name_prefix_semantics);
814
      lf_printf (file, ";\n");
815
      if (options.gen.semantic_icache)
816
        {
817
          print_semantic_body (file, instruction, expanded_bits, opcodes);
818
          print_jump (file, 1 /*is-tail */ );
819
        }
820
      else
821
        {
822
          lf_printf (file, "/* goto ");
823
          print_function_name (file,
824
                               instruction->name,
825
                               expanded_bits, function_name_prefix_semantics);
826
          lf_printf (file, "; */\n");
827
        }
828
      lf_indent (file, -2);
829
      lf_putstr (file, "}\n");
830
      lf_indent (file, -2);
831
      lf_printf (file, "}\n");
832
    }
833
 
834
  /* print the semantics */
835
  lf_printf (file, "\n");
836
  lf_indent (file, -1);
837
  print_function_name (file,
838
                       instruction->name,
839
                       expanded_bits, function_name_prefix_semantics);
840
  lf_printf (file, ":\n");
841
  lf_indent (file, +1);
842
  lf_printf (file, "{\n");
843
  lf_indent (file, +2);
844
  lf_putstr (file, "const unsigned_word cia = nia;\n");
845
  print_icache_body (file,
846
                     instruction,
847
                     expanded_bits,
848
                     cache_rules,
849
                     (options.gen.direct_access
850
                      ? define_variables
851
                      : declare_variables),
852
                     (options.gen.icache
853
                      ? get_values_from_icache : do_not_use_icache));
854
  print_semantic_body (file, instruction, expanded_bits, opcodes);
855
  if (options.gen.direct_access)
856
    print_icache_body (file,
857
                       instruction,
858
                       expanded_bits,
859
                       cache_rules,
860
                       undef_variables,
861
                       (options.gen.icache
862
                        ? get_values_from_icache : do_not_use_icache));
863
  print_jump (file, 1 /*is tail */ );
864
  lf_indent (file, -2);
865
  lf_printf (file, "}\n");
866
}
867
#endif
868
 
869
 
870
#if 0
871
static void
872
print_jump_definition (lf *file,
873
                       gen_entry *entry,
874
                       insn_entry * insn, int depth, void *data)
875
{
876
  cache_entry *cache_rules = (cache_entry *) data;
877
  if (options.generate_expanded_instructions)
878
    {
879
      ASSERT (entry->nr_insns == 1
880
              && entry->opcode == NULL
881
              && entry->parent != NULL && entry->parent->opcode != NULL);
882
      ASSERT (entry->nr_insns == 1
883
              && entry->opcode == NULL
884
              && entry->parent != NULL
885
              && entry->parent->opcode != NULL
886
              && entry->parent->opcode_rule != NULL);
887
      print_jump_insn (file,
888
                       entry->insns->words[0]->insn,
889
                       entry->expanded_bits, entry->opcode, cache_rules);
890
    }
891
  else
892
    {
893
      print_jump_insn (file,
894
                       instruction->words[0]->insn, NULL, NULL, cache_rules);
895
    }
896
}
897
#endif
898
 
899
#if 0
900
static void
901
print_jump_internal_function (lf *file,
902
                              gen_entry *table,
903
                              function_entry * function, void *data)
904
{
905
  if (function->is_internal)
906
    {
907
      lf_printf (file, "\n");
908
      lf_print__line_ref (file, function->line);
909
      lf_indent (file, -1);
910
      print_function_name (file,
911
                           function->name,
912
                           NULL,
913
                           (options.gen.icache
914
                            ? function_name_prefix_icache
915
                            : function_name_prefix_semantics));
916
      lf_printf (file, ":\n");
917
      lf_indent (file, +1);
918
      lf_printf (file, "{\n");
919
      lf_indent (file, +2);
920
      lf_printf (file, "const unsigned_word cia = nia;\n");
921
      table_print_code (file, function->code);
922
      lf_print__internal_ref (file);
923
      print_sim_engine_abort (file, "Internal function must longjump");
924
      lf_indent (file, -2);
925
      lf_printf (file, "}\n");
926
    }
927
}
928
#endif
929
 
930
 
931
 
932
#if 0
933
static void
934
print_jump_until_stop_body (lf *file,
935
                            insn_table *table, cache_table * cache_rules)
936
{
937
  lf_printf (file, "{\n");
938
  lf_indent (file, +2);
939
  lf_putstr (file, "jmp_buf halt;\n");
940
  lf_putstr (file, "jmp_buf restart;\n");
941
  lf_putstr (file, "sim_cpu *cpu = NULL;\n");
942
  lf_putstr (file, "unsigned_word nia = -1;\n");
943
  lf_putstr (file, "instruction_word instruction = 0;\n");
944
  if ((code & generate_with_icache))
945
    {
946
      lf_putstr (file, "idecode_cache *cache_entry = NULL;\n");
947
    }
948
  if (generate_smp)
949
    {
950
      lf_putstr (file, "int current_cpu = -1;\n");
951
    }
952
 
953
  /* all the switches and tables - they know about jumping */
954
  print_idecode_lookups (file, table, cache_rules);
955
 
956
  /* start the simulation up */
957
  if ((code & generate_with_icache))
958
    {
959
      lf_putstr (file, "\n");
960
      lf_putstr (file, "{\n");
961
      lf_putstr (file, "  int cpu_nr;\n");
962
      lf_putstr (file, "  for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
963
      lf_putstr (file, "    cpu_flush_icache(cpus[cpu_nr]);\n");
964
      lf_putstr (file, "}\n");
965
    }
966
 
967
  lf_putstr (file, "\n");
968
  lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
969
 
970
  lf_putstr (file, "\n");
971
  lf_putstr (file, "if (setjmp(halt))\n");
972
  lf_putstr (file, "  return;\n");
973
 
974
  lf_putstr (file, "\n");
975
  lf_putstr (file, "setjmp(restart);\n");
976
 
977
  lf_putstr (file, "\n");
978
  if (!generate_smp)
979
    {
980
      lf_putstr (file, "cpu = cpus[0];\n");
981
      lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
982
    }
983
  else
984
    {
985
      lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
986
    }
987
 
988
  if (!(code & generate_with_icache))
989
    {
990
      lf_printf (file, "\n");
991
      lf_indent (file, -1);
992
      lf_printf (file, "idecode:\n");
993
      lf_indent (file, +1);
994
    }
995
 
996
  print_jump (file, 0 /*is_tail */ );
997
 
998
  if ((code & generate_with_icache))
999
    {
1000
      lf_indent (file, -1);
1001
      lf_printf (file, "cache_miss:\n");
1002
      lf_indent (file, +1);
1003
    }
1004
 
1005
  lf_putstr (file, "instruction\n");
1006
  lf_putstr (file, "  = vm_instruction_map_read(cpu_instruction_map(cpu),\n");
1007
  lf_putstr (file, "                            cpu, nia);\n");
1008
  print_idecode_body (file, table, "/*IGORE*/");
1009
 
1010
  /* print out a table of all the internals functions */
1011
  insn_table_traverse_function (table,
1012
                                file, NULL, print_jump_internal_function);
1013
 
1014
  /* print out a table of all the instructions */
1015
  if (generate_expanded_instructions)
1016
    insn_table_traverse_tree (table, file, cache_rules, 1, NULL,        /* start */
1017
                              print_jump_definition,    /* leaf */
1018
                              NULL,     /* end */
1019
                              NULL);    /* padding */
1020
  else
1021
    insn_table_traverse_insn (table,
1022
                              file, cache_rules, print_jump_definition);
1023
  lf_indent (file, -2);
1024
  lf_printf (file, "}\n");
1025
}
1026
#endif
1027
 
1028
/****************************************************************/
1029
 
1030
 
1031
 
1032
/* Output code to do any final checks on the decoded instruction.
1033
   This includes things like verifying any on decoded fields have the
1034
   correct value and checking that (for floating point) floating point
1035
   hardware isn't disabled */
1036
 
1037
void
1038
print_idecode_validate (lf *file,
1039
                        insn_entry * instruction, insn_opcodes *opcode_paths)
1040
{
1041
  /* Validate: unchecked instruction fields
1042
 
1043
     If any constant fields in the instruction were not checked by the
1044
     idecode tables, output code to check that they have the correct
1045
     value here */
1046
  {
1047
    int nr_checks = 0;
1048
    int word_nr;
1049
    lf_printf (file, "\n");
1050
    lf_indent_suppress (file);
1051
    lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n");
1052
    lf_printf (file, "/* validate: ");
1053
    print_insn_words (file, instruction);
1054
    lf_printf (file, " */\n");
1055
    for (word_nr = 0; word_nr < instruction->nr_words; word_nr++)
1056
      {
1057
        insn_uint check_mask = 0;
1058
        insn_uint check_val = 0;
1059
        insn_word_entry *word = instruction->word[word_nr];
1060
        int bit_nr;
1061
 
1062
        /* form check_mask/check_val containing what needs to be checked
1063
           in the instruction */
1064
        for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1065
          {
1066
            insn_bit_entry *bit = word->bit[bit_nr];
1067
            insn_field_entry *field = bit->field;
1068
 
1069
            /* Make space for the next bit */
1070
            check_mask <<= 1;
1071
            check_val <<= 1;
1072
 
1073
            /* Only need to validate constant (and reserved)
1074
               bits. Skip any others */
1075
            if (field->type != insn_field_int
1076
                && field->type != insn_field_reserved)
1077
              continue;
1078
 
1079
            /* Look through the list of opcode paths that lead to this
1080
               instruction.  See if any have failed to check the
1081
               relevant bit */
1082
            if (opcode_paths != NULL)
1083
              {
1084
                insn_opcodes *entry;
1085
                for (entry = opcode_paths; entry != NULL; entry = entry->next)
1086
                  {
1087
                    opcode_field *opcode;
1088
                    for (opcode = entry->opcode;
1089
                         opcode != NULL; opcode = opcode->parent)
1090
                      {
1091
                        if (opcode->word_nr == word_nr
1092
                            && opcode->first <= bit_nr
1093
                            && opcode->last >= bit_nr)
1094
                          /* we've decoded on this bit */
1095
                          break;
1096
                      }
1097
                    if (opcode == NULL)
1098
                      /* the bit wasn't decoded on */
1099
                      break;
1100
                  }
1101
                if (entry == NULL)
1102
                  /* all the opcode paths decoded on BIT_NR, no need
1103
                     to check it */
1104
                  continue;
1105
              }
1106
 
1107
            check_mask |= 1;
1108
            check_val |= bit->value;
1109
          }
1110
 
1111
        /* if any bits not checked by opcode tables, output code to check them */
1112
        if (check_mask)
1113
          {
1114
            if (nr_checks == 0)
1115
              {
1116
                lf_printf (file, "if (WITH_RESERVED_BITS)\n");
1117
                lf_printf (file, "  {\n");
1118
                lf_indent (file, +4);
1119
              }
1120
            nr_checks++;
1121
            if (options.insn_bit_size > 32)
1122
              {
1123
                lf_printf (file, "if ((instruction_%d\n", word_nr);
1124
                lf_printf (file, "     & UNSIGNED64 (0x%08lx%08lx))\n",
1125
                           (unsigned long) (check_mask >> 32),
1126
                           (unsigned long) (check_mask));
1127
                lf_printf (file, "    != UNSIGNED64 (0x%08lx%08lx))\n",
1128
                           (unsigned long) (check_val >> 32),
1129
                           (unsigned long) (check_val));
1130
              }
1131
            else
1132
              {
1133
                lf_printf (file,
1134
                           "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
1135
                           word_nr, (unsigned long) (check_mask),
1136
                           (unsigned long) (check_val));
1137
              }
1138
            lf_indent (file, +2);
1139
            print_idecode_invalid (file, "return", invalid_illegal);
1140
            lf_indent (file, -2);
1141
          }
1142
      }
1143
    if (nr_checks > 0)
1144
      {
1145
        lf_indent (file, -4);
1146
        lf_printf (file, "  }\n");
1147
      }
1148
    lf_indent_suppress (file);
1149
    lf_printf (file, "#endif\n");
1150
  }
1151
 
1152
  /* Validate: Floating Point hardware
1153
 
1154
     If the simulator is being built with out floating point hardware
1155
     (different to it being disabled in the MSR) then floating point
1156
     instructions are invalid */
1157
  {
1158
    if (filter_is_member (instruction->flags, "f"))
1159
      {
1160
        lf_printf (file, "\n");
1161
        lf_indent_suppress (file);
1162
        lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");
1163
        lf_printf (file, "/* Validate: FP hardware exists */\n");
1164
        lf_printf (file,
1165
                   "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
1166
        lf_indent (file, +2);
1167
        print_idecode_invalid (file, "return", invalid_illegal);
1168
        lf_indent (file, -2);
1169
        lf_printf (file, "}\n");
1170
        lf_indent_suppress (file);
1171
        lf_printf (file, "#endif\n");
1172
      }
1173
  }
1174
 
1175
  /* Validate: Floating Point available
1176
 
1177
     If floating point is not available, we enter a floating point
1178
     unavailable interrupt into the cache instead of the instruction
1179
     proper.
1180
 
1181
     The PowerPC spec requires a CSI after MSR[FP] is changed and when
1182
     ever a CSI occures we flush the instruction cache. */
1183
 
1184
  {
1185
    if (filter_is_member (instruction->flags, "f"))
1186
      {
1187
        lf_printf (file, "\n");
1188
        lf_indent_suppress (file);
1189
        lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n");
1190
        lf_printf (file, "/* Validate: FP available according to cpu */\n");
1191
        lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");
1192
        lf_indent (file, +2);
1193
        print_idecode_invalid (file, "return", invalid_fp_unavailable);
1194
        lf_indent (file, -2);
1195
        lf_printf (file, "}\n");
1196
        lf_indent_suppress (file);
1197
        lf_printf (file, "#endif\n");
1198
      }
1199
  }
1200
 
1201
  /* Validate: Validate Instruction in correct slot
1202
 
1203
     Some architectures place restrictions on the slot that an
1204
     instruction can be issued in */
1205
 
1206
  {
1207
    if (filter_is_member (instruction->options, "s")
1208
        || options.gen.slot_verification)
1209
      {
1210
        lf_printf (file, "\n");
1211
        lf_indent_suppress (file);
1212
        lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");
1213
        lf_printf (file,
1214
                   "/* Validate: Instruction issued in correct slot */\n");
1215
        lf_printf (file, "if (IS_WRONG_SLOT) {\n");
1216
        lf_indent (file, +2);
1217
        print_idecode_invalid (file, "return", invalid_wrong_slot);
1218
        lf_indent (file, -2);
1219
        lf_printf (file, "}\n");
1220
        lf_indent_suppress (file);
1221
        lf_printf (file, "#endif\n");
1222
      }
1223
  }
1224
 
1225
}
1226
 
1227
 
1228
/****************************************************************/
1229
 
1230
 
1231
void
1232
print_idecode_issue_function_header (lf *file,
1233
                                     const char *processor,
1234
                                     function_decl_type decl_type,
1235
                                     int nr_prefetched_words)
1236
{
1237
  int indent;
1238
  lf_printf (file, "\n");
1239
  switch (decl_type)
1240
    {
1241
    case is_function_declaration:
1242
      lf_print__function_type_function (file, print_semantic_function_type,
1243
                                        "INLINE_IDECODE", " ");
1244
      break;
1245
    case is_function_definition:
1246
      lf_print__function_type_function (file, print_semantic_function_type,
1247
                                        "INLINE_IDECODE", "\n");
1248
      break;
1249
    case is_function_variable:
1250
      print_semantic_function_type (file);
1251
      lf_printf (file, " (*");
1252
      break;
1253
    }
1254
  indent = print_function_name (file,
1255
                                "issue",
1256
                                NULL,
1257
                                processor,
1258
                                NULL, function_name_prefix_idecode);
1259
  switch (decl_type)
1260
    {
1261
    case is_function_definition:
1262
      indent += lf_printf (file, " (");
1263
      break;
1264
    case is_function_declaration:
1265
      lf_putstr (file, "\n(");
1266
      indent = 1;
1267
      break;
1268
    case is_function_variable:
1269
      lf_putstr (file, ")\n(");
1270
      indent = 1;
1271
      break;
1272
    }
1273
  lf_indent (file, +indent);
1274
  print_semantic_function_formal (file, nr_prefetched_words);
1275
  lf_putstr (file, ")");
1276
  lf_indent (file, -indent);
1277
  switch (decl_type)
1278
    {
1279
    case is_function_definition:
1280
      lf_printf (file, "\n");
1281
      break;
1282
    case is_function_declaration:
1283
    case is_function_variable:
1284
      lf_putstr (file, ";\n");
1285
      break;
1286
    }
1287
}
1288
 
1289
 
1290
 
1291
void
1292
print_idecode_globals (lf *file)
1293
{
1294
  lf_printf (file, "enum {\n");
1295
  lf_printf (file, "  /* greater or equal to zero => table */\n");
1296
  lf_printf (file, "  function_entry = -1,\n");
1297
  lf_printf (file, "  boolean_entry = -2,\n");
1298
  lf_printf (file, "};\n");
1299
  lf_printf (file, "\n");
1300
  lf_printf (file, "typedef struct _idecode_table_entry {\n");
1301
  lf_printf (file, "  int shift;\n");
1302
  lf_printf (file, "  unsigned%d mask;\n", options.insn_bit_size);
1303
  lf_printf (file, "  unsigned%d value;\n", options.insn_bit_size);
1304
  lf_printf (file, "  void *function_or_table;\n");
1305
  lf_printf (file, "} idecode_table_entry;\n");
1306
}

powered by: WebSVN 2.1.0

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