OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [sim/] [igen/] [gen-icache.c] - Blame information for rev 24

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* The IGEN simulator generator for GDB, the GNU Debugger.
2
 
3
   Copyright 2002, 2007, 2008 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
#include "misc.h"
24
#include "lf.h"
25
#include "table.h"
26
#include "filter.h"
27
#include "igen.h"
28
 
29
#include "ld-insn.h"
30
#include "ld-decode.h"
31
 
32
#include "gen.h"
33
 
34
#include "gen-semantics.h"
35
#include "gen-idecode.h"
36
#include "gen-icache.h"
37
 
38
 
39
 
40
static void
41
print_icache_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
  lf_printf (file, "\n");
49
  lf_print__function_type_function (file, print_icache_function_type,
50
                                    "EXTERN_ICACHE", " ");
51
  print_function_name (file,
52
                       basename, format_name, NULL,
53
                       expanded_bits, function_name_prefix_icache);
54
  lf_printf (file, "\n(");
55
  print_icache_function_formal (file, nr_prefetched_words);
56
  lf_printf (file, ")");
57
  if (!is_function_definition)
58
    lf_printf (file, ";");
59
  lf_printf (file, "\n");
60
}
61
 
62
 
63
void
64
print_icache_declaration (lf *file,
65
                          insn_entry * insn,
66
                          opcode_bits *expanded_bits,
67
                          insn_opcodes *opcodes, int nr_prefetched_words)
68
{
69
  print_icache_function_header (file,
70
                                insn->name,
71
                                insn->format_name,
72
                                expanded_bits,
73
 
74
                                nr_prefetched_words);
75
}
76
 
77
 
78
 
79
static void
80
print_icache_extraction (lf *file,
81
                         const char *format_name,
82
                         cache_entry_type cache_type,
83
                         const char *entry_name,
84
                         const char *entry_type,
85
                         const char *entry_expression,
86
                         char *single_insn_field,
87
                         line_ref *line,
88
                         insn_field_entry *cur_field,
89
                         opcode_bits *expanded_bits,
90
                         icache_decl_type what_to_declare,
91
                         icache_body_type what_to_do)
