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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [sim/] [m32r/] [m32rx.c] - Blame information for rev 227

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* m32rx simulator support code
2
   Copyright (C) 1997, 1998, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
   Contributed by Cygnus Support.
5
 
6
This file is part of GDB, the GNU debugger.
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 <http://www.gnu.org/licenses/>.  */
20
 
21
#define WANT_CPU m32rxf
22
#define WANT_CPU_M32RXF
23
 
24
#include "sim-main.h"
25
#include "cgen-mem.h"
26
#include "cgen-ops.h"
27
 
28
/* The contents of BUF are in target byte order.  */
29
 
30
int
31
m32rxf_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
32
{
33
  return m32rbf_fetch_register (current_cpu, rn, buf, len);
34
}
35
 
36
/* The contents of BUF are in target byte order.  */
37
 
38
int
39
m32rxf_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
40
{
41
  return m32rbf_store_register (current_cpu, rn, buf, len);
42
}
43
 
44
/* Cover fns to get/set the control registers.
45
   FIXME: Duplicated from m32r.c.  The issue is structure offsets.  */
46
 
47
USI
48
m32rxf_h_cr_get_handler (SIM_CPU *current_cpu, UINT cr)
49
{
50
  switch (cr)
51
    {
52
    case H_CR_PSW : /* psw */
53
      return (((CPU (h_bpsw) & 0xc1) << 8)
54
              | ((CPU (h_psw) & 0xc0) << 0)
55
              | GET_H_COND ());
56
    case H_CR_BBPSW : /* backup backup psw */
57
      return CPU (h_bbpsw) & 0xc1;
58
    case H_CR_CBR : /* condition bit */
59
      return GET_H_COND ();
60
    case H_CR_SPI : /* interrupt stack pointer */
61
      if (! GET_H_SM ())
62
        return CPU (h_gr[H_GR_SP]);
63
      else
64
        return CPU (h_cr[H_CR_SPI]);
65
    case H_CR_SPU : /* user stack pointer */
66
      if (GET_H_SM ())
67
        return CPU (h_gr[H_GR_SP]);
68
      else
69
        return CPU (h_cr[H_CR_SPU]);
70
    case H_CR_BPC : /* backup pc */
71
      return CPU (h_cr[H_CR_BPC]) & 0xfffffffe;
72
    case H_CR_BBPC : /* backup backup pc */
73
      return CPU (h_cr[H_CR_BBPC]) & 0xfffffffe;
74
    case 4 : /* ??? unspecified, but apparently available */
75
    case 5 : /* ??? unspecified, but apparently available */
76
      return CPU (h_cr[cr]);
77
    default :
78
      return 0;
79
    }
80
}
81
 
82
void
83
m32rxf_h_cr_set_handler (SIM_CPU *current_cpu, UINT cr, USI newval)
84
{
85
  switch (cr)
86
    {
87
    case H_CR_PSW : /* psw */
88
      {
89
        int old_sm = (CPU (h_psw) & 0x80) != 0;
90
        int new_sm = (newval & 0x80) != 0;
91
        CPU (h_bpsw) = (newval >> 8) & 0xff;
92
        CPU (h_psw) = newval & 0xff;
93
        SET_H_COND (newval & 1);
94
        /* When switching stack modes, update the registers.  */
95
        if (old_sm != new_sm)
96
          {
97
            if (old_sm)
98
              {
99
                /* Switching user -> system.  */
100
                CPU (h_cr[H_CR_SPU]) = CPU (h_gr[H_GR_SP]);
101
                CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPI]);
102
              }
103
            else
104
              {
105
                /* Switching system -> user.  */
106
                CPU (h_cr[H_CR_SPI]) = CPU (h_gr[H_GR_SP]);
107
                CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPU]);
108
              }
109
          }
110
        break;
111
      }
112
    case H_CR_BBPSW : /* backup backup psw */
113
      CPU (h_bbpsw) = newval & 0xff;
114
      break;
115
    case H_CR_CBR : /* condition bit */
116
      SET_H_COND (newval & 1);
117
      break;
118
    case H_CR_SPI : /* interrupt stack pointer */
119
      if (! GET_H_SM ())
120
        CPU (h_gr[H_GR_SP]) = newval;
121
      else
122
        CPU (h_cr[H_CR_SPI]) = newval;
123
      break;
124
    case H_CR_SPU : /* user stack pointer */
125
      if (GET_H_SM ())
126
        CPU (h_gr[H_GR_SP]) = newval;
127
      else
128
        CPU (h_cr[H_CR_SPU]) = newval;
129
      break;
130
    case H_CR_BPC : /* backup pc */
131
      CPU (h_cr[H_CR_BPC]) = newval;
132
      break;
133
    case H_CR_BBPC : /* backup backup pc */
134
      CPU (h_cr[H_CR_BBPC]) = newval;
135
      break;
136
    case 4 : /* ??? unspecified, but apparently available */
137
    case 5 : /* ??? unspecified, but apparently available */
138
      CPU (h_cr[cr]) = newval;
139
      break;
140
    default :
141
      /* ignore */
142
      break;
143
    }
144
}
145
 
146
/* Cover fns to access h-psw.  */
147
 
148
UQI
149
m32rxf_h_psw_get_handler (SIM_CPU *current_cpu)
150
{
151
  return (CPU (h_psw) & 0xfe) | (CPU (h_cond) & 1);
152
}
153
 
154
void
155
m32rxf_h_psw_set_handler (SIM_CPU *current_cpu, UQI newval)
156
{
157
  CPU (h_psw) = newval;
158
  CPU (h_cond) = newval & 1;
159
}
160
 
161
/* Cover fns to access h-accum.  */
162
 
