@c Copyright (C) 2000 Red Hat, Inc.
@c This file is part of the CGEN manual.
@c For copying conditions, see the file cgen.texi.

@node Writing an application
@chapter Writing an application
@cindex Writing an application

This chapter contains information for those wishing to write their own
CGEN application.

@menu
* File Layout::                 Organization of source files
* File Generation Process::     Workflow in cgen
* Coding Conventions::          Coding conventions
* Accessing Loaded Data::       Reading data from loaded .cpu files
* Name References::             Architecture names in generated code
* String Building::             Building long strings and writing them out
* COS::                         Cgen's Object System
@end menu

@node File Layout
@section File Layout

Source files in cgen are organized in a very specific way.@footnote{As the
number of source files grows the entire layout may be changed, but until then
this is how things are.}  It makes it easy to find things.

@itemize @bullet
@item top level file is cgen-<app>.scm
The best way to create this file is to copy an existing application's file
(e.g. cgen-opc.scm) and modify to suit.
@item file <app>.scm contains general app-specific utilities
@item other files are <app>-foo.scm
@item add entry to dev.scm (load-<app>)
@end itemize

@node File Generation Process
@section File Generation Process

This is an overview of cgen workflow.

@itemize @bullet

@item cgen is started with list of files to generate and code generation
options

@item source code is loaded

@itemize @minus
@item application independent code is loaded if not compiled in
@item application specific code is loaded

Currently app-specific code is never compiled in.
@itemize @minus
@item doesn't affect speed as much as application independent stuff
@item subject to more frequent changes
@item makes it easier to do application development if changes to .scm
files are "ready to use"
@end itemize
@end itemize

