]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/cgen-par.c
1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2 Copyright (C) 1999 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_di_write (
110 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DI
),
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_DI_WRITE
;
118 element
->insn_address
= CPU_PC_GET (cpu
);
119 element
->kinds
.fn_di_write
.function
= write_function
;
120 element
->kinds
.fn_di_write
.regno
= regno
;
121 element
->kinds
.fn_di_write
.value
= value
;
124 void sim_queue_fn_xi_write (
126 void (*write_function
)(SIM_CPU
*cpu
, UINT
, SI
*),
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_XI_WRITE
;
134 element
->insn_address
= CPU_PC_GET (cpu
);
135 element
->kinds
.fn_xi_write
.function
= write_function
;
136 element
->kinds
.fn_xi_write
.regno
= regno
;
137 element
->kinds
.fn_xi_write
.value
[0] = value
[0];
138 element
->kinds
.fn_xi_write
.value
[1] = value
[1];
139 element
->kinds
.fn_xi_write
.value
[2] = value
[2];
140 element
->kinds
.fn_xi_write
.value
[3] = value
[3];
143 void sim_queue_fn_df_write (
145 void (*write_function
)(SIM_CPU
*cpu
, UINT
, DI
),
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_DF_WRITE
;
153 element
->insn_address
= CPU_PC_GET (cpu
);
154 element
->kinds
.fn_df_write
.function
= write_function
;
155 element
->kinds
.fn_df_write
.regno
= regno
;
156 element
->kinds
.fn_df_write
.value
= value
;
159 void sim_queue_fn_pc_write (
161 void (*write_function
)(SIM_CPU
*cpu
, USI
),
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_PC_WRITE
;
168 element
->insn_address
= CPU_PC_GET (cpu
);
169 element
->kinds
.fn_pc_write
.function
= write_function
;
170 element
->kinds
.fn_pc_write
.value
= value
;
173 void sim_queue_mem_qi_write (SIM_CPU
*cpu
, SI address
, QI value
)
175 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
176 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
177 element
->kind
= CGEN_MEM_QI_WRITE
;
178 element
->insn_address
= CPU_PC_GET (cpu
);
179 element
->kinds
.mem_qi_write
.address
= address
;
180 element
->kinds
.mem_qi_write
.value
= value
;
183 void sim_queue_mem_hi_write (SIM_CPU
*cpu
, SI address
, HI value
)
185 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (cpu
);
186 CGEN_WRITE_QUEUE_ELEMENT
*element
= CGEN_WRITE_QUEUE_NEXT (q
);
187 element
->kind
= CGEN_MEM_HI_WRITE
;
188 element
->insn_address
= CPU_PC_GET (cpu
);
189 element
->kinds
.mem_hi_write
.address
= address
;
190 element
->kinds
.mem_hi_write
.value
= value
;
193 void sim_queue_mem_si_write (SIM_CPU
*cpu
, SI address
, SI 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_SI_WRITE
;
198 element
->insn_address
= CPU_PC_GET (cpu
);
199 element
->kinds
.mem_si_write
.address
= address
;
200 element
->kinds
.mem_si_write
.value
= value
;
203 void sim_queue_mem_di_write (SIM_CPU
*cpu
, SI address
, DI 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_DI_WRITE
;
208 element
->insn_address
= CPU_PC_GET (cpu
);
209 element
->kinds
.mem_di_write
.address
= address
;
210 element
->kinds
.mem_di_write
.value
= value
;
213 void sim_queue_mem_df_write (SIM_CPU
*cpu
, SI address
, DF 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_DF_WRITE
;
218 element
->insn_address
= CPU_PC_GET (cpu
);
219 element
->kinds
.mem_df_write
.address
= address
;
220 element
->kinds
.mem_df_write
.value
= value
;
223 void sim_queue_mem_xi_write (SIM_CPU
*cpu
, SI address
, SI
*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_XI_WRITE
;
228 element
->insn_address
= CPU_PC_GET (cpu
);
229 element
->kinds
.mem_xi_write
.address
= address
;
230 element
->kinds
.mem_xi_write
.value
[0] = value
[0];
231 element
->kinds
.mem_xi_write
.value
[1] = value
[1];
232 element
->kinds
.mem_xi_write
.value
[2] = value
[2];
233 element
->kinds
.mem_xi_write
.value
[3] = value
[3];
236 /* Execute a write stored on the write queue. */
238 cgen_write_queue_element_execute (SIM_CPU
*cpu
, CGEN_WRITE_QUEUE_ELEMENT
*item
)
241 switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item
))
244 *item
->kinds
.bi_write
.target
= item
->kinds
.bi_write
.value
;
247 *item
->kinds
.qi_write
.target
= item
->kinds
.qi_write
.value
;
250 *item
->kinds
.si_write
.target
= item
->kinds
.si_write
.value
;
253 *item
->kinds
.sf_write
.target
= item
->kinds
.sf_write
.value
;
256 CPU_PC_SET (cpu
, item
->kinds
.pc_write
.value
);
258 case CGEN_FN_HI_WRITE
:
259 item
->kinds
.fn_hi_write
.function (cpu
,
260 item
->kinds
.fn_hi_write
.regno
,
261 item
->kinds
.fn_hi_write
.value
);
263 case CGEN_FN_SI_WRITE
:
264 item
->kinds
.fn_si_write
.function (cpu
,
265 item
->kinds
.fn_si_write
.regno
,
266 item
->kinds
.fn_si_write
.value
);
268 case CGEN_FN_DI_WRITE
:
269 item
->kinds
.fn_di_write
.function (cpu
,
270 item
->kinds
.fn_di_write
.regno
,
271 item
->kinds
.fn_di_write
.value
);
273 case CGEN_FN_DF_WRITE
:
274 item
->kinds
.fn_df_write
.function (cpu
,
275 item
->kinds
.fn_df_write
.regno
,
276 item
->kinds
.fn_df_write
.value
);
278 case CGEN_FN_XI_WRITE
:
279 item
->kinds
.fn_xi_write
.function (cpu
,
280 item
->kinds
.fn_xi_write
.regno
,
281 item
->kinds
.fn_xi_write
.value
);
283 case CGEN_FN_PC_WRITE
:
284 item
->kinds
.fn_pc_write
.function (cpu
, item
->kinds
.fn_pc_write
.value
);
286 case CGEN_MEM_QI_WRITE
:
287 pc
= item
->insn_address
;
288 SETMEMQI (cpu
, pc
, item
->kinds
.mem_qi_write
.address
,
289 item
->kinds
.mem_qi_write
.value
);
291 case CGEN_MEM_HI_WRITE
:
292 pc
= item
->insn_address
;
293 SETMEMHI (cpu
, pc
, item
->kinds
.mem_hi_write
.address
,
294 item
->kinds
.mem_hi_write
.value
);
296 case CGEN_MEM_SI_WRITE
:
297 pc
= item
->insn_address
;
298 SETMEMSI (cpu
, pc
, item
->kinds
.mem_si_write
.address
,
299 item
->kinds
.mem_si_write
.value
);
301 case CGEN_MEM_DI_WRITE
:
302 pc
= item
->insn_address
;
303 SETMEMDI (cpu
, pc
, item
->kinds
.mem_di_write
.address
,
304 item
->kinds
.mem_di_write
.value
);
306 case CGEN_MEM_DF_WRITE
:
307 pc
= item
->insn_address
;
308 SETMEMDF (cpu
, pc
, item
->kinds
.mem_df_write
.address
,
309 item
->kinds
.mem_df_write
.value
);
311 case CGEN_MEM_XI_WRITE
:
312 pc
= item
->insn_address
;
313 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
,
314 item
->kinds
.mem_xi_write
.value
[0]);
315 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 4,
316 item
->kinds
.mem_xi_write
.value
[1]);
317 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 8,
318 item
->kinds
.mem_xi_write
.value
[2]);
319 SETMEMSI (cpu
, pc
, item
->kinds
.mem_xi_write
.address
+ 12,
320 item
->kinds
.mem_xi_write
.value
[3]);
323 break; /* FIXME: for now....print message later. */
327 /* Utilities for the write queue. */
328 CGEN_WRITE_QUEUE_ELEMENT
*
329 cgen_write_queue_overflow (CGEN_WRITE_QUEUE
*q
)
331 abort (); /* FIXME: for now....print message later. */