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
6This file is part of the GNU instruction set simulator.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along 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.  */
25enum 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.  */
39typedef 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
160extern 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
168typedef 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
183extern CGEN_WRITE_QUEUE_ELEMENT *cgen_write_queue_overflow (CGEN_WRITE_QUEUE *);
184
185/* Functions for queuing writes.  Used by semantic code.  */
186extern void sim_queue_bi_write (SIM_CPU *, BI *, BI);
187extern void sim_queue_qi_write (SIM_CPU *, UQI *, UQI);
188extern void sim_queue_si_write (SIM_CPU *, SI *, SI);
189extern void sim_queue_sf_write (SIM_CPU *, SI *, SF);
190
191extern void sim_queue_pc_write (SIM_CPU *, USI);
192
193extern void sim_queue_fn_hi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, UHI), UINT, UHI);
194extern void sim_queue_fn_si_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, USI), UINT, USI);
195extern void sim_queue_fn_sf_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, SF), UINT, SF);
196extern void sim_queue_fn_di_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DI), UINT, DI);
197extern void sim_queue_fn_df_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DF), UINT, DF);
198extern void sim_queue_fn_xi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, SI *), UINT, SI *);
199extern void sim_queue_fn_pc_write (SIM_CPU *, void (*)(SIM_CPU *, USI), USI);
200
201extern void sim_queue_mem_qi_write (SIM_CPU *, SI, QI);
202extern void sim_queue_mem_hi_write (SIM_CPU *, SI, HI);
203extern void sim_queue_mem_si_write (SIM_CPU *, SI, SI);
204extern void sim_queue_mem_di_write (SIM_CPU *, SI, DI);
205extern void sim_queue_mem_df_write (SIM_CPU *, SI, DF);
206extern void sim_queue_mem_xi_write (SIM_CPU *, SI, SI *);
207
208extern void sim_queue_fn_mem_qi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, QI), SI, QI);
209extern void sim_queue_fn_mem_hi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, HI), SI, HI);
210extern void sim_queue_fn_mem_si_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, SI), SI, SI);
211extern void sim_queue_fn_mem_di_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, DI), SI, DI);
212extern void sim_queue_fn_mem_df_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, DF), SI, DF);
213extern void sim_queue_fn_mem_xi_write (SIM_CPU *, void (*)(SIM_CPU *, IADDR, SI, SI *), SI, SI *);
214
215#endif /* CGEN_PAR_H */
216