OSDN Git Service

gdb/testsuite/
[pf3gnuchains/pf3gnuchains3x.git] / cgen / model.scm
1 ; CPU implementation description.
2 ; Copyright (C) 2000, 2003, 2009 Red Hat, Inc.
3 ; This file is part of CGEN.
4 ; See file COPYING.CGEN for details.
5
6 ; A model is an implementation of a mach.
7 ; NOTE: wip [with all the caveats that implies].
8 ; The intent here is to define the aspects of a CPU that affect performance,
9 ; usable by any tool (but for the immediate future a simulator).
10
11 ; Pipeline specification.
12
13 (define <pipeline>
14   (class-make '<pipeline> nil '(name comment atlist elms) nil))
15
16 (define (pipeline:length p) (length (elm-xget p 'elms)))
17 \f
18 ; Function unit specification.
19
20 ; FIXME: Might wish to record which pipeline element(s) the unit is associated
21 ; with.  At the moment pipeline data isn't used, but later.
22
23 (define <unit>
24   (class-make '<unit>
25               '(<ident>)
26               '(
27                 ; wip
28                 issue done
29                 ; Lists of (name mode) pairs that record unit state.
30                 state
31                 ; Lists of (name mode [default-value]).
32                 inputs outputs
33                 ; RTL of code to invoke to do profiling.
34                 ; `nil' means use the default
35                 ; ??? Not currently used since all profiling handlers
36                 ; are user-written.
37                 profile
38                 ; Model this unit is associated with.
39                 model-name
40                 )
41               nil))
42
43 ; ??? Rather than create a circularity, we record the model's symbol in
44 ; the `model' element.
45 ; FIXME: Shouldn't use current-model-lookup.  Guile is better at printing
46 ; things with circularities now, so should probably put back the circularity
47 ; and delete the current-model-lookup reference.
48 (define (unit:model u) (current-model-lookup (elm-xget u 'model-name)))
49 (define unit:issue (elm-make-getter <unit> 'issue))
50 (define unit:done (elm-make-getter <unit> 'done))
51 (define unit:state (elm-make-getter <unit> 'state))
52 (define unit:inputs (elm-make-getter <unit> 'inputs))
53 (define unit:outputs (elm-make-getter <unit> 'outputs))
54 (define unit:profile (elm-make-getter <unit> 'profile))
55
56 ; Create a copy of unit U with new values for ISSUE and DONE.
57 ; This is used when recording an instruction's timing information.
58 ; ??? This might be better recorded in a different class from UNIT
59 ; since we're not creating a new unit, we're just special casing it for
60 ; one instruction.
61 ; FIXME: No longer used.
62
63 (define (unit:make-insn-timing u issue done)
64   (let ((result (object-copy-top u)))
65     (elm-xset! result 'issue issue)
66     (elm-xset! result 'done done)
67     result)
68 )
69 \f
70 ; The `<model>' class.
71 ;
72 ; FETCH is the instruction fetch process as it relates to the implementation.
73 ; e.g.
74 ; - how many instructions are fetched at once
75 ; - how those instructions are initially processed for delivery to the
76 ;   appropriate pipeline
77 ; RETIRE is used to specify any final processing needed to complete an insn.
78 ; PIPELINES is a list of pipeline objects.
79 ; UNITS is a list of function units.
80 ; STATE is a list of (var mode) pairs.
81 ;
82 ; For the more complicated cpus this can get really complicated really fast.
83 ; No intent is made to get there in one day.
84
85 (define <model>
86   (class-make '<model>
87               '(<ident>)
88               '(mach prefetch retire pipelines state units)
89               nil))
90
91 (define model:mach (elm-make-getter <model> 'mach))
92 (define model:prefetch (elm-make-getter <model> 'prefetch))
93 (define model:retire (elm-make-getter <model> 'retire))
94 (define model:pipelines (elm-make-getter <model> 'pipelines))
95 (define model:state (elm-make-getter <model> 'state))
96 (define model:units (elm-make-getter <model> 'units))
97
98 (define (model:enum m)
99   (gen-c-symbol (string-append "MODEL_" (string-upcase (obj:str-name m))))
100 )
101
102 (define (models-for-mach mach)
103   (let ((mach-name (obj:name mach)))
104     (find (lambda (model)
105             (eq? (obj:name (model:mach model)) mach-name))
106           (current-model-list)))
107 )
108 \f
109 ; Parse a `prefetch' spec.
110
111 (define (/prefetch-parse context expr)
112   nil
113 )
114
115 ; Parse a `retire' spec.
116
117 (define (/retire-parse context expr)
118   nil
119 )
120
121 ; Parse a `pipeline' spec.
122 ; ??? Perhaps we should also use name/value pairs here, but that's an
123 ; unnecessary complication at this point in time.
124
125 (define (/pipeline-parse context model-name spec) ; name comments attrs elements)
126   (if (not (= (length spec) 4))
127       (parse-error context "pipeline spec not `name comment attrs elements'" spec))
128   (apply make (cons <pipeline> spec))
129 )
130
131 ; Parse a function `unit' spec.
132 ; ??? Perhaps we should also use name/value pairs here, but that's an
133 ; unnecessary complication at this point in time.
134
135 (define (/unit-parse context model-name spec) ; name comments attrs elements)
136   (if (not (= (length spec) 9))
137       (parse-error context "unit spec not `name comment attrs issue done state inputs outputs profile'" spec))
138   (apply make (append (cons <unit> spec) (list model-name)))
139 )
140 \f
141 ; Parse a model definition.
142 ; This is the main routine for building a model object from a
143 ; description in the .cpu file.
144 ; All arguments are in raw (non-evaluated) form.
145
146 (define (/model-parse context name comment attrs mach-name prefetch retire pipelines state units)
147   (logit 2 "Processing model " name " ...\n")
148
149   ;; Pick out name first to augment the error context.
150   (let* ((name (parse-name context name))
151          (context (context-append-name context name))
152          (mach (current-mach-lookup mach-name)))
153
154     (if (null? units)
155         (parse-error context "there must be at least one function unit" name))
156
157     (if mach ; is `mach' being "kept"?
158         (let ((model-obj
159                (make <model>
160                      name
161                      (parse-comment context comment)
162                      (atlist-parse context attrs "cpu")
163                      mach
164                      (/prefetch-parse context prefetch)
165                      (/retire-parse context retire)
166                      (map (lambda (p) (/pipeline-parse context name p)) pipelines)
167                      state
168                      (map (lambda (u) (/unit-parse context name u)) units))))
169           model-obj)
170
171         (begin
172           ; MACH wasn't found, ignore this model.
173           (logit 2 "Nonexistant mach " mach-name ", ignoring " name ".\n")
174           #f)))
175 )
176
177 ; Read a model description.
178 ; This is the main routine for analyzing models in the .cpu file.
179 ; CONTEXT is a <context> object for error messages.
180 ; ARG-LIST is an associative list of field name and field value.
181 ; /model-parse is invoked to create the `model' object.
182
183 (define (/model-read context . arg-list)
184   (let (
185         (name nil)      ; name of model
186         (comment nil)   ; description of model
187         (attrs nil)     ; attributes
188         (mach nil)      ; mach this model implements
189         (prefetch nil)  ; instruction prefetch handling
190         (retire nil)    ; instruction completion handling
191         (pipelines nil) ; list of pipelines
192         (state nil)     ; list of (name mode) pairs to record state
193         (units nil)     ; list of function units
194         )
195
196     (let loop ((arg-list arg-list))
197       (if (null? arg-list)
198           nil
199           (let ((arg (car arg-list))
200                 (elm-name (caar arg-list)))
201             (case elm-name
202               ((name) (set! name (cadr arg)))
203               ((comment) (set! comment (cadr arg)))
204               ((attrs) (set! attrs (cdr arg)))
205               ((mach) (set! mach (cadr arg)))
206               ((prefetch) (set! prefetch (cadr arg)))
207               ((retire) (set! retire (cadr arg)))
208               ((pipeline) (set! pipelines (cons (cdr arg) pipelines)))
209               ((state) (set! state (cdr arg)))
210               ((unit) (set! units (cons (cdr arg) units)))
211               (else (parse-error context "invalid model arg" arg)))
212             (loop (cdr arg-list)))))
213
214     ; Now that we've identified the elements, build the object.
215     (/model-parse context name comment attrs mach prefetch retire pipelines state units))
216 )
217
218 ; Define a cpu model object, name/value pair list version.
219
220 (define define-model
221   (lambda arg-list
222     (let ((m (apply /model-read (cons (make-current-context "define-model")
223                                       arg-list))))
224       (if m
225           (current-model-add! m))
226       m))
227 )
228 \f
229 ; Instruction timing.
230
231 ; There is one of these for each model timing description per instruction.
232
233 (define <timing> (class-make '<timing> nil '(model units) nil))
234
235 (define timing:model (elm-make-getter <timing> 'model))
236 (define timing:units (elm-make-getter <timing> 'units))
237
238 ; timing:units is a list of these.
239 ; ARGS is a list of (name value) pairs.
240
241 (define <iunit> (class-make '<iunit> nil '(unit args) nil))
242
243 (define iunit:unit (elm-make-getter <iunit> 'unit))
244 (define iunit:args (elm-make-getter <iunit> 'args))
245
246 ; Return the default unit used by MODEL.
247 ; ??? For now this is always u-exec.
248
249 (define (model-default-unit model)
250   (object-assq 'u-exec (model:units model))
251 )
252
253 ; Subroutine of parse-insn-timing to parse the timing spec for MODEL.
254 ; The result is a <timing> object.
255
256 (define (/insn-timing-parse-model context model spec)
257   (make <timing> model
258         (map (lambda (unit-timing-desc)
259                (let ((type (car unit-timing-desc))
260                      (args (cdr unit-timing-desc)))
261                  (case type
262                    ((unit) ; syntax is `unit name (arg1 val1) ...'
263                     (let ((unit (object-assq (car args)
264                                              (model:units model))))
265                       (if (not unit)
266                           (parse-error context "unknown function unit" args))
267                       (make <iunit> unit (cdr args))))
268                    (else (parse-error context "bad unit timing spec"
269                                       unit-timing-desc)))))
270              spec))
271 )
272
273 ; Given the timing information for an instruction return an associative
274 ; list of timing objects (one for each specified model).
275 ; INSN-TIMING-DESC is a list of
276 ; (model1 (unit unit1-name ...) ...) (model2 (unit unit1-name ...) ...) ...
277 ; Entries for models not included (because the machine wasn't selected)
278 ; are returned as (model1), i.e. an empty unit list.
279
280 (define (parse-insn-timing context insn-timing-desc)
281   (logit 3 "  parse-insn-timing: context= " (context-prefix context)
282          ", desc= " insn-timing-desc "\n")
283   (map (lambda (model-timing-desc)
284          (let* ((model-name (car model-timing-desc))
285                 (model (current-model-lookup model-name)))
286            (cons model-name
287                  (if model
288                      (/insn-timing-parse-model context model
289                                                (cdr model-timing-desc))
290                      '()))))
291        insn-timing-desc)
292 )
293 \f
294 ; Called before a .cpu file is read in.
295
296 (define (model-init!)
297
298   (reader-add-command! 'define-model
299                        "\
300 Define a cpu model, name/value pair list version.
301 "
302                        nil 'arg-list define-model
303   )
304
305   *UNSPECIFIED*
306 )
307
308 ; Called after a .cpu file has been read in.
309
310 (define (model-finish!)
311   *UNSPECIFIED*
312 )