1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2 Copyright (C) 1999-2024 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. */
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
)
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
;
41 void sim_queue_qi_write (SIM_CPU
*cpu
, UQI
*target
, UQI value
)
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
;
51 void sim_queue_si_write (SIM_CPU
*cpu
, SI
*target
, SI value
)
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
;
61 void sim_queue_sf_write (SIM_CPU
*cpu
, SI
*target
, SF value
)
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
;
71 void sim_queue_pc_write (SIM_CPU
*cpu
, USI value
)
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
;
80 void sim_queue_fn_hi_write (
82 void (*write_function
)(SIM_CPU
*cpu
, UINT
, UHI
),
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
;
96 void sim_queue_fn_si_write (
98 void (*write_function
)(SIM_CPU
*cpu
, UINT
, USI
),
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
;
112 void sim_queue_fn_sf_write (
114 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SF
),
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
;
128 void sim_queue_fn_di_write (
130 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DI
),
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
;
144 void sim_queue_fn_xi_write (
146 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SI
*),
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];
163 void sim_queue_fn_df_write (
165 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DF
),
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
;
179 void sim_queue_fn_pc_write (
181 void (*write_function
)(SIM_CPU
*cpu
, USI
),
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
;
193 void sim_queue_mem_qi_write (SIM_CPU
*cpu
, SI address
, QI value
)
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
;
203 void sim_queue_mem_hi_write (SIM_CPU
*cpu
, SI address
, HI value
)
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
;
213 void sim_queue_mem_si_write (SIM_CPU
*cpu
, SI address
, SI value
)
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
;
223 void sim_queue_mem_di_write (SIM_CPU
*cpu
, SI address
, DI value
)
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
;
233 void sim_queue_mem_df_write (SIM_CPU
*cpu
, SI address
, DF value
)
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
;
243 void sim_queue_mem_xi_write (SIM_CPU
*cpu
, SI address
, SI
*value
)
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];
256 void sim_queue_fn_mem_qi_write (
258 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, QI
),
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
;
272 void sim_queue_fn_mem_hi_write (
274 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, HI
),
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
;
288 void sim_queue_fn_mem_si_write (
290 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
),
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
;
304 void sim_queue_fn_mem_di_write (
306 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DI
),
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
;
320 void sim_queue_fn_mem_df_write (
322 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DF
),
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
;
336 void sim_queue_fn_mem_xi_write (
338 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
*),
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];
355 /* Execute a write stored on the write queue. */
357 cgen_write_queue_element_execute (SIM_CPU
*cpu
, CGEN_WRITE_QUEUE_ELEMENT
*item
)
360 switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item
))
363 *item
->kinds
.bi_write
.target
= item
->kinds
.bi_write
.value
;
366 *item
->kinds
.qi_write
.target
= item
->kinds
.qi_write
.value
;
369 *item
->kinds
.si_write
.target
= item
->kinds
.si_write
.value
;
372 *item
->kinds
.sf_write
.target
= item
->kinds
.sf_write
.value
;
375 CPU_PC_SET (cpu
, item
->kinds
.pc_write
.value
);
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
);
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
);
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
);
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
);
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
);
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
);
407 case CGEN_FN_PC_WRITE
:
408 item
->kinds
.fn_pc_write
.function (cpu
, item
->kinds
.fn_pc_write
.value
);
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
);
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
);
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
);
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
);
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
);
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]);
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
);
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
);
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
);
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
);
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
);
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
);
484 break; /* FIXME: for now....print message later. */
488 /* Utilities for the write queue. */
489 CGEN_WRITE_QUEUE_ELEMENT
*
490 cgen_write_queue_overflow (CGEN_WRITE_QUEUE
*q
)
492 abort (); /* FIXME: for now....print message later. */