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