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