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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [igen/] [igen.c] - Blame information for rev 1767

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

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

powered by: WebSVN 2.1.0

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