OSDN Git Service

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