\documentstyle{article}

\title{Installing lcc}

\author{Christopher W. Fraser\\
AT\&T Bell Laboratories, 600 Mountain Avenue,\\
Murray Hill, NJ 07974
\and
David R. Hanson\\
Department of Computer Science, Princeton University,\\
Princeton, NJ 08544}

\date{May 21, 1991\\ Last Revised September 15, 1992}

\begin{document}
%\bibliographystyle{abbrv}

\maketitle

\section{Introduction}

\verb|lcc| is a retargetable compiler for ANSI C~\cite{ansi:Cstandard}.
\verb|lcc| is in production use
at Princeton University and AT\&T Bell Laboratories.
When used with a conforming preprocessor and library,
\verb|lcc| passes the conformance section of Version 2.00 of the Plum-Hall
Validation Suite for ANSI~C.

Extract the distribution into its own directory.
All paths below are relative to this directory.

All distributions include the following top-level directories;
``front-end'' distributions include {\em only\/} these directories.

\begin{center}
\begin{tabular}{ll}
\tt c		& front end \\
\tt etc		& driver, man page \\
\tt doc		& this document, other documentation \\
\tt include	& ANSI include files \\
\tt tst		& test suite \\
\tt gen0	& ``symbolic'' code generator \\
\tt gen3	& demonstration VAX code generator \\
\end{tabular}
\end{center}
``Front-end'' distributions include no production code generators
and Sec.~\ref{gen2} of this document does not apply.
Secs.~\ref{gen3} and \ref{gen0} describe how to build compilers
with the demonstation VAX code generator and
the symbolic code generator, respectively.

``Full'' distributions include code generators for the VAX, MIPS,
and Motorola 68020 with the 68881 floating-point co-processor.
These distributions add the top-level directory
\verb|gen2|, which holds the production code generators.

Installation of a production compiler
involves three steps performed in the following order.
\begin{enumerate}
\item Decide where to install the man page, the include files,
the compiler, and \verb|lcc|, the driver program; see Sec.~\ref{paths}.

\item Install a host-specific driver; see Sec.~\ref{driver}.

\item Install a host- and target-specific compiler; see Sec.~\ref{gen2}.
\end{enumerate}

\verb|c/version.h| identifies the version of the distribution
as {\tt (($x$<<8)|$y$)} for version {\tt $x$.$y$},
and \verb|LOG| describes the changes from the previous version.

