166e63ce3Schristos /* The IGEN simulator generator for GDB, the GNU Debugger.
266e63ce3Schristos
3*1424dfb3Schristos Copyright 2002-2020 Free Software Foundation, Inc.
466e63ce3Schristos
566e63ce3Schristos Contributed by Andrew Cagney.
666e63ce3Schristos
766e63ce3Schristos This file is part of GDB.
866e63ce3Schristos
966e63ce3Schristos This program is free software; you can redistribute it and/or modify
1066e63ce3Schristos it under the terms of the GNU General Public License as published by
1166e63ce3Schristos the Free Software Foundation; either version 3 of the License, or
1266e63ce3Schristos (at your option) any later version.
1366e63ce3Schristos
1466e63ce3Schristos This program is distributed in the hope that it will be useful,
1566e63ce3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1666e63ce3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1766e63ce3Schristos GNU General Public License for more details.
1866e63ce3Schristos
1966e63ce3Schristos You should have received a copy of the GNU General Public License
2066e63ce3Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */
2166e63ce3Schristos
2266e63ce3Schristos
2366e63ce3Schristos
2466e63ce3Schristos #include <getopt.h>
2566e63ce3Schristos
2666e63ce3Schristos #include "misc.h"
2766e63ce3Schristos #include "lf.h"
2866e63ce3Schristos #include "table.h"
2966e63ce3Schristos #include "config.h"
3066e63ce3Schristos #include "filter.h"
3166e63ce3Schristos
3266e63ce3Schristos #include "igen.h"
3366e63ce3Schristos
3466e63ce3Schristos #include "ld-insn.h"
3566e63ce3Schristos #include "ld-decode.h"
3666e63ce3Schristos #include "ld-cache.h"
3766e63ce3Schristos
3866e63ce3Schristos #include "gen.h"
3966e63ce3Schristos
4066e63ce3Schristos #include "gen-model.h"
4166e63ce3Schristos #include "gen-icache.h"
4266e63ce3Schristos #include "gen-itable.h"
4366e63ce3Schristos #include "gen-idecode.h"
4466e63ce3Schristos #include "gen-semantics.h"
4566e63ce3Schristos #include "gen-engine.h"
4666e63ce3Schristos #include "gen-support.h"
4766e63ce3Schristos #include "gen-engine.h"
4866e63ce3Schristos
4966e63ce3Schristos
5066e63ce3Schristos /****************************************************************/
5166e63ce3Schristos
5266e63ce3Schristos
5366e63ce3Schristos /* Semantic functions */
5466e63ce3Schristos
5566e63ce3Schristos int
print_semantic_function_formal(lf * file,int nr_prefetched_words)5666e63ce3Schristos print_semantic_function_formal (lf *file, int nr_prefetched_words)
5766e63ce3Schristos {
5866e63ce3Schristos int nr = 0;
5966e63ce3Schristos int word_nr;
6066e63ce3Schristos if (options.gen.icache || nr_prefetched_words < 0)
6166e63ce3Schristos {
6266e63ce3Schristos nr += lf_printf (file, "SIM_DESC sd,\n");
6366e63ce3Schristos nr += lf_printf (file, "%sidecode_cache *cache_entry,\n",
6466e63ce3Schristos options.module.global.prefix.l);
6566e63ce3Schristos nr += lf_printf (file, "%sinstruction_address cia",
6666e63ce3Schristos options.module.global.prefix.l);
6766e63ce3Schristos }
6866e63ce3Schristos else if (options.gen.smp)
6966e63ce3Schristos {
7066e63ce3Schristos nr += lf_printf (file, "sim_cpu *cpu,\n");
7166e63ce3Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
7266e63ce3Schristos {
7366e63ce3Schristos nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
7466e63ce3Schristos options.module.global.prefix.l, word_nr);
7566e63ce3Schristos }
7666e63ce3Schristos nr += lf_printf (file, "%sinstruction_address cia",
7766e63ce3Schristos options.module.global.prefix.l);
7866e63ce3Schristos }
7966e63ce3Schristos else
8066e63ce3Schristos {
8166e63ce3Schristos nr += lf_printf (file, "SIM_DESC sd,\n");
8266e63ce3Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
8366e63ce3Schristos {
8466e63ce3Schristos nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
8566e63ce3Schristos options.module.global.prefix.l, word_nr);
8666e63ce3Schristos }
8766e63ce3Schristos nr += lf_printf (file, "%sinstruction_address cia",
8866e63ce3Schristos options.module.global.prefix.l);
8966e63ce3Schristos }
9066e63ce3Schristos return nr;
9166e63ce3Schristos }
9266e63ce3Schristos
9366e63ce3Schristos int
print_semantic_function_actual(lf * file,int nr_prefetched_words)9466e63ce3Schristos print_semantic_function_actual (lf *file, int nr_prefetched_words)
9566e63ce3Schristos {
9666e63ce3Schristos int nr = 0;
9766e63ce3Schristos int word_nr;
9866e63ce3Schristos if (options.gen.icache || nr_prefetched_words < 0)
9966e63ce3Schristos {
10066e63ce3Schristos nr += lf_printf (file, "sd, cache_entry, cia");
10166e63ce3Schristos }
10266e63ce3Schristos else
10366e63ce3Schristos {
10466e63ce3Schristos if (options.gen.smp)
10566e63ce3Schristos nr += lf_printf (file, "cpu");
10666e63ce3Schristos else
10766e63ce3Schristos nr += lf_printf (file, "sd");
10866e63ce3Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
10966e63ce3Schristos nr += lf_printf (file, ", instruction_%d", word_nr);
11066e63ce3Schristos nr += lf_printf (file, ", cia");
11166e63ce3Schristos }
11266e63ce3Schristos return nr;
11366e63ce3Schristos }
11466e63ce3Schristos
11566e63ce3Schristos int
print_semantic_function_type(lf * file)11666e63ce3Schristos print_semantic_function_type (lf *file)
11766e63ce3Schristos {
11866e63ce3Schristos int nr = 0;
11966e63ce3Schristos nr += lf_printf (file, "%sinstruction_address",
12066e63ce3Schristos options.module.global.prefix.l);
12166e63ce3Schristos return nr;
12266e63ce3Schristos }
12366e63ce3Schristos
12466e63ce3Schristos
12566e63ce3Schristos /* Idecode functions */
12666e63ce3Schristos
12766e63ce3Schristos int
print_icache_function_formal(lf * file,int nr_prefetched_words)12866e63ce3Schristos print_icache_function_formal (lf *file, int nr_prefetched_words)
12966e63ce3Schristos {
13066e63ce3Schristos int nr = 0;
13166e63ce3Schristos int word_nr;
13266e63ce3Schristos if (options.gen.smp)
13366e63ce3Schristos nr += lf_printf (file, "sim_cpu *cpu,\n");
13466e63ce3Schristos else
13566e63ce3Schristos nr += lf_printf (file, "SIM_DESC sd,\n");
13666e63ce3Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
13766e63ce3Schristos nr += lf_printf (file, " %sinstruction_word instruction_%d,\n",
13866e63ce3Schristos options.module.global.prefix.l, word_nr);
13966e63ce3Schristos nr += lf_printf (file, " %sinstruction_address cia,\n",
14066e63ce3Schristos options.module.global.prefix.l);
14166e63ce3Schristos nr += lf_printf (file, " %sidecode_cache *cache_entry",
14266e63ce3Schristos options.module.global.prefix.l);
14366e63ce3Schristos return nr;
14466e63ce3Schristos }
14566e63ce3Schristos
14666e63ce3Schristos int
print_icache_function_actual(lf * file,int nr_prefetched_words)14766e63ce3Schristos print_icache_function_actual (lf *file, int nr_prefetched_words)
14866e63ce3Schristos {
14966e63ce3Schristos int nr = 0;
15066e63ce3Schristos int word_nr;
15166e63ce3Schristos if (options.gen.smp)
15266e63ce3Schristos nr += lf_printf (file, "cpu");
15366e63ce3Schristos else
15466e63ce3Schristos nr += lf_printf (file, "sd");
15566e63ce3Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
15666e63ce3Schristos nr += lf_printf (file, ", instruction_%d", word_nr);
15766e63ce3Schristos nr += lf_printf (file, ", cia, cache_entry");
15866e63ce3Schristos return nr;
15966e63ce3Schristos }
16066e63ce3Schristos
16166e63ce3Schristos int
print_icache_function_type(lf * file)16266e63ce3Schristos print_icache_function_type (lf *file)
16366e63ce3Schristos {
16466e63ce3Schristos int nr;
16566e63ce3Schristos if (options.gen.semantic_icache)
16666e63ce3Schristos {
16766e63ce3Schristos nr = print_semantic_function_type (file);
16866e63ce3Schristos }
16966e63ce3Schristos else
17066e63ce3Schristos {
17166e63ce3Schristos nr = lf_printf (file, "%sidecode_semantic *",
17266e63ce3Schristos options.module.global.prefix.l);
17366e63ce3Schristos }
17466e63ce3Schristos return nr;
17566e63ce3Schristos }
17666e63ce3Schristos
17766e63ce3Schristos
17866e63ce3Schristos /* Function names */
17966e63ce3Schristos
18066e63ce3Schristos static int
print_opcode_bits(lf * file,opcode_bits * bits)18166e63ce3Schristos print_opcode_bits (lf *file, opcode_bits *bits)
18266e63ce3Schristos {
18366e63ce3Schristos int nr = 0;
18466e63ce3Schristos if (bits == NULL)
18566e63ce3Schristos return nr;
18666e63ce3Schristos nr += lf_putchr (file, '_');
18766e63ce3Schristos nr += lf_putstr (file, bits->field->val_string);
18866e63ce3Schristos if (bits->opcode->is_boolean && bits->value == 0)
18966e63ce3Schristos nr += lf_putint (file, bits->opcode->boolean_constant);
19066e63ce3Schristos else if (!bits->opcode->is_boolean)
19166e63ce3Schristos {
19266e63ce3Schristos if (bits->opcode->last < bits->field->last)
19366e63ce3Schristos nr +=
19466e63ce3Schristos lf_putint (file,
19566e63ce3Schristos bits->value << (bits->field->last - bits->opcode->last));
19666e63ce3Schristos else
19766e63ce3Schristos nr += lf_putint (file, bits->value);
19866e63ce3Schristos }
19966e63ce3Schristos nr += print_opcode_bits (file, bits->next);
20066e63ce3Schristos return nr;
20166e63ce3Schristos }
20266e63ce3Schristos
20366e63ce3Schristos static int
print_c_name(lf * file,const char * name)20466e63ce3Schristos print_c_name (lf *file, const char *name)
20566e63ce3Schristos {
20666e63ce3Schristos int nr = 0;
20766e63ce3Schristos const char *pos;
20866e63ce3Schristos for (pos = name; *pos != '\0'; pos++)
20966e63ce3Schristos {
21066e63ce3Schristos switch (*pos)
21166e63ce3Schristos {
21266e63ce3Schristos case '/':
21366e63ce3Schristos case '-':
21466e63ce3Schristos break;
21566e63ce3Schristos case ' ':
21666e63ce3Schristos case '.':
21766e63ce3Schristos nr += lf_putchr (file, '_');
21866e63ce3Schristos break;
21966e63ce3Schristos default:
22066e63ce3Schristos nr += lf_putchr (file, *pos);
22166e63ce3Schristos break;
22266e63ce3Schristos }
22366e63ce3Schristos }
22466e63ce3Schristos return nr;
22566e63ce3Schristos }
22666e63ce3Schristos
22766e63ce3Schristos extern int
print_function_name(lf * file,const char * basename,const char * format_name,const char * model_name,opcode_bits * expanded_bits,lf_function_name_prefixes prefix)22866e63ce3Schristos print_function_name (lf *file,
22966e63ce3Schristos const char *basename,
23066e63ce3Schristos const char *format_name,
23166e63ce3Schristos const char *model_name,
23266e63ce3Schristos opcode_bits *expanded_bits,
23366e63ce3Schristos lf_function_name_prefixes prefix)
23466e63ce3Schristos {
23566e63ce3Schristos int nr = 0;
23666e63ce3Schristos /* the prefix */
23766e63ce3Schristos switch (prefix)
23866e63ce3Schristos {
23966e63ce3Schristos case function_name_prefix_semantics:
24066e63ce3Schristos nr += lf_printf (file, "%s", options.module.semantics.prefix.l);
24166e63ce3Schristos nr += lf_printf (file, "semantic_");
24266e63ce3Schristos break;
24366e63ce3Schristos case function_name_prefix_idecode:
24466e63ce3Schristos nr += lf_printf (file, "%s", options.module.idecode.prefix.l);
24566e63ce3Schristos nr += lf_printf (file, "idecode_");
24666e63ce3Schristos break;
24766e63ce3Schristos case function_name_prefix_itable:
24866e63ce3Schristos nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l);
24966e63ce3Schristos break;
25066e63ce3Schristos case function_name_prefix_icache:
25166e63ce3Schristos nr += lf_printf (file, "%s", options.module.icache.prefix.l);
25266e63ce3Schristos nr += lf_printf (file, "icache_");
25366e63ce3Schristos break;
25466e63ce3Schristos case function_name_prefix_engine:
25566e63ce3Schristos nr += lf_printf (file, "%s", options.module.engine.prefix.l);
25666e63ce3Schristos nr += lf_printf (file, "engine_");
25766e63ce3Schristos default:
25866e63ce3Schristos break;
25966e63ce3Schristos }
26066e63ce3Schristos
26166e63ce3Schristos if (model_name != NULL)
26266e63ce3Schristos {
26366e63ce3Schristos nr += print_c_name (file, model_name);
26466e63ce3Schristos nr += lf_printf (file, "_");
26566e63ce3Schristos }
26666e63ce3Schristos
26766e63ce3Schristos /* the function name */
26866e63ce3Schristos nr += print_c_name (file, basename);
26966e63ce3Schristos
27066e63ce3Schristos /* the format name if available */
27166e63ce3Schristos if (format_name != NULL)
27266e63ce3Schristos {
27366e63ce3Schristos nr += lf_printf (file, "_");
27466e63ce3Schristos nr += print_c_name (file, format_name);
27566e63ce3Schristos }
27666e63ce3Schristos
27766e63ce3Schristos /* the suffix */
27866e63ce3Schristos nr += print_opcode_bits (file, expanded_bits);
27966e63ce3Schristos
28066e63ce3Schristos return nr;
28166e63ce3Schristos }
28266e63ce3Schristos
28366e63ce3Schristos
28466e63ce3Schristos void
print_my_defines(lf * file,const char * basename,const char * format_name,opcode_bits * expanded_bits)28566e63ce3Schristos print_my_defines (lf *file,
28666e63ce3Schristos const char *basename,
28766e63ce3Schristos const char *format_name, opcode_bits *expanded_bits)
28866e63ce3Schristos {
28966e63ce3Schristos /* #define MY_INDEX xxxxx */
29066e63ce3Schristos lf_indent_suppress (file);
29166e63ce3Schristos lf_printf (file, "#undef MY_INDEX\n");
29266e63ce3Schristos lf_indent_suppress (file);
29366e63ce3Schristos lf_printf (file, "#define MY_INDEX ");
29466e63ce3Schristos print_function_name (file,
29566e63ce3Schristos basename, format_name, NULL,
29666e63ce3Schristos NULL, function_name_prefix_itable);
29766e63ce3Schristos lf_printf (file, "\n");
29866e63ce3Schristos /* #define MY_PREFIX xxxxxx */
29966e63ce3Schristos lf_indent_suppress (file);
30066e63ce3Schristos lf_printf (file, "#undef ");
30166e63ce3Schristos print_function_name (file,
30266e63ce3Schristos basename, format_name, NULL,
30366e63ce3Schristos expanded_bits, function_name_prefix_none);
30466e63ce3Schristos lf_printf (file, "\n");
30566e63ce3Schristos lf_indent_suppress (file);
30666e63ce3Schristos lf_printf (file, "#undef MY_PREFIX\n");
30766e63ce3Schristos lf_indent_suppress (file);
30866e63ce3Schristos lf_printf (file, "#define MY_PREFIX ");
30966e63ce3Schristos print_function_name (file,
31066e63ce3Schristos basename, format_name, NULL,
31166e63ce3Schristos expanded_bits, function_name_prefix_none);
31266e63ce3Schristos lf_printf (file, "\n");
31366e63ce3Schristos /* #define MY_NAME xxxxxx */
31466e63ce3Schristos lf_indent_suppress (file);
31566e63ce3Schristos lf_indent_suppress (file);
31666e63ce3Schristos lf_printf (file, "#undef MY_NAME\n");
31766e63ce3Schristos lf_indent_suppress (file);
31866e63ce3Schristos lf_printf (file, "#define MY_NAME \"");
31966e63ce3Schristos print_function_name (file,
32066e63ce3Schristos basename, format_name, NULL,
32166e63ce3Schristos expanded_bits, function_name_prefix_none);
32266e63ce3Schristos lf_printf (file, "\"\n");
32366e63ce3Schristos }
32466e63ce3Schristos
32566e63ce3Schristos
32666e63ce3Schristos static int
print_itrace_prefix(lf * file)32766e63ce3Schristos print_itrace_prefix (lf *file)
32866e63ce3Schristos {
32966e63ce3Schristos const char *prefix = "trace_prefix (";
33066e63ce3Schristos int indent = strlen (prefix);
33166e63ce3Schristos lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n",
33266e63ce3Schristos prefix);
33366e63ce3Schristos lf_indent (file, +indent);
33466e63ce3Schristos lf_printf (file, "%sitable[MY_INDEX].file, \\\n",
33566e63ce3Schristos options.module.itable.prefix.l);
33666e63ce3Schristos lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n",
33766e63ce3Schristos options.module.itable.prefix.l);
33866e63ce3Schristos lf_printf (file, "\"");
33966e63ce3Schristos return indent;
34066e63ce3Schristos }
34166e63ce3Schristos
34266e63ce3Schristos
34366e63ce3Schristos static void
print_itrace_format(lf * file,insn_mnemonic_entry * assembler)34466e63ce3Schristos print_itrace_format (lf *file, insn_mnemonic_entry *assembler)
34566e63ce3Schristos {
34666e63ce3Schristos /* pass=1 is fmt string; pass=2 is arguments */
34766e63ce3Schristos int pass;
34866e63ce3Schristos /* print the format string */
34966e63ce3Schristos for (pass = 1; pass <= 2; pass++)
35066e63ce3Schristos {
35166e63ce3Schristos const char *chp = assembler->format;
35266e63ce3Schristos chp++; /* skip the leading quote */
35366e63ce3Schristos /* write out the format/args */
35466e63ce3Schristos while (*chp != '\0')
35566e63ce3Schristos {
35666e63ce3Schristos if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>'))
35766e63ce3Schristos {
35866e63ce3Schristos if (pass == 1)
35966e63ce3Schristos lf_putchr (file, chp[1]);
36066e63ce3Schristos chp += 2;
36166e63ce3Schristos }
36266e63ce3Schristos else if (chp[0] == '<' || chp[0] == '%')
36366e63ce3Schristos {
36466e63ce3Schristos /* parse [ "%" ... ] "<" [ func "#" ] param ">" */
36566e63ce3Schristos const char *fmt;
36666e63ce3Schristos const char *func;
36766e63ce3Schristos int strlen_func;
36866e63ce3Schristos const char *param;
36966e63ce3Schristos int strlen_param;
37066e63ce3Schristos /* the "%" ... "<" format */
37166e63ce3Schristos fmt = chp;
37266e63ce3Schristos while (chp[0] != '<' && chp[0] != '\0')
37366e63ce3Schristos chp++;
37466e63ce3Schristos if (chp[0] != '<')
37566e63ce3Schristos error (assembler->line, "Missing `<' after `%%'\n");
37666e63ce3Schristos chp++;
37766e63ce3Schristos /* [ "func" # ] OR "param" */
37866e63ce3Schristos func = chp;
37966e63ce3Schristos param = chp;
38066e63ce3Schristos while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0')
38166e63ce3Schristos chp++;
38266e63ce3Schristos strlen_func = chp - func;
38366e63ce3Schristos if (chp[0] == '#')
38466e63ce3Schristos {
38566e63ce3Schristos chp++;
38666e63ce3Schristos param = chp;
38766e63ce3Schristos while (chp[0] != '>' && chp[0] != '\0')
38866e63ce3Schristos chp++;
38966e63ce3Schristos }
39066e63ce3Schristos strlen_param = chp - param;
39166e63ce3Schristos if (chp[0] != '>')
39266e63ce3Schristos error (assembler->line,
39366e63ce3Schristos "Missing closing `>' in assembler string\n");
39466e63ce3Schristos chp++;
39566e63ce3Schristos /* now process it */
39666e63ce3Schristos if (pass == 2)
39766e63ce3Schristos lf_printf (file, ", \\\n");
39866e63ce3Schristos if (strncmp (fmt, "<", 1) == 0)
39966e63ce3Schristos /* implicit long int format */
40066e63ce3Schristos {
40166e63ce3Schristos if (pass == 1)
40266e63ce3Schristos lf_printf (file, "%%ld");
40366e63ce3Schristos else
40466e63ce3Schristos {
40566e63ce3Schristos lf_printf (file, "(long) ");
40666e63ce3Schristos lf_write (file, param, strlen_param);
40766e63ce3Schristos }
40866e63ce3Schristos }
40966e63ce3Schristos else if (strncmp (fmt, "%<", 2) == 0)
41066e63ce3Schristos /* explicit format */
41166e63ce3Schristos {
41266e63ce3Schristos if (pass == 1)
41366e63ce3Schristos lf_printf (file, "%%");
41466e63ce3Schristos else
41566e63ce3Schristos lf_write (file, param, strlen_param);
41666e63ce3Schristos }
41766e63ce3Schristos else if (strncmp (fmt, "%s<", 3) == 0)
41866e63ce3Schristos /* string format */
41966e63ce3Schristos {
42066e63ce3Schristos if (pass == 1)
42166e63ce3Schristos lf_printf (file, "%%s");
42266e63ce3Schristos else
42366e63ce3Schristos {
42466e63ce3Schristos lf_printf (file, "%sstr_",
42566e63ce3Schristos options.module.global.prefix.l);
42666e63ce3Schristos lf_write (file, func, strlen_func);
42766e63ce3Schristos lf_printf (file, " (SD_, ");
42866e63ce3Schristos lf_write (file, param, strlen_param);
42966e63ce3Schristos lf_printf (file, ")");
43066e63ce3Schristos }
43166e63ce3Schristos }
43266e63ce3Schristos else if (strncmp (fmt, "%lx<", 4) == 0)
43366e63ce3Schristos /* simple hex */
43466e63ce3Schristos {
43566e63ce3Schristos if (pass == 1)
43666e63ce3Schristos lf_printf (file, "%%lx");
43766e63ce3Schristos else
43866e63ce3Schristos {
43966e63ce3Schristos lf_printf (file, "(unsigned long) ");
44066e63ce3Schristos lf_write (file, param, strlen_param);
44166e63ce3Schristos }
44266e63ce3Schristos }
44366e63ce3Schristos else if (strncmp (fmt, "%#lx<", 5) == 0)
44466e63ce3Schristos /* simple hex with 0x prefix */
44566e63ce3Schristos {
44666e63ce3Schristos if (pass == 1)
44766e63ce3Schristos lf_printf (file, "%%#lx");
44866e63ce3Schristos else
44966e63ce3Schristos {
45066e63ce3Schristos lf_printf (file, "(unsigned long) ");
45166e63ce3Schristos lf_write (file, param, strlen_param);
45266e63ce3Schristos }
45366e63ce3Schristos }
45466e63ce3Schristos else if (strncmp (fmt, "%08lx<", 6) == 0)
45566e63ce3Schristos /* simple hex */
45666e63ce3Schristos {
45766e63ce3Schristos if (pass == 1)
45866e63ce3Schristos lf_printf (file, "%%08lx");
45966e63ce3Schristos else
46066e63ce3Schristos {
46166e63ce3Schristos lf_printf (file, "(unsigned long) ");
46266e63ce3Schristos lf_write (file, param, strlen_param);
46366e63ce3Schristos }
46466e63ce3Schristos }
46566e63ce3Schristos else
46666e63ce3Schristos error (assembler->line, "Unknown assembler string format\n");
46766e63ce3Schristos }
46866e63ce3Schristos else
46966e63ce3Schristos {
47066e63ce3Schristos if (pass == 1)
47166e63ce3Schristos lf_putchr (file, chp[0]);
47266e63ce3Schristos chp += 1;
47366e63ce3Schristos }
47466e63ce3Schristos }
47566e63ce3Schristos }
47666e63ce3Schristos lf_printf (file, ");\n");
47766e63ce3Schristos }
47866e63ce3Schristos
47966e63ce3Schristos
48066e63ce3Schristos void
print_itrace(lf * file,insn_entry * insn,int idecode)48166e63ce3Schristos print_itrace (lf *file, insn_entry * insn, int idecode)
48266e63ce3Schristos {
48366e63ce3Schristos /* NB: Here we escape each EOLN. This is so that the the compiler
48466e63ce3Schristos treats a trace function call as a single line. Consequently any
48566e63ce3Schristos errors in the line are refered back to the same igen assembler
48666e63ce3Schristos source line */
48766e63ce3Schristos const char *phase = (idecode) ? "DECODE" : "INSN";
48866e63ce3Schristos lf_printf (file, "\n");
48966e63ce3Schristos lf_indent_suppress (file);
49066e63ce3Schristos lf_printf (file, "#if defined (WITH_TRACE)\n");
49166e63ce3Schristos lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n");
49266e63ce3Schristos lf_printf (file, "if (TRACE_ANY_P (CPU))\n");
49366e63ce3Schristos lf_printf (file, " {\n");
49466e63ce3Schristos lf_indent (file, +4);
49566e63ce3Schristos {
49666e63ce3Schristos if (insn->mnemonics != NULL)
49766e63ce3Schristos {
49866e63ce3Schristos insn_mnemonic_entry *assembler = insn->mnemonics;
49966e63ce3Schristos int is_first = 1;
50066e63ce3Schristos do
50166e63ce3Schristos {
50266e63ce3Schristos if (assembler->condition != NULL)
50366e63ce3Schristos {
50466e63ce3Schristos int indent;
50566e63ce3Schristos lf_printf (file, "%sif (%s)\n",
50666e63ce3Schristos is_first ? "" : "else ", assembler->condition);
50766e63ce3Schristos lf_indent (file, +2);
50866e63ce3Schristos lf_print__line_ref (file, assembler->line);
50966e63ce3Schristos indent = print_itrace_prefix (file);
51066e63ce3Schristos print_itrace_format (file, assembler);
51166e63ce3Schristos lf_print__internal_ref (file);
51266e63ce3Schristos lf_indent (file, -indent);
51366e63ce3Schristos lf_indent (file, -2);
51466e63ce3Schristos if (assembler->next == NULL)
51566e63ce3Schristos error (assembler->line,
51666e63ce3Schristos "Missing final unconditional assembler\n");
51766e63ce3Schristos }
51866e63ce3Schristos else
51966e63ce3Schristos {
52066e63ce3Schristos int indent;
52166e63ce3Schristos if (!is_first)
52266e63ce3Schristos {
52366e63ce3Schristos lf_printf (file, "else\n");
52466e63ce3Schristos lf_indent (file, +2);
52566e63ce3Schristos }
52666e63ce3Schristos lf_print__line_ref (file, assembler->line);
52766e63ce3Schristos indent = print_itrace_prefix (file);
52866e63ce3Schristos print_itrace_format (file, assembler);
52966e63ce3Schristos lf_print__internal_ref (file);
53066e63ce3Schristos lf_indent (file, -indent);
53166e63ce3Schristos if (!is_first)
53266e63ce3Schristos lf_indent (file, -2);
53366e63ce3Schristos if (assembler->next != NULL)
53466e63ce3Schristos error (assembler->line,
53566e63ce3Schristos "Unconditional assembler is not last\n");
53666e63ce3Schristos }
53766e63ce3Schristos is_first = 0;
53866e63ce3Schristos assembler = assembler->next;
53966e63ce3Schristos }
54066e63ce3Schristos while (assembler != NULL);
54166e63ce3Schristos }
54266e63ce3Schristos else
54366e63ce3Schristos {
54466e63ce3Schristos int indent;
54566e63ce3Schristos lf_indent (file, +2);
54666e63ce3Schristos lf_print__line_ref (file, insn->line);
54766e63ce3Schristos indent = print_itrace_prefix (file);
54866e63ce3Schristos lf_printf (file, "%%s\", \\\n");
54966e63ce3Schristos lf_printf (file, "itable[MY_INDEX].name);\n");
55066e63ce3Schristos lf_print__internal_ref (file);
55166e63ce3Schristos lf_indent (file, -indent);
55266e63ce3Schristos lf_indent (file, -2);
55366e63ce3Schristos }
55466e63ce3Schristos lf_printf (file, "/* trace the instruction execution if enabled */\n");
55566e63ce3Schristos lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase);
55666e63ce3Schristos lf_printf (file,
55766e63ce3Schristos " trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n",
55866e63ce3Schristos phase);
55966e63ce3Schristos }
56066e63ce3Schristos lf_indent (file, -4);
56166e63ce3Schristos lf_printf (file, " }\n");
56266e63ce3Schristos lf_indent_suppress (file);
56366e63ce3Schristos lf_printf (file, "#endif\n");
56466e63ce3Schristos }
56566e63ce3Schristos
56666e63ce3Schristos
56766e63ce3Schristos void
print_sim_engine_abort(lf * file,const char * message)56866e63ce3Schristos print_sim_engine_abort (lf *file, const char *message)
56966e63ce3Schristos {
57066e63ce3Schristos lf_printf (file, "sim_engine_abort (SD, CPU, cia, ");
57166e63ce3Schristos lf_printf (file, "\"%s\"", message);
57266e63ce3Schristos lf_printf (file, ");\n");
57366e63ce3Schristos }
57466e63ce3Schristos
57566e63ce3Schristos
57666e63ce3Schristos void
print_include(lf * file,igen_module module)57766e63ce3Schristos print_include (lf *file, igen_module module)
57866e63ce3Schristos {
57966e63ce3Schristos lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l);
58066e63ce3Schristos }
58166e63ce3Schristos
58266e63ce3Schristos void
print_include_inline(lf * file,igen_module module)58366e63ce3Schristos print_include_inline (lf *file, igen_module module)
58466e63ce3Schristos {
58566e63ce3Schristos lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u);
58666e63ce3Schristos lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l);
58766e63ce3Schristos lf_printf (file, "#else\n");
58866e63ce3Schristos print_include (file, module);
58966e63ce3Schristos lf_printf (file, "#endif\n");
59066e63ce3Schristos lf_printf (file, "\n");
59166e63ce3Schristos }
59266e63ce3Schristos
59366e63ce3Schristos void
print_includes(lf * file)59466e63ce3Schristos print_includes (lf *file)
59566e63ce3Schristos {
59666e63ce3Schristos lf_printf (file, "\n");
59766e63ce3Schristos lf_printf (file, "#include \"sim-inline.c\"\n");
59866e63ce3Schristos lf_printf (file, "\n");
59966e63ce3Schristos print_include_inline (file, options.module.itable);
60066e63ce3Schristos print_include_inline (file, options.module.idecode);
60166e63ce3Schristos print_include_inline (file, options.module.support);
60266e63ce3Schristos }
60366e63ce3Schristos
60466e63ce3Schristos
60566e63ce3Schristos /****************************************************************/
60666e63ce3Schristos
60766e63ce3Schristos
60866e63ce3Schristos static void
gen_semantics_h(lf * file,insn_list * semantics,int max_nr_words)60966e63ce3Schristos gen_semantics_h (lf *file, insn_list *semantics, int max_nr_words)
61066e63ce3Schristos {
61166e63ce3Schristos int word_nr;
61266e63ce3Schristos insn_list *semantic;
61366e63ce3Schristos for (word_nr = -1; word_nr <= max_nr_words; word_nr++)
61466e63ce3Schristos {
61566e63ce3Schristos lf_printf (file, "typedef ");
61666e63ce3Schristos print_semantic_function_type (file);
61766e63ce3Schristos lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l);
61866e63ce3Schristos if (word_nr >= 0)
61966e63ce3Schristos lf_printf (file, "_%d", word_nr);
62066e63ce3Schristos lf_printf (file, "\n(");
62166e63ce3Schristos lf_indent (file, +1);
62266e63ce3Schristos print_semantic_function_formal (file, word_nr);
62366e63ce3Schristos lf_indent (file, -1);
62466e63ce3Schristos lf_printf (file, ");\n");
62566e63ce3Schristos lf_printf (file, "\n");
62666e63ce3Schristos }
62766e63ce3Schristos switch (options.gen.code)
62866e63ce3Schristos {
62966e63ce3Schristos case generate_calls:
63066e63ce3Schristos for (semantic = semantics; semantic != NULL; semantic = semantic->next)
63166e63ce3Schristos {
63266e63ce3Schristos /* Ignore any special/internal instructions */
63366e63ce3Schristos if (semantic->insn->nr_words == 0)
63466e63ce3Schristos continue;
63566e63ce3Schristos print_semantic_declaration (file,
63666e63ce3Schristos semantic->insn,
63766e63ce3Schristos semantic->expanded_bits,
63866e63ce3Schristos semantic->opcodes,
63966e63ce3Schristos semantic->nr_prefetched_words);
64066e63ce3Schristos }
64166e63ce3Schristos break;
64266e63ce3Schristos case generate_jumps:
64366e63ce3Schristos lf_print__this_file_is_empty (file, "generating jumps");
64466e63ce3Schristos break;
64566e63ce3Schristos }
64666e63ce3Schristos }
64766e63ce3Schristos
64866e63ce3Schristos
64966e63ce3Schristos static void
gen_semantics_c(lf * file,insn_list * semantics,cache_entry * cache_rules)65066e63ce3Schristos gen_semantics_c (lf *file, insn_list *semantics, cache_entry *cache_rules)
65166e63ce3Schristos {
65266e63ce3Schristos if (options.gen.code == generate_calls)
65366e63ce3Schristos {
65466e63ce3Schristos insn_list *semantic;
65566e63ce3Schristos print_includes (file);
65666e63ce3Schristos print_include (file, options.module.semantics);
65766e63ce3Schristos lf_printf (file, "\n");
65866e63ce3Schristos
65966e63ce3Schristos for (semantic = semantics; semantic != NULL; semantic = semantic->next)
66066e63ce3Schristos {
66166e63ce3Schristos /* Ignore any special/internal instructions */
66266e63ce3Schristos if (semantic->insn->nr_words == 0)
66366e63ce3Schristos continue;
66466e63ce3Schristos print_semantic_definition (file,
66566e63ce3Schristos semantic->insn,
66666e63ce3Schristos semantic->expanded_bits,
66766e63ce3Schristos semantic->opcodes,
66866e63ce3Schristos cache_rules,
66966e63ce3Schristos semantic->nr_prefetched_words);
67066e63ce3Schristos }
67166e63ce3Schristos }
67266e63ce3Schristos else
67366e63ce3Schristos {
67466e63ce3Schristos lf_print__this_file_is_empty (file, "generating jump engine");
67566e63ce3Schristos }
67666e63ce3Schristos }
67766e63ce3Schristos
67866e63ce3Schristos
67966e63ce3Schristos /****************************************************************/
68066e63ce3Schristos
68166e63ce3Schristos
68266e63ce3Schristos static void
gen_icache_h(lf * file,insn_list * semantic,function_entry * functions,int max_nr_words)68366e63ce3Schristos gen_icache_h (lf *file,
68466e63ce3Schristos insn_list *semantic,
68566e63ce3Schristos function_entry * functions, int max_nr_words)
68666e63ce3Schristos {
68766e63ce3Schristos int word_nr;
68866e63ce3Schristos for (word_nr = 0; word_nr <= max_nr_words; word_nr++)
68966e63ce3Schristos {
69066e63ce3Schristos lf_printf (file, "typedef ");
69166e63ce3Schristos print_icache_function_type (file);
69266e63ce3Schristos lf_printf (file, " %sidecode_icache_%d\n(",
69366e63ce3Schristos options.module.global.prefix.l, word_nr);
69466e63ce3Schristos print_icache_function_formal (file, word_nr);
69566e63ce3Schristos lf_printf (file, ");\n");
69666e63ce3Schristos lf_printf (file, "\n");
69766e63ce3Schristos }
69866e63ce3Schristos if (options.gen.code == generate_calls && options.gen.icache)
69966e63ce3Schristos {
70066e63ce3Schristos function_entry_traverse (file, functions,
70166e63ce3Schristos print_icache_internal_function_declaration,
70266e63ce3Schristos NULL);
70366e63ce3Schristos while (semantic != NULL)
70466e63ce3Schristos {
70566e63ce3Schristos print_icache_declaration (file,
70666e63ce3Schristos semantic->insn,
70766e63ce3Schristos semantic->expanded_bits,
70866e63ce3Schristos semantic->opcodes,
70966e63ce3Schristos semantic->nr_prefetched_words);
71066e63ce3Schristos semantic = semantic->next;
71166e63ce3Schristos }
71266e63ce3Schristos }
71366e63ce3Schristos else
71466e63ce3Schristos {
71566e63ce3Schristos lf_print__this_file_is_empty (file, "generating jump engine");
71666e63ce3Schristos }
71766e63ce3Schristos }
71866e63ce3Schristos
71966e63ce3Schristos static void
gen_icache_c(lf * file,insn_list * semantic,function_entry * functions,cache_entry * cache_rules)72066e63ce3Schristos gen_icache_c (lf *file,
72166e63ce3Schristos insn_list *semantic,
72266e63ce3Schristos function_entry * functions, cache_entry *cache_rules)
72366e63ce3Schristos {
72466e63ce3Schristos /* output `internal' invalid/floating-point unavailable functions
72566e63ce3Schristos where needed */
72666e63ce3Schristos if (options.gen.code == generate_calls && options.gen.icache)
72766e63ce3Schristos {
72866e63ce3Schristos lf_printf (file, "\n");
72966e63ce3Schristos lf_printf (file, "#include \"cpu.h\"\n");
73066e63ce3Schristos lf_printf (file, "#include \"idecode.h\"\n");
73166e63ce3Schristos lf_printf (file, "#include \"semantics.h\"\n");
73266e63ce3Schristos lf_printf (file, "#include \"icache.h\"\n");
73366e63ce3Schristos lf_printf (file, "#include \"support.h\"\n");
73466e63ce3Schristos lf_printf (file, "\n");
73566e63ce3Schristos function_entry_traverse (file, functions,
73666e63ce3Schristos print_icache_internal_function_definition,
73766e63ce3Schristos NULL);
73866e63ce3Schristos lf_printf (file, "\n");
73966e63ce3Schristos while (semantic != NULL)
74066e63ce3Schristos {
74166e63ce3Schristos print_icache_definition (file,
74266e63ce3Schristos semantic->insn,
74366e63ce3Schristos semantic->expanded_bits,
74466e63ce3Schristos semantic->opcodes,
74566e63ce3Schristos cache_rules,
74666e63ce3Schristos semantic->nr_prefetched_words);
74766e63ce3Schristos semantic = semantic->next;
74866e63ce3Schristos }
74966e63ce3Schristos }
75066e63ce3Schristos else
75166e63ce3Schristos {
75266e63ce3Schristos lf_print__this_file_is_empty (file, "generating jump engine");
75366e63ce3Schristos }
75466e63ce3Schristos }
75566e63ce3Schristos
75666e63ce3Schristos
75766e63ce3Schristos /****************************************************************/
75866e63ce3Schristos
75966e63ce3Schristos
76066e63ce3Schristos static void
gen_idecode_h(lf * file,gen_table * gen,insn_table * insns,cache_entry * cache_rules)76166e63ce3Schristos gen_idecode_h (lf *file,
76266e63ce3Schristos gen_table *gen, insn_table *insns, cache_entry *cache_rules)
76366e63ce3Schristos {
76466e63ce3Schristos lf_printf (file, "typedef unsigned%d %sinstruction_word;\n",
76566e63ce3Schristos options.insn_bit_size, options.module.global.prefix.l);
76666e63ce3Schristos if (options.gen.delayed_branch)
76766e63ce3Schristos {
76866e63ce3Schristos lf_printf (file, "typedef struct _%sinstruction_address {\n",
76966e63ce3Schristos options.module.global.prefix.l);
77066e63ce3Schristos lf_printf (file, " address_word ip; /* instruction pointer */\n");
77166e63ce3Schristos lf_printf (file, " address_word dp; /* delayed-slot pointer */\n");
77266e63ce3Schristos lf_printf (file, "} %sinstruction_address;\n",
77366e63ce3Schristos options.module.global.prefix.l);
77466e63ce3Schristos }
77566e63ce3Schristos else
77666e63ce3Schristos {
77766e63ce3Schristos lf_printf (file, "typedef address_word %sinstruction_address;\n",
77866e63ce3Schristos options.module.global.prefix.l);
77966e63ce3Schristos
78066e63ce3Schristos }
78166e63ce3Schristos if (options.gen.nia == nia_is_invalid
78266e63ce3Schristos && strlen (options.module.global.prefix.u) > 0)
78366e63ce3Schristos {
78466e63ce3Schristos lf_indent_suppress (file);
78566e63ce3Schristos lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ",
78666e63ce3Schristos options.module.global.prefix.u);
78766e63ce3Schristos lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n");
78866e63ce3Schristos }
78966e63ce3Schristos lf_printf (file, "\n");
79066e63ce3Schristos print_icache_struct (file, insns, cache_rules);
79166e63ce3Schristos lf_printf (file, "\n");
79266e63ce3Schristos if (options.gen.icache)
79366e63ce3Schristos {
79466e63ce3Schristos ERROR ("FIXME - idecode with icache suffering from bit-rot");
79566e63ce3Schristos }
79666e63ce3Schristos else
79766e63ce3Schristos {
79866e63ce3Schristos gen_list *entry;
79966e63ce3Schristos for (entry = gen->tables; entry != NULL; entry = entry->next)
80066e63ce3Schristos {
80166e63ce3Schristos print_idecode_issue_function_header (file,
80266e63ce3Schristos (options.gen.multi_sim
80366e63ce3Schristos ? entry->model->name
80466e63ce3Schristos : NULL),
80566e63ce3Schristos is_function_declaration,
80666e63ce3Schristos 1 /*ALWAYS ONE WORD */ );
80766e63ce3Schristos }
80866e63ce3Schristos if (options.gen.multi_sim)
80966e63ce3Schristos {
81066e63ce3Schristos print_idecode_issue_function_header (file,
81166e63ce3Schristos NULL,
81266e63ce3Schristos is_function_variable,
81366e63ce3Schristos 1 /*ALWAYS ONE WORD */ );
81466e63ce3Schristos }
81566e63ce3Schristos }
81666e63ce3Schristos }
81766e63ce3Schristos
81866e63ce3Schristos
81966e63ce3Schristos static void
gen_idecode_c(lf * file,gen_table * gen,insn_table * isa,cache_entry * cache_rules)82066e63ce3Schristos gen_idecode_c (lf *file,
82166e63ce3Schristos gen_table *gen, insn_table *isa, cache_entry *cache_rules)
82266e63ce3Schristos {
82366e63ce3Schristos /* the intro */
82466e63ce3Schristos print_includes (file);
82566e63ce3Schristos print_include_inline (file, options.module.semantics);
82666e63ce3Schristos lf_printf (file, "\n");
82766e63ce3Schristos
82866e63ce3Schristos print_idecode_globals (file);
82966e63ce3Schristos lf_printf (file, "\n");
83066e63ce3Schristos
83166e63ce3Schristos switch (options.gen.code)
83266e63ce3Schristos {
83366e63ce3Schristos case generate_calls:
83466e63ce3Schristos {
83566e63ce3Schristos gen_list *entry;
83666e63ce3Schristos for (entry = gen->tables; entry != NULL; entry = entry->next)
83766e63ce3Schristos {
83866e63ce3Schristos print_idecode_lookups (file, entry->table, cache_rules);
83966e63ce3Schristos
84066e63ce3Schristos /* output the main idecode routine */
84166e63ce3Schristos if (!options.gen.icache)
84266e63ce3Schristos {
84366e63ce3Schristos print_idecode_issue_function_header (file,
84466e63ce3Schristos (options.gen.multi_sim
84566e63ce3Schristos ? entry->model->name
84666e63ce3Schristos : NULL),
84766e63ce3Schristos 1 /*is definition */ ,
84866e63ce3Schristos 1 /*ALWAYS ONE WORD */ );
84966e63ce3Schristos lf_printf (file, "{\n");
85066e63ce3Schristos lf_indent (file, +2);
85166e63ce3Schristos lf_printf (file, "%sinstruction_address nia;\n",
85266e63ce3Schristos options.module.global.prefix.l);
85366e63ce3Schristos print_idecode_body (file, entry->table, "nia =");
85466e63ce3Schristos lf_printf (file, "return nia;");
85566e63ce3Schristos lf_indent (file, -2);
85666e63ce3Schristos lf_printf (file, "}\n");
85766e63ce3Schristos }
85866e63ce3Schristos }
85966e63ce3Schristos break;
86066e63ce3Schristos }
86166e63ce3Schristos case generate_jumps:
86266e63ce3Schristos {
86366e63ce3Schristos lf_print__this_file_is_empty (file, "generating a jump engine");
86466e63ce3Schristos break;
86566e63ce3Schristos }
86666e63ce3Schristos }
86766e63ce3Schristos }
86866e63ce3Schristos
86966e63ce3Schristos
87066e63ce3Schristos /****************************************************************/
87166e63ce3Schristos
87266e63ce3Schristos
87366e63ce3Schristos static void
gen_run_c(lf * file,gen_table * gen)87466e63ce3Schristos gen_run_c (lf *file, gen_table *gen)
87566e63ce3Schristos {
87666e63ce3Schristos gen_list *entry;
87766e63ce3Schristos lf_printf (file, "#include \"sim-main.h\"\n");
87866e63ce3Schristos lf_printf (file, "#include \"engine.h\"\n");
87966e63ce3Schristos lf_printf (file, "#include \"idecode.h\"\n");
88066e63ce3Schristos lf_printf (file, "#include \"bfd.h\"\n");
88166e63ce3Schristos lf_printf (file, "\n");
88266e63ce3Schristos
88366e63ce3Schristos if (options.gen.multi_sim)
88466e63ce3Schristos {
88566e63ce3Schristos print_idecode_issue_function_header (file, NULL, is_function_variable,
88666e63ce3Schristos 1);
88766e63ce3Schristos lf_printf (file, "\n");
88866e63ce3Schristos print_engine_run_function_header (file, NULL, is_function_variable);
88966e63ce3Schristos lf_printf (file, "\n");
89066e63ce3Schristos }
89166e63ce3Schristos
89266e63ce3Schristos lf_printf (file, "void\n");
89366e63ce3Schristos lf_printf (file, "sim_engine_run (SIM_DESC sd,\n");
89466e63ce3Schristos lf_printf (file, " int next_cpu_nr,\n");
89566e63ce3Schristos lf_printf (file, " int nr_cpus,\n");
89666e63ce3Schristos lf_printf (file, " int siggnal)\n");
89766e63ce3Schristos lf_printf (file, "{\n");
89866e63ce3Schristos lf_indent (file, +2);
89966e63ce3Schristos if (options.gen.multi_sim)
90066e63ce3Schristos {
90166e63ce3Schristos lf_printf (file, "int mach;\n");
90266e63ce3Schristos lf_printf (file, "if (STATE_ARCHITECTURE (sd) == NULL)\n");
90366e63ce3Schristos lf_printf (file, " mach = 0;\n");
90466e63ce3Schristos lf_printf (file, "else\n");
90566e63ce3Schristos lf_printf (file, " mach = STATE_ARCHITECTURE (sd)->mach;\n");
90666e63ce3Schristos lf_printf (file, "switch (mach)\n");
90766e63ce3Schristos lf_printf (file, " {\n");
90866e63ce3Schristos lf_indent (file, +2);
90966e63ce3Schristos for (entry = gen->tables; entry != NULL; entry = entry->next)
91066e63ce3Schristos {
91166e63ce3Schristos if (options.gen.default_model != NULL
91266e63ce3Schristos && (strcmp (entry->model->name, options.gen.default_model) == 0
91366e63ce3Schristos || strcmp (entry->model->full_name,
91466e63ce3Schristos options.gen.default_model) == 0))
91566e63ce3Schristos lf_printf (file, "default:\n");
91666e63ce3Schristos lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name);
91766e63ce3Schristos lf_indent (file, +2);
91866e63ce3Schristos print_function_name (file, "issue", NULL, /* format name */
91966e63ce3Schristos NULL, /* NO processor */
92066e63ce3Schristos NULL, /* expanded bits */
92166e63ce3Schristos function_name_prefix_idecode);
92266e63ce3Schristos lf_printf (file, " = ");
92366e63ce3Schristos print_function_name (file, "issue", NULL, /* format name */
92466e63ce3Schristos entry->model->name, NULL, /* expanded bits */
92566e63ce3Schristos function_name_prefix_idecode);
92666e63ce3Schristos lf_printf (file, ";\n");
92766e63ce3Schristos print_function_name (file, "run", NULL, /* format name */
92866e63ce3Schristos NULL, /* NO processor */
92966e63ce3Schristos NULL, /* expanded bits */
93066e63ce3Schristos function_name_prefix_engine);
93166e63ce3Schristos lf_printf (file, " = ");
93266e63ce3Schristos print_function_name (file, "run", NULL, /* format name */
93366e63ce3Schristos entry->model->name, NULL, /* expanded bits */
93466e63ce3Schristos function_name_prefix_engine);
93566e63ce3Schristos lf_printf (file, ";\n");
93666e63ce3Schristos lf_printf (file, "break;\n");
93766e63ce3Schristos lf_indent (file, -2);
93866e63ce3Schristos }
93966e63ce3Schristos if (options.gen.default_model == NULL)
94066e63ce3Schristos {
94166e63ce3Schristos lf_printf (file, "default:\n");
94266e63ce3Schristos lf_indent (file, +2);
94366e63ce3Schristos lf_printf (file, "sim_engine_abort (sd, NULL, NULL_CIA,\n");
94466e63ce3Schristos lf_printf (file,
94566e63ce3Schristos " \"sim_engine_run - unknown machine\");\n");
94666e63ce3Schristos lf_printf (file, "break;\n");
94766e63ce3Schristos lf_indent (file, -2);
94866e63ce3Schristos }
94966e63ce3Schristos lf_indent (file, -2);
95066e63ce3Schristos lf_printf (file, " }\n");
95166e63ce3Schristos }
95266e63ce3Schristos print_function_name (file, "run", NULL, /* format name */
95366e63ce3Schristos NULL, /* NO processor */
95466e63ce3Schristos NULL, /* expanded bits */
95566e63ce3Schristos function_name_prefix_engine);
95666e63ce3Schristos lf_printf (file, " (sd, next_cpu_nr, nr_cpus, siggnal);\n");
95766e63ce3Schristos lf_indent (file, -2);
95866e63ce3Schristos lf_printf (file, "}\n");
95966e63ce3Schristos }
96066e63ce3Schristos
96166e63ce3Schristos /****************************************************************/
96266e63ce3Schristos
96366e63ce3Schristos static gen_table *
do_gen(insn_table * isa,decode_table * decode_rules)96466e63ce3Schristos do_gen (insn_table *isa, decode_table *decode_rules)
96566e63ce3Schristos {
96666e63ce3Schristos gen_table *gen;
96766e63ce3Schristos if (decode_rules == NULL)
96866e63ce3Schristos error (NULL, "Must specify a decode table\n");
96966e63ce3Schristos if (isa == NULL)
97066e63ce3Schristos error (NULL, "Must specify an instruction table\n");
97166e63ce3Schristos if (decode_table_max_word_nr (decode_rules) > 0)
97266e63ce3Schristos options.gen.multi_word = decode_table_max_word_nr (decode_rules);
97366e63ce3Schristos gen = make_gen_tables (isa, decode_rules);
97466e63ce3Schristos gen_tables_expand_insns (gen);
97566e63ce3Schristos gen_tables_expand_semantics (gen);
97666e63ce3Schristos return gen;
97766e63ce3Schristos }
97866e63ce3Schristos
97966e63ce3Schristos /****************************************************************/
98066e63ce3Schristos
98166e63ce3Schristos igen_options options;
98266e63ce3Schristos
98366e63ce3Schristos int
main(int argc,char ** argv,char ** envp)98466e63ce3Schristos main (int argc, char **argv, char **envp)
98566e63ce3Schristos {
98666e63ce3Schristos cache_entry *cache_rules = NULL;
98766e63ce3Schristos lf_file_references file_references = lf_include_references;
98866e63ce3Schristos decode_table *decode_rules = NULL;
98966e63ce3Schristos insn_table *isa = NULL;
99066e63ce3Schristos gen_table *gen = NULL;
99166e63ce3Schristos char *real_file_name = NULL;
99266e63ce3Schristos int is_header = 0;
99366e63ce3Schristos int ch;
99466e63ce3Schristos lf *standard_out =
99566e63ce3Schristos lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen");
99666e63ce3Schristos
99766e63ce3Schristos INIT_OPTIONS ();
99866e63ce3Schristos
99966e63ce3Schristos if (argc == 1)
100066e63ce3Schristos {
100166e63ce3Schristos printf ("Usage:\n");
100266e63ce3Schristos printf ("\n");
100366e63ce3Schristos printf (" igen <config-opts> ... <input-opts>... <output-opts>...\n");
100466e63ce3Schristos printf ("\n");
100566e63ce3Schristos printf ("Config options:\n");
100666e63ce3Schristos printf ("\n");
100766e63ce3Schristos printf (" -B <bit-size>\n");
100866e63ce3Schristos printf ("\t Set the number of bits in an instruction (deprecated).\n");
100966e63ce3Schristos printf
101066e63ce3Schristos ("\t This option can now be set directly in the instruction table.\n");
101166e63ce3Schristos printf ("\n");
101266e63ce3Schristos printf (" -D <data-structure>\n");
101366e63ce3Schristos printf
101466e63ce3Schristos ("\t Dump the specified data structure to stdout. Valid structures include:\n");
101566e63ce3Schristos printf
101666e63ce3Schristos ("\t processor-names - list the names of all the processors (models)\n");
101766e63ce3Schristos printf ("\n");
101866e63ce3Schristos printf (" -F <filter-list>\n");
101966e63ce3Schristos printf
102066e63ce3Schristos ("\t Filter out any instructions with a non-empty flags field that contains\n");
102166e63ce3Schristos printf ("\t a flag not listed in the <filter-list>.\n");
102266e63ce3Schristos printf ("\n");
102366e63ce3Schristos printf (" -H <high-bit>\n");
102466e63ce3Schristos printf
102566e63ce3Schristos ("\t Set the number of the high (most significant) instruction bit (deprecated).\n");
102666e63ce3Schristos printf
102766e63ce3Schristos ("\t This option can now be set directly in the instruction table.\n");
102866e63ce3Schristos printf ("\n");
102966e63ce3Schristos printf (" -I <directory>\n");
103066e63ce3Schristos printf
103166e63ce3Schristos ("\t Add <directory> to the list of directories searched when opening a file\n");
103266e63ce3Schristos printf ("\n");
103366e63ce3Schristos printf (" -M <model-list>\n");
103466e63ce3Schristos printf
103566e63ce3Schristos ("\t Filter out any instructions that do not support at least one of the listed\n");
103666e63ce3Schristos printf
103766e63ce3Schristos ("\t models (An instructions with no model information is considered to support\n");
103866e63ce3Schristos printf ("\t all models.).\n");
103966e63ce3Schristos printf ("\n");
104066e63ce3Schristos printf (" -N <nr-cpus>\n");
104166e63ce3Schristos printf ("\t Generate a simulator supporting <nr-cpus>\n");
104266e63ce3Schristos printf
104366e63ce3Schristos ("\t Specify `-N 0' to disable generation of the SMP. Specifying `-N 1' will\n");
104466e63ce3Schristos printf
104566e63ce3Schristos ("\t still generate an SMP enabled simulator but will only support one CPU.\n");
104666e63ce3Schristos printf ("\n");
104766e63ce3Schristos printf (" -T <mechanism>\n");
104866e63ce3Schristos printf
104966e63ce3Schristos ("\t Override the decode mechanism specified by the decode rules\n");
105066e63ce3Schristos printf ("\n");
105166e63ce3Schristos printf (" -P <prefix>\n");
105266e63ce3Schristos printf
105366e63ce3Schristos ("\t Prepend global names (except itable) with the string <prefix>.\n");
105466e63ce3Schristos printf
105566e63ce3Schristos ("\t Specify -P <module>=<prefix> to set a specific <module>'s prefix.\n");
105666e63ce3Schristos printf ("\n");
105766e63ce3Schristos printf (" -S <suffix>\n");
105866e63ce3Schristos printf
105966e63ce3Schristos ("\t Replace a global name (suffix) (except itable) with the string <suffix>.\n");
106066e63ce3Schristos printf
106166e63ce3Schristos ("\t Specify -S <module>=<suffix> to change a specific <module>'s name (suffix).\n");
106266e63ce3Schristos printf ("\n");
106366e63ce3Schristos printf (" -Werror\n");
106466e63ce3Schristos printf ("\t Make warnings errors\n");
106566e63ce3Schristos printf (" -Wnodiscard\n");
106666e63ce3Schristos printf
106766e63ce3Schristos ("\t Suppress warnings about discarded functions and instructions\n");
106866e63ce3Schristos printf (" -Wnowidth\n");
106966e63ce3Schristos printf
107066e63ce3Schristos ("\t Suppress warnings about instructions with invalid widths\n");
107166e63ce3Schristos printf (" -Wnounimplemented\n");
107266e63ce3Schristos printf ("\t Suppress warnings about unimplemented instructions\n");
107366e63ce3Schristos printf ("\n");
107466e63ce3Schristos printf (" -G [!]<gen-option>\n");
107566e63ce3Schristos printf ("\t Any of the following options:\n");
107666e63ce3Schristos printf ("\n");
107766e63ce3Schristos printf
107866e63ce3Schristos ("\t decode-duplicate - Override the decode rules, forcing the duplication of\n");
107966e63ce3Schristos printf ("\t semantic functions\n");
108066e63ce3Schristos printf
108166e63ce3Schristos ("\t decode-combine - Combine any duplicated entries within a table\n");
108266e63ce3Schristos printf
108366e63ce3Schristos ("\t decode-zero-reserved - Override the decode rules, forcing reserved bits to be\n");
108466e63ce3Schristos printf ("\t treated as zero.\n");
108566e63ce3Schristos printf
108666e63ce3Schristos ("\t decode-switch-is-goto - Overfide the padded-switch code type as a goto-switch\n");
108766e63ce3Schristos printf ("\n");
108866e63ce3Schristos printf
108966e63ce3Schristos ("\t gen-conditional-issue - conditionally issue each instruction\n");
109066e63ce3Schristos printf
109166e63ce3Schristos ("\t gen-delayed-branch - need both cia and nia passed around\n");
109266e63ce3Schristos printf
109366e63ce3Schristos ("\t gen-direct-access - use #defines to directly access values\n");
109466e63ce3Schristos printf
109566e63ce3Schristos ("\t gen-zero-r<N> - arch assumes GPR(<N>) == 0, keep it that way\n");
109666e63ce3Schristos printf
109766e63ce3Schristos ("\t gen-icache[=<N> - generate an instruction cracking cache of size <N>\n");
109866e63ce3Schristos printf ("\t Default size is %d\n",
109966e63ce3Schristos options.gen.icache_size);
110066e63ce3Schristos printf
110166e63ce3Schristos ("\t gen-insn-in-icache - save original instruction when cracking\n");
110266e63ce3Schristos printf
110366e63ce3Schristos ("\t gen-multi-sim[=MODEL] - generate multiple simulators - one per model\n");
110466e63ce3Schristos printf
110566e63ce3Schristos ("\t If specified MODEL is made the default architecture.\n");
110666e63ce3Schristos printf
110766e63ce3Schristos ("\t By default, a single simulator that will\n");
110866e63ce3Schristos printf
110966e63ce3Schristos ("\t execute any instruction is generated\n");
111066e63ce3Schristos printf
111166e63ce3Schristos ("\t gen-multi-word - generate code allowing for multi-word insns\n");
111266e63ce3Schristos printf
111366e63ce3Schristos ("\t gen-semantic-icache - include semantic code in cracking functions\n");
111466e63ce3Schristos printf
111566e63ce3Schristos ("\t gen-slot-verification - perform slot verification as part of decode\n");
111666e63ce3Schristos printf ("\t gen-nia-invalid - NIA defaults to nia_invalid\n");
111766e63ce3Schristos printf ("\t gen-nia-void - do not compute/return NIA\n");
111866e63ce3Schristos printf ("\n");
111966e63ce3Schristos printf
112066e63ce3Schristos ("\t trace-combine - report combined entries a rule application\n");
112166e63ce3Schristos printf
112266e63ce3Schristos ("\t trace-entries - report entries after a rules application\n");
112366e63ce3Schristos printf ("\t trace-rule-rejection - report each rule as rejected\n");
112466e63ce3Schristos printf ("\t trace-rule-selection - report each rule as selected\n");
112566e63ce3Schristos printf
112666e63ce3Schristos ("\t trace-insn-insertion - report each instruction as it is inserted into a decode table\n");
112766e63ce3Schristos printf
112866e63ce3Schristos ("\t trace-rule-expansion - report each instruction as it is expanded (before insertion into a decode table)\n");
112966e63ce3Schristos printf ("\t trace-all - enable all trace options\n");
113066e63ce3Schristos printf ("\n");
113166e63ce3Schristos printf
113266e63ce3Schristos ("\t field-widths - instruction formats specify widths (deprecated)\n");
113366e63ce3Schristos printf
113466e63ce3Schristos ("\t By default, an instruction format specifies bit\n");
113566e63ce3Schristos printf ("\t positions\n");
113666e63ce3Schristos printf
113766e63ce3Schristos ("\t This option can now be set directly in the\n");
113866e63ce3Schristos printf ("\t instruction table\n");
113966e63ce3Schristos printf
114066e63ce3Schristos ("\t jumps - use jumps instead of function calls\n");
114166e63ce3Schristos printf
114266e63ce3Schristos ("\t omit-line-numbers - do not include line number information in the output\n");
114366e63ce3Schristos printf ("\n");
114466e63ce3Schristos printf ("Input options:\n");
114566e63ce3Schristos printf ("\n");
114666e63ce3Schristos printf (" -k <cache-rules> (deprecated)\n");
114766e63ce3Schristos printf (" -o <decode-rules>\n");
114866e63ce3Schristos printf (" -i <instruction-table>\n");
114966e63ce3Schristos printf ("\n");
115066e63ce3Schristos printf ("Output options:\n");
115166e63ce3Schristos printf ("\n");
115266e63ce3Schristos printf (" -x Perform expansion (required)\n");
115366e63ce3Schristos printf
115466e63ce3Schristos (" -n <real-name> Specify the real name of the next output file\n");
115566e63ce3Schristos printf
115666e63ce3Schristos (" -h Generate the header (.h) file rather than the body (.c)\n");
115766e63ce3Schristos printf (" -c <output-file> output icache\n");
115866e63ce3Schristos printf (" -d <output-file> output idecode\n");
115966e63ce3Schristos printf (" -e <output-file> output engine\n");
116066e63ce3Schristos printf (" -f <output-file> output support functions\n");
116166e63ce3Schristos printf (" -m <output-file> output model\n");
116266e63ce3Schristos printf (" -r <output-file> output multi-sim run\n");
116366e63ce3Schristos printf (" -s <output-file> output schematic\n");
116466e63ce3Schristos printf (" -t <output-file> output itable\n");
116566e63ce3Schristos }
116666e63ce3Schristos
116766e63ce3Schristos while ((ch = getopt (argc, argv,
116866e63ce3Schristos "B:D:F:G:H:I:M:N:P:T:W:o:k:i:n:hc:d:e:m:r:s:t:f:x"))
116966e63ce3Schristos != -1)
117066e63ce3Schristos {
117166e63ce3Schristos fprintf (stderr, " -%c ", ch);
117266e63ce3Schristos if (optarg)
117366e63ce3Schristos fprintf (stderr, "%s ", optarg);
117466e63ce3Schristos fprintf (stderr, "\\\n");
117566e63ce3Schristos
117666e63ce3Schristos switch (ch)
117766e63ce3Schristos {
117866e63ce3Schristos
117966e63ce3Schristos case 'M':
118066e63ce3Schristos filter_parse (&options.model_filter, optarg);
118166e63ce3Schristos break;
118266e63ce3Schristos
118366e63ce3Schristos case 'D':
118466e63ce3Schristos if (strcmp (optarg, "processor-names"))
118566e63ce3Schristos {
118666e63ce3Schristos char *processor;
118766e63ce3Schristos for (processor = filter_next (options.model_filter, "");
118866e63ce3Schristos processor != NULL;
118966e63ce3Schristos processor = filter_next (options.model_filter, processor))
119066e63ce3Schristos lf_printf (standard_out, "%s\n", processor);
119166e63ce3Schristos }
119266e63ce3Schristos else
119366e63ce3Schristos error (NULL, "Unknown data structure %s, not dumped\n", optarg);
119466e63ce3Schristos break;
119566e63ce3Schristos
119666e63ce3Schristos case 'F':
119766e63ce3Schristos filter_parse (&options.flags_filter, optarg);
119866e63ce3Schristos break;
119966e63ce3Schristos
120066e63ce3Schristos case 'I':
120166e63ce3Schristos {
120266e63ce3Schristos table_include **dir = &options.include;
120366e63ce3Schristos while ((*dir) != NULL)
120466e63ce3Schristos dir = &(*dir)->next;
120566e63ce3Schristos (*dir) = ZALLOC (table_include);
120666e63ce3Schristos (*dir)->dir = strdup (optarg);
120766e63ce3Schristos }
120866e63ce3Schristos break;
120966e63ce3Schristos
121066e63ce3Schristos case 'B':
121166e63ce3Schristos options.insn_bit_size = a2i (optarg);
121266e63ce3Schristos if (options.insn_bit_size <= 0
121366e63ce3Schristos || options.insn_bit_size > max_insn_bit_size)
121466e63ce3Schristos {
121566e63ce3Schristos error (NULL, "Instruction bitsize must be in range 1..%d\n",
121666e63ce3Schristos max_insn_bit_size);
121766e63ce3Schristos }
121866e63ce3Schristos if (options.hi_bit_nr != options.insn_bit_size - 1
121966e63ce3Schristos && options.hi_bit_nr != 0)
122066e63ce3Schristos {
122166e63ce3Schristos error (NULL, "Conflict betweem hi-bit-nr and insn-bit-size\n");
122266e63ce3Schristos }
122366e63ce3Schristos break;
122466e63ce3Schristos
122566e63ce3Schristos case 'H':
122666e63ce3Schristos options.hi_bit_nr = a2i (optarg);
122766e63ce3Schristos if (options.hi_bit_nr != options.insn_bit_size - 1
122866e63ce3Schristos && options.hi_bit_nr != 0)
122966e63ce3Schristos {
123066e63ce3Schristos error (NULL, "Conflict between hi-bit-nr and insn-bit-size\n");
123166e63ce3Schristos }
123266e63ce3Schristos break;
123366e63ce3Schristos
123466e63ce3Schristos case 'N':
123566e63ce3Schristos options.gen.smp = a2i (optarg);
123666e63ce3Schristos break;
123766e63ce3Schristos
123866e63ce3Schristos case 'P':
123966e63ce3Schristos case 'S':
124066e63ce3Schristos {
124166e63ce3Schristos igen_module *names;
124266e63ce3Schristos igen_name *name;
124366e63ce3Schristos char *chp;
124466e63ce3Schristos chp = strchr (optarg, '=');
124566e63ce3Schristos if (chp == NULL)
124666e63ce3Schristos {
124766e63ce3Schristos names = &options.module.global;
124866e63ce3Schristos chp = optarg;
124966e63ce3Schristos }
125066e63ce3Schristos else
125166e63ce3Schristos {
125266e63ce3Schristos chp = chp + 1; /* skip `=' */
125366e63ce3Schristos names = NULL;
125466e63ce3Schristos if (strncmp (optarg, "global=", chp - optarg) == 0)
125566e63ce3Schristos {
125666e63ce3Schristos names = &options.module.global;
125766e63ce3Schristos }
125866e63ce3Schristos if (strncmp (optarg, "engine=", chp - optarg) == 0)
125966e63ce3Schristos {
126066e63ce3Schristos names = &options.module.engine;
126166e63ce3Schristos }
126266e63ce3Schristos if (strncmp (optarg, "icache=", chp - optarg) == 0)
126366e63ce3Schristos {
126466e63ce3Schristos names = &options.module.icache;
126566e63ce3Schristos }
126666e63ce3Schristos if (strncmp (optarg, "idecode=", chp - optarg) == 0)
126766e63ce3Schristos {
126866e63ce3Schristos names = &options.module.idecode;
126966e63ce3Schristos }
127066e63ce3Schristos if (strncmp (optarg, "itable=", chp - optarg) == 0)
127166e63ce3Schristos {
127266e63ce3Schristos names = &options.module.itable;
127366e63ce3Schristos }
127466e63ce3Schristos if (strncmp (optarg, "semantics=", chp - optarg) == 0)
127566e63ce3Schristos {
127666e63ce3Schristos names = &options.module.semantics;
127766e63ce3Schristos }
127866e63ce3Schristos if (strncmp (optarg, "support=", chp - optarg) == 0)
127966e63ce3Schristos {
128066e63ce3Schristos names = &options.module.support;
128166e63ce3Schristos }
128266e63ce3Schristos if (names == NULL)
128366e63ce3Schristos {
128466e63ce3Schristos error (NULL, "Prefix `%s' unreconized\n", optarg);
128566e63ce3Schristos }
128666e63ce3Schristos }
128766e63ce3Schristos switch (ch)
128866e63ce3Schristos {
128966e63ce3Schristos case 'P':
129066e63ce3Schristos name = &names->prefix;
129166e63ce3Schristos break;
129266e63ce3Schristos case 'S':
129366e63ce3Schristos name = &names->suffix;
129466e63ce3Schristos break;
129566e63ce3Schristos default:
129666e63ce3Schristos abort (); /* Bad switch. */
129766e63ce3Schristos }
129866e63ce3Schristos name->u = strdup (chp);
129966e63ce3Schristos name->l = strdup (chp);
130066e63ce3Schristos chp = name->u;
130166e63ce3Schristos while (*chp)
130266e63ce3Schristos {
130366e63ce3Schristos if (islower (*chp))
130466e63ce3Schristos *chp = toupper (*chp);
130566e63ce3Schristos chp++;
130666e63ce3Schristos }
130766e63ce3Schristos if (name == &options.module.global.prefix)
130866e63ce3Schristos {
130966e63ce3Schristos options.module.engine.prefix = options.module.global.prefix;
131066e63ce3Schristos options.module.icache.prefix = options.module.global.prefix;
131166e63ce3Schristos options.module.idecode.prefix = options.module.global.prefix;
131266e63ce3Schristos /* options.module.itable.prefix = options.module.global.prefix; */
131366e63ce3Schristos options.module.semantics.prefix =
131466e63ce3Schristos options.module.global.prefix;
131566e63ce3Schristos options.module.support.prefix = options.module.global.prefix;
131666e63ce3Schristos }
131766e63ce3Schristos if (name == &options.module.global.suffix)
131866e63ce3Schristos {
131966e63ce3Schristos options.module.engine.suffix = options.module.global.suffix;
132066e63ce3Schristos options.module.icache.suffix = options.module.global.suffix;
132166e63ce3Schristos options.module.idecode.suffix = options.module.global.suffix;
132266e63ce3Schristos /* options.module.itable.suffix = options.module.global.suffix; */
132366e63ce3Schristos options.module.semantics.suffix =
132466e63ce3Schristos options.module.global.suffix;
132566e63ce3Schristos options.module.support.suffix = options.module.global.suffix;
132666e63ce3Schristos }
132766e63ce3Schristos break;
132866e63ce3Schristos }
132966e63ce3Schristos
133066e63ce3Schristos case 'W':
133166e63ce3Schristos {
133266e63ce3Schristos if (strcmp (optarg, "error") == 0)
133366e63ce3Schristos options.warning = error;
133466e63ce3Schristos else if (strcmp (optarg, "nodiscard") == 0)
133566e63ce3Schristos options.warn.discard = 0;
133666e63ce3Schristos else if (strcmp (optarg, "discard") == 0)
133766e63ce3Schristos options.warn.discard = 1;
133866e63ce3Schristos else if (strcmp (optarg, "nowidth") == 0)
133966e63ce3Schristos options.warn.width = 0;
134066e63ce3Schristos else if (strcmp (optarg, "width") == 0)
134166e63ce3Schristos options.warn.width = 1;
134266e63ce3Schristos else if (strcmp (optarg, "nounimplemented") == 0)
134366e63ce3Schristos options.warn.unimplemented = 0;
134466e63ce3Schristos else if (strcmp (optarg, "unimplemented") == 0)
134566e63ce3Schristos options.warn.unimplemented = 1;
134666e63ce3Schristos else
134766e63ce3Schristos error (NULL, "Unknown -W argument `%s'\n", optarg);
134866e63ce3Schristos break;
134966e63ce3Schristos }
135066e63ce3Schristos
135166e63ce3Schristos
135266e63ce3Schristos case 'G':
135366e63ce3Schristos {
135466e63ce3Schristos int enable_p;
135566e63ce3Schristos char *argp;
135666e63ce3Schristos if (strncmp (optarg, "no-", strlen ("no-")) == 0)
135766e63ce3Schristos {
135866e63ce3Schristos argp = optarg + strlen ("no-");
135966e63ce3Schristos enable_p = 0;
136066e63ce3Schristos }
136166e63ce3Schristos else if (strncmp (optarg, "!", strlen ("!")) == 0)
136266e63ce3Schristos {
136366e63ce3Schristos argp = optarg + strlen ("no-");
136466e63ce3Schristos enable_p = 0;
136566e63ce3Schristos }
136666e63ce3Schristos else
136766e63ce3Schristos {
136866e63ce3Schristos argp = optarg;
136966e63ce3Schristos enable_p = 1;
137066e63ce3Schristos }
137166e63ce3Schristos if (strcmp (argp, "decode-duplicate") == 0)
137266e63ce3Schristos {
137366e63ce3Schristos options.decode.duplicate = enable_p;
137466e63ce3Schristos }
137566e63ce3Schristos else if (strcmp (argp, "decode-combine") == 0)
137666e63ce3Schristos {
137766e63ce3Schristos options.decode.combine = enable_p;
137866e63ce3Schristos }
137966e63ce3Schristos else if (strcmp (argp, "decode-zero-reserved") == 0)
138066e63ce3Schristos {
138166e63ce3Schristos options.decode.zero_reserved = enable_p;
138266e63ce3Schristos }
138366e63ce3Schristos
138466e63ce3Schristos else if (strcmp (argp, "gen-conditional-issue") == 0)
138566e63ce3Schristos {
138666e63ce3Schristos options.gen.conditional_issue = enable_p;
138766e63ce3Schristos }
138866e63ce3Schristos else if (strcmp (argp, "conditional-issue") == 0)
138966e63ce3Schristos {
139066e63ce3Schristos options.gen.conditional_issue = enable_p;
139166e63ce3Schristos options.warning (NULL,
139266e63ce3Schristos "Option conditional-issue replaced by gen-conditional-issue\n");
139366e63ce3Schristos }
139466e63ce3Schristos else if (strcmp (argp, "gen-delayed-branch") == 0)
139566e63ce3Schristos {
139666e63ce3Schristos options.gen.delayed_branch = enable_p;
139766e63ce3Schristos }
139866e63ce3Schristos else if (strcmp (argp, "delayed-branch") == 0)
139966e63ce3Schristos {
140066e63ce3Schristos options.gen.delayed_branch = enable_p;
140166e63ce3Schristos options.warning (NULL,
140266e63ce3Schristos "Option delayed-branch replaced by gen-delayed-branch\n");
140366e63ce3Schristos }
140466e63ce3Schristos else if (strcmp (argp, "gen-direct-access") == 0)
140566e63ce3Schristos {
140666e63ce3Schristos options.gen.direct_access = enable_p;
140766e63ce3Schristos }
140866e63ce3Schristos else if (strcmp (argp, "direct-access") == 0)
140966e63ce3Schristos {
141066e63ce3Schristos options.gen.direct_access = enable_p;
141166e63ce3Schristos options.warning (NULL,
141266e63ce3Schristos "Option direct-access replaced by gen-direct-access\n");
141366e63ce3Schristos }
141466e63ce3Schristos else if (strncmp (argp, "gen-zero-r", strlen ("gen-zero-r")) == 0)
141566e63ce3Schristos {
141666e63ce3Schristos options.gen.zero_reg = enable_p;
141766e63ce3Schristos options.gen.zero_reg_nr = atoi (argp + strlen ("gen-zero-r"));
141866e63ce3Schristos }
141966e63ce3Schristos else if (strncmp (argp, "zero-r", strlen ("zero-r")) == 0)
142066e63ce3Schristos {
142166e63ce3Schristos options.gen.zero_reg = enable_p;
142266e63ce3Schristos options.gen.zero_reg_nr = atoi (argp + strlen ("zero-r"));
142366e63ce3Schristos options.warning (NULL,
142466e63ce3Schristos "Option zero-r<N> replaced by gen-zero-r<N>\n");
142566e63ce3Schristos }
142666e63ce3Schristos else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0)
142766e63ce3Schristos {
142866e63ce3Schristos switch (argp[strlen ("gen-icache")])
142966e63ce3Schristos {
143066e63ce3Schristos case '=':
143166e63ce3Schristos options.gen.icache_size =
143266e63ce3Schristos atoi (argp + strlen ("gen-icache") + 1);
143366e63ce3Schristos options.gen.icache = enable_p;
143466e63ce3Schristos break;
143566e63ce3Schristos case '\0':
143666e63ce3Schristos options.gen.icache = enable_p;
143766e63ce3Schristos break;
143866e63ce3Schristos default:
143966e63ce3Schristos error (NULL,
144066e63ce3Schristos "Expecting -Ggen-icache or -Ggen-icache=<N>\n");
144166e63ce3Schristos }
144266e63ce3Schristos }
144366e63ce3Schristos else if (strcmp (argp, "gen-insn-in-icache") == 0)
144466e63ce3Schristos {
144566e63ce3Schristos options.gen.insn_in_icache = enable_p;
144666e63ce3Schristos }
144766e63ce3Schristos else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim"))
144866e63ce3Schristos == 0)
144966e63ce3Schristos {
145066e63ce3Schristos char *arg = &argp[strlen ("gen-multi-sim")];
145166e63ce3Schristos switch (arg[0])
145266e63ce3Schristos {
145366e63ce3Schristos case '=':
145466e63ce3Schristos options.gen.multi_sim = enable_p;
145566e63ce3Schristos options.gen.default_model = arg + 1;
145666e63ce3Schristos if (!filter_is_member
145766e63ce3Schristos (options.model_filter, options.gen.default_model))
145866e63ce3Schristos error (NULL, "multi-sim model %s unknown\n",
145966e63ce3Schristos options.gen.default_model);
146066e63ce3Schristos break;
146166e63ce3Schristos case '\0':
146266e63ce3Schristos options.gen.multi_sim = enable_p;
146366e63ce3Schristos options.gen.default_model = NULL;
146466e63ce3Schristos break;
146566e63ce3Schristos default:
146666e63ce3Schristos error (NULL,
146766e63ce3Schristos "Expecting -Ggen-multi-sim or -Ggen-multi-sim=<MODEL>\n");
146866e63ce3Schristos break;
146966e63ce3Schristos }
147066e63ce3Schristos }
147166e63ce3Schristos else if (strcmp (argp, "gen-multi-word") == 0)
147266e63ce3Schristos {
147366e63ce3Schristos options.gen.multi_word = enable_p;
147466e63ce3Schristos }
147566e63ce3Schristos else if (strcmp (argp, "gen-semantic-icache") == 0)
147666e63ce3Schristos {
147766e63ce3Schristos options.gen.semantic_icache = enable_p;
147866e63ce3Schristos }
147966e63ce3Schristos else if (strcmp (argp, "gen-slot-verification") == 0)
148066e63ce3Schristos {
148166e63ce3Schristos options.gen.slot_verification = enable_p;
148266e63ce3Schristos }
148366e63ce3Schristos else if (strcmp (argp, "verify-slot") == 0)
148466e63ce3Schristos {
148566e63ce3Schristos options.gen.slot_verification = enable_p;
148666e63ce3Schristos options.warning (NULL,
148766e63ce3Schristos "Option verify-slot replaced by gen-slot-verification\n");
148866e63ce3Schristos }
148966e63ce3Schristos else if (strcmp (argp, "gen-nia-invalid") == 0)
149066e63ce3Schristos {
149166e63ce3Schristos options.gen.nia = nia_is_invalid;
149266e63ce3Schristos }
149366e63ce3Schristos else if (strcmp (argp, "default-nia-minus-one") == 0)
149466e63ce3Schristos {
149566e63ce3Schristos options.gen.nia = nia_is_invalid;
149666e63ce3Schristos options.warning (NULL,
149766e63ce3Schristos "Option default-nia-minus-one replaced by gen-nia-invalid\n");
149866e63ce3Schristos }
149966e63ce3Schristos else if (strcmp (argp, "gen-nia-void") == 0)
150066e63ce3Schristos {
150166e63ce3Schristos options.gen.nia = nia_is_void;
150266e63ce3Schristos }
150366e63ce3Schristos else if (strcmp (argp, "trace-all") == 0)
150466e63ce3Schristos {
150566e63ce3Schristos memset (&options.trace, enable_p, sizeof (options.trace));
150666e63ce3Schristos }
150766e63ce3Schristos else if (strcmp (argp, "trace-combine") == 0)
150866e63ce3Schristos {
150966e63ce3Schristos options.trace.combine = enable_p;
151066e63ce3Schristos }
151166e63ce3Schristos else if (strcmp (argp, "trace-entries") == 0)
151266e63ce3Schristos {
151366e63ce3Schristos options.trace.entries = enable_p;
151466e63ce3Schristos }
151566e63ce3Schristos else if (strcmp (argp, "trace-rule-rejection") == 0)
151666e63ce3Schristos {
151766e63ce3Schristos options.trace.rule_rejection = enable_p;
151866e63ce3Schristos }
151966e63ce3Schristos else if (strcmp (argp, "trace-rule-selection") == 0)
152066e63ce3Schristos {
152166e63ce3Schristos options.trace.rule_selection = enable_p;
152266e63ce3Schristos }
152366e63ce3Schristos else if (strcmp (argp, "trace-insn-insertion") == 0)
152466e63ce3Schristos {
152566e63ce3Schristos options.trace.insn_insertion = enable_p;
152666e63ce3Schristos }
152766e63ce3Schristos else if (strcmp (argp, "trace-insn-expansion") == 0)
152866e63ce3Schristos {
152966e63ce3Schristos options.trace.insn_expansion = enable_p;
153066e63ce3Schristos }
153166e63ce3Schristos else if (strcmp (argp, "jumps") == 0)
153266e63ce3Schristos {
153366e63ce3Schristos options.gen.code = generate_jumps;
153466e63ce3Schristos }
153566e63ce3Schristos else if (strcmp (argp, "field-widths") == 0)
153666e63ce3Schristos {
153766e63ce3Schristos options.insn_specifying_widths = enable_p;
153866e63ce3Schristos }
153966e63ce3Schristos else if (strcmp (argp, "omit-line-numbers") == 0)
154066e63ce3Schristos {
154166e63ce3Schristos file_references = lf_omit_references;
154266e63ce3Schristos }
154366e63ce3Schristos else
154466e63ce3Schristos {
154566e63ce3Schristos error (NULL, "Unknown option %s\n", optarg);
154666e63ce3Schristos }
154766e63ce3Schristos break;
154866e63ce3Schristos }
154966e63ce3Schristos
155066e63ce3Schristos case 'i':
155166e63ce3Schristos isa = load_insn_table (optarg, cache_rules);
155266e63ce3Schristos if (isa->illegal_insn == NULL)
155366e63ce3Schristos error (NULL, "illegal-instruction missing from insn table\n");
155466e63ce3Schristos break;
155566e63ce3Schristos
155666e63ce3Schristos case 'x':
155766e63ce3Schristos gen = do_gen (isa, decode_rules);
155866e63ce3Schristos break;
155966e63ce3Schristos
156066e63ce3Schristos case 'o':
156166e63ce3Schristos decode_rules = load_decode_table (optarg);
156266e63ce3Schristos break;
156366e63ce3Schristos
156466e63ce3Schristos case 'k':
156566e63ce3Schristos if (isa != NULL)
156666e63ce3Schristos error (NULL, "Cache file must appear before the insn file\n");
156766e63ce3Schristos cache_rules = load_cache_table (optarg);
156866e63ce3Schristos break;
156966e63ce3Schristos
157066e63ce3Schristos case 'n':
157166e63ce3Schristos real_file_name = strdup (optarg);
157266e63ce3Schristos break;
157366e63ce3Schristos
157466e63ce3Schristos case 'h':
157566e63ce3Schristos is_header = 1;
157666e63ce3Schristos break;
157766e63ce3Schristos
157866e63ce3Schristos case 'c':
157966e63ce3Schristos case 'd':
158066e63ce3Schristos case 'e':
158166e63ce3Schristos case 'f':
158266e63ce3Schristos case 'm':
158366e63ce3Schristos case 'r':
158466e63ce3Schristos case 's':
158566e63ce3Schristos case 't':
158666e63ce3Schristos {
158766e63ce3Schristos lf *file = lf_open (optarg, real_file_name, file_references,
158866e63ce3Schristos (is_header ? lf_is_h : lf_is_c),
158966e63ce3Schristos argv[0]);
159066e63ce3Schristos if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f')
159166e63ce3Schristos {
159266e63ce3Schristos options.warning (NULL,
159366e63ce3Schristos "Explicitly generate tables with -x option\n");
159466e63ce3Schristos gen = do_gen (isa, decode_rules);
159566e63ce3Schristos }
159666e63ce3Schristos lf_print__file_start (file);
159766e63ce3Schristos switch (ch)
159866e63ce3Schristos {
159966e63ce3Schristos case 'm':
160066e63ce3Schristos if (is_header)
160166e63ce3Schristos gen_model_h (file, isa);
160266e63ce3Schristos else
160366e63ce3Schristos gen_model_c (file, isa);
160466e63ce3Schristos break;
160566e63ce3Schristos case 't':
160666e63ce3Schristos if (is_header)
160766e63ce3Schristos gen_itable_h (file, isa);
160866e63ce3Schristos else
160966e63ce3Schristos gen_itable_c (file, isa);
161066e63ce3Schristos break;
161166e63ce3Schristos case 'f':
161266e63ce3Schristos if (is_header)
161366e63ce3Schristos gen_support_h (file, isa);
161466e63ce3Schristos else
161566e63ce3Schristos gen_support_c (file, isa);
161666e63ce3Schristos break;
161766e63ce3Schristos case 'r':
161866e63ce3Schristos if (is_header)
161966e63ce3Schristos options.warning (NULL, "-hr option ignored\n");
162066e63ce3Schristos else
162166e63ce3Schristos gen_run_c (file, gen);
162266e63ce3Schristos break;
162366e63ce3Schristos case 's':
162466e63ce3Schristos if (is_header)
162566e63ce3Schristos gen_semantics_h (file, gen->semantics, isa->max_nr_words);
162666e63ce3Schristos else
162766e63ce3Schristos gen_semantics_c (file, gen->semantics, isa->caches);
162866e63ce3Schristos break;
162966e63ce3Schristos case 'd':
163066e63ce3Schristos if (is_header)
163166e63ce3Schristos gen_idecode_h (file, gen, isa, cache_rules);
163266e63ce3Schristos else
163366e63ce3Schristos gen_idecode_c (file, gen, isa, cache_rules);
163466e63ce3Schristos break;
163566e63ce3Schristos case 'e':
163666e63ce3Schristos if (is_header)
163766e63ce3Schristos gen_engine_h (file, gen, isa, cache_rules);
163866e63ce3Schristos else
163966e63ce3Schristos gen_engine_c (file, gen, isa, cache_rules);
164066e63ce3Schristos break;
164166e63ce3Schristos case 'c':
164266e63ce3Schristos if (is_header)
164366e63ce3Schristos gen_icache_h (file,
164466e63ce3Schristos gen->semantics,
164566e63ce3Schristos isa->functions, isa->max_nr_words);
164666e63ce3Schristos else
164766e63ce3Schristos gen_icache_c (file,
164866e63ce3Schristos gen->semantics, isa->functions, cache_rules);
164966e63ce3Schristos break;
165066e63ce3Schristos }
165166e63ce3Schristos lf_print__file_finish (file);
165266e63ce3Schristos lf_close (file);
165366e63ce3Schristos is_header = 0;
165466e63ce3Schristos }
165566e63ce3Schristos real_file_name = NULL;
165666e63ce3Schristos break;
165766e63ce3Schristos default:
165866e63ce3Schristos ERROR ("Bad switch");
165966e63ce3Schristos }
166066e63ce3Schristos }
166166e63ce3Schristos return (0);
166266e63ce3Schristos }
1663