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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [igen/] [igen.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
 
26
#include <getopt.h>
27
 
28
#include "misc.h"
29
#include "lf.h"
30
#include "table.h"
31
#include "config.h"
32
#include "filter.h"
33
 
34
#include "igen.h"
35
 
36
#include "ld-insn.h"
37
#include "ld-decode.h"
38
#include "ld-cache.h"
39
 
40
#include "gen.h"
41
 
42
#include "gen-model.h"
43
#include "gen-icache.h"
44
#include "gen-itable.h"
45
#include "gen-idecode.h"
46
#include "gen-semantics.h"
47
#include "gen-engine.h"
48
#include "gen-support.h"
49
#include "gen-engine.h"
50
 
51
 
52
/****************************************************************/
53
 
54
 
55
/* Semantic functions */
56
 
57
int
58
print_semantic_function_formal (lf *file, int nr_prefetched_words)
59
{
60
  int nr = 0;
61
  int word_nr;
62
  if (options.gen.icache || nr_prefetched_words < 0)
63
    {
64
      nr += lf_printf (file, "SIM_DESC sd,\n");
65
      nr += lf_printf (file, "%sidecode_cache *cache_entry,\n",
66
                       options.module.global.prefix.l);
67
      nr += lf_printf (file, "%sinstruction_address cia",
68
                       options.module.global.prefix.l);
69
    }
70
  else if (options.gen.smp)
71
    {
72
      nr += lf_printf (file, "sim_cpu *cpu,\n");
73
      for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
74
        {
75
          nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
76
                           options.module.global.prefix.l, word_nr);
77
        }
78
      nr += lf_printf (file, "%sinstruction_address cia",
79
                       options.module.global.prefix.l);
80
    }
81
  else
82
    {
83
      nr += lf_printf (file, "SIM_DESC sd,\n");
84
      for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
85
        {
86
          nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
87
                           options.module.global.prefix.l, word_nr);
88
        }
89
      nr += lf_printf (file, "%sinstruction_address cia",
90
                       options.module.global.prefix.l);
91
    }
92
  return nr;
93
}
94
 
95
int
96
print_semantic_function_actual (lf *file, int nr_prefetched_words)
97
{
98
  int nr = 0;
99
  int word_nr;
100
  if (options.gen.icache || nr_prefetched_words < 0)
101
    {
102
      nr += lf_printf (file, "sd, cache_entry, cia");
103
    }
104
  else
105
    {
106
      if (options.gen.smp)
107
        nr += lf_printf (file, "cpu");
108
      else
109
        nr += lf_printf (file, "sd");
110
      for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
111
        nr += lf_printf (file, ", instruction_%d", word_nr);
112
      nr += lf_printf (file, ", cia");
113
    }
114
  return nr;
115
}
116
 
117
int
118
print_semantic_function_type (lf *file)
119
{
120
  int nr = 0;
121
  nr += lf_printf (file, "%sinstruction_address",
122
                   options.module.global.prefix.l);
123
  return nr;
124
}
125
 
126
 
127
/* Idecode functions */
128
 
129
int
130
print_icache_function_formal (lf *file, int nr_prefetched_words)
131
{
132
  int nr = 0;
133
  int word_nr;
134
  if (options.gen.smp)
135
    nr += lf_printf (file, "sim_cpu *cpu,\n");
136
  else
137
    nr += lf_printf (file, "SIM_DESC sd,\n");
138
  for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
139
    nr += lf_printf (file, " %sinstruction_word instruction_%d,\n",
140
                     options.module.global.prefix.l, word_nr);
141
  nr += lf_printf (file, " %sinstruction_address cia,\n",
142
                   options.module.global.prefix.l);
143
  nr += lf_printf (file, " %sidecode_cache *cache_entry",
144
                   options.module.global.prefix.l);
145
  return nr;
146
}
147
 
148
int
149
print_icache_function_actual (lf *file, int nr_prefetched_words)
150
{
151
  int nr = 0;
152
  int word_nr;
153
  if (options.gen.smp)
154
    nr += lf_printf (file, "cpu");
155
  else
156
    nr += lf_printf (file, "sd");
157
  for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
158
    nr += lf_printf (file, ", instruction_%d", word_nr);
159
  nr += lf_printf (file, ", cia, cache_entry");
160
  return nr;
161
}
162
 
163
int
164
print_icache_function_type (lf *file)
165
{
166
  int nr;
167
  if (options.gen.semantic_icache)
168
    {
169
      nr = print_semantic_function_type (file);
170
    }
171
  else
172
    {
173
      nr = lf_printf (file, "%sidecode_semantic *",
174
                      options.module.global.prefix.l);
175
    }
176
  return nr;
177
}
178
 
179
 
180
/* Function names */
181
 
182
static int
183
print_opcode_bits (lf *file, opcode_bits *bits)
184
{
185
  int nr = 0;
186
  if (bits == NULL)
187
    return nr;
188
  nr += lf_putchr (file, '_');
189
  nr += lf_putstr (file, bits->field->val_string);
190
  if (bits->opcode->is_boolean && bits->value == 0)
191
    nr += lf_putint (file, bits->opcode->boolean_constant);
192
  else if (!bits->opcode->is_boolean)
193
    {
194
      if (bits->opcode->last < bits->field->last)
195
        nr +=
196
          lf_putint (file,
197
                     bits->value << (bits->field->last - bits->opcode->last));
198
      else
199
        nr += lf_putint (file, bits->value);
200
    }
201
  nr += print_opcode_bits (file, bits->next);
202
  return nr;
203
}
204
 
205
static int
206
print_c_name (lf *file, const char *name)
207
{
208
  int nr = 0;
209
  const char *pos;
210
  for (pos = name; *pos != '\0'; pos++)
211
    {
212
      switch (*pos)
213
        {
214
        case '/':
215
        case '-':
216
          break;
217
        case ' ':
218
        case '.':
219
          nr += lf_putchr (file, '_');
220
          break;
221
        default:
222
          nr += lf_putchr (file, *pos);
223
          break;
224
        }
225
    }
226
  return nr;
227
}
228
 
229
extern int
230
print_function_name (lf *file,
231
                     const char *basename,
232
                     const char *format_name,
233
                     const char *model_name,
234
                     opcode_bits *expanded_bits,
235
                     lf_function_name_prefixes prefix)
236
{
237
  int nr = 0;
238
  /* the prefix */
239
  switch (prefix)
240
    {
241
    case function_name_prefix_semantics:
242
      nr += lf_printf (file, "%s", options.module.semantics.prefix.l);
243
      nr += lf_printf (file, "semantic_");
244
      break;
245
    case function_name_prefix_idecode:
246
      nr += lf_printf (file, "%s", options.module.idecode.prefix.l);
247
      nr += lf_printf (file, "idecode_");
248
      break;
249
    case function_name_prefix_itable:
250
      nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l);
251
      break;
252
    case function_name_prefix_icache:
253
      nr += lf_printf (file, "%s", options.module.icache.prefix.l);
254
      nr += lf_printf (file, "icache_");
255
      break;
256
    case function_name_prefix_engine:
257
      nr += lf_printf (file, "%s", options.module.engine.prefix.l);
258
      nr += lf_printf (file, "engine_");
259
    default:
260
      break;
261
    }
262
 
263
  if (model_name != NULL)
264
    {
265
      nr += print_c_name (file, model_name);
266
      nr += lf_printf (file, "_");
267
    }