\verb|doc/*.tex| are \LaTeX\ input files for several reports that
describe \verb|lcc|, including this one.
To format these reports, run \verb|latex| twice, e.g.,
\begin{verbatim}
$ latex overview; latex overview
\end{verbatim}
Ignore warnings about overfull boxes.

\section{Paths}\label{paths}

Installation consists of three files and one directory;
these are summarized below along with paths used in typical installations.

\begin{center}
\begin{tabular}{ll}
\tt /usr/local/man/man1/lcc.1	& the man page \\
\tt /usr/local/lib/rcc		& the compiler \\
\tt /usr/local/bin/lcc		& the driver \\
\tt /usr/local/include/ansi	& include files (a directory) \\
\end{tabular}
\end{center}

These files can be placed in other, site-specific locations,
but the compiler should be named \verb|rcc|.
If the driver isn't named \verb|lcc|, edit the man page (\verb|etc/lcc.1|).

Include files are in directories named \verb|include/|{\it target}\verb|_|{\it system};
the following table lists the available combinations.
\begin{center}
\begin{tabular}{lll}
\em target	& \em system	& operating system \\[0.5ex]
\tt vax		& \tt bsd 	& 4.3BSD UNIX \\
		& \tt ultrix	& ULTRIX 3.0 \\
		& \tt v9	& 9th Edition UNIX \\
\tt mips	& \tt iris	& IRIX System V Release 3.2 \\
		& \tt mips	& RISC/OS 4.0 \\
		& \tt ultrix	& ULTRIX 4.0 \\
\tt mc		& \tt sun	& SunOS 4.0 \\
		& \tt next	& Mach \\
% \tt sparc	& \tt sun	& SunOS 4.0 \\
\end{tabular}
\end{center}
Not all combinations of {\it target}, {\it system\/} are provided
and many don't make sense.
Choose the include files that are appropriate for your system,
or make a copy of a closely related set and edit them.

For example, if the paths shown above are chosen and if
\verb|include/mips_ultrix| has the appropriate include files,
install the man page and include files by
\begin{verbatim}
$ cp etc/lcc.1 /usr/local/man/man1
$ cp include/mips_ultrix/*.h /usr/local/include/ansi
\end{verbatim}

\section{Installing the Driver}\label{driver}

The preprocessor, compiler, assembler, and loader are
invoked by a driver program, \verb|lcc|, which is similar
to \verb|cc| on most systems. It's described in the man page
\verb|etc/lcc.1|.
The driver is built by combining the host-independent
part, \verb|etc/lcc.c|, with a small host-specific part.
By convention, host-specific parts are named {\it hostname}\verb|.c|,
where {\it hostname\/} is the local name for the host on which \verb|lcc|
is being installed. \verb|etc| holds many examples.
Comments in most give the details of the
particular host; pick one that is closely related to your host,
copy it to \verb|etc/|{\it yourhostname}\verb|.c|,
and edit it as described below.
You should not have to edit \verb|etc/lcc.c|.

Debug your version of the driver by running it
with the \verb|-v -v| options, which cause it to echo the
commands it would execute, but not to execute them.

Here's \verb|etc/hart.c|, which we'll use as an example
in describing how to edit a host-specific part.
This example illustrates all of the important features.
\begin{verbatim}
/* DECStations running ULTRIX at Princeton University */

#include <string.h>

char *cpp[] = {
        "/usr/gnu/lib/gcc-cpp", "-undef",
        "-DLANGUAGE_C", "-D_LANGUAGE_C", "-D__LANGUAGE_C",
        "-D_unix", "-D__unix",
        "-Dultrix", "-D_ultrix", "-D__ultrix",
        "-Dmips", "-D_mips", "-D__mips",
        "-Dhost_mips", "-D_host_mips", "-D__host_mips",
        "-DMIPSEL", "-D_MIPSEL", "-D__MIPSEL",
        "$1", "$2", "$3", 0 };
char *include[] = { "-I/usr/local/include/ansi", 0 };
char *com[] =  { "/usr/local/lib/rcc", "$1", "$2", "$3", 0 };
char *as[] =  { "/bin/as", "-o", "$3", "", "$1",
        "-nocpp", "-EL", "$2", 0 };
char *ld[] =  { "/usr/bin/ld", "-o", "$3", "/usr/lib/crt0.o",
        "$1", "$2", "", "", "-lm", "-lc", 0 };

int option(arg) char *arg; {
        if (strcmp(arg, "-g") == 0)
                as[3] = "-g";
        else if (strcmp(arg, "-p") == 0
        && strcmp(ld[3], "/usr/lib/crt0.o") == 0) {
                ld[3] = "/usr/lib/mcrt0.o";
                ld[7] = "/usr/lib/libprof1.a";
        } else if (strcmp(arg, "-b") == 0
        && access("/usr/local/lib/bbexit.o", 4) == 0)
                ld[6] = "/usr/local/lib/bbexit.o";
        else
                return 0;
        return 1;
}
\end{verbatim}

Most of the host-specific code is data that
gives prototypes for the commands that invoke
the preprocessor, compiler, assembler, and loader.
Each command prototype is an array of pointers to strings
terminated with a null pointer;
the first string is the full path name of the command and the others
are the arguments or argument placeholders, which are described below.

The \verb|cpp| array gives the command for running the preprocessor.
\verb|lcc| is intended to be used with an ANSI preprocessor,
such as the GNU C preprocessor available from the Free Software Foundation.
If the GNU preprocessor is used,
it must be named \verb|gcc-cpp| in order for \verb|lcc|'s \verb|-N| option
to work correctly.