92
{
93
  const char *expression;
94
  opcode_bits *bits;
95
  char *reason;
96
  ASSERT (format_name != NULL);
97
  ASSERT (entry_name != NULL);
98
 
99
  /* figure out exactly what should be going on here */
100
  switch (cache_type)
101
    {
102
    case scratch_value:
103
      if ((what_to_do & put_values_in_icache)
104
          || what_to_do == do_not_use_icache)
105
        {
106
          reason = "scratch";
107
          what_to_do = do_not_use_icache;
108
        }
109
      else
110
        return;
111
      break;
112
    case compute_value:
113
      if ((what_to_do & get_values_from_icache)
114
          || what_to_do == do_not_use_icache)
115
        {
116
          reason = "compute";
117
          what_to_do = do_not_use_icache;
118
        }
119
      else
120
        return;
121
      break;
122
    case cache_value:
123
      if ((what_to_declare != undef_variables)
124
          || !(what_to_do & put_values_in_icache))
125
        {
126
          reason = "cache";
127
          what_to_declare = ((what_to_do & put_values_in_icache)
128
                             ? declare_variables : what_to_declare);
129
        }
130
      else
131
        return;
132
      break;
133
    default:
134
      abort ();                 /* Bad switch.  */
135
    }
136
 
137
  /* For the type, default to a simple unsigned */
138
  if (entry_type == NULL || strlen (entry_type) == 0)
139
    entry_type = "unsigned";
140
 
141
  /* look through the set of expanded sub fields to see if this field
142
     has been given a constant value */
143
  for (bits = expanded_bits; bits != NULL; bits = bits->next)
144
    {
145
      if (bits->field == cur_field)
146
        break;
147
    }
148
 
149
  /* Define a storage area for the cache element */
150
  switch (what_to_declare)
151
    {
152
    case undef_variables:
153
      /* We've finished with the #define value - destory it */
154
      lf_indent_suppress (file);
155
      lf_printf (file, "#undef %s\n", entry_name);
156
      return;
157
    case define_variables:
158
      /* Using direct access for this entry, clear any prior
159
         definition, then define it */
160
      lf_indent_suppress (file);
161
      lf_printf (file, "#undef %s\n", entry_name);
162
      /* Don't type cast pointer types! */
163
      lf_indent_suppress (file);
164
      if (strchr (entry_type, '*') != NULL)
165
        lf_printf (file, "#define %s (", entry_name);
166
      else
167
        lf_printf (file, "#define %s ((%s) ", entry_name, entry_type);
168
      break;
169
    case declare_variables:
170
      /* using variables to define the value */
171
      if (line != NULL)
172
        lf_print__line_ref (file, line);
173
      lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
174
      break;
175
    }
176
 
177
 
178
  /* define a value for that storage area as determined by what is in
179
     the cache */
180
  if (bits != NULL
181
      && single_insn_field != NULL
182
      && strcmp (entry_name, single_insn_field) == 0
183
      && strcmp (entry_name, cur_field->val_string) == 0
184
      && ((bits->opcode->is_boolean && bits->value == 0)
185
          || (!bits->opcode->is_boolean)))
186
    {
187
      /* The cache rule is specifying what to do with a simple
188
         instruction field.
189
 
190
         Because of instruction expansion, the field is either a
191
         constant value or equal to the specified constant (boolean
192
         comparison). (The latter indicated by bits->value == 0).
193
 
194
         The case of a field not being equal to the specified boolean
195
         value is handled later. */
196
      expression = "constant field";
197
      ASSERT (bits->field == cur_field);
198
      if (bits->opcode->is_boolean)
199
        {
200
          ASSERT (bits->value == 0);
201
          lf_printf (file, "%d", bits->opcode->boolean_constant);
202
        }
203
      else if (bits->opcode->last < bits->field->last)
204
        {
205
          lf_printf (file, "%d",
206
                     bits->value << (bits->field->last - bits->opcode->last));
207
        }
208
      else
209
        {
210
          lf_printf (file, "%d", bits->value);
211
        }
212
    }
213
  else if (bits != NULL
214
           && single_insn_field != NULL
215
           && strncmp (entry_name,
216
                       single_insn_field,
217
                       strlen (single_insn_field)) == 0
218
           && strncmp (entry_name + strlen (single_insn_field),
219
                       "_is_",
220
                       strlen ("_is_")) == 0
221
           && ((bits->opcode->is_boolean
222
                && ((unsigned)
223
                    atol (entry_name + strlen (single_insn_field) +
224
                          strlen ("_is_")) == bits->opcode->boolean_constant))
225
               || (!bits->opcode->is_boolean)))
226
    {
227
      /* The cache rule defines an entry for the comparison between a
228
         single instruction field and a constant.  The value of the
229
         comparison in someway matches that of the opcode field that
230
         was made constant through expansion. */
231
      expression = "constant compare";
232
      if (bits->opcode->is_boolean)
233
        {
234
          lf_printf (file, "%d /* %s == %d */",
235
                     bits->value == 0,
236
                     single_insn_field, bits->opcode->boolean_constant);
237
        }
238
      else if (bits->opcode->last < bits->field->last)
239
        {
240
          lf_printf (file, "%d /* %s == %d */",
241
                     (atol
242
                      (entry_name + strlen (single_insn_field) +
243
                       strlen ("_is_")) ==
244
                      (bits->
245
                       value << (bits->field->last - bits->opcode->last))),
246
                     single_insn_field,
247
                     (bits->
248
                      value << (bits->field->last - bits->opcode->last)));
249
        }
250
      else
251
        {
252
          lf_printf (file, "%d /* %s == %d */",
253
                     (atol
254
                      (entry_name + strlen (single_insn_field) +
255
                       strlen ("_is_")) == bits->value), single_insn_field,
256
                     bits->value);
257
        }
258
    }
259
  else
260
    {
261
      /* put the field in the local variable, possibly also enter it
262
         into the cache */
263
      expression = "extraction";
264
      /* handle the cache */
265
      if ((what_to_do & get_values_from_icache)
266
          || (what_to_do & put_values_in_icache))
267
        {
268
          lf_printf (file, "cache_entry->crack.%s.%s",
269
                     format_name, entry_name);
270
          if (what_to_do & put_values_in_icache)        /* also put it in the cache? */
271
            {
272
              lf_printf (file, " = ");
273
            }
274
        }
275
      if ((what_to_do & put_values_in_icache)
276
          || what_to_do == do_not_use_icache)
277
        {
278
          if (cur_field != NULL)
279
            {
280
              if (entry_expression != NULL && strlen (entry_expression) > 0)
281
                error (line,
282
                       "Instruction field entry with nonempty expression\n");
283
              if (cur_field->first == 0
284
                  && cur_field->last == options.insn_bit_size - 1)
285
                lf_printf (file, "(instruction_%d)", cur_field->word_nr);
286
              else if (cur_field->last == options.insn_bit_size - 1)
287
                lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",
288
                           options.insn_bit_size,
289
                           cur_field->word_nr,
290
                           i2target (options.hi_bit_nr, cur_field->first),
291
                           i2target (options.hi_bit_nr, cur_field->last));
292
              else
293
                lf_printf (file, "EXTRACTED%d (instruction_%d, %d, %d)",
294
                           options.insn_bit_size,
295
                           cur_field->word_nr,
296
                           i2target (options.hi_bit_nr, cur_field->first),
297
                           i2target (options.hi_bit_nr, cur_field->last));
298
            }
299
          else
300
            {
301
              lf_printf (file, "%s", entry_expression);
302
            }
303
        }
304
    }
