.\" @(#)targetdoc	1.4 12/1/92
.H1 "Targets"
.Id "target, code generation"
.pp
A code generation \fBDomain\fR is specific to the language generated,
such as C (CGC), DSP56000 assembly code (CG56), and DSP96000 assembly
code (CG96).  Each code generation domain has a default target which
defines routines generic to the target language.  A derived
.c Target
can then be written which defines architecture specific
routines.  A given language, particularly a generic language such as C,
may run on many target architectures.  Code generation functions are
cleanly divided between the default domain target and the architecture
specific target.
.pp
All target architectures are derived from the base class
.c Target .
The special class
.c KnownTarget
is used to add targets to the known
list of targets much as
.c KnownBlock
is used to add stars (and
other blocks) to the known block list and to assign names to them.
.pp
A
.c Target
object has methods for generating a schedule, compiling
the code, and running the code (which may involve downloading code to
target hardware and beginning its execution).  There also may be child
targets (for representing multiprocessor targets) together with methods
for scheduling the communication between them.  Targets also have parameters
that are user specified.
.H2 "Single-Processor Target"
.pp
.Ir "CGTarget, class"
The base target for all code generation domains is the
.c CGTarget ,
which represents a single processor by default.  As the generic code
generation target, the CGTarget class defines many common functions for
code generation targets.  Methods defined here include virtual methods
to generate, display, compile, and run the code. Derived targets
are free to redefine these virtual methods if necessary.
.H3 "Code Streams"
.Id "code streams"
.Id "CodeStream, class"
.pp
.Ir "myCode, code stream"
.Ir "procedures, code stream"
A code generation target manages code streams which are used to store
star and target generated code. The CGTarget class has the two
predefined code streams:
.c myCode
and
.c procedures .
Derived
targets are free to add more code streams using the CGTarget method
.c addStream(\fIstream-name\fR) .
For example, the default CGC target
defines six additional code streams.
.pp
The
.(c
addCode(code,\fIstream name\fR,\fI<unique name>\fR)
.)c
method of a CG star
provides an interface to all the code streams (stream name and
unique-name arguments are optional).  This method defaults to adding
code into the
.c myCode
stream.  If a stream name is specified,
addCode looks up the stream using the
.c "getStream(\fIstream-name\fR)"
method and then adds the code into that stream.  Furthermore, if a
unique name is provided for the code, the code will only be added if no
other code has previously been added with the given unique name.  The
method addCode will return TRUE if the code-string has been added to
the stream and otherwise will return FALSE. 
.pp
Other methods, such as
.c "addProcedure(code,\fI<unique name>\fR)"
can be
defined, to provide a more efficient or convenient interfaces to a
specific code stream (in this case, procedures).  With addProcedure it
becomes clear why unique names are necessary.  Recall that
addProcedure is used to declarations outside of the
main body of the code.  For example, say we wanted to write a
function in C to multiply two numbers.  The codeblock to do this
could read:
.(c
codeblock(sillyMultiply) {
/* A silly function */
double $sharedSymbol(silly,mult)(double a, double b)
    {
        double m;
        m = a*b;
        return m;
    }
}
.)c
Note that in this codeblock we used the sharedSymbol macro described in
the code generation macros section.  To add this code to the procedures
stream, in the initCode method of the star, we can call either:
.(c
    addProcedure(sillyMultiply,"mult");
.)c
or
.(c
    addCode(sillyMultiply,"procedures","mult");
.)c
or
.(c
    getStream("procedures")->put(sillyMultiply,"mult");
.)c
.pp
As with addCode, addProcedure returns a TRUE or FALSE indicating
whether the code was inserted into the code stream.  Taking this into
account, we could have added the code line by line:
.(c
if (addProcedure("/* A silly function */\en","mult")) {
    addProcedure(
       "double $sharedSymbol(silly,mult)(double a, double b)\en"
    );
    addProcedure("{\en");
    addProcedure("\etdouble m;\en");
    addProcedure("\etm = a*b;\en");
    addProcedure("\etreturn m;\en");
    addProcedure("}\en");
}
.)c
.H3 "Code Generation"
.pp
.Id "allocateMemory, method"
.Id "codeGenInit, method"
.Id "generateCode, method"
.Id "mainLoopCode, method"
Once the program graph is scheduled, the target generates the code in
the virtual method
.c generateCode() .
(Note: code streams should be
initialized before this method is called.)  All the methods called by
generateCode are virtual, thus allowing for target customization.  The
generateCode method then calls
.c allocateMemory()
which allocates
the target resources. After resources are allocated, the initCode
method of the stars are called by
.c codeGenInit() .
The next step is to form the main loop by calling the method
.c mainLoopCode() .
The number of iteration cycles are determined by the argument of the "run"
directive which a user specifies in
.i pigi
or in
.i ptcl .
To complete the body of the main loop,
.c go()
methods of stars are
called in the scheduled order.  After forming the main loop, the
.c wrapup()
methods of stars are called.  
.pp
.Id "frameCode, method"
.Id "writeCode, method"
Now, all of the code has been generated; however, the code can be in
multiple target streams.  The
.c frameCode()
method is then called
to piece the code streams and place its resultant into the
.c myCode
stream. Finally, the code is written to a file by the method
.c writeCode() .
The default file name is \fI"code.output"\fR, and
that file will be located in the directory specified by a target
parameter, \fIdestDirectory\fR.
.pp
.Id "destDirectory, target parameter"
.pp
.Id "compileCode, method"
.Id "loadCode, method"
.Id "runCode, method"
Finally, since all of the code has been generated for a target, we are
ready to compile, load, and execute the code.  Derived targets should
redefine the virtual methods
.c compileCode() ,
.c loadCode() ,
and
.c runCode()
to do these operations.  At times it does not make
sense to have separate
.c loadCode()
and
.c runCode()
methods, and in these
cases, these operations should be collapsed into the
.c runCode
method.
.H3 "Wormholes"
.Ir "wormholes, code generation"
.pp
.Id "receiveWormData, method"
.Id "sendWormData, method"
.Id "wormInputCode, method"
.Id "wormOutputCode, method"
Unfortunately at the time of this release, no code generation target
was ready that supported wormholes.  However, the methods necessary to
support wormholes have already been incorporated into
.c CGTarget .
To support wormholes, a target should redefine the virtual methods,
.c sendWormData() ,
.c receiveWormData() ,
.c wormInputCode() ,
and
.c wormOutputCode() .
The
.c sendWormData()
method sends data from
the \*PT host to the target architecture.  The
.c wormInputCode()
method is in charge of defining the code in the target language to read in the
data from the \*PT host.  The methods
.c receiveWormData()
and
.c wormOutputCode()
are similar except that they correspond to data moving
in the opposite direction.
.pp
As can be seen in reading this section, there are many virtual methods in
the CGTarget class. If a user want to create a customized target, the best
way is to look at any existing target in the appropriate domain.
.pp
.Ir "AsmTarget, class"
.Ir "HLLTarget, class"
Derived from the CGTarget class, the
.c AsmTarget
class serves as
the base target for all single processor assembly code generation
targets.  Similarly, the
.c HLLTarget
class serves as the base
target for all single processor high-level language targets, such as C
or Silage.
