]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m32r/m32r.c
Shrink size of dwarf2_per_cu_data
[thirdparty/binutils-gdb.git] / sim / m32r / m32r.c
CommitLineData
c906108c 1/* m32r simulator support code
3666a048 2 Copyright (C) 1996-2021 Free Software Foundation, Inc.
c906108c
SS
3 Contributed by Cygnus Support.
4
16b47b25 5 This file is part of GDB, the GNU debugger.
c906108c 6
16b47b25
NC
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.
c906108c 11
16b47b25
NC
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.
c906108c 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/>. */
c906108c
SS
19
20#define WANT_CPU m32rbf
21#define WANT_CPU_M32RBF
22
23#include "sim-main.h"
24#include "cgen-mem.h"
25#include "cgen-ops.h"
32a046ab 26#include <stdlib.h>
c906108c 27
e1636283
AB
28/* Return the size of REGNO in bytes. */
29
30static int
31m32rbf_register_size (int regno)
32{
33 return 4;
34}
35
c906108c
SS
36/* Decode gdb ctrl register number. */
37
38int
39m32r_decode_gdb_ctrl_regnum (int gdb_regnum)
40{
41 switch (gdb_regnum)
42 {
43 case PSW_REGNUM : return H_CR_PSW;
44 case CBR_REGNUM : return H_CR_CBR;
45 case SPI_REGNUM : return H_CR_SPI;
46 case SPU_REGNUM : return H_CR_SPU;
47 case BPC_REGNUM : return H_CR_BPC;
48 case BBPSW_REGNUM : return H_CR_BBPSW;
49 case BBPC_REGNUM : return H_CR_BBPC;
16b47b25 50 case EVB_REGNUM : return H_CR_CR5;
c906108c
SS
51 }
52 abort ();
53}
54
55/* The contents of BUF are in target byte order. */
56
57int
58m32rbf_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
59{
e1636283
AB
60 int size = m32rbf_register_size (rn);
61 if (len != size)
62 return -1;
63
c906108c 64 if (rn < 16)
16b47b25 65 SETTWI (buf, m32rbf_h_gr_get (current_cpu, rn));
c906108c
SS
66 else
67 switch (rn)
68 {
69 case PSW_REGNUM :
70 case CBR_REGNUM :
71 case SPI_REGNUM :
72 case SPU_REGNUM :
73 case BPC_REGNUM :
74 case BBPSW_REGNUM :
75 case BBPC_REGNUM :
16b47b25 76 SETTWI (buf, m32rbf_h_cr_get (current_cpu,
c906108c
SS
77 m32r_decode_gdb_ctrl_regnum (rn)));
78 break;
79 case PC_REGNUM :
16b47b25 80 SETTWI (buf, m32rbf_h_pc_get (current_cpu));
c906108c
SS
81 break;
82 case ACCL_REGNUM :
16b47b25 83 SETTWI (buf, GETLODI (m32rbf_h_accum_get (current_cpu)));
c906108c
SS
84 break;
85 case ACCH_REGNUM :
16b47b25 86 SETTWI (buf, GETHIDI (m32rbf_h_accum_get (current_cpu)));
c906108c
SS
87 break;
88 default :
89 return 0;
90 }
91
e1636283 92 return size;
c906108c
SS
93}
94
95/* The contents of BUF are in target byte order. */
96
97int
98m32rbf_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
99{
e1636283
AB
100 int size = m32rbf_register_size (rn);
101 if (len != size)
102 return -1;
103
c906108c 104 if (rn < 16)
16b47b25 105 m32rbf_h_gr_set (current_cpu, rn, GETTWI (buf));
c906108c
SS
106 else
107 switch (rn)
108 {
109 case PSW_REGNUM :
110 case CBR_REGNUM :
111 case SPI_REGNUM :
112 case SPU_REGNUM :
113 case BPC_REGNUM :
114 case BBPSW_REGNUM :
115 case BBPC_REGNUM :
16b47b25 116 m32rbf_h_cr_set (current_cpu,
c906108c
SS
117 m32r_decode_gdb_ctrl_regnum (rn),
118 GETTWI (buf));
119 break;
120 case PC_REGNUM :
16b47b25 121 m32rbf_h_pc_set (current_cpu, GETTWI (buf));
c906108c
SS
122 break;
123 case ACCL_REGNUM :
124 {
16b47b25 125 DI val = m32rbf_h_accum_get (current_cpu);
c906108c 126 SETLODI (val, GETTWI (buf));
16b47b25 127 m32rbf_h_accum_set (current_cpu, val);
c906108c
SS
128 break;
129 }
130 case ACCH_REGNUM :
131 {
16b47b25 132 DI val = m32rbf_h_accum_get (current_cpu);
c906108c 133 SETHIDI (val, GETTWI (buf));
16b47b25 134 m32rbf_h_accum_set (current_cpu, val);
c906108c
SS
135 break;
136 }
137 default :
138 return 0;
139 }
140
e1636283 141 return size;
c906108c
SS
142}
143\f
144USI
145m32rbf_h_cr_get_handler (SIM_CPU *current_cpu, UINT cr)
146{
147 switch (cr)
148 {
149 case H_CR_PSW : /* psw */
150 return (((CPU (h_bpsw) & 0xc1) << 8)
151 | ((CPU (h_psw) & 0xc0) << 0)
152 | GET_H_COND ());
153 case H_CR_BBPSW : /* backup backup psw */
154 return CPU (h_bbpsw) & 0xc1;
155 case H_CR_CBR : /* condition bit */
156 return GET_H_COND ();
157 case H_CR_SPI : /* interrupt stack pointer */
158 if (! GET_H_SM ())
159 return CPU (h_gr[H_GR_SP]);
160 else
161 return CPU (h_cr[H_CR_SPI]);
162 case H_CR_SPU : /* user stack pointer */
163 if (GET_H_SM ())
164 return CPU (h_gr[H_GR_SP]);
165 else
166 return CPU (h_cr[H_CR_SPU]);
167 case H_CR_BPC : /* backup pc */
168 return CPU (h_cr[H_CR_BPC]) & 0xfffffffe;
169 case H_CR_BBPC : /* backup backup pc */
170 return CPU (h_cr[H_CR_BBPC]) & 0xfffffffe;
171 case 4 : /* ??? unspecified, but apparently available */
172 case 5 : /* ??? unspecified, but apparently available */
173 return CPU (h_cr[cr]);
174 default :
175 return 0;
176 }
177}
178
179void
180m32rbf_h_cr_set_handler (SIM_CPU *current_cpu, UINT cr, USI newval)
181{
182 switch (cr)
183 {
184 case H_CR_PSW : /* psw */
185 {
186 int old_sm = (CPU (h_psw) & 0x80) != 0;
187 int new_sm = (newval & 0x80) != 0;
188 CPU (h_bpsw) = (newval >> 8) & 0xff;
189 CPU (h_psw) = newval & 0xff;
190 SET_H_COND (newval & 1);
191 /* When switching stack modes, update the registers. */
192 if (old_sm != new_sm)
193 {
194 if (old_sm)
195 {
196 /* Switching user -> system. */
197 CPU (h_cr[H_CR_SPU]) = CPU (h_gr[H_GR_SP]);
198 CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPI]);
199 }
200 else
201 {
202 /* Switching system -> user. */
203 CPU (h_cr[H_CR_SPI]) = CPU (h_gr[H_GR_SP]);
204 CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPU]);
205 }
206 }
207 break;
208 }
209 case H_CR_BBPSW : /* backup backup psw */
210 CPU (h_bbpsw) = newval & 0xff;
211 break;
212 case H_CR_CBR : /* condition bit */
213 SET_H_COND (newval & 1);
214 break;
215 case H_CR_SPI : /* interrupt stack pointer */
216 if (! GET_H_SM ())
217 CPU (h_gr[H_GR_SP]) = newval;
218 else
219 CPU (h_cr[H_CR_SPI]) = newval;
220 break;
221 case H_CR_SPU : /* user stack pointer */
222 if (GET_H_SM ())
223 CPU (h_gr[H_GR_SP]) = newval;
224 else
225 CPU (h_cr[H_CR_SPU]) = newval;
226 break;
227 case H_CR_BPC : /* backup pc */
228 CPU (h_cr[H_CR_BPC]) = newval;
229 break;
230 case H_CR_BBPC : /* backup backup pc */
231 CPU (h_cr[H_CR_BBPC]) = newval;
232 break;
233 case 4 : /* ??? unspecified, but apparently available */
234 case 5 : /* ??? unspecified, but apparently available */
235 CPU (h_cr[cr]) = newval;
236 break;
237 default :
238 /* ignore */
239 break;
240 }
241}
242
243/* Cover fns to access h-psw. */
244
245UQI
246m32rbf_h_psw_get_handler (SIM_CPU *current_cpu)
247{
248 return (CPU (h_psw) & 0xfe) | (CPU (h_cond) & 1);
249}
250
251void
252m32rbf_h_psw_set_handler (SIM_CPU *current_cpu, UQI newval)
253{
254 CPU (h_psw) = newval;
255 CPU (h_cond) = newval & 1;
256}
257
258/* Cover fns to access h-accum. */
259
260DI
261m32rbf_h_accum_get_handler (SIM_CPU *current_cpu)
262{
263 /* Sign extend the top 8 bits. */
264 DI r;
265#if 1
266 r = ANDDI (CPU (h_accum), MAKEDI (0xffffff, 0xffffffff));
267 r = XORDI (r, MAKEDI (0x800000, 0));
268 r = SUBDI (r, MAKEDI (0x800000, 0));
269#else
270 SI hi,lo;
271 r = CPU (h_accum);
272 hi = GETHIDI (r);
273 lo = GETLODI (r);
274 hi = ((hi & 0xffffff) ^ 0x800000) - 0x800000;
275 r = MAKEDI (hi, lo);
276#endif
277 return r;
278}
279
280void
281m32rbf_h_accum_set_handler (SIM_CPU *current_cpu, DI newval)
282{
283 CPU (h_accum) = newval;
284}
285\f
286#if WITH_PROFILE_MODEL_P
287
288/* FIXME: Some of these should be inline or macros. Later. */
289
290/* Initialize cycle counting for an insn.
291 FIRST_P is non-zero if this is the first insn in a set of parallel
292 insns. */
293
294void
295m32rbf_model_insn_before (SIM_CPU *cpu, int first_p)
296{
297 M32R_MISC_PROFILE *mp = CPU_M32R_MISC_PROFILE (cpu);
298 mp->cti_stall = 0;
299 mp->load_stall = 0;
300 if (first_p)
301 {
302 mp->load_regs_pending = 0;
303 mp->biggest_cycles = 0;
304 }
305}
306
307/* Record the cycles computed for an insn.
308 LAST_P is non-zero if this is the last insn in a set of parallel insns,
309 and we update the total cycle count.
310 CYCLES is the cycle count of the insn. */
311
312void
313m32rbf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
314{
315 PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
316 M32R_MISC_PROFILE *mp = CPU_M32R_MISC_PROFILE (cpu);
317 unsigned long total = cycles + mp->cti_stall + mp->load_stall;
318
319 if (last_p)
320 {
321 unsigned long biggest = total > mp->biggest_cycles ? total : mp->biggest_cycles;
322 PROFILE_MODEL_TOTAL_CYCLES (p) += biggest;
323 PROFILE_MODEL_CUR_INSN_CYCLES (p) = total;
324 }
325 else
326 {
327 /* Here we take advantage of the fact that !last_p -> first_p. */
328 mp->biggest_cycles = total;
329 PROFILE_MODEL_CUR_INSN_CYCLES (p) = total;
330 }
331
332 /* Branch and load stall counts are recorded independently of the
333 total cycle count. */
334 PROFILE_MODEL_CTI_STALL_CYCLES (p) += mp->cti_stall;
335 PROFILE_MODEL_LOAD_STALL_CYCLES (p) += mp->load_stall;
336
337 mp->load_regs = mp->load_regs_pending;
338}
339
340static INLINE void
341check_load_stall (SIM_CPU *cpu, int regno)
342{
343 UINT h_gr = CPU_M32R_MISC_PROFILE (cpu)->load_regs;
344
345 if (regno != -1
346 && (h_gr & (1 << regno)) != 0)
347 {
348 CPU_M32R_MISC_PROFILE (cpu)->load_stall += 2;
349 if (TRACE_INSN_P (cpu))
350 cgen_trace_printf (cpu, " ; Load stall of 2 cycles.");
351 }
352}
353
354int
355m32rbf_model_m32r_d_u_exec (SIM_CPU *cpu, const IDESC *idesc,
356 int unit_num, int referenced,
357 INT sr, INT sr2, INT dr)
358{
359 check_load_stall (cpu, sr);
360 check_load_stall (cpu, sr2);
361 return idesc->timing->units[unit_num].done;
362}
363
364int
365m32rbf_model_m32r_d_u_cmp (SIM_CPU *cpu, const IDESC *idesc,
366 int unit_num, int referenced,
367 INT src1, INT src2)
368{
369 check_load_stall (cpu, src1);
370 check_load_stall (cpu, src2);
371 return idesc->timing->units[unit_num].done;
372}
373
374int
375m32rbf_model_m32r_d_u_mac (SIM_CPU *cpu, const IDESC *idesc,
376 int unit_num, int referenced,
377 INT src1, INT src2)
378{
379 check_load_stall (cpu, src1);
380 check_load_stall (cpu, src2);
381 return idesc->timing->units[unit_num].done;
382}
383
384int
385m32rbf_model_m32r_d_u_cti (SIM_CPU *cpu, const IDESC *idesc,
386 int unit_num, int referenced,
387 INT sr)
388{
389 PROFILE_DATA *profile = CPU_PROFILE_DATA (cpu);
390 int taken_p = (referenced & (1 << 1)) != 0;
391
392 check_load_stall (cpu, sr);
393 if (taken_p)
394 {
395 CPU_M32R_MISC_PROFILE (cpu)->cti_stall += 2;
396 PROFILE_MODEL_TAKEN_COUNT (profile) += 1;
397 }
398 else
399 PROFILE_MODEL_UNTAKEN_COUNT (profile) += 1;
400 return idesc->timing->units[unit_num].done;
401}
402
403int
404m32rbf_model_m32r_d_u_load (SIM_CPU *cpu, const IDESC *idesc,
405 int unit_num, int referenced,
406 INT sr, INT dr)
407{
408 CPU_M32R_MISC_PROFILE (cpu)->load_regs_pending |= (1 << dr);
409 check_load_stall (cpu, sr);
410 return idesc->timing->units[unit_num].done;
411}
412
413int
414m32rbf_model_m32r_d_u_store (SIM_CPU *cpu, const IDESC *idesc,
415 int unit_num, int referenced,
416 INT src1, INT src2)
417{
418 check_load_stall (cpu, src1);
419 check_load_stall (cpu, src2);
420 return idesc->timing->units[unit_num].done;
421}
422
423int
424m32rbf_model_test_u_exec (SIM_CPU *cpu, const IDESC *idesc,
425 int unit_num, int referenced)
426{
427 return idesc->timing->units[unit_num].done;
428}
429
430#endif /* WITH_PROFILE_MODEL_P */