305
 
306
  switch (what_to_declare)
307
    {
308
    case define_variables:
309
      lf_printf (file, ")");
310
      break;
311
    case undef_variables:
312
      break;
313
    case declare_variables:
314
      lf_printf (file, ";");
315
      break;
316
    }
317
 
318
  ASSERT (reason != NULL && expression != NULL);
319
  lf_printf (file, " /* %s - %s */\n", reason, expression);
320
}
321
 
322
 
323
void
324
print_icache_body (lf *file,
325
                   insn_entry * instruction,
326
                   opcode_bits *expanded_bits,
327
                   cache_entry *cache_rules,
328
                   icache_decl_type what_to_declare,
329
                   icache_body_type what_to_do, int nr_prefetched_words)
330
{
331
  /* extract instruction fields */
332
  lf_printf (file, "/* Extraction: %s\n", instruction->name);
333
  lf_printf (file, "     ");
334
  switch (what_to_declare)
335
    {
336
    case define_variables:
337
      lf_printf (file, "#define");
338
      break;
339
    case declare_variables:
340
      lf_printf (file, "declare");
341
      break;
342
    case undef_variables:
343
      lf_printf (file, "#undef");
344
      break;
345
    }
346
  lf_printf (file, " ");
347
  switch (what_to_do)
348
    {
349
    case get_values_from_icache:
350
      lf_printf (file, "get-values-from-icache");
351
      break;
352
    case put_values_in_icache:
353
      lf_printf (file, "put-values-in-icache");
354
      break;
355
    case both_values_and_icache:
356
      lf_printf (file, "get-values-from-icache|put-values-in-icache");
357
      break;
358
    case do_not_use_icache:
359
      lf_printf (file, "do-not-use-icache");
360
      break;
361
    }
362
  lf_printf (file, "\n     ");
363
  print_insn_words (file, instruction);
364
  lf_printf (file, " */\n");
365
 
366
  /* pass zero - fetch from memory any missing instructions.
367
 
368
     Some of the instructions will have already been fetched (in the
369
     instruction array), others will still need fetching. */
370
  switch (what_to_do)
371
    {
372
    case get_values_from_icache:
373
      break;
374
    case put_values_in_icache:
375
    case both_values_and_icache:
376
    case do_not_use_icache:
377
      {
378
        int word_nr;
379
        switch (what_to_declare)
380
          {
381
          case undef_variables:
382
            break;
383
          case define_variables:
384
          case declare_variables:
385
            for (word_nr = nr_prefetched_words;
386
                 word_nr < instruction->nr_words; word_nr++)
387
              {
388
                /* FIXME - should be using print_icache_extraction? */
389
                lf_printf (file,
390
                           "%sinstruction_word instruction_%d UNUSED = ",
391
                           options.module.global.prefix.l, word_nr);
392
                lf_printf (file, "IMEM%d_IMMED (cia, %d)",
393
                           options.insn_bit_size, word_nr);
394
                lf_printf (file, ";\n");
395
              }
396
          }
397
      }
398
    }
399
 
400
  /* if putting the instruction words in the cache, define references
401
     for them */
402
  if (options.gen.insn_in_icache)
403
    {
404
      /* FIXME: is the instruction_word type correct? */
405
      print_icache_extraction (file, instruction->format_name, cache_value, "insn",     /* name */
406
                               "instruction_word",      /* type */
407
                               "instruction",   /* expression */
408
                               NULL,    /* origin */
409
                               NULL,    /* line */
410
                               NULL, NULL, what_to_declare, what_to_do);
411
    }
412
  lf_printf (file, "\n");
413
 
414
  /* pass one - process instruction fields.
415
 
416
     If there is no cache rule, the default is to enter the field into
417
     the cache */
418
  {
419
    insn_word_entry *word;
420
    for (word = instruction->words; word != NULL; word = word->next)
421
      {
422
        insn_field_entry *cur_field;
423
        for (cur_field = word->first;
424
             cur_field->first < options.insn_bit_size;
425
             cur_field = cur_field->next)
426
          {
427
            if (cur_field->type == insn_field_string)
428
              {
429
                cache_entry *cache_rule;
430
                cache_entry_type value_type = cache_value;
431
                line_ref *value_line = instruction->line;
432
                /* check the cache table to see if it contains a rule
433
                   overriding the default cache action for an
434
                   instruction field */
435
                for (cache_rule = cache_rules;
436
                     cache_rule != NULL; cache_rule = cache_rule->next)
437
                  {
438
                    if (filter_is_subset (instruction->field_names,
439
                                          cache_rule->original_fields)
440
                        && strcmp (cache_rule->name,
441
                                   cur_field->val_string) == 0)
442
                      {
443
                        value_type = cache_rule->entry_type;
444
                        value_line = cache_rule->line;
445
                        if (value_type == compute_value)
446
                          {
447
                            options.warning (cache_rule->line,
448
                                             "instruction field of type `compute' changed to `cache'\n");
449
                            cache_rule->entry_type = cache_value;
450
                          }
451
                        break;
452
                      }
453
                  }
454
                /* Define an entry for the field within the
455
                   instruction */
456
                print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string,     /* name */
457
                                         NULL,  /* type */
458
                                         NULL,  /* expression */
459
                                         cur_field->val_string, /* insn field */
460
                                         value_line,
461
                                         cur_field,
462
                                         expanded_bits,
463
                                         what_to_declare, what_to_do);
464
              }
465
          }
466
      }
467
  }
