1 |
6 |
jlechner |
@c Copyright (C) 2000, 2009 Red Hat, Inc.
|
2 |
|
|
@c This file is part of the CGEN manual.
|
3 |
|
|
@c For copying conditions, see the file cgen.texi.
|
4 |
|
|
|
5 |
|
|
@node Writing an application
|
6 |
|
|
@chapter Writing an application
|
7 |
|
|
@cindex Writing an application
|
8 |
|
|
|
9 |
|
|
This chapter contains information for those wishing to write their own
|
10 |
|
|
CGEN application.
|
11 |
|
|
|
12 |
|
|
@menu
|
13 |
|
|
* File Layout:: Organization of source files
|
14 |
|
|
* File Generation Process:: Workflow in cgen
|
15 |
|
|
* Coding Conventions:: Coding conventions
|
16 |
|
|
* Accessing Loaded Data:: Reading data from loaded .cpu files
|
17 |
|
|
* Arch Name References:: Architecture names in generated code
|
18 |
|
|
* String Building:: Building long strings and writing them out
|
19 |
|
|
* COS:: Cgen's Object System
|
20 |
|
|
@end menu
|
21 |
|
|
|
22 |
|
|
@node File Layout
|
23 |
|
|
@section File Layout
|
24 |
|
|
|
25 |
|
|
Source files in cgen are organized in a very specific way.@footnote{As the
|
26 |
|
|
number of source files grows the entire layout may be changed, but until then
|
27 |
|
|
this is how things are.} It makes it easy to find things.
|
28 |
|
|
|
29 |
|
|
@itemize @bullet
|
30 |
|
|
|
31 |
|
|
@item top level file is cgen-<app>.scm
|
32 |
|
|
|
33 |
|
|
The best way to create this file is to copy an existing application's file
|
34 |
|
|
(e.g. cgen-opc.scm) and modify to suit.
|
35 |
|
|
|
36 |
|
|
@item file <app>.scm contains general app-specific utilities
|
37 |
|
|
|
38 |
|
|
@item other files are <app>-foo.scm
|
39 |
|
|
|
40 |
|
|
@item add entry to dev.scm (load-<app>)
|
41 |
|
|
|
42 |
|
|
@end itemize
|
43 |
|
|
|
44 |
|
|
@node File Generation Process
|
45 |
|
|
@section File Generation Process
|
46 |
|
|
|
47 |
|
|
This is an overview of cgen workflow.
|
48 |
|
|
|
49 |
|
|
@itemize @bullet
|
50 |
|
|
|
51 |
|
|
@item cgen is started with list of files to generate and code generation
|
52 |
|
|
options
|
53 |
|
|
|
54 |
|
|
@item source code is loaded
|
55 |
|
|
|
56 |
|
|
@itemize @minus
|
57 |
|
|
|
58 |
|
|
@item application independent code is loaded if not compiled in
|
59 |
|
|
|
60 |
|
|
@item application specific code is loaded
|
61 |
|
|
|
62 |
|
|
Currently app-specific code is never compiled in.
|
63 |
|
|
@footnote{This dates from a time when CGEN supported being compiled with
|
64 |
|
|
Hobbit. That support is gone, though something else may take its place.}
|
65 |
|
|
|
66 |
|
|
@itemize @minus
|
67 |
|
|
@item doesn't affect speed as much as application independent stuff
|
68 |
|
|
@item subject to more frequent changes
|
69 |
|
|
@item makes it easier to do application development if changes to .scm
|
70 |
|
|
files are "ready to use"
|
71 |
|
|
@end itemize
|
72 |
|
|
@end itemize
|
73 |
|
|
|
74 |
|
|
@item ultimately procedure `cpu-load' is called which is the main driver for
|
75 |
|
|
loading .cpu files
|
76 |
|
|
|
77 |
|
|
@item various data structures are initialized
|
78 |
|
|
|
79 |
|
|
@item data files are loaded
|
80 |
|
|
|
81 |
|
|
@itemize @minus
|
82 |
|
|
@item main <arch>.cpu file is loaded
|
83 |
|
|
|
84 |
|
|
There is a #include-like mechanism for loading other files so big
|
85 |
|
|
architectures can be broken up into several files.
|
86 |
|
|
|
87 |
|
|
While the architecture description is being loaded, entries not requested
|
88 |
|
|
are discarded. This happens, for example, when building a simulator:
|
89 |
|
|
there's no point in keeping instructions specific to a machine that is
|
90 |
|
|
not being generated. What to keep is based on the MACH and ISA attributes.
|
91 |
|
|
|
92 |
|
|
@item application specific data files are loaded
|
93 |
|
|
|
94 |
|
|
e.g. <arch>.sim
|
95 |
|
|
@end itemize
|
96 |
|
|
|
97 |
|
|
@item builtin elements are created
|
98 |
|
|
|
99 |
|
|
@item each requested file is generated by calling cgen-<file> generator
|
100 |
|
|
|
101 |
|
|
The output is written to the output file with @code{with-output-to-file} so
|
102 |
|
|
the code must write to @code{(current-output-port)}.
|
103 |
|
|
|
104 |
|
|
Some files require heavy duty processing of the cpu description.
|
105 |
|
|
For example the simulator computes the instruction formats from the
|
106 |
|
|
instruction field lists of each instruction. This computation is deferred
|
107 |
|
|
to each cgen-<file> procedure that needs it and must be explicitly requested
|
108 |
|
|
by them. The results are cached so this is only done once of course.
|
109 |
|
|
|
110 |
|
|
@item additional processing for some opcodes files
|
111 |
|
|
|
112 |
|
|
Several opcodes files are built from three sources.
|
113 |
|
|
|
114 |
|
|
@itemize @minus
|
115 |
|
|
@item generated code
|
116 |
|
|
|
117 |
|
|
@item section in <arch>.opc file
|
118 |
|
|
|
119 |
|
|
It's not appropriate to put large amounts of C (or perhaps any C) in
|
120 |
|
|
cgen description files, yet some things are best expressed in some
|
121 |
|
|
other language (e.g. assembler/disassembler operand parsing/printing).
|
122 |
|
|
|
123 |
|
|
@item foo.in file
|
124 |
|
|
|
125 |
|
|
It seems cleaner to put large amounts of non-machine-generated C
|
126 |
|
|
in separate files from code generator.
|
127 |
|
|
@end itemize
|
128 |
|
|
|
129 |
|
|
@end itemize
|
130 |
|
|
|
131 |
|
|
@node Coding Conventions
|
132 |
|
|
@section Coding Conventions
|
133 |
|
|
|
134 |
|
|
@itemize @bullet
|
135 |
|
|
@item unless definition occupies one line, final trailing parenthesis is on
|
136 |
|
|
a line by itself beginning in column one
|
137 |
|
|
@item definitions internal to a source file begin with '-'
|
138 |
|
|
@item global state variables are named *foo-bar*
|
139 |
|
|
[FIXME: current code needs updating]
|
140 |
|
|
@item avoid uppercase, except for constants (e.g. @code{*UNSPECIFIED*})
|
141 |
|
|
@item procedures that return a boolean result end in '?'
|
142 |
|
|
@item procedures that modify something end in '!'
|
143 |
|
|
@item classes are named <name>
|
144 |
|
|
@end itemize
|
145 |
|
|
|
146 |
|
|
@node Accessing Loaded Data
|
147 |
|
|
@section Accessing Loaded Data
|
148 |
|
|
|
149 |
|
|
Each kind of description file entry (defined with `define-foo') is recorded
|
150 |
|
|
in an object of class <foo>.@footnote{not true for <arch> but will be RSN}
|
151 |
|
|
All the data is collected together in an object of class
|
152 |
|
|
<arch>.
|
153 |
|
|
@footnote{modes aren't recorded here, should they be?}
|
154 |
|
|
|
155 |
|
|
Data for the currently selected architecture is obtained with several
|
156 |
|
|
access functions.
|
157 |
|
|
|
158 |
|
|
@smallexample
|
159 |
|
|
(current-arch-name)
|
160 |
|
|
- return symbol that is the name of the arch
|
161 |
|
|
- this is the name specified with `define-arch'
|
162 |
|
|
|
163 |
|
|
(current-arch-comment)
|
164 |
|
|
- return the comment specified with `define-arch'
|
165 |
|
|
|
166 |
|
|
(current-arch-atlist)
|
167 |
|
|
- return the attributes specified with `define-arch'
|
168 |
|
|
|
169 |
|
|
(current-arch-default-alignment)
|
170 |
|
|
- return a symbol indicated the default alignment
|
171 |
|
|
- one of aligned, unaligned, forced
|
172 |
|
|
|
173 |
|
|
(current-arch-insn-lsb0?)
|
174 |
|
|
- return a #t if the least significant bit in a word is numbered 0
|
175 |
|
|
- return a #f if the most significant bit in a word is numbered 0
|
176 |
|
|
|
177 |
|
|
(current-arch-mach-name-list)
|
178 |
|
|
- return a list of names (as symbols) of all machs in the architecture
|
179 |
|
|
|
180 |
|
|
(current-arch-isa-name-list)
|
181 |
|
|
- return a list of names (as symbols) of all isas in the architecture
|
182 |
|
|
|
183 |
|
|
For most of the remaining elements, there are three main accessors:
|
184 |
|
|
[foo is sometimes abbreviated]
|
185 |
|
|
- current-foo-list - returns list of <foo> objects in the architecture
|
186 |
|
|
- current-foo-add! - add a <foo> object to the architecture
|
187 |
|
|
- current-foo-lookup - lookup the <foo> object based on its name
|
188 |
|
|
|
189 |
|
|
<atlist>
|
190 |
|
|
(current-attr-list)
|
191 |
|
|
(current-attr-add!)
|
192 |
|
|
(current-attr-lookup)
|
193 |
|
|
|
194 |
|
|
<enum>
|
195 |
|
|
(current-enum-list)
|
196 |
|
|
(current-enum-add!)
|
197 |
|
|
(current-enum-lookup)
|
198 |
|
|
|
199 |
|
|
<keyword>
|
200 |
|
|
(current-kw-list)
|
201 |
|
|
(current-kw-add!)
|
202 |
|
|
(current-kw-lookup)
|
203 |
|
|
|
204 |
|
|
<isa>
|
205 |
|
|
(current-isa-list)
|
206 |
|
|
(current-isa-add!)
|
207 |
|
|
(current-isa-lookup)
|
208 |
|
|
|
209 |
|
|
<cpu>
|
210 |
|
|
(current-cpu-list)
|
211 |
|
|
(current-cpu-add!)
|
212 |
|
|
(current-cpu-lookup)
|
213 |
|
|
|
214 |
|
|
<mach>
|
215 |
|
|
(current-mach-list)
|
216 |
|
|
(current-mach-add!)
|
217 |
|
|
(current-mach-lookup)
|
218 |
|
|
|
219 |
|
|
<model>
|
220 |
|
|
(current-model-list)
|
221 |
|
|
(current-model-add!)
|
222 |
|
|
(current-model-lookup)
|
223 |
|
|
|
224 |
|
|
<hardware>
|
225 |
|
|
(current-hw-list)
|
226 |
|
|
(current-hw-add!)
|
227 |
|
|
(current-hw-lookup)
|
228 |
|
|
|
229 |
|
|
<ifield>
|
230 |
|
|
(current-ifld-list)
|
231 |
|
|
(current-ifld-add!)
|
232 |
|
|
(current-ifld-lookup)
|
233 |
|
|
|
234 |
|
|
<operand>
|
235 |
|
|
(current-op-list)
|
236 |
|
|
(current-op-add!)
|
237 |
|
|
(current-op-lookup)
|
238 |
|
|
|
239 |
|
|
<insn>
|
240 |
|
|
(current-insn-list)
|
241 |
|
|
(current-insn-add!)
|
242 |
|
|
(current-insn-lookup)
|
243 |
|
|
|
244 |
|
|
<macro-insn>
|
245 |
|
|
(current-minsn-list)
|
246 |
|
|
(current-minsn-add!)
|
247 |
|
|
(current-minsn-lookup)
|
248 |
|
|
|
249 |
|
|
(current-ifmt-list)
|
250 |
|
|
- return list of computed <iformat> objects
|
251 |
|
|
|
252 |
|
|
(current-sfmt-list)
|
253 |
|
|
- return list of computed <sformat> objects
|
254 |
|
|
|
255 |
|
|
[there are a few more to be documented, not sure they'll remain as is]
|
256 |
|
|
@end smallexample
|
257 |
|
|
|
258 |
|
|
@node Arch Name References
|
259 |
|
|
@section Arch Name References
|
260 |
|
|
|
261 |
|
|
To simplify writing code generators, system names can be
|
262 |
|
|
specified with fixed strings rather than having to compute them.
|
263 |
|
|
The output is post-processed to convert the strings to the actual names.
|
264 |
|
|
Upper and lower case names are supported.
|
265 |
|
|
|
266 |
|
|
@itemize @bullet
|
267 |
|
|
@item For the architecture name use @@arch@@, @@ARCH@@.
|
268 |
|
|
@item For the cpu family name use @@cpu@@, @@CPU@@.
|
269 |
|
|
@item For the prefix use @@prefix@@, @@PREFIX@@.
|
270 |
|
|
@end itemize
|
271 |
|
|
|
272 |
|
|
The @samp{prefix} notion is to segregate different code for the same
|
273 |
|
|
cpu family. For example, this is used to segregate the ARM ISA from the
|
274 |
|
|
Thumb ISA.
|
275 |
|
|
|
276 |
|
|
@node String Building
|
277 |
|
|
@section String Building
|
278 |
|
|
|
279 |
|
|
Output generation uses a combination of writing text out as it is computed
|
280 |
|
|
and building text for later writing out.
|
281 |
|
|
|
282 |
|
|
The top level file generator uses @code{string-write}. It takes string-lists
|
283 |
|
|
and thunks as arguments and writes each argument in turn to stdout.
|
284 |
|
|
String-lists are lists of strings (nested arbitrarily deep). It's cheaper
|
285 |
|
|
to @code{cons} long strings together than to use @code{string-append}.
|
286 |
|
|
Thunks return string-lists to write out, but isn't computed until all
|
287 |
|
|
preceding arguments to `string-write' have been written out. This allows
|
288 |
|
|
deferring building up of large amounts of text until it needs to be.
|
289 |
|
|
|
290 |
|
|
The main procedures for building strings and writing them out are:
|
291 |
|
|
|
292 |
|
|
@itemize @bullet
|
293 |
|
|
|
294 |
|
|
@item (string-write string-list-or-thunk1 string-list-or-thunk2 @dots{})
|
295 |
|
|
|
296 |
|
|
Loops over arguments writing them out in turn.
|
297 |
|
|
|
298 |
|
|
@item (string-write-map proc string-list-or-thunk-list)
|
299 |
|
|
|
300 |
|
|
Apply proc to each element in string-list-or-thunk-list and write out
|
301 |
|
|
the result.
|
302 |
|
|
|
303 |
|
|
@item (string-list arg1 arg2 @dots{})
|
304 |
|
|
|
305 |
|
|
Return list of arguments. This is identical to @code{list} except it
|
306 |
|
|
is intended to take string-lists as arguments.
|
307 |
|
|
|
308 |
|
|
@item (string-list-map proc arg-list)
|
309 |
|
|
|
310 |
|
|
Return list of @code{proc} applied to each element of @code{arg-list}.
|
311 |
|
|
This is identical to @code{map} except it is intended to take strings
|
312 |
|
|
as arguments.
|
313 |
|
|
|
314 |
|
|
@item (string-append string1 string2 @dots{})
|
315 |
|
|
|
316 |
|
|
For small arguments it's just as well to use @code{string-append}.
|
317 |
|
|
This is a standard Scheme procedure. The output is also easier to read
|
318 |
|
|
when developing interactively. And some subroutines are used in multiple
|
319 |
|
|
contexts including some where strings are required, so sometimes you
|
320 |
|
|
have to use @code{string-append}.
|
321 |
|
|
|
322 |
|
|
@end itemize
|
323 |
|
|
|
324 |
|
|
@node COS
|
325 |
|
|
@section COS
|
326 |
|
|
|
327 |
|
|
COS is CGEN's Object System. It's a simple OO system for Guile that
|
328 |
|
|
was written to provide something useful until Guile had its own.
|
329 |
|
|
COS will be replaced with GOOPs if the Scheme implementation of CGEN is kept.
|
330 |
|
|
|
331 |
|
|
The pure Scheme implementation of COS uses vectors to record objects and
|
332 |
|
|
classes.
|
333 |
|
|
@c There no longer is a C implementation, but keep this for awhile.
|
334 |
|
|
@c The C implementation uses smobs (though classes are still
|
335 |
|
|
@c implemented with vectors).
|
336 |
|
|
|
337 |
|
|
A complete list of user-visible functions is at the top of @file{cos.scm}.
|
338 |
|
|
|
339 |
|
|
Here is a list of the frequently used ones.
|
340 |
|
|
|
341 |
|
|
@itemize @bullet
|
342 |
|
|
|
343 |
|
|
@item (class-make name parent-name-list element-list method-list)
|
344 |
|
|
|
345 |
|
|
Use @code{class-make} to define a class.
|
346 |
|
|
|
347 |
|
|
@smallexample
|
348 |
|
|
name: symbol, <name-of-class>
|
349 |
|
|
parent-name-list: list of symbols, names of each parent class
|
350 |
|
|
element-list: list of either symbols or (symbol .@: initial-value)
|
351 |
|
|
method-list: list of (symbol .@: lambda)
|
352 |
|
|
@end smallexample
|
353 |
|
|
|
354 |
|
|
The result is the class's definition. It is usually assigned to a global
|
355 |
|
|
variable with same name as class's name. Current cgen code always does
|
356 |
|
|
this. It's not a requirement but it is convention.
|
357 |
|
|
|
358 |
|
|
@item (new <class-name>)
|
359 |
|
|
|
360 |
|
|
Create a new object with @code{new}.
|
361 |
|
|
@code{<class-name>} is typically the global variable that recorded
|
362 |
|
|
the results of @code{class-make}. The result is a new object of the
|
363 |
|
|
requested class. Class elements have either an "undefined" value
|
364 |
|
|
or an initial value if one was specified when the class was defined.
|
365 |
|
|
|
366 |
|
|
@item (define-getters class-name prefix element-list)
|
367 |
|
|
|
368 |
|
|
Elements (aka members) are read/written with "accessors".
|
369 |
|
|
Read accessors are defined with @code{define-getters}, which
|
370 |
|
|
creates one procedure for each element, each defined as
|
371 |
|
|
@code{(prefix-element-name object)}.
|
372 |
|
|
|
373 |
|
|
This is a macro so don't quote anything.
|
374 |
|
|
|
375 |
|
|
@item (define-setters class-name prefix element-list)
|
376 |
|
|
|
377 |
|
|
Write accessors are defined with @code{define-setters}, which
|
378 |
|
|
creates one procedure for each element, each defined as
|
379 |
|
|
@code{(prefix-set-element-name!@: object new-value)}.
|
380 |
|
|
|
381 |
|
|
This is a macro so don't quote anything.
|
382 |
|
|
|
383 |
|
|
@item (elm-get object elm-name)
|
384 |
|
|
|
385 |
|
|
This can only be used in method definitions (blech, blah blah blah).
|
386 |
|
|
|
387 |
|
|
@item (elm-set!@: object elm-name new-value)
|
388 |
|
|
|
389 |
|
|
This can only be used in method definitions (blech, blah blah blah).
|
390 |
|
|
|
391 |
|
|
@item (send object method-name arg1 arg2)
|
392 |
|
|
|
393 |
|
|
Invoke method @code{method-name} on @code{object}.
|
394 |
|
|
|
395 |
|
|
The convention is to put this in a cover fn:
|
396 |
|
|
@code{(class-name-method-name object arg1 arg2)}.
|
397 |
|
|
|
398 |
|
|
@item (send-next object method-name arg1 arg2)
|
399 |
|
|
|
400 |
|
|
Same as @code{send} except only usable in methods and is used to invoke
|
401 |
|
|
the method in the parent class.
|
402 |
|
|
|
403 |
|
|
@item (make object .@: args)
|
404 |
|
|
|
405 |
|
|
One standard way to create a new object is with @code{make}.
|
406 |
|
|
It is a wrapper, defined as
|
407 |
|
|
|
408 |
|
|
@smallexample
|
409 |
|
|
(define (make object .@: args)
|
410 |
|
|
(apply send (cons (new object) (cons 'make!@: args)))
|
411 |
|
|
)
|
412 |
|
|
@end smallexample
|
413 |
|
|
|
414 |
|
|
@item (vmake class .@: args)
|
415 |
|
|
|
416 |
|
|
The other standard way to create objects is with @code{vmake}.
|
417 |
|
|
|
418 |
|
|
@code{args} is a list of option names and arguments.
|
419 |
|
|
|
420 |
|
|
??? Not completely implemented yet.
|
421 |
|
|
|
422 |
|
|
@item (method-make!@: class method-name lambda)
|
423 |
|
|
|
424 |
|
|
The normal way of creating methods is to use @code{method-make!}, not define
|
425 |
|
|
them with the class. It's just easier to define them separately.
|
426 |
|
|
|
427 |
|
|
@item (method-make-virtual!@: class method-name lambda)
|
428 |
|
|
|
429 |
|
|
Create virtual methods created with @code{method-make-virtual!}.
|
430 |
|
|
|
431 |
|
|
@item (method-make-forward!@: class elm-name methods) -> unspecified
|
432 |
|
|
|
433 |
|
|
Forwarding a method invocation on one object to another is extremely
|
434 |
|
|
useful so some utilities have been created to simplify creating forwarding
|
435 |
|
|
methods.
|
436 |
|
|
|
437 |
|
|
@code{methods} is a list of method names. A method is created for each one
|
438 |
|
|
that forwards the method onto the object contained in element ELM-NAME.
|
439 |
|
|
|
440 |
|
|
@item (method-make-virtual-forward!)
|
441 |
|
|
|
442 |
|
|
Same as method-make-forward!@: except that it creates virtual methods.
|
443 |
|
|
|
444 |
|
|
@end itemize
|