1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2 Copyright (C) 1999-2019 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/>. */
24 /* Functions required by the cgen interface. These functions add various
25 kinds of writes to the write queue. */
26 void sim_queue_bi_write (SIM_CPU
*cpu
, BI
*target
, BI value
)
28 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
29 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
30 element
->kind
= CGEN_BI_WRITE
;
31 element
->insn_address
= CPU_PC_GET (cpu
);
32 element
->kinds
.bi_write
.target
= target
;
33 element
->kinds
.bi_write
.value
= value
;
36 void sim_queue_qi_write (SIM_CPU
*cpu
, UQI
*target
, UQI value
)
38 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
39 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
40 element
->kind
= CGEN_QI_WRITE
;
41 element
->insn_address
= CPU_PC_GET (cpu
);
42 element
->kinds
.qi_write
.target
= target
;
43 element
->kinds
.qi_write
.value
= value
;
46 void sim_queue_si_write (SIM_CPU
*cpu
, SI
*target
, SI value
)
48 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
49 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
50 element
->kind
= CGEN_SI_WRITE
;
51 element
->insn_address
= CPU_PC_GET (cpu
);
52 element
->kinds
.si_write
.target
= target
;
53 element
->kinds
.si_write
.value
= value
;
56 void sim_queue_sf_write (SIM_CPU
*cpu
, SI
*target
, SF value
)
58 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
59 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
60 element
->kind
= CGEN_SF_WRITE
;
61 element
->insn_address
= CPU_PC_GET (cpu
);
62 element
->kinds
.sf_write
.target
= target
;
63 element
->kinds
.sf_write
.value
= value
;
66 void sim_queue_pc_write (SIM_CPU
*cpu
, USI value
)
68 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
69 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
70 element
->kind
= CGEN_PC_WRITE
;
71 element
->insn_address
= CPU_PC_GET (cpu
);
72 element
->kinds
.pc_write
.value
= value
;
75 void sim_queue_fn_hi_write (
77 void (*write_function
)(SIM_CPU
*cpu
, UINT
, UHI
),
82 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
83 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
84 element
->kind
= CGEN_FN_HI_WRITE
;
85 element
->insn_address
= CPU_PC_GET (cpu
);
86 element
->kinds
.fn_hi_write
.function
= write_function
;
87 element
->kinds
.fn_hi_write
.regno
= regno
;
88 element
->kinds
.fn_hi_write
.value
= value
;
91 void sim_queue_fn_si_write (
93 void (*write_function
)(SIM_CPU
*cpu
, UINT
, USI
),
98 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
99 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
100 element
->kind
= CGEN_FN_SI_WRITE
;
101 element
->insn_address
= CPU_PC_GET (cpu
);
102 element
->kinds
.fn_si_write
.function
= write_function
;
103 element
->kinds
.fn_si_write
.regno
= regno
;
104 element
->kinds
.fn_si_write
.value
= value
;
107 void sim_queue_fn_sf_write (
109 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SF
),
114 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
115 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
116 element
->kind
= CGEN_FN_SF_WRITE
;
117 element
->insn_address
= CPU_PC_GET (cpu
);
118 element
->kinds
.fn_sf_write
.function
= write_function
;
119 element
->kinds
.fn_sf_write
.regno
= regno
;
120 element
->kinds
.fn_sf_write
.value
= value
;
123 void sim_queue_fn_di_write (
125 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DI
),
130 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
131 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
132 element
->kind
= CGEN_FN_DI_WRITE
;
133 element
->insn_address
= CPU_PC_GET (cpu
);
134 element
->kinds
.fn_di_write
.function
= write_function
;
135 element
->kinds
.fn_di_write
.regno
= regno
;
136 element
->kinds
.fn_di_write
.value
= value
;
139 void sim_queue_fn_xi_write (
141 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SI
*),
146 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
147 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
148 element
->kind
= CGEN_FN_XI_WRITE
;
149 element
->insn_address
= CPU_PC_GET (cpu
);
150 element
->kinds
.fn_xi_write
.function
= write_function
;
151 element
->kinds
.fn_xi_write
.regno
= regno
;
152 element
->kinds
.fn_xi_write
.value
[0] = value
[0];
153 element
->kinds
.fn_xi_write
.value
[1] = value
[1];
154 element
->kinds
.fn_xi_write
.value
[2] = value
[2];
155 element
->kinds
.fn_xi_write
.value
[3] = value
[3];
158 void sim_queue_fn_df_write (
160 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DF
),
165 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
166 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
167 element
->kind
= CGEN_FN_DF_WRITE
;
168 element
->insn_address
= CPU_PC_GET (cpu
);
169 element
->kinds
.fn_df_write
.function
= write_function
;
170 element
->kinds
.fn_df_write
.regno
= regno
;
171 element
->kinds
.fn_df_write
.value
= value
;
174 void sim_queue_fn_pc_write (
176 void (*write_function
)(SIM_CPU
*cpu
, USI
),
180 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
181 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
182 element
->kind
= CGEN_FN_PC_WRITE
;
183 element
->insn_address
= CPU_PC_GET (cpu
);
184 element
->kinds
.fn_pc_write
.function
= write_function
;
185 element
->kinds
.fn_pc_write
.value
= value
;
188 void sim_queue_mem_qi_write (SIM_CPU
*cpu
, SI address
, QI value
)
190 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
191 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
192 element
->kind
= CGEN_MEM_QI_WRITE
;
193 element
->insn_address
= CPU_PC_GET (cpu
);
194 element
->kinds
.mem_qi_write
.address
= address
;
195 element
->kinds
.mem_qi_write
.value
= value
;
198 void sim_queue_mem_hi_write (SIM_CPU
*cpu
, SI address
, HI value
)
200 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
201 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
202 element
->kind
= CGEN_MEM_HI_WRITE
;
203 element
->insn_address
= CPU_PC_GET (cpu
);
204 element
->kinds
.mem_hi_write
.address
= address
;
205 element
->kinds
.mem_hi_write
.value
= value
;
208 void sim_queue_mem_si_write (SIM_CPU
*cpu
, SI address
, SI value
)
210 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
211 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
212 element
->kind
= CGEN_MEM_SI_WRITE
;
213 element
->insn_address
= CPU_PC_GET (cpu
);
214 element
->kinds
.mem_si_write
.address
= address
;
215 element
->kinds
.mem_si_write
.value
= value
;
218 void sim_queue_mem_di_write (SIM_CPU
*cpu
, SI address
, DI value
)
220 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
221 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
222 element
->kind
= CGEN_MEM_DI_WRITE
;
223 element
->insn_address
= CPU_PC_GET (cpu
);
224 element
->kinds
.mem_di_write
.address
= address
;
225 element
->kinds
.mem_di_write
.value
= value
;
228 void sim_queue_mem_df_write (SIM_CPU
*cpu
, SI address
, DF value
)
230 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
231 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
232 element
->kind
= CGEN_MEM_DF_WRITE
;
233 element
->insn_address
= CPU_PC_GET (cpu
);
234 element
->kinds
.mem_df_write
.address
= address
;
235 element
->kinds
.mem_df_write
.value
= value
;
238 void sim_queue_mem_xi_write (SIM_CPU
*cpu
, SI address
, SI
*value
)
240 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
241 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
242 element
->kind
= CGEN_MEM_XI_WRITE
;
243 element
->insn_address
= CPU_PC_GET (cpu
);
244 element
->kinds
.mem_xi_write
.address
= address
;
245 element
->kinds
.mem_xi_write
.value
[0] = value
[0];
246 element
->kinds
.mem_xi_write
.value
[1] = value
[1];
247 element
->kinds
.mem_xi_write
.value
[2] = value
[2];
248 element
->kinds
.mem_xi_write
.value
[3] = value
[3];
251 void sim_queue_fn_mem_qi_write (
253 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, QI
),
258 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
259 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
260 element
->kind
= CGEN_FN_MEM_QI_WRITE
;
261 element
->insn_address
= CPU_PC_GET (cpu
);
262 element
->kinds
.fn_mem_qi_write
.function
= write_function
;
263 element
->kinds
.fn_mem_qi_write
.address
= address
;
264 element
->kinds
.fn_mem_qi_write
.value
= value
;
267 void sim_queue_fn_mem_hi_write (
269 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, HI
),
274 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
275 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
276 element
->kind
= CGEN_FN_MEM_HI_WRITE
;
277 element
->insn_address
= CPU_PC_GET (cpu
);
278 element
->kinds
.fn_mem_hi_write
.function
= write_function
;
279 element
->kinds
.fn_mem_hi_write
.address
= address
;
280 element
->kinds
.fn_mem_hi_write
.value
= value
;
283 void sim_queue_fn_mem_si_write (
285 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
),
290 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
291 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
292 element
->kind
= CGEN_FN_MEM_SI_WRITE
;
293 element
->insn_address
= CPU_PC_GET (cpu
);
294 element
->kinds
.fn_mem_si_write
.function
= write_function
;
295 element
->kinds
.fn_mem_si_write
.address
= address
;
296 element
->kinds
.fn_mem_si_write
.value
= value
;
299 void sim_queue_fn_mem_di_write (
301 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DI
),
306 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
307 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
308 element
->kind
= CGEN_FN_MEM_DI_WRITE
;
309 element
->insn_address
= CPU_PC_GET (cpu
);
310 element
->kinds
.fn_mem_di_write
.function
= write_function
;
311 element
->kinds
.fn_mem_di_write
.address
= address
;
312 element
->kinds
.fn_mem_di_write
.value
= value
;
315 void sim_queue_fn_mem_df_write (
317 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DF
),
322 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
323 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
324 element
->kind
= CGEN_FN_MEM_DF_WRITE
;
325 element
->insn_address
= CPU_PC_GET (cpu
);
326 element
->kinds
.fn_mem_df_write
.function
= write_function
;
327 element
->kinds
.fn_mem_df_write
.address
= address
;
328 element
->kinds
.fn_mem_df_write
.value
= value
;
331 void sim_queue_fn_mem_xi_write (
333 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
*),
338 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
339 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
340 element
->kind
= CGEN_FN_MEM_XI_WRITE
;
341 element
->insn_address
= CPU_PC_GET (cpu
);
342 element
->kinds
.fn_mem_xi_write
.function
= write_function
;
343 element
->kinds
.fn_mem_xi_write
.address
= address
;
344 element
->kinds
.fn_mem_xi_write
.value
[0] = value
[0];
345 element
->kinds
.fn_mem_xi_write
.value
[1] = value
[1];
346 element
->kinds
.fn_mem_xi_write
.value
[2] = value
[2];
347 element
->kinds
.fn_mem_xi_write
.value
[3] = value
[3];
350 /* Execute a write stored on the write queue. */
352 cgen_write_queue_element_execute (SIM_CPU
*cpu
, CGEN_WRITE_QUEUE_ELEMENT
*item
)
355 switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item
))
358 *item
->kinds
.bi_write
.target
= item
->kinds
.bi_write
.value
;
361 *item
->kinds
.qi_write
.target
= item
->kinds
.qi_write
.value
;
364 *item
->kinds
.si_write
.target
= item
->kinds
.si_write
.value
;
367 *item
->kinds
.sf_write
.target
= item
->kinds
.sf_write
.value
;
370 CPU_PC_SET (cpu
, item
->kinds
.pc_write
.value
);
372 case CGEN_FN_HI_WRITE
:
373 item
->kinds
.fn_hi_write
.function (cpu
,
374 item
->kinds
.fn_hi_write
.regno
,
375 item
->kinds
.fn_hi_write
.value
);
377 case CGEN_FN_SI_WRITE
:
378 item
->kinds
.fn_si_write
.function (cpu
,
379 item
->kinds
.fn_si_write
.regno
,
380 item
->kinds
.fn_si_write
.value
);
382 case CGEN_FN_SF_WRITE
:
383 item
->kinds
.fn_sf_write
.function (cpu
,
384 item
->kinds
.fn_sf_write
.regno
,
385 item
->kinds
.fn_sf_write
.value
);
387 case CGEN_FN_DI_WRITE
:
388 item
->kinds
.fn_di_write
.function (cpu
,
389 item
->kinds
.fn_di_write
.regno
,
390 item
->kinds
.fn_di_write
.value
);
392 case CGEN_FN_DF_WRITE
:
393 item
->kinds
.fn_df_write
.function (cpu
,
394 item
->kinds
.fn_df_write
.regno
,
395 item
->kinds
.fn_df_write
.value
);
397 case CGEN_FN_XI_WRITE
:
398 item
->kinds
.fn_xi_write
.function (cpu
,
399 item
->kinds
.fn_xi_write
.regno
,
400 item
->kinds
.fn_xi_write
.value
);
402 case CGEN_FN_PC_WRITE
:
403 item
->kinds
.fn_pc_write
.function (cpu
, item
->kinds
.fn_pc_write
.value
);
405 case CGEN_MEM_QI_WRITE
:
406 pc
= item
->insn_address
;
407 SETMEMQI (cpu
, pc
, item
->kinds
.mem_qi_write
.address
,
408 item
->kinds
.mem_qi_write
.value
);
410 case CGEN_MEM_HI_WRITE
:
411 pc
= item
->insn_address
;
412 SETMEMHI (cpu
, pc
, item
->kinds
.mem_hi_write
.address
,
413 item
->kinds
.mem_hi_write
.value
);
415 case CGEN_MEM_SI_WRITE
:
416 pc
= item
->insn_address
;
417 SETMEMSI (cpu
, pc
, item
->kinds
.mem_si_write
.address
,
418 item
->kinds
.mem_si_write
.value
);
420 case CGEN_MEM_DI_WRITE
:
421 pc
= item
->insn_address
;
422 SETMEMDI (cpu
, pc
, item
->kinds
.mem_di_write
.address
,
423 item
->kinds
.mem_di_write
.value
);
425 case CGEN_MEM_DF_WRITE
:
426 pc
= item
->insn_address
;
427 SETMEMDF (cpu
, pc
, item
->kinds
.mem_df_write
.address
,
428 item
->kinds
.mem_df_write
.value
);
430 case CGEN_MEM_XI_WRITE
:
431 pc
= item
->insn_address
;
432 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
,
433 item
->kinds
.mem_xi_write
.value
[0]);
434 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 4,
435 item
->kinds
.mem_xi_write
.value
[1]);
436 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 8,
437 item
->kinds
.mem_xi_write
.value
[2]);
438 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 12,
439 item
->kinds
.mem_xi_write
.value
[3]);
441 case CGEN_FN_MEM_QI_WRITE
:
442 pc
= item
->insn_address
;
443 item
->kinds
.fn_mem_qi_write
.function (cpu
, pc
,
444 item
->kinds
.fn_mem_qi_write
.address
,
445 item
->kinds
.fn_mem_qi_write
.value
);
447 case CGEN_FN_MEM_HI_WRITE
:
448 pc
= item
->insn_address
;
449 item
->kinds
.fn_mem_hi_write
.function (cpu
, pc
,
450 item
->kinds
.fn_mem_hi_write
.address
,
451 item
->kinds
.fn_mem_hi_write
.value
);
453 case CGEN_FN_MEM_SI_WRITE
:
454 pc
= item
->insn_address
;
455 item
->kinds
.fn_mem_si_write
.function (cpu
, pc
,
456 item
->kinds
.fn_mem_si_write
.address
,
457 item
->kinds
.fn_mem_si_write
.value
);
459 case CGEN_FN_MEM_DI_WRITE
:
460 pc
= item
->insn_address
;
461 item
->kinds
.fn_mem_di_write
.function (cpu
, pc
,
462 item
->kinds
.fn_mem_di_write
.address
,
463 item
->kinds
.fn_mem_di_write
.value
);
465 case CGEN_FN_MEM_DF_WRITE
:
466 pc
= item
->insn_address
;
467 item
->kinds
.fn_mem_df_write
.function (cpu
, pc
,
468 item
->kinds
.fn_mem_df_write
.address
,
469 item
->kinds
.fn_mem_df_write
.value
);
471 case CGEN_FN_MEM_XI_WRITE
:
472 pc
= item
->insn_address
;
473 item
->kinds
.fn_mem_xi_write
.function (cpu
, pc
,
474 item
->kinds
.fn_mem_xi_write
.address
,
475 item
->kinds
.fn_mem_xi_write
.value
);
479 break; /* FIXME: for now....print message later. */
483 /* Utilities for the write queue. */
484 CGEN_WRITE_QUEUE_ELEMENT
*
485 cgen_write_queue_overflow (CGEN_WRITE_QUEUE
*q
)
487 abort (); /* FIXME: for now....print message later. */