1 /* Simulator header for cgen parallel support.
2    Copyright (C) 1999, 2000, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4    Contributed by Cygnus Solutions.
5 
6 This file is part of the GNU instruction set simulator.
7 
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #ifndef CGEN_PAR_H
22 #define CGEN_PAR_H
23 
24 /* Kinds of writes stored on the write queue.  */
25 enum cgen_write_queue_kind {
26   CGEN_BI_WRITE, CGEN_QI_WRITE, CGEN_SI_WRITE, CGEN_SF_WRITE,
27   CGEN_PC_WRITE,
28   CGEN_FN_HI_WRITE, CGEN_FN_SI_WRITE, CGEN_FN_SF_WRITE,
29   CGEN_FN_DI_WRITE, CGEN_FN_DF_WRITE,
30   CGEN_FN_XI_WRITE, CGEN_FN_PC_WRITE,
31   CGEN_MEM_QI_WRITE, CGEN_MEM_HI_WRITE, CGEN_MEM_SI_WRITE, CGEN_MEM_DI_WRITE,
32   CGEN_MEM_DF_WRITE, CGEN_MEM_XI_WRITE,
33   CGEN_FN_MEM_QI_WRITE, CGEN_FN_MEM_HI_WRITE, CGEN_FN_MEM_SI_WRITE,
34   CGEN_FN_MEM_DI_WRITE, CGEN_FN_MEM_DF_WRITE, CGEN_FN_MEM_XI_WRITE,
35   CGEN_NUM_WRITE_KINDS
36 };
37 
38 /* Element of the write queue.  */
39 typedef struct {
40   enum cgen_write_queue_kind kind; /* Used to select union member below.  */
41   IADDR insn_address;       /* Address of the insn performing the write.  */
42   unsigned32 flags;         /* Target specific flags.  */
43   long       word1;         /* Target specific field.  */
44   union {
45     struct {
46       BI  *target;
47       BI   value;
48     } bi_write;
49     struct {
50       UQI *target;
51       QI   value;
52     } qi_write;
53     struct {
54       SI *target;
55       SI  value;
56     } si_write;
57     struct {
58       SI *target;
59       SF  value;
60     } sf_write;
61     struct {
62       USI value;
63     } pc_write;
64     struct {
65       UINT regno;
66       UHI   value;
67       void (*function)(SIM_CPU *, UINT, UHI);
68     } fn_hi_write;
69     struct {
70       UINT regno;
71       SI   value;
72       void (*function)(SIM_CPU *, UINT, USI);
73     } fn_si_write;
74     struct {
75       UINT regno;
76       SF   value;
77       void (*function)(SIM_CPU *, UINT, SF);
78     } fn_sf_write;
79     struct {
80       UINT regno;
81       DI   value;
82       void (*function)(SIM_CPU *, UINT, DI);
83     } fn_di_write;
84     struct {
85       UINT regno;
86       DF   value;
87       void (*function)(SIM_CPU *, UINT, DF);
88     } fn_df_write;
89     struct {
90       UINT regno;
91       SI   value[4];
92       void (*function)(SIM_CPU *, UINT, SI *);
93     } fn_xi_write;
94     struct {
95       USI  value;
96       void (*function)(SIM_CPU *, USI);
97     } fn_pc_write;
98     struct {
99       SI   address;
100       QI   value;
101     } mem_qi_write;
102     struct {
103       SI   address;
104       HI   value;
105     } mem_hi_write;
106     struct {
107       SI   address;
108       SI   value;
109     } mem_si_write;
110     struct {
111       SI   address;
112       DI   value;
113     } mem_di_write;
114     struct {
115       SI   address;
116       DF   value;
117     } mem_df_write;
118     struct {
119       SI   address;
120       SI   value[4];
121     } mem_xi_write;
122     struct {
123       SI   address;
124       QI   value;
125       void (*function)(SIM_CPU *, IADDR, SI, QI);
126     } fn_mem_qi_write;
127     struct {
128       SI   address;
129       HI   value;
130       void (*function)(SIM_CPU *, IADDR, SI, HI);
131     } fn_mem_hi_write;
132     struct {
133       SI   address;
134       SI   value;
135       void (*function)(SIM_CPU *, IADDR, SI, SI);
136     } fn_mem_si_write;
137     struct {
138       SI   address;
139       DI   value;
140       void (*function)(SIM_CPU *, IADDR, SI, DI);
141     } fn_mem_di_write;
142     struct {
143       SI   address;
144       DF   value;
145       void (*function)(SIM_CPU *, IADDR, SI, DF);
146     } fn_mem_df_write;
147     struct {
148       SI   address;
149       SI   value[4];
150       void (*function)(SIM_CPU *, IADDR, SI, SI *);
151     } fn_mem_xi_write;
152   } kinds;
153 } CGEN_WRITE_QUEUE_ELEMENT;
154 
155 #define CGEN_WRITE_QUEUE_ELEMENT_KIND(element) ((element)->kind)
156 #define CGEN_WRITE_QUEUE_ELEMENT_IADDR(element) ((element)->insn_address)
157 #define CGEN_WRITE_QUEUE_ELEMENT_FLAGS(element) ((element)->flags)
158 #define CGEN_WRITE_QUEUE_ELEMENT_WORD1(element) ((element)->word1)
159 
160 extern void cgen_write_queue_element_execute (
161   SIM_CPU *, CGEN_WRITE_QUEUE_ELEMENT *
162 );
163 
164 /* Instance of the queue for parallel write-after support.  */
165 /* FIXME: Should be dynamic?  */
166 #define CGEN_WRITE_QUEUE_SIZE (64 * 4) /* 64 writes x 4 insns -- for now.  */
167 
168 typedef struct {
169   int index;
170   CGEN_WRITE_QUEUE_ELEMENT q[CGEN_WRITE_QUEUE_SIZE];
171 } CGEN_WRITE_QUEUE;
172 
173 #define CGEN_WRITE_QUEUE_CLEAR(queue)       ((queue)->index = 0)
174 #define CGEN_WRITE_QUEUE_INDEX(queue)       ((queue)->index)
175 #define CGEN_WRITE_QUEUE_ELEMENT(queue, ix) (&(queue)->q[(ix)])
176 
177 #define CGEN_WRITE_QUEUE_NEXT(queue) (   \
178   (queue)->index < CGEN_WRITE_QUEUE_SIZE \
179     ? &(queue)->q[(queue)->index++]      \
180     : cgen_write_queue_overflow (queue)  \
181 )
182 
183 extern CGEN_WRITE_QUEUE_ELEMENT *cgen_write_queue_overflow (CGEN_WRITE_QUEUE *);
184 
185 /* Functions for queuing writes.  Used by semantic code.  */
186 extern void sim_queue_bi_write (SIM_CPU *, BI *, BI);
187 extern void sim_queue_qi_write (SIM_CPU *, UQI *, UQI);
188 extern void sim_queue_si_write (SIM_CPU *, SI *, SI);
189 extern void sim_queue_sf_write (SIM_CPU *, SI *, SF);
190 
191 extern void sim_queue_pc_write (SIM_CPU *, USI);
192 
193 extern void sim_queue_fn_hi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, UHI), UINT, UHI);
194 extern void sim_queue_fn_si_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, USI), UINT, USI);
195 extern void sim_queue_fn_sf_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, SF), UINT, SF);
196 extern void sim_queue_fn_di_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DI), UINT, DI);
197 extern void sim_queue_fn_df_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DF), UINT, DF);
198 extern void sim_queue_fn_xi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, SI *), UINT, SI *);
199 extern void sim_queue_fn_pc_write (SIM_CPU *, void (*)(SIM_CPU *, USI), USI);
200 
201 extern void sim_queue_mem_qi_write (SIM_CPU *, SI, QI);
202 extern void sim_queue_mem_hi_write (SIM_CPU *, SI, HI);
203 extern void sim_queue_mem_si_write (SIM_CPU *, SI, SI);
204 extern void sim_queue_mem_di_write (SIM_CPU *, SI, DI);
205 extern void sim_queue_mem_df_write (SIM_CPU *, SI, DF);
206 extern void sim_queue_mem_xi_write (SIM_CPU *, SI, SI *);
207 
208 extern void sim_queue_fn_mem_qi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, QI), SI, QI);
209 extern void sim_queue_fn_mem_hi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, HI), SI, HI);
210 extern void sim_queue_fn_mem_si_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, SI), SI, SI);
211 extern void sim_queue_fn_mem_di_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, DI), SI, DI);
212 extern void sim_queue_fn_mem_df_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, DF), SI, DF);
213 extern void sim_queue_fn_mem_xi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, SI *), SI, SI *);
214 
215 #endif /* CGEN_PAR_H */
216