268
 
269
  /* the function name */
270
  nr += print_c_name (file, basename);
271
 
272
  /* the format name if available */
273
  if (format_name != NULL)
274
    {
275
      nr += lf_printf (file, "_");
276
      nr += print_c_name (file, format_name);
277
    }
278
 
279
  /* the suffix */
280
  nr += print_opcode_bits (file, expanded_bits);
281
 
282
  return nr;
283
}
284
 
285
 
286
void
287
print_my_defines (lf *file,
288
                  const char *basename,
289
                  const char *format_name, opcode_bits *expanded_bits)
290
{
291
  /* #define MY_INDEX xxxxx */
292
  lf_indent_suppress (file);
293
  lf_printf (file, "#undef MY_INDEX\n");
294
  lf_indent_suppress (file);
295
  lf_printf (file, "#define MY_INDEX ");
296
  print_function_name (file,
297
                       basename, format_name, NULL,
298
                       NULL, function_name_prefix_itable);
299
  lf_printf (file, "\n");
300
  /* #define MY_PREFIX xxxxxx */
301
  lf_indent_suppress (file);
302
  lf_printf (file, "#undef ");
303
  print_function_name (file,
304
                       basename, format_name, NULL,
305
                       expanded_bits, function_name_prefix_none);
306
  lf_printf (file, "\n");
307
  lf_indent_suppress (file);
308
  lf_printf (file, "#undef MY_PREFIX\n");
309
  lf_indent_suppress (file);
310
  lf_printf (file, "#define MY_PREFIX ");
311
  print_function_name (file,
312
                       basename, format_name, NULL,
313
                       expanded_bits, function_name_prefix_none);
314
  lf_printf (file, "\n");
315
  /* #define MY_NAME xxxxxx */
316
  lf_indent_suppress (file);
317
  lf_indent_suppress (file);
318
  lf_printf (file, "#undef MY_NAME\n");
319
  lf_indent_suppress (file);
320
  lf_printf (file, "#define MY_NAME \"");
321
  print_function_name (file,
322
                       basename, format_name, NULL,
323
                       expanded_bits, function_name_prefix_none);
324
  lf_printf (file, "\"\n");
325
}
326
 
327
 
328
static int
329
print_itrace_prefix (lf *file)
330
{
331
  const char *prefix = "trace_prefix (";
332
  int indent = strlen (prefix);
333
  lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n",
334
             prefix);
335
  lf_indent (file, +indent);
336
  lf_printf (file, "%sitable[MY_INDEX].file, \\\n",
337
             options.module.itable.prefix.l);
338
  lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n",
339
             options.module.itable.prefix.l);
340
  lf_printf (file, "\"");
341
  return indent;
342
}
343
 
344
 
345
static void
346
print_itrace_format (lf *file, insn_mnemonic_entry *assembler)
347
{
348
  /* pass=1 is fmt string; pass=2 is arguments */
349
  int pass;
350
  /* print the format string */
351
  for (pass = 1; pass <= 2; pass++)
352
    {
353
      const char *chp = assembler->format;
354
      chp++;                    /* skip the leading quote */
355
      /* write out the format/args */
356
      while (*chp != '\0')
357
        {
358
          if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>'))
359
            {
360
              if (pass == 1)
361
                lf_putchr (file, chp[1]);
362
              chp += 2;
363
            }
364
          else if (chp[0] == '<' || chp[0] == '%')
365
            {
366
              /* parse [ "%" ... ] "<" [ func "#" ] param ">" */
367
              const char *fmt;
368
              const char *func;
369
              int strlen_func;
370
              const char *param;
371
              int strlen_param;
372
              /* the "%" ... "<" format */
373
              fmt = chp;
374
              while (chp[0] != '<' && chp[0] != '\0')
375
                chp++;
376
              if (chp[0] != '<')
377
                error (assembler->line, "Missing `<' after `%%'\n");
378
              chp++;
379
              /* [ "func" # ] OR "param" */
380
              func = chp;
381
              param = chp;
382
              while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0')
383
                chp++;
384
              strlen_func = chp - func;
385
              if (chp[0] == '#')
386
                {
387
                  chp++;
388
                  param = chp;
389
                  while (chp[0] != '>' && chp[0] != '\0')
390
                    chp++;
391
                }
392
              strlen_param = chp - param;
393
              if (chp[0] != '>')
394
                error (assembler->line,
395
                       "Missing closing `>' in assembler string\n");
396
              chp++;
397
              /* now process it */
398
              if (pass == 2)
399
                lf_printf (file, ", \\\n");
400
              if (strncmp (fmt, "<", 1) == 0)
401
                /* implicit long int format */
402
                {
403
                  if (pass == 1)
404
                    lf_printf (file, "%%ld");
405
                  else
406
                    {
407
                      lf_printf (file, "(long) ");
408
                      lf_write (file, param, strlen_param);
409
                    }
410
                }
411
              else if (strncmp (fmt, "%<", 2) == 0)
412
                /* explicit format */
413
                {
414
                  if (pass == 1)
415
                    lf_printf (file, "%%");
416
                  else
417
                    lf_write (file, param, strlen_param);
418
                }
419
              else if (strncmp (fmt, "%s<", 3) == 0)
420
                /* string format */
421
                {
422
                  if (pass == 1)
423
                    lf_printf (file, "%%s");
424
                  else
425
                    {
426
                      lf_printf (file, "%sstr_",
427
                                 options.module.global.prefix.l);
428
                      lf_write (file, func, strlen_func);
429
                      lf_printf (file, " (SD_, ");
430
                      lf_write (file, param, strlen_param);
431
                      lf_printf (file, ")");
432
                    }
433
                }
434
              else if (strncmp (fmt, "%lx<", 4) == 0)
435
                /* simple hex */
436
                {
437
                  if (pass == 1)
438
                    lf_printf (file, "%%lx");
439
                  else
440
                    {
441
                      lf_printf (file, "(unsigned long) ");
442
                      lf_write (file, param, strlen_param);
443
                    }
444
                }
445
              else if (strncmp (fmt, "%#lx<", 5) == 0)
446
                /* simple hex with 0x prefix */
447
                {
448
                  if (pass == 1)
449
                    lf_printf (file, "%%#lx");
450
                  else
451
                    {
452
                      lf_printf (file, "(unsigned long) ");
453
                      lf_write (file, param, strlen_param);
454
                    }
455
                }
456
              else if (strncmp (fmt, "%08lx<", 6) == 0)
457
                /* simple hex */
458
                {
459
                  if (pass == 1)
460
                    lf_printf (file, "%%08lx");
461
                  else
462
                    {
463
                      lf_printf (file, "(unsigned long) ");
464
                      lf_write (file, param, strlen_param);
465
                    }
466
                }
467
              else
468
                error (assembler->line, "Unknown assembler string format\n");
469
            }
470
          else
471
            {
472
              if (pass == 1)
473
                lf_putchr (file, chp[0]);
474
              chp += 1;
475
            }
476
        }
477
    }
478
  lf_printf (file, ");\n");
479
}
480
 
481
 
