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