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