Literal arguments specified in prototypes, e.g., \verb|"-Dmips"| in
the \verb|cpp| command above, are passed to the command as given.

The strings \verb|"$1"|, \verb|"$2"|, and \verb|"$3"| in
prototypes are placeholders for {\em lists} of arguments that
are substituted in a copy of the prototype before the command is executed.
\verb|$1| is replaced by the {\em options} specified by the user;
for the preprocessor, this list always contains at least
\verb|-Dunix| and \verb|-D__LCC__|.
\verb|$2| is replaced by the {\em input} files,
and \verb|$3| is replaced by the {\em output} file.

Zero-length arguments after replacement are removed from
the argument list before the command is invoked. So, e.g.,
if the preprocessor is invoked without an output file,
\verb|"$3"| becomes \verb|""|, which is removed from the final argument list.

For example, to specify a preprocessor command prototype to invoke
\verb|/bin/cpp| with the options \verb|-Dmips| and \verb|-Dultrix|,
the \verb|cpp| array would be
\begin{verbatim}
char *cpp[] = { "/bin/cpp", "-Dvax", "-Dultrix",
        "$1", "$2", "$3", 0 };
\end{verbatim}

The \verb|include| array is a list of \verb|-I| options that
specify which directives should be searched to satisfy include directives.
These directories are searched in the order given.
The first directory should be the one to which the ANSI
header files were copied in Sec.~\ref{paths}.
The driver adds these options to \verb|cpp|'s arguments
when it invokes the preprocessor, except when \verb|-N| is specified.

Design this list carefully.  Mixing ANSI and pre-ANSI headers (e.g., by
listing \verb|/usr/include| after the directory of ANSI headers as
shown above) may mix incompatible headers.  Unless the default list holds {\em only}
\verb|/usr/include| or {\em only\/} the ANSI headers, many users may be
forced to use \verb|-N| and \verb|-I| incessantly.

\verb|com| gives the command for invoking the compiler.
This prototype can appear exactly as shown above, except
that the command name should be edited to reflect the
location of the compiler chosen in Sec.~\ref{paths}.

\verb|as| gives the command for invoking the assembler.

