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.
5 ; Return C code to define cpu implementation properties.
7 (define (-gen-cpu-imp-properties)
10 /* The properties of this cpu's implementation. */
12 static const MACH_IMP_PROPERTIES @cpu@_imp_properties =
24 ; Insn modeling support.
26 ; Generate code to profile hardware elements.
27 ; ??? Not currently used.
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)))))
34 ; For each operand, record its being get/set.
35 (string-list-map (lambda (op) (send op 'gen-profile-code insn #f))
37 (string-list-map (lambda (op) (send op 'gen-profile-code insn #t))
42 ; Return decls of hardware element profilers.
43 ; ??? Not currently used.
45 (define (-gen-hw-profile-decls)
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 *"
53 ", int") ; FIXME: get index type
55 "extern void @cpu@_model_mark_set_"
56 (gen-sym hw) " (SIM_CPU *"
59 ", int") ; FIXME: get index type
61 (find hw-profilable? (current-hw-list)))
66 ; Return name of profiling handler for MODEL, UNIT.
67 ; Also called by sim.scm.
69 (define (gen-model-unit-fn-name model unit)
70 (string-append "@cpu@_model_" (gen-sym model) "_" (gen-sym unit))
73 ; Return decls of all insn model handlers.
74 ; This is called from sim-decode.scm.
76 (define (gen-model-fn-decls)
77 (let ((gen-args (lambda (args)
78 (gen-c-args (map (lambda (arg)
80 (mode:c-type (mode:lookup (cadr arg)))
81 " /*" (car arg) "*/"))
83 ; Indices of scalars not passed.
84 (not (null? (cdr arg))))
89 ; -gen-hw-profile-decls
90 "/* Function unit handlers (user written). */\n\n"
93 (string-list-map (lambda (unit)
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))
102 (model:units model)))
103 (current-model-list))
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"
112 ; Return name of profile handler for INSN, MODEL.
114 (define (-gen-model-insn-fn-name model insn)
115 (string-append "model_" (gen-sym model) "_" (gen-sym insn))
118 ; Return function to model INSN.
120 (define (-gen-model-insn-fn model insn)
121 (logit 2 "Processing modeling for " (obj:name insn) ": \"" (insn-syntax insn) "\" ...\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"
129 (gen-define-field-macro (insn-sfmt insn))
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)
137 (send insn 'gen-profile-locals model)
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")
151 (gen-undef-field-macro (insn-sfmt insn))
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
161 (define (-gen-model-insn-fns)
163 "/* Model handlers for each insn. */\n\n"
164 (lambda () (string-write-map
167 (lambda (insn) (-gen-model-insn-fn model insn))
168 (real-insns (current-insn-list))))
169 (current-model-list)))
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.
177 (define (-gen-insn-unit-timing model insn u args)
180 "(int) " (unit:enum u) ", "
181 (number->string (unit:issue u)) ", "
182 (let ((cycles (assq-ref args 'cycles)))
184 (number->string (car cycles))
185 (number->string (unit:done u))))
190 ; Generate timing table entry for MODEL for INSN.
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)
198 (gen-cpu-insn-enum (mach-cpu (model:mach model)) insn)
200 (if (obj-has-attr? insn 'VIRTUAL)
202 (-gen-model-insn-fn-name model insn))
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
218 ; Generate model timing table for MODEL.
220 (define (-gen-model-timing-table model)
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))))
230 ; Return C code to define model profiling support stuff.
232 (define (-gen-model-profile-data)
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)))
240 ; Return C code to define the model table for MACH.
242 (define (-gen-mach-model-table mach)
245 static const MODEL " (gen-sym mach) "_models[] =\n{\n"
246 (string-list-map (lambda (model)
248 "\"" (obj:name model) "\", "
249 "& " (gen-sym (model:mach model)) "_mach, "
250 (model:enum model) ", "
254 (gen-sym model) "_model_init"
256 (find (lambda (model) (eq? (obj:name mach)
257 (obj:name (model:mach model))))
258 (current-model-list)))
264 ; Return C code to define model init fn.
266 (define (-gen-model-init-fn model)
269 (gen-sym model) "_model_init (SIM_CPU *cpu)
271 CPU_MODEL_DATA (cpu) = (void *) zalloc (sizeof (MODEL_"
272 (string-upcase (gen-sym model))
278 ; Return C code to define model data and support fns.
280 (define (-gen-model-defns)
282 (lambda () (string-write-map -gen-model-init-fn (current-model-list)))
283 "#if WITH_PROFILE_MODEL_P
284 #define TIMING_DATA(td) td
286 #define TIMING_DATA(td) 0
288 (lambda () (string-write-map -gen-mach-model-table (current-mach-list)))
292 ; Return C definitions for this cpu family variant.
294 (define (-gen-cpu-defns)
298 @cpu@_prepare_run (SIM_CPU *cpu)
300 if (CPU_IDESC (cpu) == NULL)
301 @cpu@_init_idesc_table (cpu);
304 static const CGEN_INSN *
305 @cpu@_get_idata (SIM_CPU *cpu, int inum)
307 return CPU_IDESC (cpu) [inum].idata;
313 ; Return C code to define the machine data.
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))))))
324 (gen-sym mach) "_init_cpu (SIM_CPU *cpu)
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;
335 CPU_FAST_ENGINE_FN (cpu) = @cpu@_engine_run_fast;
337 CPU_FAST_ENGINE_FN (cpu) = @cpu@_engine_run_full;
341 const MACH " (gen-sym mach) "_mach =
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,
357 (current-mach-list)))
360 ; Top level file generators.
364 (define (cgen-model.c)
365 (logit 1 "Generating " (gen-cpu-name) " model.c ...\n")
369 ; Turn parallel execution support on if cpu needs it.
370 (set-with-parallel?! (state-parallel-exec?))
373 (gen-copyright "Simulator model support for @cpu@."
374 CURRENT-COPYRIGHT CURRENT-PACKAGE)
376 #define WANT_CPU @cpu@
377 #define WANT_CPU_@CPU@
379 #include \"sim-main.h\"
381 /* The profiling data is recorded here, but is accessed via the profiling
382 mechanism. After all, this is information for profiling. */
384 #if WITH_PROFILE_MODEL_P
388 -gen-model-profile-data
389 "#endif /* WITH_PROFILE_MODEL_P */\n\n"
392 -gen-cpu-imp-properties