468
 
469
  /* pass two - any cache fields not processed above */
470
  {
471
    cache_entry *cache_rule;
472
    for (cache_rule = cache_rules;
473
         cache_rule != NULL; cache_rule = cache_rule->next)
474
      {
475
        if (filter_is_subset (instruction->field_names,
476
                              cache_rule->original_fields)
477
            && !filter_is_member (instruction->field_names, cache_rule->name))
478
          {
479
            char *single_field =
480
              filter_next (cache_rule->original_fields, "");
481
            if (filter_next (cache_rule->original_fields, single_field) !=
482
                NULL)
483
              single_field = NULL;
484
            print_icache_extraction (file, instruction->format_name, cache_rule->entry_type, cache_rule->name, cache_rule->type, cache_rule->expression, single_field, cache_rule->line, NULL,  /* cur_field */
485
                                     expanded_bits,
486
                                     what_to_declare, what_to_do);
487
          }
488
      }
489
  }
490
 
491
  lf_print__internal_ref (file);
492
}
493
 
494
 
495
 
496
typedef struct _form_fields form_fields;
497
struct _form_fields
498
{
499
  char *name;
500
  filter *fields;
501
  form_fields *next;
502
};
503
 
504
static form_fields *
505
insn_table_cache_fields (insn_table *isa)
506
{
507
  form_fields *forms = NULL;
508
  insn_entry *insn;
509
  for (insn = isa->insns; insn != NULL; insn = insn->next)
510
    {
511
      form_fields **form = &forms;
512
      while (1)
513
        {
514
          if (*form == NULL)
515
            {
516
              /* new format name, add it */
517
              form_fields *new_form = ZALLOC (form_fields);
518
              new_form->name = insn->format_name;
519
              filter_add (&new_form->fields, insn->field_names);
520
              *form = new_form;
521
              break;
522
            }
523
          else if (strcmp ((*form)->name, insn->format_name) == 0)
524
            {
525
              /* already present, add field names to the existing list */
526
              filter_add (&(*form)->fields, insn->field_names);
527
              break;
528
            }
529
          form = &(*form)->next;
530
        }
531
    }
532
  return forms;
533
}
534
 
