1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions.
5 This file is part of the GNU instruction set simulator.
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.
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.
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/>. */
20 /* This must come before any other includes. */
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
)
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
;
40 void sim_queue_qi_write (SIM_CPU
*cpu
, UQI
*target
, UQI value
)
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
;
50 void sim_queue_si_write (SIM_CPU
*cpu
, SI
*target
, SI value
)
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
;
60 void sim_queue_sf_write (SIM_CPU
*cpu
, SI
*target
, SF value
)
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
;
70 void sim_queue_pc_write (SIM_CPU
*cpu
, USI value
)
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
;
79 void sim_queue_fn_hi_write (
81 void (*write_function
)(SIM_CPU
*cpu
, UINT
, UHI
),
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
;
95 void sim_queue_fn_si_write (
97 void (*write_function
)(SIM_CPU
*cpu
, UINT
, USI
),
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
;
111 void sim_queue_fn_sf_write (
113 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SF
),
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
;
127 void sim_queue_fn_di_write (
129 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DI
),
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
;
143 void sim_queue_fn_xi_write (
145 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SI
*),
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];
162 void sim_queue_fn_df_write (
164 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DF
),
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
;
178 void sim_queue_fn_pc_write (
180 void (*write_function
)(SIM_CPU
*cpu
, USI
),
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
;
192 void sim_queue_mem_qi_write (SIM_CPU
*cpu
, SI address
, QI value
)
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
;
202 void sim_queue_mem_hi_write (SIM_CPU
*cpu
, SI address
, HI value
)
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
;
212 void sim_queue_mem_si_write (SIM_CPU
*cpu
, SI address
, SI value
)
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
;
222 void sim_queue_mem_di_write (SIM_CPU
*cpu
, SI address
, DI value
)
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
;
232 void sim_queue_mem_df_write (SIM_CPU
*cpu
, SI address
, DF value
)
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
;
242 void sim_queue_mem_xi_write (SIM_CPU
*cpu
, SI address
, SI
*value
)
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];
255 void sim_queue_fn_mem_qi_write (
257 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, QI
),
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
;
271 void sim_queue_fn_mem_hi_write (
273 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, HI
),
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
;
287 void sim_queue_fn_mem_si_write (
289 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
),
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
;
303 void sim_queue_fn_mem_di_write (
305 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DI
),
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
;
319 void sim_queue_fn_mem_df_write (
321 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DF
),
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
;
335 void sim_queue_fn_mem_xi_write (
337 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
*),
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];
354 /* Execute a write stored on the write queue. */
356 cgen_write_queue_element_execute (SIM_CPU
*cpu
, CGEN_WRITE_QUEUE_ELEMENT
*item
)
359 switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item
))
362 *item
->kinds
.bi_write
.target
= item
->kinds
.bi_write
.value
;
365 *item
->kinds
.qi_write
.target
= item
->kinds
.qi_write
.value
;
368 *item
->kinds
.si_write
.target
= item
->kinds
.si_write
.value
;
371 *item
->kinds
.sf_write
.target
= item
->kinds
.sf_write
.value
;
374 CPU_PC_SET (cpu
, item
->kinds
.pc_write
.value
);
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
);
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
);
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
);
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
);
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
);
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
);
406 case CGEN_FN_PC_WRITE
:
407 item
->kinds
.fn_pc_write
.function (cpu
, item
->kinds
.fn_pc_write
.value
);
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
);
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
);
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
);
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
);
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
);
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]);
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
);
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
);
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
);
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
);
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
);
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
);
483 break; /* FIXME: for now....print message later. */
487 /* Utilities for the write queue. */
488 CGEN_WRITE_QUEUE_ELEMENT
*
489 cgen_write_queue_overflow (CGEN_WRITE_QUEUE
*q
)
491 abort (); /* FIXME: for now....print message later. */
This page took 0.039686 seconds and 4 git commands to generate.