import gdb-1999-10-18 snapshot
[platform/upstream/binutils.git] / 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.
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->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->kinds.qi_write.target = target;
42   element->kinds.qi_write.value  = value;
43 }
44
45 void sim_queue_si_write (SIM_CPU *cpu, SI *target, SI value)
46 {
47   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
48   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
49   element->kind = CGEN_SI_WRITE;
50   element->kinds.si_write.target = target;
51   element->kinds.si_write.value  = value;
52 }
53
54 void sim_queue_sf_write (SIM_CPU *cpu, SI *target, SF value)
55 {
56   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
57   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
58   element->kind = CGEN_SF_WRITE;
59   element->kinds.sf_write.target = target;
60   element->kinds.sf_write.value  = value;
61 }
62
63 void sim_queue_pc_write (SIM_CPU *cpu, USI value)
64 {
65   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
66   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
67   element->kind = CGEN_PC_WRITE;
68   element->kinds.pc_write.value = value;
69 }
70
71 void sim_queue_fn_hi_write (
72   SIM_CPU *cpu,
73   void (*write_function)(SIM_CPU *cpu, UINT, UHI),
74   UINT regno,
75   UHI value
76 )
77 {
78   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
79   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
80   element->kind = CGEN_FN_HI_WRITE;
81   element->kinds.fn_hi_write.function = write_function;
82   element->kinds.fn_hi_write.regno = regno;
83   element->kinds.fn_hi_write.value = value;
84 }
85
86 void sim_queue_fn_si_write (
87   SIM_CPU *cpu,
88   void (*write_function)(SIM_CPU *cpu, UINT, USI),
89   UINT regno,
90   SI value
91 )
92 {
93   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
94   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
95   element->kind = CGEN_FN_SI_WRITE;
96   element->kinds.fn_si_write.function = write_function;
97   element->kinds.fn_si_write.regno = regno;
98   element->kinds.fn_si_write.value = value;
99 }
100
101 void sim_queue_fn_di_write (
102   SIM_CPU *cpu,
103   void (*write_function)(SIM_CPU *cpu, UINT, DI),
104   UINT regno,
105   DI value
106 )
107 {
108   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
109   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
110   element->kind = CGEN_FN_DI_WRITE;
111   element->kinds.fn_di_write.function = write_function;
112   element->kinds.fn_di_write.regno = regno;
113   element->kinds.fn_di_write.value = value;
114 }
115
116 void sim_queue_fn_df_write (
117   SIM_CPU *cpu,
118   void (*write_function)(SIM_CPU *cpu, UINT, DI),
119   UINT regno,
120   DF value
121 )
122 {
123   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
124   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
125   element->kind = CGEN_FN_DF_WRITE;
126   element->kinds.fn_df_write.function = write_function;
127   element->kinds.fn_df_write.regno = regno;
128   element->kinds.fn_df_write.value = value;
129 }
130
131 void sim_queue_mem_qi_write (SIM_CPU *cpu, SI address, QI value)
132 {
133   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
134   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
135   element->kind = CGEN_MEM_QI_WRITE;
136   element->kinds.mem_qi_write.address = address;
137   element->kinds.mem_qi_write.value   = value;
138 }
139
140 void sim_queue_mem_hi_write (SIM_CPU *cpu, SI address, HI value)
141 {
142   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
143   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
144   element->kind = CGEN_MEM_HI_WRITE;
145   element->kinds.mem_hi_write.address = address;
146   element->kinds.mem_hi_write.value   = value;
147 }
148
149 void sim_queue_mem_si_write (SIM_CPU *cpu, SI address, SI value)
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_MEM_SI_WRITE;
154   element->kinds.mem_si_write.address = address;
155   element->kinds.mem_si_write.value   = value;
156 }
157
158 void sim_queue_mem_di_write (SIM_CPU *cpu, SI address, DI value)
159 {
160   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
161   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
162   element->kind = CGEN_MEM_DI_WRITE;
163   element->kinds.mem_di_write.address = address;
164   element->kinds.mem_di_write.value   = value;
165 }
166
167 void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value)
168 {
169   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
170   CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
171   element->kind = CGEN_MEM_DF_WRITE;
172   element->kinds.mem_df_write.address = address;
173   element->kinds.mem_df_write.value   = value;
174 }
175
176 /* Execute a write stored on the write queue.  */
177 void
178 cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item)
179 {
180   IADDR pc;
181   switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
182     {
183     case CGEN_BI_WRITE:
184       *item->kinds.bi_write.target = item->kinds.bi_write.value;
185       break;
186     case CGEN_QI_WRITE:
187       *item->kinds.qi_write.target = item->kinds.qi_write.value;
188       break;
189     case CGEN_SI_WRITE:
190       *item->kinds.si_write.target = item->kinds.si_write.value;
191       break;
192     case CGEN_SF_WRITE:
193       *item->kinds.sf_write.target = item->kinds.sf_write.value;
194       break;
195     case CGEN_PC_WRITE:
196       CPU_PC_SET (cpu, item->kinds.pc_write.value);
197       break;
198     case CGEN_FN_HI_WRITE:
199       item->kinds.fn_hi_write.function (cpu,
200                                         item->kinds.fn_hi_write.regno,
201                                         item->kinds.fn_hi_write.value);
202       break;
203     case CGEN_FN_SI_WRITE:
204       item->kinds.fn_si_write.function (cpu,
205                                         item->kinds.fn_si_write.regno,
206                                         item->kinds.fn_si_write.value);
207       break;
208     case CGEN_FN_DI_WRITE:
209       item->kinds.fn_di_write.function (cpu,
210                                         item->kinds.fn_di_write.regno,
211                                         item->kinds.fn_di_write.value);
212       break;
213     case CGEN_FN_DF_WRITE:
214       item->kinds.fn_df_write.function (cpu,
215                                         item->kinds.fn_df_write.regno,
216                                         item->kinds.fn_df_write.value);
217       break;
218     case CGEN_MEM_QI_WRITE:
219       pc = CPU_PC_GET (cpu);
220       SETMEMQI (cpu, pc, item->kinds.mem_qi_write.address,
221                 item->kinds.mem_qi_write.value);
222       break;
223     case CGEN_MEM_HI_WRITE:
224       pc = CPU_PC_GET (cpu);
225       SETMEMHI (cpu, pc, item->kinds.mem_hi_write.address,
226                 item->kinds.mem_hi_write.value);
227       break;
228     case CGEN_MEM_SI_WRITE:
229       pc = CPU_PC_GET (cpu);
230       SETMEMSI (cpu, pc, item->kinds.mem_si_write.address,
231                 item->kinds.mem_si_write.value);
232       break;
233     case CGEN_MEM_DI_WRITE:
234       pc = CPU_PC_GET (cpu);
235       SETMEMDI (cpu, pc, item->kinds.mem_di_write.address,
236                 item->kinds.mem_di_write.value);
237       break;
238     case CGEN_MEM_DF_WRITE:
239       pc = CPU_PC_GET (cpu);
240       SETMEMDF (cpu, pc, item->kinds.mem_df_write.address,
241                 item->kinds.mem_df_write.value);
242       break;
243     default:
244       break; /* FIXME: for now....print message later.  */
245     }
246 }
247
248 /* Utilities for the write queue.  */
249 CGEN_WRITE_QUEUE_ELEMENT *
250 cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q)
251 {
252   abort (); /* FIXME: for now....print message later.  */
253   return 0;
254 }