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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [sim/] [common/] [genmloop.sh] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
# Generate the main loop of the simulator.
2
# Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3
# Contributed by Cygnus Support.
4
#
5
# This file is part of the GNU simulators.
6
#
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2, or (at your option)
10
# any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License along
18
# with this program; if not, write to the Free Software Foundation, Inc.,
19
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
#
21
# This file creates two files: eng.hin and mloop.cin.
22
# eng.hin defines a few macros that specify what kind of engine was selected
23
# based on the arguments to this script.
24
# mloop.cin contains the engine.
25
#
26
# ??? Rename mloop.c to eng.c?
27
# ??? Rename mainloop.in to engine.in?
28
# ??? Add options to specify output file names?
29
# ??? Rename this file to genengine.sh?
30
#
31
# Syntax: genmloop.sh [options]
32
#
33
# Options:
34
#
35
# -mono | -multi
36
#    - specify single cpu or multiple cpus (number specifyable at runtime),
37
#      maximum number is a configuration parameter
38
#    - -multi wip
39
#
40
# -fast: include support for fast execution in addition to full featured mode
41
#
42
#       Full featured mode is for tracing, profiling, etc. and is always
43
#       provided.  Fast mode contains no frills, except speed.
44
#       A target need only provide a "full" version of one of
45
#       simple,scache,pbb.  If the target wants it can also provide a fast
46
#       version of same.  It can't provide more than this.
47
#       ??? Later add ability to have another set of full/fast semantics
48
#       for use in with-devices/with-smp situations (pbb can be inappropriate
49
#       here).
50
#
51
# -full-switch: same as -fast but for full featured version of -switch
52
#       Only needed if -fast present.
53
#
54
# -simple: simple execution engine (the default)
55
#
56
#       This engine fetches and executes one instruction at a time.
57
#       Field extraction is done in the semantic routines.
58
#
59
#       ??? There are two possible flavours of -simple.  One that extracts
60
#       fields in the semantic routine (which is what is implemented here),
61
#       and one that stores the extracted fields in ARGBUF before calling the
62
#       semantic routine.  The latter is essentially the -scache case with a
63
#       cache size of one (and the scache lookup code removed).  There are no
64
#       current uses of this and it's not clear when doing this would be a win.
65
#       More complicated ISA's that want to use -simple may find this a win.
66
#       Should this ever be desirable, implement a new engine style here and
67
#       call it -extract (or some such).  It's believed that the CGEN-generated
68
#       code for the -scache case would be usable here, so no new code
69
#       generation option would be needed for CGEN.
70
#
71
# -scache: use the scache to speed things up (not always a win)
72
#
73
#       This engine caches the extracted instruction before executing it.
74
#       When executing instructions they are first looked up in the scache.
75
#
76
# -pbb: same as -scache but extract a (pseudo-) basic block at a time
77
#
78
#       This engine is basically identical to the scache version except that
79
#       extraction is done a pseudo-basic-block at a time and the address of
80
#       the scache entry of a branch target is recorded as well.
81
#       Additional speedups are then possible by defering Ctrl-C checking
82
#       to the end of basic blocks and by threading the insns together.
83
#       We call them pseudo-basic-block's instead of just basic-blocks because
84
#       they're not necessarily basic-blocks, though normally are.
85
#
86
# -parallel-read: support parallel execution with read-before-exec support.
87
# -parallel-write: support parallel execution with write-after-exec support.
88
# -parallel-generic-write: support parallel execution with generic queued
89
#       writes.
90
#
91
#       One of these options is specified in addition to -simple, -scache,
92
#       -pbb.  Note that while the code can determine if the cpu supports
93
#       parallel execution with HAVE_PARALLEL_INSNS [and thus this option is
94
#       technically unnecessary], having this option cuts down on the clutter
95
#       in the result.
96
#
97
# -parallel-only: semantic code only supports parallel version of insn
98
#
99
#       Semantic code only supports parallel versions of each insn.
100
#       Things can be sped up by generating both serial and parallel versions
101
#       and is better suited to mixed parallel architectures like the m32r.
102
#
103
# -switch file: specify file containing semantics implemented as a switch()
104
#
105
# -cpu <cpu-family>
106
#
107
#       Specify the cpu family name.
108
#
109
# -infile <input-file>
110
#
111
#       Specify the mainloop.in input file.
112
#
113
# Only one of -scache/-pbb may be selected.
114
# -simple is the default.
115
#
116
####
117
#
118
# TODO
119
# - build mainloop.in from .cpu file
120
 
121
type=mono
122
#scache=
123
#fast=
124
#full_switch=
125
#pbb=
126
parallel=no
127
parallel_only=no
128
switch=
129
cpu="unknown"
130
infile=""
131
 
132
while test $# -gt 0
133
do
134
        case $1 in
135
        -mono) type=mono ;;
136
        -multi) type=multi ;;
137
        -no-fast) ;;
138
        -fast) fast=yes ;;
139
        -full-switch) full_switch=yes ;;
140
        -simple) ;;
141
        -scache) scache=yes ;;
142
        -pbb) pbb=yes ;;
143
        -no-parallel) ;;
144
        -parallel-read) parallel=read ;;
145
        -parallel-write) parallel=write ;;
146
        -parallel-generic-write) parallel=genwrite ;;
147
        -parallel-only) parallel_only=yes ;;
148
        -switch) shift ; switch=$1 ;;
149
        -cpu) shift ; cpu=$1 ;;
150
        -infile) shift ; infile=$1 ;;
151
        *) echo "unknown option: $1" >&2 ; exit 1 ;;
152
        esac
153
        shift
154
done
155
 
156
# Argument validation.
157
 
158
if [ x$scache = xyes -a x$pbb = xyes ] ; then
159
    echo "only one of -scache and -pbb may be selected" >&2
160
    exit 1
161
fi
162
 
163
if [ "x$cpu" = xunknown ] ; then
164
    echo "cpu family not specified" >&2
