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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [sim/] [igen/] [igen.c] - Blame information for rev 258

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

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

powered by: WebSVN 2.1.0

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