gen-icache.c revision 1.1.1.2 1 1.1 christos /* This file is part of the program psim.
2 1.1 christos
3 1.1 christos Copyright (C) 1994-1997, Andrew Cagney <cagney (at) highland.com.au>
4 1.1 christos
5 1.1 christos This program is free software; you can redistribute it and/or modify
6 1.1 christos it under the terms of the GNU General Public License as published by
7 1.1 christos the Free Software Foundation; either version 3 of the License, or
8 1.1 christos (at your option) any later version.
9 1.1 christos
10 1.1 christos This program is distributed in the hope that it will be useful,
11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 1.1 christos GNU General Public License for more details.
14 1.1 christos
15 1.1 christos You should have received a copy of the GNU General Public License
16 1.1 christos along with this program; if not, see <http://www.gnu.org/licenses/>.
17 1.1 christos
18 1.1 christos */
19 1.1 christos
20 1.1.1.2 christos #include <stdlib.h>
21 1.1 christos
22 1.1 christos #include "misc.h"
23 1.1 christos #include "lf.h"
24 1.1 christos #include "table.h"
25 1.1 christos
26 1.1 christos #include "filter.h"
27 1.1 christos
28 1.1 christos #include "ld-decode.h"
29 1.1 christos #include "ld-cache.h"
30 1.1 christos #include "ld-insn.h"
31 1.1 christos
32 1.1 christos #include "igen.h"
33 1.1 christos
34 1.1 christos #include "gen-semantics.h"
35 1.1 christos #include "gen-idecode.h"
36 1.1 christos #include "gen-icache.h"
37 1.1 christos
38 1.1 christos
39 1.1 christos
40 1.1 christos static void
41 1.1 christos print_icache_function_header(lf *file,
42 1.1 christos const char *basename,
43 1.1 christos insn_bits *expanded_bits,
44 1.1 christos int is_function_definition)
45 1.1 christos {
46 1.1 christos lf_printf(file, "\n");
47 1.1 christos lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "EXTERN_ICACHE", " ");
48 1.1 christos print_function_name(file,
49 1.1 christos basename,
50 1.1 christos expanded_bits,
51 1.1 christos function_name_prefix_icache);
52 1.1 christos lf_printf(file, "\n(%s)", ICACHE_FUNCTION_FORMAL);
53 1.1 christos if (!is_function_definition)
54 1.1 christos lf_printf(file, ";");
55 1.1 christos lf_printf(file, "\n");
56 1.1 christos }
57 1.1 christos
58 1.1 christos
59 1.1 christos void
60 1.1 christos print_icache_declaration(insn_table *entry,
61 1.1 christos lf *file,
62 1.1 christos void *data,
63 1.1 christos insn *instruction,
64 1.1 christos int depth)
65 1.1 christos {
66 1.1 christos if (generate_expanded_instructions) {
67 1.1 christos ASSERT(entry->nr_insn == 1);
68 1.1 christos print_icache_function_header(file,
69 1.1 christos entry->insns->file_entry->fields[insn_name],
70 1.1 christos entry->expanded_bits,
71 1.1 christos 0/* is not function definition */);
72 1.1 christos }
73 1.1 christos else {
74 1.1 christos print_icache_function_header(file,
75 1.1 christos instruction->file_entry->fields[insn_name],
76 1.1 christos NULL,
77 1.1 christos 0/* is not function definition */);
78 1.1 christos }
79 1.1 christos }
80 1.1 christos
81 1.1 christos
82 1.1 christos
83 1.1 christos static void
84 1.1 christos print_icache_extraction(lf *file,
85 1.1 christos insn *instruction,
86 1.1 christos const char *entry_name,
87 1.1 christos const char *entry_type,
88 1.1 christos const char *entry_expression,
89 1.1 christos const char *original_name,
90 1.1 christos const char *file_name,
91 1.1 christos int line_nr,
92 1.1 christos insn_field *cur_field,
93 1.1 christos insn_bits *bits,
94 1.1 christos icache_decl_type what_to_declare,
95 1.1 christos icache_body_type what_to_do,
96 1.1 christos const char *reason)
97 1.1 christos {
98 1.1 christos const char *expression;
99 1.1 christos ASSERT(entry_name != NULL);
100 1.1 christos
101 1.1 christos /* Define a storage area for the cache element */
102 1.1 christos if (what_to_declare == undef_variables) {
103 1.1 christos /* We've finished with the value - destory it */
104 1.1 christos lf_indent_suppress(file);
105 1.1 christos lf_printf(file, "#undef %s\n", entry_name);
106 1.1 christos return;
107 1.1 christos }
108 1.1 christos else if (what_to_declare == define_variables) {
109 1.1 christos lf_indent_suppress(file);
110 1.1 christos lf_printf(file, "#define %s ", entry_name);
111 1.1 christos }
112 1.1 christos else {
113 1.1 christos if (file_name != NULL)
114 1.1 christos lf_print__external_reference(file, line_nr, file_name);
115 1.1.1.2 christos lf_printf(file, "%s const %s ATTRIBUTE_UNUSED = ",
116 1.1 christos entry_type == NULL ? "unsigned" : entry_type,
117 1.1 christos entry_name);
118 1.1 christos }
119 1.1 christos
120 1.1 christos /* define a value for that storage area as determined by what is in
121 1.1 christos the cache */
122 1.1 christos if (bits != NULL
123 1.1 christos && strcmp(entry_name, cur_field->val_string) == 0
124 1.1 christos && ((bits->opcode->is_boolean && bits->value == 0)
125 1.1 christos || (!bits->opcode->is_boolean))) {
126 1.1 christos /* The simple field has been made constant (as a result of
127 1.1 christos expanding instructions or similar). Remember that for a
128 1.1 christos boolean field, value is either 0 (implying the required
129 1.1 christos boolean_constant) or nonzero (implying some other value and
130 1.1 christos handled later below) - Define the variable accordingly */
131 1.1 christos expression = "constant field";
132 1.1 christos ASSERT(bits->field == cur_field);
133 1.1 christos ASSERT(entry_type == NULL);
134 1.1 christos if (bits->opcode->is_boolean)
135 1.1 christos lf_printf(file, "%d", bits->opcode->boolean_constant);
136 1.1 christos else if (bits->opcode->last < bits->field->last)
137 1.1 christos lf_printf(file, "%d",
138 1.1 christos bits->value << (bits->field->last - bits->opcode->last));
139 1.1 christos else
140 1.1 christos lf_printf(file, "%d", bits->value);
141 1.1 christos }
142 1.1 christos else if (bits != NULL
143 1.1 christos && original_name != NULL
144 1.1 christos && strncmp(entry_name,
145 1.1 christos original_name, strlen(original_name)) == 0
146 1.1 christos && strncmp(entry_name + strlen(original_name),
147 1.1 christos "_is_", strlen("_is_")) == 0
148 1.1 christos && ((bits->opcode->is_boolean
149 1.1 christos && (atol(entry_name + strlen(original_name) + strlen("_is_"))
150 1.1 christos == bits->opcode->boolean_constant))
151 1.1 christos || (!bits->opcode->is_boolean))) {
152 1.1 christos expression = "constant compare";
153 1.1 christos /* An entry, derived from ORIGINAL_NAME, is testing to see of the
154 1.1 christos ORIGINAL_NAME has a specific constant value. That value
155 1.1 christos matching a boolean or constant field */
156 1.1 christos if (bits->opcode->is_boolean)
157 1.1 christos lf_printf(file, "%d /* %s == %d */",
158 1.1 christos bits->value == 0,
159 1.1 christos original_name,
160 1.1 christos bits->opcode->boolean_constant);
161 1.1 christos else if (bits->opcode->last < bits->field->last)
162 1.1 christos lf_printf(file, "%d /* %s == %d */",
163 1.1 christos (atol(entry_name + strlen(original_name) + strlen("_is_"))
164 1.1 christos == (bits->value << (bits->field->last - bits->opcode->last))),
165 1.1 christos original_name,
166 1.1 christos (bits->value << (bits->field->last - bits->opcode->last)));
167 1.1 christos else
168 1.1 christos lf_printf(file, "%d /* %s == %d */",
169 1.1 christos (atol(entry_name + strlen(original_name) + strlen("_is_"))
170 1.1 christos == bits->value),
171 1.1 christos original_name,
172 1.1 christos bits->value);
173 1.1 christos }
174 1.1 christos else {
175 1.1 christos /* put the field in the local variable, possibly also enter it
176 1.1 christos into the cache */
177 1.1 christos expression = "extraction";
178 1.1 christos /* handle the cache */
179 1.1 christos if ((what_to_do & get_values_from_icache)
180 1.1 christos || (what_to_do & put_values_in_icache)) {
181 1.1 christos lf_printf(file, "cache_entry->crack.%s.%s",
182 1.1 christos instruction->file_entry->fields[insn_form],
183 1.1 christos entry_name);
184 1.1 christos if (what_to_do & put_values_in_icache) /* also put it in the cache? */
185 1.1 christos lf_printf(file, " = ");
186 1.1 christos }
187 1.1 christos if ((what_to_do & put_values_in_icache)
188 1.1 christos || what_to_do == do_not_use_icache) {
189 1.1 christos if (cur_field != NULL && strcmp(entry_name, cur_field->val_string) == 0)
190 1.1 christos lf_printf(file, "EXTRACTED32(instruction, %d, %d)",
191 1.1 christos i2target(hi_bit_nr, cur_field->first),
192 1.1 christos i2target(hi_bit_nr, cur_field->last));
193 1.1 christos else if (entry_expression != NULL)
194 1.1 christos lf_printf(file, "%s", entry_expression);
195 1.1 christos else
196 1.1 christos lf_printf(file, "eval_%s", entry_name);
197 1.1 christos }
198 1.1 christos }
199 1.1 christos
200 1.1 christos if (!((what_to_declare == define_variables)
201 1.1 christos || (what_to_declare == undef_variables)))
202 1.1 christos lf_printf(file, ";");
203 1.1 christos if (reason != NULL)
204 1.1 christos lf_printf(file, " /* %s - %s */", reason, expression);
205 1.1 christos lf_printf(file, "\n");
206 1.1 christos }
207 1.1 christos
208 1.1 christos
209 1.1 christos void
210 1.1 christos print_icache_body(lf *file,
211 1.1 christos insn *instruction,
212 1.1 christos insn_bits *expanded_bits,
213 1.1 christos cache_table *cache_rules,
214 1.1 christos icache_decl_type what_to_declare,
215 1.1 christos icache_body_type what_to_do)
216 1.1 christos {
217 1.1 christos insn_field *cur_field;
218 1.1 christos
219 1.1 christos /* extract instruction fields */
220 1.1 christos lf_printf(file, "/* extraction: %s ",
221 1.1 christos instruction->file_entry->fields[insn_format]);
222 1.1 christos switch (what_to_declare) {
223 1.1 christos case define_variables:
224 1.1 christos lf_printf(file, "#define");
225 1.1 christos break;
226 1.1 christos case declare_variables:
227 1.1 christos lf_printf(file, "declare");
228 1.1 christos break;
229 1.1 christos case undef_variables:
230 1.1 christos lf_printf(file, "#undef");
231 1.1 christos break;
232 1.1 christos }
233 1.1 christos lf_printf(file, " ");
234 1.1 christos switch (what_to_do) {
235 1.1 christos case get_values_from_icache:
236 1.1 christos lf_printf(file, "get-values-from-icache");
237 1.1 christos break;
238 1.1 christos case put_values_in_icache:
239 1.1 christos lf_printf(file, "put-values-in-icache");
240 1.1 christos break;
241 1.1 christos case both_values_and_icache:
242 1.1 christos lf_printf(file, "get-values-from-icache|put-values-in-icache");
243 1.1 christos break;
244 1.1 christos case do_not_use_icache:
245 1.1 christos lf_printf(file, "do-not-use-icache");
246 1.1 christos break;
247 1.1 christos }
248 1.1 christos lf_printf(file, " */\n");
249 1.1 christos
250 1.1 christos for (cur_field = instruction->fields->first;
251 1.1 christos cur_field->first < insn_bit_size;
252 1.1 christos cur_field = cur_field->next) {
253 1.1 christos if (cur_field->is_string) {
254 1.1 christos insn_bits *bits;
255 1.1 christos int found_rule = 0;
256 1.1 christos /* find any corresponding value */
257 1.1 christos for (bits = expanded_bits;
258 1.1 christos bits != NULL;
259 1.1 christos bits = bits->last) {
260 1.1 christos if (bits->field == cur_field)
261 1.1 christos break;
262 1.1 christos }
263 1.1 christos /* try the cache rule table for what to do */
264 1.1 christos {
265 1.1 christos cache_table *cache_rule;
266 1.1 christos for (cache_rule = cache_rules;
267 1.1 christos cache_rule != NULL;
268 1.1 christos cache_rule = cache_rule->next) {
269 1.1 christos if (strcmp(cur_field->val_string, cache_rule->field_name) == 0) {
270 1.1 christos found_rule = 1;
271 1.1 christos if (cache_rule->type == scratch_value
272 1.1 christos && ((what_to_do & put_values_in_icache)
273 1.1 christos || what_to_do == do_not_use_icache))
274 1.1 christos print_icache_extraction(file,
275 1.1 christos instruction,
276 1.1 christos cache_rule->derived_name,
277 1.1 christos cache_rule->type_def,
278 1.1 christos cache_rule->expression,
279 1.1 christos cache_rule->field_name,
280 1.1 christos cache_rule->file_entry->file_name,
281 1.1 christos cache_rule->file_entry->line_nr,
282 1.1 christos cur_field,
283 1.1 christos bits,
284 1.1 christos what_to_declare,
285 1.1 christos do_not_use_icache,
286 1.1 christos "icache scratch");
287 1.1 christos else if (cache_rule->type == compute_value
288 1.1 christos && ((what_to_do & get_values_from_icache)
289 1.1 christos || what_to_do == do_not_use_icache))
290 1.1 christos print_icache_extraction(file,
291 1.1 christos instruction,
292 1.1 christos cache_rule->derived_name,
293 1.1 christos cache_rule->type_def,
294 1.1 christos cache_rule->expression,
295 1.1 christos cache_rule->field_name,
296 1.1 christos cache_rule->file_entry->file_name,
297 1.1 christos cache_rule->file_entry->line_nr,
298 1.1 christos cur_field,
299 1.1 christos bits,
300 1.1 christos what_to_declare,
301 1.1 christos do_not_use_icache,
302 1.1 christos "semantic compute");
303 1.1 christos else if (cache_rule->type == cache_value
304 1.1 christos && ((what_to_declare != undef_variables)
305 1.1 christos || !(what_to_do & put_values_in_icache)))
306 1.1 christos print_icache_extraction(file,
307 1.1 christos instruction,
308 1.1 christos cache_rule->derived_name,
309 1.1 christos cache_rule->type_def,
310 1.1 christos cache_rule->expression,
311 1.1 christos cache_rule->field_name,
312 1.1 christos cache_rule->file_entry->file_name,
313 1.1 christos cache_rule->file_entry->line_nr,
314 1.1 christos cur_field,
315 1.1 christos bits,
316 1.1 christos ((what_to_do & put_values_in_icache)
317 1.1 christos ? declare_variables
318 1.1 christos : what_to_declare),
319 1.1 christos what_to_do,
320 1.1 christos "in icache");
321 1.1 christos }
322 1.1 christos }
323 1.1 christos }
324 1.1 christos /* No rule at all, assume that this is needed in the semantic
325 1.1 christos function (when values are extracted from the icache) and
326 1.1 christos hence must be put into the cache */
327 1.1 christos if (found_rule == 0
328 1.1 christos && ((what_to_declare != undef_variables)
329 1.1 christos || !(what_to_do & put_values_in_icache)))
330 1.1 christos print_icache_extraction(file,
331 1.1 christos instruction,
332 1.1 christos cur_field->val_string,
333 1.1 christos NULL, NULL, NULL, /* type, exp, orig */
334 1.1 christos instruction->file_entry->file_name,
335 1.1 christos instruction->file_entry->line_nr,
336 1.1 christos cur_field,
337 1.1 christos bits,
338 1.1 christos ((what_to_do & put_values_in_icache)
339 1.1 christos ? declare_variables
340 1.1 christos : what_to_declare),
341 1.1 christos what_to_do,
342 1.1 christos "default in icache");
343 1.1 christos /* any thing else ... */
344 1.1 christos }
345 1.1 christos }
346 1.1 christos
347 1.1 christos lf_print__internal_reference(file);
348 1.1 christos
349 1.1 christos if ((code & generate_with_insn_in_icache)) {
350 1.1 christos lf_printf(file, "\n");
351 1.1 christos print_icache_extraction(file,
352 1.1 christos instruction,
353 1.1 christos "insn",
354 1.1 christos "instruction_word",
355 1.1 christos "instruction",
356 1.1 christos NULL, /* origin */
357 1.1 christos NULL, 0, /* file_name & line_nr */
358 1.1 christos NULL, NULL,
359 1.1 christos what_to_declare,
360 1.1 christos what_to_do,
361 1.1 christos NULL);
362 1.1 christos }
363 1.1 christos }
364 1.1 christos
365 1.1 christos
366 1.1 christos
367 1.1 christos typedef struct _icache_tree icache_tree;
368 1.1 christos struct _icache_tree {
369 1.1.1.2 christos const char *name;
370 1.1 christos icache_tree *next;
371 1.1 christos icache_tree *children;
372 1.1 christos };
373 1.1 christos
374 1.1 christos static icache_tree *
375 1.1 christos icache_tree_insert(icache_tree *tree,
376 1.1.1.2 christos const char *name)
377 1.1 christos {
378 1.1 christos icache_tree *new_tree;
379 1.1 christos /* find it */
380 1.1 christos icache_tree **ptr_to_cur_tree = &tree->children;
381 1.1 christos icache_tree *cur_tree = *ptr_to_cur_tree;
382 1.1 christos while (cur_tree != NULL
383 1.1 christos && strcmp(cur_tree->name, name) < 0) {
384 1.1 christos ptr_to_cur_tree = &cur_tree->next;
385 1.1 christos cur_tree = *ptr_to_cur_tree;
386 1.1 christos }
387 1.1 christos ASSERT(cur_tree == NULL
388 1.1 christos || strcmp(cur_tree->name, name) >= 0);
389 1.1 christos /* already in the tree */
390 1.1 christos if (cur_tree != NULL
391 1.1 christos && strcmp(cur_tree->name, name) == 0)
392 1.1 christos return cur_tree;
393 1.1 christos /* missing, insert it */
394 1.1 christos ASSERT(cur_tree == NULL
395 1.1 christos || strcmp(cur_tree->name, name) > 0);
396 1.1 christos new_tree = ZALLOC(icache_tree);
397 1.1 christos new_tree->name = name;
398 1.1 christos new_tree->next = cur_tree;
399 1.1 christos *ptr_to_cur_tree = new_tree;
400 1.1 christos return new_tree;
401 1.1 christos }
402 1.1 christos
403 1.1 christos
404 1.1 christos static icache_tree *
405 1.1 christos insn_table_cache_fields(insn_table *table)
406 1.1 christos {
407 1.1 christos icache_tree *tree = ZALLOC(icache_tree);
408 1.1 christos insn *instruction;
409 1.1 christos for (instruction = table->insns;
410 1.1 christos instruction != NULL;
411 1.1 christos instruction = instruction->next) {
412 1.1 christos insn_field *field;
413 1.1 christos icache_tree *form =
414 1.1 christos icache_tree_insert(tree,
415 1.1 christos instruction->file_entry->fields[insn_form]);
416 1.1 christos for (field = instruction->fields->first;
417 1.1 christos field != NULL;
418 1.1 christos field = field->next) {
419 1.1 christos if (field->is_string)
420 1.1 christos icache_tree_insert(form, field->val_string);
421 1.1 christos }
422 1.1 christos }
423 1.1 christos return tree;
424 1.1 christos }
425 1.1 christos
426 1.1 christos
427 1.1 christos
428 1.1 christos extern void
429 1.1 christos print_icache_struct(insn_table *instructions,
430 1.1 christos cache_table *cache_rules,
431 1.1 christos lf *file)
432 1.1 christos {
433 1.1 christos icache_tree *tree = insn_table_cache_fields(instructions);
434 1.1 christos
435 1.1 christos lf_printf(file, "\n");
436 1.1 christos lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n",
437 1.1 christos (code & generate_with_icache) ? icache_size : 0);
438 1.1 christos lf_printf(file, "\n");
439 1.1 christos
440 1.1 christos /* create an instruction cache if being used */
441 1.1 christos if ((code & generate_with_icache)) {
442 1.1 christos icache_tree *form;
443 1.1 christos lf_printf(file, "typedef struct _idecode_cache {\n");
444 1.1 christos lf_printf(file, " unsigned_word address;\n");
445 1.1 christos lf_printf(file, " void *semantic;\n");
446 1.1 christos lf_printf(file, " union {\n");
447 1.1 christos for (form = tree->children;
448 1.1 christos form != NULL;
449 1.1 christos form = form->next) {
450 1.1 christos icache_tree *field;
451 1.1 christos lf_printf(file, " struct {\n");
452 1.1 christos if (code & generate_with_insn_in_icache)
453 1.1 christos lf_printf(file, " instruction_word insn;\n");
454 1.1 christos for (field = form->children;
455 1.1 christos field != NULL;
456 1.1 christos field = field->next) {
457 1.1 christos cache_table *cache_rule;
458 1.1 christos int found_rule = 0;
459 1.1 christos for (cache_rule = cache_rules;
460 1.1 christos cache_rule != NULL;
461 1.1 christos cache_rule = cache_rule->next) {
462 1.1 christos if (strcmp(field->name, cache_rule->field_name) == 0) {
463 1.1 christos found_rule = 1;
464 1.1 christos if (cache_rule->derived_name != NULL)
465 1.1 christos lf_printf(file, " %s %s; /* %s */\n",
466 1.1 christos (cache_rule->type_def == NULL
467 1.1 christos ? "unsigned"
468 1.1 christos : cache_rule->type_def),
469 1.1 christos cache_rule->derived_name,
470 1.1 christos cache_rule->field_name);
471 1.1 christos }
472 1.1 christos }
473 1.1 christos if (!found_rule)
474 1.1 christos lf_printf(file, " unsigned %s;\n", field->name);
475 1.1 christos }
476 1.1 christos lf_printf(file, " } %s;\n", form->name);
477 1.1 christos }
478 1.1 christos lf_printf(file, " } crack;\n");
479 1.1 christos lf_printf(file, "} idecode_cache;\n");
480 1.1 christos }
481 1.1 christos else {
482 1.1 christos /* alernativly, since no cache, emit a dummy definition for
483 1.1 christos idecode_cache so that code refering to the type can still compile */
484 1.1 christos lf_printf(file, "typedef void idecode_cache;\n");
485 1.1 christos }
486 1.1 christos lf_printf(file, "\n");
487 1.1 christos }
488 1.1 christos
489 1.1 christos
490 1.1 christos
491 1.1 christos static void
492 1.1 christos print_icache_function(lf *file,
493 1.1 christos insn *instruction,
494 1.1 christos insn_bits *expanded_bits,
495 1.1 christos opcode_field *opcodes,
496 1.1 christos cache_table *cache_rules)
497 1.1 christos {
498 1.1 christos int indent;
499 1.1 christos
500 1.1 christos /* generate code to enter decoded instruction into the icache */
501 1.1 christos lf_printf(file, "\n");
502 1.1 christos lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "EXTERN_ICACHE", "\n");
503 1.1 christos indent = print_function_name(file,
504 1.1 christos instruction->file_entry->fields[insn_name],
505 1.1 christos expanded_bits,
506 1.1 christos function_name_prefix_icache);
507 1.1 christos lf_indent(file, +indent);
508 1.1 christos lf_printf(file, "(%s)\n", ICACHE_FUNCTION_FORMAL);
509 1.1 christos lf_indent(file, -indent);
510 1.1 christos
511 1.1 christos /* function header */
512 1.1 christos lf_printf(file, "{\n");
513 1.1 christos lf_indent(file, +2);
514 1.1 christos
515 1.1 christos print_my_defines(file, expanded_bits, instruction->file_entry);
516 1.1 christos print_itrace(file, instruction->file_entry, 1/*putting-value-in-cache*/);
517 1.1 christos
518 1.1 christos print_idecode_validate(file, instruction, opcodes);
519 1.1 christos
520 1.1 christos lf_printf(file, "\n");
521 1.1 christos lf_printf(file, "{\n");
522 1.1 christos lf_indent(file, +2);
523 1.1 christos if ((code & generate_with_semantic_icache))
524 1.1 christos lf_printf(file, "unsigned_word nia;\n");
525 1.1 christos print_icache_body(file,
526 1.1 christos instruction,
527 1.1 christos expanded_bits,
528 1.1 christos cache_rules,
529 1.1 christos ((code & generate_with_direct_access)
530 1.1 christos ? define_variables
531 1.1 christos : declare_variables),
532 1.1 christos ((code & generate_with_semantic_icache)
533 1.1 christos ? both_values_and_icache
534 1.1 christos : put_values_in_icache));
535 1.1 christos
536 1.1 christos lf_printf(file, "\n");
537 1.1 christos lf_printf(file, "cache_entry->address = cia;\n");
538 1.1 christos lf_printf(file, "cache_entry->semantic = ");
539 1.1 christos print_function_name(file,
540 1.1 christos instruction->file_entry->fields[insn_name],
541 1.1 christos expanded_bits,
542 1.1 christos function_name_prefix_semantics);
543 1.1 christos lf_printf(file, ";\n");
544 1.1 christos lf_printf(file, "\n");
545 1.1 christos
546 1.1 christos if ((code & generate_with_semantic_icache)) {
547 1.1 christos lf_printf(file, "/* semantic routine */\n");
548 1.1 christos print_semantic_body(file,
549 1.1 christos instruction,
550 1.1 christos expanded_bits,
551 1.1 christos opcodes);
552 1.1 christos lf_printf(file, "return nia;\n");
553 1.1 christos }
554 1.1 christos
555 1.1 christos if (!(code & generate_with_semantic_icache)) {
556 1.1 christos lf_printf(file, "/* return the function proper */\n");
557 1.1 christos lf_printf(file, "return ");
558 1.1 christos print_function_name(file,
559 1.1 christos instruction->file_entry->fields[insn_name],
560 1.1 christos expanded_bits,
561 1.1 christos function_name_prefix_semantics);
562 1.1 christos lf_printf(file, ";\n");
563 1.1 christos }
564 1.1 christos
565 1.1 christos if ((code & generate_with_direct_access))
566 1.1 christos print_icache_body(file,
567 1.1 christos instruction,
568 1.1 christos expanded_bits,
569 1.1 christos cache_rules,
570 1.1 christos undef_variables,
571 1.1 christos ((code & generate_with_semantic_icache)
572 1.1 christos ? both_values_and_icache
573 1.1 christos : put_values_in_icache));
574 1.1 christos
575 1.1 christos lf_indent(file, -2);
576 1.1 christos lf_printf(file, "}\n");
577 1.1 christos lf_indent(file, -2);
578 1.1 christos lf_printf(file, "}\n");
579 1.1 christos }
580 1.1 christos
581 1.1 christos
582 1.1 christos void
583 1.1 christos print_icache_definition(insn_table *entry,
584 1.1 christos lf *file,
585 1.1 christos void *data,
586 1.1 christos insn *instruction,
587 1.1 christos int depth)
588 1.1 christos {
589 1.1 christos cache_table *cache_rules = (cache_table*)data;
590 1.1 christos if (generate_expanded_instructions) {
591 1.1 christos ASSERT(entry->nr_insn == 1
592 1.1 christos && entry->opcode == NULL
593 1.1 christos && entry->parent != NULL
594 1.1 christos && entry->parent->opcode != NULL);
595 1.1 christos ASSERT(entry->nr_insn == 1
596 1.1 christos && entry->opcode == NULL
597 1.1 christos && entry->parent != NULL
598 1.1 christos && entry->parent->opcode != NULL
599 1.1 christos && entry->parent->opcode_rule != NULL);
600 1.1 christos print_icache_function(file,
601 1.1 christos entry->insns,
602 1.1 christos entry->expanded_bits,
603 1.1 christos entry->opcode,
604 1.1 christos cache_rules);
605 1.1 christos }
606 1.1 christos else {
607 1.1 christos print_icache_function(file,
608 1.1 christos instruction,
609 1.1 christos NULL,
610 1.1 christos NULL,
611 1.1 christos cache_rules);
612 1.1 christos }
613 1.1 christos }
614 1.1 christos
615 1.1 christos
616 1.1 christos
617 1.1 christos void
618 1.1 christos print_icache_internal_function_declaration(insn_table *table,
619 1.1 christos lf *file,
620 1.1 christos void *data,
621 1.1 christos table_entry *function)
622 1.1 christos {
623 1.1 christos ASSERT((code & generate_with_icache) != 0);
624 1.1 christos if (it_is("internal", function->fields[insn_flags])) {
625 1.1 christos lf_printf(file, "\n");
626 1.1 christos lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "PSIM_INLINE_ICACHE",
627 1.1 christos "\n");
628 1.1 christos print_function_name(file,
629 1.1 christos function->fields[insn_name],
630 1.1 christos NULL,
631 1.1 christos function_name_prefix_icache);
632 1.1 christos lf_printf(file, "\n(%s);\n", ICACHE_FUNCTION_FORMAL);
633 1.1 christos }
634 1.1 christos }
635 1.1 christos
636 1.1 christos
637 1.1 christos void
638 1.1 christos print_icache_internal_function_definition(insn_table *table,
639 1.1 christos lf *file,
640 1.1 christos void *data,
641 1.1 christos table_entry *function)
642 1.1 christos {
643 1.1 christos ASSERT((code & generate_with_icache) != 0);
644 1.1 christos if (it_is("internal", function->fields[insn_flags])) {
645 1.1 christos lf_printf(file, "\n");
646 1.1 christos lf_print_function_type(file, ICACHE_FUNCTION_TYPE, "PSIM_INLINE_ICACHE",
647 1.1 christos "\n");
648 1.1 christos print_function_name(file,
649 1.1 christos function->fields[insn_name],
650 1.1 christos NULL,
651 1.1 christos function_name_prefix_icache);
652 1.1 christos lf_printf(file, "\n(%s)\n", ICACHE_FUNCTION_FORMAL);
653 1.1 christos lf_printf(file, "{\n");
654 1.1 christos lf_indent(file, +2);
655 1.1 christos lf_printf(file, "/* semantic routine */\n");
656 1.1 christos table_entry_print_cpp_line_nr(file, function);
657 1.1 christos if ((code & generate_with_semantic_icache)) {
658 1.1 christos lf_print__c_code(file, function->annex);
659 1.1 christos lf_printf(file, "error(\"Internal function must longjump\\n\");\n");
660 1.1 christos lf_printf(file, "return 0;\n");
661 1.1 christos }
662 1.1 christos else {
663 1.1 christos lf_printf(file, "return ");
664 1.1 christos print_function_name(file,
665 1.1 christos function->fields[insn_name],
666 1.1 christos NULL,
667 1.1 christos function_name_prefix_semantics);
668 1.1 christos lf_printf(file, ";\n");
669 1.1 christos }
670 1.1 christos
671 1.1 christos lf_print__internal_reference(file);
672 1.1 christos lf_indent(file, -2);
673 1.1 christos lf_printf(file, "}\n");
674 1.1 christos }
675 1.1 christos }
676