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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [cris/] [mloop.in] - Blame information for rev 853

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

Line No. Rev Author Line
1 330 jeremybenn
# Simulator main loop for CRIS. -*- C -*-
2
# Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
3
# Free Software Foundation, Inc.
4
# Contributed by Axis Communications.
5
#
6
# This file is part of the GNU simulators.
7
#
8
# This program is free software; you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation; either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License
19
# along with this program.  If not, see .
20
 
21
# Based on the fr30 file.
22
 
23
# Syntax:
24
# /bin/sh mainloop.in command
25
#
26
# Command is one of:
27
#
28
# init
29
# support
30
# extract-{simple,scache,pbb}
31
# {full,fast}-exec-{simple,scache,pbb}
32
#
33
# A target need only provide a "full" version of one of simple,scache,pbb.
34
# If the target wants it can also provide a fast version of same.
35
# It can't provide more than this, however for illustration's sake the CRIS
36
# port provides examples of all.
37
 
38
# ??? After a few more ports are done, revisit.
39
# Will eventually need to machine generate a lot of this.
40
 
41
case "x$1" in
42
 
43
xsupport)
44
 
45
cat <
46
/* It seems we don't have a templated header file corresponding to
47
   cris-tmpl.c, so we have to get out declarations the hackish way.  */
48
extern void @cpu@_specific_init (SIM_CPU *current_cpu);
49
 
50
static INLINE const IDESC *
51
extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, ARGBUF *abuf,
52
         int fast_p)
53
{
54
  const IDESC *id = @cpu@_decode (current_cpu, pc, insn,
55
#if CGEN_INT_INSN_P
56
                                  insn,
57
#endif
58
                                  abuf);
59
  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
60
  if (! fast_p)
61
    {
62
      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
63
      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
64
      @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
65
    }
66
  return id;
67
}
68
 
69
static INLINE SEM_PC
70
execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
71
{
72
  SEM_PC vpc;
73
 
74
  if (fast_p)
75
    {
76
#if ! WITH_SEM_SWITCH_FAST
77
#if WITH_SCACHE
78
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
79
#else
80
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
81
#endif
82
#else
83
      abort ();
84
#endif /* WITH_SEM_SWITCH_FAST */
85
    }
86
  else
87
    {
88
#if ! WITH_SEM_SWITCH_FULL
89
      ARGBUF *abuf = &sc->argbuf;
90
      const IDESC *idesc = abuf->idesc;
91
#if WITH_SCACHE_PBB
92
      int virtual_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_VIRTUAL);
93
#else
94
      int virtual_p = 0;
95
#endif
96
 
97
      if (! virtual_p)
98
        {
99
          /* FIXME: call x-before */
100
          if (ARGBUF_PROFILE_P (abuf))
101
            PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
102
          /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
103
          if (PROFILE_MODEL_P (current_cpu)
104
              && ARGBUF_PROFILE_P (abuf))
105
            @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
106
          TRACE_INSN_INIT (current_cpu, abuf, 1);
107
          TRACE_INSN (current_cpu, idesc->idata,
108
                      (const struct argbuf *) abuf, abuf->addr);
109
        }
110
#if WITH_SCACHE
111
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
112
#else
113
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
114
#endif
115
      if (! virtual_p)
116
        {
117
          /* FIXME: call x-after */
118
          if (PROFILE_MODEL_P (current_cpu)
119
              && ARGBUF_PROFILE_P (abuf))
120
            {
121
              int cycles;
122
 
123
              cycles = (*idesc->timing->model_fn) (current_cpu, sc);
124
              @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
125
            }
126
          TRACE_INSN_FINI (current_cpu, abuf, 1);
127
        }
128
#else
129
      abort ();
130
#endif /* WITH_SEM_SWITCH_FULL */
131
    }
132
 
133
  return vpc;
134
}
135
 
136
EOF
137
 
138
;;
139
 
140
xinit)
141
 
142
cat <
143
  /* This seemed the only sane location to emit a call to a
144
     model-specific init function.  It may not work for all simulator
145
     types.  FIXME: Introduce a model-init hook.  */
146
 
147
  /* We use the same condition as the code that's expected to follow, so
148
     GCC can consolidate the code with only one conditional.  */