165
    exit 1
166
fi
167
 
168
if [ "x$infile" = x ] ; then
169
    echo "mainloop.in not specified" >&2
170
    exit 1
171
fi
172
 
173
lowercase='abcdefghijklmnopqrstuvwxyz'
174
uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
175
CPU=`echo ${cpu} | tr "${lowercase}" "${uppercase}"`
176
 
177
##########################################################################
178
 
179
rm -f eng.hin
180
exec 1>eng.hin
181
 
182
echo "/* engine configuration for ${cpu} */"
183
echo ""
184
 
185
echo "/* WITH_FAST: non-zero if a fast version of the engine is available"
186
echo "   in addition to the full-featured version.  */"
187
if [ x$fast = xyes ] ; then
188
        echo "#define WITH_FAST 1"
189
else
190
        echo "#define WITH_FAST 0"
191
fi
192
 
193
echo ""
194
echo "/* WITH_SCACHE_PBB_${CPU}: non-zero if the pbb engine was selected.  */"
195
if [ x$pbb = xyes ] ; then
196
        echo "#define WITH_SCACHE_PBB_${CPU} 1"
197
else
198
        echo "#define WITH_SCACHE_PBB_${CPU} 0"
199
fi
200
 
201
echo ""
202
echo "/* HAVE_PARALLEL_INSNS: non-zero if cpu can parallelly execute > 1 insn.  */"
203
# blah blah blah, other ways to do this, blah blah blah
204
case x$parallel in
205
xno)
206
    echo "#define HAVE_PARALLEL_INSNS 0"
207
    echo "#define WITH_PARALLEL_READ 0"
208
    echo "#define WITH_PARALLEL_WRITE 0"
209
    echo "#define WITH_PARALLEL_GENWRITE 0"
210
    ;;
211
xread)
212
    echo "#define HAVE_PARALLEL_INSNS 1"
213
    echo "/* Parallel execution is supported by read-before-exec.  */"
214
    echo "#define WITH_PARALLEL_READ 1"
215
    echo "#define WITH_PARALLEL_WRITE 0"
216
    echo "#define WITH_PARALLEL_GENWRITE 0"
217
    ;;
218
xwrite)
219
    echo "#define HAVE_PARALLEL_INSNS 1"
220
    echo "/* Parallel execution is supported by write-after-exec.  */"
221
    echo "#define WITH_PARALLEL_READ 0"
222
    echo "#define WITH_PARALLEL_WRITE 1"
223
    echo "#define WITH_PARALLEL_GENWRITE 0"
224
    ;;
225
xgenwrite)
226
    echo "#define HAVE_PARALLEL_INSNS 1"
227
    echo "/* Parallel execution is supported by generic write-after-exec.  */"
228
    echo "#define WITH_PARALLEL_READ 0"
229
    echo "#define WITH_PARALLEL_WRITE 0"
230
    echo "#define WITH_PARALLEL_GENWRITE 1"
231
    ;;
232
esac
233
 
234
if [ "x$switch" != x ] ; then
235
        echo ""
236
        echo "/* WITH_SEM_SWITCH_FULL: non-zero if full-featured engine is"
237
        echo "   implemented as a switch().  */"
238
        if [ x$fast != xyes -o x$full_switch = xyes ] ; then
239
                echo "#define WITH_SEM_SWITCH_FULL 1"
240
        else
241
                echo "#define WITH_SEM_SWITCH_FULL 0"
242
        fi
243
        echo ""
244
        echo "/* WITH_SEM_SWITCH_FAST: non-zero if fast engine is"
245
        echo "   implemented as a switch().  */"
246
        if [ x$fast = xyes ] ; then
247
                echo "#define WITH_SEM_SWITCH_FAST 1"
248
        else
249
                echo "#define WITH_SEM_SWITCH_FAST 0"
250
        fi
251
fi
252
 
253
# Decls of functions we define.
254
 
255
echo ""
256
echo "/* Functions defined in the generated mainloop.c file"
257
echo "   (which doesn't necessarily have that file name).  */"
258
echo ""
259
echo "extern ENGINE_FN ${cpu}_engine_run_full;"
260
echo "extern ENGINE_FN ${cpu}_engine_run_fast;"
261
 
262
if [ x$pbb = xyes ] ; then
263
        echo ""
264
        echo "extern SEM_PC ${cpu}_pbb_begin (SIM_CPU *, int);"
265
        echo "extern SEM_PC ${cpu}_pbb_chain (SIM_CPU *, SEM_ARG);"
266
        echo "extern SEM_PC ${cpu}_pbb_cti_chain (SIM_CPU *, SEM_ARG, SEM_BRANCH_TYPE, PCADDR);"
267
        echo "extern void ${cpu}_pbb_before (SIM_CPU *, SCACHE *);"
268
        echo "extern void ${cpu}_pbb_after (SIM_CPU *, SCACHE *);"
269
fi
270
 
271
##########################################################################
272
 
273
rm -f tmp-mloop.cin mloop.cin
274
exec 1>tmp-mloop.cin
275
 
276
# We use @cpu@ instead of ${cpu} because we still need to run sed to handle
277
# transformation of @cpu@ for mainloop.in, so there's no need to use ${cpu}
278
# here.
279
 
280
cat << EOF
281
/* This file is generated by the genmloop script.  DO NOT EDIT! */
282
 
283
/* Enable switch() support in cgen headers.  */
284
#define SEM_IN_SWITCH
285
 
286
#define WANT_CPU @cpu@
287
#define WANT_CPU_@CPU@
288
 
289
#include "sim-main.h"
290
#include "bfd.h"
291
#include "cgen-mem.h"
292
#include "cgen-ops.h"
293
#include "sim-assert.h"
294
 
295
/* Fill in the administrative ARGBUF fields required by all insns,
296
   virtual and real.  */
297
 
