]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/ppc/gen-semantics.c
sim: ppc: unify igen filter modules
[thirdparty/binutils-gdb.git] / sim / ppc / gen-semantics.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20
21
22 #include "misc.h"
23 #include "lf.h"
24 #include "lf-ppc.h"
25 #include "table.h"
26 #include "filter.h"
27 #include "filter-ppc.h"
28
29 #include "ld-decode.h"
30 #include "ld-cache.h"
31 #include "ld-insn.h"
32
33 #include "igen.h"
34
35 #include "gen-semantics.h"
36 #include "gen-icache.h"
37 #include "gen-idecode.h"
38
39
40 static void
41 print_semantic_function_header(lf *file,
42 const char *basename,
43 insn_bits *expanded_bits,
44 int is_function_definition)
45 {
46 int indent;
47 lf_printf(file, "\n");
48 lf_print__function_type(file, SEMANTIC_FUNCTION_TYPE, "PSIM_EXTERN_SEMANTICS",
49 (is_function_definition ? "\n" : " "));
50 indent = print_function_name(file,
51 basename,
52 expanded_bits,
53 function_name_prefix_semantics);
54 if (is_function_definition)
55 lf_indent(file, +indent);
56 else
57 lf_printf(file, "\n");
58 lf_printf(file, "(%s)", SEMANTIC_FUNCTION_FORMAL);
59 if (is_function_definition)
60 lf_indent(file, -indent);
61 else
62 lf_printf(file, ";");
63 lf_printf(file, "\n");
64 }
65
66 void
67 print_semantic_declaration(insn_table *entry,
68 lf *file,
69 void *data,
70 insn *instruction,
71 int depth)
72 {
73 if (generate_expanded_instructions) {
74 ASSERT(entry->nr_insn == 1);
75 print_semantic_function_header(file,
76 instruction->file_entry->fields[insn_name],
77 entry->expanded_bits,
78 0/* is not function definition*/);
79 }
80 else {
81 print_semantic_function_header(file,
82 instruction->file_entry->fields[insn_name],
83 NULL,
84 0/* is not function definition*/);
85 }
86 }
87
88
89 \f
90 /* generate the semantics.c file */
91
92
93 void
94 print_idecode_illegal(lf *file,
95 const char *result)
96 {
97 if ((code & generate_jumps))
98 lf_printf(file, "goto %s_illegal;\n", (code & generate_with_icache) ? "icache" : "semantic");
99 else if ((code & generate_with_icache))
100 lf_printf(file, "%s icache_illegal(%s);\n", result, ICACHE_FUNCTION_ACTUAL);
101 else
102 lf_printf(file, "%s semantic_illegal(%s);\n", result, SEMANTIC_FUNCTION_ACTUAL);
103 }
104
105
106 void
107 print_semantic_body(lf *file,
108 insn *instruction,
109 insn_bits *expanded_bits,
110 opcode_field *opcodes)
111 {
112 print_itrace(file, instruction->file_entry, 0/*put_value_in_cache*/);
113
114 /* validate the instruction, if a cache this has already been done */
115 if (!(code & generate_with_icache))
116 print_idecode_validate(file, instruction, opcodes);
117
118 /* generate the profiling call - this is delayed until after the
119 instruction has been verified */
120 lf_printf(file, "\n");
121 lf_printf(file, "/* monitoring: */\n");
122 lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE) {\n");
123 lf_printf(file, " mon_issue(");
124 print_function_name(file,
125 instruction->file_entry->fields[insn_name],
126 NULL,
127 function_name_prefix_itable);
128 lf_printf(file, ", processor, cia);\n");
129 lf_printf(file, "}\n");
130
131 /* generate the code (or at least something */
132 lf_printf(file, "\n");
133 lf_printf(file, "/* semantics: */\n");
134 lf_printf(file, "nia = cia + %d;\n", insn_bit_size / 8);
135 if (instruction->file_entry->annex != NULL) {
136 /* true code */
137 table_entry_print_cpp_line_nr(file, instruction->file_entry);
138 lf_printf(file, "{\n");
139 lf_indent(file, +2);
140 lf_print__c_code(file, instruction->file_entry->annex);
141 lf_indent(file, -2);
142 lf_printf(file, "}\n");
143 lf_print__internal_ref(file);
144 }
145 else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
146 lf_print__internal_ref(file);
147 }
148 else {
149 /* abort so it is implemented now */
150 table_entry_print_cpp_line_nr(file, instruction->file_entry);
151 lf_putstr(file, "error(\"%s:%d:0x%08lx:%s unimplemented\\n\",\n");
152 lf_printf(file, " itable[MY_INDEX].file, itable[MY_INDEX].line_nr, (long)cia, itable[MY_INDEX].name);\n");
153 lf_print__internal_ref(file);
154 }
155 }
156
157 static void
158 print_c_semantic(lf *file,
159 insn *instruction,
160 insn_bits *expanded_bits,
161 opcode_field *opcodes,
162 cache_table *cache_rules)
163 {
164
165 lf_printf(file, "{\n");
166 lf_indent(file, +2);
167
168 print_my_defines(file, expanded_bits, instruction->file_entry);
169 lf_printf(file, "\n");
170 print_icache_body(file,
171 instruction,
172 expanded_bits,
173 cache_rules,
174 ((code & generate_with_direct_access)
175 ? define_variables
176 : declare_variables),
177 ((code & generate_with_icache)
178 ? get_values_from_icache
179 : do_not_use_icache));
180
181 lf_printf(file, "unsigned_word nia;\n");
182 print_semantic_body(file,
183 instruction,
184 expanded_bits,
185 opcodes);
186 lf_printf(file, "return nia;\n");
187
188 /* generate something to clean up any #defines created for the cache */
189 if (code & generate_with_direct_access)
190 print_icache_body(file,
191 instruction,
192 expanded_bits,
193 cache_rules,
194 undef_variables,
195 ((code & generate_with_icache)
196 ? get_values_from_icache
197 : do_not_use_icache));
198
199 lf_indent(file, -2);
200 lf_printf(file, "}\n");
201 }
202
203 static void
204 print_c_semantic_function(lf *file,
205 insn *instruction,
206 insn_bits *expanded_bits,
207 opcode_field *opcodes,
208 cache_table *cache_rules)
209 {
210 /* build the semantic routine to execute the instruction */
211 print_semantic_function_header(file,
212 instruction->file_entry->fields[insn_name],
213 expanded_bits,
214 1/*is-function-definition*/);
215 print_c_semantic(file,
216 instruction,
217 expanded_bits,
218 opcodes,
219 cache_rules);
220 }
221
222 void
223 print_semantic_definition(insn_table *entry,
224 lf *file,
225 void *data,
226 insn *instruction,
227 int depth)
228 {
229 cache_table *cache_rules = (cache_table*)data;
230 if (generate_expanded_instructions) {
231 ASSERT(entry->nr_insn == 1
232 && entry->opcode == NULL
233 && entry->parent != NULL
234 && entry->parent->opcode != NULL);
235 ASSERT(entry->nr_insn == 1
236 && entry->opcode == NULL
237 && entry->parent != NULL
238 && entry->parent->opcode != NULL
239 && entry->parent->opcode_rule != NULL);
240 print_c_semantic_function(file,
241 entry->insns,
242 entry->expanded_bits,
243 entry->parent->opcode,
244 cache_rules);
245 }
246 else {
247 print_c_semantic_function(file, instruction,
248 NULL, NULL,
249 cache_rules);
250 }
251 }