OSDN Git Service

Updated Russian translation.
[pf3gnuchains/pf3gnuchains3x.git] / cgen / sid-model.scm
1 ; Simulator model support, plus misc. things associated with a cpu family.
2 ; Copyright (C) 2000, 2002, 2003, 2006, 2009 Red Hat, Inc.
3 ; This file is part of CGEN.
4
5 (define (unit:enum u)
6   (gen-c-symbol (string-append "UNIT_"
7                                (string-upcase (obj:str-name u))))
8 )
9
10 ; Return C code to define cpu implementation properties.
11
12 (define (/gen-cpu-imp-properties)
13   (string-list
14    "\
15 /* The properties of this cpu's implementation.  */
16
17 static const MACH_IMP_PROPERTIES @cpu@_imp_properties =
18 {
19   sizeof (@cpu@_cpu),
20 #if WITH_SCACHE
21   sizeof (SCACHE)
22 #else
23   0
24 #endif
25 };\n\n"
26    )
27 )
28 \f
29 ; Insn modeling support.
30
31 ; Generate code to profile hardware elements.
32 ; ??? Not currently used.
33
34 (define (/gen-hw-profile-code)
35   ; Fetch profilable input and output operands of the semantic code.
36   (let ((in-ops (find op-profilable? (sfmt-in-ops (insn-sfmt insn))))
37         (out-ops (find op-profilable? (sfmt-out-ops (insn-sfmt insn)))))
38     (string-list
39      ; For each operand, record its being get/set.
40      (string-list-map (lambda (op) (send op 'gen-profile-code insn #f))
41                       in-ops)
42      (string-list-map (lambda (op) (send op 'gen-profile-code insn #t))
43                       out-ops)
44      ))
45 )
46
47 ; Return decls of hardware element profilers.
48 ; ??? Not currently used.
49
50 (define (/gen-hw-profile-decls)
51   (string-list
52    "/* Hardware profiling handlers.  */\n\n"
53    (string-list-map (lambda (hw)
54                       (string-append "extern void @prefix@_model_mark_get_"
55                                      (gen-sym hw) " (@cpu@_cpu *"
56                                      (if (hw-scalar? hw)
57                                          ""
58                                          ", int") ; FIXME: get index type
59                                      ");\n"
60                                      "extern void @prefix@_model_mark_set_"
61                                      (gen-sym hw) " (@cpu@_cpu *"
62                                      (if (hw-scalar? hw)
63                                          ""
64                                          ", int") ; FIXME: get index type
65                                      ");\n"))
66                     (find hw-profilable? (current-hw-list)))
67    "\n"
68    )
69 )
70
71 ; Return the name of the class representing the given MODEL.
72 (define (gen-model-class-name model)
73   (string-append "@prefix@_" (gen-sym model) "_model")
74 )
75
76 ; Return name of profiling handler for MODEL, UNIT.
77 ; Also called by sim.scm.
78
79 (define (gen-model-unit-fn-name model unit when)
80   (string-append "model_" (gen-sym unit) "_" (symbol->string when))
81 )
82
83 (define (gen-model-unit-fn-decl model unit when)
84   (let ((gen-args (lambda (args)
85                     (gen-c-args (map (lambda (arg)
86                                        (string-append
87                                         (mode:c-type (mode:lookup (cadr arg)))
88                                         " /*" (symbol->string (car arg)) "*/"))
89                                      (find (lambda (arg)
90                                              ; Indices of scalars not passed.
91                                              (not (null? (cdr arg))))
92                                            args)))))
93         )
94     (string-append
95      "  virtual UINT "
96      (gen-model-unit-fn-name model unit when)
97      " (@cpu@_cpu *cpu, const struct @prefix@_idesc *idesc,"
98      " int unit_num"
99      (if (equal? when 'after)
100          ", unsigned long long referenced" "")
101      (gen-args (unit:inputs unit))
102      (gen-args (unit:outputs unit))
103      ")\n"))
104 )
105
106 ; Return decls of all insn model handlers.
107
108 (define (gen-model-fn-decls model)
109   (string-list
110    "\n"
111    "// Function unit handlers\n"
112    "// To be overridden as needed.\n"
113    (string-list-map (lambda (unit)
114                       (string-append
115                        (gen-model-unit-fn-decl model unit 'before)
116                        "    {\n"
117                        "      return 0;\n"
118                        "    }\n"
119                        (gen-model-unit-fn-decl model unit 'after)
120                        "    {\n"
121                        "      return timing[idesc->sem_index].units[unit_num].done;\n"
122                        "    }\n"))
123                     (model:units model))
124   )
125 )
126
127 ; Return name of profile handler for INSN, MODEL.
128
129 (define (/gen-model-insn-fn-name model insn when)
130   (string-append "model_" (gen-sym insn) "_" (symbol->string when))
131 )
132
133 (define (/gen-model-insn-qualified-fn-name model insn when)
134   (string-append (gen-model-class-name model) "::" (/gen-model-insn-fn-name model insn when))
135 )
136
137 ; Return declaration of function to model INSN.
138
139 (define (/gen-model-insn-fn-decl model insn when)
140   (string-list
141    "UINT "
142    (/gen-model-insn-fn-name model insn when)
143    " (@cpu@_cpu *current_cpu, @prefix@_scache *sem);\n"
144   )
145 )
146
147 (define (/gen-model-insn-fn-decls model)
148   (string-list
149    "  // These methods call the appropriate unit modeller(s) for each insn.\n"
150    (string-list-map
151     (lambda (insn)
152       (string-list
153        "  " (/gen-model-insn-fn-decl model insn 'before)
154        "  " (/gen-model-insn-fn-decl model insn 'after)))
155     (real-insns (current-insn-list)))
156   )
157 )
158
159 ; Return function to model INSN.
160
161 (define (/gen-model-insn-fn model insn when)
162   (logit 2 "Processing modeling for " (obj:name insn) ": \"" (insn-syntax insn) "\" ...\n")
163   (let ((sfmt (insn-sfmt insn)))
164     (string-list
165      "UINT\n"
166      (/gen-model-insn-qualified-fn-name model insn when)
167      " (@cpu@_cpu *current_cpu, @prefix@_scache *sem)\n"
168      "{\n"
169      (if (with-scache?)
170          (gen-define-field-macro sfmt)
171          "")
172      "  const @prefix@_scache* abuf = sem;\n"
173      "  const @prefix@_idesc* idesc = abuf->idesc;\n"
174      ; or: idesc = & CPU_IDESC (current_cpu) ["
175      ; (gen-cpu-insn-enum (mach-cpu (model:mach model)) insn)
176      ; "];\n"
177      "  int cycles = 0;\n"
178      (send insn 'gen-profile-locals model)
179      (if (with-scache?)
180          ""
181          (string-list
182           "  PCADDR UNUSED pc = current_cpu->hardware.h_pc;\n"
183           "  @prefix@_insn_word insn = abuf->insn;\n"
184           (gen-define-ifields (sfmt-iflds sfmt) (sfmt-length sfmt) "  " #f)
185           (gen-sfmt-argvars-defns sfmt)
186           (gen-extract-ifields (sfmt-iflds sfmt) (sfmt-length sfmt) "  " #f)
187           (gen-sfmt-argvars-assigns sfmt)))
188      ; Emit code to model the insn.  Function units are handled here.
189      (send insn 'gen-profile-code model when "cycles")
190      "  return cycles;\n"
191      (if (with-scache?)
192          (gen-undef-field-macro sfmt)
193          "")
194      "}\n\n"))
195 )
196
197
198 ; Return insn modeling handlers.
199 ; ??? Might wish to reduce the amount of output by combining identical cases.
200 ; ??? Modelling of insns could be table driven, but that puts constraints on
201 ; generality.
202
203 (define (/gen-model-insn-fns)
204   (string-write
205    "/* Model handlers for each insn.  */\n\n"
206    (lambda () (string-write-map
207                (lambda (model)
208                  (string-write
209                   ; Generate the model constructor.
210                   (gen-model-class-name model) "::" (gen-model-class-name model) " (@cpu@_cpu *cpu)\n"
211                   "  : cgen_model (cpu)\n"
212                   "{\n"
213                   "}\n"
214                   "\n")
215                  (string-write-map
216                   (lambda (insn)
217                     (string-list
218                      (/gen-model-insn-fn model insn 'before)
219                      (/gen-model-insn-fn model insn 'after)))
220                   (real-insns (current-insn-list))))
221                (current-model-list)))
222    )
223 )
224
225 (define (/gen-model-class-decls model)
226   (string-append
227    "\n"
228    "  "
229    (gen-enum-decl 'unit_number "unit types"
230                   "UNIT_"
231                   (cons '(none)
232                         (append
233                          ; "apply append" squeezes out nils.
234                          (apply append
235                                 (list 
236                                  ; create <model_name>-<unit-name> for each unit
237                                  (let ((units (model:units model)))
238                                    (if (null? units)
239                                        nil
240                                        (map (lambda (unit)
241                                               (cons (obj:name unit)
242                                                     (cons '- (atlist-attrs (obj-atlist model)))))
243                                             units)))))
244                          '((max)))))
245    "  struct unit {\n"
246    "    unit_number unit;\n"
247    "    UINT issue;\n"
248    "    UINT done;\n"
249    "  };\n\n"
250
251    ; FIXME: revisit MAX_UNITS
252   "  static const int MAX_UNITS = "
253   (number->string
254    (let ((insn-list (real-insns (current-insn-list))))
255      (if (null? insn-list)
256          1
257          (apply max
258                 (map (lambda (lengths) (apply max lengths))
259                      (map (lambda (insn)
260                             (let ((timing (insn-timing insn)))
261                               (if (null? timing)
262                                   '(1)
263                                   (map (lambda (insn-timing)
264                                          (if (null? (cdr insn-timing))
265                                              '1
266                                              (length (timing:units (cdr insn-timing)))))
267                                        timing))))
268                           insn-list))))))
269    ";\n"
270   )
271 )
272
273 ; Return the C++ class representing the given model.
274 (define (gen-model-class model)
275   (string-list
276    "\
277 class " (gen-model-class-name model) " : public cgen_model
278 {
279 public:
280   " (gen-model-class-name model) " (@cpu@_cpu *cpu);
281
282   // Call the proper unit modelling function for the given insn.
283   UINT model_before (@cpu@_cpu *current_cpu, @prefix@_scache* sem)
284     {
285       return (this->*(timing[sem->idesc->sem_index].model_before)) (current_cpu, sem);
286     } 
287   UINT model_after (@cpu@_cpu *current_cpu, @prefix@_scache* sem)
288     {
289       return (this->*(timing[sem->idesc->sem_index].model_after)) (current_cpu, sem);
290     } 
291 "
292    (gen-model-fn-decls model)
293    "\
294
295 protected:
296 "
297    (/gen-model-insn-fn-decls model)
298    (/gen-model-class-decls model)
299 "\
300
301   typedef UINT (" (gen-model-class-name model) "::*model_function) (@cpu@_cpu* current_cpu, @prefix@_scache* sem);
302
303   struct insn_timing {
304     // This is an integer that identifies this insn.
305     UINT num;
306     // Functions to handle insn-specific profiling.
307     model_function model_before;
308     model_function model_after;
309     // Array of function units used by this insn.
310     unit units[MAX_UNITS];
311   };
312
313   static const insn_timing timing[];
314 };
315 "
316   )
317 )
318
319 ; Return the C++ classes representing the current list of models.
320 (define (gen-model-classes)
321    (string-list-map
322     (lambda (model)
323       (string-list
324        "\n"
325        (gen-model-class model)))
326     (current-model-list))
327 )
328 \f
329 ; Generate timing table entry for function unit U while executing INSN.
330 ; U is a <unit> object.
331 ; ARGS is a list of overriding arguments from INSN.
332
333 (define (/gen-insn-unit-timing model insn u args)
334   (string-append
335    "{ "
336    (gen-model-class-name model) "::" (unit:enum u) ", "
337    (number->string (unit:issue u)) ", "
338    (let ((cycles (assq-ref args 'cycles)))
339      (if cycles
340          (number->string (car cycles))
341          (number->string (unit:done u))))
342    " }, "
343    )
344 )
345
346 ; Generate timing table entry for MODEL for INSN.
347
348 (define (/gen-insn-timing model insn)
349   ; Instruction timing is stored as an associative list based on the model.
350   (let ((timing (assq (obj:name model) (insn-timing insn))))
351     ;(display timing) (newline)
352     (string-list
353      "  { "
354      (gen-cpu-insn-enum (mach-cpu (model:mach model)) insn)
355      ", "
356      (if (obj-has-attr? insn 'VIRTUAL)
357          "0, 0"
358          (string-append
359           "& " (/gen-model-insn-qualified-fn-name model insn 'before) ", "
360           "& " (/gen-model-insn-qualified-fn-name model insn 'after)))
361      ", { "
362      (string-drop
363       -2
364       (if (not timing)
365           (/gen-insn-unit-timing model insn (model-default-unit model) nil)
366           (let ((units (timing:units (cdr timing))))
367             (string-map (lambda (iunit)
368                           (/gen-insn-unit-timing model insn
369                                                  (iunit:unit iunit)
370                                                  (iunit:args iunit)))
371                         units))))
372      " } },\n"
373      ))
374 )
375
376 ; Generate model timing table for MODEL.
377
378 (define (/gen-model-timing-table model)
379   (string-write
380    "/* Model timing data for `" (obj:name model) "'.  */\n\n"
381    "const " (gen-model-class-name model) "::insn_timing " (gen-model-class-name model) "::timing[] = {\n"
382    (lambda () (string-write-map (lambda (insn) (/gen-insn-timing model insn))
383                                 (non-multi-insns (non-alias-insns (current-insn-list)))))
384    "};\n\n"
385    )
386 )
387
388 ; Return C code to define model profiling support stuff.
389
390 (define (/gen-model-profile-data)
391   (string-write
392    "/* We assume UNIT_NONE == 0 because the tables don't always terminate\n"
393    "   entries with it.  */\n\n"
394    (lambda () (string-write-map /gen-model-timing-table (current-model-list)))
395    )
396 )
397
398 ; Return C code to define the model table for MACH.
399
400 (define (/gen-mach-model-table mach)
401   (string-list
402    "\
403 static const MODEL " (gen-sym mach) "_models[] =\n{\n"
404    (string-list-map (lambda (model)
405                       (string-list "  { "
406                                    "\"" (obj:name model) "\", "
407                                    "& " (gen-sym (model:mach model)) "_mach, "
408                                    (model:enum model) ", "
409                                    "TIMING_DATA (& "
410                                    (gen-sym model)
411                                    "_timing[0]), "
412                                    (gen-sym model) "_model_init"
413                                    " },\n"))
414                     (find (lambda (model) (eq? (obj:name mach)
415                                                (obj:name (model:mach model))))
416                           (current-model-list)))
417    "  { 0 }\n"
418    "};\n\n"
419    )
420 )
421
422 ; Return C code to define model init fn.
423
424 (define (/gen-model-init-fn model)
425   (string-list "\
426 static void\n"
427 (gen-sym model) "_model_init (@cpu@_cpu *cpu)
428 {
429   cpu->model_data = new @PREFIX@_MODEL_DATA;
430 }\n\n"
431    )
432 )
433
434 ; Return C code to define model data and support fns.
435
436 (define (/gen-model-defns)
437   (string-write
438    (lambda () (string-write-map /gen-model-init-fn (current-model-list)))
439    "#if WITH_PROFILE_MODEL_P
440 #define TIMING_DATA(td) td
441 #else
442 #define TIMING_DATA(td) 0
443 #endif\n\n"
444    (lambda () (string-write-map /gen-mach-model-table (current-mach-list)))
445    )
446 )
447
448 ; Return C definitions for this cpu family variant.
449
450 (define (/gen-cpu-defns)
451   "" 
452 )
453
454 ; Return C code to define the machine data.
455
456 (define (/gen-mach-defns)
457   (string-list-map
458    (lambda (mach)
459      (gen-obj-sanitize
460       mach
461       (string-list "\
462 static void\n"
463 (gen-sym mach) "_init_cpu (@cpu@_cpu *cpu)
464 {
465   @prefix@_init_idesc_table (cpu);
466 }
467
468 const MACH " (gen-sym mach) "_mach =
469 {
470   \"" (obj:name mach) "\", "
471   "\"" (mach-bfd-name mach) "\",
472   " (number->string (cpu-word-bitsize (mach-cpu mach))) ", "
473   ; FIXME: addr-bitsize: delete
474   (number->string (cpu-word-bitsize (mach-cpu mach))) ", "
475   "& " (gen-sym mach) "_models[0], "
476   "& " (gen-sym (mach-cpu mach)) "_imp_properties,
477   " (gen-sym mach) "_init_cpu
478 };
479
480 ")))
481
482    (current-mach-list))
483 )
484 \f
485 ; Top level file generators.
486
487 ; Generate model.cxx
488
489 (define (cgen-model.cxx)
490   (logit 1 "Generating " (gen-cpu-name) "-model.cxx ...\n")
491   (assert-keep-one)
492
493   ; Turn parallel execution support on if cpu needs it.
494   (set-with-parallel?! (state-parallel-exec?))
495
496   (string-write
497    (gen-c-copyright "Simulator model support for @prefix@."
498                   copyright-red-hat package-red-hat-simulators)
499    "\
500
501 #if HAVE_CONFIG_H
502 #include \"config.h\"
503 #endif
504 #include \"@cpu@.h\"
505
506 using namespace @cpu@; // FIXME: namespace organization still wip
507
508 /* The profiling data is recorded here, but is accessed via the profiling
509    mechanism.  After all, this is information for profiling.  */
510
511 "
512    /gen-model-insn-fns
513    /gen-model-profile-data
514 ;  not adapted for sid yet
515 ;   /gen-model-defns
516 ;   /gen-cpu-imp-properties
517 ;   /gen-cpu-defns
518 ;   /gen-mach-defns
519    )
520 )
521
522 (define (cgen-model.h)
523   (logit 1 "Generating " (gen-cpu-name) "-model.h ...\n")
524   (assert-keep-one)
525
526   (string-write
527    (gen-c-copyright "Simulator model support for @prefix@."
528                   copyright-red-hat package-red-hat-simulators)
529    "\
530 #ifndef @PREFIX@_MODEL_H
531 #define @PREFIX@_MODEL_H
532
533 #include \"cgen-cpu.h\"
534 #include \"cgen-model.h\"
535
536 namespace @cpu@
537 {
538 using namespace cgen;
539 "
540    (gen-model-classes)
541    "\
542
543 } // namespace @cpu@
544
545 #endif // @PREFIX@_MODEL_H
546 "
547   )
548 )