298
static INLINE void
299
@cpu@_fill_argbuf (const SIM_CPU *cpu, ARGBUF *abuf, const IDESC *idesc,
300
                    PCADDR pc, int fast_p)
301
{
302
#if WITH_SCACHE
303
  SEM_SET_CODE (abuf, idesc, fast_p);
304
  ARGBUF_ADDR (abuf) = pc;
305
#endif
306
  ARGBUF_IDESC (abuf) = idesc;
307
}
308
 
309
/* Fill in tracing/profiling fields of an ARGBUF.  */
310
 
311
static INLINE void
312
@cpu@_fill_argbuf_tp (const SIM_CPU *cpu, ARGBUF *abuf,
313
                       int trace_p, int profile_p)
314
{
315
  ARGBUF_TRACE_P (abuf) = trace_p;
316
  ARGBUF_PROFILE_P (abuf) = profile_p;
317
}
318
 
319
#if WITH_SCACHE_PBB
320
 
321
/* Emit the "x-before" handler.
322
   x-before is emitted before each insn (serial or parallel).
323
   This is as opposed to x-after which is only emitted at the end of a group
324
   of parallel insns.  */
325
 
326
static INLINE void
327
@cpu@_emit_before (SIM_CPU *current_cpu, SCACHE *sc, PCADDR pc, int first_p)
328
{
329
  ARGBUF *abuf = &sc[0].argbuf;
330
  const IDESC *id = & CPU_IDESC (current_cpu) [@CPU@_INSN_X_BEFORE];
331
 
332
  abuf->fields.before.first_p = first_p;
333
  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, 0);
334
  /* no need to set trace_p,profile_p */
335
}
336
 
337
/* Emit the "x-after" handler.
338
   x-after is emitted after a serial insn or at the end of a group of
339
   parallel insns.  */
340
 
341
static INLINE void
342
@cpu@_emit_after (SIM_CPU *current_cpu, SCACHE *sc, PCADDR pc)
343
{
344
  ARGBUF *abuf = &sc[0].argbuf;
345
  const IDESC *id = & CPU_IDESC (current_cpu) [@CPU@_INSN_X_AFTER];
346
 
347
  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, 0);
348
  /* no need to set trace_p,profile_p */
349
}
350
 
351
#endif /* WITH_SCACHE_PBB */
352
 
353
EOF
354
 
355
${SHELL} $infile support
356
 
357
##########################################################################
358
 
359
# Simple engine: fetch an instruction, execute the instruction.
360
#
361
# Instruction fields are not extracted into ARGBUF, they are extracted in
362
# the semantic routines themselves.  However, there is still a need to pass
363
# and return misc. information to the semantic routines so we still use ARGBUF.
364
# [One could certainly implement things differently and remove ARGBUF.
365
# It's not clear this is necessarily always a win.]
366
# ??? The use of the SCACHE struct is for consistency with the with-scache
367
# case though it might be a source of confusion.
368
 
369
if [ x$scache != xyes -a x$pbb != xyes ] ; then
370
 
371
    cat << EOF
372
 
373
#define FAST_P 0
374
 
375
void
376
@cpu@_engine_run_full (SIM_CPU *current_cpu)
377
{
378
#define FAST_P 0
379
  SIM_DESC current_state = CPU_STATE (current_cpu);
380
  /* ??? Use of SCACHE is a bit of a hack as we don't actually use the scache.
381
     We do however use ARGBUF so for consistency with the other engine flavours
382
     the SCACHE type is used.  */
383
  SCACHE cache[MAX_LIW_INSNS];
384
  SCACHE *sc = &cache[0];
385
 
386
EOF
387
 
388
case x$parallel in
389
xread | xwrite)
390
    cat << EOF
391
  PAREXEC pbufs[MAX_PARALLEL_INSNS];
392
  PAREXEC *par_exec;
393
 
394
EOF
395
    ;;
396
esac
397
 
398
# Any initialization code before looping starts.
399
# Note that this code may declare some locals.
400
${SHELL} $infile init
401
 
402
if [ x$parallel = xread ] ; then
403
  cat << EOF
404
 
405
#if defined (__GNUC__)
406
  {
407
    if (! CPU_IDESC_READ_INIT_P (current_cpu))
408
      {
409
/* ??? Later maybe paste read.c in when building mainloop.c.  */
410
#define DEFINE_LABELS
411
#include "readx.c"
412
        CPU_IDESC_READ_INIT_P (current_cpu) = 1;
413
      }
414
  }
415
#endif
416
 
417
EOF
418
fi
419
 
420
cat << EOF
421
 
422
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
423
    {
424
#if WITH_SEM_SWITCH_FULL
425
#if defined (__GNUC__)
426
/* ??? Later maybe paste sem-switch.c in when building mainloop.c.  */
427
#define DEFINE_LABELS
428
#include "$switch"
429
#endif
430
#else
431
      @cpu@_sem_init_idesc_table (current_cpu);
432
#endif
433
      CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
434
    }
435
 
436
  do
437
    {
438
/* begin full-exec-simple */
439
EOF
440
 
441
${SHELL} $infile full-exec-simple
442
 
443
cat << EOF
444
/* end full-exec-simple */
445
 
446
      ++ CPU_INSN_COUNT (current_cpu);
447
    }
448
  while (0 /*CPU_RUNNING_P (current_cpu)*/);
449
}
450
 
451
#undef FAST_P
452
 
453
EOF
454
 
455
####################################
456
 
457
# Simple engine: fast version.
458
# ??? A somewhat dubious effort, but for completeness' sake.
459
 
460
if [ x$fast = xyes ] ; then
461
 
462
    cat << EOF
463
 
464
#define FAST_P 1
465
 
466
FIXME: "fast simple version unimplemented, delete -fast arg to genmloop.sh."
467
 
468
#undef FAST_P
469
 
470
EOF
471
 
472
fi # -fast
473
 
474
fi # simple engine
475
 
476
##########################################################################
477
 