535
 
536
 
537
extern void
538
print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules)
539
{
540
  /* Create a list of all the different instruction formats with their
541
     corresponding field names. */
542
  form_fields *formats = insn_table_cache_fields (isa);
543
 
544
  lf_printf (file, "\n");
545
  lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
546
             options.module.global.prefix.u,
547
             (options.gen.icache ? options.gen.icache_size : 0));
548
  lf_printf (file, "\n");
549
 
550
  /* create an instruction cache if being used */
551
  if (options.gen.icache)
552
    {
553
      lf_printf (file, "typedef struct _%sidecode_cache {\n",
554
                 options.module.global.prefix.l);
555
      lf_indent (file, +2);
556
      {
557
        form_fields *format;
558
        lf_printf (file, "unsigned_word address;\n");
559
        lf_printf (file, "void *semantic;\n");
560
        lf_printf (file, "union {\n");
561
        lf_indent (file, +2);
562
        for (format = formats; format != NULL; format = format->next)
563
          {
564
            lf_printf (file, "struct {\n");
565
            lf_indent (file, +2);
566
            {
567
              cache_entry *cache_rule;
568
              char *field;
569
              /* space for any instruction words */
570
              if (options.gen.insn_in_icache)
571
                lf_printf (file, "instruction_word insn[%d];\n",
572
                           isa->max_nr_words);
573
              /* define an entry for any applicable cache rules */
574
              for (cache_rule = cache_rules;
575
                   cache_rule != NULL; cache_rule = cache_rule->next)
576
                {
577
                  /* nb - sort of correct - should really check against
578
                     individual instructions */
579
                  if (filter_is_subset
580
                      (format->fields, cache_rule->original_fields))
581
                    {
582
                      char *memb;
583
                      lf_printf (file, "%s %s;",
584
                                 (cache_rule->type == NULL
585
                                  ? "unsigned"
586
                                  : cache_rule->type), cache_rule->name);
587
                      lf_printf (file, " /*");
588
                      for (memb =
589
                           filter_next (cache_rule->original_fields, "");
590
                           memb != NULL;
591
                           memb =
592
                           filter_next (cache_rule->original_fields, memb))
593
                        {
594
                          lf_printf (file, " %s", memb);
595
                        }
596
                      lf_printf (file, " */\n");
597
                    }
598
                }
599
              /* define an entry for any fields not covered by a cache rule */
600
              for (field = filter_next (format->fields, "");
601
                   field != NULL; field = filter_next (format->fields, field))
602
                {
603
                  cache_entry *cache_rule;
604
                  int found_rule = 0;
605
                  for (cache_rule = cache_rules;
606
                       cache_rule != NULL; cache_rule = cache_rule->next)
607
                    {
608
                      if (strcmp (cache_rule->name, field) == 0)
609
                        {
610
                          found_rule = 1;
611
                          break;
612
                        }
613
                    }
614
                  if (!found_rule)
615
                    lf_printf (file, "unsigned %s; /* default */\n", field);
616
                }
617
            }
618
            lf_indent (file, -2);
619
            lf_printf (file, "} %s;\n", format->name);
620
          }
621
        lf_indent (file, -2);
622
        lf_printf (file, "} crack;\n");
623
      }
624
      lf_indent (file, -2);
625
      lf_printf (file, "} %sidecode_cache;\n",
626
                 options.module.global.prefix.l);
627
    }
