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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [igen/] [gen-icache.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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