478
# Non-parallel scache engine: lookup insn in scache, fetch if missing,
479
# then execute it.
480
 
481
if [ x$scache = xyes -a x$parallel = xno ] ; then
482
 
483
    cat << EOF
484
 
485
static INLINE SCACHE *
486
@cpu@_scache_lookup (SIM_CPU *current_cpu, PCADDR vpc, SCACHE *scache,
487
                     unsigned int hash_mask, int FAST_P)
488
{
489
  /* First step: look up current insn in hash table.  */
490
  SCACHE *sc = scache + SCACHE_HASH_PC (vpc, hash_mask);
491
 
492
  /* If the entry isn't the one we want (cache miss),
493
     fetch and decode the instruction.  */
494
  if (sc->argbuf.addr != vpc)
495
    {
496
      if (! FAST_P)
497
        PROFILE_COUNT_SCACHE_MISS (current_cpu);
498
 
499
/* begin extract-scache */
500
EOF
501
 
502
${SHELL} $infile extract-scache
503
 
504
cat << EOF
505
/* end extract-scache */
506
    }
507
  else if (! FAST_P)
508
    {
509
      PROFILE_COUNT_SCACHE_HIT (current_cpu);
510
      /* Make core access statistics come out right.
511
         The size is a guess, but it's currently not used either.  */
512
      PROFILE_COUNT_CORE (current_cpu, vpc, 2, exec_map);
513
    }
514
 
515
  return sc;
516
}
517
 
518
#define FAST_P 0
519
 
520
void
521
@cpu@_engine_run_full (SIM_CPU *current_cpu)
522
{
523
  SIM_DESC current_state = CPU_STATE (current_cpu);
524
  SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
525
  unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
526
  SEM_PC vpc;
527
 
528
EOF
529
 
530
# Any initialization code before looping starts.
531
# Note that this code may declare some locals.
532
${SHELL} $infile init
533
 
534
cat << EOF
535
 
536
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
537
    {
538
#if ! WITH_SEM_SWITCH_FULL
539
      @cpu@_sem_init_idesc_table (current_cpu);
540
#endif
541
      CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
542
    }
543
 
544
  vpc = GET_H_PC ();
545
 
546
  do
547
    {
548
      SCACHE *sc;
549
 
550
      sc = @cpu@_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
551
 
552
/* begin full-exec-scache */
553
EOF
554
 
555
${SHELL} $infile full-exec-scache
556
 
557
cat << EOF
558
/* end full-exec-scache */
559
 
560
      SET_H_PC (vpc);
561
 
562
      ++ CPU_INSN_COUNT (current_cpu);
563
    }
564
  while (0 /*CPU_RUNNING_P (current_cpu)*/);
565
}
566
 
567
#undef FAST_P
568
 
569
EOF
570
 
571
####################################
572
 
573
# Non-parallel scache engine: fast version.
574
 
575
if [ x$fast = xyes ] ; then
576
 
577
    cat << EOF
578
 
579
#define FAST_P 1
580
 
581
void
582
@cpu@_engine_run_fast (SIM_CPU *current_cpu)
583
{
584
  SIM_DESC current_state = CPU_STATE (current_cpu);
585
  SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
586
  unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
587
  SEM_PC vpc;
588
 
589
EOF
590
 
591
# Any initialization code before looping starts.
592
# Note that this code may declare some locals.
593
${SHELL} $infile init
594
 
595
cat << EOF
596
 
597
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
598
    {
599
#if WITH_SEM_SWITCH_FAST
600
#if defined (__GNUC__)
601
/* ??? Later maybe paste sem-switch.c in when building mainloop.c.  */
602
#define DEFINE_LABELS
603
#include "$switch"
604
#endif
605
#else
606
      @cpu@_semf_init_idesc_table (current_cpu);
607
#endif
608
      CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
609
    }
610
 
611
  vpc = GET_H_PC ();
612
 
613
  do
614
    {
615
      SCACHE *sc;
616
 
617
      sc = @cpu@_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
618
 
619
/* begin fast-exec-scache */
620
EOF
621
 
622
${SHELL} $infile fast-exec-scache
623
 
624
cat << EOF
625
/* end fast-exec-scache */
626
 
627
      SET_H_PC (vpc);
628
 
629
      ++ CPU_INSN_COUNT (current_cpu);
630
    }
631
  while (0 /*CPU_RUNNING_P (current_cpu)*/);
632
}
633
 
634
#undef FAST_P
635
 
636
EOF
637
 
638
fi # -fast
639
 
640
fi # -scache && ! parallel
641
 
642
##########################################################################
643
 
644
# Parallel scache engine: lookup insn in scache, fetch if missing,
645
# then execute it.
646
# For the parallel case we give the target more flexibility.
647
 
648
if [ x$scache = xyes -a x$parallel != xno ] ; then
649
 
650
    cat << EOF
651
 
652
static INLINE SCACHE *
653
@cpu@_scache_lookup (SIM_CPU *current_cpu, PCADDR vpc, SCACHE *scache,
654
                     unsigned int hash_mask, int FAST_P)
655
{
656
  /* First step: look up current insn in hash table.  */
657
  SCACHE *sc = scache + SCACHE_HASH_PC (vpc, hash_mask);
658
 
659
  /* If the entry isn't the one we want (cache miss),
660
     fetch and decode the instruction.  */
661
  if (sc->argbuf.addr != vpc)
662
    {
663
      if (! FAST_P)
664
        PROFILE_COUNT_SCACHE_MISS (current_cpu);
665
 
666
#define SET_LAST_INSN_P(last_p) do { sc->last_insn_p = (last_p); } while (0)
667
/* begin extract-scache */
668
EOF
669
 
670
${SHELL} $infile extract-scache
671
 
672
cat << EOF
673
/* end extract-scache */
674
#undef SET_LAST_INSN_P
675
    }
676
  else if (! FAST_P)
677
    {
678
      PROFILE_COUNT_SCACHE_HIT (current_cpu);
679
      /* Make core access statistics come out right.
680
         The size is a guess, but it's currently not used either.  */
681
      PROFILE_COUNT_CORE (current_cpu, vpc, 2, exec_map);
682
    }
683
 
684
  return sc;
685
}
686
 