628
  else
629
    {
630
      /* alernativly, since no cache, emit a dummy definition for
631
         idecode_cache so that code refering to the type can still compile */
632
      lf_printf (file, "typedef void %sidecode_cache;\n",
633
                 options.module.global.prefix.l);
634
    }
635
  lf_printf (file, "\n");
636
}
637
 
638
 
639
 
640
static void
641
print_icache_function (lf *file,
642
                       insn_entry * instruction,
643
                       opcode_bits *expanded_bits,
644
                       insn_opcodes *opcodes,
645
                       cache_entry *cache_rules, int nr_prefetched_words)
646
{
647
  int indent;
648
 
649
  /* generate code to enter decoded instruction into the icache */
650
  lf_printf (file, "\n");
651
  lf_print__function_type_function (file, print_icache_function_type,
652
                                    "EXTERN_ICACHE", "\n");
653
  indent = print_function_name (file,
654
                                instruction->name,
655
                                instruction->format_name,
656
                                NULL,
657
                                expanded_bits, function_name_prefix_icache);
658
  indent += lf_printf (file, " ");
659
  lf_indent (file, +indent);
660
  lf_printf (file, "(");
661
  print_icache_function_formal (file, nr_prefetched_words);
662
  lf_printf (file, ")\n");
663
  lf_indent (file, -indent);
664
 
665
  /* function header */
666
  lf_printf (file, "{\n");
667
  lf_indent (file, +2);
668
 
669
  print_my_defines (file,
670
                    instruction->name,
671
                    instruction->format_name, expanded_bits);
672
  print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
673
 
674
  print_idecode_validate (file, instruction, opcodes);
675
 
676
  lf_printf (file, "\n");
677
  lf_printf (file, "{\n");
678
  lf_indent (file, +2);
679
  if (options.gen.semantic_icache)
680
    lf_printf (file, "unsigned_word nia;\n");
681
  print_icache_body (file,
682
                     instruction,
683
                     expanded_bits,
684
                     cache_rules,
685
                     (options.gen.direct_access
686
                      ? define_variables
687
                      : declare_variables),
688
                     (options.gen.semantic_icache
689
                      ? both_values_and_icache
690
                      : put_values_in_icache), nr_prefetched_words);
691
 
692
  lf_printf (file, "\n");
693
  lf_printf (file, "cache_entry->address = cia;\n");
694
  lf_printf (file, "cache_entry->semantic = ");
695
  print_function_name (file,
696
                       instruction->name,
697
                       instruction->format_name,
698
                       NULL, expanded_bits, function_name_prefix_semantics);
699
  lf_printf (file, ";\n");
700
  lf_printf (file, "\n");
701
 
702
  if (options.gen.semantic_icache)
703
    {
704
      lf_printf (file, "/* semantic routine */\n");
705
      print_semantic_body (file, instruction, expanded_bits, opcodes);
706
      lf_printf (file, "return nia;\n");
707
    }
708
 
709
  if (!options.gen.semantic_icache)
710
    {
711
      lf_printf (file, "/* return the function proper */\n");
712
      lf_printf (file, "return ");
713
      print_function_name (file,
714
                           instruction->name,
715
                           instruction->format_name,
716
                           NULL,
717
                           expanded_bits, function_name_prefix_semantics);
718
      lf_printf (file, ";\n");
719
    }
720
 
721
  if (options.gen.direct_access)
722
    {
723
      print_icache_body (file,
724
                         instruction,
725
                         expanded_bits,
726
                         cache_rules,
727
                         undef_variables,
728
                         (options.gen.semantic_icache
729
                          ? both_values_and_icache
730
                          : put_values_in_icache), nr_prefetched_words);
731
    }
732
 
733
  lf_indent (file, -2);
734
  lf_printf (file, "}\n");
735
  lf_indent (file, -2);
736
  lf_printf (file, "}\n");
737
}
738
 
