1 |
6 |
jlechner |
; Simulator generator support routines.
|
2 |
|
|
; Copyright (C) 2000, 2001, 2002, 2006, 2009 Red Hat, Inc.
|
3 |
|
|
; This file is part of CGEN.
|
4 |
|
|
|
5 |
|
|
; i.e. this file fills in the missing pieces of the interface between
|
6 |
|
|
; the application independent part of CGEN (i.e. the code loaded by read.scm)
|
7 |
|
|
; and the application dependent part (i.e. sim-*.scm).
|
8 |
|
|
; `send' is not intended to appear in sim-*.scm.
|
9 |
|
|
; [It still does but that's to be fixed.]
|
10 |
|
|
; Specify which application.
|
11 |
|
|
|
12 |
|
|
; Return the C type of something. This isn't always a mode.
|
13 |
|
|
; Return the C type of an index's value or #f if not needed (scalar).
|
14 |
|
|
|
15 |
|
|
; Currently supported options:
|
16 |
|
|
|
17 |
|
|
; generate code to use the scache
|
18 |
|
|
|
19 |
|
|
; with-profile fn|sw
|
20 |
|
|
|
21 |
|
|
; code (fn) or in the semantic switch (sw)
|
22 |
|
|
|
23 |
|
|
; For architectures that have parallel execution.
|
24 |
|
|
; Execute the semantics by recording the results in a generic buffer,
|
25 |
|
|
; and doing a post-semantics writeback pass.
|
26 |
|
|
; with-parallel-only
|
27 |
|
|
; Only generate parallel versions of each insn.
|
28 |
|
|
; with-multiple-isa
|
29 |
|
|
|
30 |
|
|
; copyright fsf|redhat
|
31 |
|
|
|
32 |
|
|
; package gnusim|cygsim
|
33 |
|
|
; indicate the software package
|
34 |
|
|
; #t if the scache is being used
|
35 |
|
|
; #t if we're generating profiling code
|
36 |
|
|
; Each of the function and switch semantic code can have profiling.
|
37 |
|
|
; The options as passed are stored in -with-profile-{fn,sw}?, and
|
38 |
|
|
; -with-profile? is set at code generation time.
|
39 |
|
|
; #t if multiple isa support is enabled
|
40 |
|
|
; Handle parallel execution with generic writeback pass.
|
41 |
|
|
; Only generate parallel versions of each insn.
|
42 |
|
|
; String containing copyright text.
|
43 |
|
|
; String containing text defining the package we're generating code for.
|
44 |
|
|
; Initialize the options.
|
45 |
|
|
; Handle an option passed in from the command line.
|
46 |
|
|
"fn""sw""invalid with-profile value""fsf""redhat""invalid copyright value""gnusim""cygsim""invalid package value""unknown option"; #t if the cpu can execute insns parallely.
|
47 |
|
|
; This one isn't passed on the command line, but we follow the convention
|
48 |
|
|
; of prefixing these things with `with-'.
|
49 |
|
|
; While processing operand reading (or writing), parallel execution support
|
50 |
|
|
; needs to be turned off, so it is up to the appropriate cgen-foo.c proc to
|
51 |
|
|
|
52 |
|
|
; Kind of parallel support.
|
53 |
|
|
; If 'read, read pre-processing is done.
|
54 |
|
|
; If 'write, write post-processing is done.
|
55 |
|
|
|
56 |
|
|
; version used read pre-processing. Not sure supporting both is useful
|
57 |
|
|
; in the long run.
|
58 |
|
|
; #t if parallel support is provided by read pre-processing.
|
59 |
|
|
; #t if parallel support is provided by write post-processing.
|
60 |
|
|
; Misc. utilities.
|
61 |
|
|
; All machine generated cpu elements are accessed through a cover macro
|
62 |
|
|
; to hide the details of the underlying implementation.
|
63 |
|
|
"CPU"" ("")"; Return C code to fetch a value from instruction memory.
|
64 |
|
|
; PC-VAR is the C expression containing the address of the start of the
|
65 |
|
|
|
66 |
|
|
; ??? Aligned/unaligned support?
|
67 |
|
|
"GETIMEM""UQI""UHI""USI""bad bitsize argument to gen-ifetch"" (current_cpu, "" + "")"; Instruction field support code.
|
68 |
|
|
; Return a <c-expr> object of the value of an ifield.
|
69 |
|
|
|
70 |
|
|
; set until the method processing the dest.
|
71 |
|
|
""; Type system.
|
72 |
|
|
; Methods:
|
73 |
|
|
|
74 |
|
|
; gen-sym-decl - generate decl using the provided symbol
|
75 |
|
|
; gen-sym-get-macro - generate GET macro for accessing CPU elements
|
76 |
|
|
; gen-sym-set-macro - generate SET macro for accessing CPU elements
|
77 |
|
|
|
78 |
|
|
" /* "" */\n"" "" "";\n"""""; Array type
|
79 |
|
|
" /* "" */\n"" "" "";\n""#define GET_""("") ""\n""#define SET_""("", x) ""("" = (x))\n"; Return a reference to the array.
|
80 |
|
|
|
81 |
|
|
; INDEX is either a single index object or a (possibly empty) list of objects,
|
82 |
|
|
; one object per dimension.
|
83 |
|
|
|
84 |
|
|
;
|
85 |
|
|
|
86 |
|
|
; <integer> 'gen-type
|
87 |
|
|
; (lambda (self)
|
88 |
|
|
; (mode:c-type (mode-find (elm-get self 'bits)
|
89 |
|
|
; (if (has-attr? self 'UNSIGNED)
|
90 |
|
|
; 'UINT 'INT)))
|
91 |
|
|
; )
|
92 |
|
|
;)
|
93 |
|
|
;
|
94 |
|
|
;(method-make! <integer> 'gen-sym-decl (lambda (self sym comment) ""))
|
95 |
|
|
;(method-make! <integer> 'gen-sym-get-macro (lambda (self sym comment) ""))
|
96 |
|
|
;(method-make! <integer> 'gen-sym-set-macro (lambda (self sym comment) ""))
|
97 |
|
|
|
98 |
|
|
;
|
99 |
|
|
|
100 |
|
|
; things the simulator will want to do with it.
|
101 |
|
|
;
|
102 |
|
|
; Methods:
|
103 |
|
|
; gen-decl
|
104 |
|
|
; gen-get-macro - Generate definition of the GET access macro.
|
105 |
|
|
; gen-set-macro - Generate definition of the SET access macro.
|
106 |
|
|
; gen-write - Same as gen-read except done on output operands
|
107 |
|
|
; cxmake-get - Return a <c-expr> object to fetch the value.
|
108 |
|
|
; gen-set-quiet - Set the value.
|
109 |
|
|
; ??? Could just call this gen-set as there is no gen-set-trace
|
110 |
|
|
; but for consistency with the messages passed to operands
|
111 |
|
|
; we use this same.
|
112 |
|
|
; gen-type - C type to use to record value, as a string.
|
113 |
|
|
; ??? Delete and just use get-mode?
|
114 |
|
|
; save-index? - return #t if an index needs to be saved for parallel
|
115 |
|
|
; execution post-write processing
|
116 |
|
|
; gen-profile-decl
|
117 |
|
|
; gen-record-profile
|
118 |
|
|
; get-mode
|
119 |
|
|
; gen-profile-locals
|
120 |
|
|
; gen-sym-decl - Return a C declaration using the provided symbol.
|
121 |
|
|
; gen-sym-get-macro - Generate default GET access macro.
|
122 |
|
|
; gen-sym-set-macro - Generate default SET access macro.
|
123 |
|
|
; gen-ref - Return a C reference to the object.
|
124 |
|
|
; Generate CPU state struct entries.
|
125 |
|
|
|
126 |
|
|
; Each hardware type must provide its own gen-write method.
|
127 |
|
|
"gen-write method not overridden:"; gen-type handler, must be overridden
|
128 |
|
|
"gen-type not overridden:"""; Default gen-record-profile method.
|
129 |
|
|
""; nothing to do
|
130 |
|
|
; Default cxmake-get method.
|
131 |
|
|
; Return a <c-expr> object of the value of SELF.
|
132 |
|
|
; ESTATE is the current rtl evaluator state.
|
133 |
|
|
; INDEX is a <hw-index> object. It must be an ifield.
|
134 |
|
|
; SELECTOR is a hardware selector RTX.
|
135 |
|
|
|
136 |
|
|
""""; PC support
|
137 |
|
|
; 'gen-set-quiet helper for PC values.
|
138 |
|
|
; NEWVAL is a <c-expr> object of the value to be assigned.
|
139 |
|
|
; If OPTIONS contains #:direct, set the PC directly, bypassing semantic
|
140 |
|
|
; code considerations.
|
141 |
|
|
; ??? OPTIONS support wip. Probably want a new form (or extend existing form)
|
142 |
|
|
; of rtx: that takes a variable number of named arguments.
|
143 |
|
|
; ??? Another way to get #:direct might be (raw-reg h-pc).
|
144 |
|
|
"Not a PC:""SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, "", vpc);\n""SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, "", vpc);\n"; Handle updates of the pc during parallel execution.
|
145 |
|
|
; This is done in a post-processing pass after semantic evaluation.
|
146 |
|
|
; SFMT is the <sformat>.
|
147 |
|
|
; OP is the operand.
|
148 |
|
|
; ACCESS-MACRO is the runtime C macro to use to fetch indices computed
|
149 |
|
|
; during semantic evaluation.
|
150 |
|
|
;
|
151 |
|
|
|
152 |
|
|
; At this point I'm reluctant to willy nilly make methods virtual.
|
153 |
|
|
|
154 |
|
|
; Forward these methods onto TYPE.
|
155 |
|
|
; For parallel instructions supported by queueing outputs for later update,
|
156 |
|
|
|
157 |
|
|
; An example of when the index isn't needed is if the index can be determined
|
158 |
|
|
|
159 |
|
|
; FIXME: Later handle case where register number is determined at runtime.
|
160 |
|
|
; Handle updates of registers during parallel execution.
|
161 |
|
|
; This is done in a post-processing pass after semantic evaluation.
|
162 |
|
|
|
163 |
|
|
|
164 |
|
|
; ACCESS-MACRO is the runtime C macro to use to fetch indices computed
|
165 |
|
|
; during semantic evaluation.
|
166 |
|
|
; FIXME: May need mode of OP.
|
167 |
|
|
; First get a hw-index object to use during indexing.
|
168 |
|
|
|
169 |
|
|
; evaluation. Others are computed during the extraction phase.
|
170 |
|
|
" "" ("")"" /* "" */\n"" unsigned long "";\n"; FIXME: Need to handle scalars.
|
171 |
|
|
"""index""index""""index""x"; not `mode', sets have mode VOID
|
172 |
|
|
"(x)""(index)""(x)"; Utility to build a <c-expr> object to fetch the value of a register.
|
173 |
|
|
; If the register is accessed via a cover function/macro, do it.
|
174 |
|
|
; Otherwise fetch the value from the cached address or from the CPU struct.
|
175 |
|
|
"GET_"" ("""")"; FIXME: redo test
|
176 |
|
|
"* "; raw-reg: support
|
177 |
|
|
; ??? raw-reg: support is wip
|
178 |
|
|
; Utilities to generate C code to assign a variable to a register.
|
179 |
|
|
"SET_"" ("""", "");\n"; FIXME: redo test
|
180 |
|
|
|
181 |
|
|
; ??? wip
|
182 |
|
|
|
183 |
|
|
"_""_get""_""_set"; Generate decls for access fns of register HW, beginning with
|
184 |
|
|
|
185 |
|
|
; SCALAR? is #t if the register is a scalar. Otherwise it is #f and the
|
186 |
|
|
; register is a bank of registers.
|
187 |
|
|
" "" (SIM_CPU *"""", UINT"");\n""void "" (SIM_CPU *, """"UINT, "");\n"; Generate defns of access fns of register HW, beginning with
|
188 |
|
|
; PREFIX, using C type TYPE.
|
189 |
|
|
; SCALAR? is #t if the register is a scalar. Otherwise it is #f and the
|
190 |
|
|
; register is a bank of registers.
|
191 |
|
|
; GET/SET-CODE are C fragments to get/set the value.
|
192 |
|
|
; ??? Inlining left for later.
|
193 |
|
|
|
194 |
|
|
"GETMEM""""ASI"" (""current_cpu, pc, """", "")""SETMEM""""ASI"" (""current_cpu, pc, """", "", "");\n"""""""; For parallel instructions supported by queueing outputs for later update,
|
195 |
|
|
|
196 |
|
|
; In the case of the complete memory address being an immediate
|
197 |
|
|
; argument, we can return #f (later).
|
198 |
|
|
" "" ("")"; Immediates, addresses.
|
199 |
|
|
; Forward these methods onto TYPE.
|
200 |
|
|
"gen-write of <hw-immediate> shouldn't happen"; FIXME.
|
201 |
|
|
|
202 |
|
|
; ESTATE is the current rtl evaluator state.
|
203 |
|
|
|
204 |
|
|
; Needed because we record our own copy of the ifield in ARGBUF.
|
205 |
|
|
; SELECTOR is a hardware selector RTX.
|
206 |
|
|
"not an ifield hw-index""gen-write of <hw-address> shouldn't happen"; FIXME: revisit.
|
207 |
|
|
"IADDR"; Return a <c-expr> object of the value of SELF.
|
208 |
|
|
|
209 |
|
|
; INDEX is a <hw-index> object. It must be an ifield.
|
210 |
|
|
; Needed because we record our own copy of the ifield in ARGBUF,
|
211 |
|
|
; *and* because we want to record in the result the 'CACHED attribute
|
212 |
|
|
; since instruction addresses based on ifields are fixed [and thus cacheable].
|
213 |
|
|
; SELECTOR is a hardware selector RTX.
|
214 |
|
|
"not an ifield hw-index"; ??? Perhaps a better way would be to defer evaluating the src of a
|
215 |
|
|
; set until the method processing the dest.
|
216 |
|
|
""; Hardware index support code.
|
217 |
|
|
|
218 |
|
|
; In the cases where this is needed (the index isn't known until insn
|
219 |
|
|
; execution time), the index is computed along with the value to be stored,
|
220 |
|
|
; so this is easy.
|
221 |
|
|
" ("")"; Return the name of the PAREXEC structure member holding a hardware index
|
222 |
|
|
; for operand OP.
|
223 |
|
|
"_idx"; Cover fn to hardware indices to generate the actual C code.
|
224 |
|
|
|
225 |
|
|
; The result is a string of C code.
|
226 |
|
|
; FIXME:wip
|
227 |
|
|
""; special case UINT to cut down on unnecessary verbosity.
|
228 |
|
|
; ??? May wish to handle more similarily.
|
229 |
|
|
"(("") "")""""-gen-hw-index-raw: invalid index:"; Same as -gen-hw-index-raw except used where speedups are possible.
|
230 |
|
|
; e.g. doing array index calcs at extraction time.
|
231 |
|
|
|
232 |
|
|
; FIXME: redo test
|
233 |
|
|
|
234 |
|
|
; If MODE is VOID, abort.
|
235 |
|
|
|
236 |
|
|
; Hardware selector support code.
|
237 |
|
|
; Generate C code for SEL.
|
238 |
|
|
; Instruction operand support code.
|
239 |
|
|
; Methods:
|
240 |
|
|
|
241 |
|
|
; gen-read - Record an operand's value prior to parallely executing
|
242 |
|
|
; several instructions. Not used if gen-write used.
|
243 |
|
|
; gen-write - Write back an operand's value after parallely executing
|
244 |
|
|
; several instructions. Not used if gen-read used.
|
245 |
|
|
; cxmake-get - Return C code to fetch the value of an operand.
|
246 |
|
|
; gen-set-quiet - Return C code to set the value of an operand.
|
247 |
|
|
; gen-set-trace - Return C code to set the value of an operand, and print
|
248 |
|
|
; a result trace message. ??? Ideally this will go away when
|
249 |
|
|
; trace record support is complete.
|
250 |
|
|
; Return the C type of an operand.
|
251 |
|
|
; Generally we forward things on to TYPE, but for the actual type we need to
|
252 |
|
|
|
253 |
|
|
;(method-make-forward! <operand> 'type '(gen-type))
|
254 |
|
|
; First get the mode.
|
255 |
|
|
; If it's VOID use the type's type.
|
256 |
|
|
; Extra pc operand methods.
|
257 |
|
|
; The enclosing function must set `pc' to the correct value.
|
258 |
|
|
"pc"; For parallel write post-processing, we don't want to defer setting the pc.
|
259 |
|
|
; ??? Not sure anymore.
|
260 |
|
|
;(method-make!
|
261 |
|
|
; <pc> 'gen-set-quiet
|
262 |
|
|
; (lambda (self estate mode index selector newval)
|
263 |
|
|
; (-op-gen-set-quiet self estate mode index selector newval)))
|
264 |
|
|
|
265 |
|
|
; <pc> 'gen-set-trace
|
266 |
|
|
; (lambda (self estate mode index selector newval)
|
267 |
|
|
; (-op-gen-set-trace self estate mode index selector newval)))
|
268 |
|
|
; Name of C macro to access parallel execution operand support.
|
269 |
|
|
"OPRND"; Return C code to fetch an operand's value and save it away for the
|
270 |
|
|
; semantic handler. This is used to handle parallel execution of several
|
271 |
|
|
; instructions where all inputs of all insns are read before any outputs are
|
272 |
|
|
; written.
|
273 |
|
|
; For operands, the word `read' is only used in this context.
|
274 |
|
|
; Return C code to write an operand's value.
|
275 |
|
|
; This is used to handle parallel execution of several instructions where all
|
276 |
|
|
; outputs are written to temporary spots first, and then a final
|
277 |
|
|
|
278 |
|
|
; For operands, the word `write' is only used in this context.
|
279 |
|
|
; Default gen-read method.
|
280 |
|
|
; This is used to help support targets with parallel insns.
|
281 |
|
|
; Either this or gen-write (but not both) is used.
|
282 |
|
|
|
283 |
|
|
; Ditto for the selector.
|
284 |
|
|
";\n"; Forward gen-write onto the <hardware> object.
|
285 |
|
|
; If operand is conditionally written, we have to check that first.
|
286 |
|
|
; ??? If two (or more) operands are written based on the same condition,
|
287 |
|
|
; all the tests can be collapsed together. Not sure that's a big
|
288 |
|
|
; enough win yet.
|
289 |
|
|
" if (written & (1 << ""))\n"" {\n"" "" }\n"; Return <c-expr> object to get the value of an operand.
|
290 |
|
|
; ESTATE is the current rtl evaluator state.
|
291 |
|
|
; If INDEX is non-#f use it, otherwise use (op:index self).
|
292 |
|
|
; This special handling of #f for INDEX is *only* supported for operands
|
293 |
|
|
; in cxmake-get, gen-set-quiet, and gen-set-trace.
|
294 |
|
|
|
295 |
|
|
; If the instruction could be parallely executed with others and we're
|
296 |
|
|
; doing read pre-processing, the operand has already been fetched, we
|
297 |
|
|
; just have to grab the cached value.
|
298 |
|
|
; ??? reg-raw: support wip
|
299 |
|
|
" ("")"; FIXME: want CACHED attr if present
|
300 |
|
|
; Utilities to implement gen-set-quiet/gen-set-trace.
|
301 |
|
|
; Return C code to call the appropriate queued-write handler.
|
302 |
|
|
; ??? wip
|
303 |
|
|
" ""sim_queue_"; FIXME: clean up (pc? op) vs (memory? hw)
|
304 |
|
|
; FIXME: (send 'pc?) is a temporary hack, (pc? op) didn't work
|
305 |
|
|
"fn_""""pc""mem_""scalar_""""fn_""""_write (current_cpu"; ??? May need to include h/w id some day.
|
306 |
|
|
", ""@cpu@"""""", "", "", "", "");\n"" "" ("")"" = "";\n"""" "" ("")"" = "";\n"" {\n"" "" opval = "";\n"; Dispatch to setter code if appropriate
|
307 |
|
|
" ""opval""opval";else
|
308 |
|
|
"opval"" written |= (1 << "");\n"""; TRACE_RESULT_<MODE> (cpu, abuf, hwnum, opnum, value);
|
309 |
|
|
|
310 |
|
|
; operand instance table].
|
311 |
|
|
; Could just scan the operand table for the operand or hardware number,
|
312 |
|
|
; assuming the operand number is stored in `op'.
|
313 |
|
|
" TRACE_RESULT (current_cpu, abuf"", "", "", opval);\n"" }\n"" {\n"" "" opval = "";\n""opval"" "" ("")"" = "";\n"""" "" ("")"" = opval;\n"" written |= (1 << "");\n"""; TRACE_RESULT_<MODE> (cpu, abuf, hwnum, opnum, value);
|
314 |
|
|
; For each insn record array of operand numbers [or indices into
|
315 |
|
|
; operand instance table].
|
316 |
|
|
; Could just scan the operand table for the operand or hardware number,
|
317 |
|
|
; assuming the operand number is stored in `op'.
|
318 |
|
|
" TRACE_RESULT (current_cpu, abuf"", "", "", opval);\n"" }\n"; Return C code to set the value of an operand.
|
319 |
|
|
; NEWVAL is a <c-expr> object of the value to store.
|
320 |
|
|
; If INDEX is non-#f use it, otherwise use (op:index self).
|
321 |
|
|
; This special handling of #f for INDEX is *only* supported for operands
|
322 |
|
|
; in cxmake-get, gen-set-quiet, and gen-set-trace.
|
323 |
|
|
; Ditto for SELECTOR.
|
324 |
|
|
; ??? raw-reg: support wip
|
325 |
|
|
; Return C code to set the value of an operand and print TRACE_RESULT message.
|
326 |
|
|
; NEWVAL is a <c-expr> object of the value to store.
|
327 |
|
|
; If INDEX is non-#f use it, otherwise use (op:index self).
|
328 |
|
|
; This special handling of #f for INDEX is *only* supported for operands
|
329 |
|
|
; in cxmake-get, gen-set-quiet, and gen-set-trace.
|
330 |
|
|
; Ditto for SELECTOR.
|
331 |
|
|
; ??? raw-reg: support wip
|
332 |
|
|
; Define and undefine C macros to tuck away details of instruction format used
|
333 |
|
|
; in the parallel execution functions. See gen-define-field-macro for a
|
334 |
|
|
; similar thing done for extraction/semantic functions.
|
335 |
|
|
"#define ""(f) ""par_exec->operands."".f\n""#undef ""\n"; Operand profiling and parallel execution support.
|
336 |
|
|
; Return boolean indicating if operand OP needs its index saved
|
337 |
|
|
|
338 |
|
|
; Return C code to record profile data for modeling use.
|
339 |
|
|
|
340 |
|
|
; This shouldn't be called in the case of a scalar, the code should be
|
341 |
|
|
; smart enough to know there is no need.
|
342 |
|
|
; Return C code to record the data needed for profiling operand SELF.
|
343 |
|
|
; This is done during extraction.
|
344 |
|
|
""" "" = "";\n"; Return C code to track profiling of operand SELF.
|
345 |
|
|
|
346 |
|
|
" ""@cpu@_model_mark_""set_""get_"" (current_cpu"""", "");\n"; CPU, mach, model support.
|
347 |
|
|
|
348 |
|
|
"@prefix@_insn_type""instructions in cpu family @cpu@""@PREFIX@_INSN_"; Return the enum of INSN in cpu family CPU.
|
349 |
|
|
|
350 |
|
|
; cpu family. This collapses the insn enum space for each cpu to increase
|
351 |
|
|
|
352 |
|
|
"@PREFIX@_INSN_"; Return C code to declare the machine data.
|
353 |
|
|
|
354 |
|
|
"const MACH *sim_machs[] =\n{\n""#ifdef ""\n"" & ""_mach,\n""#endif\n"" 0\n""};\n\n"; Return C declarations of cpu model support stuff.
|
355 |
|
|
; ??? This goes in arch.h but a better place is each cpu.h.
|
356 |
|
|
"model types""MODEL_""#define MAX_MODELS ((int) MODEL_MAX)\n\n""unit types""UNIT_"; "apply append" squeezes out nils.
|
357 |
|
|
; create <model_name>-<unit-name> for each unit
|
358 |
|
|
; FIXME: revisit MAX_UNITS
|
359 |
|
|
|
360 |
|
|
""; Lookup operand named OP-NAME in INSN.
|
361 |
|
|
|
362 |
|
|
; IN-OUT is 'in to request an input operand, 'out to request an output operand,
|
363 |
|
|
; and 'in-out to request either (though if an operand is used for input and
|
364 |
|
|
; output then the input version is returned).
|
365 |
|
|
; FIXME: Move elsewhere.
|
366 |
|
|
|
367 |
|
|
; UNIT-NUM is number of the unit in INSN.
|
368 |
|
|
|
369 |
|
|
; - NAME is a spec name, one of cycles, pred, in, out.
|
370 |
|
|
|
371 |
|
|
; as they appear in the semantic code to operand names as they appear in
|
372 |
|
|
; the function unit spec.
|
373 |
|
|
; - VALUE is the operand to NAME. For in,out it is (NAME VALUE) where
|
374 |
|
|
; - NAME is the name of an input/output arg of the unit.
|
375 |
|
|
; - VALUE is the name of the operand as it appears in semantic code.
|
376 |
|
|
|
377 |
|
|
; ??? This is a big sucker, though half of it is just the definitions
|
378 |
|
|
; of utility fns.
|
379 |
|
|
; Return C code to initialize UNIT-REFERENCED-VAR to be a bit mask
|
380 |
|
|
; of operands of UNIT that were read/written by INSN.
|
381 |
|
|
; INSN-REFERENCED-VAR is a bitmask of operands read/written by INSN.
|
382 |
|
|
|
383 |
|
|
; UNIT-REFERENCED-VAR.
|
384 |
|
|
; ??? For now we assume all input operands are read.
|
385 |
|
|
"insn_referenced""referenced"" ""if ("" & (1 << "")) "" |= 1 << "";\n"" "" |= 1 << "";\n"""; Initialize unit argument ARG.
|
386 |
|
|
; OUT? is #f for input args, #t for output args.
|
387 |
|
|
; Ignore scalars.
|
388 |
|
|
; Ignore remapped arg, handled elsewhere.
|
389 |
|
|
; Ignore operands not in INSN.
|
390 |
|
|
|
391 |
|
|
; OUT? is #f for input args, #t for output args.
|
392 |
|
|
|
393 |
|
|
""" "" "" = ""0"";\n"; Return C code to pass unit argument ARG to the handler.
|
394 |
|
|
; OUT? is #f for input args, #t for output args.
|
395 |
|
|
; ignore scalars
|
396 |
|
|
""", "" {\n"" int referenced = 0;\n"" int UNUSED insn_referenced = abuf->written;\n"; Declare variables to hold unit arguments.
|
397 |
|
|
; Initialize 'em, being careful not to initialize an operand that
|
398 |
|
|
|
399 |
|
|
; Make a list of names of in/out overrides.
|
400 |
|
|
""""""""" "" = "";\n"""" "" = "";\n""""insn function unit spec""invalid spec"; Create bitmask indicating which args were referenced.
|
401 |
|
|
; Emit the call to the handler.
|
402 |
|
|
" "" += "" (current_cpu, idesc"", "", referenced"");\n"" }\n"; Return C code to profile an insn-specific unit's usage.
|
403 |
|
|
; UNIT-NUM is number of the unit in INSN.
|
404 |
|
|
|
405 |
|
|
; ARGBUF support is put in cpuall.h, which doesn't depend on sim-cpu.scm,
|
406 |
|
|
|
407 |
|
|
; Utility of -gen-argbuf-fields-union to generate the definition for
|
408 |
|
|
; <sformat-abuf> SBUF.
|
409 |
|
|
"Processing sbuf format "" ...\n"" struct { /* "" */\n"" int empty;\n"" "" "";\n"" } "";\n"; Utility of gen-argbuf-type to generate the union of extracted ifields.
|
410 |
|
|
"\
|
411 |
|
|
/* Instruction argument buffer. */
|
412 |
|
|
|
413 |
|
|
union sem_fields {\n""\
|
414 |
|
|
|
415 |
|
|
/* Writeback handler. */
|
416 |
|
|
struct {
|
417 |
|
|
/* Pointer to argbuf entry for insn whose results need writing back. */
|
418 |
|
|
const struct argbuf *abuf;
|
419 |
|
|
} write;
|
420 |
|
|
/* x-before handler */
|
421 |
|
|
struct {
|
422 |
|
|
/*const SCACHE *insns[MAX_PARALLEL_INSNS];*/
|
423 |
|
|
int first_p;
|
424 |
|
|
} before;
|
425 |
|
|
/* x-after handler */
|
426 |
|
|
struct {
|
427 |
|
|
int empty;
|
428 |
|
|
|
429 |
|
|
/* This entry is used to terminate each pbb. */
|
430 |
|
|
|
431 |
|
|
/* Number of insns in pbb. */
|
432 |
|
|
int insn_count;
|
433 |
|
|
/* Next pbb to execute. */
|
434 |
|
|
SCACHE *next;
|
435 |
|
|
SCACHE *branch_target;
|
436 |
|
|
} chain;
|
437 |
|
|
#endif
|
438 |
|
|
};\n\n"; Generate the definition of the structure that records arguments.
|
439 |
|
|
; This is a union of structures with one structure for each insn format.
|
440 |
|
|
|
441 |
|
|
; administrivia.
|
442 |
|
|
; CPU-DATA? is #t if data for the currently selected cpu is to be included.
|
443 |
|
|
"Generating ARGBUF type ...\n""""""#ifndef WANT_CPU\n""\
|
444 |
|
|
/* The ARGBUF struct. */
|
445 |
|
|
struct argbuf {
|
446 |
|
|
/* These are the baseclass definitions. */
|
447 |
|
|
IADDR addr;
|
448 |
|
|
const IDESC *idesc;
|
449 |
|
|
|
450 |
|
|
char profile_p;
|
451 |
|
|
/* ??? Temporary hack for skip insns. */
|
452 |
|
|
char skip_count;
|
453 |
|
|
char unused;
|
454 |
|
|
/* cpu specific data follows */\n""\
|
455 |
|
|
union sem semantic;
|
456 |
|
|
int written;
|
457 |
|
|
union sem_fields fields;\n""\
|
458 |
|
|
CGEN_INSN_INT insn;
|
459 |
|
|
|
460 |
|
|
; This is cpu family specific (member `argbuf' is) so it is machine generated.
|
461 |
|
|
|
462 |
|
|
"Generating SCACHE type ...\n""""#ifndef WANT_CPU\n""\
|
463 |
|
|
/* A cached insn.
|
464 |
|
|
|
465 |
|
|
??? SCACHE used to contain more than just argbuf. We could delete the
|
466 |
|
|
type entirely and always just use ARGBUF, but for future concerns and as
|
467 |
|
|
|
468 |
|
|
|
469 |
|
|
struct scache {
|
470 |
|
|
struct argbuf argbuf;\n""\
|
471 |
|
|
int first_insn_p;
|
472 |
|
|
|
473 |
|
|
; Generate a table of mode data.
|
474 |
|
|
; For now all we need is the names.
|
475 |
|
|
"const char *mode_names[] = {\n"" \"""\",\n"; We don't treat aliases as being different from the real
|
476 |
|
|
; mode here, so ignore them.
|
477 |
|
|
"};\n\n"; Insn profiling support.
|
478 |
|
|
; Generate declarations for local variables needed for modelling code.
|
479 |
|
|
|
480 |
|
|
; (has-attr? self 'COND-CTI))))
|
481 |
|
|
; (string-append
|
482 |
|
|
; (if cti? " int UNUSED taken_p = 0;\n" "")
|
483 |
|
|
; ))
|
484 |
|
|
""; Generate C code to profile INSN.
|
485 |
|
|
; .cpu file loading support
|
486 |
|
|
; Only run sim-analyze-insns! once.
|
487 |
|
|
|
488 |
|
|
; Called before/after the .cpu file has been read in.
|
489 |
|
|
;; Subroutine of -create-virtual-insns!.
|
490 |
|
|
;; Add virtual insn INSN to the database.
|
491 |
|
|
;; We put virtual insns ahead of normal insns because they're kind of special,
|
492 |
|
|
;; and it helps to see them first in lists.
|
493 |
|
|
;; ORDINAL is a used to place the insn ahead of normal insns;
|
494 |
|
|
;; it is a pair so we can do the update for the next virtual insn here.
|
495 |
|
|
; Create the virtual insns.
|
496 |
|
|
"virtual insns";; Record as a pair so -virtual-insn-add! can update it.
|
497 |
|
|
"pbb begin handler""--begin--""\
|
498 |
|
|
{
|
499 |
|
|
#if WITH_SCACHE_PBB_@PREFIX@
|
500 |
|
|
|
501 |
|
|
/* In the switch case FAST_P is a constant, allowing several optimizations
|
502 |
|
|
in any called inline functions. */
|
503 |
|
|
vpc = @prefix@_pbb_begin (current_cpu, FAST_P);
|
504 |
|
|
#else
|
505 |
|
|
#if 0 /* cgen engine can't handle dynamic fast/full switching yet. */
|
506 |
|
|
vpc = @prefix@_pbb_begin (current_cpu, STATE_RUN_FAST_P (CPU_STATE (current_cpu)));
|
507 |
|
|
#else
|
508 |
|
|
|
509 |
|
|
#endif
|
510 |
|
|
#endif
|
511 |
|
|
#endif
|
512 |
|
|
}
|
513 |
|
|
""pbb chain handler""--chain--""\
|
514 |
|
|
{
|
515 |
|
|
|
516 |
|
|
vpc = @prefix@_pbb_chain (current_cpu, sem_arg);
|
517 |
|
|
#ifdef DEFINE_SWITCH
|
518 |
|
|
BREAK (sem);
|
519 |
|
|
#endif
|
520 |
|
|
#endif
|
521 |
|
|
}
|
522 |
|
|
""pbb cti-chain handler""--cti-chain--""\
|
523 |
|
|
{
|
524 |
|
|
#if WITH_SCACHE_PBB_@PREFIX@
|
525 |
|
|
#ifdef DEFINE_SWITCH
|
526 |
|
|
vpc = @prefix@_pbb_cti_chain (current_cpu, sem_arg,
|
527 |
|
|
pbb_br_type, pbb_br_npc);
|
528 |
|
|
BREAK (sem);
|
529 |
|
|
#else
|
530 |
|
|
/* FIXME: Allow provision of explicit ifmt spec in insn spec. */
|
531 |
|
|
vpc = @prefix@_pbb_cti_chain (current_cpu, sem_arg,
|
532 |
|
|
CPU_PBB_BR_TYPE (current_cpu),
|
533 |
|
|
CPU_PBB_BR_NPC (current_cpu));
|
534 |
|
|
|
535 |
|
|
#endif
|
536 |
|
|
}
|
537 |
|
|
""pbb begin handler""--before--""\
|
538 |
|
|
{
|
539 |
|
|
#if WITH_SCACHE_PBB_@PREFIX@
|
540 |
|
|
@prefix@_pbb_before (current_cpu, sem_arg);
|
541 |
|
|
#endif
|
542 |
|
|
}
|
543 |
|
|
""pbb after handler""--after--""\
|
544 |
|
|
{
|
545 |
|
|
#if WITH_SCACHE_PBB_@PREFIX@
|
546 |
|
|
@prefix@_pbb_after (current_cpu, sem_arg);
|
547 |
|
|
#endif
|
548 |
|
|
}
|
549 |
|
|
""invalid insn handler""--invalid--""\
|
550 |
|
|
{
|
551 |
|
|
/* Update the recorded pc in the cpu state struct.
|
552 |
|
|
Only necessary for WITH_SCACHE case, but to avoid the
|
553 |
|
|
conditional compilation .... */
|
554 |
|
|
SET_H_PC (pc);
|
555 |
|
|
/* Virtual insns have zero size. Overwrite vpc with address of next insn
|
556 |
|
|
using the default-insn-bitsize spec. When executing insns in parallel
|
557 |
|
|
we may want to queue the fault and continue execution. */
|
558 |
|
|
|
559 |
|
|
vpc = sim_engine_invalid_insn (current_cpu, pc, vpc);
|
560 |
|
|
|
561 |
|
|
"; Add begin,chain,before,after,invalid handlers if not provided.
|
562 |
|
|
; The code generators should first look for x-foo-@prefix@, then for x-foo.
|
563 |
|
|
; ??? This is good enough for the first pass. Will eventually need to use
|
564 |
|
|
; less C and more RTL.
|
565 |
|
|
; Called after file is read in and global error checks are done
|
566 |
|
|
; to initialize tables.
|
567 |
|
|
; Scan insns, analyzing semantics and computing instruction formats.
|
568 |
|
|
; 'twould be nice to do this in sim-analyze! but it doesn't know whether this
|
569 |
|
|
; needs to be done or not (which is determined by what files are being
|
570 |
|
|
; generated). Since this is an expensive operation, we defer doing this
|
571 |
|
|
; to the files that need it.
|
572 |
|
|
; This can only be done if one isa and one cpu family is being kept.
|
573 |
|
|
; don't include aliases
|
574 |
|
|
; do analyze the semantics
|
575 |
|
|
; Compute the set of sformat argument buffers.
|
576 |
|
|
; Do our own error checking.
|
577 |
|
|
; For debugging.
|
578 |
|
|
;cgen-mem-ops.h
|
579 |
|
|
;cgen-sem-ops.h
|
580 |
|
|
;cgen-ops.c
|
581 |
|
|
;cgen-extract.c
|
582 |
|
|
;cgen-mainloop.in
|
583 |
|
|
|