482
void
483
print_itrace (lf *file, insn_entry * insn, int idecode)
484
{
485
  /* NB: Here we escape each EOLN. This is so that the the compiler
486
     treats a trace function call as a single line.  Consequently any
487
     errors in the line are refered back to the same igen assembler
488
     source line */
489
  const char *phase = (idecode) ? "DECODE" : "INSN";
490
  lf_printf (file, "\n");
491
  lf_indent_suppress (file);
492
  lf_printf (file, "#if defined (WITH_TRACE)\n");
493
  lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n");
494
  lf_printf (file, "if (TRACE_ANY_P (CPU))\n");
495
  lf_printf (file, "  {\n");
496
  lf_indent (file, +4);
497
  {
498
    if (insn->mnemonics != NULL)
499
      {
500
        insn_mnemonic_entry *assembler = insn->mnemonics;
501
        int is_first = 1;
502
        do
503
          {
504
            if (assembler->condition != NULL)
505
              {
506
                int indent;
507
                lf_printf (file, "%sif (%s)\n",
508
                           is_first ? "" : "else ", assembler->condition);
509
                lf_indent (file, +2);
510
                lf_print__line_ref (file, assembler->line);
511
                indent = print_itrace_prefix (file);
512
                print_itrace_format (file, assembler);
513
                lf_print__internal_ref (file);
514
                lf_indent (file, -indent);
515
                lf_indent (file, -2);
516
                if (assembler->next == NULL)
517
                  error (assembler->line,
518
                         "Missing final unconditional assembler\n");
519
              }
520
            else
521
              {
522
                int indent;
523
                if (!is_first)
524
                  {
525
                    lf_printf (file, "else\n");
526
                    lf_indent (file, +2);
527
                  }
528
                lf_print__line_ref (file, assembler->line);
529
                indent = print_itrace_prefix (file);
530
                print_itrace_format (file, assembler);
531
                lf_print__internal_ref (file);
532
                lf_indent (file, -indent);
533
                if (!is_first)
534
                  lf_indent (file, -2);
535
                if (assembler->next != NULL)
536
                  error (assembler->line,
537
                         "Unconditional assembler is not last\n");
538
              }
539
            is_first = 0;
540
            assembler = assembler->next;
541
          }
542
        while (assembler != NULL);
543
      }
544
    else
545
      {
546
        int indent;
547
        lf_indent (file, +2);
548
        lf_print__line_ref (file, insn->line);
549
        indent = print_itrace_prefix (file);
550
        lf_printf (file, "%%s\", \\\n");
551
        lf_printf (file, "itable[MY_INDEX].name);\n");
552
        lf_print__internal_ref (file);
553
        lf_indent (file, -indent);
554
        lf_indent (file, -2);
555
      }
556
    lf_printf (file, "/* trace the instruction execution if enabled */\n");
557
    lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase);
558
    lf_printf (file,
559
               "  trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n",
560
               phase);
561
  }
562
  lf_indent (file, -4);
563
  lf_printf (file, "  }\n");
564
  lf_indent_suppress (file);
565
  lf_printf (file, "#endif\n");
566
}
567
 
568
 
569
void
570
print_sim_engine_abort (lf *file, const char *message)
571
{
572
  lf_printf (file, "sim_engine_abort (SD, CPU, cia, ");
573
  lf_printf (file, "\"%s\"", message);
574
  lf_printf (file, ");\n");
575
}
576
 
577
 
578
void
579
print_include (lf *file, igen_module module)
580
{
581
  lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l);
582
}
583
 
584
void
585
print_include_inline (lf *file, igen_module module)
586
{
587
  lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u);
588
  lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l);
589
  lf_printf (file, "#else\n");
590
  print_include (file, module);
591
  lf_printf (file, "#endif\n");
592
  lf_printf (file, "\n");
593
}
594
 
595
void
596
print_includes (lf *file)
597
{
598
  lf_printf (file, "\n");
599
  lf_printf (file, "#include \"sim-inline.c\"\n");
600
  lf_printf (file, "\n");
601
  print_include_inline (file, options.module.itable);
602
  print_include_inline (file, options.module.idecode);
603
  print_include_inline (file, options.module.support);
604
}
605
 
606
 
607
/****************************************************************/
608
 
609
 
610
static void
611
gen_semantics_h (lf *file, insn_list *semantics, int max_nr_words)
612
{
613
  int word_nr;
614
  insn_list *semantic;
615
  for (word_nr = -1; word_nr <= max_nr_words; word_nr++)
616
    {
617
      lf_printf (file, "typedef ");
618
      print_semantic_function_type (file);
619
      lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l);
620
      if (word_nr >= 0)
621
        lf_printf (file, "_%d", word_nr);
622
      lf_printf (file, "\n(");
623
      lf_indent (file, +1);
624
      print_semantic_function_formal (file, word_nr);
625
      lf_indent (file, -1);
626
      lf_printf (file, ");\n");
627
      lf_printf (file, "\n");
628
    }
629
  switch (options.gen.code)
630
    {
631
    case generate_calls:
632
      for (semantic = semantics; semantic != NULL; semantic = semantic->next)
633
        {
634
          /* Ignore any special/internal instructions */
635
          if (semantic->insn->nr_words == 0)
636
            continue;
637
          print_semantic_declaration (file,
638
                                      semantic->insn,
639
                                      semantic->expanded_bits,
640
                                      semantic->opcodes,
641
                                      semantic->nr_prefetched_words);
642
        }
643
      break;
644
    case generate_jumps:
645
      lf_print__this_file_is_empty (file, "generating jumps");
646
      break;
647
    }
648
}
649
 
650
 
651
static void
652
gen_semantics_c (lf *file, insn_list *semantics, cache_entry *cache_rules)
653
{
654
  if (options.gen.code == generate_calls)
655
    {
656
      insn_list *semantic;
657
      print_includes (file);
658
      print_include (file, options.module.semantics);
659
      lf_printf (file, "\n");
660
 
661
      for (semantic = semantics; semantic != NULL; semantic = semantic->next)
662
        {
663
          /* Ignore any special/internal instructions */
664
          if (semantic->insn->nr_words == 0)
665
            continue;
666
          print_semantic_definition (file,
667
                                     semantic->insn,
668
                                     semantic->expanded_bits,
669
                                     semantic->opcodes,
670
                                     cache_rules,
671
                                     semantic->nr_prefetched_words);
672
        }
673
    }
674
  else
675
    {
676
      lf_print__this_file_is_empty (file, "generating jump engine");
677
    }
678
}
679
 
680
 
681
/****************************************************************/
682
 
683
 
684
static void
685
gen_icache_h (lf *file,
686
              insn_list *semantic,
687
              function_entry * functions, int max_nr_words)
688
{
689
  int word_nr;
690
  for (word_nr = 0; word_nr <= max_nr_words; word_nr++)
691
    {
692
      lf_printf (file, "typedef ");
693
      print_icache_function_type (file);
694
      lf_printf (file, " %sidecode_icache_%d\n(",
695
                 options.module.global.prefix.l, word_nr);
696
      print_icache_function_formal (file, word_nr);
697
      lf_printf (file, ");\n");
698
      lf_printf (file, "\n");
699
    }
700
  if (options.gen.code == generate_calls && options.gen.icache)
701
    {
702
      function_entry_traverse (file, functions,
703
                               print_icache_internal_function_declaration,
704
                               NULL);
705
      while (semantic != NULL)
706
        {
707
          print_icache_declaration (file,
708
                                    semantic->insn,
709
                                    semantic->expanded_bits,
710
                                    semantic->opcodes,
711
                                    semantic->nr_prefetched_words);
712
          semantic = semantic->next;
713
        }
714
    }
715
  else
716
    {
717
      lf_print__this_file_is_empty (file, "generating jump engine");
718
    }
719
}
720
 