739
 
740
void
741
print_icache_definition (lf *file,
742
                         insn_entry * insn,
743
                         opcode_bits *expanded_bits,
744
                         insn_opcodes *opcodes,
745
                         cache_entry *cache_rules, int nr_prefetched_words)
746
{
747
  print_icache_function (file,
748
                         insn,
749
                         expanded_bits,
750
                         opcodes, cache_rules, nr_prefetched_words);
751
}
752
 
753
 
754
 
755
void
756
print_icache_internal_function_declaration (lf *file,
757
                                            function_entry * function,
758
                                            void *data)
759
{
760
  ASSERT (options.gen.icache);
761
  if (function->is_internal)
762
    {
763
      lf_printf (file, "\n");
764
      lf_print__function_type_function (file, print_icache_function_type,
765
                                        "INLINE_ICACHE", "\n");
766
      print_function_name (file,
767
                           function->name,
768
                           NULL, NULL, NULL, function_name_prefix_icache);
769
      lf_printf (file, "\n(");
770
      print_icache_function_formal (file, 0);
771
      lf_printf (file, ");\n");
772
    }
773
}
774
 
775
 
776
void
777
print_icache_internal_function_definition (lf *file,
778
                                           function_entry * function,
779
                                           void *data)
780
{
781
  ASSERT (options.gen.icache);
782
  if (function->is_internal)
783
    {
784
      lf_printf (file, "\n");
785
      lf_print__function_type_function (file, print_icache_function_type,
786
                                        "INLINE_ICACHE", "\n");
787
      print_function_name (file,
788
                           function->name,
789
                           NULL, NULL, NULL, function_name_prefix_icache);
790
      lf_printf (file, "\n(");
791
      print_icache_function_formal (file, 0);
792
      lf_printf (file, ")\n");
793
      lf_printf (file, "{\n");
794
      lf_indent (file, +2);
795
      lf_printf (file, "/* semantic routine */\n");
796
      if (options.gen.semantic_icache)
797
        {
798
          lf_print__line_ref (file, function->code->line);
799
          table_print_code (file, function->code);
800
          lf_printf (file,
801
                     "error (\"Internal function must longjump\\n\");\n");
802
          lf_printf (file, "return 0;\n");
803
        }
804
      else
805
        {
806
          lf_printf (file, "return ");
807
          print_function_name (file,
808
                               function->name,
809
                               NULL,
810
                               NULL, NULL, function_name_prefix_semantics);
811
          lf_printf (file, ";\n");
812
        }
813
 
814
      lf_print__internal_ref (file);
815
      lf_indent (file, -2);
816
      lf_printf (file, "}\n");
817
    }
818
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.