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