149
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
150
    @cpu@_specific_init (current_cpu);
151
EOF
152
 
153
;;
154
 
155
xextract-simple | xextract-scache)
156
 
157
# Inputs:  current_cpu, vpc, sc, FAST_P
158
# Outputs: sc filled in
159
 
160
cat <
161
{
162
  CGEN_INSN_INT insn = GETIMEMUHI (current_cpu, vpc);
163
  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
164
}
165
EOF
166
 
167
;;
168
 
169
xextract-pbb)
170
 
171
# Inputs:  current_cpu, pc, sc, max_insns, FAST_P
172
# Outputs: sc, pc
173
# sc must be left pointing past the last created entry.
174
# pc must be left pointing past the last created entry.
175
# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called
176
# to record the vpc of the cti insn.
177
# SET_INSN_COUNT(n) must be called to record number of real insns.
178
 
179
cat <
180
{
181
  const IDESC *idesc;
182
  int icount = 0;
183
 
184
  /* Make sure the buffer doesn't overflow for profiled insns if
185
     max_insns happens to not be a multiple of 3.  */
186
  if (!FAST_P)
187
     max_insns -= 2 + 3;
188
  else
189
     /* There might be two real insns handled per loop.  */
190
     max_insns--;
191
 
192
  while (max_insns > 0)
193
    {
194
      UHI insn = GETIMEMUHI (current_cpu, pc);
195
      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
196
      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
197
      int befaft_p = profile_p || trace_p;
198
 
199
      if (befaft_p)
200
        {
201
          @cpu@_emit_before (current_cpu, sc, pc, 1);
202
          ++sc;
203
          sc->argbuf.trace_p = trace_p;
204
          sc->argbuf.profile_p = profile_p;
205
          --max_insns;
206
        }
207
 
208
      idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
209
      ++sc;
210
      --max_insns;
211
      ++icount;
212
 
213
      if (befaft_p)
214
        {
215
          @cpu@_emit_after (current_cpu, sc, pc);
216
          ++sc;
217
          --max_insns;
218
        }
219
 
220
      pc += idesc->length;
221
 
222
      if (IDESC_CTI_P (idesc))
223
        {
224
          SET_CTI_VPC (sc - 1);
225
 
226
          /* Delay slot?  Ignore for zero-instructions (bcc .+2) since
227
             those are treated as exit insns to avoid runaway sessions
228
             for invalid programs.  */
229
          if (insn != 0 && CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_DELAY_SLOT))
230
            {
231
              UHI insn;
232
              trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
233
              profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
234
              befaft_p = profile_p || trace_p;
235
 
236
              if (befaft_p)
237
                {
238
                  @cpu@_emit_before (current_cpu, sc, pc, 1);
239
                  ++sc;
240
                  sc->argbuf.trace_p = trace_p;
241
                  sc->argbuf.profile_p = profile_p;
242
                  --max_insns;
243
                }
244
 
245
              insn = GETIMEMUHI (current_cpu, pc);
246
              idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
247
              ++sc;
248
              --max_insns;
249
              ++icount;
250
 
251
              if (befaft_p)
252
                {
253
                  @cpu@_emit_after (current_cpu, sc, pc);
254
                  ++sc;
255
                  --max_insns;
256
                }
257
              pc += idesc->length;
258
            }
259
          break;
260
        }
261
    }
262
 
263
 Finish:
264
  SET_INSN_COUNT (icount);
265
}
266
EOF
267
 
268
;;
269
 
270
xfull-exec-* | xfast-exec-*)
271
 
272
# Inputs: current_cpu, sc, FAST_P
273
# Outputs: vpc
274
# vpc contains the address of the next insn to execute
275
 
276
cat <
277
{
278
#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
279
#define DEFINE_SWITCH
280
#include "sem@cpu@-switch.c"
281
#else
282
  vpc = execute (current_cpu, vpc, FAST_P);
283
#endif
284
}
285
EOF
286
 
287
;;
288
 
289
*)
290
  echo "Invalid argument to mainloop.in: $1" >&2
291
  exit 1
292
  ;;
293
 
294
esac

powered by: WebSVN 2.1.0

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