721
static void
722
gen_icache_c (lf *file,
723
              insn_list *semantic,
724
              function_entry * functions, cache_entry *cache_rules)
725
{
726
  /* output `internal' invalid/floating-point unavailable functions
727
     where needed */
728
  if (options.gen.code == generate_calls && options.gen.icache)
729
    {
730
      lf_printf (file, "\n");
731
      lf_printf (file, "#include \"cpu.h\"\n");
732
      lf_printf (file, "#include \"idecode.h\"\n");
733
      lf_printf (file, "#include \"semantics.h\"\n");
734
      lf_printf (file, "#include \"icache.h\"\n");
735
      lf_printf (file, "#include \"support.h\"\n");
736
      lf_printf (file, "\n");
737
      function_entry_traverse (file, functions,
738
                               print_icache_internal_function_definition,
739
                               NULL);
740
      lf_printf (file, "\n");
741
      while (semantic != NULL)
742
        {
743
          print_icache_definition (file,
744
                                   semantic->insn,
745
                                   semantic->expanded_bits,
746
                                   semantic->opcodes,
747
                                   cache_rules,
748
                                   semantic->nr_prefetched_words);
749
          semantic = semantic->next;
750
        }
751
    }
752
  else
753
    {
754
      lf_print__this_file_is_empty (file, "generating jump engine");
755
    }
756
}
757
 
758
 
759
/****************************************************************/
760
 
761
 
762
static void
763
gen_idecode_h (lf *file,
764
               gen_table *gen, insn_table *insns, cache_entry *cache_rules)
765
{
766
  lf_printf (file, "typedef unsigned%d %sinstruction_word;\n",
767
             options.insn_bit_size, options.module.global.prefix.l);
768
  if (options.gen.delayed_branch)
769
    {
770
      lf_printf (file, "typedef struct _%sinstruction_address {\n",
771
                 options.module.global.prefix.l);
772
      lf_printf (file, "  address_word ip; /* instruction pointer */\n");
773
      lf_printf (file, "  address_word dp; /* delayed-slot pointer */\n");
774
      lf_printf (file, "} %sinstruction_address;\n",
775
                 options.module.global.prefix.l);
776
    }
777
  else
778
    {
779
      lf_printf (file, "typedef address_word %sinstruction_address;\n",
780
                 options.module.global.prefix.l);
781
 
782
    }
783
  if (options.gen.nia == nia_is_invalid
784
      && strlen (options.module.global.prefix.u) > 0)
785
    {
786
      lf_indent_suppress (file);
787
      lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ",
788
                 options.module.global.prefix.u);
789
      lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n");
790
    }
791
  lf_printf (file, "\n");
792
  print_icache_struct (file, insns, cache_rules);
793
  lf_printf (file, "\n");
794
  if (options.gen.icache)
795
    {
796
      ERROR ("FIXME - idecode with icache suffering from bit-rot");
797
    }
798
  else
799
    {
800
      gen_list *entry;
801
      for (entry = gen->tables; entry != NULL; entry = entry->next)
802
        {
803
          print_idecode_issue_function_header (file,
804
                                               (options.gen.multi_sim
805
                                                ? entry->model->name
806
                                                : NULL),
807
                                               is_function_declaration,
808
                                               1 /*ALWAYS ONE WORD */ );
809
        }
810
      if (options.gen.multi_sim)
811
        {
812
          print_idecode_issue_function_header (file,
813
                                               NULL,
814
                                               is_function_variable,
815
                                               1 /*ALWAYS ONE WORD */ );
816
        }
817
    }
818
}
819
 
820
 
821
static void
822
gen_idecode_c (lf *file,
823
               gen_table *gen, insn_table *isa, cache_entry *cache_rules)
824
{
825
  /* the intro */
826
  print_includes (file);
827
  print_include_inline (file, options.module.semantics);
828
  lf_printf (file, "\n");
829
 
830
  print_idecode_globals (file);
831
  lf_printf (file, "\n");
832
 
833
  switch (options.gen.code)
834
    {
835
    case generate_calls:
836
      {
837
        gen_list *entry;
838
        for (entry = gen->tables; entry != NULL; entry = entry->next)
839
          {
840
            print_idecode_lookups (file, entry->table, cache_rules);
841
 
842
            /* output the main idecode routine */
843
            if (!options.gen.icache)
844
              {
845
                print_idecode_issue_function_header (file,
846
                                                     (options.gen.multi_sim
847
                                                      ? entry->model->name
848
                                                      : NULL),
849
                                                     1 /*is definition */ ,
850
                                                     1 /*ALWAYS ONE WORD */ );
851
                lf_printf (file, "{\n");
852
                lf_indent (file, +2);
853
                lf_printf (file, "%sinstruction_address nia;\n",
854
                           options.module.global.prefix.l);
855
                print_idecode_body (file, entry->table, "nia =");
856
                lf_printf (file, "return nia;");
857
                lf_indent (file, -2);
858
                lf_printf (file, "}\n");
859
              }
860
          }
861
        break;
862
      }
863
    case generate_jumps:
864
      {
865
        lf_print__this_file_is_empty (file, "generating a jump engine");
866
        break;
867
      }
868
    }
869
}
870
 
871
 
872
/****************************************************************/
873
 
874
 
875
static void
876
gen_run_c (lf *file, gen_table *gen)
877
{
878
  gen_list *entry;
879
  lf_printf (file, "#include \"sim-main.h\"\n");
880
  lf_printf (file, "#include \"engine.h\"\n");
881
  lf_printf (file, "#include \"idecode.h\"\n");
882
  lf_printf (file, "#include \"bfd.h\"\n");
883
  lf_printf (file, "\n");
884
 
885
  if (options.gen.multi_sim)
886
    {
887
      print_idecode_issue_function_header (file, NULL, is_function_variable,
888
                                           1);
889
      lf_printf (file, "\n");
890
      print_engine_run_function_header (file, NULL, is_function_variable);
891
      lf_printf (file, "\n");
892
    }
893
 
894
  lf_printf (file, "void\n");
895
  lf_printf (file, "sim_engine_run (SIM_DESC sd,\n");
896
  lf_printf (file, "                int next_cpu_nr,\n");
897
  lf_printf (file, "                int nr_cpus,\n");
898
  lf_printf (file, "                int siggnal)\n");
899
  lf_printf (file, "{\n");
900
  lf_indent (file, +2);
901
  if (options.gen.multi_sim)
902
    {
903
      lf_printf (file, "int mach;\n");
904
      lf_printf (file, "if (STATE_ARCHITECTURE (sd) == NULL)\n");
905
      lf_printf (file, "  mach = 0;\n");
906
      lf_printf (file, "else\n");
907
      lf_printf (file, "  mach = STATE_ARCHITECTURE (sd)->mach;\n");
908
      lf_printf (file, "switch (mach)\n");
909
      lf_printf (file, "  {\n");
910
      lf_indent (file, +2);
911
      for (entry = gen->tables; entry != NULL; entry = entry->next)
912
        {
913
          if (options.gen.default_model != NULL
914
              && (strcmp (entry->model->name, options.gen.default_model) == 0
915
                  || strcmp (entry->model->full_name,
916
                             options.gen.default_model) == 0))
917
            lf_printf (file, "default:\n");
918
          lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name);
919
          lf_indent (file, +2);
920
          print_function_name (file, "issue", NULL,     /* format name */
921
                               NULL,    /* NO processor */
922
                               NULL,    /* expanded bits */
923
                               function_name_prefix_idecode);
924
          lf_printf (file, " = ");
925
          print_function_name (file, "issue", NULL,     /* format name */
926
                               entry->model->name, NULL,        /* expanded bits */
927
                               function_name_prefix_idecode);
928
          lf_printf (file, ";\n");
929
          print_function_name (file, "run", NULL,       /* format name */
930
                               NULL,    /* NO processor */
931
                               NULL,    /* expanded bits */
932
                               function_name_prefix_engine);
933
          lf_printf (file, " = ");
934
          print_function_name (file, "run", NULL,       /* format name */
935
                               entry->model->name, NULL,        /* expanded bits */
936
                               function_name_prefix_engine);
937
          lf_printf (file, ";\n");
938
          lf_printf (file, "break;\n");
939
          lf_indent (file, -2);
940
        }
941
      if (options.gen.default_model == NULL)
942
        {
943
          lf_printf (file, "default:\n");
944
          lf_indent (file, +2);
945
          lf_printf (file, "sim_engine_abort (sd, NULL, NULL_CIA,\n");
946
          lf_printf (file,
947
                     "                  \"sim_engine_run - unknown machine\");\n");
948
          lf_printf (file, "break;\n");
949
          lf_indent (file, -2);
950
        }
951
      lf_indent (file, -2);
952
      lf_printf (file, "  }\n");
953
    }
