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