]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/sim-n-core.h
Switch the license of all files explicitly copyright the FSF
[thirdparty/binutils-gdb.git] / sim / common / sim-n-core.h
CommitLineData
b85e4829
AC
1/* The common simulator framework for GDB, the GNU Debugger.
2
6aba47ca 3 Copyright 2002, 2007 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
141
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 {
167#if (WITH_DEVICES)
168 if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
169 {
170 unsigned_M data;
7a292a7a 171 if (device_io_read_buffer (mapping->device, &data, mapping->space, addr, N, CPU_STATE (cpu), cpu, cia) != N)
c906108c
SS
172 device_error (mapping->device, "internal error - %s - io_read_buffer should not fail",
173 XSTRING (sim_core_read_aligned_N));
174 val = T2H_M (data);
175 break;
176 }
177#endif
178#if (WITH_HW)
179 if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
180 {
181 unsigned_M data;
182 sim_cpu_hw_io_read_buffer (cpu, cia, mapping->device, &data, mapping->space, addr, N);
183 val = T2H_M (data);
184 break;
185 }
186#endif
187 val = T2H_M (*(unsigned_M*) sim_core_translate (mapping, addr));
188 }
189 while (0);
190 PROFILE_COUNT_CORE (cpu, addr, N, map);
191 if (TRACE_P (cpu, TRACE_CORE_IDX))
192 sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
193 return val;
194}
195#endif
196
197/* TAGS: sim_core_read_unaligned_1 sim_core_read_unaligned_2 */
198/* TAGS: sim_core_read_unaligned_4 sim_core_read_unaligned_8 */
199/* TAGS: sim_core_read_unaligned_16 */
200
201#if (M == N && N > 1)
202INLINE_SIM_CORE(unsigned_M)
203sim_core_read_unaligned_N(sim_cpu *cpu,
204 sim_cia cia,
205 unsigned map,
206 address_word addr)
207{
208 int alignment = N - 1;
209 /* if hardwired to forced alignment just do it */
210 if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
211 return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
212 else if ((addr & alignment) == 0)
213 return sim_core_read_aligned_N (cpu, cia, map, addr);
214 else
215 switch (CURRENT_ALIGNMENT)
216 {
217 case STRICT_ALIGNMENT:
218 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
219 read_transfer, sim_core_unaligned_signal);
220 case NONSTRICT_ALIGNMENT:
221 {
222 unsigned_M val;
223 if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N)
224 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
225 read_transfer, sim_core_unaligned_signal);
226 val = T2H_M(val);
227 PROFILE_COUNT_CORE (cpu, addr, N, map);
228 if (TRACE_P (cpu, TRACE_CORE_IDX))
229 sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
230 return val;
231 }
232 case FORCED_ALIGNMENT:
233 return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
234 case MIXED_ALIGNMENT:
235 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
236 "internal error - %s - mixed alignment",
237 XSTRING (sim_core_read_unaligned_N));
238 default:
239 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
240 "internal error - %s - bad switch",
241 XSTRING (sim_core_read_unaligned_N));
242 /* to keep some compilers happy, we return a dummy */
243 return sim_core_dummy_M;
244 }
245}
246#endif
247
248/* TAGS: sim_core_read_misaligned_3 sim_core_read_misaligned_5 */
249/* TAGS: sim_core_read_misaligned_6 sim_core_read_misaligned_7 */
250
251#if (M != N)
252INLINE_SIM_CORE(unsigned_M)
253sim_core_read_misaligned_N(sim_cpu *cpu,
254 sim_cia cia,
255 unsigned map,
256 address_word addr)
257{
258 unsigned_M val = 0;
259 if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, N) != N)
260 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
261 read_transfer, sim_core_unaligned_signal);
262 if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
263 val = SWAP_M (val);
264 if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
265 val >>= (M - N) * 8;
266 PROFILE_COUNT_CORE (cpu, addr, N, map);
267 if (TRACE_P (cpu, TRACE_CORE_IDX))
268 sim_core_trace_M (cpu, cia, __LINE__, read_transfer, map, addr, val, N);
269 return val;
270}
271#endif
272
273/* TAGS: sim_core_write_aligned_1 sim_core_write_aligned_2 */
274/* TAGS: sim_core_write_aligned_4 sim_core_write_aligned_8 */
275/* TAGS: sim_core_write_aligned_16 */
276
277#if (M == N)
278INLINE_SIM_CORE(void)
279sim_core_write_aligned_N(sim_cpu *cpu,
280 sim_cia cia,
281 unsigned map,
282 address_word xaddr,
283 unsigned_M val)
284{
285 sim_cpu_core *cpu_core = CPU_CORE (cpu);
286 sim_core_common *core = &cpu_core->common;
287 sim_core_mapping *mapping;
288 address_word addr;
289#if WITH_XOR_ENDIAN != 0
290 if (WITH_XOR_ENDIAN)
291 addr = xaddr ^ cpu_core->xor[(N - 1) % WITH_XOR_ENDIAN];
292 else
293#endif
294 addr = xaddr;
295 mapping = sim_core_find_mapping (core, map, addr, N, write_transfer, 1 /*abort*/, cpu, cia);
296 do
297 {
298#if (WITH_DEVICES)
299 if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
300 {
301 unsigned_M data = H2T_M (val);
7a292a7a 302 if (device_io_write_buffer (mapping->device, &data, mapping->space, addr, N, CPU_STATE (cpu), cpu, cia) != N)
c906108c
SS
303 device_error (mapping->device, "internal error - %s - io_write_buffer should not fail",
304 XSTRING (sim_core_write_aligned_N));
305 break;
306 }
307#endif
308#if (WITH_HW)
309 if (WITH_CALLBACK_MEMORY && mapping->device != NULL)
310 {
311 unsigned_M data = H2T_M (val);
312 sim_cpu_hw_io_write_buffer (cpu, cia, mapping->device, &data, mapping->space, addr, N);
313 break;
314 }
315#endif
316 *(unsigned_M*) sim_core_translate (mapping, addr) = H2T_M (val);
317 }
318 while (0);
319 PROFILE_COUNT_CORE (cpu, addr, N, map);
320 if (TRACE_P (cpu, TRACE_CORE_IDX))
321 sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
322}
323#endif
324
325/* TAGS: sim_core_write_unaligned_1 sim_core_write_unaligned_2 */
326/* TAGS: sim_core_write_unaligned_4 sim_core_write_unaligned_8 */
327/* TAGS: sim_core_write_unaligned_16 */
328
329#if (M == N && N > 1)
330INLINE_SIM_CORE(void)
331sim_core_write_unaligned_N(sim_cpu *cpu,
332 sim_cia cia,
333 unsigned map,
334 address_word addr,
335 unsigned_M val)
336{
337 int alignment = N - 1;
338 /* if hardwired to forced alignment just do it */
339 if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
340 sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
341 else if ((addr & alignment) == 0)
342 sim_core_write_aligned_N (cpu, cia, map, addr, val);
343 else
344 switch (CURRENT_ALIGNMENT)
345 {
346 case STRICT_ALIGNMENT:
347 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
348 write_transfer, sim_core_unaligned_signal);
349 break;
350 case NONSTRICT_ALIGNMENT:
351 {
352 unsigned_M data = H2T_M (val);
353 if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N)
354 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
355 write_transfer, sim_core_unaligned_signal);
356 PROFILE_COUNT_CORE (cpu, addr, N, map);
357 if (TRACE_P (cpu, TRACE_CORE_IDX))
358 sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
359 break;
360 }
361 case FORCED_ALIGNMENT:
362 sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
363 break;
364 case MIXED_ALIGNMENT:
365 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
366 "internal error - %s - mixed alignment",
367 XSTRING (sim_core_write_unaligned_N));
368 break;
369 default:
370 sim_engine_abort (CPU_STATE (cpu), cpu, cia,
371 "internal error - %s - bad switch",
372 XSTRING (sim_core_write_unaligned_N));
373 break;
374 }
375}
376#endif
377
378/* TAGS: sim_core_write_misaligned_3 sim_core_write_misaligned_5 */
379/* TAGS: sim_core_write_misaligned_6 sim_core_write_misaligned_7 */
380
381#if (M != N)
382INLINE_SIM_CORE(void)
383sim_core_write_misaligned_N(sim_cpu *cpu,
384 sim_cia cia,
385 unsigned map,
386 address_word addr,
387 unsigned_M val)
388{
389 unsigned_M data = val;
390 if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
391 data <<= (M - N) * 8;
392 if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
393 data = SWAP_M (data);
394 if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &data, addr, N) != N)
395 SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, N, addr,
396 write_transfer, sim_core_unaligned_signal);
397 PROFILE_COUNT_CORE (cpu, addr, N, map);
398 if (TRACE_P (cpu, TRACE_CORE_IDX))
399 sim_core_trace_M (cpu, cia, __LINE__, write_transfer, map, addr, val, N);
400}
401#endif
402
403
404/* NOTE: see start of file for #define of these macros */
405#undef unsigned_M
406#undef T2H_M
407#undef H2T_M
408#undef SWAP_M
409#undef sim_core_read_aligned_N
410#undef sim_core_read_unaligned_N
411#undef sim_core_read_misaligned_N
412#undef sim_core_write_aligned_N
413#undef sim_core_write_unaligned_N
414#undef sim_core_write_misaligned_N
415#undef sim_core_trace_M
416#undef sim_core_dummy_M
417#undef M
418#undef N