@item ultimately procedure `cpu-load' is called which is the main driver for
loading .cpu files

@item various data structures are initialized

@item data files are loaded

@itemize @minus
@item main <arch>.cpu file is loaded

There is a #include-like mechanism for loading other files so big
architectures can be broken up into several files.

While the architecture description is being loaded, entries not requested
are discarded.  This happens, for example, when building a simulator:
there's no point in keeping instructions specific to a machine that is
not being generated.  What to keep is based on the MACH and ISA attributes.

@item application specific data files are loaded

e.g. <arch>.sim
@end itemize

@item builtin elements are created

@item each requested file is generated by calling cgen-<file> generator

The output is written to the output file with @code{with-output-to-file} so
the code must write to @code{(current-output-port)}.

Some files require heavy duty processing of the cpu description.
For example the simulator computes the instruction formats from the
instruction field lists of each instruction.  This computation is defered
to each cgen-<file> procedure that needs it and must be explicitly requested
by them.  The results are cached so this is only done once of course.

@item additional processing for some opcodes files

Several opcodes files are built from three sources.

@itemize @minus
@item generated code

@item section in <arch>.opc file

It's not appropriate to put large amounts of C (or perhaps any C) in
cgen description files, yet some things are best expressed in some
other language (e.g. assembler/disassembler operand parsing/printing).

@item foo.in file

It seems cleaner to put large amounts of non-machine-generated C
in separate files from code generator.
@end itemize

@end itemize

@node Coding Conventions
@section Coding Conventions

@itemize @bullet
@item unless definition occupies one line, final trailing parenthesis is on
a line by itself beginning in column one
@item definitions internal to a source file begin with '-'
@item global state variables are named *foo-bar*
[FIXME: current code needs updating]
@item avoid uppercase (except for ???)
@item procedures that return a boolean result end in '?'
@item procedures that modify something end in '!'
@item classes are named <name>
@end itemize

@node Accessing Loaded Data
@section Accessing Loaded Data

Each kind of description file entry (defined with `define-foo') is recorded
in an object of class <foo>.@footnote{not true for <arch> but will be RSN}
All the data is collected together in an object of class
<system>.@footnote{got a better name?}
@footnote{modes aren't recorded here, should they be?}

Data for the currently selected architecture is obtained with several
access functions.

@smallexample
  (current-arch-name)
  - return symbol that is the name of the arch
  - this is the name specified with `define-arch'

  (current-arch-comment)
  - return the comment specified with `define-arch'

  (current-arch-atlist)
  - return the attributes specified with `define-arch'

  (current-arch-default-alignment)
  - return a symbol indicated the default aligment
    - one of aligned, unaligned, forced

  (current-arch-insn-lsb0?)
  - return a #t if the least significant bit in a word is numbered 0
  - return a #f if the most significant bit in a word is numbered 0

  (current-arch-mach-name-list)
  - return a list of names (as symbols) of all machs in the architecture

  (current-arch-isa-name-list)
  - return a list of names (as symbols) of all isas in the architecture

  - for most of the remaining elements, there are three main accessors
    [foo is sometimes abbreviated]
    - current-foo-list - returns list of <foo> objects in the architecture
    - current-foo-add! - add a <foo> object to the architecture
    - current-foo-lookup - lookup the <foo> object based on its name

  <atlist>
  (current-attr-list)
  (current-attr-add!)
  (current-attr-lookup)

  <enum>
  (current-enum-list)
  (current-enum-add!)
  (current-enum-lookup)

  <keyword>
  (current-kw-list)
  (current-kw-add!)
  (current-kw-lookup)

  <isa>
  (current-isa-list)
  (current-isa-add!)
  (current-isa-lookup)

  <cpu>
  (current-cpu-list)
  (current-cpu-add!)
  (current-cpu-lookup)

  <mach>
  (current-mach-list)
  (current-mach-add!)
  (current-mach-lookup)

  <model>
  (current-model-list)
  (current-model-add!)
  (current-model-lookup)

  <hardware>
  (current-hw-list)
  (current-hw-add!)
  (current-hw-lookup)

  <ifield>
  (current-ifld-list)
  (current-ifld-add!)
  (current-ifld-lookup)

  <operand>
  (current-op-list)
  (current-op-add!)
  (current-op-lookup)

  <insn>
  (current-insn-list)
  (current-insn-add!)
  (current-insn-lookup)

  <macro-insn>
  (current-minsn-list)
  (current-minsn-add!)
  (current-minsn-lookup)

  (current-ifmt-list)
  - return list of computed <iformat> objects

  (current-sfmt-list)
  - return list of computed <sformat> objects

  [there are a few more to be documented, not sure they'll remain as is]
@end smallexample

@node Name References
@section Name References

To simplify writing code generators, system names can be
specified with fixed strings rather than having to compute them.
The output is post-processed to convert the strings to the actual names.
Upper and lower case names are supported.

@itemize @bullet
@item For the architecture name use @@arch@@, @@ARCH@@.
@item For the cpu family name use @@cpu@@, @@CPU@@.
@item For the prefix use @@prefix@@, @@PREFIX@@.
@end itemize

The @samp{prefix} notion is to segregate different code for the same
cpu family.  For example, this is used to segregate the ARM ISA from the
Thumb ISA.

@node String Building
@section String Building

Output generation uses a combination of writing text out as it is computed
and building text for later writing out.

The top level file generator uses @code{string-write}.  It takes string-lists
and thunks as arguments and writes each argument in turn to stdout.
String-lists are lists of strings (nested arbitrarily deep).  It's cheaper
to @code{cons} long strings together than to use @code{string-append}.
Thunks return string-lists to write out, but isn't computed until all
preceeding arguments to `string-write' have been written out.  This allows
defering building up of large amounts of text until it needs to be.

The main procedures for building strings and writing them out are:

@itemize @bullet

@item (string-write string-list-or-thunk1 string-list-or-thunk2 ...)

Loops over arguments writing them out in turn.

@item (string-write-map proc string-list-or-thunk-list)

Apply proc to each element in string-list-or-thunk-list and write out
the result.

@item (string-list arg1 arg2 ...)

Return list of arguments.  This is identical to @code{list} except it
is intended to take string-lists as arguments.

@item (string-list-map proc arg-list)

Return list of @code{proc} applied to each element of @code{arg-list}.
This is identical to @code{map} except it is intended to take strings
as arguments.

@item (string-append string1 string2 ...)

For small arguments it's just as well to use @code{string-append}.
This is a standard Scheme procedure.  The output is also easier to read
when developing interactively.  And some subroutines are used in multiple
contexts including some where strings are required.

@end itemize

@node COS
@section COS

COS is Cgen's Object System.  It's a simple OO system for Guile that
was written to provide something useful until Guile had its own.
COS will be replaced with GOOPs if the Scheme implementation of cgen is kept.

The pure Scheme implementation of COS uses vectors to record objects and
classes.  The C implementation uses smobs (though classes are still
implemented with vectors).

A complete list of user-visible functions is at the top of @file{cos.scm}.

Here is a list of the frequently used ones.

@itemize @bullet

@item (class-make name parent-name-list element-list method-list)

Use @code{class-make} to define a class.

@smallexample
name: symbol, <name-of-class>
parent-name-list: list of symbols, names of each parent class
element-list: list of either symbols or (symbol . initial-value)
method-list: list of (symbol . lambda)
@end smallexample

The result is the class's definition.  It is usually assigned to a global
variable with same name as class's name.  Current cgen code always does
this.  It's not a requirement but it is convention.

@item (new <class-name>)

Create a new object with @code{new}.
@code{<class-name>} is typically the global variable that recorded
the results of @code{class-make}.  The result is a new object of the
requested class.  Class elements have either an "undefined" value
or an initial value if one was specified when the class was defined.

@item (define-getters class-name prefix element-list)

Elements (aka members) are read/written with "accessors".
Read accessors are defined with @code{define-getters}, which
creates one procedure for each element, each defined as
@code{(prefix-element-name object)}.

This is a macro so don't quote anything.

@item (define-setters class-name prefix element-list)

Write accessors are defined with @code{define-setters}, which
creates one procedure for each element, each defined as
@code{(prefix-set-element-name! object new-value)}.

This is a macro so don't quote anything.

@item (elm-get object elm-name)

This can only be used in method definitions (blech, blah blah blah).

@item (elm-set! object elm-name new-value)

This can only be used in method definitions (blech, blah blah blah).

@item (send object method-name arg1 arg2)

Invoke method @code{method-name} on @code{object}.

The convention is to put this in a cover fn:
@code{(class-name-method-name object arg1 arg2)}.

@item (send-next object method-name arg1 arg2)

Same as @code{send} except only usable in methods and is used to invoke
the method in the parent class.

@item (make object . args)

One standard way to create a new object is with @code{make}.
It is a wrapper, defined as

@smallexample
(define (make object . args)
  (apply send (cons (new object) (cons 'make! args)))
)
@end smallexample

@item (vmake class . args)

The other standard way to create objects is with @code{vmake}.

@code{args} is a list of option names and arguments.

??? Not completely implemented yet.

@item (method-make! class method-name lambda)

The normal way of creating methods is to use @code{method-make!}, not define
them with the class.  It's just easier to define them separately.

@item (method-make-virtual! class method-name lambda)

Create virtual methods created with @code{method-make-virtual!}.

@item (method-make-forward! class elm-name methods) -> unspecified

Forwarding a method invocation on one object to another is extremely
useful so some utilities have been created to simplify creating forwarding
methods.

@code{methods} is a list of method names.  A method is created for each one
that forwards the method onto the object contained in element ELM-NAME.

@item (method-make-virtual-forward!)

Same as method-make-forward! except that it creates virtual methods.

@end itemize
