1 /* Simulator header for cgen parallel support.
2    Copyright (C) 1999-2013 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 #ifndef CGEN_PAR_H
21 #define CGEN_PAR_H
22 
23 /* Kinds of writes stored on the write queue.  */
24 enum cgen_write_queue_kind {
25   CGEN_BI_WRITE, CGEN_QI_WRITE, CGEN_SI_WRITE, CGEN_SF_WRITE,
26   CGEN_PC_WRITE,
27   CGEN_FN_HI_WRITE, CGEN_FN_SI_WRITE, CGEN_FN_SF_WRITE,
28   CGEN_FN_DI_WRITE, CGEN_FN_DF_WRITE,
29   CGEN_FN_XI_WRITE, CGEN_FN_PC_WRITE,
30   CGEN_MEM_QI_WRITE, CGEN_MEM_HI_WRITE, CGEN_MEM_SI_WRITE, CGEN_MEM_DI_WRITE,
31   CGEN_MEM_DF_WRITE, CGEN_MEM_XI_WRITE,
32   CGEN_FN_MEM_QI_WRITE, CGEN_FN_MEM_HI_WRITE, CGEN_FN_MEM_SI_WRITE,
33   CGEN_FN_MEM_DI_WRITE, CGEN_FN_MEM_DF_WRITE, CGEN_FN_MEM_XI_WRITE,
34   CGEN_NUM_WRITE_KINDS
35 };
36 
37 /* Element of the write queue.  */
38 typedef struct {
39   enum cgen_write_queue_kind kind; /* Used to select union member below.  */
40   IADDR insn_address;       /* Address of the insn performing the write.  */
41   unsigned32 flags;         /* Target specific flags.  */
42   long       word1;         /* Target specific field.  */
43   union {
44     struct {
45       BI  *target;
46       BI   value;
47     } bi_write;
48     struct {
49       UQI *target;
50       QI   value;
51     } qi_write;
52     struct {
53       SI *target;
54       SI  value;
55     } si_write;
56     struct {
57       SI *target;
58       SF  value;
59     } sf_write;
60     struct {
61       USI value;
62     } pc_write;
63     struct {
64       UINT regno;
65       UHI   value;
66       void (*function)(SIM_CPU *, UINT, UHI);
67     } fn_hi_write;
68     struct {
69       UINT regno;
70       SI   value;
71       void (*function)(SIM_CPU *, UINT, USI);
72     } fn_si_write;
73     struct {
74       UINT regno;
75       SF   value;
76       void (*function)(SIM_CPU *, UINT, SF);
77     } fn_sf_write;
78     struct {
79       UINT regno;
80       DI   value;
81       void (*function)(SIM_CPU *, UINT, DI);
82     } fn_di_write;
83     struct {
84       UINT regno;
85       DF   value;
86       void (*function)(SIM_CPU *, UINT, DF);
87     } fn_df_write;
88     struct {
89       UINT regno;
90       SI   value[4];
91       void (*function)(SIM_CPU *, UINT, SI *);
92     } fn_xi_write;
93     struct {
94       USI  value;
95       void (*function)(SIM_CPU *, USI);
96     } fn_pc_write;
97     struct {
98       SI   address;
99       QI   value;
100     } mem_qi_write;
101     struct {
102       SI   address;
103       HI   value;
104     } mem_hi_write;
105     struct {
106       SI   address;
107       SI   value;
108     } mem_si_write;
109     struct {
110       SI   address;
111       DI   value;
112     } mem_di_write;
113     struct {
114       SI   address;
115       DF   value;
116     } mem_df_write;
117     struct {
118       SI   address;
119       SI   value[4];
120     } mem_xi_write;
121     struct {
122       SI   address;
123       QI   value;
124       void (*function)(SIM_CPU *, IADDR, SI, QI);
125     } fn_mem_qi_write;
126     struct {
127       SI   address;
128       HI   value;
129       void (*function)(SIM_CPU *, IADDR, SI, HI);
130     } fn_mem_hi_write;
131     struct {
132       SI   address;
133       SI   value;
134       void (*function)(SIM_CPU *, IADDR, SI, SI);
135     } fn_mem_si_write;
136     struct {
137       SI   address;
138       DI   value;
139       void (*function)(SIM_CPU *, IADDR, SI, DI);
140     } fn_mem_di_write;
141     struct {
142       SI   address;
143       DF   value;
144       void (*function)(SIM_CPU *, IADDR, SI, DF);
145     } fn_mem_df_write;
146     struct {
147       SI   address;
148       SI   value[4];
149       void (*function)(SIM_CPU *, IADDR, SI, SI *);
150     } fn_mem_xi_write;
151   } kinds;
152 } CGEN_WRITE_QUEUE_ELEMENT;
153 
154 #define CGEN_WRITE_QUEUE_ELEMENT_KIND(element) ((element)->kind)
155 #define CGEN_WRITE_QUEUE_ELEMENT_IADDR(element) ((element)->insn_address)
156 #define CGEN_WRITE_QUEUE_ELEMENT_FLAGS(element) ((element)->flags)
157 #define CGEN_WRITE_QUEUE_ELEMENT_WORD1(element) ((element)->word1)
158 
159 extern void cgen_write_queue_element_execute (
160   SIM_CPU *, CGEN_WRITE_QUEUE_ELEMENT *
161 );
162 
163 /* Instance of the queue for parallel write-after support.  */
164 /* FIXME: Should be dynamic?  */
165 #define CGEN_WRITE_QUEUE_SIZE (64 * 4) /* 64 writes x 4 insns -- for now.  */
166 
167 typedef struct {
168   int index;
169   CGEN_WRITE_QUEUE_ELEMENT q[CGEN_WRITE_QUEUE_SIZE];
170 } CGEN_WRITE_QUEUE;
171 
172 #define CGEN_WRITE_QUEUE_CLEAR(queue)       ((queue)->index = 0)
173 #define CGEN_WRITE_QUEUE_INDEX(queue)       ((queue)->index)
174 #define CGEN_WRITE_QUEUE_ELEMENT(queue, ix) (&(queue)->q[(ix)])
175 
176 #define CGEN_WRITE_QUEUE_NEXT(queue) (   \
177   (queue)->index < CGEN_WRITE_QUEUE_SIZE \
178     ? &(queue)->q[(queue)->index++]      \
179     : cgen_write_queue_overflow (queue)  \
180 )
181 
182 extern CGEN_WRITE_QUEUE_ELEMENT *cgen_write_queue_overflow (CGEN_WRITE_QUEUE *);
183 
184 /* Functions for queuing writes.  Used by semantic code.  */
185 extern void sim_queue_bi_write (SIM_CPU *, BI *, BI);
186 extern void sim_queue_qi_write (SIM_CPU *, UQI *, UQI);
187 extern void sim_queue_si_write (SIM_CPU *, SI *, SI);
188 extern void sim_queue_sf_write (SIM_CPU *, SI *, SF);
189 
190 extern void sim_queue_pc_write (SIM_CPU *, USI);
191 
192 extern void sim_queue_fn_hi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, UHI), UINT, UHI);
193 extern void sim_queue_fn_si_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, USI), UINT, USI);
194 extern void sim_queue_fn_sf_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, SF), UINT, SF);
195 extern void sim_queue_fn_di_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DI), UINT, DI);
196 extern void sim_queue_fn_df_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DF), UINT, DF);
197 extern void sim_queue_fn_xi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, SI *), UINT, SI *);
198 extern void sim_queue_fn_pc_write (SIM_CPU *, void (*)(SIM_CPU *, USI), USI);
199 
200 extern void sim_queue_mem_qi_write (SIM_CPU *, SI, QI);
201 extern void sim_queue_mem_hi_write (SIM_CPU *, SI, HI);
202 extern void sim_queue_mem_si_write (SIM_CPU *, SI, SI);
203 extern void sim_queue_mem_di_write (SIM_CPU *, SI, DI);
204 extern void sim_queue_mem_df_write (SIM_CPU *, SI, DF);
205 extern void sim_queue_mem_xi_write (SIM_CPU *, SI, SI *);
206 
207 extern void sim_queue_fn_mem_qi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, QI), SI, QI);
208 extern void sim_queue_fn_mem_hi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, HI), SI, HI);
209 extern void sim_queue_fn_mem_si_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, SI), SI, SI);
210 extern void sim_queue_fn_mem_di_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, DI), SI, DI);
211 extern void sim_queue_fn_mem_df_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, DF), SI, DF);
212 extern void sim_queue_fn_mem_xi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, SI *), SI, SI *);
213 
214 #endif /* CGEN_PAR_H */
215