1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #error "N must be #defined"
31 /* NOTE: see end of file for #undef of these macros */
33 #define unsigned_M XCONCAT2(unsigned_,M)
35 #define T2H_M XCONCAT2(T2H_,M)
36 #define H2T_M XCONCAT2(H2T_,M)
37 #define SWAP_M XCONCAT2(SWAP_,M)
39 #define sim_core_read_aligned_N XCONCAT2(sim_core_read_aligned_,N)
40 #define sim_core_read_unaligned_N XCONCAT2(sim_core_read_unaligned_,N)
41 #define sim_core_read_misaligned_N XCONCAT2(sim_core_read_misaligned_,N)
42 #define sim_core_write_aligned_N XCONCAT2(sim_core_write_aligned_,N)
43 #define sim_core_write_unaligned_N XCONCAT2(sim_core_write_unaligned_,N)
44 #define sim_core_write_misaligned_N XCONCAT2(sim_core_write_misaligned_,N)
45 #define sim_core_trace_M XCONCAT2(sim_core_trace_,M)
48 /* TAGS: sim_core_trace_1 sim_core_trace_2 */
49 /* TAGS: sim_core_trace_4 sim_core_trace_8 */
50 /* TAGS: sim_core_trace_16 */
54 sim_core_trace_M (sim_cpu
*cpu
,
63 char *transfer
= (type
== read_transfer
? "read" : "write");
64 char *direction
= (type
== read_transfer
? "->" : "<-");
66 trace_printf (CPU_STATE (cpu
), cpu
,
67 "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%08lx%08lx%08lx%08lx\n",
70 sim_core_map_to_str (map
),
73 (unsigned long) V4_16 (val
, 0),
74 (unsigned long) V4_16 (val
, 1),
75 (unsigned long) V4_16 (val
, 2),
76 (unsigned long) V4_16 (val
, 3));
79 trace_printf (CPU_STATE (cpu
), cpu
,
80 "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%08lx%08lx\n",
83 sim_core_map_to_str (map
),
86 (unsigned long) V4_8 (val
, 0),
87 (unsigned long) V4_8 (val
, 1));
90 trace_printf (CPU_STATE (cpu
), cpu
,
91 "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%08lx\n",
95 sim_core_map_to_str (map
),
101 trace_printf (CPU_STATE (cpu
), cpu
,
102 "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%04lx\n",
106 sim_core_map_to_str (map
),
107 (unsigned long) addr
,
109 (unsigned long) val
);
112 trace_printf (CPU_STATE (cpu
), cpu
,
113 "sim-n-core.h:%d: %s-%d %s:0x%08lx %s 0x%02lx\n",
117 sim_core_map_to_str (map
),
118 (unsigned long) addr
,
120 (unsigned long) val
);
126 /* TAGS: sim_core_read_aligned_1 sim_core_read_aligned_2 */
127 /* TAGS: sim_core_read_aligned_4 sim_core_read_aligned_8 */
128 /* TAGS: sim_core_read_aligned_16 */
131 INLINE_SIM_CORE(unsigned_M
)
132 sim_core_read_aligned_N(sim_cpu
*cpu
,
137 sim_cpu_core
*cpu_core
= CPU_CORE (cpu
);
138 sim_core_common
*core
= &cpu_core
->common
;
140 sim_core_mapping
*mapping
;
142 #if WITH_XOR_ENDIAN != 0
144 addr
= xaddr
^ cpu_core
->xor[(N
- 1) % WITH_XOR_ENDIAN
];
148 mapping
= sim_core_find_mapping (core
, map
, addr
, N
, read_transfer
, 1 /*abort*/, cpu
, cia
);
150 if (WITH_CALLBACK_MEMORY
&& mapping
->device
!= NULL
) {
152 if (device_io_read_buffer (mapping
->device
, &data
, mapping
->space
, addr
, N
) != N
)
153 device_error (mapping
->device
, "internal error - %s - io_read_buffer should not fail",
154 XSTRING (sim_core_read_aligned_N
));
159 val
= T2H_M (*(unsigned_M
*) sim_core_translate (mapping
, addr
));
160 PROFILE_COUNT_CORE (cpu
, addr
, N
, map
);
161 if (TRACE_P (cpu
, TRACE_CORE_IDX
))
162 sim_core_trace_M (cpu
, cia
, __LINE__
, read_transfer
, map
, addr
, val
, N
);
167 /* TAGS: sim_core_read_unaligned_1 sim_core_read_unaligned_2 */
168 /* TAGS: sim_core_read_unaligned_4 sim_core_read_unaligned_8 */
169 /* TAGS: sim_core_read_unaligned_16 */
171 #if (M == N && N > 1)
172 INLINE_SIM_CORE(unsigned_M
)
173 sim_core_read_unaligned_N(sim_cpu
*cpu
,
178 int alignment
= N
- 1;
179 /* if hardwired to forced alignment just do it */
180 if (WITH_ALIGNMENT
== FORCED_ALIGNMENT
)
181 return sim_core_read_aligned_N (cpu
, cia
, map
, addr
& ~alignment
);
182 else if ((addr
& alignment
) == 0)
183 return sim_core_read_aligned_N (cpu
, cia
, map
, addr
);
185 switch (CURRENT_ALIGNMENT
)
187 case STRICT_ALIGNMENT
:
188 SIM_CORE_SIGNAL (CPU_STATE (cpu
), cpu
, cia
, map
, N
, addr
,
189 read_transfer
, sim_core_unaligned_signal
);
190 case NONSTRICT_ALIGNMENT
:
193 if (sim_core_xor_read_buffer (CPU_STATE (cpu
), cpu
, map
, &val
, addr
, N
) != N
)
194 SIM_CORE_SIGNAL (CPU_STATE (cpu
), cpu
, cia
, map
, N
, addr
,
195 read_transfer
, sim_core_unaligned_signal
);
197 PROFILE_COUNT_CORE (cpu
, addr
, N
, map
);
198 if (TRACE_P (cpu
, TRACE_CORE_IDX
))
199 sim_core_trace_M (cpu
, cia
, __LINE__
, read_transfer
, map
, addr
, val
, N
);
202 case FORCED_ALIGNMENT
:
203 return sim_core_read_aligned_N (cpu
, cia
, map
, addr
& ~alignment
);
204 case MIXED_ALIGNMENT
:
205 sim_engine_abort (CPU_STATE (cpu
), cpu
, cia
,
206 "internal error - %s - mixed alignment",
207 XSTRING (sim_core_read_unaligned_N
));
209 sim_engine_abort (CPU_STATE (cpu
), cpu
, cia
,
210 "internal error - %s - bad switch",
211 XSTRING (sim_core_read_unaligned_N
));
212 /* to keep some compilers happy, we return a dummy */
214 unsigned_M val
[1] = { };
221 /* TAGS: sim_core_read_misaligned_3 sim_core_read_misaligned_5 */
222 /* TAGS: sim_core_read_misaligned_6 sim_core_read_misaligned_7 */
225 INLINE_SIM_CORE(unsigned_M
)
226 sim_core_read_misaligned_N(sim_cpu
*cpu
,
232 if (sim_core_xor_read_buffer (CPU_STATE (cpu
), cpu
, map
, &val
, addr
, N
) != N
)
233 SIM_CORE_SIGNAL (CPU_STATE (cpu
), cpu
, cia
, map
, N
, addr
,
234 read_transfer
, sim_core_unaligned_signal
);
235 if (CURRENT_HOST_BYTE_ORDER
!= CURRENT_TARGET_BYTE_ORDER
)
237 if (CURRENT_TARGET_BYTE_ORDER
== BIG_ENDIAN
)
239 PROFILE_COUNT_CORE (cpu
, addr
, N
, map
);
240 if (TRACE_P (cpu
, TRACE_CORE_IDX
))
241 sim_core_trace_M (cpu
, cia
, __LINE__
, read_transfer
, map
, addr
, val
, N
);
246 /* TAGS: sim_core_write_aligned_1 sim_core_write_aligned_2 */
247 /* TAGS: sim_core_write_aligned_4 sim_core_write_aligned_8 */
248 /* TAGS: sim_core_write_aligned_16 */
251 INLINE_SIM_CORE(void)
252 sim_core_write_aligned_N(sim_cpu
*cpu
,
258 sim_cpu_core
*cpu_core
= CPU_CORE (cpu
);
259 sim_core_common
*core
= &cpu_core
->common
;
260 sim_core_mapping
*mapping
;
262 #if WITH_XOR_ENDIAN != 0
264 addr
= xaddr
^ cpu_core
->xor[(N
- 1) % WITH_XOR_ENDIAN
];
268 mapping
= sim_core_find_mapping (core
, map
, addr
, N
, write_transfer
, 1 /*abort*/, cpu
, cia
);
270 if (WITH_CALLBACK_MEMORY
&& mapping
->device
!= NULL
) {
271 unsigned_M data
= H2T_M (val
);
272 if (device_io_write_buffer (mapping
->device
, &data
, mapping
->space
, addr
, N
, cpu
, cia
) != N
)
273 device_error (mapping
->device
, "internal error - %s - io_write_buffer should not fail",
274 XSTRING (sim_core_write_aligned_N
));
278 *(unsigned_M
*) sim_core_translate (mapping
, addr
) = H2T_M (val
);
279 PROFILE_COUNT_CORE (cpu
, addr
, N
, map
);
280 if (TRACE_P (cpu
, TRACE_CORE_IDX
))
281 sim_core_trace_M (cpu
, cia
, __LINE__
, write_transfer
, map
, addr
, val
, N
);
285 /* TAGS: sim_core_write_unaligned_1 sim_core_write_unaligned_2 */
286 /* TAGS: sim_core_write_unaligned_4 sim_core_write_unaligned_8 */
287 /* TAGS: sim_core_write_unaligned_16 */
289 #if (M == N && N > 1)
290 INLINE_SIM_CORE(void)
291 sim_core_write_unaligned_N(sim_cpu
*cpu
,
297 int alignment
= N
- 1;
298 /* if hardwired to forced alignment just do it */
299 if (WITH_ALIGNMENT
== FORCED_ALIGNMENT
)
300 sim_core_write_aligned_N (cpu
, cia
, map
, addr
& ~alignment
, val
);
301 else if ((addr
& alignment
) == 0)
302 sim_core_write_aligned_N (cpu
, cia
, map
, addr
, val
);
304 switch (CURRENT_ALIGNMENT
)
306 case STRICT_ALIGNMENT
:
307 SIM_CORE_SIGNAL (CPU_STATE (cpu
), cpu
, cia
, map
, N
, addr
,
308 write_transfer
, sim_core_unaligned_signal
);
310 case NONSTRICT_ALIGNMENT
:
312 unsigned_M data
= H2T_M (val
);
313 if (sim_core_xor_write_buffer (CPU_STATE (cpu
), cpu
, map
, &data
, addr
, N
) != N
)
314 SIM_CORE_SIGNAL (CPU_STATE (cpu
), cpu
, cia
, map
, N
, addr
,
315 write_transfer
, sim_core_unaligned_signal
);
316 PROFILE_COUNT_CORE (cpu
, addr
, N
, map
);
317 if (TRACE_P (cpu
, TRACE_CORE_IDX
))
318 sim_core_trace_M (cpu
, cia
, __LINE__
, write_transfer
, map
, addr
, val
, N
);
321 case FORCED_ALIGNMENT
:
322 sim_core_write_aligned_N (cpu
, cia
, map
, addr
& ~alignment
, val
);
324 case MIXED_ALIGNMENT
:
325 sim_engine_abort (CPU_STATE (cpu
), cpu
, cia
,
326 "internal error - %s - mixed alignment",
327 XSTRING (sim_core_write_unaligned_N
));
330 sim_engine_abort (CPU_STATE (cpu
), cpu
, cia
,
331 "internal error - %s - bad switch",
332 XSTRING (sim_core_write_unaligned_N
));
338 /* TAGS: sim_core_write_misaligned_3 sim_core_write_misaligned_5 */
339 /* TAGS: sim_core_write_misaligned_6 sim_core_write_misaligned_7 */
342 INLINE_SIM_CORE(void)
343 sim_core_write_misaligned_N(sim_cpu
*cpu
,
349 unsigned_M data
= val
;
350 if (CURRENT_TARGET_BYTE_ORDER
== BIG_ENDIAN
)
351 data
<<= (M
- N
) * 8;
352 if (CURRENT_HOST_BYTE_ORDER
!= CURRENT_TARGET_BYTE_ORDER
)
353 data
= SWAP_M (data
);
354 if (sim_core_xor_write_buffer (CPU_STATE (cpu
), cpu
, map
, &data
, addr
, N
) != N
)
355 SIM_CORE_SIGNAL (CPU_STATE (cpu
), cpu
, cia
, map
, N
, addr
,
356 write_transfer
, sim_core_unaligned_signal
);
357 PROFILE_COUNT_CORE (cpu
, addr
, N
, map
);
358 if (TRACE_P (cpu
, TRACE_CORE_IDX
))
359 sim_core_trace_M (cpu
, cia
, __LINE__
, write_transfer
, map
, addr
, val
, N
);
364 /* NOTE: see start of file for #define of these macros */
369 #undef sim_core_read_aligned_N
370 #undef sim_core_read_unaligned_N
371 #undef sim_core_read_misaligned_N
372 #undef sim_core_write_aligned_N
373 #undef sim_core_write_unaligned_N
374 #undef sim_core_write_misaligned_N
375 #undef sim_core_trace_M