687
#define FAST_P 0
688
 
689
void
690
@cpu@_engine_run_full (SIM_CPU *current_cpu)
691
{
692
  SIM_DESC current_state = CPU_STATE (current_cpu);
693
  SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
694
  unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
695
  SEM_PC vpc;
696
 
697
EOF
698
 
699
# Any initialization code before looping starts.
700
# Note that this code may declare some locals.
701
${SHELL} $infile init
702
 
703
if [ x$parallel = xread ] ; then
704
cat << EOF
705
#if defined (__GNUC__)
706
  {
707
    if (! CPU_IDESC_READ_INIT_P (current_cpu))
708
      {
709
/* ??? Later maybe paste read.c in when building mainloop.c.  */
710
#define DEFINE_LABELS
711
#include "readx.c"
712
        CPU_IDESC_READ_INIT_P (current_cpu) = 1;
713
      }
714
  }
715
#endif
716
 
717
EOF
718
fi
719
 
720
cat << EOF
721
 
722
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
723
    {
724
#if ! WITH_SEM_SWITCH_FULL
725
      @cpu@_sem_init_idesc_table (current_cpu);
726
#endif
727
      CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
728
    }
729
 
730
  vpc = GET_H_PC ();
731
 
732
  do
733
    {
734
/* begin full-exec-scache */
735
EOF
736
 
737
${SHELL} $infile full-exec-scache
738
 
739
cat << EOF
740
/* end full-exec-scache */
741
    }
742
  while (0 /*CPU_RUNNING_P (current_cpu)*/);
743
}
744
 
745
#undef FAST_P
746
 
747
EOF
748
 
749
####################################
750
 
751
# Parallel scache engine: fast version.
752
 
753
if [ x$fast = xyes ] ; then
754
 
755
    cat << EOF
756
 
757
#define FAST_P 1
758
 
759
void
760
@cpu@_engine_run_fast (SIM_CPU *current_cpu)
761
{
762
  SIM_DESC current_state = CPU_STATE (current_cpu);
763
  SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
764
  unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
765
  SEM_PC vpc;
766
  PAREXEC pbufs[MAX_PARALLEL_INSNS];
767
  PAREXEC *par_exec;
768
 
769
EOF
770
 
771
# Any initialization code before looping starts.
772
# Note that this code may declare some locals.
773
${SHELL} $infile init
774
 
775
if [ x$parallel = xread ] ; then
776
cat << EOF
777
 
778
#if defined (__GNUC__)
779
  {
780
    if (! CPU_IDESC_READ_INIT_P (current_cpu))
781
      {
782
/* ??? Later maybe paste read.c in when building mainloop.c.  */
783
#define DEFINE_LABELS
784
#include "readx.c"
785
        CPU_IDESC_READ_INIT_P (current_cpu) = 1;
786
      }
787
  }
788
#endif
789
 
790
EOF
791
fi
792
 
793
cat << EOF
794
 
795
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
796
    {
797
#if WITH_SEM_SWITCH_FAST
798
#if defined (__GNUC__)
799
/* ??? Later maybe paste sem-switch.c in when building mainloop.c.  */
800
#define DEFINE_LABELS
801
#include "$switch"
802
#endif
803
#else
804
      @cpu@_semf_init_idesc_table (current_cpu);
805
#endif
806
      CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
807
    }
808
 
809
  vpc = GET_H_PC ();
810
 
811
  do
812
    {
813
/* begin fast-exec-scache */
814
EOF
815
 
816
${SHELL} $infile fast-exec-scache
817
 
818
cat << EOF
819
/* end fast-exec-scache */
820
    }
821
  while (0 /*CPU_RUNNING_P (current_cpu)*/);
822
}
823
 
824
#undef FAST_P
825
 
826
EOF
827
 
828
fi # -fast
829
 
830
fi # -scache && parallel
831
 
832
##########################################################################
833
 
834
# Compilation engine: lookup insn in scache, extract a pbb
835
# (pseudo-basic-block) if missing, then execute the pbb.
836
# A "pbb" is a sequence of insns up to the next cti insn or until
837
# some prespecified maximum.
838
# CTI: control transfer instruction.
839
 
840
if [ x$pbb = xyes ] ; then
841
 
842
    cat << EOF
843
 
844
/* Record address of cti terminating a pbb.  */
845
#define SET_CTI_VPC(sc) do { _cti_sc = (sc); } while (0)
846
/* Record number of [real] insns in pbb.  */
847
#define SET_INSN_COUNT(n) do { _insn_count = (n); } while (0)
848
 
849
/* Fetch and extract a pseudo-basic-block.
850
   FAST_P is non-zero if no tracing/profiling/etc. is wanted.  */
851
 
