Commit | Line | Data |
---|---|---|
a1dc3945 AC |
1 | /* This file is part of the program psim. |
2 | ||
3 | Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au> | |
4 | ||
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. | |
9 | ||
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. | |
14 | ||
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. | |
18 | ||
19 | */ | |
20 | ||
21 | ||
22 | #ifndef N | |
23 | #error "N must be #defined" | |
24 | #endif | |
25 | ||
1fe05280 AC |
26 | #include "sim-xcat.h" |
27 | ||
a1dc3945 AC |
28 | /* NOTE: see end of file for #undef of these macros */ |
29 | #define unsigned_N XCONCAT2(unsigned_,N) | |
30 | #define T2H_N XCONCAT2(T2H_,N) | |
31 | #define H2T_N XCONCAT2(H2T_,N) | |
32 | ||
7a418800 AC |
33 | #define sim_core_read_aligned_N XCONCAT2(sim_core_read_aligned_,N) |
34 | #define sim_core_write_aligned_N XCONCAT2(sim_core_write_aligned_,N) | |
35 | #define sim_core_read_unaligned_N XCONCAT2(sim_core_read_unaligned_,N) | |
36 | #define sim_core_write_unaligned_N XCONCAT2(sim_core_write_unaligned_,N) | |
a1dc3945 | 37 | |
74db699d DE |
38 | /* TAGS: sim_core_read_aligned_1 sim_core_read_aligned_2 */ |
39 | /* TAGS: sim_core_read_aligned_4 sim_core_read_aligned_8 */ | |
40 | /* TAGS: sim_core_read_aligned_word */ | |
a1dc3945 AC |
41 | |
42 | INLINE_SIM_CORE(unsigned_N) | |
7a418800 AC |
43 | sim_core_read_aligned_N(sim_cpu *cpu, |
44 | sim_cia cia, | |
45 | sim_core_maps map, | |
cd0d873d | 46 | unsigned_word xaddr) |
a1dc3945 | 47 | { |
cd0d873d | 48 | sim_cpu_core *cpu_core = CPU_CORE (cpu); |
2f2e6c5d | 49 | sim_core_common *core = &cpu_core->common; |
1fe05280 | 50 | unsigned_N val; |
cd0d873d AC |
51 | sim_core_mapping *mapping; |
52 | address_word addr; | |
53 | if (WITH_XOR_ENDIAN) | |
54 | addr = xaddr ^ cpu_core->xor[(sizeof(unsigned_N) - 1) % WITH_XOR_ENDIAN]; | |
55 | else | |
56 | addr = xaddr; | |
57 | mapping = sim_core_find_mapping (core, map, | |
58 | addr, | |
59 | sizeof (unsigned_N), | |
60 | read_transfer, | |
61 | 1 /*abort*/, cpu, cia); | |
a1dc3945 AC |
62 | #if (WITH_DEVICES) |
63 | if (WITH_CALLBACK_MEMORY && mapping->device != NULL) { | |
64 | unsigned_N data; | |
1fe05280 AC |
65 | if (device_io_read_buffer (mapping->device, |
66 | &data, | |
67 | mapping->space, | |
68 | addr, | |
69 | sizeof (unsigned_N)) != sizeof (unsigned_N)) | |
cd0d873d AC |
70 | device_error (mapping->device, "internal error - %s - io_read_buffer should not fail", |
71 | XSTRING (sim_core_read_aligned_N)); | |
1fe05280 | 72 | val = T2H_N (data); |
a1dc3945 AC |
73 | } |
74 | else | |
75 | #endif | |
1fe05280 | 76 | val = T2H_N (*(unsigned_N*) sim_core_translate (mapping, addr)); |
7a418800 | 77 | if (TRACE_P (cpu, TRACE_CORE_IDX)) |
74db699d DE |
78 | if (sizeof (unsigned_N) > 4) |
79 | trace_printf (CPU_STATE (cpu), cpu, | |
a34abff8 | 80 | "sim-n-core.h:%d: read-%d %s:0x%08lx -> 0x%08lx%08lx\n", |
74db699d DE |
81 | __LINE__, |
82 | sizeof (unsigned_N), | |
83 | sim_core_map_to_str (map), | |
84 | (unsigned long) addr, | |
85 | (unsigned long) (((unsigned64)(val)) >> 32), | |
86 | (unsigned long) val); | |
87 | else | |
88 | trace_printf (CPU_STATE (cpu), cpu, | |
a34abff8 | 89 | "sim-n-core.h:%d: read-%d %s:0x%08lx -> 0x%0*lx\n", |
74db699d DE |
90 | __LINE__, |
91 | sizeof (unsigned_N), | |
92 | sim_core_map_to_str (map), | |
93 | (unsigned long) addr, | |
94 | sizeof (unsigned_N) * 2, | |
95 | (unsigned long) val); | |
1fe05280 | 96 | return val; |
a1dc3945 AC |
97 | } |
98 | ||
74db699d DE |
99 | /* TAGS: sim_core_read_unaligned_1 sim_core_read_unaligned_2 */ |
100 | /* TAGS: sim_core_read_unaligned_4 sim_core_read_unaligned_8 */ | |
101 | /* TAGS: sim_core_read_unaligned_word */ | |
a1dc3945 | 102 | |
7a418800 AC |
103 | INLINE_SIM_CORE(unsigned_N) |
104 | sim_core_read_unaligned_N(sim_cpu *cpu, | |
105 | sim_cia cia, | |
106 | sim_core_maps map, | |
cd0d873d | 107 | address_word addr) |
7a418800 AC |
108 | { |
109 | int alignment = sizeof (unsigned_N) - 1; | |
110 | /* if hardwired to forced alignment just do it */ | |
111 | if (WITH_ALIGNMENT == FORCED_ALIGNMENT) | |
112 | return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment); | |
113 | else if ((addr & alignment) == 0) | |
114 | return sim_core_read_aligned_N (cpu, cia, map, addr); | |
115 | else | |
116 | switch (CURRENT_ALIGNMENT) | |
117 | { | |
118 | case STRICT_ALIGNMENT: | |
cd0d873d AC |
119 | SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, |
120 | sizeof (unsigned_N), addr, | |
121 | read_transfer, sim_core_unaligned_signal); | |
7a418800 AC |
122 | return -1; |
123 | case NONSTRICT_ALIGNMENT: | |
124 | { | |
125 | unsigned_N val; | |
2f2e6c5d AC |
126 | if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr, |
127 | sizeof(unsigned_N)) | |
7a418800 | 128 | != sizeof(unsigned_N)) |
cd0d873d AC |
129 | SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, |
130 | sizeof (unsigned_N), addr, | |
131 | read_transfer, sim_core_unaligned_signal); | |
7a418800 AC |
132 | val = T2H_N(val); |
133 | return val; | |
134 | } | |
135 | case FORCED_ALIGNMENT: | |
136 | return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment); | |
137 | case MIXED_ALIGNMENT: | |
cd0d873d AC |
138 | sim_engine_abort (CPU_STATE (cpu), cpu, cia, |
139 | "internal error - %s - mixed alignment", | |
140 | XSTRING (sim_core_read_unaligned_N)); | |
7a418800 AC |
141 | return 0; |
142 | default: | |
cd0d873d AC |
143 | sim_engine_abort (CPU_STATE (cpu), cpu, cia, |
144 | "internal error - %s - bad switch", | |
145 | XSTRING (sim_core_read_unaligned_N)); | |
7a418800 AC |
146 | return 0; |
147 | } | |
148 | } | |
149 | ||
74db699d DE |
150 | /* TAGS: sim_core_write_aligned_1 sim_core_write_aligned_2 */ |
151 | /* TAGS: sim_core_write_aligned_4 sim_core_write_aligned_8 */ | |
152 | /* TAGS: sim_core_write_aligned_word */ | |
a1dc3945 AC |
153 | |
154 | INLINE_SIM_CORE(void) | |
7a418800 AC |
155 | sim_core_write_aligned_N(sim_cpu *cpu, |
156 | sim_cia cia, | |
157 | sim_core_maps map, | |
cd0d873d | 158 | unsigned_word xaddr, |
7a418800 | 159 | unsigned_N val) |
a1dc3945 | 160 | { |
cd0d873d | 161 | sim_cpu_core *cpu_core = CPU_CORE (cpu); |
2f2e6c5d | 162 | sim_core_common *core = &cpu_core->common; |
cd0d873d AC |
163 | sim_core_mapping *mapping; |
164 | address_word addr; | |
165 | if (WITH_XOR_ENDIAN) | |
166 | addr = xaddr ^ cpu_core->xor[(sizeof(unsigned_N) - 1) % WITH_XOR_ENDIAN]; | |
167 | else | |
168 | addr = xaddr; | |
169 | mapping = sim_core_find_mapping(core, map, | |
170 | addr, | |
171 | sizeof (unsigned_N), | |
172 | write_transfer, | |
173 | 1 /*abort*/, cpu, cia); | |
a1dc3945 AC |
174 | #if (WITH_DEVICES) |
175 | if (WITH_CALLBACK_MEMORY && mapping->device != NULL) { | |
1fe05280 AC |
176 | unsigned_N data = H2T_N (val); |
177 | if (device_io_write_buffer (mapping->device, | |
178 | &data, | |
179 | mapping->space, | |
180 | addr, | |
181 | sizeof (unsigned_N), /* nr_bytes */ | |
182 | cpu, | |
183 | cia) != sizeof (unsigned_N)) | |
cd0d873d AC |
184 | device_error (mapping->device, "internal error - %s - io_write_buffer should not fail", |
185 | XSTRING (sim_core_write_aligned_N)); | |
a1dc3945 AC |
186 | } |
187 | else | |
188 | #endif | |
1fe05280 | 189 | *(unsigned_N*) sim_core_translate (mapping, addr) = H2T_N (val); |
7a418800 | 190 | if (TRACE_P (cpu, TRACE_CORE_IDX)) |
74db699d DE |
191 | if (sizeof (unsigned_N) > 4) |
192 | trace_printf (CPU_STATE (cpu), cpu, | |
a34abff8 | 193 | "sim-n-core.h:%d: write-%d %s:0x%08lx <- 0x%08lx%08lx\n", |
74db699d DE |
194 | __LINE__, |
195 | sizeof (unsigned_N), | |
196 | sim_core_map_to_str (map), | |
197 | (unsigned long) addr, | |
198 | (unsigned long) (((unsigned64)(val)) >> 32), | |
199 | (unsigned long) val); | |
200 | else | |
201 | trace_printf (CPU_STATE (cpu), cpu, | |
a34abff8 | 202 | "sim-n-core.h:%d: write-%d %s:0x%08lx <- 0x%0*lx\n", |
74db699d DE |
203 | __LINE__, |
204 | sizeof (unsigned_N), | |
205 | sim_core_map_to_str (map), | |
206 | (unsigned long) addr, | |
207 | sizeof (unsigned_N) * 2, | |
208 | (unsigned long) val); | |
a1dc3945 AC |
209 | } |
210 | ||
74db699d DE |
211 | /* TAGS: sim_core_write_unaligned_1 sim_core_write_unaligned_2 */ |
212 | /* TAGS: sim_core_write_unaligned_4 sim_core_write_unaligned_8 */ | |
213 | /* TAGS: sim_core_write_unaligned_word */ | |
a1dc3945 | 214 | |
7a418800 AC |
215 | INLINE_SIM_CORE(void) |
216 | sim_core_write_unaligned_N(sim_cpu *cpu, | |
217 | sim_cia cia, | |
218 | sim_core_maps map, | |
cd0d873d | 219 | address_word addr, |
7a418800 AC |
220 | unsigned_N val) |
221 | { | |
222 | int alignment = sizeof (unsigned_N) - 1; | |
223 | /* if hardwired to forced alignment just do it */ | |
224 | if (WITH_ALIGNMENT == FORCED_ALIGNMENT) | |
225 | sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val); | |
226 | else if ((addr & alignment) == 0) | |
227 | sim_core_write_aligned_N (cpu, cia, map, addr, val); | |
228 | else | |
229 | switch (CURRENT_ALIGNMENT) | |
230 | { | |
231 | case STRICT_ALIGNMENT: | |
cd0d873d AC |
232 | SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, |
233 | sizeof (unsigned_N), addr, | |
234 | write_transfer, sim_core_unaligned_signal); | |
7a418800 AC |
235 | break; |
236 | case NONSTRICT_ALIGNMENT: | |
237 | { | |
2f2e6c5d AC |
238 | unsigned_N val = H2T_N (val); |
239 | if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &val, addr, | |
240 | sizeof(unsigned_N)) | |
7a418800 | 241 | != sizeof(unsigned_N)) |
cd0d873d AC |
242 | SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, |
243 | sizeof (unsigned_N), addr, | |
244 | write_transfer, sim_core_unaligned_signal); | |
7a418800 AC |
245 | break; |
246 | } | |
247 | case FORCED_ALIGNMENT: | |
248 | sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val); | |
74db699d | 249 | break; |
7a418800 | 250 | case MIXED_ALIGNMENT: |
cd0d873d AC |
251 | sim_engine_abort (CPU_STATE (cpu), cpu, cia, |
252 | "internal error - %s - mixed alignment", | |
253 | XSTRING (sim_core_write_unaligned_N)); | |
7a418800 AC |
254 | break; |
255 | default: | |
cd0d873d AC |
256 | sim_engine_abort (CPU_STATE (cpu), cpu, cia, |
257 | "internal error - %s - bad switch", | |
258 | XSTRING (sim_core_write_unaligned_N)); | |
7a418800 AC |
259 | break; |
260 | } | |
261 | } | |
262 | ||
263 | ||
a1dc3945 AC |
264 | /* NOTE: see start of file for #define of these macros */ |
265 | #undef unsigned_N | |
266 | #undef T2H_N | |
267 | #undef H2T_N | |
7a418800 AC |
268 | #undef sim_core_read_aligned_N |
269 | #undef sim_core_write_aligned_N | |
270 | #undef sim_core_read_unaligned_N | |
271 | #undef sim_core_write_unaligned_N |