Update copyright notices to add year 2010.
[deliverable/binutils-gdb.git] / sim / m32r / m32r2.c
CommitLineData
16b47b25 1/* m32r2 simulator support code
dc3cf14f 2 Copyright (C) 1997, 1998, 2003, 2007, 2008, 2009, 2010
e4d013fc 3 Free Software Foundation, Inc.
16b47b25
NC
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
4744ac1b
JB
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
16b47b25
NC
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
4744ac1b
JB
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/>. */
16b47b25
NC
20
21#define WANT_CPU m32r2f
22#define WANT_CPU_M32R2F
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
30int
31m32r2f_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
38int
39m32r2f_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\f
44/* Cover fns to get/set the control registers.
45 FIXME: Duplicated from m32r.c. The issue is structure offsets. */
46
47USI
48m32r2f_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
82void
83m32r2f_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
148UQI
149m32r2f_h_psw_get_handler (SIM_CPU *current_cpu)
150{
151 return (CPU (h_psw) & 0xfe) | (CPU (h_cond) & 1);
152}
153
154void
155m32r2f_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
163DI
164m32r2f_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
174void
175m32r2f_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
182DI
183m32r2f_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
198void
199m32r2f_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\f
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
214void
215m32r2f_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
225void
226m32r2f_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
227{
228 m32rbf_model_insn_after (cpu, last_p, cycles);
229}
230
231static INLINE void
232check_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
245int
246m32r2f_model_m32r2_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
255int
256m32r2f_model_m32r2_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
265int
266m32r2f_model_m32r2_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
275int
276m32r2f_model_m32r2_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
294int
295m32r2f_model_m32r2_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
303int
304m32r2f_model_m32r2_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 */
This page took 0.264992 seconds and 4 git commands to generate.