\verb|ld| gives the command for invoking the loader.
For the other commands, the list \verb|$2| contains a single file;
for \verb|ld|, \verb|$2| contains all `.o' files and libraries, and
\verb|$3| is \verb|a.out|, unless the \verb|-o| option is specified.
As suggested in the code above, \verb|ld| must also specify
the appropriate startup code and default libraries.

The \verb|option| function is described below;
for now, use an existing \verb|option| function or one that returns \verb|0|.

After specifying the prototypes, compile the driver by
\begin{verbatim}
$ cd etc
$ make HOST=hart
\end{verbatim}
where \verb|hart| is replaced by {\it yourhostname}.
Run the resulting \verb|a.out| with the options \verb|-v -v|
to display the commands that would be executed, e.g.,
\begin{verbatim}
$ a.out -v -v foo.c baz.c mylib.a -lX11
a.out version 1.9
foo.c:
/usr/gnu/lib/gcc-cpp -undef -DLANGUAGE_C -D_LANGUAGE_C
   -D__LANGUAGE_C -D_unix -D__unix -Dultrix -D_ultrix -D__ultrix
   -Dmips -D_mips -D__mips -Dhost_mips -D_host_mips -D__host_mips
   -DMIPSEL -D_MIPSEL -D__MIPSEL -Dunix -D__LCC__ -v
   -I/usr/local/include/ansi foo.c |
   /usr/local/lib/rcc -v - /tmp/lcc18299.s
/bin/as -o foo.o -nocpp -EL /tmp/lcc18299.s
baz.c:
/usr/gnu/lib/gcc-cpp -undef -DLANGUAGE_C -D_LANGUAGE_C
   -D__LANGUAGE_C -D_unix -D__unix -Dultrix -D_ultrix -D__ultrix
   -Dmips -D_mips -D__mips -Dhost_mips -D_host_mips -D__host_mips
   -DMIPSEL -D_MIPSEL -D__MIPSEL -Dunix -D__LCC__ -v
   -I/usr/local/include/ansi baz.c |
   /usr/local/lib/rcc -v - /tmp/lcc18299.s
/bin/as -o baz.o -nocpp -EL /tmp/lcc18299.s
/usr/bin/ld -o a.out /usr/lib/crt0.o foo.o baz.o mylib.a
   -lX11 -lm -lc
rm /tmp/lcc18299.s
\end{verbatim}
Leading spaces indicate lines that have been folded manually to fit this page.
Note the use of a pipeline to connect the preprocessor and compiler.
\verb|lcc| arranges this pipeline itself; it does not call the shell.
 
As the output shows, \verb|lcc| places temporary files in \verb|/tmp|.
Alternatives can be specified by defining \verb|TEMPDIR| in \verb|CFLAGS|
when making the driver, e.g.,
\begin{verbatim}
$ make CFLAGS='-DTEMPDIR=\"/usr/tmp\"' HOST=hart
\end{verbatim}
causes \verb|lcc| to place temporary files in \verb|/usr/tmp|.

Once the driver is completed, install it by
\begin{verbatim}
$ cp a.out /usr/local/bin/lcc
\end{verbatim}
where the destination is the location chosen for \verb|lcc| in Sec.~\ref{paths}.

The \verb|option| function is called for the options
\verb|-g|, \verb|-p|, \verb|-pg|, and \verb|-b| because these compiler options might
also affect the loader's arguments. For these options,
the driver calls \verb|option(arg)| to give the host-specific
code an opportunity to edit the \verb|ld| prototype, if necessary.
\verb|option| can change \verb|ld|, if necessary, and return \verb|1| to
announce its acceptance of the option. If the option
is unsupported, \verb|option| should return \verb|0|.

For example, in response to \verb|-g|, the \verb|option| function shown above
changes \verb|as[3]| from \verb|""| to \verb|"-g"|, which specifies
the debugging option to the assembler. If \verb|-g| is not specified,
the \verb|""| argument is omitted from the \verb|as| command
because it's empty.

Likewise, the \verb|-p| causes \verb|option| to change the name
of the startup code and add the name of the profiling library. Note that
\verb|option| has been written to support simultaneous use
of \verb|-g| and \verb|-p|, e.g.,
\begin{verbatim}
$ a.out -v -v -g -p foo.s baz.o -o myfoo
a.out version 1.9
/bin/as -o foo.o -g -nocpp -EL foo.s
/usr/bin/ld -o myfoo /usr/lib/mcrt0.o foo.o baz.o
   /usr/lib/libprof1.a -lm -lc
rm /tmp/lcc18317.s
\end{verbatim}

On Suns, the driver
passes any option beginning with \verb|-f| to \verb|option|
to support Sun's \verb|-f68881| option. The driver also
recognizes \verb|-Bstatic| and \verb|-Bdynamic| as linker options,
and recognizes but ignores Sun's \verb|-target|~{\it name\/} option.

The option \verb|-Wo|{\it arg\/} causes the driver to pass {\it arg\/}
to \verb|option|. Such options have no other effect; this mechanism
is provided to support system-specific options that affect the
commands executed by the driver.

The \verb|-b| option causes the compiler to generate
code to count the number of times each expression is executed.
The \verb|exit| function in \verb|etc/bbexit.c| writes these
counts to \verb|prof.out| when the program terminates.
If \verb|option| is called with \verb|-b|,
it must edit the \verb|ld| command accordingly,
as shown above. This version of \verb|option| uses
the \verb|access| system call to insure that \verb|bbexit.o| is installed before
editing the \verb|ld| command. To install \verb|bbexit.o| execute
\begin{verbatim}
$ make bbexit.o
$ cp bbexit.o /usr/local/lib/bbexit.o
\end{verbatim}
If necessary, change \verb|/usr/local/lib| to reflect local conventions.
The \verb|exit| function in \verb|etc/bbexit.c| works on the
systems listed in Sec.~\ref{paths}, but may need to be modified for other systems.
The implementation of the \verb|-b| option is described
in Ref.~\cite{fraser:hanson:91b}.
The \LaTeX\ source for the technical report version of this paper
is in \verb|doc/overview.tex|.

If \verb|option| supports \verb|-b|, you should also
install \verb|etc/bprint.c|, which reads \verb|prof.out|
and generates a listing annotated with execution counts.
After \verb|lcc| is installed, install \verb|bprint| with the commands
\begin{verbatim}
$ make bprint
$ cp bprint /usr/local/bin/bprint
$ cp bprint.1 /usr/local/man/man1
\end{verbatim}
The \verb|makefile| uses \verb|lcc| to compile \verb|bprint.c|;
you must use \verb|lcc| or another ANSI~C compiler, e.g., \verb|gcc|,
because \verb|bprint.c| is written in ANSI~C.
Also, \verb|bprint.c| {\em includes\/} \verb|"../c/profio.c"|, so it must
be compiled in \verb|etc|.

To complete the driver,
write an appropriate \verb|option| function for your system,
and make and install the driver as described above.

\section{Installing a Production Compiler}\label{gen2}

\verb|gen2| contains source code common to all of the production
code generators and directories for each of the supported targets:

\begin{center}
\begin{tabular}{ll}
\tt gen2/vax	& VAX code generator \\
\tt gen2/mips	& MIPS code generator \\
\tt gen2/mc	& Motorola 68020 \& 68881 code generator \\
%\tt gen2/sparc	& SPARC code generator \\
\end{tabular}
\end{center}

A production compiler, \verb|rcc|, is built by compiling it
with the host C compiler and then using the result to re-compile itself.
A test suite is used to
verify that the compiler is working correctly.
The examples below use the MIPS compiler under Ultrix
to illustrate this process.
You must have the driver, \verb|lcc|, installed in order
to build and test \verb|rcc|.
If any of the steps below fail, contact us (see Sec.~\ref{bugs}).

The \verb|makefile| runs the shell script
\verb|gen2/run| on each C program in the test suite, \verb|tst|.
\verb|gen2/makefile| uses \verb|include| directives, which are supported by
most versions of \verb|make|. If your version of \verb|make|
doesn't support \verb|include|, build a suitable \verb|makefile|
by replacing the \verb|include|s with the specified \verb|makefile|s.
Note that the path names are relative to the \verb|gen2| directory.

The object files, \verb|rcc|, and the generated code for
the programs in the test suite are placed in the directory
{\tt gen2/\it target\/\tt-\it system\/} where {\it target\/} and {\it system\/}
are the names of your target machine and its operating system, respectively.
There are directories for the supported {\it target\/}, {\it system\/} combinations,
e.g., \verb|mips-ultrix|.

The {\it target\/} and {\it system\/} values are read from the
variables \verb|TARGET| and \verb|OS|, respectively.
Values for these variables must be specified when invoking \verb|make|
along with system-specific values for \verb|CFLAGS| and \verb|LDFLAGS|,
if necessary.
The following table lists the \verb|make| commands for the supported
{\it target\/-system\/} combinations.
\begin{center}\tt
\begin{tabular}{llll}
make TARGET=vax   & OS=bsd\\
make TARGET=vax   & OS=ultrix\\
make TARGET=vax   & OS=v9\\[1ex]

make TARGET=mips  & OS=iris	& CFLAGS=-cckr\\
make TARGET=mips  & OS=ultrix\\ 
make TARGET=mips  & OS=mips\\[1ex]

%make TARGET=sparc & OS=sun	& LDFLAGS='-s -Bstatic'\\[1ex]

make TARGET=mc    & OS=sun	& LDFLAGS='-s -Bstatic'\\
make TARGET=mc    & OS=next\\ 
\end{tabular}
\end{center}
For example, to build an \verb|rcc| for a MIPS running Ultrix, execute the commands
\begin{verbatim}
$ cd gen2
$ make TARGET=mips OS=ultrix
cd mips-ultrix;
   cc -c -Dmips_ultrix -I../mips -I.. -I../../c ../../c/dag.c
...
cd mips-ultrix;
   cc -c -Dmips_ultrix -I../mips -I.. -I../../c ../mips/sel.c
cc -s -o mips-ultrix/rcc mips-ultrix/dag.o  ...  mips-ultrix/sel.o
\end{verbatim}
There may be a few warnings, but there should be no errors.

Once \verb|rcc| is built with the host C compiler,
run the test suite to verify that \verb|rcc| is working correctly,
specifying the appropriate operating system from those listed
in Sec.~\ref{paths}, e.g.,
\begin{verbatim}
$ make TARGET=mips OS=ultrix test
mips-ultrix 8q:
mips-ultrix array:
mips-ultrix cf:
mips-ultrix cq:
mips-ultrix cvt:
mips-ultrix fields:
mips-ultrix front:
mips-ultrix incr:
mips-ultrix init:
mips-ultrix limits:
mips-ultrix paranoia:
mips-ultrix sort:
mips-ultrix spill:
mips-ultrix stdarg:
mips-ultrix struct:
mips-ultrix switch:
mips-ultrix wf1:
mips-ultrix yacc:
\end{verbatim}
For each C program in the test suite,
\verb|gen2/run| compiles the program and uses \verb|diff|
to compare the generated assembly code
with the expected code (the expected MIPS code for \verb|tst/8q.c| is
in \verb|gen2/mips-ultrix/tst/8q.s.bak|, etc.). If there are differences, the script
executes the generated code with the input given in \verb|tst|
(the input for \verb|tst/8q.c| is in \verb|tst/8q.0|, etc.)
and compares the output with the expected output
(the expected output from \verb|tst/8q.c| on the MIPS is
in \verb|gen2/mips-ultrix/tst/8q.1.bak|, etc.). The script also compares the
diagnostics from the compiler with the expected diagnostics.

On some systems, there may be a few differences between the generated code
and the expected code.
These differences occur because the expected code is
generated by cross compilation
on a MIPS and the least-significant bits of some floating-point constants
differ from those bits in constants generated on your system.
There should be no differences in the output from executing the test programs.

The \verb|mips-ultrix| preceding the name of each test program in the output
above indicates a {\it target\/\it-system\/} combination, e.g.,
``generating code for a \verb|mips| running the
\verb|ultrix| operating system''.

Next, build \verb|rcc| again using the just-built \verb|rcc|:
\begin{verbatim}
$ make TARGET=mips OS=ultrix triple
rm -f mips-ultrix/*.o
make TARGET=mips OS=ultrix CC='lcc -B./ -d0.1 -A'
   CFLAGS='-N -I../../include/mips_ultrix '
   LDFLAGS='-s' mips-ultrix/rcc
cd mips-ultrix;
   lcc -B./ -d0.1 -A -c -Dmips_ultrix -N -I../../include/mips_ultrix
   -I../mips -I.. -I../../c ../../c/dag.c
...
lcc -B./ -d0.1 -A -s -o mips-ultrix/rcc
   mips-ultrix/dag.o ... mips-ultrix/sel.o
od +8 <mips-ultrix/rcc >mips-ultrix/tst/od2
rm -f mips-ultrix/*.o
make TARGET=mips OS=ultrix CC='lcc -B./ -d0.1 -A'
   CFLAGS='-N -I../../include/mips_ultrix '
   LDFLAGS='-s' mips-ultrix/rcc
cd mips-ultrix;
   lcc -B./ -d0.1 -A -c -Dmips_ultrix -N -I../../include/mips_ultrix
   -I../mips -I.. -I../../c ../../c/dag.c
...
lcc -B./ -d0.1 -A -s -o mips-ultrix/rcc
   mips-ultrix/dag.o ... mips-ultrix/sel.o
od +8 <mips-ultrix/rcc >mips-ultrix/tst/od3
cmp mips-ultrix/tst/od[23] && rm mips-ultrix/tst/od[23]
\end{verbatim}
This command builds \verb|mips-ultrix/rcc| twice; once using the
\verb|mips-ultrix/rcc| built by \verb|cc|
and again using the \verb|mips-ultrix/rcc| built by \verb|lcc|.
After building each version, an octal dump of the resulting binary is made,
and the two dumps are compared. They should be identical, as shown
at the end of the output above.
If they aren't, our compiler is generating bad code.
This triple-compilation test is described in Ref.~\cite{cornelius:etal:84}.
(They name four generations because they number them differently.)

The final version of \verb|mips-ultrix/rcc| should also pass the test suite;
i.e., the output from \verb|make TARGET=mips OS=ultrix test|
should be identical to that from the previous \verb|make|.

Now install the final version of \verb|mips-ultrix/rcc|:
\begin{verbatim}
$ cp mips-ultrix/rcc /usr/local/lib/rcc
\end{verbatim}
where the destination is the location chosen for \verb|rcc| in Sec.~\ref{paths}.

On some systems, you may be able
to use environment variables and \verb|make|'s \verb|-e|
option to avoid specifying \verb|TARGET|
and \verb|OS| on each \verb|make| command, and
the \verb|make| commands described above can be done with a single command:
\begin{verbatim}
$ TARGET=mips OS=ultrix export TARGET OS
$ make -e test triple test clean
\end{verbatim}
\verb|make clean| cleans up, but does not remove \verb|mips-ultrix/rcc|, and
\verb|make clobber| cleans up and removes \verb|mips-ultrix/rcc|.

The software used to build the production code generators
is described in Ref.~\cite{fraser:sigplan89}; it is not available.

\section{Building the Demonstration VAX Compiler}\label{gen3}

The code generator in \verb|gen3| emits naive VAX code.
It is not a production code generator. It is included only
to illustrate the interface between the front end
and the code generator. If you want to replace \verb|lcc|'s code generator,
study it and not the larger production code generators.

This code generator is detailed in
Refs.~\cite{fraser:hanson:interface:TR,fraser:hanson:91a,fraser:hanson:92}.
\verb|doc/interface.tex| holds the \LaTeX\ source for the latest
version of Ref.~\cite{fraser:hanson:interface:TR}.

\verb|makefile| uses \verb|include| directives, which are supported by
most versions of \verb|make|. If your version of \verb|make|
doesn't support \verb|include|, build a suitable \verb|makefile|
by replacing the \verb|include|s with the specified \verb|makefile|s.

The default and only acceptable \verb|TARGET| is \verb|vax|
and the default \verb|OS| is \verb|bsd|, so the commands
\begin{verbatim}
$ cd gen3
$ make test
\end{verbatim}
build and test \verb|vax-bsd/rcc|;
The \verb|makefile| uses \verb|lcc| instead of \verb|cc|
because \verb|gen3/gen.c| is written in ANSI~C.
If \verb|lcc| is unavailable, use another ANSI~C compiler, e.g., \verb|gcc|,
and use a command like
\begin{verbatim}
$ make CC=gcc test
\end{verbatim}
to build the demonstration compiler. Alternatively, you can specify
another ANSI~C compiler by editing \verb|gen3/makefile|.

There may be warnings, but there should be no errors.
As for the production code generators, this command
tests \verb|vax-bsd/rcc| by running a shell script,
\verb|gen3/run|, on each C program in the test suite.
This script compiles a program and compares the generated VAX code
with the expected code (the expected VAX code for \verb|tst/8q.c| is
in \verb|gen3/vax-bsd/tst/8q.s.bak|, etc.).
There should be no significant differences.
If there are differences, the script executes the generated code
and compares the output with the expected output
(the expected output from \verb|tst/8q.c| is
in \verb|gen3/vax-bsd/tst/8q.1.bak|, etc.).

\verb|make triple| is the same as for the production compilers,
\verb|make clean| cleans up, but does not remove \verb|rcc|, and
\verb|make clobber| cleans up and removes \verb|rcc|.

\section{Building the Symbolic Compiler}\label{gen0}

The code generator in \verb|gen0| documents the
interface between the front end and the code generator and is used routinely in
front-end development. The output of this code generator is a printable
representation of the input program, e.g., the dags constructed by the
front end are printed, and other interface functions print their arguments.
The output is not executable, unlike the output of the demonstration
VAX code generator.

The interface is described in
Refs.~\cite{fraser:hanson:interface:TR,fraser:hanson:91a}.
The \LaTeX\ source for the latest version of
Ref.~\cite{fraser:hanson:interface:TR} is in \verb|doc/interface.tex|.

\verb|makefile| uses \verb|include| directives, which are supported by
most versions of \verb|make|. If your version of \verb|make|
doesn't support \verb|include|, build a suitable \verb|makefile|
by replacing the \verb|include|s with the specified \verb|makefile|s.

For the symbolic compiler, \verb|TARGET| and \verb|OS| serve only
to identify an include directory, and \verb|gen0/makefile|
specifies \verb|vax| and \verb|bsd| as defaults.
The commands
\begin{verbatim}
$ cd gen0
$ make test
\end{verbatim}
build the symbolic compiler, \verb|vax-bsd/rcc|, and tests it by running the shell script
\verb|gen0/run| on each C program in the test suite, \verb|tst|.
This script compiles a program and uses \verb|diff| to compare the generated symbolic code
with the expected code (the expected code for \verb|tst/8q.c| is
in \verb|gen0/vax-bsd/tst/8q.s.bak|, etc.). There should be no differences.
The script also compares the
diagnostics from the compiler with the expected diagnostics
(the expected diagnostics for \verb|tst/8q.c| are
in \verb|tst/8q.2|, etc.).

\verb|make clean| cleans up, but does not remove \verb|rcc|, and
\verb|make clobber| cleans up and removes \verb|rcc|.

\section{Reporting Bugs}\label{bugs}

Bugs can be reported by sending mail with the shortest program
that exposes them and the details reported by \verb|lcc|'s \verb|-v|
option to \verb|lcc-bugs@princeton.edu|.
Other questions, comments, and requests to be added
to the \verb|lcc| mailing list can be sent to \verb|lcc-requests@princeton.edu|.

%\bibliography{refs,lib}
\begin{thebibliography}{1}

\bibitem{ansi:Cstandard}
American National Standard Institute, Inc., New York.
\newblock {\em American National Standards for Information Systems, Programming
  Language C {ANSI} X3.159--1989}, 1990.

\bibitem{cornelius:etal:84}
B.~J. Cornelius, I.~R. Lowman, and D.~J. Robson.
\newblock Steady-state compilers.
\newblock {\em Software---Practice \& Experience}, 14(8):705--709, Aug. 1984.

\bibitem{fraser:sigplan89}
C.~W. Fraser.
\newblock A language for writing code generators.
\newblock {\em Proceedings of the SIGPLAN'89 Conference on Programming Language
  Design and Implementation, SIGPLAN Notices}, 24(7):238--245, July 1989.

\bibitem{fraser:hanson:interface:TR}
C.~W. Fraser and D.~R. Hanson.
\newblock A code generation interface for {ANSI C}.
\newblock Technical Report CS-TR-270-90, Princeton University, Department of
  Computer Science, Princeton, NJ, July 1990.

\bibitem{fraser:hanson:91a}
C.~W. Fraser and D.~R. Hanson.
\newblock A code generation interface for {ANSI C}.
\newblock {\em Software---Practice \& Experience}, 21(9):963--988, Sept. 1991.

\bibitem{fraser:hanson:91b}
C.~W. Fraser and D.~R. Hanson.
\newblock A retargetable compiler for {ANSI C}.
\newblock {\em SIGPLAN Notices}, 26(10):29--43, Oct. 1991.

\bibitem{fraser:hanson:92}
C.~W. Fraser and D.~R. Hanson.
\newblock Simple register spilling in a retargetable compiler.
\newblock {\em Software---Practice \& Experience}, 22(1):85--99, Jan. 1992.

\end{thebibliography}

\end{document}