954
  print_function_name (file, "run", NULL,       /* format name */
955
                       NULL,    /* NO processor */
956
                       NULL,    /* expanded bits */
957
                       function_name_prefix_engine);
958
  lf_printf (file, " (sd, next_cpu_nr, nr_cpus, siggnal);\n");
959
  lf_indent (file, -2);
960
  lf_printf (file, "}\n");
961
}
962
 
963
/****************************************************************/
964
 
965
static gen_table *
966
do_gen (insn_table *isa, decode_table *decode_rules)
967
{
968
  gen_table *gen;
969
  if (decode_rules == NULL)
970
    error (NULL, "Must specify a decode table\n");
971
  if (isa == NULL)
972
    error (NULL, "Must specify an instruction table\n");
973
  if (decode_table_max_word_nr (decode_rules) > 0)
974
    options.gen.multi_word = decode_table_max_word_nr (decode_rules);
975
  gen = make_gen_tables (isa, decode_rules);
976
  gen_tables_expand_insns (gen);
977
  gen_tables_expand_semantics (gen);
978
  return gen;
979
}
980
 
981
/****************************************************************/
982
 
983
igen_options options;
984
 
985
int
986
main (int argc, char **argv, char **envp)
987
{
988
  cache_entry *cache_rules = NULL;
989
  lf_file_references file_references = lf_include_references;
990
  decode_table *decode_rules = NULL;
991
  insn_table *isa = NULL;
992
  gen_table *gen = NULL;
993
  char *real_file_name = NULL;
994
  int is_header = 0;
995
  int ch;
996
  lf *standard_out =
997
    lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen");
998
 
999
  INIT_OPTIONS ();
1000
 
1001
  if (argc == 1)
1002
    {
1003
      printf ("Usage:\n");
1004
      printf ("\n");
1005
      printf ("  igen <config-opts> ... <input-opts>... <output-opts>...\n");
1006
      printf ("\n");
1007
      printf ("Config options:\n");
1008
      printf ("\n");
1009
      printf ("  -B <bit-size>\n");
1010
      printf ("\t Set the number of bits in an instruction (deprecated).\n");
1011
      printf
1012
        ("\t This option can now be set directly in the instruction table.\n");
1013
      printf ("\n");
1014
      printf ("  -D <data-structure>\n");
1015
      printf
1016
        ("\t Dump the specified data structure to stdout. Valid structures include:\n");
1017
      printf
1018
        ("\t processor-names - list the names of all the processors (models)\n");
1019
      printf ("\n");
1020
      printf ("  -F <filter-list>\n");
1021
      printf
1022
        ("\t Filter out any instructions with a non-empty flags field that contains\n");
1023
      printf ("\t a flag not listed in the <filter-list>.\n");
1024
      printf ("\n");
1025
      printf ("  -H <high-bit>\n");
1026
      printf
1027
        ("\t Set the number of the high (most significant) instruction bit (deprecated).\n");
1028
      printf
1029
        ("\t This option can now be set directly in the instruction table.\n");
1030
      printf ("\n");
1031
      printf ("  -I <directory>\n");
1032
      printf
1033
        ("\t Add <directory> to the list of directories searched when opening a file\n");
1034
      printf ("\n");
1035
      printf ("  -M <model-list>\n");
1036
      printf
1037
        ("\t Filter out any instructions that do not support at least one of the listed\n");
1038
      printf
1039
        ("\t models (An instructions with no model information is considered to support\n");
1040
      printf ("\t all models.).\n");
1041
      printf ("\n");
1042
      printf ("  -N <nr-cpus>\n");
1043
      printf ("\t Generate a simulator supporting <nr-cpus>\n");
1044
      printf
1045
        ("\t Specify `-N 0' to disable generation of the SMP. Specifying `-N 1' will\n");
1046
      printf
1047
        ("\t still generate an SMP enabled simulator but will only support one CPU.\n");
1048
      printf ("\n");
1049
      printf ("  -T <mechanism>\n");
1050
      printf
1051
        ("\t Override the decode mechanism specified by the decode rules\n");
1052
      printf ("\n");
1053
      printf ("  -P <prefix>\n");
1054
      printf
1055
        ("\t Prepend global names (except itable) with the string <prefix>.\n");
1056
      printf
1057
        ("\t Specify -P <module>=<prefix> to set a specific <module>'s prefix.\n");
1058
      printf ("\n");
1059
      printf ("  -S <suffix>\n");
1060
      printf
1061
        ("\t Replace a global name (suffix) (except itable) with the string <suffix>.\n");
1062
      printf
1063
        ("\t Specify -S <module>=<suffix> to change a specific <module>'s name (suffix).\n");
1064
      printf ("\n");
1065
      printf ("  -Werror\n");
1066
      printf ("\t Make warnings errors\n");
1067
      printf ("  -Wnodiscard\n");
1068
      printf
1069
        ("\t Suppress warnings about discarded functions and instructions\n");
1070
      printf ("  -Wnowidth\n");
1071
      printf
1072
        ("\t Suppress warnings about instructions with invalid widths\n");
1073
      printf ("  -Wnounimplemented\n");
1074
      printf ("\t Suppress warnings about unimplemented instructions\n");
1075
      printf ("\n");
1076
      printf ("  -G [!]<gen-option>\n");
1077
      printf ("\t Any of the following options:\n");
1078
      printf ("\n");
1079
      printf
1080
        ("\t decode-duplicate       - Override the decode rules, forcing the duplication of\n");
1081
      printf ("\t                          semantic functions\n");
1082
      printf
1083
        ("\t decode-combine         - Combine any duplicated entries within a table\n");
1084
      printf
1085
        ("\t decode-zero-reserved   - Override the decode rules, forcing reserved bits to be\n");
1086
      printf ("\t                          treated as zero.\n");
1087
      printf
1088
        ("\t decode-switch-is-goto  - Overfide the padded-switch code type as a goto-switch\n");
1089
      printf ("\n");
1090
      printf
1091
        ("\t gen-conditional-issue  - conditionally issue each instruction\n");
1092
      printf
1093
        ("\t gen-delayed-branch     - need both cia and nia passed around\n");
1094
      printf
1095
        ("\t gen-direct-access      - use #defines to directly access values\n");
1096
      printf
1097
        ("\t gen-zero-r<N>          - arch assumes GPR(<N>) == 0, keep it that way\n");
1098
      printf
1099
        ("\t gen-icache[=<N>        - generate an instruction cracking cache of size <N>\n");
1100
      printf ("\t                          Default size is %d\n",
1101
              options.gen.icache_size);
1102
      printf
1103
        ("\t gen-insn-in-icache     - save original instruction when cracking\n");
1104
      printf
1105
        ("\t gen-multi-sim[=MODEL]  - generate multiple simulators - one per model\n");
1106
      printf
1107
        ("\t                          If specified MODEL is made the default architecture.\n");
1108
      printf
1109
        ("\t                          By default, a single simulator that will\n");
1110
      printf
1111
        ("\t                          execute any instruction is generated\n");
1112
      printf
1113
        ("\t gen-multi-word         - generate code allowing for multi-word insns\n");
1114
      printf
1115
        ("\t gen-semantic-icache    - include semantic code in cracking functions\n");
1116
      printf
1117
        ("\t gen-slot-verification  - perform slot verification as part of decode\n");
1118
      printf ("\t gen-nia-invalid        - NIA defaults to nia_invalid\n");
1119
      printf ("\t gen-nia-void           - do not compute/return NIA\n");
1120
      printf ("\n");
1121
      printf
1122
        ("\t trace-combine          - report combined entries a rule application\n");
1123
      printf
1124
        ("\t trace-entries          - report entries after a rules application\n");
1125
      printf ("\t trace-rule-rejection   - report each rule as rejected\n");
1126
      printf ("\t trace-rule-selection   - report each rule as selected\n");
1127
      printf
1128
        ("\t trace-insn-insertion   - report each instruction as it is inserted into a decode table\n");
1129
      printf
1130
        ("\t trace-rule-expansion   - report each instruction as it is expanded (before insertion into a decode table)\n");
1131
      printf ("\t trace-all              - enable all trace options\n");
1132
      printf ("\n");
1133
      printf
1134
        ("\t field-widths           - instruction formats specify widths (deprecated)\n");
1135
      printf
1136
        ("\t                          By default, an instruction format specifies bit\n");
1137
      printf ("\t                          positions\n");
1138
      printf
1139
        ("\t                          This option can now be set directly in the\n");
1140
      printf ("\t                          instruction table\n");
1141
      printf
1142
        ("\t jumps                  - use jumps instead of function calls\n");
1143
      printf
1144
        ("\t omit-line-numbers      - do not include line number information in the output\n");
1145
      printf ("\n");
1146
      printf ("Input options:\n");
1147
      printf ("\n");
1148
      printf ("  -k <cache-rules> (deprecated)\n");
1149
      printf ("  -o <decode-rules>\n");
1150
      printf ("  -i <instruction-table>\n");
1151
      printf ("\n");
1152
      printf ("Output options:\n");
1153
      printf ("\n");
1154
      printf ("  -x                    Perform expansion (required)\n");
1155
      printf
1156
        ("  -n <real-name>        Specify the real name of the next output file\n");
1157
      printf
1158
        ("  -h                 Generate the header (.h) file rather than the body (.c)\n");
1159
      printf ("  -c <output-file>      output icache\n");
1160
      printf ("  -d <output-file>      output idecode\n");
1161
      printf ("  -e <output-file>      output engine\n");
1162
      printf ("  -f <output-file>      output support functions\n");
1163
      printf ("  -m <output-file>      output model\n");
1164
      printf ("  -r <output-file>      output multi-sim run\n");
1165
      printf ("  -s <output-file>      output schematic\n");
1166
      printf ("  -t <output-file>      output itable\n");
1167
    }
1168
 
1169
  while ((ch = getopt (argc, argv,
1170
                       "B:D:F:G:H:I:M:N:P:T:W:o:k:i:n:hc:d:e:m:r:s:t:f:x"))
1171
         != -1)
1172
    {
1173
      fprintf (stderr, "  -%c ", ch);
1174
      if (optarg)
1175
        fprintf (stderr, "%s ", optarg);
1176
      fprintf (stderr, "\\\n");
1177
 
1178
      switch (ch)
1179
        {
1180
 
1181
        case 'M':
1182
          filter_parse (&options.model_filter, optarg);
1183
          break;
1184
 
1185
        case 'D':
1186
          if (strcmp (optarg, "processor-names"))
1187
            {
1188
              char *processor;
1189
              for (processor = filter_next (options.model_filter, "");
1190
                   processor != NULL;
1191
                   processor = filter_next (options.model_filter, processor))
1192
                lf_printf (standard_out, "%s\n", processor);
1193
            }
1194
          else
1195
            error (NULL, "Unknown data structure %s, not dumped\n", optarg);
1196
          break;
1197
 
1198
        case 'F':
1199
          filter_parse (&options.flags_filter, optarg);
1200
          break;
1201
 
1202
        case 'I':
1203
          {
1204
            table_include **dir = &options.include;
1205
            while ((*dir) != NULL)
1206
              dir = &(*dir)->next;
1207
            (*dir) = ZALLOC (table_include);
1208
            (*dir)->dir = strdup (optarg);
1209
          }
1210
          break;
1211
 
1212
        case 'B':
1213
          options.insn_bit_size = a2i (optarg);
1214
          if (options.insn_bit_size <= 0
1215
              || options.insn_bit_size > max_insn_bit_size)
1216
            {
1217
              error (NULL, "Instruction bitsize must be in range 1..%d\n",
1218
                     max_insn_bit_size);
1219
            }
1220
          if (options.hi_bit_nr != options.insn_bit_size - 1
1221
              && options.hi_bit_nr != 0)
1222
            {
1223
              error (NULL, "Conflict betweem hi-bit-nr and insn-bit-size\n");
1224
            }
1225
          break;
1226
 
1227
        case 'H':
1228
          options.hi_bit_nr = a2i (optarg);
1229
          if (options.hi_bit_nr != options.insn_bit_size - 1
1230
              && options.hi_bit_nr != 0)
1231
            {
1232
              error (NULL, "Conflict between hi-bit-nr and insn-bit-size\n");
1233
            }
1234
          break;
1235
 
1236
        case 'N':
1237
          options.gen.smp = a2i (optarg);
1238
          break;
1239
 
1240
        case 'P':
1241
        case 'S':
1242
          {
1243
            igen_module *names;
1244
            igen_name *name;
1245
            char *chp;
1246
            chp = strchr (optarg, '=');
1247
            if (chp == NULL)
1248
              {
1249
                names = &options.module.global;
1250
                chp = optarg;
1251
              }
1252
            else
1253
              {
1254
                chp = chp + 1;  /* skip `=' */
1255
                names = NULL;
1256
                if (strncmp (optarg, "global=", chp - optarg) == 0)
1257
                  {
1258
                    names = &options.module.global;
1259
                  }
1260
                if (strncmp (optarg, "engine=", chp - optarg) == 0)
1261
                  {
1262
                    names = &options.module.engine;
1263
                  }
1264
                if (strncmp (optarg, "icache=", chp - optarg) == 0)
1265
                  {
1266
                    names = &options.module.icache;
1267
                  }
1268
                if (strncmp (optarg, "idecode=", chp - optarg) == 0)
1269
                  {
1270
                    names = &options.module.idecode;
1271
                  }
1272
                if (strncmp (optarg, "itable=", chp - optarg) == 0)
1273
                  {
1274
                    names = &options.module.itable;
1275
                  }
1276
                if (strncmp (optarg, "semantics=", chp - optarg) == 0)
1277
                  {
1278
                    names = &options.module.semantics;
1279
                  }
1280
                if (strncmp (optarg, "support=", chp - optarg) == 0)
1281
                  {
1282
                    names = &options.module.support;
1283
                  }
1284
                if (names == NULL)
1285
                  {
1286
                    error (NULL, "Prefix `%s' unreconized\n", optarg);
1287
                  }
1288
              }
1289
            switch (ch)
1290
              {
1291
              case 'P':
1292
                name = &names->prefix;
1293
                break;
1294
              case 'S':
1295
                name = &names->suffix;
1296
                break;
1297
              default:
1298
                abort ();       /* Bad switch.  */
1299
              }
1300
            name->u = strdup (chp);
1301
            name->l = strdup (chp);
1302
            chp = name->u;
1303
            while (*chp)
1304
              {
1305
                if (islower (*chp))
1306
                  *chp = toupper (*chp);
1307
                chp++;
1308
              }
1309
            if (name == &options.module.global.prefix)
1310
              {
1311
                options.module.engine.prefix = options.module.global.prefix;
1312
                options.module.icache.prefix = options.module.global.prefix;
1313
                options.module.idecode.prefix = options.module.global.prefix;
1314
                /* options.module.itable.prefix = options.module.global.prefix; */
1315
                options.module.semantics.prefix =
1316
                  options.module.global.prefix;
1317
                options.module.support.prefix = options.module.global.prefix;
1318
              }
1319
            if (name == &options.module.global.suffix)
1320
              {
1321
                options.module.engine.suffix = options.module.global.suffix;
1322
                options.module.icache.suffix = options.module.global.suffix;
1323
                options.module.idecode.suffix = options.module.global.suffix;
1324
                /* options.module.itable.suffix = options.module.global.suffix; */
1325
                options.module.semantics.suffix =
1326
                  options.module.global.suffix;
1327
                options.module.support.suffix = options.module.global.suffix;
1328
              }
1329
            break;
1330
          }
1331
 
1332
        case 'W':
1333
          {
1334
            if (strcmp (optarg, "error") == 0)
1335
              options.warning = error;
1336
            else if (strcmp (optarg, "nodiscard") == 0)
1337
              options.warn.discard = 0;
1338
            else if (strcmp (optarg, "discard") == 0)
1339
              options.warn.discard = 1;
1340
            else if (strcmp (optarg, "nowidth") == 0)
1341
              options.warn.width = 0;
1342
            else if (strcmp (optarg, "width") == 0)
1343
              options.warn.width = 1;
1344
            else if (strcmp (optarg, "nounimplemented") == 0)
1345
              options.warn.unimplemented = 0;
1346
            else if (strcmp (optarg, "unimplemented") == 0)
1347
              options.warn.unimplemented = 1;
1348
            else
1349
              error (NULL, "Unknown -W argument `%s'\n", optarg);
1350
            break;
1351
          }
1352
 
1353
 
1354
        case 'G':
1355
          {
1356
            int enable_p;
1357
            char *argp;
1358
            if (strncmp (optarg, "no-", strlen ("no-")) == 0)
1359
              {
1360
                argp = optarg + strlen ("no-");
1361
                enable_p = 0;
1362
              }
1363
            else if (strncmp (optarg, "!", strlen ("!")) == 0)
1364
              {
1365
                argp = optarg + strlen ("no-");
1366
                enable_p = 0;
1367
              }
1368
            else
1369
              {
1370
                argp = optarg;
1371
                enable_p = 1;
1372
              }
1373
            if (strcmp (argp, "decode-duplicate") == 0)
1374
              {
1375
                options.decode.duplicate = enable_p;
1376
              }
1377
            else if (strcmp (argp, "decode-combine") == 0)
1378
              {
1379
                options.decode.combine = enable_p;
1380
              }
1381
            else if (strcmp (argp, "decode-zero-reserved") == 0)
1382
              {
1383
                options.decode.zero_reserved = enable_p;
1384
              }
1385
 
1386
            else if (strcmp (argp, "gen-conditional-issue") == 0)
1387
              {
1388
                options.gen.conditional_issue = enable_p;
1389
              }
1390
            else if (strcmp (argp, "conditional-issue") == 0)
1391
              {
1392
                options.gen.conditional_issue = enable_p;
1393
                options.warning (NULL,
1394
                                 "Option conditional-issue replaced by gen-conditional-issue\n");
1395
              }
1396
            else if (strcmp (argp, "gen-delayed-branch") == 0)
1397
              {
1398
                options.gen.delayed_branch = enable_p;
1399
              }
1400
            else if (strcmp (argp, "delayed-branch") == 0)
1401
              {
1402
                options.gen.delayed_branch = enable_p;
1403
                options.warning (NULL,
1404
                                 "Option delayed-branch replaced by gen-delayed-branch\n");
1405
              }
1406
            else if (strcmp (argp, "gen-direct-access") == 0)
1407
              {
1408
                options.gen.direct_access = enable_p;
1409
              }
1410
            else if (strcmp (argp, "direct-access") == 0)
1411
              {
1412
                options.gen.direct_access = enable_p;
1413
                options.warning (NULL,
1414
                                 "Option direct-access replaced by gen-direct-access\n");
1415
              }
1416
            else if (strncmp (argp, "gen-zero-r", strlen ("gen-zero-r")) == 0)
1417
              {
1418
                options.gen.zero_reg = enable_p;
1419
                options.gen.zero_reg_nr = atoi (argp + strlen ("gen-zero-r"));
1420
              }
1421
            else if (strncmp (argp, "zero-r", strlen ("zero-r")) == 0)
1422
              {
1423
                options.gen.zero_reg = enable_p;
1424
                options.gen.zero_reg_nr = atoi (argp + strlen ("zero-r"));
1425
                options.warning (NULL,
1426
                                 "Option zero-r<N> replaced by gen-zero-r<N>\n");
1427
              }
1428
            else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0)
1429
              {
1430
                switch (argp[strlen ("gen-icache")])
1431
                  {
1432
                  case '=':
1433
                    options.gen.icache_size =
1434
                      atoi (argp + strlen ("gen-icache") + 1);
1435
                    options.gen.icache = enable_p;
1436
                    break;
1437
                  case '\0':
1438
                    options.gen.icache = enable_p;
1439
                    break;
1440
                  default:
1441
                    error (NULL,
1442
                           "Expecting -Ggen-icache or -Ggen-icache=<N>\n");
1443
                  }
1444
              }
1445
            else if (strcmp (argp, "gen-insn-in-icache") == 0)
1446
              {
1447
                options.gen.insn_in_icache = enable_p;
1448
              }
1449
            else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim"))
1450
                     == 0)
1451
              {
1452
                char *arg = &argp[strlen ("gen-multi-sim")];
1453
                switch (arg[0])
1454
                  {
1455
                  case '=':
1456
                    options.gen.multi_sim = enable_p;
1457
                    options.gen.default_model = arg + 1;
1458
                    if (!filter_is_member
1459
                        (options.model_filter, options.gen.default_model))
1460
                      error (NULL, "multi-sim model %s unknown\n",
1461
                             options.gen.default_model);
1462
                    break;
1463
                  case '\0':
1464
                    options.gen.multi_sim = enable_p;
1465
                    options.gen.default_model = NULL;
1466
                    break;
1467
                  default:
1468
                    error (NULL,
1469
                           "Expecting -Ggen-multi-sim or -Ggen-multi-sim=<MODEL>\n");
1470
                    break;
1471
                  }
1472
              }
1473
            else if (strcmp (argp, "gen-multi-word") == 0)
1474
              {
1475
                options.gen.multi_word = enable_p;
1476
              }
1477
            else if (strcmp (argp, "gen-semantic-icache") == 0)
1478
              {
1479
                options.gen.semantic_icache = enable_p;
1480
              }
1481
            else if (strcmp (argp, "gen-slot-verification") == 0)
1482
              {
1483
                options.gen.slot_verification = enable_p;
1484
              }
1485
            else if (strcmp (argp, "verify-slot") == 0)
1486
              {
1487
                options.gen.slot_verification = enable_p;
1488
                options.warning (NULL,
1489
                                 "Option verify-slot replaced by gen-slot-verification\n");
1490
              }
1491
            else if (strcmp (argp, "gen-nia-invalid") == 0)
1492
              {
1493
                options.gen.nia = nia_is_invalid;
1494
              }
1495
            else if (strcmp (argp, "default-nia-minus-one") == 0)
1496
              {
1497
                options.gen.nia = nia_is_invalid;
1498
                options.warning (NULL,
1499
                                 "Option default-nia-minus-one replaced by gen-nia-invalid\n");
1500
              }
1501
            else if (strcmp (argp, "gen-nia-void") == 0)
1502
              {
1503
                options.gen.nia = nia_is_void;
1504
              }
1505
            else if (strcmp (argp, "trace-all") == 0)
1506
              {
1507
                memset (&options.trace, enable_p, sizeof (options.trace));
1508
              }
1509
            else if (strcmp (argp, "trace-combine") == 0)
1510
              {
1511
                options.trace.combine = enable_p;
1512
              }
1513
            else if (strcmp (argp, "trace-entries") == 0)
1514
              {
1515
                options.trace.entries = enable_p;
1516
              }
1517
            else if (strcmp (argp, "trace-rule-rejection") == 0)
1518
              {
1519
                options.trace.rule_rejection = enable_p;
1520
              }
1521
            else if (strcmp (argp, "trace-rule-selection") == 0)
1522
              {
1523
                options.trace.rule_selection = enable_p;
1524
              }
1525
            else if (strcmp (argp, "trace-insn-insertion") == 0)
1526
              {
1527
                options.trace.insn_insertion = enable_p;
1528
              }
1529
            else if (strcmp (argp, "trace-insn-expansion") == 0)
1530
              {
1531
                options.trace.insn_expansion = enable_p;
1532
              }
1533
            else if (strcmp (argp, "jumps") == 0)
1534
              {
1535
                options.gen.code = generate_jumps;
1536
              }
1537
            else if (strcmp (argp, "field-widths") == 0)
1538
              {
1539
                options.insn_specifying_widths = enable_p;
1540
              }
1541
            else if (strcmp (argp, "omit-line-numbers") == 0)
1542
              {
1543
                file_references = lf_omit_references;
1544
              }
1545
            else
1546
              {
1547
                error (NULL, "Unknown option %s\n", optarg);
1548
              }
1549
            break;
1550
          }
1551
 
1552
        case 'i':
1553
          isa = load_insn_table (optarg, cache_rules);
1554
          if (isa->illegal_insn == NULL)
1555
            error (NULL, "illegal-instruction missing from insn table\n");
1556
          break;
1557
 
1558
        case 'x':
1559
          gen = do_gen (isa, decode_rules);
1560
          break;
1561
 
1562
        case 'o':
1563
          decode_rules = load_decode_table (optarg);
1564
          break;
1565
 
1566
        case 'k':
1567
          if (isa != NULL)
1568
            error (NULL, "Cache file must appear before the insn file\n");
1569
          cache_rules = load_cache_table (optarg);
1570
          break;
1571
 
1572
        case 'n':
1573
          real_file_name = strdup (optarg);
1574
          break;
1575
 
1576
        case 'h':
1577
          is_header = 1;
1578
          break;
1579
 
1580
        case 'c':
1581
        case 'd':
1582
        case 'e':
1583
        case 'f':
1584
        case 'm':
1585
        case 'r':
1586
        case 's':
1587
        case 't':
1588
          {
1589
            lf *file = lf_open (optarg, real_file_name, file_references,
1590
                                (is_header ? lf_is_h : lf_is_c),
1591
                                argv[0]);
1592
            if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f')
1593
              {
1594
                options.warning (NULL,
1595
                                 "Explicitly generate tables with -x option\n");
1596
                gen = do_gen (isa, decode_rules);
1597
              }
1598
            lf_print__file_start (file);
1599
            switch (ch)
1600
              {
1601
              case 'm':
1602
                if (is_header)
1603
                  gen_model_h (file, isa);
1604
                else
1605
                  gen_model_c (file, isa);
1606
                break;
1607
              case 't':
1608
                if (is_header)
1609
                  gen_itable_h (file, isa);
1610
                else
1611
                  gen_itable_c (file, isa);
1612
                break;
1613
              case 'f':
1614
                if (is_header)
1615
                  gen_support_h (file, isa);
1616
                else
1617
                  gen_support_c (file, isa);
1618
                break;
1619
              case 'r':
1620
                if (is_header)
1621
                  options.warning (NULL, "-hr option ignored\n");
1622
                else
1623
                  gen_run_c (file, gen);
1624
                break;
1625
              case 's':
1626
                if (is_header)
1627
                  gen_semantics_h (file, gen->semantics, isa->max_nr_words);
1628
                else
1629
                  gen_semantics_c (file, gen->semantics, isa->caches);
1630
                break;
1631
              case 'd':
1632
                if (is_header)
1633
                  gen_idecode_h (file, gen, isa, cache_rules);
1634
                else
1635
                  gen_idecode_c (file, gen, isa, cache_rules);
1636
                break;
1637
              case 'e':
1638
                if (is_header)
1639
                  gen_engine_h (file, gen, isa, cache_rules);
1640
                else
1641
                  gen_engine_c (file, gen, isa, cache_rules);
1642
                break;
1643
              case 'c':
1644
                if (is_header)
1645
                  gen_icache_h (file,
1646
                                gen->semantics,
1647
                                isa->functions, isa->max_nr_words);
1648
                else
1649
                  gen_icache_c (file,
1650
                                gen->semantics, isa->functions, cache_rules);
1651
                break;
1652
              }
1653
            lf_print__file_finish (file);
1654
            lf_close (file);
1655
            is_header = 0;
1656
          }
1657
          real_file_name = NULL;
1658
          break;
1659
        default:
1660
          ERROR ("Bad switch");
1661
        }
1662
    }
1663
  return (0);
1664
}

powered by: WebSVN 2.1.0

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