2002-11-21 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / sim / igen / gen-semantics.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
3 Copyright 2002 Free Software Foundation, Inc.
4
5 Contributed by Andrew Cagney.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
c906108c
SS
23
24
25
26#include "misc.h"
27#include "lf.h"
28#include "table.h"
29#include "filter.h"
30#include "igen.h"
31
32#include "ld-insn.h"
33#include "ld-decode.h"
34
35#include "gen.h"
36
37#include "gen-semantics.h"
38#include "gen-icache.h"
39#include "gen-idecode.h"
40
41
42static void
43print_semantic_function_header (lf *file,
44 const char *basename,
45 const char *format_name,
46 opcode_bits *expanded_bits,
47 int is_function_definition,
48 int nr_prefetched_words)
49{
50 int indent;
51 lf_printf(file, "\n");
52 lf_print__function_type_function (file, print_semantic_function_type,
53 "EXTERN_SEMANTICS",
54 (is_function_definition ? "\n" : " "));
55 indent = print_function_name (file,
56 basename,
57 format_name,
58 NULL,
59 expanded_bits,
60 function_name_prefix_semantics);
61 if (is_function_definition)
62 {
63 indent += lf_printf (file, " ");
64 lf_indent (file, +indent);
65 }
66 else
67 {
68 lf_printf (file, "\n");
69 }
70 lf_printf (file, "(");
71 lf_indent (file, +1);
72 print_semantic_function_formal (file, nr_prefetched_words);
73 lf_indent (file, -1);
74 lf_printf (file, ")");
75 if (is_function_definition)
76 {
77 lf_indent (file, -indent);
78 }
79 else
80 {
81 lf_printf (file, ";");
82 }
83 lf_printf (file, "\n");
84}
85
86void
87print_semantic_declaration (lf *file,
88 insn_entry *insn,
89 opcode_bits *expanded_bits,
90 insn_opcodes *opcodes,
91 int nr_prefetched_words)
92{
93 print_semantic_function_header (file,
94 insn->name,
95 insn->format_name,
96 expanded_bits,
97 0/* is not function definition*/,
98 nr_prefetched_words);
99}
100
101
102\f
103/* generate the semantics.c file */
104
105
106void
107print_idecode_invalid (lf *file,
108 const char *result,
109 invalid_type type)
110{
111 const char *name;
112 switch (type)
113 {
114 default: name = "unknown"; break;
115 case invalid_illegal: name = "illegal"; break;
116 case invalid_fp_unavailable: name = "fp_unavailable"; break;
117 case invalid_wrong_slot: name = "wrong_slot"; break;
118 }
119 if (options.gen.code == generate_jumps)
120 {
121 lf_printf (file, "goto %s_%s;\n",
122 (options.gen.icache ? "icache" : "semantic"),
123 name);
124 }
125 else if (options.gen.icache)
126 {
127 lf_printf (file, "%s %sicache_%s (", result, options.module.global.prefix.l, name);
128 print_icache_function_actual (file, 0);
129 lf_printf (file, ");\n");
130 }
131 else
132 {
133 lf_printf (file, "%s %ssemantic_%s (", result, options.module.global.prefix.l, name);
134 print_semantic_function_actual (file, 0);
135 lf_printf (file, ");\n");
136 }
137}
138
139
140void
141print_semantic_body (lf *file,
142 insn_entry *instruction,
143 opcode_bits *expanded_bits,
144 insn_opcodes *opcodes)
145{
146 /* validate the instruction, if a cache this has already been done */
147 if (!options.gen.icache)
148 {
149 print_idecode_validate (file, instruction, opcodes);
150 }
151
152 print_itrace (file, instruction, 0/*put_value_in_cache*/);
153
154 /* generate the instruction profile call - this is delayed until
155 after the instruction has been verified. The count macro
156 generated is prefixed by ITABLE_PREFIX */
157 {
158 lf_printf (file, "\n");
159 lf_indent_suppress (file);
160 lf_printf (file, "#if defined (%sPROFILE_COUNT_INSN)\n",
161 options.module.itable.prefix.u);
162 lf_printf (file, "%sPROFILE_COUNT_INSN (CPU, CIA, MY_INDEX);\n",
163 options.module.itable.prefix.u);
164 lf_indent_suppress (file);
165 lf_printf (file, "#endif\n");
166 }
167
168 /* generate the model call - this is delayed until after the
169 instruction has been verified */
170 {
171 lf_printf (file, "\n");
172 lf_indent_suppress (file);
173 lf_printf (file, "#if defined (WITH_MON)\n");
174 lf_printf (file, "/* monitoring: */\n");
175 lf_printf (file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
176 lf_printf (file, " mon_issue (");
177 print_function_name (file,
178 instruction->name,
179 instruction->format_name,
180 NULL,
181 NULL,
182 function_name_prefix_itable);
183 lf_printf (file, ", cpu, cia);\n");
184 lf_indent_suppress (file);
185 lf_printf (file, "#endif\n");
186 lf_printf (file, "\n");
187 }
188
189 /* determine the new instruction address */
190 {
191 lf_printf(file, "/* keep the next instruction address handy */\n");
192 if (options.gen.nia == nia_is_invalid)
193 {
194 lf_printf(file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n",
195 options.module.global.prefix.u);
196 }
197 else
198 {
199 int nr_immeds = instruction->nr_words - 1;
200 if (options.gen.delayed_branch)
201 {
202 if (nr_immeds > 0)
203 {
204 lf_printf (file, "cia.dp += %d * %d; %s\n",
205 options.insn_bit_size / 8, nr_immeds,
206 "/* skip dp immeds */");
207 }
208 lf_printf (file, "nia.ip = cia.dp; %s\n",
209 "/* instruction pointer */");
210 lf_printf (file, "nia.dp = cia.dp + %d; %s\n",
211 options.insn_bit_size / 8,
212 "/* delayed-slot pointer */");
213 }
214 else
215 {
216 if (nr_immeds > 0)
217 {
218 lf_printf (file, "nia = cia + %d * (%d + 1); %s\n",
219 options.insn_bit_size / 8, nr_immeds,
220 "/* skip immeds as well */");
221
222 }
223 else
224 {
225 lf_printf (file, "nia = cia + %d;\n",
226 options.insn_bit_size / 8);
227 }
228 }
229 }
230 }
231
232 /* if conditional, generate code to verify that the instruction
233 should be issued */
234 if (filter_is_member (instruction->options, "c")
235 || options.gen.conditional_issue)
236 {
237 lf_printf (file, "\n");
238 lf_printf (file, "/* execute only if conditional passes */\n");
239 lf_printf (file, "if (IS_CONDITION_OK)\n");
240 lf_printf (file, " {\n");
241 lf_indent (file, +4);
242 /* FIXME - need to log a conditional failure */
243 }
244
245 /* Architecture expects a REG to be zero. Instead of having to
246 check every read to see if it is refering to that REG just zap it
247 at the start of every instruction */
248 if (options.gen.zero_reg)
249 {
250 lf_printf (file, "\n");
251 lf_printf (file, "/* Architecture expects REG to be zero */\n");
86e0da7a 252 lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr);
c906108c
SS
253 }
254
255 /* generate the code (or at least something */
256 lf_printf (file, "\n");
257 lf_printf (file, "/* semantics: */\n");
258 if (instruction->code != NULL)
259 {
260 /* true code */
261 lf_printf (file, "{\n");
262 lf_indent (file, +2);
263 lf_print__line_ref (file, instruction->code->line);
264 table_print_code (file, instruction->code);
265 lf_indent (file, -2);
266 lf_printf (file, "}\n");
267 lf_print__internal_ref (file);
268 }
269 else if (filter_is_member (instruction->options, "nop"))
270 {
271 lf_print__internal_ref (file);
272 }
273 else
274 {
275 const char *prefix = "sim_engine_abort (";
276 int indent = strlen (prefix);
277 /* abort so it is implemented now */
278 lf_print__line_ref (file, instruction->line);
279 lf_printf (file, "%sSD, CPU, cia, \\\n", prefix);
280 lf_indent (file, +indent);
281 lf_printf (file, "\"%s:%d:0x%%08lx:%%s unimplemented\\n\", \\\n",
282 filter_filename (instruction->line->file_name),
283 instruction->line->line_nr);
284 lf_printf (file, "(long) CIA, \\\n");
285 lf_printf (file, "%sitable[MY_INDEX].name);\n",
286 options.module.itable.prefix.l);
287 lf_indent (file, -indent);
288 lf_print__internal_ref (file);
289 }
290
291 /* Close off the conditional execution */
292 if (filter_is_member (instruction->options, "c")
293 || options.gen.conditional_issue)
294 {
295 lf_indent (file, -4);
296 lf_printf (file, " }\n");
297 }
298}
299
300static void
301print_c_semantic (lf *file,
302 insn_entry *instruction,
303 opcode_bits *expanded_bits,
304 insn_opcodes *opcodes,
305 cache_entry *cache_rules,
306 int nr_prefetched_words)
307{
308
309 lf_printf (file, "{\n");
310 lf_indent (file, +2);
311
312 print_my_defines (file,
313 instruction->name,
314 instruction->format_name,
315 expanded_bits);
316 lf_printf (file, "\n");
317 print_icache_body (file,
318 instruction,
319 expanded_bits,
320 cache_rules,
321 (options.gen.direct_access
322 ? define_variables
323 : declare_variables),
324 (options.gen.icache
325 ? get_values_from_icache
326 : do_not_use_icache),
327 nr_prefetched_words);
328
329 lf_printf (file, "%sinstruction_address nia;\n", options.module.global.prefix.l);
330 print_semantic_body (file,
331 instruction,
332 expanded_bits,
333 opcodes);
334 lf_printf (file, "return nia;\n");
335
336 /* generate something to clean up any #defines created for the cache */
337 if (options.gen.direct_access)
338 {
339 print_icache_body (file,
340 instruction,
341 expanded_bits,
342 cache_rules,
343 undef_variables,
344 (options.gen.icache
345 ? get_values_from_icache
346 : do_not_use_icache),
347 nr_prefetched_words);
348 }
349
350 lf_indent (file, -2);
351 lf_printf (file, "}\n");
352}
353
354static void
355print_c_semantic_function (lf *file,
356 insn_entry *instruction,
357 opcode_bits *expanded_bits,
358 insn_opcodes *opcodes,
359 cache_entry *cache_rules,
360 int nr_prefetched_words)
361{
362 /* build the semantic routine to execute the instruction */
363 print_semantic_function_header (file,
364 instruction->name,
365 instruction->format_name,
366 expanded_bits,
367 1/*is-function-definition*/,
368 nr_prefetched_words);
369 print_c_semantic (file,
370 instruction,
371 expanded_bits,
372 opcodes,
373 cache_rules,
374 nr_prefetched_words);
375}
376
377void
378print_semantic_definition (lf *file,
379 insn_entry *insn,
380 opcode_bits *expanded_bits,
381 insn_opcodes *opcodes,
382 cache_entry *cache_rules,
383 int nr_prefetched_words)
384{
385 print_c_semantic_function (file,
386 insn,
387 expanded_bits,
388 opcodes,
389 cache_rules,
390 nr_prefetched_words);
391}
392
393
This page took 0.168056 seconds and 4 git commands to generate.