852
INLINE SEM_PC
853
@cpu@_pbb_begin (SIM_CPU *current_cpu, int FAST_P)
854
{
855
  SEM_PC new_vpc;
856
  PCADDR pc;
857
  SCACHE *sc;
858
  int max_insns = CPU_SCACHE_MAX_CHAIN_LENGTH (current_cpu);
859
 
860
  pc = GET_H_PC ();
861
 
862
  new_vpc = scache_lookup_or_alloc (current_cpu, pc, max_insns, &sc);
863
  if (! new_vpc)
864
    {
865
      /* Leading '_' to avoid collision with mainloop.in.  */
866
      int _insn_count = 0;
867
      SCACHE *orig_sc = sc;
868
      SCACHE *_cti_sc = NULL;
869
      int slice_insns = CPU_MAX_SLICE_INSNS (current_cpu);
870
 
871
      /* First figure out how many instructions to compile.
872
         MAX_INSNS is the size of the allocated buffer, which includes space
873
         for before/after handlers if they're being used.
874
         SLICE_INSNS is the maxinum number of real insns that can be
875
         executed.  Zero means "as many as we want".  */
876
      /* ??? max_insns is serving two incompatible roles.
877
         1) Number of slots available in scache buffer.
878
         2) Number of real insns to execute.
879
         They're incompatible because there are virtual insns emitted too
880
         (chain,cti-chain,before,after handlers).  */
881
 
882
      if (slice_insns == 1)
883
        {
884
          /* No need to worry about extra slots required for virtual insns
885
             and parallel exec support because MAX_CHAIN_LENGTH is
886
             guaranteed to be big enough to execute at least 1 insn!  */
887
          max_insns = 1;
888
        }
889
      else
890
        {
891
          /* Allow enough slop so that while compiling insns, if max_insns > 0
892
             then there's guaranteed to be enough space to emit one real insn.
893
             MAX_CHAIN_LENGTH is typically much longer than
894
             the normal number of insns between cti's anyway.  */
895
          max_insns -= (1 /* one for the trailing chain insn */
896
                        + (FAST_P
897
                           ? 0
898
                           : (1 + MAX_PARALLEL_INSNS) /* before+after */)
899
                        + (MAX_PARALLEL_INSNS > 1
900
                           ? (MAX_PARALLEL_INSNS * 2)
901
                           : 0));
902
 
903
          /* Account for before/after handlers.  */
904
          if (! FAST_P)
905
            slice_insns *= 3;
906
 
907
          if (slice_insns > 0
908
              && slice_insns < max_insns)
909
            max_insns = slice_insns;
910
        }
911
 
912
      new_vpc = sc;
913
 
914
      /* SC,PC must be updated to point passed the last entry used.
915
         SET_CTI_VPC must be called if pbb is terminated by a cti.
916
         SET_INSN_COUNT must be called to record number of real insns in
917
         pbb [could be computed by us of course, extra cpu but perhaps
918
         negligible enough].  */
919
 
920
/* begin extract-pbb */
921
EOF
922
 
923
${SHELL} $infile extract-pbb
924
 
925
cat << EOF
926
/* end extract-pbb */
927
 
928
      /* The last one is a pseudo-insn to link to the next chain.
929
         It is also used to record the insn count for this chain.  */
930
      {
931
        const IDESC *id;
932
 
933
        /* Was pbb terminated by a cti?  */
934
        if (_cti_sc)
935
          {
936
            id = & CPU_IDESC (current_cpu) [@CPU@_INSN_X_CTI_CHAIN];
937
          }
938
        else
939
          {
940
            id = & CPU_IDESC (current_cpu) [@CPU@_INSN_X_CHAIN];
941
          }
942
        SEM_SET_CODE (&sc->argbuf, id, FAST_P);
943
        sc->argbuf.idesc = id;
944
        sc->argbuf.addr = pc;
945
        sc->argbuf.fields.chain.insn_count = _insn_count;
946
        sc->argbuf.fields.chain.next = 0;
947
        sc->argbuf.fields.chain.branch_target = 0;
948
        ++sc;
949
      }
950
 
951
      /* Update the pointer to the next free entry, may not have used as
952
         many entries as was asked for.  */
953
      CPU_SCACHE_NEXT_FREE (current_cpu) = sc;
954
      /* Record length of chain if profiling.
955
         This includes virtual insns since they count against
956
         max_insns too.  */
957
      if (! FAST_P)
958
        PROFILE_COUNT_SCACHE_CHAIN_LENGTH (current_cpu, sc - orig_sc);
959
    }
960
 
961
  return new_vpc;
962
}
963
 
964
/* Chain to the next block from a non-cti terminated previous block.  */
965
 
966
INLINE SEM_PC
967
@cpu@_pbb_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg)
968
{
969
  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
970
 
971
  PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
972
 
973
  SET_H_PC (abuf->addr);
974
 
975
  /* If not running forever, exit back to main loop.  */
976
  if (CPU_MAX_SLICE_INSNS (current_cpu) != 0
977
      /* Also exit back to main loop if there's an event.
978
         Note that if CPU_MAX_SLICE_INSNS != 1, events won't get processed
979
         at the "right" time, but then that was what was asked for.
980
         There is no silver bullet for simulator engines.
981
         ??? Clearly this needs a cleaner interface.
982
         At present it's just so Ctrl-C works.  */
983
      || STATE_EVENTS (CPU_STATE (current_cpu))->work_pending)
984
    CPU_RUNNING_P (current_cpu) = 0;
985
 
986
  /* If chained to next block, go straight to it.  */
987
  if (abuf->fields.chain.next)
988
    return abuf->fields.chain.next;
989
  /* See if next block has already been compiled.  */
990
  abuf->fields.chain.next = scache_lookup (current_cpu, abuf->addr);
991
  if (abuf->fields.chain.next)
992
    return abuf->fields.chain.next;
993
  /* Nope, so next insn is a virtual insn to invoke the compiler
994
     (begin a pbb).  */
995
  return CPU_SCACHE_PBB_BEGIN (current_cpu);
996
}
997
 
998
/* Chain to the next block from a cti terminated previous block.
999
   BR_TYPE indicates whether the branch was taken and whether we can cache
1000
   the vpc of the branch target.
1001
   NEW_PC is the target's branch address, and is only valid if
1002
   BR_TYPE != SEM_BRANCH_UNTAKEN.  */
1003
 
1004
INLINE SEM_PC
1005
@cpu@_pbb_cti_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg,
1006
                     SEM_BRANCH_TYPE br_type, PCADDR new_pc)
