daily update
[external/binutils.git] / sim / common / cgen-par.c
1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2    Copyright (C) 1999, 2000, 2007, 2008 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 3 of the License, or
10 (at your option) 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
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "sim-main.h"
21 #include "cgen-mem.h"
22 #include "cgen-par.h"
23
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)
27 {
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;
34 }
35
36 void sim_queue_qi_write (SIM_CPU *cpu, UQI *target, UQI value)
37 {
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;
44 }
45
46 void sim_queue_si_write (SIM_CPU *cpu, SI *target, SI value)
47 {
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;
54 }
55
56 void sim_queue_sf_write (SIM_CPU *cpu, SI *target, SF value)
57 {
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;
64 }
65
66 void sim_queue_pc_write (SIM_CPU *cpu, USI value)
67 {
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;
73 }
74
75 void sim_queue_fn_hi_write (
76   SIM_CPU *cpu,
77   void (*write_function)(SIM_CPU *cpu, UINT, UHI),
78   UINT regno,
79   UHI value
80 )
81 {
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;
89 }
90
91 void sim_queue_fn_si_write (
92   SIM_CPU *cpu,
93   void (*write_function)(SIM_CPU *cpu, UINT, USI),
94   UINT regno,
95   USI value
96 )
97 {
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;
105 }
106
107 void sim_queue_fn_sf_write (
108   SIM_CPU *cpu,
109   void (*write_function)(SIM_CPU *cpu, UINT, SF),
110   UINT regno,
111   SF value
112 )
113 {
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;
121 }
122
123 void sim_queue_fn_di_write (
124   SIM_CPU *cpu,
125   void (*write_function)(SIM_CPU *cpu, UINT, DI),
126   UINT regno,
127   DI value
128 )
129 {
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;
137 }
138
139 void sim_queue_fn_xi_write (
140   SIM_CPU *cpu,
141   void (*write_function)(SIM_CPU *cpu, UINT, SI *),
142   UINT regno,
143   SI *value
144 )
145 {
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];
156 }
157
158 void sim_queue_fn_df_write (
159   SIM_CPU *cpu,
160   void (*write_function)(SIM_CPU *cpu, UINT, DF),
161   UINT regno,
162   DF value
163 )
164 {
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;
172 }
173
174 void sim_queue_fn_pc_write (
175   SIM_CPU *cpu,
176   void (*write_function)(SIM_CPU *cpu, USI),
177   USI value
178 )
179 {
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;
186 }
187
188 void sim_queue_mem_qi_write (SIM_CPU *cpu, SI address, QI value)
189 {
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;
196 }
197
198 void sim_queue_mem_hi_write (SIM_CPU *cpu, SI address, HI value)
199 {
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;
206 }
207
208 void sim_queue_mem_si_write (SIM_CPU *cpu, SI address, SI value)
209 {
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;
216 }
217
218 void sim_queue_mem_di_write (SIM_CPU *cpu, SI address, DI value)
219 {
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;
226 }
227
228 void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value)
229 {
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;
236 }
237
238 void sim_queue_mem_xi_write (SIM_CPU *cpu, SI address, SI *value)
239 {
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];
249 }
250
251 void sim_queue_fn_mem_qi_write (
252   SIM_CPU *cpu,
253   void (*write_function)(SIM_CPU *cpu, IADDR, SI, QI),
254   SI address,
255   QI value
256 )
257 {
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;
265 }
266
267 void sim_queue_fn_mem_hi_write (
268   SIM_CPU *cpu,
269   void (*write_function)(SIM_CPU *cpu, IADDR, SI, HI),
270   SI address,
271   HI value
272 )
273 {
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;
281 }
282
283 void sim_queue_fn_mem_si_write (
284   SIM_CPU *cpu,
285   void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI),
286   SI address,
287   SI value
288 )
289 {
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;
297 }
298
299 void sim_queue_fn_mem_di_write (
300   SIM_CPU *cpu,
301   void (*write_function)(SIM_CPU *cpu, IADDR, SI, DI),
302   SI address,
303   DI value
304 )
305 {
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;
313 }
314
315 void sim_queue_fn_mem_df_write (
316   SIM_CPU *cpu,
317   void (*write_function)(SIM_CPU *cpu, IADDR, SI, DF),
318   SI address,
319   DF value
320 )
321 {
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;
329 }
330
331 void sim_queue_fn_mem_xi_write (
332   SIM_CPU *cpu,
333   void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI *),
334   SI address,
335   SI *value
336 )
337 {
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];
348 }
349
350 /* Execute a write stored on the write queue.  */
351 void
352 cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item)
353 {
354   IADDR pc;
355   switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
356     {
357     case CGEN_BI_WRITE:
358       *item->kinds.bi_write.target = item->kinds.bi_write.value;
359       break;
360     case CGEN_QI_WRITE:
361       *item->kinds.qi_write.target = item->kinds.qi_write.value;
362       break;
363     case CGEN_SI_WRITE:
364       *item->kinds.si_write.target = item->kinds.si_write.value;
365       break;
366     case CGEN_SF_WRITE:
367       *item->kinds.sf_write.target = item->kinds.sf_write.value;
368       break;
369     case CGEN_PC_WRITE:
370       CPU_PC_SET (cpu, item->kinds.pc_write.value);
371       break;
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);
376       break;
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);
381       break;
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);
386       break;
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);
391       break;
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);
396       break;
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);
401       break;
402     case CGEN_FN_PC_WRITE:
403       item->kinds.fn_pc_write.function (cpu, item->kinds.fn_pc_write.value);
404       break;
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);
409       break;
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);
414       break;
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);
419       break;
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);
424       break;
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);
429       break;
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]);
440       break;
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);
446       break;
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);
452       break;
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);
458       break;
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);
464       break;
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);
470       break;
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);
476       break;
477     default:
478       abort ();
479       break; /* FIXME: for now....print message later.  */
480     }
481 }
482
483 /* Utilities for the write queue.  */
484 CGEN_WRITE_QUEUE_ELEMENT *
485 cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q)
486 {
487   abort (); /* FIXME: for now....print message later.  */
488   return 0;
489 }