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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [sim/] [igen/] [gen-icache.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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