1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2 Copyright (C) 1999, 2000 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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 /* Functions required by the cgen interface. These functions add various
26 kinds of writes to the write queue. */
27 void sim_queue_bi_write (SIM_CPU
*cpu
, BI
*target
, BI value
)
29 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
30 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
31 element
->kind
= CGEN_BI_WRITE
;
32 element
->insn_address
= CPU_PC_GET (cpu
);
33 element
->kinds
.bi_write
.target
= target
;
34 element
->kinds
.bi_write
.value
= value
;
37 void sim_queue_qi_write (SIM_CPU
*cpu
, UQI
*target
, UQI value
)
39 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
40 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
41 element
->kind
= CGEN_QI_WRITE
;
42 element
->insn_address
= CPU_PC_GET (cpu
);
43 element
->kinds
.qi_write
.target
= target
;
44 element
->kinds
.qi_write
.value
= value
;
47 void sim_queue_si_write (SIM_CPU
*cpu
, SI
*target
, SI value
)
49 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
50 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
51 element
->kind
= CGEN_SI_WRITE
;
52 element
->insn_address
= CPU_PC_GET (cpu
);
53 element
->kinds
.si_write
.target
= target
;
54 element
->kinds
.si_write
.value
= value
;
57 void sim_queue_sf_write (SIM_CPU
*cpu
, SI
*target
, SF value
)
59 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
60 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
61 element
->kind
= CGEN_SF_WRITE
;
62 element
->insn_address
= CPU_PC_GET (cpu
);
63 element
->kinds
.sf_write
.target
= target
;
64 element
->kinds
.sf_write
.value
= value
;
67 void sim_queue_pc_write (SIM_CPU
*cpu
, USI value
)
69 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
70 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
71 element
->kind
= CGEN_PC_WRITE
;
72 element
->insn_address
= CPU_PC_GET (cpu
);
73 element
->kinds
.pc_write
.value
= value
;
76 void sim_queue_fn_hi_write (
78 void (*write_function
)(SIM_CPU
*cpu
, UINT
, UHI
),
83 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
84 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
85 element
->kind
= CGEN_FN_HI_WRITE
;
86 element
->insn_address
= CPU_PC_GET (cpu
);
87 element
->kinds
.fn_hi_write
.function
= write_function
;
88 element
->kinds
.fn_hi_write
.regno
= regno
;
89 element
->kinds
.fn_hi_write
.value
= value
;
92 void sim_queue_fn_si_write (
94 void (*write_function
)(SIM_CPU
*cpu
, UINT
, USI
),
99 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
100 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
101 element
->kind
= CGEN_FN_SI_WRITE
;
102 element
->insn_address
= CPU_PC_GET (cpu
);
103 element
->kinds
.fn_si_write
.function
= write_function
;
104 element
->kinds
.fn_si_write
.regno
= regno
;
105 element
->kinds
.fn_si_write
.value
= value
;
108 void sim_queue_fn_sf_write (
110 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SF
),
115 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
116 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
117 element
->kind
= CGEN_FN_SF_WRITE
;
118 element
->insn_address
= CPU_PC_GET (cpu
);
119 element
->kinds
.fn_sf_write
.function
= write_function
;
120 element
->kinds
.fn_sf_write
.regno
= regno
;
121 element
->kinds
.fn_sf_write
.value
= value
;
124 void sim_queue_fn_di_write (
126 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DI
),
131 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
132 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
133 element
->kind
= CGEN_FN_DI_WRITE
;
134 element
->insn_address
= CPU_PC_GET (cpu
);
135 element
->kinds
.fn_di_write
.function
= write_function
;
136 element
->kinds
.fn_di_write
.regno
= regno
;
137 element
->kinds
.fn_di_write
.value
= value
;
140 void sim_queue_fn_xi_write (
142 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SI
*),
147 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
148 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
149 element
->kind
= CGEN_FN_XI_WRITE
;
150 element
->insn_address
= CPU_PC_GET (cpu
);
151 element
->kinds
.fn_xi_write
.function
= write_function
;
152 element
->kinds
.fn_xi_write
.regno
= regno
;
153 element
->kinds
.fn_xi_write
.value
[0] = value
[0];
154 element
->kinds
.fn_xi_write
.value
[1] = value
[1];
155 element
->kinds
.fn_xi_write
.value
[2] = value
[2];
156 element
->kinds
.fn_xi_write
.value
[3] = value
[3];
159 void sim_queue_fn_df_write (
161 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DF
),
166 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
167 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
168 element
->kind
= CGEN_FN_DF_WRITE
;
169 element
->insn_address
= CPU_PC_GET (cpu
);
170 element
->kinds
.fn_df_write
.function
= write_function
;
171 element
->kinds
.fn_df_write
.regno
= regno
;
172 element
->kinds
.fn_df_write
.value
= value
;
175 void sim_queue_fn_pc_write (
177 void (*write_function
)(SIM_CPU
*cpu
, USI
),
181 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
182 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
183 element
->kind
= CGEN_FN_PC_WRITE
;
184 element
->insn_address
= CPU_PC_GET (cpu
);
185 element
->kinds
.fn_pc_write
.function
= write_function
;
186 element
->kinds
.fn_pc_write
.value
= value
;
189 void sim_queue_mem_qi_write (SIM_CPU
*cpu
, SI address
, QI value
)
191 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
192 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
193 element
->kind
= CGEN_MEM_QI_WRITE
;
194 element
->insn_address
= CPU_PC_GET (cpu
);
195 element
->kinds
.mem_qi_write
.address
= address
;
196 element
->kinds
.mem_qi_write
.value
= value
;
199 void sim_queue_mem_hi_write (SIM_CPU
*cpu
, SI address
, HI value
)
201 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
202 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
203 element
->kind
= CGEN_MEM_HI_WRITE
;
204 element
->insn_address
= CPU_PC_GET (cpu
);
205 element
->kinds
.mem_hi_write
.address
= address
;
206 element
->kinds
.mem_hi_write
.value
= value
;
209 void sim_queue_mem_si_write (SIM_CPU
*cpu
, SI address
, SI value
)
211 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
212 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
213 element
->kind
= CGEN_MEM_SI_WRITE
;
214 element
->insn_address
= CPU_PC_GET (cpu
);
215 element
->kinds
.mem_si_write
.address
= address
;
216 element
->kinds
.mem_si_write
.value
= value
;
219 void sim_queue_mem_di_write (SIM_CPU
*cpu
, SI address
, DI value
)
221 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
222 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
223 element
->kind
= CGEN_MEM_DI_WRITE
;
224 element
->insn_address
= CPU_PC_GET (cpu
);
225 element
->kinds
.mem_di_write
.address
= address
;
226 element
->kinds
.mem_di_write
.value
= value
;
229 void sim_queue_mem_df_write (SIM_CPU
*cpu
, SI address
, DF value
)
231 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
232 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
233 element
->kind
= CGEN_MEM_DF_WRITE
;
234 element
->insn_address
= CPU_PC_GET (cpu
);
235 element
->kinds
.mem_df_write
.address
= address
;
236 element
->kinds
.mem_df_write
.value
= value
;
239 void sim_queue_mem_xi_write (SIM_CPU
*cpu
, SI address
, SI
*value
)
241 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
242 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
243 element
->kind
= CGEN_MEM_XI_WRITE
;
244 element
->insn_address
= CPU_PC_GET (cpu
);
245 element
->kinds
.mem_xi_write
.address
= address
;
246 element
->kinds
.mem_xi_write
.value
[0] = value
[0];
247 element
->kinds
.mem_xi_write
.value
[1] = value
[1];
248 element
->kinds
.mem_xi_write
.value
[2] = value
[2];
249 element
->kinds
.mem_xi_write
.value
[3] = value
[3];
252 void sim_queue_fn_mem_qi_write (
254 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, QI
),
259 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
260 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
261 element
->kind
= CGEN_FN_MEM_QI_WRITE
;
262 element
->insn_address
= CPU_PC_GET (cpu
);
263 element
->kinds
.fn_mem_qi_write
.function
= write_function
;
264 element
->kinds
.fn_mem_qi_write
.address
= address
;
265 element
->kinds
.fn_mem_qi_write
.value
= value
;
268 void sim_queue_fn_mem_hi_write (
270 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, HI
),
275 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
276 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
277 element
->kind
= CGEN_FN_MEM_HI_WRITE
;
278 element
->insn_address
= CPU_PC_GET (cpu
);
279 element
->kinds
.fn_mem_hi_write
.function
= write_function
;
280 element
->kinds
.fn_mem_hi_write
.address
= address
;
281 element
->kinds
.fn_mem_hi_write
.value
= value
;
284 void sim_queue_fn_mem_si_write (
286 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
),
291 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
292 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
293 element
->kind
= CGEN_FN_MEM_SI_WRITE
;
294 element
->insn_address
= CPU_PC_GET (cpu
);
295 element
->kinds
.fn_mem_si_write
.function
= write_function
;
296 element
->kinds
.fn_mem_si_write
.address
= address
;
297 element
->kinds
.fn_mem_si_write
.value
= value
;
300 void sim_queue_fn_mem_di_write (
302 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DI
),
307 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
308 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
309 element
->kind
= CGEN_FN_MEM_DI_WRITE
;
310 element
->insn_address
= CPU_PC_GET (cpu
);
311 element
->kinds
.fn_mem_di_write
.function
= write_function
;
312 element
->kinds
.fn_mem_di_write
.address
= address
;
313 element
->kinds
.fn_mem_di_write
.value
= value
;
316 void sim_queue_fn_mem_df_write (
318 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, DF
),
323 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
324 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
325 element
->kind
= CGEN_FN_MEM_DF_WRITE
;
326 element
->insn_address
= CPU_PC_GET (cpu
);
327 element
->kinds
.fn_mem_df_write
.function
= write_function
;
328 element
->kinds
.fn_mem_df_write
.address
= address
;
329 element
->kinds
.fn_mem_df_write
.value
= value
;
332 void sim_queue_fn_mem_xi_write (
334 void (*write_function
)(SIM_CPU
*cpu
, IADDR
, SI
, SI
*),
339 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
340 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
341 element
->kind
= CGEN_FN_MEM_XI_WRITE
;
342 element
->insn_address
= CPU_PC_GET (cpu
);
343 element
->kinds
.fn_mem_xi_write
.function
= write_function
;
344 element
->kinds
.fn_mem_xi_write
.address
= address
;
345 element
->kinds
.fn_mem_xi_write
.value
[0] = value
[0];
346 element
->kinds
.fn_mem_xi_write
.value
[1] = value
[1];
347 element
->kinds
.fn_mem_xi_write
.value
[2] = value
[2];
348 element
->kinds
.fn_mem_xi_write
.value
[3] = value
[3];
351 /* Execute a write stored on the write queue. */
353 cgen_write_queue_element_execute (SIM_CPU
*cpu
, CGEN_WRITE_QUEUE_ELEMENT
*item
)
356 switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item
))
359 *item
->kinds
.bi_write
.target
= item
->kinds
.bi_write
.value
;
362 *item
->kinds
.qi_write
.target
= item
->kinds
.qi_write
.value
;
365 *item
->kinds
.si_write
.target
= item
->kinds
.si_write
.value
;
368 *item
->kinds
.sf_write
.target
= item
->kinds
.sf_write
.value
;
371 CPU_PC_SET (cpu
, item
->kinds
.pc_write
.value
);
373 case CGEN_FN_HI_WRITE
:
374 item
->kinds
.fn_hi_write
.function (cpu
,
375 item
->kinds
.fn_hi_write
.regno
,
376 item
->kinds
.fn_hi_write
.value
);
378 case CGEN_FN_SI_WRITE
:
379 item
->kinds
.fn_si_write
.function (cpu
,
380 item
->kinds
.fn_si_write
.regno
,
381 item
->kinds
.fn_si_write
.value
);
383 case CGEN_FN_SF_WRITE
:
384 item
->kinds
.fn_sf_write
.function (cpu
,
385 item
->kinds
.fn_sf_write
.regno
,
386 item
->kinds
.fn_sf_write
.value
);
388 case CGEN_FN_DI_WRITE
:
389 item
->kinds
.fn_di_write
.function (cpu
,
390 item
->kinds
.fn_di_write
.regno
,
391 item
->kinds
.fn_di_write
.value
);
393 case CGEN_FN_DF_WRITE
:
394 item
->kinds
.fn_df_write
.function (cpu
,
395 item
->kinds
.fn_df_write
.regno
,
396 item
->kinds
.fn_df_write
.value
);
398 case CGEN_FN_XI_WRITE
:
399 item
->kinds
.fn_xi_write
.function (cpu
,
400 item
->kinds
.fn_xi_write
.regno
,
401 item
->kinds
.fn_xi_write
.value
);
403 case CGEN_FN_PC_WRITE
:
404 item
->kinds
.fn_pc_write
.function (cpu
, item
->kinds
.fn_pc_write
.value
);
406 case CGEN_MEM_QI_WRITE
:
407 pc
= item
->insn_address
;
408 SETMEMQI (cpu
, pc
, item
->kinds
.mem_qi_write
.address
,
409 item
->kinds
.mem_qi_write
.value
);
411 case CGEN_MEM_HI_WRITE
:
412 pc
= item
->insn_address
;
413 SETMEMHI (cpu
, pc
, item
->kinds
.mem_hi_write
.address
,
414 item
->kinds
.mem_hi_write
.value
);
416 case CGEN_MEM_SI_WRITE
:
417 pc
= item
->insn_address
;
418 SETMEMSI (cpu
, pc
, item
->kinds
.mem_si_write
.address
,
419 item
->kinds
.mem_si_write
.value
);
421 case CGEN_MEM_DI_WRITE
:
422 pc
= item
->insn_address
;
423 SETMEMDI (cpu
, pc
, item
->kinds
.mem_di_write
.address
,
424 item
->kinds
.mem_di_write
.value
);
426 case CGEN_MEM_DF_WRITE
:
427 pc
= item
->insn_address
;
428 SETMEMDF (cpu
, pc
, item
->kinds
.mem_df_write
.address
,
429 item
->kinds
.mem_df_write
.value
);
431 case CGEN_MEM_XI_WRITE
:
432 pc
= item
->insn_address
;
433 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
,
434 item
->kinds
.mem_xi_write
.value
[0]);
435 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 4,
436 item
->kinds
.mem_xi_write
.value
[1]);
437 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 8,
438 item
->kinds
.mem_xi_write
.value
[2]);
439 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 12,
440 item
->kinds
.mem_xi_write
.value
[3]);
442 case CGEN_FN_MEM_QI_WRITE
:
443 pc
= item
->insn_address
;
444 item
->kinds
.fn_mem_qi_write
.function (cpu
, pc
,
445 item
->kinds
.fn_mem_qi_write
.address
,
446 item
->kinds
.fn_mem_qi_write
.value
);
448 case CGEN_FN_MEM_HI_WRITE
:
449 pc
= item
->insn_address
;
450 item
->kinds
.fn_mem_hi_write
.function (cpu
, pc
,
451 item
->kinds
.fn_mem_hi_write
.address
,
452 item
->kinds
.fn_mem_hi_write
.value
);
454 case CGEN_FN_MEM_SI_WRITE
:
455 pc
= item
->insn_address
;
456 item
->kinds
.fn_mem_si_write
.function (cpu
, pc
,
457 item
->kinds
.fn_mem_si_write
.address
,
458 item
->kinds
.fn_mem_si_write
.value
);
460 case CGEN_FN_MEM_DI_WRITE
:
461 pc
= item
->insn_address
;
462 item
->kinds
.fn_mem_di_write
.function (cpu
, pc
,
463 item
->kinds
.fn_mem_di_write
.address
,
464 item
->kinds
.fn_mem_di_write
.value
);
466 case CGEN_FN_MEM_DF_WRITE
:
467 pc
= item
->insn_address
;
468 item
->kinds
.fn_mem_df_write
.function (cpu
, pc
,
469 item
->kinds
.fn_mem_df_write
.address
,
470 item
->kinds
.fn_mem_df_write
.value
);
472 case CGEN_FN_MEM_XI_WRITE
:
473 pc
= item
->insn_address
;
474 item
->kinds
.fn_mem_xi_write
.function (cpu
, pc
,
475 item
->kinds
.fn_mem_xi_write
.address
,
476 item
->kinds
.fn_mem_xi_write
.value
);
480 break; /* FIXME: for now....print message later. */
484 /* Utilities for the write queue. */
485 CGEN_WRITE_QUEUE_ELEMENT
*
486 cgen_write_queue_overflow (CGEN_WRITE_QUEUE
*q
)
488 abort (); /* FIXME: for now....print message later. */