Update copyright year range in all GDB files.
[deliverable/binutils-gdb.git] / sim / common / sim-n-core.h
CommitLineData
b85e4829
AC
1/* The common simulator framework for GDB, the GNU Debugger.
2
b811d2c2 3 Copyright 2002-2020 Free Software Foundation, Inc.
b85e4829
AC
4
5 Contributed by Andrew Cagney and Red Hat.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
b85e4829
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22
23#ifndef N
24#error "N must be #defined"
25#endif
26#ifndef M
27#define M N
28#endif
29
30/* N: The number of bytes of data to transfer.
31 M: The number of bytes in the type used to transfer the data */
32
33#if (N > M)
34#error "N (nr bytes of data) must be <= M (nr of bytes in data type)"
35#endif
36
37
38#include "symcat.h"
39
40/* NOTE: see end of file for #undef of these macros */
41
42#define unsigned_M XCONCAT2(unsigned_,M)
43
44#define T2H_M XCONCAT2(T2H_,M)
45#define H2T_M XCONCAT2(H2T_,M)
46#define SWAP_M XCONCAT2(SWAP_,M)
47
48#define sim_core_read_aligned_N XCONCAT2(sim_core_read_aligned_,N)
49#define sim_core_read_unaligned_N XCONCAT2(sim_core_read_unaligned_,N)
50#define sim_core_read_misaligned_N XCONCAT2(sim_core_read_misaligned_,N)
51#define sim_core_write_aligned_N XCONCAT2(sim_core_write_aligned_,N)
52#define sim_core_write_unaligned_N XCONCAT2(sim_core_write_unaligned_,N)
53#define sim_core_write_misaligned_N XCONCAT2(sim_core_write_misaligned_,N)
54#define sim_core_trace_M XCONCAT2(sim_core_trace_,M)
55#define sim_core_dummy_M XCONCAT2(sim_core_dummy_,M)
56
57
58#if (M == N && N > 1)
59/* dummy variable used as a return value when nothing else is
60 available and the compiler is complaining */
61static unsigned_M sim_core_dummy_M;
62#endif
63
64
65/* TAGS: sim_core_trace_1 sim_core_trace_2 */
66/* TAGS: sim_core_trace_4 sim_core_trace_8 */
67/* TAGS: sim_core_trace_16 */
68
69#if (M == N)
70STATIC_SIM_CORE(void)
71sim_core_trace_M (sim_cpu *cpu,
72 sim_cia cia,
73 int line_nr,
74 transfer_type type,
75 unsigned map,
76 address_word addr,
77 unsigned_M val,
78 int nr_bytes)
79{
80 const char *transfer = (type == read_transfer ? "read" : "write");
81 const char *direction = (type == read_transfer ? "->" : "<-");
82
83 if (TRACE_DEBUG_P (cpu))
84 trace_printf (CPU_STATE (cpu), cpu, "sim-n-core.h:%d: ", line_nr);
85
86#if (M == 16)
87 trace_printf (CPU_STATE (cpu), cpu,
88 "%s-%d %s:0x%08lx %s 0x%08lx%08lx%08lx%08lx\n",
89 transfer, nr_bytes,
90 map_to_str (map),
91 (unsigned long) addr,
92 direction,
93 (unsigned long) V4_16 (val, 0),
94 (unsigned long) V4_16 (val, 1),
95 (unsigned long) V4_16 (val, 2),
96 (unsigned long) V4_16 (val, 3));
97#endif
98#if (M == 8)
99 trace_printf (CPU_STATE (cpu), cpu,
100 "%s-%d %s:0x%08lx %s 0x%08lx%08lx\n",
101 transfer, nr_bytes,
102 map_to_str (map),
103 (unsigned long) addr,
104 direction,
105 (unsigned long) V4_8 (val, 0),
106 (unsigned long) V4_8 (val, 1));
107#endif
108#if (M == 4)
109 trace_printf (CPU_STATE (cpu), cpu,
110 "%s-%d %s:0x%08lx %s 0x%08lx\n",
111 transfer,
112 nr_bytes,
113 map_to_str (map),
114 (unsigned long) addr,
115 direction,
116 (unsigned long) val);
117#endif
118#if (M == 2)
119 trace_printf (CPU_STATE (cpu), cpu,
120 "%s-%d %s:0x%08lx %s 0x%04lx\n",
121 transfer,
122 nr_bytes,
123 map_to_str (map),
124 (unsigned long) addr,
125 direction,
126 (unsigned long) val);
127#endif
128#if (M == 1)
129 trace_printf (CPU_STATE (cpu), cpu,
130 "%s-%d %s:0x%08lx %s 0x%02lx\n",
131 transfer,
132 nr_bytes,
133 map_to_str (map),
134 (unsigned long) addr,
135 direction,
136 (unsigned long) val);
137#endif
138}
139#endif
140
028f6515 141
c906108c
SS
142/* TAGS: sim_core_read_aligned_1 sim_core_read_aligned_2 */
143/* TAGS: sim_core_read_aligned_4 sim_core_read_aligned_8 */
144/* TAGS: sim_core_read_aligned_16 */
145
146#if (M == N)
147INLINE_SIM_CORE(unsigned_M)
148sim_core_read_aligned_N(sim_cpu *cpu,
149 sim_cia cia,
150 unsigned map,
151 address_word xaddr)
152{
153 sim_cpu_core *cpu_core = CPU_CORE (cpu);
154 sim_core_common *core = &cpu_core->common;
155 unsigned_M val;
156 sim_core_mapping *mapping;
157 address_word addr;
158#if WITH_XOR_ENDIAN != 0
159 if (WITH_XOR_ENDIAN)
160 addr = xaddr ^ cpu_core->xor[(N - 1) % WITH_XOR_ENDIAN];
161 else
162#endif
163 addr = xaddr;
164 mapping = sim_core_find_mapping (core, map, addr, N, read_transfer, 1 /*abort*/, cpu, cia);
165 do
166 {
c906108c 167#if (WITH_HW)
9e8e7dd9 168 if (mapping->device != NULL)
c906108c
SS
169 {
170 unsigned_M data;
171 sim_cpu_hw_io_read_buffer (cpu, cia, mapping->device, &data, mapping->space, addr, N);
172 val = T2H_M (data);
173 break;
174 }
175#endif
176 val = T2H_M (*(unsigned_M*) sim_core_translate (mapping, addr));
177 }
178 while (0);
179 PROFILE_COUNT_CORE (cpu, addr, N, map);
180 if (TRACE_P (cpu, TRACE_CORE_IDX))
181 sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
182 return val;
183}
184#endif
028f6515 185
c906108c
SS
186/* TAGS: sim_core_read_unaligned_1 sim_core_read_unaligned_2 */
187/* TAGS: sim_core_read_unaligned_4 sim_core_read_unaligned_8 */
188/* TAGS: sim_core_read_unaligned_16 */
189
190#if (M == N && N > 1)
191INLINE_SIM_CORE(unsigned_M)
192sim_core_read_unaligned_N(sim_cpu *cpu,
193 sim_cia cia,
194 unsigned map,
195 address_word addr)
196{
197 int alignment = N - 1;
198 /* if hardwired to forced alignment just do it */
199 if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
200 return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
201 else if ((addr & alignment) == 0)
202 return sim_core_read_aligned_N (cpu, cia, map, addr);
203 else
204 switch (CURRENT_ALIGNMENT)
205 {
206 case STRICT_ALIGNMENT:
207 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
208 read_transfer, sim_core_unaligned_signal);
209 case NONSTRICT_ALIGNMENT:
210 {
211 unsigned_M val;
212 if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N)
213 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
214 read_transfer, sim_core_unaligned_signal);
215 val = T2H_M(val);
216 PROFILE_COUNT_CORE (cpu, addr, N, map);
217 if (TRACE_P (cpu, TRACE_CORE_IDX))
218 sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
219 return val;
220 }
221 case FORCED_ALIGNMENT:
222 return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
223 case MIXED_ALIGNMENT:
224 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
225 "internal error - %s - mixed alignment",
226 XSTRING (sim_core_read_unaligned_N));
227 default:
228 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
229 "internal error - %s - bad switch",
230 XSTRING (sim_core_read_unaligned_N));
231 /* to keep some compilers happy, we return a dummy */
232 return sim_core_dummy_M;
233 }
234}
235#endif
236
237/* TAGS: sim_core_read_misaligned_3 sim_core_read_misaligned_5 */
238/* TAGS: sim_core_read_misaligned_6 sim_core_read_misaligned_7 */
239
240#if (M != N)
241INLINE_SIM_CORE(unsigned_M)
242sim_core_read_misaligned_N(sim_cpu *cpu,
243 sim_cia cia,
244 unsigned map,
245 address_word addr)
246{
247 unsigned_M val = 0;
248 if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N)
249 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
250 read_transfer, sim_core_unaligned_signal);
0cb8d851 251 if (HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
c906108c 252 val = SWAP_M (val);
1ac72f06 253 if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
c906108c
SS
254 val >>= (M - N) * 8;
255 PROFILE_COUNT_CORE (cpu, addr, N, map);
256 if (TRACE_P (cpu, TRACE_CORE_IDX))
257 sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
258 return val;
259}
260#endif
261
262/* TAGS: sim_core_write_aligned_1 sim_core_write_aligned_2 */
263/* TAGS: sim_core_write_aligned_4 sim_core_write_aligned_8 */
264/* TAGS: sim_core_write_aligned_16 */
265
266#if (M == N)
267INLINE_SIM_CORE(void)
268sim_core_write_aligned_N(sim_cpu *cpu,
269 sim_cia cia,
270 unsigned map,
271 address_word xaddr,
272 unsigned_M val)
273{
274 sim_cpu_core *cpu_core = CPU_CORE (cpu);
275 sim_core_common *core = &cpu_core->common;
276 sim_core_mapping *mapping;
277 address_word addr;
278#if WITH_XOR_ENDIAN != 0
279 if (WITH_XOR_ENDIAN)
280 addr = xaddr ^ cpu_core->xor[(N - 1) % WITH_XOR_ENDIAN];
281 else
282#endif
283 addr = xaddr;
284 mapping = sim_core_find_mapping (core, map, addr, N, write_transfer, 1 /*abort*/, cpu, cia);
285 do
286 {
c906108c 287#if (WITH_HW)
9e8e7dd9 288 if (mapping->device != NULL)
c906108c
SS
289 {
290 unsigned_M data = H2T_M (val);
291 sim_cpu_hw_io_write_buffer (cpu, cia, mapping->device, &data, mapping->space, addr, N);
292 break;
293 }
294#endif
295 *(unsigned_M*) sim_core_translate (mapping, addr) = H2T_M (val);
296 }
297 while (0);
298 PROFILE_COUNT_CORE (cpu, addr, N, map);
299 if (TRACE_P (cpu, TRACE_CORE_IDX))
300 sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
301}
302#endif
303
304/* TAGS: sim_core_write_unaligned_1 sim_core_write_unaligned_2 */
305/* TAGS: sim_core_write_unaligned_4 sim_core_write_unaligned_8 */
306/* TAGS: sim_core_write_unaligned_16 */
307
308#if (M == N && N > 1)
309INLINE_SIM_CORE(void)
310sim_core_write_unaligned_N(sim_cpu *cpu,
311 sim_cia cia,
312 unsigned map,
313 address_word addr,
314 unsigned_M val)
315{
316 int alignment = N - 1;
317 /* if hardwired to forced alignment just do it */
318 if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
319 sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
320 else if ((addr & alignment) == 0)
321 sim_core_write_aligned_N (cpu, cia, map, addr, val);
322 else
323 switch (CURRENT_ALIGNMENT)
324 {
325 case STRICT_ALIGNMENT:
326 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
327 write_transfer, sim_core_unaligned_signal);
328 break;
329 case NONSTRICT_ALIGNMENT:
330 {
331 unsigned_M data = H2T_M (val);
332 if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N)
333 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
334 write_transfer, sim_core_unaligned_signal);
335 PROFILE_COUNT_CORE (cpu, addr, N, map);
336 if (TRACE_P (cpu, TRACE_CORE_IDX))
337 sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
338 break;
339 }
340 case FORCED_ALIGNMENT:
341 sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
342 break;
343 case MIXED_ALIGNMENT:
344 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
345 "internal error - %s - mixed alignment",
346 XSTRING (sim_core_write_unaligned_N));
347 break;
348 default:
349 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
350 "internal error - %s - bad switch",
351 XSTRING (sim_core_write_unaligned_N));
352 break;
353 }
354}
355#endif
356
357/* TAGS: sim_core_write_misaligned_3 sim_core_write_misaligned_5 */
358/* TAGS: sim_core_write_misaligned_6 sim_core_write_misaligned_7 */
359
360#if (M != N)
361INLINE_SIM_CORE(void)
362sim_core_write_misaligned_N(sim_cpu *cpu,
363 sim_cia cia,
364 unsigned map,
365 address_word addr,
366 unsigned_M val)
367{
368 unsigned_M data = val;
1ac72f06 369 if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
c906108c 370 data <<= (M - N) * 8;
0cb8d851 371 if (HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
c906108c
SS
372 data = SWAP_M (data);
373 if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N)
374 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
375 write_transfer, sim_core_unaligned_signal);
376 PROFILE_COUNT_CORE (cpu, addr, N, map);
377 if (TRACE_P (cpu, TRACE_CORE_IDX))
378 sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
379}
380#endif
381
382
383/* NOTE: see start of file for #define of these macros */
384#undef unsigned_M
385#undef T2H_M
386#undef H2T_M
387#undef SWAP_M
388#undef sim_core_read_aligned_N
389#undef sim_core_read_unaligned_N
390#undef sim_core_read_misaligned_N
391#undef sim_core_write_aligned_N
392#undef sim_core_write_unaligned_N
393#undef sim_core_write_misaligned_N
394#undef sim_core_trace_M
395#undef sim_core_dummy_M
396#undef M
397#undef N
This page took 0.922539 seconds and 4 git commands to generate.