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.
6 (gen-c-symbol (string-append "UNIT_"
7 (string-upcase (obj:str-name u))))
10 ; Return C code to define cpu implementation properties.
12 (define (/gen-cpu-imp-properties)
15 /* The properties of this cpu's implementation. */
17 static const MACH_IMP_PROPERTIES @cpu@_imp_properties =
29 ; Insn modeling support.
31 ; Generate code to profile hardware elements.
32 ; ??? Not currently used.
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)))))
39 ; For each operand, record its being get/set.
40 (string-list-map (lambda (op) (send op 'gen-profile-code insn #f))
42 (string-list-map (lambda (op) (send op 'gen-profile-code insn #t))
47 ; Return decls of hardware element profilers.
48 ; ??? Not currently used.
50 (define (/gen-hw-profile-decls)
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 *"
58 ", int") ; FIXME: get index type
60 "extern void @prefix@_model_mark_set_"
61 (gen-sym hw) " (@cpu@_cpu *"
64 ", int") ; FIXME: get index type
66 (find hw-profilable? (current-hw-list)))
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")
76 ; Return name of profiling handler for MODEL, UNIT.
77 ; Also called by sim.scm.
79 (define (gen-model-unit-fn-name model unit when)
80 (string-append "model_" (gen-sym unit) "_" (symbol->string when))
83 (define (gen-model-unit-fn-decl model unit when)
84 (let ((gen-args (lambda (args)
85 (gen-c-args (map (lambda (arg)
87 (mode:c-type (mode:lookup (cadr arg)))
88 " /*" (symbol->string (car arg)) "*/"))
90 ; Indices of scalars not passed.
91 (not (null? (cdr arg))))
96 (gen-model-unit-fn-name model unit when)
97 " (@cpu@_cpu *cpu, const struct @prefix@_idesc *idesc,"
99 (if (equal? when 'after)
100 ", unsigned long long referenced" "")
101 (gen-args (unit:inputs unit))
102 (gen-args (unit:outputs unit))
106 ; Return decls of all insn model handlers.
108 (define (gen-model-fn-decls model)
111 "// Function unit handlers\n"
112 "// To be overridden as needed.\n"
113 (string-list-map (lambda (unit)
115 (gen-model-unit-fn-decl model unit 'before)
119 (gen-model-unit-fn-decl model unit 'after)
121 " return timing[idesc->sem_index].units[unit_num].done;\n"
127 ; Return name of profile handler for INSN, MODEL.
129 (define (/gen-model-insn-fn-name model insn when)
130 (string-append "model_" (gen-sym insn) "_" (symbol->string when))
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))
137 ; Return declaration of function to model INSN.
139 (define (/gen-model-insn-fn-decl model insn when)
142 (/gen-model-insn-fn-name model insn when)
143 " (@cpu@_cpu *current_cpu, @prefix@_scache *sem);\n"
147 (define (/gen-model-insn-fn-decls model)
149 " // These methods call the appropriate unit modeller(s) for each insn.\n"
153 " " (/gen-model-insn-fn-decl model insn 'before)
154 " " (/gen-model-insn-fn-decl model insn 'after)))
155 (real-insns (current-insn-list)))
159 ; Return function to model INSN.
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)))
166 (/gen-model-insn-qualified-fn-name model insn when)
167 " (@cpu@_cpu *current_cpu, @prefix@_scache *sem)\n"
170 (gen-define-field-macro sfmt)
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)
178 (send insn 'gen-profile-locals model)
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")
192 (gen-undef-field-macro sfmt)
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
203 (define (/gen-model-insn-fns)
205 "/* Model handlers for each insn. */\n\n"
206 (lambda () (string-write-map
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"
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)))
225 (define (/gen-model-class-decls model)
229 (gen-enum-decl 'unit_number "unit types"
233 ; "apply append" squeezes out nils.
236 ; create <model_name>-<unit-name> for each unit
237 (let ((units (model:units model)))
241 (cons (obj:name unit)
242 (cons '- (atlist-attrs (obj-atlist model)))))
246 " unit_number unit;\n"
251 ; FIXME: revisit MAX_UNITS
252 " static const int MAX_UNITS = "
254 (let ((insn-list (real-insns (current-insn-list))))
255 (if (null? insn-list)
258 (map (lambda (lengths) (apply max lengths))
260 (let ((timing (insn-timing insn)))
263 (map (lambda (insn-timing)
264 (if (null? (cdr insn-timing))
266 (length (timing:units (cdr insn-timing)))))
273 ; Return the C++ class representing the given model.
274 (define (gen-model-class model)
277 class " (gen-model-class-name model) " : public cgen_model
280 " (gen-model-class-name model) " (@cpu@_cpu *cpu);
282 // Call the proper unit modelling function for the given insn.
283 UINT model_before (@cpu@_cpu *current_cpu, @prefix@_scache* sem)
285 return (this->*(timing[sem->idesc->sem_index].model_before)) (current_cpu, sem);
287 UINT model_after (@cpu@_cpu *current_cpu, @prefix@_scache* sem)
289 return (this->*(timing[sem->idesc->sem_index].model_after)) (current_cpu, sem);
292 (gen-model-fn-decls model)
297 (/gen-model-insn-fn-decls model)
298 (/gen-model-class-decls model)
301 typedef UINT (" (gen-model-class-name model) "::*model_function) (@cpu@_cpu* current_cpu, @prefix@_scache* sem);
304 // This is an integer that identifies this insn.
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];
313 static const insn_timing timing[];
319 ; Return the C++ classes representing the current list of models.
320 (define (gen-model-classes)
325 (gen-model-class model)))
326 (current-model-list))
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.
333 (define (/gen-insn-unit-timing model insn u args)
336 (gen-model-class-name model) "::" (unit:enum u) ", "
337 (number->string (unit:issue u)) ", "
338 (let ((cycles (assq-ref args 'cycles)))
340 (number->string (car cycles))
341 (number->string (unit:done u))))
346 ; Generate timing table entry for MODEL for INSN.
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)
354 (gen-cpu-insn-enum (mach-cpu (model:mach model)) insn)
356 (if (obj-has-attr? insn 'VIRTUAL)
359 "& " (/gen-model-insn-qualified-fn-name model insn 'before) ", "
360 "& " (/gen-model-insn-qualified-fn-name model insn 'after)))
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
376 ; Generate model timing table for MODEL.
378 (define (/gen-model-timing-table model)
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)))))
388 ; Return C code to define model profiling support stuff.
390 (define (/gen-model-profile-data)
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)))
398 ; Return C code to define the model table for MACH.
400 (define (/gen-mach-model-table mach)
403 static const MODEL " (gen-sym mach) "_models[] =\n{\n"
404 (string-list-map (lambda (model)
406 "\"" (obj:name model) "\", "
407 "& " (gen-sym (model:mach model)) "_mach, "
408 (model:enum model) ", "
412 (gen-sym model) "_model_init"
414 (find (lambda (model) (eq? (obj:name mach)
415 (obj:name (model:mach model))))
416 (current-model-list)))
422 ; Return C code to define model init fn.
424 (define (/gen-model-init-fn model)
427 (gen-sym model) "_model_init (@cpu@_cpu *cpu)
429 cpu->model_data = new @PREFIX@_MODEL_DATA;
434 ; Return C code to define model data and support fns.
436 (define (/gen-model-defns)
438 (lambda () (string-write-map /gen-model-init-fn (current-model-list)))
439 "#if WITH_PROFILE_MODEL_P
440 #define TIMING_DATA(td) td
442 #define TIMING_DATA(td) 0
444 (lambda () (string-write-map /gen-mach-model-table (current-mach-list)))
448 ; Return C definitions for this cpu family variant.
450 (define (/gen-cpu-defns)
454 ; Return C code to define the machine data.
456 (define (/gen-mach-defns)
463 (gen-sym mach) "_init_cpu (@cpu@_cpu *cpu)
465 @prefix@_init_idesc_table (cpu);
468 const MACH " (gen-sym mach) "_mach =
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
485 ; Top level file generators.
489 (define (cgen-model.cxx)
490 (logit 1 "Generating " (gen-cpu-name) "-model.cxx ...\n")
493 ; Turn parallel execution support on if cpu needs it.
494 (set-with-parallel?! (state-parallel-exec?))
497 (gen-c-copyright "Simulator model support for @prefix@."
498 copyright-red-hat package-red-hat-simulators)
502 #include \"config.h\"
506 using namespace @cpu@; // FIXME: namespace organization still wip
508 /* The profiling data is recorded here, but is accessed via the profiling
509 mechanism. After all, this is information for profiling. */
513 /gen-model-profile-data
514 ; not adapted for sid yet
516 ; /gen-cpu-imp-properties
522 (define (cgen-model.h)
523 (logit 1 "Generating " (gen-cpu-name) "-model.h ...\n")
527 (gen-c-copyright "Simulator model support for @prefix@."
528 copyright-red-hat package-red-hat-simulators)
530 #ifndef @PREFIX@_MODEL_H
531 #define @PREFIX@_MODEL_H
533 #include \"cgen-cpu.h\"
534 #include \"cgen-model.h\"
538 using namespace cgen;
545 #endif // @PREFIX@_MODEL_H