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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [igen/] [gen-idecode.c] - Blame information for rev 233

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

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

powered by: WebSVN 2.1.0

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