1007
{
1008
  SEM_PC *new_vpc_ptr;
1009
 
1010
  PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
1011
 
1012
  /* If not running forever, exit back to main loop.  */
1013
  if (CPU_MAX_SLICE_INSNS (current_cpu) != 0
1014
      /* Also exit back to main loop if there's an event.
1015
         Note that if CPU_MAX_SLICE_INSNS != 1, events won't get processed
1016
         at the "right" time, but then that was what was asked for.
1017
         There is no silver bullet for simulator engines.
1018
         ??? Clearly this needs a cleaner interface.
1019
         At present it's just so Ctrl-C works.  */
1020
      || STATE_EVENTS (CPU_STATE (current_cpu))->work_pending)
1021
    CPU_RUNNING_P (current_cpu) = 0;
1022
 
1023
  /* Restart compiler if we branched to an uncacheable address
1024
     (e.g. "j reg").  */
1025
  if (br_type == SEM_BRANCH_UNCACHEABLE)
1026
    {
1027
      SET_H_PC (new_pc);
1028
      return CPU_SCACHE_PBB_BEGIN (current_cpu);
1029
    }
1030
 
1031
  /* If branch wasn't taken, update the pc and set BR_ADDR_PTR to our
1032
     next chain ptr.  */
1033
  if (br_type == SEM_BRANCH_UNTAKEN)
1034
    {
1035
      ARGBUF *abuf = SEM_ARGBUF (sem_arg);
1036
      new_pc = abuf->addr;
1037
      SET_H_PC (new_pc);
1038
      new_vpc_ptr = &abuf->fields.chain.next;
1039
    }
1040
  else
1041
    {
1042
      ARGBUF *abuf = SEM_ARGBUF (sem_arg);
1043
      SET_H_PC (new_pc);
1044
      new_vpc_ptr = &abuf->fields.chain.branch_target;
1045
    }
1046
 
1047
  /* If chained to next block, go straight to it.  */
1048
  if (*new_vpc_ptr)
1049
    return *new_vpc_ptr;
1050
  /* See if next block has already been compiled.  */
1051
  *new_vpc_ptr = scache_lookup (current_cpu, new_pc);
1052
  if (*new_vpc_ptr)
1053
    return *new_vpc_ptr;
1054
  /* Nope, so next insn is a virtual insn to invoke the compiler
1055
     (begin a pbb).  */
1056
  return CPU_SCACHE_PBB_BEGIN (current_cpu);
1057
}
1058
 
1059
/* x-before handler.
1060
   This is called before each insn.  */
1061
 
1062
void
1063
@cpu@_pbb_before (SIM_CPU *current_cpu, SCACHE *sc)
1064
{
1065
  SEM_ARG sem_arg = sc;
1066
  const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
1067
  int first_p = abuf->fields.before.first_p;
1068
  const ARGBUF *cur_abuf = SEM_ARGBUF (sc + 1);
1069
  const IDESC *cur_idesc = cur_abuf->idesc;
1070
  PCADDR pc = cur_abuf->addr;
1071
 
1072
  if (ARGBUF_PROFILE_P (cur_abuf))
1073
    PROFILE_COUNT_INSN (current_cpu, pc, cur_idesc->num);
1074
 
1075
  /* If this isn't the first insn, finish up the previous one.  */
1076
 
1077
  if (! first_p)
1078
    {
1079
      if (PROFILE_MODEL_P (current_cpu))
1080
        {
1081
          const SEM_ARG prev_sem_arg = sc - 1;
1082
          const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
1083
          const IDESC *prev_idesc = prev_abuf->idesc;
1084
          int cycles;
1085
 
1086
          /* ??? May want to measure all insns if doing insn tracing.  */
1087
          if (ARGBUF_PROFILE_P (prev_abuf))
1088
            {
1089
              cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
1090
              @cpu@_model_insn_after (current_cpu, 0 /*last_p*/, cycles);
1091
            }
1092
        }
1093
 
1094
      TRACE_INSN_FINI (current_cpu, cur_abuf, 0 /*last_p*/);
1095
    }
1096
 
1097
  /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
1098
  if (PROFILE_MODEL_P (current_cpu)
1099
      && ARGBUF_PROFILE_P (cur_abuf))
1100
    @cpu@_model_insn_before (current_cpu, first_p);
1101
 
1102
  TRACE_INSN_INIT (current_cpu, cur_abuf, first_p);
1103
  TRACE_INSN (current_cpu, cur_idesc->idata, cur_abuf, pc);
1104
}
1105
 
1106
/* x-after handler.
1107
   This is called after a serial insn or at the end of a group of parallel
1108
   insns.  */
1109
 
1110
void
1111
@cpu@_pbb_after (SIM_CPU *current_cpu, SCACHE *sc)
1112
{
1113
  SEM_ARG sem_arg = sc;
1114
  const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
1115
  const SEM_ARG prev_sem_arg = sc - 1;
1116
  const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
1117
 
1118
  /* ??? May want to measure all insns if doing insn tracing.  */
1119
  if (PROFILE_MODEL_P (current_cpu)
1120
      && ARGBUF_PROFILE_P (prev_abuf))
1121
    {
1122
      const IDESC *prev_idesc = prev_abuf->idesc;
1123
      int cycles;
1124
 
1125
      cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
1126
      @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
1127
    }
1128
  TRACE_INSN_FINI (current_cpu, prev_abuf, 1 /*last_p*/);
1129
}
1130
 
1131
#define FAST_P 0
1132
 
1133
void
1134
@cpu@_engine_run_full (SIM_CPU *current_cpu)
1135
{
1136
  SIM_DESC current_state = CPU_STATE (current_cpu);
1137
  SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
1138
  /* virtual program counter */
1139
  SEM_PC vpc;
1140
#if WITH_SEM_SWITCH_FULL
1141
  /* For communication between cti's and cti-chain.  */
1142
  SEM_BRANCH_TYPE pbb_br_type;
1143
  PCADDR pbb_br_npc;
1144
#endif
1145
 
1146
EOF
1147
 
1148
case x$parallel in
1149
xread | xwrite)
1150
    cat << EOF
1151
  PAREXEC pbufs[MAX_PARALLEL_INSNS];
