]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/cgen-par.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / sim / common / cgen-par.c
1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2 Copyright (C) 1999-2023 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions.
4
5 This file is part of the GNU instruction set simulator.
6
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
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
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.
16
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/>. */
19
20 /* This must come before any other includes. */
21 #include "defs.h"
22
23 #include <stdlib.h>
24
25 #include "sim-main.h"
26 #include "cgen-mem.h"
27 #include "cgen-par.h"
28
29 /* Functions required by the cgen interface. These functions add various
30 kinds of writes to the write queue. */
31 void sim_queue_bi_write (SIM_CPU *cpu, BI *target, BI value)
32 {
33 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
34 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
35 element->kind = CGEN_BI_WRITE;
36 element->insn_address = CPU_PC_GET (cpu);
37 element->kinds.bi_write.target = target;
38 element->kinds.bi_write.value = value;
39 }
40
41 void sim_queue_qi_write (SIM_CPU *cpu, UQI *target, UQI value)
42 {
43 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
44 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
45 element->kind = CGEN_QI_WRITE;
46 element->insn_address = CPU_PC_GET (cpu);
47 element->kinds.qi_write.target = target;
48 element->kinds.qi_write.value = value;
49 }
50
51 void sim_queue_si_write (SIM_CPU *cpu, SI *target, SI value)
52 {
53 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
54 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
55 element->kind = CGEN_SI_WRITE;
56 element->insn_address = CPU_PC_GET (cpu);
57 element->kinds.si_write.target = target;
58 element->kinds.si_write.value = value;
59 }
60
61 void sim_queue_sf_write (SIM_CPU *cpu, SI *target, SF value)
62 {
63 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
64 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
65 element->kind = CGEN_SF_WRITE;
66 element->insn_address = CPU_PC_GET (cpu);
67 element->kinds.sf_write.target = target;
68 element->kinds.sf_write.value = value;
69 }
70
71 void sim_queue_pc_write (SIM_CPU *cpu, USI value)
72 {
73 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
74 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
75 element->kind = CGEN_PC_WRITE;
76 element->insn_address = CPU_PC_GET (cpu);
77 element->kinds.pc_write.value = value;
78 }
79
80 void sim_queue_fn_hi_write (
81 SIM_CPU *cpu,
82 void (*write_function)(SIM_CPU *cpu, UINT, UHI),
83 UINT regno,
84 UHI value
85 )
86 {
87 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
88 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
89 element->kind = CGEN_FN_HI_WRITE;
90 element->insn_address = CPU_PC_GET (cpu);
91 element->kinds.fn_hi_write.function = write_function;
92 element->kinds.fn_hi_write.regno = regno;
93 element->kinds.fn_hi_write.value = value;
94 }
95
96 void sim_queue_fn_si_write (
97 SIM_CPU *cpu,
98 void (*write_function)(SIM_CPU *cpu, UINT, USI),
99 UINT regno,
100 USI value
101 )
102 {
103 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
104 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
105 element->kind = CGEN_FN_SI_WRITE;
106 element->insn_address = CPU_PC_GET (cpu);
107 element->kinds.fn_si_write.function = write_function;
108 element->kinds.fn_si_write.regno = regno;
109 element->kinds.fn_si_write.value = value;
110 }
111
112 void sim_queue_fn_sf_write (
113 SIM_CPU *cpu,
114 void (*write_function)(SIM_CPU *cpu, UINT, SF),
115 UINT regno,
116 SF value
117 )
118 {
119 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
120 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
121 element->kind = CGEN_FN_SF_WRITE;
122 element->insn_address = CPU_PC_GET (cpu);
123 element->kinds.fn_sf_write.function = write_function;
124 element->kinds.fn_sf_write.regno = regno;
125 element->kinds.fn_sf_write.value = value;
126 }
127
128 void sim_queue_fn_di_write (
129 SIM_CPU *cpu,
130 void (*write_function)(SIM_CPU *cpu, UINT, DI),
131 UINT regno,
132 DI value
133 )
134 {
135 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
136 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
137 element->kind = CGEN_FN_DI_WRITE;
138 element->insn_address = CPU_PC_GET (cpu);
139 element->kinds.fn_di_write.function = write_function;
140 element->kinds.fn_di_write.regno = regno;
141 element->kinds.fn_di_write.value = value;
142 }
143
144 void sim_queue_fn_xi_write (
145 SIM_CPU *cpu,
146 void (*write_function)(SIM_CPU *cpu, UINT, SI *),
147 UINT regno,
148 SI *value
149 )
150 {
151 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
152 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
153 element->kind = CGEN_FN_XI_WRITE;
154 element->insn_address = CPU_PC_GET (cpu);
155 element->kinds.fn_xi_write.function = write_function;
156 element->kinds.fn_xi_write.regno = regno;
157 element->kinds.fn_xi_write.value[0] = value[0];
158 element->kinds.fn_xi_write.value[1] = value[1];
159 element->kinds.fn_xi_write.value[2] = value[2];
160 element->kinds.fn_xi_write.value[3] = value[3];
161 }
162
163 void sim_queue_fn_df_write (
164 SIM_CPU *cpu,
165 void (*write_function)(SIM_CPU *cpu, UINT, DF),
166 UINT regno,
167 DF value
168 )
169 {
170 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
171 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
172 element->kind = CGEN_FN_DF_WRITE;
173 element->insn_address = CPU_PC_GET (cpu);
174 element->kinds.fn_df_write.function = write_function;
175 element->kinds.fn_df_write.regno = regno;
176 element->kinds.fn_df_write.value = value;
177 }
178
179 void sim_queue_fn_pc_write (
180 SIM_CPU *cpu,
181 void (*write_function)(SIM_CPU *cpu, USI),
182 USI value
183 )
184 {
185 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
186 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
187 element->kind = CGEN_FN_PC_WRITE;
188 element->insn_address = CPU_PC_GET (cpu);
189 element->kinds.fn_pc_write.function = write_function;
190 element->kinds.fn_pc_write.value = value;
191 }
192
193 void sim_queue_mem_qi_write (SIM_CPU *cpu, SI address, QI value)
194 {
195 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
196 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
197 element->kind = CGEN_MEM_QI_WRITE;
198 element->insn_address = CPU_PC_GET (cpu);
199 element->kinds.mem_qi_write.address = address;
200 element->kinds.mem_qi_write.value = value;
201 }
202
203 void sim_queue_mem_hi_write (SIM_CPU *cpu, SI address, HI value)
204 {
205 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
206 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
207 element->kind = CGEN_MEM_HI_WRITE;
208 element->insn_address = CPU_PC_GET (cpu);
209 element->kinds.mem_hi_write.address = address;
210 element->kinds.mem_hi_write.value = value;
211 }
212
213 void sim_queue_mem_si_write (SIM_CPU *cpu, SI address, SI value)
214 {
215 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
216 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
217 element->kind = CGEN_MEM_SI_WRITE;
218 element->insn_address = CPU_PC_GET (cpu);
219 element->kinds.mem_si_write.address = address;
220 element->kinds.mem_si_write.value = value;
221 }
222
223 void sim_queue_mem_di_write (SIM_CPU *cpu, SI address, DI value)
224 {
225 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
226 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
227 element->kind = CGEN_MEM_DI_WRITE;
228 element->insn_address = CPU_PC_GET (cpu);
229 element->kinds.mem_di_write.address = address;
230 element->kinds.mem_di_write.value = value;
231 }
232
233 void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value)
234 {
235 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
236 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
237 element->kind = CGEN_MEM_DF_WRITE;
238 element->insn_address = CPU_PC_GET (cpu);
239 element->kinds.mem_df_write.address = address;
240 element->kinds.mem_df_write.value = value;
241 }
242
243 void sim_queue_mem_xi_write (SIM_CPU *cpu, SI address, SI *value)
244 {
245 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
246 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
247 element->kind = CGEN_MEM_XI_WRITE;
248 element->insn_address = CPU_PC_GET (cpu);
249 element->kinds.mem_xi_write.address = address;
250 element->kinds.mem_xi_write.value[0] = value[0];
251 element->kinds.mem_xi_write.value[1] = value[1];
252 element->kinds.mem_xi_write.value[2] = value[2];
253 element->kinds.mem_xi_write.value[3] = value[3];
254 }
255
256 void sim_queue_fn_mem_qi_write (
257 SIM_CPU *cpu,
258 void (*write_function)(SIM_CPU *cpu, IADDR, SI, QI),
259 SI address,
260 QI value
261 )
262 {
263 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
264 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
265 element->kind = CGEN_FN_MEM_QI_WRITE;
266 element->insn_address = CPU_PC_GET (cpu);
267 element->kinds.fn_mem_qi_write.function = write_function;
268 element->kinds.fn_mem_qi_write.address = address;
269 element->kinds.fn_mem_qi_write.value = value;
270 }
271
272 void sim_queue_fn_mem_hi_write (
273 SIM_CPU *cpu,
274 void (*write_function)(SIM_CPU *cpu, IADDR, SI, HI),
275 SI address,
276 HI value
277 )
278 {
279 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
280 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
281 element->kind = CGEN_FN_MEM_HI_WRITE;
282 element->insn_address = CPU_PC_GET (cpu);
283 element->kinds.fn_mem_hi_write.function = write_function;
284 element->kinds.fn_mem_hi_write.address = address;
285 element->kinds.fn_mem_hi_write.value = value;
286 }
287
288 void sim_queue_fn_mem_si_write (
289 SIM_CPU *cpu,
290 void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI),
291 SI address,
292 SI value
293 )
294 {
295 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
296 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
297 element->kind = CGEN_FN_MEM_SI_WRITE;
298 element->insn_address = CPU_PC_GET (cpu);
299 element->kinds.fn_mem_si_write.function = write_function;
300 element->kinds.fn_mem_si_write.address = address;
301 element->kinds.fn_mem_si_write.value = value;
302 }
303
304 void sim_queue_fn_mem_di_write (
305 SIM_CPU *cpu,
306 void (*write_function)(SIM_CPU *cpu, IADDR, SI, DI),
307 SI address,
308 DI value
309 )
310 {
311 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
312 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
313 element->kind = CGEN_FN_MEM_DI_WRITE;
314 element->insn_address = CPU_PC_GET (cpu);
315 element->kinds.fn_mem_di_write.function = write_function;
316 element->kinds.fn_mem_di_write.address = address;
317 element->kinds.fn_mem_di_write.value = value;
318 }
319
320 void sim_queue_fn_mem_df_write (
321 SIM_CPU *cpu,
322 void (*write_function)(SIM_CPU *cpu, IADDR, SI, DF),
323 SI address,
324 DF value
325 )
326 {
327 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
328 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
329 element->kind = CGEN_FN_MEM_DF_WRITE;
330 element->insn_address = CPU_PC_GET (cpu);
331 element->kinds.fn_mem_df_write.function = write_function;
332 element->kinds.fn_mem_df_write.address = address;
333 element->kinds.fn_mem_df_write.value = value;
334 }
335
336 void sim_queue_fn_mem_xi_write (
337 SIM_CPU *cpu,
338 void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI *),
339 SI address,
340 SI *value
341 )
342 {
343 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
344 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
345 element->kind = CGEN_FN_MEM_XI_WRITE;
346 element->insn_address = CPU_PC_GET (cpu);
347 element->kinds.fn_mem_xi_write.function = write_function;
348 element->kinds.fn_mem_xi_write.address = address;
349 element->kinds.fn_mem_xi_write.value[0] = value[0];
350 element->kinds.fn_mem_xi_write.value[1] = value[1];
351 element->kinds.fn_mem_xi_write.value[2] = value[2];
352 element->kinds.fn_mem_xi_write.value[3] = value[3];
353 }
354
355 /* Execute a write stored on the write queue. */
356 void
357 cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item)
358 {
359 IADDR pc;
360 switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
361 {
362 case CGEN_BI_WRITE:
363 *item->kinds.bi_write.target = item->kinds.bi_write.value;
364 break;
365 case CGEN_QI_WRITE:
366 *item->kinds.qi_write.target = item->kinds.qi_write.value;
367 break;
368 case CGEN_SI_WRITE:
369 *item->kinds.si_write.target = item->kinds.si_write.value;
370 break;
371 case CGEN_SF_WRITE:
372 *item->kinds.sf_write.target = item->kinds.sf_write.value;
373 break;
374 case CGEN_PC_WRITE:
375 CPU_PC_SET (cpu, item->kinds.pc_write.value);
376 break;
377 case CGEN_FN_HI_WRITE:
378 item->kinds.fn_hi_write.function (cpu,
379 item->kinds.fn_hi_write.regno,
380 item->kinds.fn_hi_write.value);
381 break;
382 case CGEN_FN_SI_WRITE:
383 item->kinds.fn_si_write.function (cpu,
384 item->kinds.fn_si_write.regno,
385 item->kinds.fn_si_write.value);
386 break;
387 case CGEN_FN_SF_WRITE:
388 item->kinds.fn_sf_write.function (cpu,
389 item->kinds.fn_sf_write.regno,
390 item->kinds.fn_sf_write.value);
391 break;
392 case CGEN_FN_DI_WRITE:
393 item->kinds.fn_di_write.function (cpu,
394 item->kinds.fn_di_write.regno,
395 item->kinds.fn_di_write.value);
396 break;
397 case CGEN_FN_DF_WRITE:
398 item->kinds.fn_df_write.function (cpu,
399 item->kinds.fn_df_write.regno,
400 item->kinds.fn_df_write.value);
401 break;
402 case CGEN_FN_XI_WRITE:
403 item->kinds.fn_xi_write.function (cpu,
404 item->kinds.fn_xi_write.regno,
405 item->kinds.fn_xi_write.value);
406 break;
407 case CGEN_FN_PC_WRITE:
408 item->kinds.fn_pc_write.function (cpu, item->kinds.fn_pc_write.value);
409 break;
410 case CGEN_MEM_QI_WRITE:
411 pc = item->insn_address;
412 SETMEMQI (cpu, pc, item->kinds.mem_qi_write.address,
413 item->kinds.mem_qi_write.value);
414 break;
415 case CGEN_MEM_HI_WRITE:
416 pc = item->insn_address;
417 SETMEMHI (cpu, pc, item->kinds.mem_hi_write.address,
418 item->kinds.mem_hi_write.value);
419 break;
420 case CGEN_MEM_SI_WRITE:
421 pc = item->insn_address;
422 SETMEMSI (cpu, pc, item->kinds.mem_si_write.address,
423 item->kinds.mem_si_write.value);
424 break;
425 case CGEN_MEM_DI_WRITE:
426 pc = item->insn_address;
427 SETMEMDI (cpu, pc, item->kinds.mem_di_write.address,
428 item->kinds.mem_di_write.value);
429 break;
430 case CGEN_MEM_DF_WRITE:
431 pc = item->insn_address;
432 SETMEMDF (cpu, pc, item->kinds.mem_df_write.address,
433 item->kinds.mem_df_write.value);
434 break;
435 case CGEN_MEM_XI_WRITE:
436 pc = item->insn_address;
437 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address,
438 item->kinds.mem_xi_write.value[0]);
439 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 4,
440 item->kinds.mem_xi_write.value[1]);
441 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 8,
442 item->kinds.mem_xi_write.value[2]);
443 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 12,
444 item->kinds.mem_xi_write.value[3]);
445 break;
446 case CGEN_FN_MEM_QI_WRITE:
447 pc = item->insn_address;
448 item->kinds.fn_mem_qi_write.function (cpu, pc,
449 item->kinds.fn_mem_qi_write.address,
450 item->kinds.fn_mem_qi_write.value);
451 break;
452 case CGEN_FN_MEM_HI_WRITE:
453 pc = item->insn_address;
454 item->kinds.fn_mem_hi_write.function (cpu, pc,
455 item->kinds.fn_mem_hi_write.address,
456 item->kinds.fn_mem_hi_write.value);
457 break;
458 case CGEN_FN_MEM_SI_WRITE:
459 pc = item->insn_address;
460 item->kinds.fn_mem_si_write.function (cpu, pc,
461 item->kinds.fn_mem_si_write.address,
462 item->kinds.fn_mem_si_write.value);
463 break;
464 case CGEN_FN_MEM_DI_WRITE:
465 pc = item->insn_address;
466 item->kinds.fn_mem_di_write.function (cpu, pc,
467 item->kinds.fn_mem_di_write.address,
468 item->kinds.fn_mem_di_write.value);
469 break;
470 case CGEN_FN_MEM_DF_WRITE:
471 pc = item->insn_address;
472 item->kinds.fn_mem_df_write.function (cpu, pc,
473 item->kinds.fn_mem_df_write.address,
474 item->kinds.fn_mem_df_write.value);
475 break;
476 case CGEN_FN_MEM_XI_WRITE:
477 pc = item->insn_address;
478 item->kinds.fn_mem_xi_write.function (cpu, pc,
479 item->kinds.fn_mem_xi_write.address,
480 item->kinds.fn_mem_xi_write.value);
481 break;
482 default:
483 abort ();
484 break; /* FIXME: for now....print message later. */
485 }
486 }
487
488 /* Utilities for the write queue. */
489 CGEN_WRITE_QUEUE_ELEMENT *
490 cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q)
491 {
492 abort (); /* FIXME: for now....print message later. */
493 return 0;
494 }