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.
5 ; Return C code to define cpu implementation properties.
8 (gen-c-symbol (string-append "UNIT_"
9 (string-upcase (obj:str-name (unit:model u)))
11 (string-upcase (obj:str-name u))))
14 (define (/gen-cpu-imp-properties)
17 /* The properties of this cpu's implementation. */
19 static const MACH_IMP_PROPERTIES @cpu@_imp_properties =
31 ; Insn modeling support.
33 ; Generate code to profile hardware elements.
34 ; ??? Not currently used.
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)))))
41 ; For each operand, record its being get/set.
42 (string-list-map (lambda (op) (send op 'gen-profile-code insn #f))
44 (string-list-map (lambda (op) (send op 'gen-profile-code insn #t))
49 ; Return decls of hardware element profilers.
50 ; ??? Not currently used.
52 (define (/gen-hw-profile-decls)
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 *"
60 ", int") ; FIXME: get index type
62 "extern void @cpu@_model_mark_set_"
63 (gen-sym hw) " (SIM_CPU *"
66 ", int") ; FIXME: get index type
68 (find hw-profilable? (current-hw-list)))
73 ; Return name of profiling handler for MODEL, UNIT.
74 ; Also called by sim.scm.
76 (define (gen-model-unit-fn-name model unit)
77 (string-append "@cpu@_model_" (gen-sym model) "_" (gen-sym unit))
80 ; Return decls of all insn model handlers.
81 ; This is called from sim-decode.scm.
83 (define (gen-model-fn-decls)
84 (let ((gen-args (lambda (args)
85 (gen-c-args (map (lambda (arg)
87 (mode:c-type (mode:lookup (cadr arg)))
88 " /*" (car arg) "*/"))
90 ; Indices of scalars not passed.
91 (not (null? (cdr arg))))
96 ; /gen-hw-profile-decls
97 "/* Function unit handlers (user written). */\n\n"
100 (string-list-map (lambda (unit)
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))
109 (model:units model)))
110 (current-model-list))
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"
119 ; Return name of profile handler for INSN, MODEL.
121 (define (/gen-model-insn-fn-name model insn)
122 (string-append "model_" (gen-sym model) "_" (gen-sym insn))
125 ; Return function to model INSN.
127 (define (/gen-model-insn-fn model insn)
128 (logit 2 "Processing modeling for " (obj:name insn) ": \"" (insn-syntax insn) "\" ...\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"
136 (gen-define-field-macro (insn-sfmt insn))
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)
144 (send insn 'gen-profile-locals model)
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")
158 (gen-undef-field-macro (insn-sfmt insn))
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
168 (define (/gen-model-insn-fns)
170 "/* Model handlers for each insn. */\n\n"
171 (lambda () (string-write-map
174 (lambda (insn) (/gen-model-insn-fn model insn))
175 (real-insns (current-insn-list))))
176 (current-model-list)))
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.
184 (define (/gen-insn-unit-timing model insn u args)
187 "(int) " (unit:enum u) ", "
188 (number->string (unit:issue u)) ", "
189 (let ((cycles (assq-ref args 'cycles)))
191 (number->string (car cycles))
192 (number->string (unit:done u))))
197 ; Generate timing table entry for MODEL for INSN.
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)
205 (gen-cpu-insn-enum (mach-cpu (model:mach model)) insn)
207 (if (obj-has-attr? insn 'VIRTUAL)
209 (/gen-model-insn-fn-name model insn))
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
225 ; Generate model timing table for MODEL.
227 (define (/gen-model-timing-table model)
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))))
237 ; Return C code to define model profiling support stuff.
239 (define (/gen-model-profile-data)
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)))
247 ; Return C code to define the model table for MACH.
249 (define (/gen-mach-model-table mach)
252 static const MODEL " (gen-sym mach) "_models[] =\n{\n"
253 (string-list-map (lambda (model)
255 "\"" (obj:str-name model) "\", "
256 "& " (gen-sym (model:mach model)) "_mach, "
257 (model:enum model) ", "
261 (gen-sym model) "_model_init"
263 (find (lambda (model) (eq? (obj:name mach)
264 (obj:name (model:mach model))))
265 (current-model-list)))
271 ; Return C code to define model init fn.
273 (define (/gen-model-init-fn model)
276 (gen-sym model) "_model_init (SIM_CPU *cpu)
278 CPU_MODEL_DATA (cpu) = (void *) zalloc (sizeof (MODEL_"
279 (string-upcase (gen-sym model))
285 ; Return C code to define model data and support fns.
287 (define (/gen-model-defns)
289 (lambda () (string-write-map /gen-model-init-fn (current-model-list)))
290 "#if WITH_PROFILE_MODEL_P
291 #define TIMING_DATA(td) td
293 #define TIMING_DATA(td) 0
295 (lambda () (string-write-map /gen-mach-model-table (current-mach-list)))
299 ; Return C definitions for this cpu family variant.
301 (define (/gen-cpu-defns)
305 @cpu@_prepare_run (SIM_CPU *cpu)
307 if (CPU_IDESC (cpu) == NULL)
308 @prefix@_init_idesc_table (cpu);
311 static const CGEN_INSN *
312 @cpu@_get_idata (SIM_CPU *cpu, int inum)
314 return CPU_IDESC (cpu) [inum].idata;
320 ; Return C code to define the machine data.
322 (define (/gen-mach-defns)
329 (gen-sym mach) "_init_cpu (SIM_CPU *cpu)
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;
340 CPU_FAST_ENGINE_FN (cpu) = @prefix@_engine_run_fast;
342 CPU_FAST_ENGINE_FN (cpu) = @prefix@_engine_run_full;
346 const MACH " (gen-sym mach) "_mach =
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,
365 ; Top level file generators.
369 (define (cgen-model.c)
370 (logit 1 "Generating " (gen-cpu-name) "'s model.c ...\n")
374 ; Turn parallel execution support on if cpu needs it.
375 (set-with-parallel?! (state-parallel-exec?))
378 (gen-c-copyright "Simulator model support for @cpu@."
379 CURRENT-COPYRIGHT CURRENT-PACKAGE)
381 #define WANT_CPU @cpu@
382 #define WANT_CPU_@CPU@
384 #include \"sim-main.h\"
386 /* The profiling data is recorded here, but is accessed via the profiling
387 mechanism. After all, this is information for profiling. */
389 #if WITH_PROFILE_MODEL_P
393 /gen-model-profile-data
394 "#endif /* WITH_PROFILE_MODEL_P */\n\n"
397 /gen-cpu-imp-properties