163
DI
164
m32rxf_h_accum_get_handler (SIM_CPU *current_cpu)
165
{
166
  /* Sign extend the top 8 bits.  */
167
  DI r;
168
  r = ANDDI (CPU (h_accum), MAKEDI (0xffffff, 0xffffffff));
169
  r = XORDI (r, MAKEDI (0x800000, 0));
170
  r = SUBDI (r, MAKEDI (0x800000, 0));
171
  return r;
172
}
173
 
174
void
175
m32rxf_h_accum_set_handler (SIM_CPU *current_cpu, DI newval)
176
{
177
  CPU (h_accum) = newval;
178
}
179
 
180
/* Cover fns to access h-accums.  */
181
 
182
DI
183
m32rxf_h_accums_get_handler (SIM_CPU *current_cpu, UINT regno)
184
{
185
  /* FIXME: Yes, this is just a quick hack.  */
186
  DI r;
187
  if (regno == 0)
188
    r = CPU (h_accum);
189
  else
190
    r = CPU (h_accums[1]);
191
  /* Sign extend the top 8 bits.  */
192
  r = ANDDI (r, MAKEDI (0xffffff, 0xffffffff));
193
  r = XORDI (r, MAKEDI (0x800000, 0));
194
  r = SUBDI (r, MAKEDI (0x800000, 0));
195
  return r;
196
}
197
 
198
void
199
m32rxf_h_accums_set_handler (SIM_CPU *current_cpu, UINT regno, DI newval)
200
{
201
  /* FIXME: Yes, this is just a quick hack.  */
202
  if (regno == 0)
203
    CPU (h_accum) = newval;
204
  else
205
    CPU (h_accums[1]) = newval;
206
}
207
 
208
#if WITH_PROFILE_MODEL_P
209
 
210
/* Initialize cycle counting for an insn.
211
   FIRST_P is non-zero if this is the first insn in a set of parallel
212
   insns.  */
213
 
214
void
215
m32rxf_model_insn_before (SIM_CPU *cpu, int first_p)
216
{
217
  m32rbf_model_insn_before (cpu, first_p);
218
}
219
 
220
/* Record the cycles computed for an insn.
221
   LAST_P is non-zero if this is the last insn in a set of parallel insns,
222
   and we update the total cycle count.
223
   CYCLES is the cycle count of the insn.  */
224
 
225
void
226
m32rxf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
227
{
228
  m32rbf_model_insn_after (cpu, last_p, cycles);
229
}
230
 
231
static INLINE void
232
check_load_stall (SIM_CPU *cpu, int regno)
233
{
234
  UINT h_gr = CPU_M32R_MISC_PROFILE (cpu)->load_regs;
235
 
236
  if (regno != -1
237
      && (h_gr & (1 << regno)) != 0)
238
    {
239
      CPU_M32R_MISC_PROFILE (cpu)->load_stall += 2;
240
      if (TRACE_INSN_P (cpu))
241
        cgen_trace_printf (cpu, " ; Load stall of 2 cycles.");
242
    }
243
}
244
 
245
int
246
m32rxf_model_m32rx_u_exec (SIM_CPU *cpu, const IDESC *idesc,
247
                           int unit_num, int referenced,
248
                           INT sr, INT sr2, INT dr)
249
{
250
  check_load_stall (cpu, sr);
251
  check_load_stall (cpu, sr2);
252
  return idesc->timing->units[unit_num].done;
253
}
254
 
255
int
256
m32rxf_model_m32rx_u_cmp (SIM_CPU *cpu, const IDESC *idesc,
257
                           int unit_num, int referenced,
258
                           INT src1, INT src2)
259
{
260
  check_load_stall (cpu, src1);
261
  check_load_stall (cpu, src2);
262
  return idesc->timing->units[unit_num].done;
263
}
264
 
265
int
266
m32rxf_model_m32rx_u_mac (SIM_CPU *cpu, const IDESC *idesc,
267
                           int unit_num, int referenced,
268
                           INT src1, INT src2)
269
{
270
  check_load_stall (cpu, src1);
271
  check_load_stall (cpu, src2);
272
  return idesc->timing->units[unit_num].done;
273
}
274
 
275
int
276
m32rxf_model_m32rx_u_cti (SIM_CPU *cpu, const IDESC *idesc,
277
                          int unit_num, int referenced,
278
                          INT sr)
279
{
280
  PROFILE_DATA *profile = CPU_PROFILE_DATA (cpu);
281
  int taken_p = (referenced & (1 << 1)) != 0;
282
 
283
  check_load_stall (cpu, sr);
284
  if (taken_p)
285
    {
286
      CPU_M32R_MISC_PROFILE (cpu)->cti_stall += 2;
287
      PROFILE_MODEL_TAKEN_COUNT (profile) += 1;
288
    }
289
  else
290
    PROFILE_MODEL_UNTAKEN_COUNT (profile) += 1;
291
  return idesc->timing->units[unit_num].done;
292
}
293
 
294
int
295
m32rxf_model_m32rx_u_load (SIM_CPU *cpu, const IDESC *idesc,
296
                           int unit_num, int referenced,
297
                           INT sr, INT dr)
298
{
299
  CPU_M32R_MISC_PROFILE (cpu)->load_regs_pending |= (1 << dr);
300
  return idesc->timing->units[unit_num].done;
301
}
302
 
303
int
304
m32rxf_model_m32rx_u_store (SIM_CPU *cpu, const IDESC *idesc,
305
                            int unit_num, int referenced,
306
                            INT src1, INT src2)
307
{
308
  return idesc->timing->units[unit_num].done;
309
}
310
 
311
#endif /* WITH_PROFILE_MODEL_P */

powered by: WebSVN 2.1.0

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