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