1152
  PAREXEC *par_exec = &pbufs[0];
1153
 
1154
EOF
1155
    ;;
1156
esac
1157
 
1158
# Any initialization code before looping starts.
1159
# Note that this code may declare some locals.
1160
${SHELL} $infile init
1161
 
1162
cat << EOF
1163
 
1164
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
1165
    {
1166
      /* ??? 'twould be nice to move this up a level and only call it once.
1167
         On the other hand, in the "let's go fast" case the test is only done
1168
         once per pbb (since we only return to the main loop at the end of
1169
         a pbb).  And in the "let's run until we're done" case we don't return
1170
         until the program exits.  */
1171
 
1172
#if WITH_SEM_SWITCH_FULL
1173
#if defined (__GNUC__)
1174
/* ??? Later maybe paste sem-switch.c in when building mainloop.c.  */
1175
#define DEFINE_LABELS
1176
#include "$switch"
1177
#endif
1178
#else
1179
      @cpu@_sem_init_idesc_table (current_cpu);
1180
#endif
1181
 
1182
      /* Initialize the "begin (compile) a pbb" virtual insn.  */
1183
      vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
1184
      SEM_SET_FULL_CODE (SEM_ARGBUF (vpc),
1185
                         & CPU_IDESC (current_cpu) [@CPU@_INSN_X_BEGIN]);
1186
      vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [@CPU@_INSN_X_BEGIN];
1187
 
1188
      CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
1189
    }
1190
 
1191
  CPU_RUNNING_P (current_cpu) = 1;
1192
  /* ??? In the case where we're returning to the main loop after every
1193
     pbb we don't want to call pbb_begin each time (which hashes on the pc
1194
     and does a table lookup).  A way to speed this up is to save vpc
1195
     between calls.  */
1196
  vpc = @cpu@_pbb_begin (current_cpu, FAST_P);
1197
 
1198
  do
1199
    {
1200
/* begin full-exec-pbb */
1201
EOF
1202
 
1203
${SHELL} $infile full-exec-pbb
1204
 
1205
cat << EOF
1206
/* end full-exec-pbb */
1207
    }
1208
  while (CPU_RUNNING_P (current_cpu));
1209
}
1210
 
1211
#undef FAST_P
1212
 
1213
EOF
1214
 
1215
####################################
1216
 
1217
# Compile engine: fast version.
1218
 
1219
if [ x$fast = xyes ] ; then
1220
 
1221
    cat << EOF
1222
 
1223
#define FAST_P 1
1224
 
1225
void
1226
@cpu@_engine_run_fast (SIM_CPU *current_cpu)
1227
{
1228
  SIM_DESC current_state = CPU_STATE (current_cpu);
1229
  SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
1230
  /* virtual program counter */
1231
  SEM_PC vpc;
1232
#if WITH_SEM_SWITCH_FAST
1233
  /* For communication between cti's and cti-chain.  */
1234
  SEM_BRANCH_TYPE pbb_br_type;
1235
  PCADDR pbb_br_npc;
1236
#endif
1237
 
1238
EOF
1239
 
1240
case x$parallel in
1241
xread | xwrite)
1242
    cat << EOF
1243
  PAREXEC pbufs[MAX_PARALLEL_INSNS];
1244
  PAREXEC *par_exec = &pbufs[0];
1245
 
1246
EOF
1247
    ;;
1248
esac
1249
 
1250
# Any initialization code before looping starts.
1251
# Note that this code may declare some locals.
1252
${SHELL} $infile init
1253
 
1254
cat << EOF
1255
 
1256
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
1257
    {
1258
      /* ??? 'twould be nice to move this up a level and only call it once.
1259
         On the other hand, in the "let's go fast" case the test is only done
1260
         once per pbb (since we only return to the main loop at the end of
1261
         a pbb).  And in the "let's run until we're done" case we don't return
1262
         until the program exits.  */
1263
 
1264
#if WITH_SEM_SWITCH_FAST
1265
#if defined (__GNUC__)
1266
/* ??? Later maybe paste sem-switch.c in when building mainloop.c.  */
1267
#define DEFINE_LABELS
1268
#include "$switch"
1269
#endif
1270
#else
1271
      @cpu@_semf_init_idesc_table (current_cpu);
1272
#endif
1273
 
1274
      /* Initialize the "begin (compile) a pbb" virtual insn.  */
1275
      vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
1276
      SEM_SET_FAST_CODE (SEM_ARGBUF (vpc),
1277
                         & CPU_IDESC (current_cpu) [@CPU@_INSN_X_BEGIN]);
1278
      vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [@CPU@_INSN_X_BEGIN];
1279
 
1280
      CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
1281
    }
1282
 
1283
  CPU_RUNNING_P (current_cpu) = 1;
1284
  /* ??? In the case where we're returning to the main loop after every
1285
     pbb we don't want to call pbb_begin each time (which hashes on the pc
1286
     and does a table lookup).  A way to speed this up is to save vpc
1287
     between calls.  */
1288
  vpc = @cpu@_pbb_begin (current_cpu, FAST_P);
1289
 
1290
  do
1291
    {
1292
/* begin fast-exec-pbb */
1293
EOF
1294
 
1295
${SHELL} $infile fast-exec-pbb
1296
 
1297
cat << EOF
1298
/* end fast-exec-pbb */
1299
    }
1300
  while (CPU_RUNNING_P (current_cpu));
1301
}
1302
 
1303
#undef FAST_P
1304
 
1305
EOF
1306
fi # -fast
1307
 
1308
fi # -pbb
1309
 
1310
# Process @cpu@,@CPU@ appearing in mainloop.in.
1311
sed -e "s/@cpu@/$cpu/g" -e "s/@CPU@/$CPU/g" < tmp-mloop.cin > mloop.cin
1312
rc=$?
1313
rm -f tmp-mloop.cin
1314
 
1315
exit $rc

powered by: WebSVN 2.1.0

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