OSDN Git Service

* symbols.c (resolve_symbol_value): Remove "finalize" param,
[pf3gnuchains/pf3gnuchains3x.git] / cgen / sim-model.scm
1 ; Simulator model support, plus misc. things associated with a cpu family.
2 ; Copyright (C) 2000 Red Hat, Inc.
3 ; This file is part of CGEN.
4
5 ; Return C code to define cpu implementation properties.
6
7 (define (-gen-cpu-imp-properties)
8   (string-list
9    "\
10 /* The properties of this cpu's implementation.  */
11
12 static const MACH_IMP_PROPERTIES @cpu@_imp_properties =
13 {
14   sizeof (SIM_CPU),
15 #if WITH_SCACHE
16   sizeof (SCACHE)
17 #else
18   0
19 #endif
20 };\n\n"
21    )
22 )
23 \f
24 ; Insn modeling support.
25
26 ; Generate code to profile hardware elements.
27 ; ??? Not currently used.
28
29 (define (-gen-hw-profile-code)
30   ; Fetch profilable input and output operands of the semantic code.
31   (let ((in-ops (find op-profilable? (sfmt-in-ops (insn-sfmt insn))))
32         (out-ops (find op-profilable? (sfmt-out-ops (insn-sfmt insn)))))
33     (string-list
34      ; For each operand, record its being get/set.
35      (string-list-map (lambda (op) (send op 'gen-profile-code insn #f))
36                       in-ops)
37      (string-list-map (lambda (op) (send op 'gen-profile-code insn #t))
38                       out-ops)
39      ))
40 )
41
42 ; Return decls of hardware element profilers.
43 ; ??? Not currently used.
44
45 (define (-gen-hw-profile-decls)
46   (string-list
47    "/* Hardware profiling handlers.  */\n\n"
48    (string-list-map (lambda (hw)
49                       (string-append "extern void @cpu@_model_mark_get_"
50                                      (gen-sym hw) " (SIM_CPU *"
51                                      (if (hw-scalar? hw)
52                                          ""
53                                          ", int") ; FIXME: get index type
54                                      ");\n"
55                                      "extern void @cpu@_model_mark_set_"
56                                      (gen-sym hw) " (SIM_CPU *"
57                                      (if (hw-scalar? hw)
58                                          ""
59                                          ", int") ; FIXME: get index type
60                                      ");\n"))
61                     (find hw-profilable? (current-hw-list)))
62    "\n"
63    )
64 )
65
66 ; Return name of profiling handler for MODEL, UNIT.
67 ; Also called by sim.scm.
68
69 (define (gen-model-unit-fn-name model unit)
70   (string-append "@cpu@_model_" (gen-sym model) "_" (gen-sym unit))
71 )
72
73 ; Return decls of all insn model handlers.
74 ; This is called from sim-decode.scm.
75
76 (define (gen-model-fn-decls)
77   (let ((gen-args (lambda (args)
78                     (gen-c-args (map (lambda (arg)
79                                        (string-append
80                                         (mode:c-type (mode:lookup (cadr arg)))
81                                         " /*" (car arg) "*/"))
82                                      (find (lambda (arg)
83                                              ; Indices of scalars not passed.
84                                              (not (null? (cdr arg))))
85                                            args)))))
86         )
87
88     (string-list
89      ; -gen-hw-profile-decls
90      "/* Function unit handlers (user written).  */\n\n"
91      (string-list-map
92       (lambda (model)
93         (string-list-map (lambda (unit)
94                            (string-append
95                             "extern int "
96                             (gen-model-unit-fn-name model unit)
97                             " (SIM_CPU *, const IDESC *,"
98                             " int /*unit_num*/, int /*referenced*/"
99                             (gen-args (unit:inputs unit))
100                             (gen-args (unit:outputs unit))
101                             ");\n"))
102                          (model:units model)))
103       (current-model-list))
104      "\n"
105      "/* Profiling before/after handlers (user written) */\n\n"
106      "extern void @cpu@_model_insn_before (SIM_CPU *, int /*first_p*/);\n"
107      "extern void @cpu@_model_insn_after (SIM_CPU *, int /*last_p*/, int /*cycles*/);\n"
108      "\n"
109      ))
110 )
111
112 ; Return name of profile handler for INSN, MODEL.
113
114 (define (-gen-model-insn-fn-name model insn)
115   (string-append "model_" (gen-sym model) "_" (gen-sym insn))
116 )
117
118 ; Return function to model INSN.
119
120 (define (-gen-model-insn-fn model insn)
121   (logit 2 "Processing modeling for " (obj:name insn) ": \"" (insn-syntax insn) "\" ...\n")
122   (string-list
123    "static int\n"
124    (-gen-model-insn-fn-name model insn)
125    ; sem_arg is a void * to keep cgen specific stuff out of sim-model.h
126    " (SIM_CPU *current_cpu, void *sem_arg)\n"
127    "{\n"
128    (if (with-scache?)
129        (gen-define-field-macro (insn-sfmt insn))
130        "")
131    "  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);\n"
132    "  const IDESC * UNUSED idesc = abuf->idesc;\n"
133    ; or: idesc = & CPU_IDESC (current_cpu) ["
134    ; (gen-cpu-insn-enum (mach-cpu (model:mach model)) insn)
135    ; "];\n"
136    "  int cycles = 0;\n"
137    (send insn 'gen-profile-locals model)
138    (if (with-scache?)
139        ""
140        (string-list
141         "  IADDR UNUSED pc = GET_H_PC ();\n"
142         "  CGEN_INSN_INT insn = abuf->insn;\n"
143         (gen-define-ifmt-ifields (insn-ifmt insn) "  " #f #t)
144         (gen-sfmt-op-argbuf-defns (insn-sfmt insn))
145         (gen-extract-ifmt-ifields (insn-ifmt insn) "  " #f #t)
146         (gen-sfmt-op-argbuf-assigns (insn-sfmt insn))))
147    ; Emit code to model the insn.  Function units are handled here.
148    (send insn 'gen-profile-code model "cycles")
149    "  return cycles;\n"
150    (if (with-scache?)
151        (gen-undef-field-macro (insn-sfmt insn))
152        "")
153    "}\n\n")
154 )
155
156 ; Return insn modeling handlers.
157 ; ??? Might wish to reduce the amount of output by combining identical cases.
158 ; ??? Modelling of insns could be table driven, but that puts constraints on
159 ; generality.
160
161 (define (-gen-model-insn-fns)
162   (string-write
163    "/* Model handlers for each insn.  */\n\n"
164    (lambda () (string-write-map
165                (lambda (model)
166                  (string-write-map
167                   (lambda (insn) (-gen-model-insn-fn model insn))
168                   (real-insns (current-insn-list))))
169                (current-model-list)))
170    )
171 )
172 \f
173 ; Generate timing table entry for function unit U while executing INSN.
174 ; U is a <unit> object.
175 ; ARGS is a list of overriding arguments from INSN.
176
177 (define (-gen-insn-unit-timing model insn u args)
178   (string-append
179    "{ "
180    "(int) " (unit:enum u) ", "
181    (number->string (unit:issue u)) ", "
182    (let ((cycles (assq-ref args 'cycles)))
183      (if cycles
184          (number->string (car cycles))
185          (number->string (unit:done u))))
186    " }, "
187    )
188 )
189
190 ; Generate timing table entry for MODEL for INSN.
191
192 (define (-gen-insn-timing model insn)
193   ; Instruction timing is stored as an associative list based on the model.
194   (let ((timing (assq (obj:name model) (insn-timing insn))))
195     ;(display timing) (newline)
196     (string-list
197      "  { "
198      (gen-cpu-insn-enum (mach-cpu (model:mach model)) insn)
199      ", "
200      (if (obj-has-attr? insn 'VIRTUAL)
201          "0"
202          (-gen-model-insn-fn-name model insn))
203      ", { "
204      (string-drop
205       -2
206       (if (not timing)
207           (-gen-insn-unit-timing model insn (model-default-unit model) nil)
208           (let ((units (timing:units (cdr timing))))
209             (string-map (lambda (iunit)
210                           (-gen-insn-unit-timing model insn
211                                                  (iunit:unit iunit)
212                                                  (iunit:args iunit)))
213                         units))))
214      " } },\n"
215      ))
216 )
217
218 ; Generate model timing table for MODEL.
219
220 (define (-gen-model-timing-table model)
221   (string-write
222    "/* Model timing data for `" (obj:name model) "'.  */\n\n"
223    "static const INSN_TIMING " (gen-sym model) "_timing[] = {\n"
224    (lambda () (string-write-map (lambda (insn) (-gen-insn-timing model insn))
225                                 (non-alias-insns (current-insn-list))))
226    "};\n\n"
227    )
228 )
229
230 ; Return C code to define model profiling support stuff.
231
232 (define (-gen-model-profile-data)
233   (string-write
234    "/* We assume UNIT_NONE == 0 because the tables don't always terminate\n"
235    "   entries with it.  */\n\n"
236    (lambda () (string-write-map -gen-model-timing-table (current-model-list)))
237    )
238 )
239
240 ; Return C code to define the model table for MACH.
241
242 (define (-gen-mach-model-table mach)
243   (string-list
244    "\
245 static const MODEL " (gen-sym mach) "_models[] =\n{\n"
246    (string-list-map (lambda (model)
247                       (string-list "  { "
248                                    "\"" (obj:name model) "\", "
249                                    "& " (gen-sym (model:mach model)) "_mach, "
250                                    (model:enum model) ", "
251                                    "TIMING_DATA (& "
252                                    (gen-sym model)
253                                    "_timing[0]), "
254                                    (gen-sym model) "_model_init"
255                                    " },\n"))
256                     (find (lambda (model) (eq? (obj:name mach)
257                                                (obj:name (model:mach model))))
258                           (current-model-list)))
259    "  { 0 }\n"
260    "};\n\n"
261    )
262 )
263
264 ; Return C code to define model init fn.
265
266 (define (-gen-model-init-fn model)
267   (string-list "\
268 static void\n"
269 (gen-sym model) "_model_init (SIM_CPU *cpu)
270 {
271   CPU_MODEL_DATA (cpu) = (void *) zalloc (sizeof (MODEL_"
272    (string-upcase (gen-sym model))
273    "_DATA));
274 }\n\n"
275    )
276 )
277
278 ; Return C code to define model data and support fns.
279
280 (define (-gen-model-defns)
281   (string-write
282    (lambda () (string-write-map -gen-model-init-fn (current-model-list)))
283    "#if WITH_PROFILE_MODEL_P
284 #define TIMING_DATA(td) td
285 #else
286 #define TIMING_DATA(td) 0
287 #endif\n\n"
288    (lambda () (string-write-map -gen-mach-model-table (current-mach-list)))
289    )
290 )
291
292 ; Return C definitions for this cpu family variant.
293
294 (define (-gen-cpu-defns)
295   (string-list "\
296
297 static void
298 @cpu@_prepare_run (SIM_CPU *cpu)
299 {
300   if (CPU_IDESC (cpu) == NULL)
301     @cpu@_init_idesc_table (cpu);
302 }
303
304 static const CGEN_INSN *
305 @cpu@_get_idata (SIM_CPU *cpu, int inum)
306 {
307   return CPU_IDESC (cpu) [inum].idata;
308 }
309
310 ")
311 )
312
313 ; Return C code to define the machine data.
314
315 (define (-gen-mach-defns)
316   (let* ((insns (gen-obj-list-enums (non-multi-insns (current-insn-list))))
317          (last-insn (string-upcase (gen-c-symbol (caar (list-take -1 insns))))))
318     (string-list-map
319      (lambda (mach)
320        (gen-obj-sanitize
321         mach
322         (string-list "\
323 static void\n"
324 (gen-sym mach) "_init_cpu (SIM_CPU *cpu)
325 {
326   CPU_REG_FETCH (cpu) = " (gen-sym (mach-cpu mach)) "_fetch_register;
327   CPU_REG_STORE (cpu) = " (gen-sym (mach-cpu mach)) "_store_register;
328   CPU_PC_FETCH (cpu) = " (gen-sym (mach-cpu mach)) "_h_pc_get;
329   CPU_PC_STORE (cpu) = " (gen-sym (mach-cpu mach)) "_h_pc_set;
330   CPU_GET_IDATA (cpu) = @cpu@_get_idata;
331   CPU_MAX_INSNS (cpu) = @CPU@_INSN_" last-insn " + 1;
332   CPU_INSN_NAME (cpu) = cgen_insn_name;
333   CPU_FULL_ENGINE_FN (cpu) = @cpu@_engine_run_full;
334 #if WITH_FAST
335   CPU_FAST_ENGINE_FN (cpu) = @cpu@_engine_run_fast;
336 #else
337   CPU_FAST_ENGINE_FN (cpu) = @cpu@_engine_run_full;
338 #endif
339 }
340
341 const MACH " (gen-sym mach) "_mach =
342 {
343   \"" (obj:name mach) "\", "
344   "\"" (mach-bfd-name mach) "\", "
345   (mach-enum mach) ",\n"
346   "  " (number->string (cpu-word-bitsize (mach-cpu mach))) ", "
347   ; FIXME: addr-bitsize: delete
348   (number->string (cpu-word-bitsize (mach-cpu mach))) ", "
349   "& " (gen-sym mach) "_models[0], "
350   "& " (gen-sym (mach-cpu mach)) "_imp_properties,
351   " (gen-sym mach) "_init_cpu,
352   @cpu@_prepare_run
353 };
354
355 ")))
356
357    (current-mach-list)))
358 )
359 \f
360 ; Top level file generators.
361
362 ; Generate model.c
363
364 (define (cgen-model.c)
365   (logit 1 "Generating " (gen-cpu-name) " model.c ...\n")
366
367   (sim-analyze-insns!)
368
369   ; Turn parallel execution support on if cpu needs it.
370   (set-with-parallel?! (state-parallel-exec?))
371
372   (string-write
373    (gen-copyright "Simulator model support for @cpu@."
374                   CURRENT-COPYRIGHT CURRENT-PACKAGE)
375    "\
376 #define WANT_CPU @cpu@
377 #define WANT_CPU_@CPU@
378
379 #include \"sim-main.h\"
380
381 /* The profiling data is recorded here, but is accessed via the profiling
382    mechanism.  After all, this is information for profiling.  */
383
384 #if WITH_PROFILE_MODEL_P
385
386 "
387    -gen-model-insn-fns
388    -gen-model-profile-data
389 "#endif /* WITH_PROFILE_MODEL_P */\n\n"
390
391    -gen-model-defns
392    -gen-cpu-imp-properties
393    -gen-cpu-defns
394    -gen-mach-defns
395    )
396 )