]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/gen-semantics.c
Move 2006 ChangeLog entries to ChangeLog-2006.
[thirdparty/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;
4e0bf4c4 51 lf_printf (file, "\n");
c906108c
SS
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,
4e0bf4c4 88 insn_entry * insn,
c906108c 89 opcode_bits *expanded_bits,
4e0bf4c4 90 insn_opcodes *opcodes, int nr_prefetched_words)
c906108c
SS
91{
92 print_semantic_function_header (file,
93 insn->name,
94 insn->format_name,
95 expanded_bits,
4e0bf4c4 96 0 /* is not function definition */ ,
c906108c
SS
97 nr_prefetched_words);
98}
4e0bf4c4 99\f
c906108c
SS
100
101
c906108c
SS
102/* generate the semantics.c file */
103
104
105void
4e0bf4c4 106print_idecode_invalid (lf *file, const char *result, invalid_type type)
c906108c
SS
107{
108 const char *name;
109 switch (type)
110 {
4e0bf4c4
AC
111 default:
112 name = "unknown";
113 break;
114 case invalid_illegal:
115 name = "illegal";
116 break;
117 case invalid_fp_unavailable:
118 name = "fp_unavailable";
119 break;
120 case invalid_wrong_slot:
121 name = "wrong_slot";
122 break;
c906108c
SS
123 }
124 if (options.gen.code == generate_jumps)
125 {
126 lf_printf (file, "goto %s_%s;\n",
4e0bf4c4 127 (options.gen.icache ? "icache" : "semantic"), name);
c906108c
SS
128 }
129 else if (options.gen.icache)
130 {
4e0bf4c4
AC
131 lf_printf (file, "%s %sicache_%s (", result,
132 options.module.global.prefix.l, name);
c906108c
SS
133 print_icache_function_actual (file, 0);
134 lf_printf (file, ");\n");
135 }
136 else
137 {
4e0bf4c4
AC
138 lf_printf (file, "%s %ssemantic_%s (", result,
139 options.module.global.prefix.l, name);
c906108c
SS
140 print_semantic_function_actual (file, 0);
141 lf_printf (file, ");\n");
142 }
143}
144
145
146void
147print_semantic_body (lf *file,
4e0bf4c4
AC
148 insn_entry * instruction,
149 opcode_bits *expanded_bits, insn_opcodes *opcodes)
c906108c
SS
150{
151 /* validate the instruction, if a cache this has already been done */
152 if (!options.gen.icache)
153 {
154 print_idecode_validate (file, instruction, opcodes);
155 }
4e0bf4c4
AC
156
157 print_itrace (file, instruction, 0 /*put_value_in_cache */ );
158
c906108c
SS
159 /* generate the instruction profile call - this is delayed until
160 after the instruction has been verified. The count macro
161 generated is prefixed by ITABLE_PREFIX */
162 {
163 lf_printf (file, "\n");
164 lf_indent_suppress (file);
165 lf_printf (file, "#if defined (%sPROFILE_COUNT_INSN)\n",
166 options.module.itable.prefix.u);
167 lf_printf (file, "%sPROFILE_COUNT_INSN (CPU, CIA, MY_INDEX);\n",
168 options.module.itable.prefix.u);
169 lf_indent_suppress (file);
170 lf_printf (file, "#endif\n");
171 }
172
173 /* generate the model call - this is delayed until after the
174 instruction has been verified */
175 {
176 lf_printf (file, "\n");
177 lf_indent_suppress (file);
178 lf_printf (file, "#if defined (WITH_MON)\n");
179 lf_printf (file, "/* monitoring: */\n");
180 lf_printf (file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
181 lf_printf (file, " mon_issue (");
182 print_function_name (file,
183 instruction->name,
184 instruction->format_name,
4e0bf4c4 185 NULL, NULL, function_name_prefix_itable);
c906108c
SS
186 lf_printf (file, ", cpu, cia);\n");
187 lf_indent_suppress (file);
188 lf_printf (file, "#endif\n");
189 lf_printf (file, "\n");
190 }
4e0bf4c4 191
c906108c
SS
192 /* determine the new instruction address */
193 {
4e0bf4c4 194 lf_printf (file, "/* keep the next instruction address handy */\n");
c906108c
SS
195 if (options.gen.nia == nia_is_invalid)
196 {
4e0bf4c4
AC
197 lf_printf (file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n",
198 options.module.global.prefix.u);
c906108c
SS
199 }
200 else
201 {
202 int nr_immeds = instruction->nr_words - 1;
203 if (options.gen.delayed_branch)
204 {
205 if (nr_immeds > 0)
206 {
207 lf_printf (file, "cia.dp += %d * %d; %s\n",
208 options.insn_bit_size / 8, nr_immeds,
209 "/* skip dp immeds */");
210 }
211 lf_printf (file, "nia.ip = cia.dp; %s\n",
212 "/* instruction pointer */");
213 lf_printf (file, "nia.dp = cia.dp + %d; %s\n",
214 options.insn_bit_size / 8,
215 "/* delayed-slot pointer */");
216 }
217 else
218 {
219 if (nr_immeds > 0)
220 {
221 lf_printf (file, "nia = cia + %d * (%d + 1); %s\n",
222 options.insn_bit_size / 8, nr_immeds,
223 "/* skip immeds as well */");
4e0bf4c4 224
c906108c
SS
225 }
226 else
227 {
228 lf_printf (file, "nia = cia + %d;\n",
229 options.insn_bit_size / 8);
230 }
231 }
232 }
233 }
4e0bf4c4 234
c906108c
SS
235 /* if conditional, generate code to verify that the instruction
236 should be issued */
237 if (filter_is_member (instruction->options, "c")
238 || options.gen.conditional_issue)
239 {
240 lf_printf (file, "\n");
241 lf_printf (file, "/* execute only if conditional passes */\n");
242 lf_printf (file, "if (IS_CONDITION_OK)\n");
243 lf_printf (file, " {\n");
244 lf_indent (file, +4);
245 /* FIXME - need to log a conditional failure */
246 }
4e0bf4c4 247
c906108c
SS
248 /* Architecture expects a REG to be zero. Instead of having to
249 check every read to see if it is refering to that REG just zap it
250 at the start of every instruction */
251 if (options.gen.zero_reg)
252 {
253 lf_printf (file, "\n");
254 lf_printf (file, "/* Architecture expects REG to be zero */\n");
86e0da7a 255 lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr);
c906108c 256 }
4e0bf4c4 257
c906108c
SS
258 /* generate the code (or at least something */
259 lf_printf (file, "\n");
260 lf_printf (file, "/* semantics: */\n");
261 if (instruction->code != NULL)
262 {
263 /* true code */
264 lf_printf (file, "{\n");
265 lf_indent (file, +2);
266 lf_print__line_ref (file, instruction->code->line);
267 table_print_code (file, instruction->code);
268 lf_indent (file, -2);
269 lf_printf (file, "}\n");
270 lf_print__internal_ref (file);
271 }
272 else if (filter_is_member (instruction->options, "nop"))
273 {
274 lf_print__internal_ref (file);
275 }
276 else
277 {
278 const char *prefix = "sim_engine_abort (";
279 int indent = strlen (prefix);
280 /* abort so it is implemented now */
281 lf_print__line_ref (file, instruction->line);
282 lf_printf (file, "%sSD, CPU, cia, \\\n", prefix);
283 lf_indent (file, +indent);
284 lf_printf (file, "\"%s:%d:0x%%08lx:%%s unimplemented\\n\", \\\n",
285 filter_filename (instruction->line->file_name),
286 instruction->line->line_nr);
287 lf_printf (file, "(long) CIA, \\\n");
288 lf_printf (file, "%sitable[MY_INDEX].name);\n",
289 options.module.itable.prefix.l);
290 lf_indent (file, -indent);
291 lf_print__internal_ref (file);
292 }
4e0bf4c4 293
c906108c
SS
294 /* Close off the conditional execution */
295 if (filter_is_member (instruction->options, "c")
296 || options.gen.conditional_issue)
297 {
298 lf_indent (file, -4);
299 lf_printf (file, " }\n");
4e0bf4c4 300 }
c906108c
SS
301}
302
303static void
304print_c_semantic (lf *file,
4e0bf4c4 305 insn_entry * instruction,
c906108c
SS
306 opcode_bits *expanded_bits,
307 insn_opcodes *opcodes,
4e0bf4c4 308 cache_entry *cache_rules, int nr_prefetched_words)
c906108c 309{
4e0bf4c4 310
c906108c
SS
311 lf_printf (file, "{\n");
312 lf_indent (file, +2);
4e0bf4c4 313
c906108c
SS
314 print_my_defines (file,
315 instruction->name,
4e0bf4c4 316 instruction->format_name, expanded_bits);
c906108c
SS
317 lf_printf (file, "\n");
318 print_icache_body (file,
319 instruction,
320 expanded_bits,
321 cache_rules,
322 (options.gen.direct_access
323 ? define_variables
324 : declare_variables),
325 (options.gen.icache
326 ? get_values_from_icache
4e0bf4c4
AC
327 : do_not_use_icache), nr_prefetched_words);
328
329 lf_printf (file, "%sinstruction_address nia;\n",
330 options.module.global.prefix.l);
331 print_semantic_body (file, instruction, expanded_bits, opcodes);
c906108c 332 lf_printf (file, "return nia;\n");
4e0bf4c4 333
c906108c
SS
334 /* generate something to clean up any #defines created for the cache */
335 if (options.gen.direct_access)
336 {
337 print_icache_body (file,
338 instruction,
339 expanded_bits,
340 cache_rules,
341 undef_variables,
342 (options.gen.icache
343 ? get_values_from_icache
4e0bf4c4 344 : do_not_use_icache), nr_prefetched_words);
c906108c 345 }
4e0bf4c4 346
c906108c
SS
347 lf_indent (file, -2);
348 lf_printf (file, "}\n");
349}
350
351static void
352print_c_semantic_function (lf *file,
4e0bf4c4 353 insn_entry * instruction,
c906108c
SS
354 opcode_bits *expanded_bits,
355 insn_opcodes *opcodes,
4e0bf4c4 356 cache_entry *cache_rules, int nr_prefetched_words)
c906108c
SS
357{
358 /* build the semantic routine to execute the instruction */
359 print_semantic_function_header (file,
360 instruction->name,
361 instruction->format_name,
362 expanded_bits,
4e0bf4c4 363 1 /*is-function-definition */ ,
c906108c
SS
364 nr_prefetched_words);
365 print_c_semantic (file,
366 instruction,
4e0bf4c4 367 expanded_bits, opcodes, cache_rules, nr_prefetched_words);
c906108c
SS
368}
369
370void
371print_semantic_definition (lf *file,
4e0bf4c4 372 insn_entry * insn,
c906108c
SS
373 opcode_bits *expanded_bits,
374 insn_opcodes *opcodes,
4e0bf4c4 375 cache_entry *cache_rules, int nr_prefetched_words)
c906108c
SS
376{
377 print_c_semantic_function (file,
378 insn,
379 expanded_bits,
4e0bf4c4 380 opcodes, cache_rules, nr_prefetched_words);
c906108c 381}