74a8f3316b7829cd204045f0426b62696eb49b85
[external/binutils.git] / sim / common / cgen-par.c
1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2    Copyright (C) 1999, 2000, 2007 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4
5 This file is part of the GNU instruction set simulator.
6
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)
10 any later version.
11
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.
16
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.  */
20
21 #include "sim-main.h"
22 #include "cgen-mem.h"
23 #include "cgen-par.h"
24
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)
28 {
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;
35 }
36
37 void sim_queue_qi_write (SIM_CPU *cpu, UQI *target, UQI value)
38 {
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;
45 }
46
47 void sim_queue_si_write (SIM_CPU *cpu, SI *target, SI value)
48 {
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;
55 }
56
57 void sim_queue_sf_write (SIM_CPU *cpu, SI *target, SF value)
58 {
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;
65 }
66
67 void sim_queue_pc_write (SIM_CPU *cpu, USI value)
68 {
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;
74 }
75
76 void sim_queue_fn_hi_write (
77   SIM_CPU *cpu,
78   void (*write_function)(SIM_CPU *cpu, UINT, UHI),
79   UINT regno,
80   UHI value
81 )
82 {
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;
90 }
91
92 void sim_queue_fn_si_write (
93   SIM_CPU *cpu,
94   void (*write_function)(SIM_CPU *cpu, UINT, USI),
95   UINT regno,
96   USI value
97 )
98 {
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;
106 }
107
108 void sim_queue_fn_sf_write (
109   SIM_CPU *cpu,
110   void (*write_function)(SIM_CPU *cpu, UINT, SF),
111   UINT regno,
112   SF value
113 )
114 {
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;
122 }
123
124 void sim_queue_fn_di_write (
125   SIM_CPU *cpu,
126   void (*write_function)(SIM_CPU *cpu, UINT, DI),
127   UINT regno,
128   DI value
129 )
130 {
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;
138 }
139
140 void sim_queue_fn_xi_write (
141   SIM_CPU *cpu,
142   void (*write_function)(SIM_CPU *cpu, UINT, SI *),
143   UINT regno,
144   SI *value
145 )
146 {
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];
157 }
158
159 void sim_queue_fn_df_write (
160   SIM_CPU *cpu,
161   void (*write_function)(SIM_CPU *cpu, UINT, DF),
162   UINT regno,
163   DF value
164 )
165 {
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;
173 }
174
175 void sim_queue_fn_pc_write (
176   SIM_CPU *cpu,
177   void (*write_function)(SIM_CPU *cpu, USI),
178   USI value
179 )
180 {
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;
187 }
188
189 void sim_queue_mem_qi_write (SIM_CPU *cpu, SI address, QI value)
190 {
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;
197 }
198
199 void sim_queue_mem_hi_write (SIM_CPU *cpu, SI address, HI value)
200 {
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;
207 }
208
209 void sim_queue_mem_si_write (SIM_CPU *cpu, SI address, SI value)
210 {
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;
217 }
218
219 void sim_queue_mem_di_write (SIM_CPU *cpu, SI address, DI value)
220 {
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;
227 }
228
229 void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value)
230 {
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;
237 }
238
239 void sim_queue_mem_xi_write (SIM_CPU *cpu, SI address, SI *value)
240 {
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];
250 }
251
252 void sim_queue_fn_mem_qi_write (
253   SIM_CPU *cpu,
254   void (*write_function)(SIM_CPU *cpu, IADDR, SI, QI),
255   SI address,
256   QI value
257 )
258 {
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;
266 }
267
268 void sim_queue_fn_mem_hi_write (
269   SIM_CPU *cpu,
270   void (*write_function)(SIM_CPU *cpu, IADDR, SI, HI),
271   SI address,
272   HI value
273 )
274 {
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;
282 }
283
284 void sim_queue_fn_mem_si_write (
285   SIM_CPU *cpu,
286   void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI),
287   SI address,
288   SI value
289 )
290 {
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;
298 }
299
300 void sim_queue_fn_mem_di_write (
301   SIM_CPU *cpu,
302   void (*write_function)(SIM_CPU *cpu, IADDR, SI, DI),
303   SI address,
304   DI value
305 )
306 {
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;
314 }
315
316 void sim_queue_fn_mem_df_write (
317   SIM_CPU *cpu,
318   void (*write_function)(SIM_CPU *cpu, IADDR, SI, DF),
319   SI address,
320   DF value
321 )
322 {
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;
330 }
331
332 void sim_queue_fn_mem_xi_write (
333   SIM_CPU *cpu,
334   void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI *),
335   SI address,
336   SI *value
337 )
338 {
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];
349 }
350
351 /* Execute a write stored on the write queue.  */
352 void
353 cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item)
354 {
355   IADDR pc;
356   switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
357     {
358     case CGEN_BI_WRITE:
359       *item->kinds.bi_write.target = item->kinds.bi_write.value;
360       break;
361     case CGEN_QI_WRITE:
362       *item->kinds.qi_write.target = item->kinds.qi_write.value;
363       break;
364     case CGEN_SI_WRITE:
365       *item->kinds.si_write.target = item->kinds.si_write.value;
366       break;
367     case CGEN_SF_WRITE:
368       *item->kinds.sf_write.target = item->kinds.sf_write.value;
369       break;
370     case CGEN_PC_WRITE:
371       CPU_PC_SET (cpu, item->kinds.pc_write.value);
372       break;
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);
377       break;
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);
382       break;
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);
387       break;
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);
392       break;
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);
397       break;
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);
402       break;
403     case CGEN_FN_PC_WRITE:
404       item->kinds.fn_pc_write.function (cpu, item->kinds.fn_pc_write.value);
405       break;
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);
410       break;
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);
415       break;
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);
420       break;
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);
425       break;
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);
430       break;
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]);
441       break;
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);
447       break;
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);
453       break;
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);
459       break;
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);
465       break;
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);
471       break;
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);
477       break;
478     default:
479       abort ();
480       break; /* FIXME: for now....print message later.  */
481     }
482 }
483
484 /* Utilities for the write queue.  */
485 CGEN_WRITE_QUEUE_ELEMENT *
486 cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q)
487 {
488   abort (); /* FIXME: for now....print message later.  */
489   return 0;
490 }