xref: /netbsd-src/external/gpl3/gdb/dist/sim/common/cgen-par.c (revision 88241920d21b339bf319c0e979ffda80c49a2936)
1 /* Simulator parallel routines for CGEN simulators (and maybe others).
2    Copyright (C) 1999-2024 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 /* This must come before any other includes.  */
21 #include "defs.h"
22 
23 #include <stdlib.h>
24 
25 #include "sim-main.h"
26 #include "cgen-mem.h"
27 #include "cgen-par.h"
28 
29 /* Functions required by the cgen interface.  These functions add various
30    kinds of writes to the write queue.  */
31 void sim_queue_bi_write (SIM_CPU *cpu, BI *target, BI value)
32 {
33   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
34   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
35   element->kind = CGEN_BI_WRITE;
36   element->insn_address = CPU_PC_GET (cpu);
37   element->kinds.bi_write.target = target;
38   element->kinds.bi_write.value  = value;
39 }
40 
41 void sim_queue_qi_write (SIM_CPU *cpu, UQI *target, UQI value)
42 {
43   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
44   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
45   element->kind = CGEN_QI_WRITE;
46   element->insn_address = CPU_PC_GET (cpu);
47   element->kinds.qi_write.target = target;
48   element->kinds.qi_write.value  = value;
49 }
50 
51 void sim_queue_si_write (SIM_CPU *cpu, SI *target, SI value)
52 {
53   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
54   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
55   element->kind = CGEN_SI_WRITE;
56   element->insn_address = CPU_PC_GET (cpu);
57   element->kinds.si_write.target = target;
58   element->kinds.si_write.value  = value;
59 }
60 
61 void sim_queue_sf_write (SIM_CPU *cpu, SI *target, SF value)
62 {
63   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
64   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
65   element->kind = CGEN_SF_WRITE;
66   element->insn_address = CPU_PC_GET (cpu);
67   element->kinds.sf_write.target = target;
68   element->kinds.sf_write.value  = value;
69 }
70 
71 void sim_queue_pc_write (SIM_CPU *cpu, USI value)
72 {
73   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
74   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
75   element->kind = CGEN_PC_WRITE;
76   element->insn_address = CPU_PC_GET (cpu);
77   element->kinds.pc_write.value = value;
78 }
79 
80 void sim_queue_fn_hi_write (
81   SIM_CPU *cpu,
82   void (*write_function)(SIM_CPU *cpu, UINT, UHI),
83   UINT regno,
84   UHI value
85 )
86 {
87   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
88   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
89   element->kind = CGEN_FN_HI_WRITE;
90   element->insn_address = CPU_PC_GET (cpu);
91   element->kinds.fn_hi_write.function = write_function;
92   element->kinds.fn_hi_write.regno = regno;
93   element->kinds.fn_hi_write.value = value;
94 }
95 
96 void sim_queue_fn_si_write (
97   SIM_CPU *cpu,
98   void (*write_function)(SIM_CPU *cpu, UINT, USI),
99   UINT regno,
100   USI value
101 )
102 {
103   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
104   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
105   element->kind = CGEN_FN_SI_WRITE;
106   element->insn_address = CPU_PC_GET (cpu);
107   element->kinds.fn_si_write.function = write_function;
108   element->kinds.fn_si_write.regno = regno;
109   element->kinds.fn_si_write.value = value;
110 }
111 
112 void sim_queue_fn_sf_write (
113   SIM_CPU *cpu,
114   void (*write_function)(SIM_CPU *cpu, UINT, SF),
115   UINT regno,
116   SF value
117 )
118 {
119   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
120   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
121   element->kind = CGEN_FN_SF_WRITE;
122   element->insn_address = CPU_PC_GET (cpu);
123   element->kinds.fn_sf_write.function = write_function;
124   element->kinds.fn_sf_write.regno = regno;
125   element->kinds.fn_sf_write.value = value;
126 }
127 
128 void sim_queue_fn_di_write (
129   SIM_CPU *cpu,
130   void (*write_function)(SIM_CPU *cpu, UINT, DI),
131   UINT regno,
132   DI value
133 )
134 {
135   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
136   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
137   element->kind = CGEN_FN_DI_WRITE;
138   element->insn_address = CPU_PC_GET (cpu);
139   element->kinds.fn_di_write.function = write_function;
140   element->kinds.fn_di_write.regno = regno;
141   element->kinds.fn_di_write.value = value;
142 }
143 
144 void sim_queue_fn_xi_write (
145   SIM_CPU *cpu,
146   void (*write_function)(SIM_CPU *cpu, UINT, SI *),
147   UINT regno,
148   SI *value
149 )
150 {
151   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
152   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
153   element->kind = CGEN_FN_XI_WRITE;
154   element->insn_address = CPU_PC_GET (cpu);
155   element->kinds.fn_xi_write.function = write_function;
156   element->kinds.fn_xi_write.regno = regno;
157   element->kinds.fn_xi_write.value[0] = value[0];
158   element->kinds.fn_xi_write.value[1] = value[1];
159   element->kinds.fn_xi_write.value[2] = value[2];
160   element->kinds.fn_xi_write.value[3] = value[3];
161 }
162 
163 void sim_queue_fn_df_write (
164   SIM_CPU *cpu,
165   void (*write_function)(SIM_CPU *cpu, UINT, DF),
166   UINT regno,
167   DF value
168 )
169 {
170   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
171   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
172   element->kind = CGEN_FN_DF_WRITE;
173   element->insn_address = CPU_PC_GET (cpu);
174   element->kinds.fn_df_write.function = write_function;
175   element->kinds.fn_df_write.regno = regno;
176   element->kinds.fn_df_write.value = value;
177 }
178 
179 void sim_queue_fn_pc_write (
180   SIM_CPU *cpu,
181   void (*write_function)(SIM_CPU *cpu, USI),
182   USI value
183 )
184 {
185   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
186   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
187   element->kind = CGEN_FN_PC_WRITE;
188   element->insn_address = CPU_PC_GET (cpu);
189   element->kinds.fn_pc_write.function = write_function;
190   element->kinds.fn_pc_write.value = value;
191 }
192 
193 void sim_queue_mem_qi_write (SIM_CPU *cpu, SI address, QI value)
194 {
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_QI_WRITE;
198   element->insn_address = CPU_PC_GET (cpu);
199   element->kinds.mem_qi_write.address = address;
200   element->kinds.mem_qi_write.value   = value;
201 }
202 
203 void sim_queue_mem_hi_write (SIM_CPU *cpu, SI address, HI value)
204 {
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_HI_WRITE;
208   element->insn_address = CPU_PC_GET (cpu);
209   element->kinds.mem_hi_write.address = address;
210   element->kinds.mem_hi_write.value   = value;
211 }
212 
213 void sim_queue_mem_si_write (SIM_CPU *cpu, SI address, SI value)
214 {
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_SI_WRITE;
218   element->insn_address = CPU_PC_GET (cpu);
219   element->kinds.mem_si_write.address = address;
220   element->kinds.mem_si_write.value   = value;
221 }
222 
223 void sim_queue_mem_di_write (SIM_CPU *cpu, SI address, DI value)
224 {
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_DI_WRITE;
228   element->insn_address = CPU_PC_GET (cpu);
229   element->kinds.mem_di_write.address = address;
230   element->kinds.mem_di_write.value   = value;
231 }
232 
233 void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value)
234 {
235   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
236   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
237   element->kind = CGEN_MEM_DF_WRITE;
238   element->insn_address = CPU_PC_GET (cpu);
239   element->kinds.mem_df_write.address = address;
240   element->kinds.mem_df_write.value   = value;
241 }
242 
243 void sim_queue_mem_xi_write (SIM_CPU *cpu, SI address, SI *value)
244 {
245   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
246   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
247   element->kind = CGEN_MEM_XI_WRITE;
248   element->insn_address = CPU_PC_GET (cpu);
249   element->kinds.mem_xi_write.address = address;
250   element->kinds.mem_xi_write.value[0] = value[0];
251   element->kinds.mem_xi_write.value[1] = value[1];
252   element->kinds.mem_xi_write.value[2] = value[2];
253   element->kinds.mem_xi_write.value[3] = value[3];
254 }
255 
256 void sim_queue_fn_mem_qi_write (
257   SIM_CPU *cpu,
258   void (*write_function)(SIM_CPU *cpu, IADDR, SI, QI),
259   SI address,
260   QI value
261 )
262 {
263   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
264   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
265   element->kind = CGEN_FN_MEM_QI_WRITE;
266   element->insn_address = CPU_PC_GET (cpu);
267   element->kinds.fn_mem_qi_write.function = write_function;
268   element->kinds.fn_mem_qi_write.address = address;
269   element->kinds.fn_mem_qi_write.value   = value;
270 }
271 
272 void sim_queue_fn_mem_hi_write (
273   SIM_CPU *cpu,
274   void (*write_function)(SIM_CPU *cpu, IADDR, SI, HI),
275   SI address,
276   HI value
277 )
278 {
279   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
280   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
281   element->kind = CGEN_FN_MEM_HI_WRITE;
282   element->insn_address = CPU_PC_GET (cpu);
283   element->kinds.fn_mem_hi_write.function = write_function;
284   element->kinds.fn_mem_hi_write.address = address;
285   element->kinds.fn_mem_hi_write.value   = value;
286 }
287 
288 void sim_queue_fn_mem_si_write (
289   SIM_CPU *cpu,
290   void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI),
291   SI address,
292   SI value
293 )
294 {
295   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
296   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
297   element->kind = CGEN_FN_MEM_SI_WRITE;
298   element->insn_address = CPU_PC_GET (cpu);
299   element->kinds.fn_mem_si_write.function = write_function;
300   element->kinds.fn_mem_si_write.address = address;
301   element->kinds.fn_mem_si_write.value   = value;
302 }
303 
304 void sim_queue_fn_mem_di_write (
305   SIM_CPU *cpu,
306   void (*write_function)(SIM_CPU *cpu, IADDR, SI, DI),
307   SI address,
308   DI value
309 )
310 {
311   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
312   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
313   element->kind = CGEN_FN_MEM_DI_WRITE;
314   element->insn_address = CPU_PC_GET (cpu);
315   element->kinds.fn_mem_di_write.function = write_function;
316   element->kinds.fn_mem_di_write.address = address;
317   element->kinds.fn_mem_di_write.value   = value;
318 }
319 
320 void sim_queue_fn_mem_df_write (
321   SIM_CPU *cpu,
322   void (*write_function)(SIM_CPU *cpu, IADDR, SI, DF),
323   SI address,
324   DF value
325 )
326 {
327   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
328   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
329   element->kind = CGEN_FN_MEM_DF_WRITE;
330   element->insn_address = CPU_PC_GET (cpu);
331   element->kinds.fn_mem_df_write.function = write_function;
332   element->kinds.fn_mem_df_write.address = address;
333   element->kinds.fn_mem_df_write.value   = value;
334 }
335 
336 void sim_queue_fn_mem_xi_write (
337   SIM_CPU *cpu,
338   void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI *),
339   SI address,
340   SI *value
341 )
342 {
343   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
344   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
345   element->kind = CGEN_FN_MEM_XI_WRITE;
346   element->insn_address = CPU_PC_GET (cpu);
347   element->kinds.fn_mem_xi_write.function = write_function;
348   element->kinds.fn_mem_xi_write.address = address;
349   element->kinds.fn_mem_xi_write.value[0] = value[0];
350   element->kinds.fn_mem_xi_write.value[1] = value[1];
351   element->kinds.fn_mem_xi_write.value[2] = value[2];
352   element->kinds.fn_mem_xi_write.value[3] = value[3];
353 }
354 
355 /* Execute a write stored on the write queue.  */
356 void
357 cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item)
358 {
359   IADDR pc;
360   switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
361     {
362     case CGEN_BI_WRITE:
363       *item->kinds.bi_write.target = item->kinds.bi_write.value;
364       break;
365     case CGEN_QI_WRITE:
366       *item->kinds.qi_write.target = item->kinds.qi_write.value;
367       break;
368     case CGEN_SI_WRITE:
369       *item->kinds.si_write.target = item->kinds.si_write.value;
370       break;
371     case CGEN_SF_WRITE:
372       *item->kinds.sf_write.target = item->kinds.sf_write.value;
373       break;
374     case CGEN_PC_WRITE:
375       CPU_PC_SET (cpu, item->kinds.pc_write.value);
376       break;
377     case CGEN_FN_HI_WRITE:
378       item->kinds.fn_hi_write.function (cpu,
379 					item->kinds.fn_hi_write.regno,
380 					item->kinds.fn_hi_write.value);
381       break;
382     case CGEN_FN_SI_WRITE:
383       item->kinds.fn_si_write.function (cpu,
384 					item->kinds.fn_si_write.regno,
385 					item->kinds.fn_si_write.value);
386       break;
387     case CGEN_FN_SF_WRITE:
388       item->kinds.fn_sf_write.function (cpu,
389 					item->kinds.fn_sf_write.regno,
390 					item->kinds.fn_sf_write.value);
391       break;
392     case CGEN_FN_DI_WRITE:
393       item->kinds.fn_di_write.function (cpu,
394 					item->kinds.fn_di_write.regno,
395 					item->kinds.fn_di_write.value);
396       break;
397     case CGEN_FN_DF_WRITE:
398       item->kinds.fn_df_write.function (cpu,
399 					item->kinds.fn_df_write.regno,
400 					item->kinds.fn_df_write.value);
401       break;
402     case CGEN_FN_XI_WRITE:
403       item->kinds.fn_xi_write.function (cpu,
404 					item->kinds.fn_xi_write.regno,
405 					item->kinds.fn_xi_write.value);
406       break;
407     case CGEN_FN_PC_WRITE:
408       item->kinds.fn_pc_write.function (cpu, item->kinds.fn_pc_write.value);
409       break;
410     case CGEN_MEM_QI_WRITE:
411       pc = item->insn_address;
412       SETMEMQI (cpu, pc, item->kinds.mem_qi_write.address,
413 		item->kinds.mem_qi_write.value);
414       break;
415     case CGEN_MEM_HI_WRITE:
416       pc = item->insn_address;
417       SETMEMHI (cpu, pc, item->kinds.mem_hi_write.address,
418 		item->kinds.mem_hi_write.value);
419       break;
420     case CGEN_MEM_SI_WRITE:
421       pc = item->insn_address;
422       SETMEMSI (cpu, pc, item->kinds.mem_si_write.address,
423 		item->kinds.mem_si_write.value);
424       break;
425     case CGEN_MEM_DI_WRITE:
426       pc = item->insn_address;
427       SETMEMDI (cpu, pc, item->kinds.mem_di_write.address,
428 		item->kinds.mem_di_write.value);
429       break;
430     case CGEN_MEM_DF_WRITE:
431       pc = item->insn_address;
432       SETMEMDF (cpu, pc, item->kinds.mem_df_write.address,
433 		item->kinds.mem_df_write.value);
434       break;
435     case CGEN_MEM_XI_WRITE:
436       pc = item->insn_address;
437       SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address,
438 		item->kinds.mem_xi_write.value[0]);
439       SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 4,
440 		item->kinds.mem_xi_write.value[1]);
441       SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 8,
442 		item->kinds.mem_xi_write.value[2]);
443       SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 12,
444 		item->kinds.mem_xi_write.value[3]);
445       break;
446     case CGEN_FN_MEM_QI_WRITE:
447       pc = item->insn_address;
448       item->kinds.fn_mem_qi_write.function (cpu, pc,
449 					    item->kinds.fn_mem_qi_write.address,
450 					    item->kinds.fn_mem_qi_write.value);
451       break;
452     case CGEN_FN_MEM_HI_WRITE:
453       pc = item->insn_address;
454       item->kinds.fn_mem_hi_write.function (cpu, pc,
455 					    item->kinds.fn_mem_hi_write.address,
456 					    item->kinds.fn_mem_hi_write.value);
457       break;
458     case CGEN_FN_MEM_SI_WRITE:
459       pc = item->insn_address;
460       item->kinds.fn_mem_si_write.function (cpu, pc,
461 					    item->kinds.fn_mem_si_write.address,
462 					    item->kinds.fn_mem_si_write.value);
463       break;
464     case CGEN_FN_MEM_DI_WRITE:
465       pc = item->insn_address;
466       item->kinds.fn_mem_di_write.function (cpu, pc,
467 					    item->kinds.fn_mem_di_write.address,
468 					    item->kinds.fn_mem_di_write.value);
469       break;
470     case CGEN_FN_MEM_DF_WRITE:
471       pc = item->insn_address;
472       item->kinds.fn_mem_df_write.function (cpu, pc,
473 					    item->kinds.fn_mem_df_write.address,
474 					    item->kinds.fn_mem_df_write.value);
475       break;
476     case CGEN_FN_MEM_XI_WRITE:
477       pc = item->insn_address;
478       item->kinds.fn_mem_xi_write.function (cpu, pc,
479 					    item->kinds.fn_mem_xi_write.address,
480 					    item->kinds.fn_mem_xi_write.value);
481       break;
482     default:
483       abort ();
484       break; /* FIXME: for now....print message later.  */
485     }
486 }
487 
488 /* Utilities for the write queue.  */
489 CGEN_WRITE_QUEUE_ELEMENT *
490 cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q)
491 {
492   abort (); /* FIXME: for now....print message later.  */
493   return 0;
494 }
495