Initial (Large Upload)
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# Build all documentation
|
||||
#
|
||||
|
||||
all:
|
||||
(cd pictures; make)
|
||||
(cd html; make)
|
||||
(cd latex; make)
|
||||
|
||||
clean:
|
||||
(cd pictures; make clean)
|
||||
(cd html; make clean)
|
||||
(cd latex; make clean)
|
||||
@@ -0,0 +1,16 @@
|
||||
You will need the following programs to build the documentation.
|
||||
|
||||
1. Perl 5.004 or more recent
|
||||
2. LaTeX (I use the TeTeX distribution)
|
||||
3. fig2dev 3.2 (from xfig)
|
||||
|
||||
To build the documentation do the following:
|
||||
|
||||
1. In this directory, type make
|
||||
2. cd latex
|
||||
3. make again
|
||||
4. make again
|
||||
5. make again (Three times to make LaTeX stablize on the cross references)
|
||||
|
||||
The HTML pages will be in the directory html, starting from html/index.html
|
||||
The LaTeX documents will be in the directory latex.
|
||||
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 741 B |
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,86 @@
|
||||
#
|
||||
# This file compiles the documentation
|
||||
#
|
||||
|
||||
HTML= mlrisc.html mltexdoc.html
|
||||
|
||||
|
||||
TEX= ../latex/annotations.tex \
|
||||
../latex/graphics.tex \
|
||||
../latex/instructions.tex \
|
||||
../latex/mltree.tex \
|
||||
../latex/delayslots.tex \
|
||||
../latex/cells.tex \
|
||||
../latex/cluster.tex \
|
||||
../latex/constants.tex \
|
||||
../latex/pseudo-ops.tex \
|
||||
../latex/streams.tex \
|
||||
../latex/labelexp.tex \
|
||||
../latex/labels.tex \
|
||||
../latex/regions.tex \
|
||||
../latex/regmap.tex \
|
||||
../latex/graphs.tex \
|
||||
../latex/mlrisc-ir.tex \
|
||||
../latex/compiler-graphs.tex \
|
||||
../latex/SSA.tex \
|
||||
../latex/VLIW.tex \
|
||||
../latex/ra.tex \
|
||||
../latex/ILP.tex \
|
||||
../latex/mlrisc-arch.tex \
|
||||
../latex/future-work.tex \
|
||||
../latex/asm.tex \
|
||||
../latex/mc.tex \
|
||||
../latex/span-dep.tex \
|
||||
../latex/instrsel.tex \
|
||||
../latex/availability.tex \
|
||||
../latex/gc.tex \
|
||||
../latex/mlrisc-gen.tex \
|
||||
../latex/contributions.tex \
|
||||
../latex/systems.tex \
|
||||
../latex/mlrisc-graphics.tex \
|
||||
../latex/contributors.tex \
|
||||
../latex/requirements.tex \
|
||||
../latex/INTRO.tex \
|
||||
../latex/problem.tex \
|
||||
../latex/mlrisc-compiler.tex \
|
||||
../latex/mlrisc-ir-rep.tex \
|
||||
../latex/backend-opt.tex \
|
||||
../latex/sys-integration.tex \
|
||||
../latex/optimizations.tex \
|
||||
../latex/span-dep.tex \
|
||||
../latex/mlrisc-md.tex \
|
||||
../latex/mlrisc-ra.tex \
|
||||
../latex/line-counts.tex \
|
||||
../latex/sparc.tex \
|
||||
../latex/alpha.tex \
|
||||
../latex/x86.tex \
|
||||
../latex/ppc.tex \
|
||||
../latex/mips.tex \
|
||||
../latex/hppa.tex \
|
||||
../latex/C6.tex \
|
||||
../latex/mltree-ext.tex \
|
||||
../latex/mltree-util.tex
|
||||
|
||||
all: pictures $(HTML) makelinks
|
||||
|
||||
pictures:
|
||||
(cd ../pictures; make)
|
||||
|
||||
cvsrm:
|
||||
cvsrm $(HTML)
|
||||
|
||||
clean:
|
||||
/bin/rm -f *.html
|
||||
|
||||
makelinks:
|
||||
@if [ ! -d graphics ]; then ln -f -s ../graphics .; fi
|
||||
@if [ ! -d pictures ]; then ln -f -s ../pictures .; fi
|
||||
@if [ ! -f index.html ]; then ln -f -s INTRO.html index.html ; fi
|
||||
|
||||
|
||||
|
||||
%.html: ../latex/%.tex mltex2html mltex.thm
|
||||
perl mltex2html ../latex/$(@:.html=.tex)
|
||||
|
||||
mlrisc.html: $(TEX)
|
||||
mltexdoc.html: ../latex/mltex.tex
|
||||
@@ -0,0 +1,116 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Theme file for MLTeX
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Background color for document
|
||||
#
|
||||
$BACKGROUND_COLOR="#ffffff"; #white
|
||||
|
||||
#
|
||||
# Default text color for document
|
||||
#
|
||||
$TEXT_COLOR="#000020"; #very dark blue
|
||||
|
||||
#
|
||||
# Color of page title
|
||||
#
|
||||
$TITLE_COLOR="#aa0000"; #dark red
|
||||
|
||||
#
|
||||
# Color of the abstract title
|
||||
#
|
||||
$ABSTRACT_TITLE_COLOR="#486591"; #black
|
||||
|
||||
#
|
||||
# Color of each section title
|
||||
#
|
||||
$SECTION_COLOR="#486591";
|
||||
|
||||
#
|
||||
# Color of each subsection title
|
||||
#
|
||||
$SUBSECTION_COLOR="#486591";
|
||||
|
||||
#
|
||||
# Color of each subsubsection title
|
||||
#
|
||||
$SUBSUBSECTION_COLOR="#486591";
|
||||
|
||||
#
|
||||
# Color of each paragraph title
|
||||
#
|
||||
$PARAGRAPH_COLOR="#486591";
|
||||
|
||||
#
|
||||
# Colors for macros \newdef and \newtype
|
||||
#
|
||||
$NEWDEF_COLOR="#ff0000"; #red
|
||||
$NEWTYPE_COLOR="#ff0000"; #red
|
||||
|
||||
#
|
||||
# Colors for html links
|
||||
#
|
||||
$LINK_COLOR="navy";
|
||||
$VLINK_COLOR="gray";
|
||||
$ALINK_COLOR="maroon";
|
||||
|
||||
#
|
||||
# Colors for SML type variables, keywords and identifiers
|
||||
#
|
||||
$SML_TYVAR_COLOR="#00aaaa";
|
||||
$SML_KEYWORD_COLOR="#6060a0";
|
||||
$SML_IDENT_COLOR="#9c4040";
|
||||
|
||||
#
|
||||
# Color for emphasis
|
||||
#
|
||||
$EMPH_COLOR="#ff0000"; #red
|
||||
|
||||
#
|
||||
# Color for description items
|
||||
#
|
||||
$DESC_COLOR="#000070"; #blue
|
||||
|
||||
#
|
||||
# Color for captions
|
||||
#
|
||||
$CAPTION_COLOR="#007777"; #green/blue
|
||||
|
||||
#
|
||||
# Color of ML code
|
||||
#
|
||||
$CODE_COLOR="#000000"; # black
|
||||
|
||||
#
|
||||
# Background color of table of contents
|
||||
#
|
||||
$TOC_BACKGROUND_COLOR="#e6e6e6";
|
||||
|
||||
$SECTION_TOC_TEXT_COLOR="#486591";
|
||||
$MAJORSECTION_TEXT_COLOR="ffffff";
|
||||
$MAJORSECTION_BACKGROUND_COLOR="#486591";
|
||||
$SECTION_TOC_BACKGROUND_COLOR="#e6e6e6";
|
||||
$TOC_FACE="hevetica";
|
||||
$MAX_LOCAL_TOC_ENTRY_LENGTH=40;
|
||||
$MAX_GLOBAL_TOC_ENTRY_LENGTH=40;
|
||||
$GLOBAL_TOC_WIDTH=170;
|
||||
$SCREEN_WIDTH=700;
|
||||
$TEXT_WIDTH=600;
|
||||
$TOC_SIZE=-1;
|
||||
|
||||
$X_PIXELS = 1024;
|
||||
$Y_PIXELS = 768;
|
||||
$IMAGE_SCALING=0.8;
|
||||
$PAPER_HEIGHT = "11in";
|
||||
$PAPER_WIDTH = "8.5in";
|
||||
|
||||
@AUTHORS=("Lal George", "Allen Leung");
|
||||
@EMAILS=('george@research.bell-labs.com','leunga@cs.nyu.edu');
|
||||
|
||||
$WWWHOST="www.cs.nyu.edu";
|
||||
$URLPREFIX="leunga/MLRISC/Doc/html/";
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,3 @@
|
||||
\section{The TI C6x Back End}
|
||||
|
||||
No documentation yet.
|
||||
@@ -0,0 +1,23 @@
|
||||
\section{ILP Optimizations}
|
||||
\subsection{Introduction}
|
||||
This section is under construction. A new scheduler framework
|
||||
for superscalars that ties into the machine description language
|
||||
is currently being developed.
|
||||
\subsection{The ILP ToolBox}
|
||||
\subsubsection{List Scheduler}
|
||||
\subsubsection{Ranking Algorithms}
|
||||
Some more complex ranking algorithms (than say critical path) have been
|
||||
implemented. These are:
|
||||
\begin{itemize}
|
||||
\item The algorithm of
|
||||
\mlrischref{scheduling/PalemSimons.sig}{Palem and Simons}
|
||||
which appeared in TOPLAS '93. This algorithm
|
||||
computes the modified deadlines of a set instructions, with
|
||||
precedence, latency, and deadlines constraints.
|
||||
|
||||
\item The algorithm of
|
||||
\mlrischref{scheduling/LeungPalemPnueli.sig}{Leung, Palem, and Pnueli}
|
||||
which appeared in PACT '98.
|
||||
This algorithm computes the modified deadlines of a set of instructions,
|
||||
with precedence, latency, release-times and deadline constraints.
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,48 @@
|
||||
\section{MLRISC}
|
||||
\begin{center}
|
||||
\begin{Bold}
|
||||
A framework for retargetable and optimizing compiler back ends
|
||||
\end{Bold}
|
||||
\end{center}
|
||||
\begin{center}
|
||||
\begin{tabular}{cc}
|
||||
\begin{address}
|
||||
\href{mailto:george@research.bell-labs.com}{Lal George}
|
||||
\end{address} &
|
||||
\begin{address}
|
||||
\href{mailto:leunga@cs.nyu.edu}{ Allen Leung}
|
||||
\end{address} \\
|
||||
Bell Labs & New York University \\
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
\begin{center}
|
||||
\image{MLRISC logo}{pictures/png/uncol.png}{align="middle"}
|
||||
|
||||
\begin{Italics}
|
||||
\href{contributors.html}{Contributors}
|
||||
\end{Italics}
|
||||
\end{center}
|
||||
|
||||
Writing native code generators for modern processors is a significant
|
||||
investment. Unfortunately it is difficult
|
||||
to reuse this investment for other architectures, and even more
|
||||
difficult to reuse for other source language compilers. MLRISC is
|
||||
a customizable optimizing back-end written in
|
||||
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/sml.html}{Standard ML}
|
||||
and has been successfully retargeted to multiple architectures.
|
||||
MLRISC deals elegantly with the special requirements imposed by the
|
||||
execution model of different high-level, typed languages, by allowing
|
||||
many components of the system to be customized to fit the source language
|
||||
semantics and runtime system requirements.
|
||||
|
||||
The \begin{color}{#aa0000}Overview\end{color} pages on the left provide
|
||||
an introduction the MLRISC system, mostly from the client's perspective,
|
||||
while the \begin{color}{#aa0000}System\end{color}
|
||||
pages give a more detailed look at the
|
||||
innards, and are of interest to MLRISC hackers. As usual, development of
|
||||
the system has outpaced the documentation process substantally; thus
|
||||
the latter part of the document is incomplete but it may still be useful.
|
||||
|
||||
These pages are also available in
|
||||
\href{../latex/mlrisc.ps}{tech report} form.
|
||||
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# This file compiles the documentation
|
||||
#
|
||||
|
||||
TEX= sml.tex mlrisc.tex mltexdoc.tex
|
||||
PDF= $(TEX:.tex=.pdf)
|
||||
|
||||
all: pictures $(PDF)
|
||||
|
||||
pictures:
|
||||
(cd ../pictures; make)
|
||||
|
||||
pdf: $(PDF)
|
||||
|
||||
%.pdf:
|
||||
latexmk -bibtex -ps- -pdf $(@:.pdf=.tex)
|
||||
|
||||
mlrisc.pdf: annotations.tex graphics.tex instructions.tex mltree.tex \
|
||||
delayslots.tex cells.tex cluster.tex constants.tex \
|
||||
pseudo-ops.tex streams.tex labelexp.tex labels.tex regions.tex \
|
||||
regmap.tex graphs.tex mlrisc-ir.tex compiler-graphs.tex \
|
||||
SSA.tex VLIW.tex ra.tex ILP.tex mlrisc-arch.tex \
|
||||
future-work.tex asm.tex mc.tex instrsel.tex \
|
||||
availability.tex gc.tex mlrisc-gen.tex contributions.tex \
|
||||
systems.tex mlrisc-graphics.tex contributors.tex \
|
||||
requirements.tex INTRO.tex problem.tex mlrisc-compiler.tex \
|
||||
mlrisc-ir-rep.tex backend-opt.tex sys-integration.tex \
|
||||
optimizations.tex span-dep.tex mlrisc-md.tex line-counts.tex \
|
||||
sparc.tex alpha.tex x86.tex ppc.tex mips.tex hppa.tex C6.tex \
|
||||
mltree-ext.tex mltree-util.tex
|
||||
|
||||
mltexdoc.pdf: mltex.tex
|
||||
|
||||
clean:
|
||||
rm -f $(PDF) *.aux *.log *.bbl *.blg
|
||||
@@ -0,0 +1,21 @@
|
||||
\section{SSA Optimizations}\label{sec:ssa}
|
||||
|
||||
All SSA optimization modules satisfy the signature
|
||||
\mlrischref{SSA/ssa-optimization.sig}{SSA\_OPTIMIZATION},
|
||||
which is defined as:
|
||||
\begin{SML}
|
||||
signature SSA_OPTIMIZATION = sig
|
||||
structure SSA : SSA
|
||||
|
||||
val optimize : SSA.ssa -> SSA.ssa
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The following SSA based scalar optimizations have been implemented in MLRISC.
|
||||
\begin{itemize}
|
||||
\item \mlrischref{SSA/ssa-dead-code-elim.sml}{Dead code elimination}
|
||||
\item \mlrischref{SSA/ssa-gvn.sml}{Global value numbering, constant folding, algebraic simplication}
|
||||
\item \mlrischref{SSA/ssa-gcm.sml}{Global code motion}
|
||||
\item \mlrischref{SSA/ssa-cond-const-prop.sml}{Conditional constant propagation}
|
||||
\item \mlrischref{SSA/ssa-op-str-red.sml}{Strength reduction}
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,21 @@
|
||||
\section{Optimizations for VLIW/EPIC Architectures}
|
||||
|
||||
\subsection{Overview}
|
||||
Many newer architectures such as the upcoming IA-64 and the
|
||||
DSPs such as the C6 are VLIW or so called EPIC machines.
|
||||
These architectures depends on the compiler to
|
||||
extract instruction level parallelism (\newdef{ILP})
|
||||
and data level parallelism (\newdef{DLP}).
|
||||
|
||||
Optimizations for these architectures include:
|
||||
\begin{itemize}
|
||||
\item Hyperblock construction
|
||||
\item Predication and predicate analysis
|
||||
\item Hyperblock scheduling
|
||||
\item Modulo scheduling
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Hyperblocks}
|
||||
\subsection{Predicate Analysis}
|
||||
\subsection{Hyperblock Scheduling}
|
||||
\subsection{Modulo Scheduling}
|
||||
@@ -0,0 +1,97 @@
|
||||
\section{The Alpha Back End}
|
||||
|
||||
\subsection{Trap Shadows, Floating Exceptions, and Denormalized Numbers on the DEC Alpha}
|
||||
|
||||
\emph{By Andrew W. Appel and Lal George, Nov 28, 1995}
|
||||
|
||||
See section 4.7.5.1 of the \emph{Alpha Architecture Reference Manual}.
|
||||
|
||||
The Alpha has imprecise exceptions, meaning that if a floating
|
||||
point instruction raises an IEEE exception, the exception may
|
||||
not interrupt the processor until several successive instructions have
|
||||
completed. ML, on the other hand, may want a "precise" model
|
||||
of floating point exceptions.
|
||||
|
||||
Furthermore, the Alpha hardware does not support denormalized numbers
|
||||
(for ``gradual underflow''). Instead, underflow always rounds to zero.
|
||||
However, each floating operation (add, mult, etc.) has a trapping
|
||||
variant that will raise an exception (imprecisely, of course) on
|
||||
underflow; in that case, the instruction will produce a zero result
|
||||
AND an exception will occur. In fact, there are several variants
|
||||
of each instruction; three variants of MULT are:
|
||||
\begin{description}
|
||||
\item[MULT s1,s2,d] truncate denormalized result to zero; no exception
|
||||
\item[MULT/U s1,s2,d] truncate denormalized result to zero; raise UNDERFLOW
|
||||
\item[MULT/SU s1,s2,d] software completion, producing denormalized result
|
||||
\end{description}
|
||||
|
||||
The hardware treats the \verb|MULT/U| and \verb|MULT/SU|
|
||||
instructions identically,
|
||||
truncating a denormalized result to zero and raising the UNDERFLOW
|
||||
exception. But the operating system, on an UNDERFLOW exception,
|
||||
examines the faulting instruction to see if it's an \verb|/SU|
|
||||
form, and if so,
|
||||
recalculates \verb|s1*s2|, puts the right answer in \verb|d|, and continues,
|
||||
all without invoking the user's signal handler.
|
||||
|
||||
Because most machines compute with denormalized numbers in hardware,
|
||||
to maximize portability of SML programs, we use the \verb|MULT/SU| form.
|
||||
(and \verb|ADD/SU|, \verb|SUB/SU|, etc.) But to use this form successfully,
|
||||
certain rules have to be followed. Basically, d cannot be the same
|
||||
register as s1 or s2, because the opsys needs to be able to
|
||||
recalculate the operation using the original contents of s1 and s2,
|
||||
and the MULT/SU instruction will overwrite d even if it traps.
|
||||
|
||||
More generally, we may want to have a sequence of floating-point
|
||||
instructions. The rules for such a sequence are:
|
||||
|
||||
1. The sequence should end with a \verb|TRAPB| (trap barrier) instruction.
|
||||
(This could be relaxed somewhat, but certainly a \verb|TRAPB| would
|
||||
be a good idea sometime before the next branch instruction or
|
||||
update of an ML reference variable, or any other ML side effect.)
|
||||
2. No instruction in the sequence should destroy any operand of itself
|
||||
or of any previous instruction in the sequence.
|
||||
3. No two instructions in the sequence should write the same destination
|
||||
register.
|
||||
|
||||
We can achieve these conditions by the following trick in the
|
||||
Alpha code generator. Each instruction in the sequence will write
|
||||
to a different temporary; this is guaranteed by the translation from
|
||||
ML-RISC. At the beginning of the sequence, we will put a special
|
||||
pseudo-instruction (we call it \verb|DEFFREG|) that ``defines''
|
||||
the destination
|
||||
register of the arithmetic instruction. If there are $K$ arithmetic
|
||||
instructions in the sequence, then we'll insert $K$
|
||||
\verb|DEFFREG| instructions
|
||||
all at the beginning of the sequence.
|
||||
Then, each arithop will not only ``define'' its destination temporary
|
||||
but will ``use'' it as well. When all these instructions are fed to
|
||||
the liveness analyzer, the resulting interference graph will then
|
||||
have inteference edges satisfying conditions 2 and 3 above.
|
||||
|
||||
Of course, \verb|DEFFREG| doesn't actually generate any code. In our model
|
||||
of the Alpha, every instruction generates exactly 4 bytes of code
|
||||
except the ``span-dependent'' ones. Therefore, we'll specify \verb|DEFFREG|
|
||||
as a span-dependent instruction whose minimum and maximum sizes are zero.
|
||||
|
||||
At the moment, we do not group arithmetic operations into sequences;
|
||||
that is, each arithop will be preceded by a single \verb|DEFFREG| and
|
||||
followed by a \verb|TRAPB|. To avoid the cost of all those \verb|TRAPB|'s,
|
||||
we should improve this when we have time. Warning: Don't put more
|
||||
than 31 instructions in the sequence, because they're all required
|
||||
to write to different destination registers!
|
||||
|
||||
What about multiple traps? For example, suppose a sequence of
|
||||
instructions produces an Overflow and a Divide-by-Zero exception?
|
||||
ML would like to know only about the earliest trap, but the hardware
|
||||
will report \emph{BOTH} traps to the operating system. However, as long
|
||||
as the rules above are followed (and the software-completion versions
|
||||
of the arithmetic instructions are used), the operating system will
|
||||
have enough information to know which instruction produced the
|
||||
trap. It is very probable that the operating system will report \emph{ONLY}
|
||||
the earlier trap to the user process, but I'm not sure.
|
||||
|
||||
For a hint about what the operating system is doing in its own
|
||||
trap-handler (with software completion), see section 6.3.2 of
|
||||
``\emph{OpenVMS Alpha Software}'' (Part II of the Alpha Architecture
|
||||
Manual). This stuff should apply to Unix (OSF1) as well as VMS.
|
||||
@@ -0,0 +1,33 @@
|
||||
\section{Annotations}
|
||||
|
||||
\subsection{Overview}
|
||||
A compiler front-end has to be propagate information to
|
||||
the back-end. An optimization phase may have to leave behind information
|
||||
at various places of the IR so that other phases can reuse such information.
|
||||
MLRISC uses the \newdef{annotations}
|
||||
mechanism for these functions.
|
||||
Individual instructions, basic blocks, and flow graph edges,
|
||||
can be attached one or more annotations.
|
||||
|
||||
The basic MLRISC system understands many annotations. Some examples are:
|
||||
\begin{description}
|
||||
\item[COMMENT]
|
||||
these can be used to attach comments. If attached to
|
||||
an instruction, the assemblers will output
|
||||
them as part of their assembly output.
|
||||
\item[BRANCH\_PROB]
|
||||
these can be attached to a branch instruction to indicate
|
||||
the probability in which is it taken.
|
||||
\item[EXECUTION\_FREQ]
|
||||
these can be attached to a basic block to indicate
|
||||
its expected execution frequency
|
||||
\end{description}
|
||||
|
||||
\subsection{Details}
|
||||
The primitive annotations datatype is defined
|
||||
to have this \mlrischref{library/annotations.sig}{signature}.
|
||||
In addition, MLRISC predefined a few primitive annotations that are
|
||||
recognized by the core system. This signature is
|
||||
\mlrischref{instructions/mlriscAnnotations.sig}{MLRISC\_ANNOTATIONS}.
|
||||
More detailed documentation can be found in this
|
||||
\href{http://cm.bell-labs.com/cm/cs/what/smlnj/compiler-notes/annotations.ps}{paper}.
|
||||
@@ -0,0 +1,60 @@
|
||||
\section{Assemblers}
|
||||
|
||||
\subsubsection{Overview}
|
||||
Assemblers in MLRISC satisfy the signature
|
||||
\mlrischref{emit/instruction-emitter.sig}{INSTRUCTION\_EMITTER},
|
||||
which is defined as:
|
||||
\begin{SML}
|
||||
signature INSTRUCTION_EMITTER =
|
||||
sig
|
||||
structure I : \href{instructions.html}{INSTRUCTIONS}
|
||||
structure C : \href{cells.html}{CELLS}
|
||||
structure S : \href{streams.html}{INSTRUCTION_STREAM}
|
||||
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
|
||||
sharing I.C = C
|
||||
sharing S.P = P
|
||||
|
||||
val makeStream : Annotations.annotations ->
|
||||
((int -> int) -> I.instruction -> unit,
|
||||
unit,'b,'c,'d,'e) S.stream
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The function \sml{makeStream} returns an instruction stream.
|
||||
By default the output is bound to the stream \sml{AsmStream.asmOutStream}
|
||||
defined in the structure
|
||||
\mlrischref{emit/asmStream.sml}{AsmStream} at creation time.
|
||||
|
||||
The structure \sml{AsmStream} satisfy the following signature.
|
||||
\begin{SML}
|
||||
signature ASM_STREAM = sig
|
||||
val asmOutStream : TextIO.outstream ref
|
||||
val withStream : TextIO.outstream -> ('a -> 'b) -> 'a -> 'b
|
||||
end
|
||||
\end{SML}
|
||||
\subsubsection{Redirecting the Output}
|
||||
It is possible to redirect the output of an instruction stream.
|
||||
For example, the following statement
|
||||
\begin{SML}
|
||||
val asm = makeStream []
|
||||
\end{SML}
|
||||
binds the output of \sml{asm} to \sml{AsmStream.asmOutStream}, which
|
||||
by default is just \sml{TextIO.stdOut}. On the other hand, the
|
||||
statement
|
||||
\begin{SML}
|
||||
val asm = AsmStream.withStream mystream makeStream []
|
||||
\end{SML}
|
||||
binds the output of asm to \sml{mystream}.
|
||||
|
||||
\subsubsection{More Details}
|
||||
|
||||
Assemblers are automatically generated by the
|
||||
\href{mlrisc-md.html}{MDGen} tool. Some specific generated
|
||||
assemblers are listed below:
|
||||
\begin{enumerate}
|
||||
\item \mlrischref{sparc/emit/sparcAsm.sml}{Sparc}
|
||||
\item \mlrischref{hppa/emit/hppaAsm.sml}{Hppa}
|
||||
\item \mlrischref{alpha/emit/alphaAsm.sml}{Alpha}
|
||||
\item \mlrischref{ppc/emit/ppcAsm.sml}{Power PC}
|
||||
\item \mlrischref{x86/emit/x86Asm.sml}{X86}
|
||||
\end{enumerate}
|
||||
@@ -0,0 +1,33 @@
|
||||
\section{How to Obtain MLRISC}
|
||||
|
||||
There are a few ways to obtain the MLRISC system.
|
||||
\begin{enumerate}
|
||||
\item
|
||||
An old version of MLRISC is available from
|
||||
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/doc/MLRISC/quick-tour/index.html}{this link}.
|
||||
This version is stable but very out-dated, and does
|
||||
not contain the most up-to-date features.
|
||||
\item
|
||||
New experimental versions are available from the
|
||||
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/software.html}{SML/NJ software page} as part of the SML/NJ compiler releases.
|
||||
These versions are relative stable, but
|
||||
do not include the entire MLRISC source tree.
|
||||
\item \href{mailto:leunga@cs.nyu.edu}{Allen}
|
||||
keeps an up-to-date version of MLRISC at NYU for private use.
|
||||
This version includes everything but is under constant changes, so beware!
|
||||
To access the CVS repository, set your \sml{CVSROOT} environment variable
|
||||
to
|
||||
\begin{verbatim}
|
||||
:pserver:mlrisc@react-ilp.cs.nyu.edu:/home/leunga/mlrisc
|
||||
\end{verbatim}
|
||||
and checkout the repository using
|
||||
\begin{verbatim}
|
||||
cvs co MLRISC++
|
||||
\end{verbatim}
|
||||
The password to use is \sml{mlrisc}.
|
||||
\item
|
||||
Generally speaking, you can get the latest version of MLRISC by asking
|
||||
\href{mailto:george@research.bell-labs.com}{Lal}.
|
||||
\end{enumerate}
|
||||
MLRISC is \newdef{free, open source} software, and is released under the
|
||||
\href{http://cm.bell-labs.com/cm/cs/what/smlnj/license.html}{SML/NJ license}.
|
||||
@@ -0,0 +1,15 @@
|
||||
\section{Back End Optimizations}
|
||||
|
||||
Once MLRisc trees have been generated, they are passed into a module
|
||||
that generates a flowgraph of target machine instructions. Again,
|
||||
this module and all subsequent optimization phases have been
|
||||
specialized to the front end.
|
||||
\image{Back end optimizations}{pictures/png/optimization.png}{align=right}
|
||||
Nearly all
|
||||
instruction selection modules provided by MLRISC use a simple tree
|
||||
pattern matching algorithm rather than the more heavy weight BURG
|
||||
tools --- including the x86 \begin{color}{#580000} It is important to
|
||||
emphasis that all optimizations are performed on the flowgraph of
|
||||
target machine instructions and \emph{not} MLRisc
|
||||
immediate IR. \end{color} There is complete flexibility in the order,
|
||||
and nature of the optimizations performed.
|
||||
@@ -0,0 +1,146 @@
|
||||
\section{Cells}
|
||||
|
||||
MLRISC uses
|
||||
the \mlrischref{instructions/cells.sig}{CELLS}
|
||||
interface to define all readable/writable resources
|
||||
in a machine architecture, or \emph{cells}
|
||||
The types defined herein are:
|
||||
\begin{itemize}
|
||||
\item \sml{cellkind} -- different classes of cells are assigned
|
||||
difference cellkinds. The following cellkinds should be present
|
||||
\begin{itemize}
|
||||
\item \sml{GP} -- general purpose registers.
|
||||
\item \sml{FP} -- floating point registers.
|
||||
\item \sml{CC} -- condition code registers.
|
||||
\end{itemize}
|
||||
In addition, the cellkinds \sml{MEM} and \sml{CTRL}
|
||||
should also be defined. These are used for representing
|
||||
memory based data dependence and control dependence.
|
||||
\begin{itemize}
|
||||
\item \sml{MEM} -- memory
|
||||
\item \sml{CTRL} -- control dependence
|
||||
\end{itemize}
|
||||
\item \sml{regmap} -- \href{regmap.html}{register map}
|
||||
\item \sml{cellset} -- a cellset represent a set of cells. This
|
||||
type can be used to denote live-in/live-out information. Cellsets are
|
||||
implemented as immutable abstract types.
|
||||
\end{itemize}
|
||||
|
||||
These core definitions are defined in the following signature
|
||||
\begin{SML}
|
||||
signature \mlrischref{instructions/cells.sig}{CELLS\_BASIS} =
|
||||
sig
|
||||
eqtype cellkind
|
||||
type cell = int
|
||||
type regmap = cell Intmap.intmap
|
||||
exception Cells
|
||||
|
||||
val cellkinds : cellkind list
|
||||
val cellkindToString : cellkind -> string
|
||||
val firstPseudo : cell
|
||||
val Reg : cellkind -> int -> cell
|
||||
val GPReg : int -> cell
|
||||
val FPReg : int -> cell
|
||||
val cellRange : cellkind -> {low:int, high:int}
|
||||
val newCell : cellkind -> 'a -> cell
|
||||
val cellKind : cell -> cellkind
|
||||
val updateCellKind : cell * cellkind -> unit
|
||||
val numCell : cellkind -> unit -> int
|
||||
val maxCell : unit -> cell
|
||||
val newReg : 'a -> cell
|
||||
val newFreg : 'a -> cell
|
||||
val newVar : cell -> cell
|
||||
val regmap : unit -> regmap
|
||||
val lookup : regmap -> cell -> cell
|
||||
val reset : unit -> unit
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
\begin{itemize}
|
||||
\item\sml{cellkinds} -- this is a list of all the cellkinds defined in the
|
||||
architecture
|
||||
\item\sml{cellkindToString} -- this function maps a cellkind into its name
|
||||
\item\sml{firstPseudo} -- MLRISC numbered physical resources
|
||||
in the architecture from 0 to firstPseudo-1.
|
||||
This is the first usable virtual register number.
|
||||
\item\sml{Reg} -- This function maps the $i$th physical
|
||||
resource of a particular cellkind to its internal encoding used by MLRISC.
|
||||
Note that all resources in MLRISC are named uniquely.
|
||||
\item\sml{GPReg} -- abbreviation for \sml{Reg GP}
|
||||
\item\sml{FPReg} -- abbreviation for \sml{Reg FP}
|
||||
\item \sml{cellRange} -- this returns a range \sml{{low, high}}
|
||||
when given a cellkind, with denotes the range of physical resources
|
||||
\item \sml{newCell} -- This function returns a new virtual register
|
||||
of a particular cellkind.
|
||||
\item \sml{newReg} -- abbreviation as \sml{newCell GP}
|
||||
\item \sml{newFreg} -- abbreviation as \sml{newCell FP}
|
||||
\item \sml{cellKind} -- When given a cell number, this returns its
|
||||
cellkind. Note that this feature is not enabled by default.
|
||||
\item \sml{updateCellKind} -- updates the cellkind of a cell.
|
||||
\item \sml{numCell} -- returns the number of virtual cells allocated for one cellkind.
|
||||
\item \sml{maxCell} -- returns the next virtual cell id.
|
||||
\item \sml{newVar} -- given a cell id, return a new cell id of
|
||||
the same cellkind.
|
||||
\item \sml{regmap} -- This function returns a new empty regmap
|
||||
\item \sml{lookup} -- This converts a regmap into a lookup function.
|
||||
\item \sml{reset} -- This function resets all counters associated
|
||||
with all virtual cells.
|
||||
\end{itemize}
|
||||
|
||||
\begin{SML}
|
||||
signature CELLS = sig
|
||||
include CELLS_BASIS
|
||||
val GP : cellkind
|
||||
val FP : cellkind
|
||||
val CC : cellkind
|
||||
val MEM : cellkind
|
||||
val CTRL : cellkind
|
||||
val toString : cellkind -> cell -> string
|
||||
val stackptrR : cell
|
||||
val asmTmpR : cell
|
||||
val fasmTmp : cell
|
||||
val zeroReg : cellkind -> cell option
|
||||
|
||||
type cellset
|
||||
|
||||
val empty : cellset
|
||||
val addCell : cellkind -> cell * cellset -> cellset
|
||||
val rmvCell : cellkind -> cell * cellset -> cellset
|
||||
val addReg : cell * cellset -> cellset
|
||||
val rmvReg : cell * cellset -> cellset
|
||||
val addFreg : cell * cellset -> cellset
|
||||
val rmvFreg : cell * cellset -> cellset
|
||||
val getCell : cellkind -> cellset -> cell list
|
||||
val updateCell : cellkind -> cellset * cell list -> cellset
|
||||
|
||||
val cellsetToString : cellset -> string
|
||||
val cellsetToString' : (cell -> cell) -> cellset -> string
|
||||
|
||||
val cellsetToCells : cellset -> cell list
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
\begin{itemize}
|
||||
\item \sml{toString} -- convert a cell id of a certain cellkind into
|
||||
its assembly name.
|
||||
\item \sml{stackptrR} -- the cell id of the stack pointer register.
|
||||
\item \sml{asmTmpR} -- the cell id of the assembly temporary
|
||||
\item \sml{fasmTmp} -- the cell id of the floating point temporary
|
||||
\item \sml{zeroReg} -- given the cellkind, returns the cell id of the
|
||||
source that always hold the value of zero, if there is any.
|
||||
\item \sml{empty} -- an empty cellset
|
||||
\item \sml{addCell} -- inserts a cell into a cellset
|
||||
\item \sml{rmvCell} -- remove a cell from a cellset
|
||||
\item \sml{addReg} -- abbreviation for \sml{addCell GP}
|
||||
\item \sml{rmvReg} -- abbreviation for \sml{rmvCell GP}
|
||||
\item \sml{addFreg} -- abbreviation for \sml{addCell FP}
|
||||
\item \sml{rmvFreg} -- abbreviation for \sml{rmvCell FP}
|
||||
\item \sml{getCell} -- lookup all cells of a particular cellkind from
|
||||
the cellset
|
||||
\item \sml{updateCell} -- replace all cells of a particular cellkind
|
||||
from the cellset.
|
||||
\item \sml{cellsetToString} -- pretty print a cellset
|
||||
\item \sml{cellsetToString'} -- pretty print a cellset, but first
|
||||
apply a regmap function.
|
||||
\item \sml{cellsetToCells} -- convert a cellset into list form.
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,53 @@
|
||||
\section{Cluster}
|
||||
|
||||
A \newdef{cluster}
|
||||
represents a compilation unit in linearized form,
|
||||
and contains information about the control flow, global annotations,
|
||||
block and edge execution frequencies, and live-in/live-out information.
|
||||
|
||||
Its signature is:
|
||||
\begin{SML}
|
||||
signature FLOWGRAPH = sig
|
||||
structure C : \href{cells.html}{CELLS}
|
||||
structure I : \href{instructions.html}{INSTRUCTIONS}
|
||||
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
|
||||
structure W : \href{freq.html}{FREQ}
|
||||
sharing I.C = C
|
||||
|
||||
datatype block =
|
||||
PSEUDO of P.pseudo_op
|
||||
| LABEL of Label.label
|
||||
| BBLOCK of
|
||||
\{ blknum : int,
|
||||
freq : W.freq ref,
|
||||
annotations : Annotations.annotations ref,
|
||||
liveIn : C.cellset ref,
|
||||
liveOut : C.cellset ref,
|
||||
succ : edge list ref,
|
||||
pred : edge list ref,
|
||||
insns : I.instruction list ref
|
||||
\}
|
||||
| ENTRY of
|
||||
\{blknum : int, freq : W.freq ref, succ : edge list ref\}
|
||||
| EXIT of
|
||||
\{blknum : int, freq : W.freq ref, pred : edge list ref\}
|
||||
withtype edge = block * W.freq ref
|
||||
|
||||
datatype cluster =
|
||||
CLUSTER of \{
|
||||
blocks: block list,
|
||||
entry : block,
|
||||
exit : block,
|
||||
regmap: C.regmap,
|
||||
blkCounter : int ref,
|
||||
annotations : Annotations.annotations ref
|
||||
\}
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
Clusters are used in
|
||||
\href{span-dep.html}{span dependency resolution},
|
||||
\href{delayslots.html}{delay slot filling},
|
||||
\href{asm.html}{assembly},
|
||||
and \href{mc.html}{machine code}
|
||||
output, since these phases require the code laid out in linearized form.
|
||||
@@ -0,0 +1,434 @@
|
||||
\section{Basic Compiler Graphs}
|
||||
|
||||
\subsection{Introduction}
|
||||
In this section we describe the set of core compiler specific graphs and
|
||||
algorithms implemented in MLRISC.
|
||||
Mostly of these algorithms are parameterized with respect
|
||||
to the actual intermediate representation, and as such they
|
||||
do not provide many facilities that are provided by higher abstraction
|
||||
layers, such as in \href{mlrisc-ir.html}{MLRISC IR},
|
||||
or in \href{SSA.html}{SSA}.
|
||||
|
||||
\subsubsection{Dominator/Post-dominator Trees}
|
||||
\newdef{Dominance}
|
||||
is a fundamental concept in compiler optimizations.
|
||||
Node $A$ $dominates$ $B$
|
||||
iff all paths from the start node
|
||||
to $B$ intersects A. A dual notion is the concept of
|
||||
$post-dominance$:
|
||||
$A$ \newdef{post-dominates} $B$ iff all paths from $B$ to the stop node
|
||||
intersects $A$. A (post-)dominator tree can be used
|
||||
to summarize the dominance/post-dominance relationship.
|
||||
|
||||
\begin{SML}
|
||||
functor \mlrischref{ir/dominator.sml}{DominatorTree}
|
||||
(GraphImpl : GRAPH_IMPLEMENTATION) : DOMINATOR_TREE
|
||||
\end{SML}
|
||||
The functor implements dominator analysis and
|
||||
creates a dominator/post-dominator tree from a graph $G$. A dominator tree is implemented as a graph
|
||||
with the following definition:
|
||||
\begin{SML}
|
||||
signature \mlrischref{ir/dominator.sig}{DOMINATOR_TREE} = sig
|
||||
exception Dominator
|
||||
datatype 'n dom_node =
|
||||
DOM of \{ node : 'n, level : int, preorder : int, postorder : int \}
|
||||
type ('n,'e,'g) dom_info
|
||||
type ('n,'e,'g) dominator_tree = ('n dom_node,unit,('n,'e,'g) dom_info) graph
|
||||
type ('n,'e,'g) postdominator_tree = ('n dom_node,unit,('n,'e,'g) dom_info) graph
|
||||
\end{SML}
|
||||
|
||||
We annotated each node in
|
||||
a dominator tree with three extra fields of information, which
|
||||
is useful for other algorithms:
|
||||
\begin{itemize}
|
||||
\item\sml{level} is the nesting level of the tree. The root
|
||||
node has level 0, children of the root has level 1 and so on.
|
||||
\item\sml{preorder} is the preorder numbering of a node
|
||||
\item\sml{preorder} is the postorder numbering of a node.
|
||||
\end{itemize}
|
||||
|
||||
To create a dominator tree and a postdominator tree
|
||||
from a graph, the following function should be called.
|
||||
\begin{SML}
|
||||
val dominator_trees : ('n,'e,'g) graph ->
|
||||
('n,'e,'g) dominator_tree * ('n,'e,'g) postdominator_tree
|
||||
\end{SML}
|
||||
We use the algorithm of Tarjan and Lengauer, which
|
||||
runs in time $O(|V+E|\alpha(|V+E|))$ where $\alpha$ is the functional
|
||||
inverse of the Ackermann function.
|
||||
|
||||
To perform many common queries on a dominator tree, we first
|
||||
call the function \sml{methods} to obtain a method object.
|
||||
\begin{SML}
|
||||
val methods : ('n,'e,'g) dominator_tree -> dominator_methods
|
||||
\end{SML}
|
||||
|
||||
The methods are packed into the following type:
|
||||
\begin{SML}
|
||||
type dominator_methods =
|
||||
\{ dominates : node_id * node_id -> bool,
|
||||
immediately_dominates : node_id * node_id -> bool,
|
||||
strictly_dominates : node_id * node_id -> bool,
|
||||
postdominates : node_id * node_id -> bool,
|
||||
immediately_postdominates : node_id * node_id -> bool,
|
||||
strictly_postdominates : node_id * node_id -> bool,
|
||||
control_equivalent : node_id * node_id -> bool,
|
||||
idom : node_id -> node_id, $(* ~1 if none *)$
|
||||
idoms : node_id -> node_id list,
|
||||
doms : node_id -> node_id list,
|
||||
ipdom : node_id -> node_id, $(* ~1 if none *)$
|
||||
ipdoms : node_id -> node_id list,
|
||||
pdoms : node_id -> node_id list,
|
||||
dom_lca : node_id * node_id -> node_id,
|
||||
pdom_lca : node_id * node_id -> node_id,
|
||||
dom_level : node_id -> int,
|
||||
pdom_level : node_id -> int,
|
||||
control_equivalent_partitions : unit -> node_id list list
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
The query methods are as follows:
|
||||
\begin{methods}
|
||||
dominates($a,b$) & returns true iff $a$ dominates $b$ \\
|
||||
immediately\_dominates($a,b$) & returns true iff $a$ immediately dominates $b$ \\
|
||||
strictly\_dominates($a,b$) & returns true iff $a$ strictly dominates $b$ \\
|
||||
postdominates($a,b$) & returns true iff $a$ post-dominates $b$ \\
|
||||
immediately\_postdominates($a,b$) & returns true iff $a$ immediately post-dominates $b$ \\
|
||||
strictly\_postdominates($a,b$) & returns true iff $a$ strictly post-dominates $b$ \\
|
||||
control\_equivalent($a,b$) &
|
||||
returns true iff $a$ dominates $b$ and vice versa \\
|
||||
idom($a$) & returns the immediate dominator of $a$, or $-1$ if none exists \\
|
||||
idoms($a$) & returns all nodes that $a$ immediately dominates \\
|
||||
doms($a$) & returns all nodes that $a$ dominates (including $a$ itself) \\
|
||||
ipdom($a$) & returns the immediate post-dominator of $a$, or $-1$ if none exists \\
|
||||
ipdoms($a$) & returns all nodes that $a$ immediately post-dominates \\
|
||||
pdoms($a$) & returns all nodes that $a$ post-dominates (including $a$ itself) \\
|
||||
dom\_lca($a,b$) & returns the least common ancestor of $a$ and $b$ in
|
||||
the dominator tree \\
|
||||
pdom\_lca($a,b$) & returns the least common ancestor of $a$ and $b$
|
||||
in the post-dominator tree \\
|
||||
dom\_level($a$) & returns the nesting level of $a$ in the dominator tree \\
|
||||
pdom\_level($b$) & returns the nesting level of $a$ in the post-dominator
|
||||
tree \\
|
||||
control\_equivalent\_partitions & partitions the graph into
|
||||
a set of control equivalent nodes.
|
||||
\end{methods}
|
||||
|
||||
The methods \sml{dom_lca}, \sml{pdom_lca} and
|
||||
\sml{control_equivalent_partitions} executes in $O(n)$ time, where
|
||||
$n$ is the size of the dominator tree. The other methods run in $O(1)$ time.
|
||||
|
||||
\subsubsection{Control Dependence Graph}
|
||||
Given two nodes $A$ and $B$ in a control flow graph $G$,
|
||||
we say that $B$ is \newdef{control dependent} on $A$ iff
|
||||
\begin{itemize}
|
||||
\item $B$ post-dominates a successor of $A$
|
||||
\item $B$ does not strictly post-dominates $A$
|
||||
\end{itemize}
|
||||
Intuitively, $B$ is control dependent on $A$ means that
|
||||
some path in the program that goes through $A$ can by-passed $B$,
|
||||
and furthermore, $A$ is the point in which this divergence can occur.
|
||||
Control dependence is used to various kinds of analysis and optimizations in
|
||||
a compiler, such as code motion and global scheduling~\cite{bernstein-rodeh}.
|
||||
|
||||
To build a control dependence graph, the functor
|
||||
\sml{ControlDependenceGraph} can be used:
|
||||
\begin{SML}
|
||||
signature \mlrischref{ir/cdg.sig}{CONTROL_DEPENDENCE_GRAPH} = sig
|
||||
type ('n,'e,'g) cdg = ('n,'e,'g) graph
|
||||
|
||||
val control_dependence_graph :
|
||||
('e -> bool) ->
|
||||
('n,'e,'g) dominator_tree *
|
||||
('n,'e,'g) postdominator_tree ->
|
||||
('n,'e,'g) cdg
|
||||
end
|
||||
functor \mlrischref{ir/cdg.sml}{ControlDependenceGraph}
|
||||
(structure Dom : DOMINATOR_TREE
|
||||
structure GraphImpl : GRAPH_IMPLEMENTATION
|
||||
) : CONTROL_DEPENDENCE_GRAPH
|
||||
\end{SML}
|
||||
The control depedence graph is a subcomponent of the
|
||||
program dependence graph commonly used in
|
||||
modern compiler optimizations.
|
||||
|
||||
\subsubsection{Dominance Frontiers}
|
||||
|
||||
Many algorithms involving the notion of control dependence or dominance
|
||||
can be rephrased in terms of \newdef{dominance frontiers}.
|
||||
A node $A$ is in the dominance frontiers of $B$ iff
|
||||
$B$ dominates a predecessor of $A$ but $B$ does not strictly-dominate $A$.
|
||||
We denote this as $A \in DF(B)$.
|
||||
The dual notion of \newdef{post-dominance frontiers} can be defined
|
||||
analogously using the post-dominator tree\footnote{Control dependence
|
||||
can be defined in terms of post-dominance frontiers.}.
|
||||
|
||||
\begin{SML}
|
||||
functor \mlrischref{ir/dominance-frontier.sml}{DominanceFrontiers}(Dom : DOMINATOR_TREE) : DOMINANCE_FRONTIERS
|
||||
\end{SML}
|
||||
The functor \sml{DominanceFrontiers} can be used to
|
||||
compute all the dominance frontiers of all the nodes in a graph.
|
||||
It has the following signature.
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{ir/dominance-frontier.sig}{DOMINANCE_FRONTIERS} = sig
|
||||
structure Dom : DOMINATOR_TREE
|
||||
type dominance_frontiers = node_id list array
|
||||
val DFs : ('n,'e,'g) Dom.dominator_tree -> dominance_frontiers
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Iterated Dominance Frontiers}
|
||||
|
||||
\newdef{Iterated dominance frontiers} (denoted as $DF^+$) are defined
|
||||
as the least fixed point of iterating the operation $DF$. Formally,
|
||||
define the dominance frontiers on a set $S$ as follows:
|
||||
\[
|
||||
DF(S) \defas \Union_{A \in S} DF(A)
|
||||
\]
|
||||
Define iteration of $DF$, denoted as $DF^n$, as follows:
|
||||
\begin{eqnarray*}
|
||||
DF^1(S) & \defas & DF(S) \\
|
||||
DF^{n+1}(S) & \defas & DF(S \union DF^n(S)) \\
|
||||
\end{eqnarray*}
|
||||
The iterated dominance frontiers $DF^+(S)$ on a set $S$ are defined as
|
||||
the limit:
|
||||
\[
|
||||
DF^+(S) \defas \lim_{n \to \infty} DF^n(S)
|
||||
\]
|
||||
|
||||
Iterated dominance frontiers of a set $S$ can be computed in
|
||||
time $O(|S|+|V|+|E|)$ using the
|
||||
algorithm by Sreedhar and Gao~\cite{linear-time-IDF}\footnote{
|
||||
In practice it is often sub-linear in $|V|+|E|$.}.
|
||||
|
||||
\begin{SML}
|
||||
functor \mlrischref{ir/djgraph.sml}{DJGraph}(Dom : DOMINATOR_TREE) : DJ_GRAPH
|
||||
\end{SML}
|
||||
The functor \sml{DJGraph} implements this algorithm.
|
||||
It satisfies the signature below:
|
||||
\begin{SML}
|
||||
signature \mlrischref{ir/djgraph.sig}{DJ_GRAPH} = sig
|
||||
structure Dom : DOMINATOR_TREE
|
||||
type ('n,'e,'g) dj_graph = ('n,'e,'g) Dom.dominator_tree
|
||||
val dj_graph : ('n,'e,'g) dj_graph ->
|
||||
\{ DF : node_id -> node_id list,
|
||||
IDF : node_id -> node_id list,
|
||||
IDFs : node_id list -> node_id list
|
||||
\}
|
||||
end
|
||||
\end{SML}
|
||||
The function \sml{dj_graph} takes a dominator tree and returns
|
||||
three query methods for computing dominance and iterated dominance frontiers.
|
||||
Method \sml{DF} computes $DF(v)$ for a single node $v$.
|
||||
Method \sml{IDF} computes the $DF^+(v)$, and method
|
||||
\sml{IDFs} computes $DF^+(S)$ when given a set of node ids.
|
||||
The dominator tree must not be updated while these operations
|
||||
are being performed.
|
||||
|
||||
Sreedhar's original algorithm is phrased in terms of the
|
||||
DJ-graph, which is a fusion of the dominator tree
|
||||
with its underlying flowgraph. Our variant operates on the
|
||||
dominator tree and the flowgraph at the same time, without
|
||||
building an intermediate data structure.
|
||||
|
||||
Iterated dominance frontiers are used
|
||||
in many algorithms that deal with the notion of dominance.
|
||||
For example, our SSA construction algorithm uses iterated
|
||||
dominance frontiers to identify confluent points in the program
|
||||
where $phi$-functions are to be placed.
|
||||
|
||||
\subsubsection{Loop Nesting Tree}
|
||||
|
||||
A \newdef{natural loop} $L$ in a graph is a maximal
|
||||
strongly connected component
|
||||
such that all nodes in $L$ are dominated by a single node $h$, called
|
||||
the \newdef{loop header}. Loops tend to form good optimization candidates
|
||||
and consequently \newdef{loop detection} is an essential task in a compiler.
|
||||
The functor
|
||||
\begin{SML}
|
||||
functor \mlrischref{ir/loop-structure.sml}{LoopStructure}
|
||||
(structure GraphImpl : GRAPH_IMPLEMENTATION
|
||||
structure Dom : DOMINATOR_TREE
|
||||
) : LOOP_STRUCTURE
|
||||
\end{SML}
|
||||
recognizes all natural loops in a graph and built a
|
||||
\newdef{loop nesting tree}
|
||||
that describes the loop nesting relationship between graphs.
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{ir/loop-structure.sig}{LOOP_STRUCTURE} = sig
|
||||
structure Dom : DOMINATOR_TREE
|
||||
datatype ('n,'e,'g) loop =
|
||||
LOOP of \{ nesting : int,
|
||||
header : node_id,
|
||||
loop_nodes : node_id list,
|
||||
backedges : 'e edge list,
|
||||
exits : 'e edge list
|
||||
\}
|
||||
|
||||
type ('n,'e,'g) loop_info
|
||||
type ('n,'e,'g) loop_structure = (('n,'e,'g) loop,unit, ('n,'e,'g) loop_info) graph
|
||||
|
||||
val loop_structure : ('n,'e,'g) Dom.dominator_tree -> ('n,'e,'g) loop_structure
|
||||
val nesting_level : ('n,'e,'g) loop_structure -> node_id array
|
||||
val header : ('n,'e,'g) loop_structure -> node_id array
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
Our algorithm computes the loop nesting tree in time
|
||||
$O((|V|+|E|)\alpha(|V|+|E|))$.
|
||||
Each node in this tree represents a loop in the flowgraph, except the
|
||||
root of the tree, which represents the entire graph.
|
||||
Given a flowgraph $G$, the root
|
||||
of the loop nesting tree is defined to be the sole vertex in
|
||||
\sml{#entry} $G$. Other nodes in the tree
|
||||
are indexed by the loop header node ids.
|
||||
|
||||
Loop detection classifies each loop and for
|
||||
each loop $L$, the following information is obtained:
|
||||
\begin{itemize}
|
||||
\item An integer \sml{nesting}. The root of the tree has nesting
|
||||
depth 0. The top level loops have nesting depth 1, etc.
|
||||
\item The node id of the loop \sml{header} $h$.
|
||||
\item A set of \sml{loop_nodes}. Loop nodes are
|
||||
nodes that are in the strongly connected
|
||||
component $L$, but excluding the header $h$
|
||||
and all nodes that are part of any nested loops.
|
||||
Thus all nodes are uniquely partitioned in header nodes and
|
||||
loop nodes, and loop nodes are further partitioned into different
|
||||
sets according to which headers they are immediately nested under.
|
||||
\item A set of \sml{backedges}. A back-edge is an
|
||||
edge that targets the header $h$ and originates from a loop node
|
||||
in $L$.
|
||||
\item A set of loop \sml{exits}. An exit-edge is an edge
|
||||
that originates from a loop node within $L$
|
||||
targets a node outside of $L$. Note that this set does not include
|
||||
any exit-edges contained in loops nested in $L$ but
|
||||
target a node out of $L$.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Static Single Assignment}
|
||||
|
||||
An SSA construction algorithm based on~\cite{SSA,Briggs-SSA,linear-time-IDF}
|
||||
is implemented in the following functor:
|
||||
\begin{SML}
|
||||
functor \mlrischref{ir/ssa.sml}{StaticSingleAssignmentForm}
|
||||
(Dom : DOMINATOR_TREE) : STATIC_SINGLE_ASSIGNMENT_FORM
|
||||
\end{SML}
|
||||
|
||||
SSA-based optimizations in MLRISC
|
||||
are actually implemented on top of a
|
||||
high-level SSA layer described in Section~\ref{sec:ssa}.
|
||||
So it is not necessary to use this module directly. Nevertheless,
|
||||
there can be situations in which this module can be specialized in other
|
||||
ways; for example, in the construction of sparse evaluation graphs.
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{ir/ssa.sig}{STATIC_SINGLE_ASSIGNMENT_FORM} = sig
|
||||
structure Dom : DOMINATOR_TREE
|
||||
type var = int
|
||||
type phi = var * var * var list $(* orig def/def/uses *)$
|
||||
type renamer = \{defs : var list, uses: var list\} ->
|
||||
\{defs : var list, uses: var list\}
|
||||
type copy = \{dst : var list, src: var list\} -> unit
|
||||
|
||||
val compute_ssa :
|
||||
('n,'e,'g) Dom.dominator_tree ->
|
||||
\{ max_var : var,
|
||||
defs : 'n node -> var list,
|
||||
is_live : var * int -> bool,
|
||||
rename_var : var -> var,
|
||||
rename_stmt : \{rename:renamer,copy:copy\} -> 'n node -> unit,
|
||||
insert_phi : \{block : 'n node,
|
||||
in_edges : 'e edge list,
|
||||
phis : phi list
|
||||
\} -> unit
|
||||
\} -> unit
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
This module defines the function \sml{compute_ssa}, which
|
||||
constructs an SSA graph. It requires
|
||||
the following information from the client:
|
||||
\begin{itemize}
|
||||
\item A dominator tree of the flowgraph.
|
||||
\item \sml{max_var} -- the maximum variable id (integer) that exists
|
||||
in the flowgraph. All variables are assumed to be indexed by non-negative
|
||||
integers.
|
||||
\item \sml{defs}($X$) -- a function that returns $defs(X)$,
|
||||
i.e.~the set of variable names defined in block $X$.
|
||||
If a minimal SSA form is desired, this set should include all the definitions
|
||||
in $X$. If a pruned SSA form is required, this set should
|
||||
include only the set of names that are live-out in $X$.
|
||||
\item \sml{is_live}($v,X$) -- a function that determines if
|
||||
variable $v$ is live-in into block $X$. If not, a $\phi$-function will
|
||||
not be placed in $X$. For example, to compute
|
||||
the minimal-SSA form, this function should always return true.
|
||||
\item \sml{rename_var}($v$) -- a function that returns a new
|
||||
unique name for variable $v$.
|
||||
\item \sml{rename_stmt} -- a function of type
|
||||
\sml{{rename:renamer,copy:copy} -> 'n node -> unit} where
|
||||
\begin{SML}
|
||||
type renamer = \{defs : var list, uses: var list\} ->
|
||||
\{defs : var list, uses: var list\}
|
||||
type copy = \{dst : var list, src: var list\} -> unit
|
||||
\end{SML}
|
||||
Function \sml{rename_stmt} is called for each block
|
||||
in the flowgraph in the order of the dominator tree, and
|
||||
is responsible for renaming all the variables in $X$ by
|
||||
calling the functions \sml{renamer} or \sml{copy}.
|
||||
Function \sml{renamer} renames all definitions and uses of
|
||||
a statement, while function \sml{copy} renames
|
||||
of a set of parallel assignments
|
||||
\item \sml{insert_phi}($X$,$es$,$phis$) --
|
||||
a function that inserts a set of
|
||||
$\phi$-definitions $phis$ in block $X$, where $es$
|
||||
is the list of control flow edges that merge into block $X$.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{IDEFS/IUSE sets}
|
||||
Reif and Tarjan define the following useful notions for
|
||||
computing approximate birth-points for expressions, which in turn
|
||||
can be used to drive other optimizations.
|
||||
Given a node $X$, let $idom(X)$ denote the immediate dominator of $X$.
|
||||
Let $def(X)$ ($use(X)$) denote all the definitions (uses) in $X$.
|
||||
Given a path $p \equiv v_1\ldots v_n$, define $def(p)$ ($use(p)$) as
|
||||
\begin{eqnarray*}
|
||||
def(v_1\ldots v_n) & \equiv &\union_{i \in 1 \ldots n} def(v_i) \\
|
||||
use(v_1\ldots v_n) & \equiv &\union_{i \in 1 \ldots n} use(v_i)
|
||||
\end{eqnarray*}
|
||||
|
||||
Let $P(X)$ denotes all the paths from $idom(X)$ to $X$
|
||||
that does not cross $idom(X)$ internally. Then define
|
||||
$idef(X)$ ($iuse(X)$) as:
|
||||
\begin{eqnarray*}
|
||||
idef(X) & \equiv & \Union_{idom(X) v_1 \ldots v_n X \in P(X)}
|
||||
def(v_1\ldots v_n) \\
|
||||
iuse(X) & \equiv & \Union_{idom(X) v_1 \ldots v_n X \in P(X)}
|
||||
use(v_1\ldots v_n)
|
||||
\end{eqnarray*}
|
||||
The sets $ipostdef(X)$ and $ipostuse(X)$ are defined analogously
|
||||
using the postdominator tree.
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{ir/idefs2.sig}{IDEFS} = sig
|
||||
type var = int
|
||||
val compute_idefs :
|
||||
\{def_use : 'n Graph.node -> var list * var list,
|
||||
cfg : ('n,'e,'g) Graph.graph
|
||||
\} ->
|
||||
\{ idefuse : unit -> (RegSet.regset * RegSet.regset) Array.array,
|
||||
ipostdefuse : unit -> (RegSet.regset * RegSet.regset) Array.array
|
||||
\}
|
||||
end
|
||||
structure \mlrischref{ir/idefs2.sml}{IDefs} : IDEFS
|
||||
\end{SML}
|
||||
Structure \sml{IDefs} implements the function
|
||||
\sml{comput_idefs} for computing
|
||||
the $idef$, $iuse$, $ipostdef$ and $ipostuse$ sets of a control flow
|
||||
graph. It takes as arguments a flowgraph and a function \sml{def_use}, which
|
||||
takes a graph node and returns the def/use sets of the node.
|
||||
It returns two functions \sml{idefuse} and \sml{ipostdefuse} which
|
||||
compute the $idef/iuse$ and $ipostdef/ipostuse$ sets. These sets
|
||||
are returned as arrays indexed by node ids.
|
||||
@@ -0,0 +1,36 @@
|
||||
\section{Client Defined Constants}
|
||||
\subsubsection{Introduction}
|
||||
MLRISC allows the client to inject abstract
|
||||
\newdef{constants} that are resolved
|
||||
only at the end of the compilation phase into the instruction stream.
|
||||
These constants can be used whereever an integer literal is expected.
|
||||
Typical usage are stack frame offsets for spill locations which are only
|
||||
known after register allocation,
|
||||
and garbage collection and exception map which are resolved only
|
||||
when all address calculation are performed.
|
||||
|
||||
\subsubsection{The Details}
|
||||
Client defined constants should satsify the following signature:
|
||||
\begin{SML}
|
||||
signature \mlrischref{instructions/constant.sig}{CONSTANT} = sig
|
||||
type const
|
||||
|
||||
val toString : const -> string
|
||||
val valueOf : const -> int
|
||||
val hash : const -> word
|
||||
val == : const * const -> bool
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The methods are:
|
||||
\begin{methods}
|
||||
toString & a pretty printing function \\
|
||||
valueOf & returns the value of the constant \\
|
||||
hash & returns the hash value of the constant \\
|
||||
== & compare two constants for identity \\
|
||||
\end{methods}
|
||||
|
||||
The method \sml{toString} should be implemented in all cases.
|
||||
The method \sml{valueOf} is necessary only if machine code generation
|
||||
is used. The last two methods, \sml{hash} and \sml{==} are necessary
|
||||
only if SSA optimizations are used.
|
||||
@@ -0,0 +1,60 @@
|
||||
\section{Contributions}
|
||||
The optimizations provided by MLRISC are at a similar level to
|
||||
those performed by the Impact compiler; several target back ends
|
||||
exist (Dec Alpha, HPPA, Sparc, x86, and PPC); but more importantly, the
|
||||
framework has been demonstrated in \href{systems.html}{real use}
|
||||
for languages with radically different execution models. These include:
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{|c|c|} \hline
|
||||
Compiler & Association \\ \hline
|
||||
\begin{color}{#005500}SML/NJ\end{color} & Bell Labs and Princeton\\\hline
|
||||
\begin{color}{#005500}TIL\end{color} & CMU \\ \hline
|
||||
\begin{color}{#005500}Tiger\end{color} & Princeton \\ \hline
|
||||
\begin{color}{#005500}C--\end{color} & OGI \\ \hline
|
||||
\begin{color}{#005500}SML/Regions\end{color} & DIKU \\ \hline
|
||||
\begin{color}{#005500}Moby\end{color} & Bell Labs \\ \hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
The strength of MLRISC lies in the ability to easily create high
|
||||
quality code generator for each of these systems. For example:
|
||||
|
||||
\begin{description}
|
||||
\item[Tiger:] Has an execution
|
||||
model very similar to C with stack allocated activation frames,
|
||||
and also maintains static and dynamic chains to support lexical
|
||||
scoping.
|
||||
|
||||
\item[TIL:] Is similar to C in its
|
||||
use of activation frames, however it uses a
|
||||
\emph{typed intermediate language} that
|
||||
supports \emph{almost tag-free}
|
||||
garbage collection. This has severe implications on the
|
||||
interaction of spilling and garbage collection. The set of live
|
||||
variables and their locations, be it registers or frame slots,
|
||||
is recorded in a trace table for a specific program point. When
|
||||
spilling occurs, it is necessary to adjust some of these trace
|
||||
tables to reflect the new locations of live variables.
|
||||
|
||||
\item[SML/NJ:] Has no runtime
|
||||
stack, but stores all execution context in a garbage collected
|
||||
heap. This arrangement imposes special requirements for spilling
|
||||
registers. SML/NJ also does \emph{dynamic linking} --- that is
|
||||
to say, no use is made of a conventional linker, but machine
|
||||
code is generated directly and linked into the interactive
|
||||
environment, dynamically.
|
||||
|
||||
\item[C--:] Is a C-like portable assembly
|
||||
language used as an intermediate language for high level typed language,
|
||||
and provides direct compilation support for exceptions and
|
||||
precise garbage collection. In addition, it allows
|
||||
interoperability with C function calls.
|
||||
\end{description}
|
||||
|
||||
It is not uncommon for any of these systems to store special global
|
||||
values in dedicated registers, and use their own parameter passing
|
||||
and callee-save conventions. In any language that supports garbage
|
||||
collection, there are also the issues of generating gc type maps,
|
||||
and gc-safety in aggressive optimizations. MLRISC deals with all these
|
||||
important issues by allowing customization of many aspects of the system.
|
||||
@@ -0,0 +1,15 @@
|
||||
\section{Contributors}
|
||||
\subsubsection{Past}
|
||||
\begin{itemize}
|
||||
\item Florent Guillame (INRIA)
|
||||
\item George C. Necula (CMU)
|
||||
\item Ken Cline (CMU)
|
||||
\item Andrew Bernard (CMU)
|
||||
\item Dino Oliva (NEC)
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Present}
|
||||
\begin{itemize}
|
||||
\item Allen Leung (NYU)
|
||||
\item Fermin Reig (University of Glasgow)
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,174 @@
|
||||
\section{Delay Slot Filling}
|
||||
\subsection{ Overview }
|
||||
|
||||
Superscalar architectures such as the Sparc, MIPS, and PA-RISC
|
||||
contain delayed branch and/or load instructions.
|
||||
Delay slot filling is necessary
|
||||
task of the back end to keep the instruction pipelines busy. To accomodate
|
||||
the intricate semantics of branch delay slot in various architectures,
|
||||
MLRISC uses the following very general framework for dealing with
|
||||
delayed instructions.
|
||||
|
||||
\begin{description}
|
||||
\item[Instruction representation]
|
||||
To make it easy to deal with instruction with delay slot, MLRISC allow
|
||||
the following extensions to instruction representations.
|
||||
\begin{itemize}
|
||||
\item Instructions with delay slot may have a
|
||||
\begin{color}{#aa0000}nop\end{color} flag. When this flag is true
|
||||
the delay slot is assumed to be filled with a NOP instruction.
|
||||
\item Instructions with delay slots that can be nullified may have a
|
||||
\begin{color}{#aa0000}nullified\end{color} flag.
|
||||
When this flag is true the branch delay slot is assumed to be
|
||||
nullified.
|
||||
\end{itemize}
|
||||
\item[Nullification semantics]
|
||||
Unfortunately, nullification semantics
|
||||
in architectures vary. In general, MLRISC allows the following
|
||||
additional nullification characteristics to be specified.
|
||||
\begin{itemize}
|
||||
\item Nullification can be specified as illegal; this is needed
|
||||
because some instructions can not be nullified
|
||||
\item When nullification is enabled, the semantics of the delay slot
|
||||
instruction may depend on the direction of the branch, and whether
|
||||
a conditional test succeeds.
|
||||
\item Certain class of instructions may be declared to be illegal
|
||||
to fit into certain class of delay slots.
|
||||
\end{itemize}
|
||||
\end{description}
|
||||
|
||||
For example, conditional branch instructions on the Sparc are defined
|
||||
as follows:
|
||||
\begin{verbatim}
|
||||
Bicc of {b:branch, a:bool, label:Label.label, nop:bool}
|
||||
asm: ``b<b><a>\t<label><nop>''
|
||||
padding: nop = true
|
||||
nullified: a = true and (case b of I.BA => false | _ => true)
|
||||
delayslot candidate: false
|
||||
\end{verbatim}
|
||||
\noindent where \sml{a} is \emph{annul} flag and \sml{nop} is the nop
|
||||
flag (see \mlrischref{sparc/sparc.md}{the Sparc machine description}).
|
||||
A constructor term
|
||||
\begin{SML}
|
||||
Bicc\{b=BE, a=true, label=label, nop=true\}
|
||||
\end{SML}
|
||||
denotes the instruction sequence
|
||||
\begin{verbatim}
|
||||
be,a label
|
||||
nop
|
||||
\end{verbatim}
|
||||
while
|
||||
\begin{SML}
|
||||
Bicc\{b=BE, a=false, label=label, nop=false\}
|
||||
\end{SML}
|
||||
denotes
|
||||
\begin{verbatim}
|
||||
be label
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\subsection{The Interface}
|
||||
|
||||
Architecture information about how delay slot filling is to be performed
|
||||
is described in the signature
|
||||
\mlrischref{backpatch/delaySlotProps.sig}{DELAY\_SLOT\_PROPERTIES}.
|
||||
\begin{SML}
|
||||
signature DELAY_SLOT_PROPERTIES =
|
||||
sig
|
||||
structure I : INSTRUCTIONS
|
||||
|
||||
datatype delay_slot =
|
||||
D_NONE | D_ERROR | D_ALWAYS
|
||||
| D_TAKEN | D_FALLTHRU
|
||||
|
||||
val delaySlotSize : int
|
||||
val delaySlot : \{ instr : I.instruction, backward : bool \} ->
|
||||
\{ n : bool,
|
||||
nOn : delay_slot,
|
||||
nOff : delay_slot,
|
||||
nop : bool
|
||||
\}
|
||||
val enableDelaySlot :
|
||||
\{instr : I.instruction, n:bool, nop:bool\} -> I.instruction
|
||||
val conflict :
|
||||
\{regmap:int->int,src:I.instruction,dst:I.instruction\} -> bool
|
||||
val delaySlotCandidate :
|
||||
\{ jmp : I.instruction, delaySlot : I.instruction \} -> bool
|
||||
val setTarget : I.instruction * Label.label -> I.instruction
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The components of this signature are:
|
||||
\begin{description}
|
||||
\item[delay\_slot] This datatype describes properties related to a
|
||||
delay slot.
|
||||
\begin{description}
|
||||
\item[D\_NONE] This indicates that no delay slot is possible.
|
||||
\item[D\_ERROR] This indicates that it is an error
|
||||
\item[D\_ALWAYS] This indicates that the delay slot is always active
|
||||
\item[D\_TAKEN] This indicates that the
|
||||
delay slot is only active when branch is taken
|
||||
\item[D\_FALLTHRU] This indicates that the delay slot
|
||||
is only active when branch is not taken
|
||||
\end{description}
|
||||
\item[delaySlotSize] This is size of delay slot in bytes.
|
||||
|
||||
\item[delaySlot] This method takes an instruction \sml{instr}
|
||||
and a flag indicating whether the branch is \sml{backward},
|
||||
and returns the delay slot properties of an instruction. The
|
||||
properties is described by four fields.
|
||||
\begin{description}
|
||||
\item[n : bool] This bit is if the nullified bit in the
|
||||
instruction is currently set.
|
||||
\item[nOn : delay\_slot] This field indicates the delay slot
|
||||
type when the instruction is nullified.
|
||||
\item[nOff : delay\_slot] This field indiciates the delay slot
|
||||
type when the instruction is not nullified.
|
||||
\item[nop : bool] This bit indicates whether there is an
|
||||
implicit padded nop.
|
||||
\end{description}
|
||||
|
||||
|
||||
\item[enableDelaySlot]
|
||||
This method set the nullification and nop flags of an instruction.
|
||||
|
||||
\item[conflict] This method checks whether there are any conflicts
|
||||
between instruction \sml{src} and \sml{dst}.
|
||||
\item[delaySlotCandidate]
|
||||
This method checks whether instruction \sml{delaySlot} is within the
|
||||
class of instructions that can fit within the delay slot of
|
||||
instruction \sml{jmp}.
|
||||
|
||||
\item[setTarget]
|
||||
This method changes the branch target of an instruction.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{Examples}
|
||||
For example,
|
||||
\begin{SML}
|
||||
delaySlot\{instr=instr, backward=true\} =
|
||||
\{n=true, nOn=D_ERROR, nOff=D_ALWAYS, nop=true\}
|
||||
\end{SML}
|
||||
\noindent means that the instruction nullification bit is on, the
|
||||
the nullification cannot be turned off, delay slot is always active
|
||||
(when not nullified), and there is currently an implicit padded nop.
|
||||
|
||||
\begin{SML}
|
||||
delaySlot\{instr=instr, backward=false\} =
|
||||
\{n=false, nOn=D_NONE, nOff=D_TAKEN, nop=false\}
|
||||
\end{SML}
|
||||
\noindent means that the nullification bit is off, the delay slot
|
||||
is inactive when the nullification bit is off, the delay slot is only
|
||||
active when the (forward) branch is taken when \sml{instr} is
|
||||
not-nullified, and there
|
||||
is no implicitly padded nop.
|
||||
|
||||
\begin{SML}
|
||||
delaySlot\{instr=instr, backward=true\} =
|
||||
\{n=true, nOn=D_TAKEN, nOff=D_ALWAYS, nop=true\}
|
||||
\end{SML}
|
||||
\noindent means that the nullification bit is on, the delay slot
|
||||
is active on a taken (backward) branch when the nullification bit is off,
|
||||
the delay slot is always active when \sml{instr} is not-nullified,
|
||||
and there is currently an implicitly padded nop.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
\section{Frequency Driven Compilation}
|
||||
|
||||
Most optimizations in MLRISC are driven by execution frequencies
|
||||
estimates provided by the front-end. These can be in the form of explicit
|
||||
vertex and edge frequencies, in the form of branch probabilities, or a
|
||||
combination of the above. Frequency information can be propagated
|
||||
to the backend via the \href{annotations.html}{annotations} mechanism.
|
||||
@@ -0,0 +1,30 @@
|
||||
\section{Future Work}
|
||||
\subsection{Short Term}
|
||||
|
||||
\begin{description}
|
||||
\item[Detailed user manual:]
|
||||
A detailed user manual describing the interfaces, algorithms,
|
||||
and examples on how to put together code generators.
|
||||
\item[Support for GC:]
|
||||
There is a strong interaction
|
||||
with support for GC and global code motion. MLRISC aims at
|
||||
providing a generic framework for code generators, and finding
|
||||
the right level of information to support GC and global code
|
||||
motion is an issue. I think we have several solutions to address
|
||||
this that need more evaluation.
|
||||
\item[Other architectures:] There is the need to port
|
||||
to other architectures like the MIPS, and the IA-64.
|
||||
\end{description}
|
||||
\hr
|
||||
\subsection{Long Term}
|
||||
\begin{description}
|
||||
\item[Predicated VLIW compilation:] Currently, the framework
|
||||
for predicated VLIW architectures compilation
|
||||
is incomplete, and contain only one back end (C6)
|
||||
\item[Other compilers:] I would really like to see some
|
||||
major compiler effort bootstrapped with an MLRISC backend.
|
||||
\item[Verification] It is extremely difficult to
|
||||
debug errors in modules that perform aggressive code
|
||||
reorganizations. Ideas from formal methods such as typed assembly
|
||||
language (TAL) or Proof Carrying Code (PCC) are worth investigating.
|
||||
\end{description}
|
||||
@@ -0,0 +1,104 @@
|
||||
\section{Garbage Collection Safety}
|
||||
\subsection{Motivation}
|
||||
High level languages such as SML make use of garbage collectors
|
||||
to reclaim unused storage at runtime. For generality, I assume that
|
||||
a precise, compacting garbage collector is used. In general,
|
||||
low-level optimizations that reorder instructions
|
||||
pass \newdef{gc safepoints}, when applied naively,
|
||||
are not safe. In general, two general classes of safety issues can be identified:
|
||||
\begin{description}
|
||||
\item[derived values]
|
||||
A derived value $x$ is a value that are
|
||||
dependent on the addresses of one of more heap allocated objects
|
||||
$a1,a2,a3,\ldots$ and/or the recent branch history.
|
||||
When these allocated objects $a1,a2,a3,\ldots$
|
||||
are moved by the garbage collector, $x$
|
||||
has to be adjusted accordingly.
|
||||
|
||||
For example, inductive variable elimination may transformed an array
|
||||
indexing into a running pointer to the middle of an array object.
|
||||
Such running pointer is a derived value and is dependent on the
|
||||
starting address of the array.
|
||||
|
||||
The main difficulty in handling a derived value $x$
|
||||
during garbage collection is that sometimes it is impossible or
|
||||
counter-productive to recompute from $a1,a2,a3,\ldots$.
|
||||
For example, when the recent branch history is unknown, or when the
|
||||
precise relationship between $x$ and $a1,a2,a3,\ldots$ cannot
|
||||
be inferred from context.
|
||||
We call these \newdef{unrecoverable} derived values.
|
||||
\item[incomplete allocation]
|
||||
If heap allocation is performed inlined, then code motion may
|
||||
render some allocation incomplete at a gc safepoint. In general, incomplete
|
||||
allocation has to be completed, or rolled backed and then reexecuted
|
||||
after garbage collection, when the source language semantics allow it.
|
||||
\end{description}
|
||||
|
||||
Typically, two gc safepoints cannot be separated by an unbounded
|
||||
number of allocations, which implies that in general, optimizations that move
|
||||
instructions between basic blocks are unsafe when naively applied,
|
||||
which greatly limits the class of optimizations in such an environment
|
||||
to trivial basic block level optimizations.
|
||||
framework is a necessity.
|
||||
|
||||
|
||||
\subsection{Safety Framework}
|
||||
MLRISC contains a gc-safety framework
|
||||
for performing aggressive machine level optimizations, including SSA-based
|
||||
scalar optimizations, global instruction scheduling, and global
|
||||
register allocation. Unlike previous work in this area, phases that
|
||||
perform optimizations and phases that maintain and update
|
||||
garbage collection information are completely separate, and the optimizer
|
||||
is constructed in a fully modular manner. In particular,
|
||||
gc-types and safety constraints
|
||||
are \emph{parameterizable}
|
||||
by the source language semantics, the object representation,
|
||||
and the target architectures.
|
||||
|
||||
This framework has the following overall structure:
|
||||
\begin{description}
|
||||
\item[Garbage collection invariants annotation]
|
||||
The front-end client is responsible for annotating each
|
||||
value in the program with a \newdef{gc type}, which is
|
||||
used to specify the abstract object representation,
|
||||
and the constraints on code motion that may be applied to such a value.
|
||||
The front-end uses an architecture independent \href{mltree.html}{RTL}
|
||||
language for representing the program, thus this annotation
|
||||
phase is portable between target architectures.
|
||||
\item[GC constraints propagation]
|
||||
After instruction selection, gc constraint are propagated throughout
|
||||
the machine level program representation. Again, for portability, gc typing
|
||||
rules are specified in terms of the \href{mltree.html}{ RTL } of
|
||||
the machine instructions. In this phase, unsafe code motions which
|
||||
exposes unrecoverable derived values to gc safepoints are automatically
|
||||
identified. (Pseudo) control dependence and anti-control dependence
|
||||
constraints are then added the program representation to prohibit all
|
||||
gc-unsafe code motions.
|
||||
\item[Machine level optimizations]
|
||||
After constraints propagation, traditional
|
||||
machine level optimizations such as
|
||||
SSA optimizations and/or global scheduling are applied, without regard
|
||||
to gc information. This is safe because
|
||||
all gc safety constraints have been translated into the appropriate
|
||||
code motion constraints.
|
||||
\item[GC type propagation and gc code generation]
|
||||
GC type inference is performed when all optimizations
|
||||
have been performed. GC safepoints are then
|
||||
identified and the root sets are determined. In addition, compensation
|
||||
code are inserted at gc points for repairing recoverable derived values.
|
||||
\end{description}
|
||||
\subsection{Concurrency Safety}
|
||||
In the presence of \newdef{concurrency}, i.e. multiple threads
|
||||
of control that communicate via a shared heap, the above framework
|
||||
will have to slightly extended. As in before, we assume that
|
||||
context switching can only occur at well-defined
|
||||
\emph{safepoints}.
|
||||
The crucial aspect is that values that are live at safepoints must be
|
||||
classified as \newdef{local} or \newdef{global}.
|
||||
Local values are only observable from
|
||||
the local thread, while global values are potentially observable and mutable
|
||||
from other threads. The invariants to maintain are as follows:
|
||||
\begin{itemize}
|
||||
\item Only local and recoverable derived values may be live at a safepoint,
|
||||
\item Only local and recoverable allocation may be incomplete at a safepoint
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,128 @@
|
||||
\section{The Graph Visualization Library}
|
||||
\subsection{Overview}
|
||||
Visualization is an important aid for debugging graph algorithms.
|
||||
MLRISC provides a simple facility for displaying graphs that
|
||||
adheres to the graph interface. Two graph viewer
|
||||
back-ends are currently supported. (An interface to the \emph{dot}
|
||||
tool is still available but is unsupported.)
|
||||
\begin{itemize}
|
||||
\item \externhref{http://www.cs.uni-sb.de/RW/users/sander/html/gsvcg1.html}{vcg} --
|
||||
this tool supports the browsing
|
||||
of hierarchical graphs, zoom in/zoom out functions. It can
|
||||
handle up to around 5000 nodes in a graph.
|
||||
\item \externhref{http://www.Informatik.Uni-Bremen.DE/~davinci/}{daVinci} --
|
||||
this tool supports a separate
|
||||
``survey'' view from the main view and text searching. This tool is
|
||||
slower than vcg but it has a nicer interface, and
|
||||
can handle up to around 500 nodes in a graph.
|
||||
\end{itemize}
|
||||
All graph viewing back-ends work in the same manner.
|
||||
They take a graph whose nodes and edges are annotated with \newdef{layout}
|
||||
instructions and translate these layout instructions
|
||||
into the target description language. For vcg, the target description
|
||||
language is GDL. For daVinci, it is a language based on s-expressions.
|
||||
|
||||
\subsection{Graph Layout}
|
||||
Some basic layout formats are defined structure \sml{GraphLayout} are:
|
||||
\begin{SML}
|
||||
structure \mlrischref{visualization/graphLayout.sml}{GraphLayout} = struct
|
||||
datatype format =
|
||||
LABEL of string
|
||||
| COLOR of string
|
||||
| NODE_COLOR of string
|
||||
| EDGE_COLOR of string
|
||||
| TEXT_COLOR of string
|
||||
| ARROW_COLOR of string
|
||||
| BACKARROW_COLOR of string
|
||||
| BORDER_COLOR of string
|
||||
| BORDERLESS
|
||||
| SHAPE of string
|
||||
| ALGORITHM of string
|
||||
| EDGEPATTERN of string
|
||||
|
||||
type ('n,'e,'g) style =
|
||||
\{ edge : 'e edge -> format list,
|
||||
node : 'n node -> format list,
|
||||
graph : 'g -> format list
|
||||
\}
|
||||
type layout = (format list, format list, format list) graph
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The interpretation of the layout formats are as follows:
|
||||
\begin{center}
|
||||
\begin{tabular}{|l|l|} \hline
|
||||
\sml{LABEL} $l$ & Label a node or an edge with the string $l$ \\
|
||||
\sml{COLOR} $c$ & Use color $c$ for a node or an edge \\
|
||||
\sml{NODE_COLOR} $c$ & Use color $c$ for a node \\
|
||||
\sml{EDGE_COLOR} $c$ & Use color $c$ for an edge \\
|
||||
\sml{TEXT_COLOR} $c$ & Use color $c$ for the text within a node \\
|
||||
\sml{ARROW_COLOR} $c$ & Use color $c$ for the arrow of an edge \\
|
||||
\sml{BACKARROW_COLOR} $c$ & Use color $c$ for the arrow of an edge \\
|
||||
\sml{BORDER_COLOR} $c$ & Use color $c$ for the border in a node \\
|
||||
\sml{BORDERLESS} & Disable border for a node \\
|
||||
\sml{SHAPE} $s$ & Use shape $s$ for a node \\
|
||||
\sml{ALGORITHM} $a$ & Use algorithm $a$ to layout the graph \\
|
||||
\sml{EDGEPATTERN} $p$ & Use pattern $p$ to layout an edge \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
Exactly how these formats are interpreted is determined by
|
||||
the visualization tool that is used. If a feature is unsupported
|
||||
then the corresponding format will be ignored.
|
||||
Please see the appropriate reference manuals of vcg and daVinci for details.
|
||||
|
||||
\subsection{Layout style}
|
||||
How a graph is layout is determined by its \newdef{layout style}:
|
||||
\begin{SML}
|
||||
type ('n,'e,'g) style =
|
||||
\{ edge : 'e edge -> format list,
|
||||
node : 'n node -> format list,
|
||||
graph : 'g -> format list
|
||||
\}
|
||||
\end{SML}
|
||||
which is simply three functions that convert nodes, edges and graph
|
||||
info into layout formats.
|
||||
The function \sml{makeLayout} can be used to convert a
|
||||
layout style into a layout, which can then be passed to a graph
|
||||
viewer to be displayed.
|
||||
\begin{SML}
|
||||
GraphLayout.makeLayout : ('n,'e,'g) style -> ('n,'e,'g) graph -> layout
|
||||
\end{SML}
|
||||
|
||||
\subsection{Graph Displays}
|
||||
|
||||
A \newdef{graph display} is an abstraction for the
|
||||
interface that converts a layout graph into an external graph
|
||||
description language. This abstraction is defined in the
|
||||
signature below.
|
||||
\begin{SML}
|
||||
signature \mlrischref{visualization/graphDisplay.sig}{GRAPH_DISPLAY} = sig
|
||||
val suffix : unit -> string
|
||||
val program : unit -> string
|
||||
val visualize : (string -> unit) -> GraphLayout.layout -> unit
|
||||
end
|
||||
\end{SML}
|
||||
\begin{itemize}
|
||||
\item \sml{suffix} is the common file suffix used for the graph description
|
||||
language
|
||||
\item \sml{program} is the common name of the graph visualization tool
|
||||
\item \sml{visualize} is a function that takes a
|
||||
string output function and a layout graph $G$ as arguments
|
||||
and generates a graph description based on $G$
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Graph Viewers}
|
||||
|
||||
The graph viewer functor
|
||||
\mlrischref{visualization/graphViewer.sml}{GraphViewer}
|
||||
takes a graph display back-end and creates a graph viewer
|
||||
that can be used to display any layout graph.
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{visualization/graphViewer.sig}{GRAPH_VIEWER} = sig
|
||||
val view : GraphLayout.layout -> unit
|
||||
end
|
||||
functor GraphViewer(D : GRAPH_DISPLAY) : GRAPH_VIEWER
|
||||
\end{SML}
|
||||
@@ -0,0 +1,3 @@
|
||||
\section{The PA RISC Back End}
|
||||
|
||||
No documentation yet.
|
||||
@@ -0,0 +1,244 @@
|
||||
\section{Instruction Selection} \label{sec:instrsel}
|
||||
Instruction selection modules are reponsible for translating
|
||||
\href{mltree.html}{MLTree} statements into a flowgraph consisting
|
||||
of target machine instructions. MLRISC decomposes this complex task
|
||||
into \emph{three} components:
|
||||
\begin{description}
|
||||
\item[Instruction selection modules] which are responsible for
|
||||
mapping a sequence of MLTree statements into a sequence target machine code,
|
||||
\item[Flowgraph builders] which are responsible for constructing
|
||||
the graph representation of the program from a sequence of target machine
|
||||
instructions, and
|
||||
\item[Client Extender] which are responsible for compiling
|
||||
MLTree extensions (see also Section~\ref{sec:mltree-extension}).
|
||||
\end{description}
|
||||
By detaching these components, extra flexiblity is obtained. For example,
|
||||
the MLRISC system uses two different internal representations. The
|
||||
first, \href{cluster.html}{cluster}, is a \emph{light-weight} representation
|
||||
which is suitable for simple compilers without extensive
|
||||
optimizations; the second, \href{mlrisc-ir.html}{MLRISC IR}, is a
|
||||
\emph{heavy duty} representation which allows very complex transformations
|
||||
to be performed. Since the flowgraph builders are detached from the
|
||||
instruction selection modules, the same instruction selection modules
|
||||
can be used for both representations.
|
||||
|
||||
For consistency, the three components communicate to each other
|
||||
via the same \href{stream.html}{stream} interface.
|
||||
|
||||
\subsection{Interface Definition}
|
||||
All instruction selection modules satisfy the following signature:
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{mltree/mltreecomp.sig}{MLTREECOMP} =
|
||||
sig
|
||||
structure T : \href{mltree.html}{MLTREE}
|
||||
structure I : \href{instructions.html}{INSTRUCTIONS}
|
||||
structure C : \href{cells.html}{CELLS}
|
||||
sharing T.LabelExp = I.\href{labelexp.html}{LabelExp}
|
||||
sharing I.C = C
|
||||
|
||||
type instrStream = (I.instruction,C.regmap,C.cellset) T.stream
|
||||
type mltreeStream = (T.stm,C.regmap,T.mlrisc list) T.stream
|
||||
|
||||
val selectInstructions : instrStream -> mltreeStream
|
||||
end
|
||||
\end{SML}
|
||||
Intuitively, this signature states that
|
||||
the instruction selection module
|
||||
returns a function that can transform a stream of MLTree statements
|
||||
(\newtype{mltreeStream}) into a stream of instructions of the target
|
||||
machine (\newtype{instrStream}).
|
||||
|
||||
\subsubsection{Compiling Client Extensions}
|
||||
|
||||
Compilation of client extensions to MLTREE is controlled by the
|
||||
following signature:
|
||||
\begin{SML}
|
||||
signature \mlrischref{mltree/mltreecomp.sig}{MLTREE_EXTENSION_COMP} =
|
||||
sig
|
||||
structure T : \href{mltree.html}{MLTREE}
|
||||
structure I : \href{instructions.html}{INSTRUCTIONS}
|
||||
structure C : \href{cells.html}{CELLS}
|
||||
sharing T.LabelExp = I.\href{labelexp.html}{LabelExp}
|
||||
sharing I.C = C
|
||||
|
||||
type reducer =
|
||||
(I.instruction,C.regmap,C.cellset,I.operand,I.addressing_mode) T.reducer
|
||||
|
||||
val compileSext : reducer -> \{stm:T.sext, an:T.an list\} -> unit
|
||||
val compileRext : reducer -> \{e:T.ty * T.rext, rd:C.cell, an:T.an list\} -> unit
|
||||
val compileFext : reducer -> \{e:T.ty * T.fext, fd:C.cell, an:T.an list\} -> unit
|
||||
val compileCCext : reducer -> \{e:T.ty * T.ccext, ccd:C.cell, an:T.an list\} -> unit
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
Methods \verb|compileSext|, \verb|compileRext|, etc.~are callbacks that
|
||||
are responsible for compiling MLTREE extensions. The arguments
|
||||
to these callbacks have the following meaning:
|
||||
\begin{description}
|
||||
\item[reducer] The first argument is always the \newtype{reducer},
|
||||
which contains internal methods for translating MLTree constructs
|
||||
into machine code. These methods are supplied by the instruction
|
||||
selection modules.
|
||||
\item[an] This is a list of annotations that should be attached to the
|
||||
generated code.
|
||||
\item[ty, fty] These are the types of the extension construct.
|
||||
\item[stm, e] This are the extension statement and expression.
|
||||
\item[rd, fd, cd] These are the target registers of the
|
||||
expression extension, i.e.~the callback should generate the appropriate
|
||||
code for the expression and writes the result to this target.
|
||||
\end{description}
|
||||
|
||||
For example, when an instruction selection encounters a
|
||||
\verb|FOR(|$i,a,b,s$\verb|)| statement extension
|
||||
defined in Section~\ref{sec:mltree-extension}, the callback
|
||||
\begin{SML}
|
||||
compileStm reducer \{ stm=FOR(\(i,a,b,s\)), an=an \}
|
||||
\end{SML}
|
||||
\noindent is be involved.
|
||||
|
||||
The \newtype{reducer} type is defined
|
||||
in the signature \mlrischref{mltree/mltree.sig}{MLTREE} and has the
|
||||
following type:
|
||||
\begin{SML}
|
||||
datatype reducer =
|
||||
REDUCER of
|
||||
\{ reduceRexp : rexp -> reg,
|
||||
reduceFexp : fexp -> reg,
|
||||
reduceCCexp : ccexp -> reg,
|
||||
reduceStm : stm * an list -> unit,
|
||||
operand : rexp -> I.operand,
|
||||
reduceOperand : I.operand -> reg,
|
||||
addressOf : rexp -> I.addressing_mode,
|
||||
emit : I.instruction * an list -> unit,
|
||||
instrStream : (I.instruction,C.regmap,C.cellset) stream,
|
||||
mltreeStream : (stm,C.regmap,mlrisc list) stream
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
The components of the reducer are
|
||||
\begin{description}
|
||||
\item[reduceRexp, reduceFexp, reduceCCexp] These functions
|
||||
take an expression of type integer, floating point and condition code,
|
||||
translate them into machine code and return the
|
||||
register that holds the result.
|
||||
\item[reduceStm] This function takes an MLTree statement and translates
|
||||
it into machine code. it also takes a second argument, which is the
|
||||
list of annotations that should be attached to the statement.
|
||||
\item[operand] This function translates an \sml{rexp} into an
|
||||
\sml{operand} of the machine architecture.
|
||||
\item[reduceOperand] This function takes an operand of the machine
|
||||
architecture and reduces it into an integer register.
|
||||
\item[addressOf] This function takes an \sml{rexp}, treats
|
||||
it as an address expression and translates it into the appropriate
|
||||
\sml{addresssing_mode} of the target architecture.
|
||||
\item[emit] This function emits an instruction with attached annotations
|
||||
to the instruction stream
|
||||
\item[instrStream, mltreeStream] These are the instruction stream
|
||||
and mltree streams that are currently bound to the extender.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{Extension Example}
|
||||
Here is an example of how the extender mechanism can be used,
|
||||
using the \sml{DSP_MLTREE} extensions defined in
|
||||
Section~\ref{sec:mltree-extension}. We need supply two
|
||||
new functions, \verb|compileDSPStm| for compiling the \verb|FOR|
|
||||
construct, and \verb|compileDSPRexp| for compiling the \verb|SUM|,
|
||||
and saturated arithmetic instructions.
|
||||
|
||||
The first function, \sml{compileDSPStm}, is generic and simply
|
||||
translates the \verb|FOR| loop into the appropriate branches.
|
||||
Basically, we will translate \verb|FOR(|$i,start,stop,body$\verb|)| into
|
||||
the following loop in pseudo code:
|
||||
\begin{SML}
|
||||
limit = \(stop\)
|
||||
\(i\) = \(start\)
|
||||
goto test
|
||||
loop: \(body\)
|
||||
\(i\) = \(i\) + 1
|
||||
test: if \(i\) <= limit goto loop
|
||||
\end{SML}
|
||||
This transformation can be implemented as follows:
|
||||
\begin{SML}
|
||||
functor DSPMLTreeExtensionComp
|
||||
(structure I : DSP_INSTRUCTION_SET
|
||||
structure T : DSP_MLTREE
|
||||
sharing I.LabelExp = T.LabelExp
|
||||
) =
|
||||
struct
|
||||
structure I = I
|
||||
structure T = T
|
||||
structure C = I.C
|
||||
|
||||
type reducer =
|
||||
(I.instruction,C.regmap,C.cellset,I.operand,I.addressing_mode) T.reducer
|
||||
|
||||
fun mark(s, []) = s
|
||||
| mark(s, a::an) = mark(ANNOTATION(s, a), an)
|
||||
fun compileSext (REDUCER\{reduceStm, ...\})
|
||||
\{stm=FOR(i, start, stop, body), an\} =
|
||||
let val limit = C.newReg()
|
||||
val loop = Label.newLabel ""
|
||||
val test = Label.newLabel ""
|
||||
in reduceStm(
|
||||
SEQ[MV(32, i, start),
|
||||
MV(32, limit, stop),
|
||||
JMP([], [LABEL(LabelExp.LABEL test)], []),
|
||||
LABEL loop,
|
||||
body,
|
||||
MV(32, i, ADD(32, REG(32, i), LI 1),
|
||||
LABEL test,
|
||||
mark(BCC([],
|
||||
CMP(32, LE, REG(32, i), REG(32, limit)),
|
||||
loop),
|
||||
an),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
...
|
||||
\end{SML}
|
||||
In this transformation, we have chosen to proprogate the annotation
|
||||
\verb|an| into the branch constructor.
|
||||
|
||||
Assuming the target architecture that we are translated into contains
|
||||
saturated arithmetic instructions \verb|SADD|, \verb|SSUB|, \verb|SMUL|
|
||||
and \verb|SDIV|, the DSP extensions
|
||||
\verb|SUM| and saturated arithmetic expressions can be handled as follows.
|
||||
\begin{SML}
|
||||
fun compileRext (REDUCER\{reduceStm, reduceRexp, emit, ...\})
|
||||
\{ty, e, rd, an\} =
|
||||
(case (ty,e) of
|
||||
(_,T.SUM(i, a, b, exp)) =>
|
||||
reduceStm(SEQ[MV(ty, rd, LI 0),
|
||||
FOR(i, a, b,
|
||||
mark(MV(ty, rd, ADD(ty, REG(ty, rd), exp)), an))
|
||||
]
|
||||
)
|
||||
| (32,T.SADD(x,y)) => emit(I.SADD\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
|
||||
| (32,T.SSUB(x,y)) => emit(I.SSUB\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
|
||||
| (32,T.SMUL(x,y)) => emit(I.SMUL\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
|
||||
| (32,T.SDIV(x,y)) => emit(I.SDIV\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
|
||||
| ...
|
||||
)
|
||||
|
||||
fun compileFext _ _ = ()
|
||||
fun compileCCext _ _ = ()
|
||||
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
Note that in this example, we have simply chosen to reduce
|
||||
a \verb|SUM| expression into the high level \verb|FOR| construct.
|
||||
Clearly, other translation schemes are possible.
|
||||
|
||||
\subsection{Instruction Selection Modules}
|
||||
Here are the actual code for the various back ends:
|
||||
\begin{enumerate}
|
||||
\item \mlrischref{sparc/mltree/sparc.sml}{Sparc}
|
||||
\item \mlrischref{hppa/mltree/hppa.sml}{PA-RISC}
|
||||
\item \mlrischref{alpha/mltree/alpha.sml}{Alpha}
|
||||
\item \mlrischref{ppc/mltree/ppc.sml}{Power PC}
|
||||
\item \mlrischref{x86/mltree/x86.sml}{X86}
|
||||
\item C6xx
|
||||
\end{enumerate}
|
||||
@@ -0,0 +1,88 @@
|
||||
\section{Instructions}
|
||||
|
||||
Instructions in MLRISC are implemented as abstract datatypes and
|
||||
must satisfy the signature
|
||||
\mlrischref{instructions/instructions.sig}{INSTRUCTIONS}, defined as follows:
|
||||
|
||||
\begin{SML}
|
||||
signature INSTRUCTIONS =
|
||||
sig
|
||||
structure C : \href{cells.html}{CELLS}
|
||||
structure Constant : \href{constants.html}{CONSTANT}
|
||||
structure LabelExp : \href{labelexp.html}{LABELEXP}
|
||||
sharing LabelExp.Constant = Constant
|
||||
|
||||
type operand
|
||||
type ea
|
||||
type addressing_mode
|
||||
type instruction
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
Type \sml{operand} is used to represent ioperands,
|
||||
\sml{ea} is used to represent effective addresses, type
|
||||
\sml{addressing_mode} is used to represent the internal addressing mode
|
||||
used by the architecture. Note that these are all abstract according to
|
||||
the signature, so the client has complete freedom in choosing the most
|
||||
convenient representation for these things.
|
||||
|
||||
\subsection{Predication}
|
||||
For architectures that have full \newdef{predication}
|
||||
built-in, such as the C6xx or IA-64, the instruction set should be
|
||||
extended to satisfy the signature:
|
||||
\begin{SML}
|
||||
signature \mlrischref{instructions/pred-instructions.sig}{PREDICATED_INSTRUCTIONS} =
|
||||
sig
|
||||
include INSTRUCTIONS
|
||||
|
||||
type predicate
|
||||
end
|
||||
\end{SML}
|
||||
This basically says that the type that is used to represent a predicate
|
||||
can be implemented however the client wants. This flexibility
|
||||
is quite important since the predication model may differ substantially
|
||||
from architecture to architecture.
|
||||
|
||||
For example, in the TI C6, there are no seperate predicate register files
|
||||
and integer registers double as predicate registers, and the predicate
|
||||
true is any non-zero value. Each instruction can be predicated under a
|
||||
predicate register or its negation. In contrasts, architectures such as
|
||||
IA-64 and HP's Playdoh incorporate separate predicate registers into their
|
||||
architectures. In Playdoh, \newdef{predicate defining} instructions
|
||||
actually set a pair of complementary predicate registers,
|
||||
and instructions can only
|
||||
be predicated under the value of a predicate register, not its negation.
|
||||
|
||||
\subsection{VLIW}
|
||||
VLIW architectures differ from superscalars in that
|
||||
resource assignments are statically determined at compile time.
|
||||
We distinguish between two different types of resources, namely
|
||||
\newdef{functional units} and \newdef{data paths}.
|
||||
The latter type is particularly
|
||||
important for clustered architectures.
|
||||
The following signature
|
||||
is used to describe VLIW instructions:
|
||||
\begin{SML}
|
||||
signature \mlrischref{instructions/vliw-instructions.sig}{VLIW\_INSTRUCTIONS} =
|
||||
sig
|
||||
|
||||
include INSTRUCTIONS
|
||||
structure FU : \mlrischref{instructions/funits.sig}{FUNITS}
|
||||
structure DP : \mlrischref{instructions/datapaths.sig}{DATAPATHS}
|
||||
end
|
||||
\end{SML}
|
||||
The signature \sml{FUNITS} is used to describe functional unit
|
||||
resources, while the signature \sml{DATAPATHS} is used to describe
|
||||
data paths.
|
||||
|
||||
\subsection{Predicated VLIW}
|
||||
|
||||
Finally, instructions sets for predicated VLIW/EPIC machines should match
|
||||
the signature
|
||||
\begin{SML}
|
||||
signature \mlrischref{instructions/pred-vliw-instructions.sig}{PREDICATED_VLIW_INSTRUCTIONS} =
|
||||
sig
|
||||
include VLIW_INSTRUCTIONS
|
||||
type predicate
|
||||
end
|
||||
\end{SML}
|
||||
@@ -0,0 +1,40 @@
|
||||
\section{Label Expressions}
|
||||
|
||||
A \newdef{label expression} is a constant
|
||||
expression defined in terms of labels, or user
|
||||
defined \href{constants.html}{constants}. MLRISC uses the type
|
||||
\sml{labexp} to represent label expressions. Label expressions
|
||||
are defined in the structure
|
||||
\mlrischref{instructions/labelExp.sml}{LabelExp}.
|
||||
|
||||
The datatype \sml{labexp} has the following definition:
|
||||
\begin{SML}
|
||||
datatype labexp =
|
||||
LABEL of Label.label
|
||||
| CONST of Constant.const
|
||||
| INT of int
|
||||
| PLUS of labexp * labexp
|
||||
| MINUS of labexp * labexp
|
||||
| MULT of labexp * labexp
|
||||
| DIV of labexp * labexp
|
||||
| LSHIFT of labexp * word
|
||||
| RSHIFT of labexp * word
|
||||
| AND of labexp * word
|
||||
| OR of labexp * word
|
||||
\end{SML}
|
||||
|
||||
In addition, the following functions are defined in \sml{labexp}:
|
||||
\begin{itemize}
|
||||
\item \sml{valueOf : labexp -> int} -- Returns the value associated with
|
||||
a label expression
|
||||
\item \sml{toString : labexp -> string} -- Return the pretty printed representation of an expression
|
||||
\item \sml{hash : labexp -> word} -- Returns the hash value of an expression
|
||||
\item \sml{== : labexp * labexp -> bool} -- Tests whether two label expression are lexically identical
|
||||
\end{itemize}
|
||||
|
||||
The type \sml{labexp} is depends on client defined
|
||||
\href{constants.html}{constants} typed. The functor \sml{LabelExp}
|
||||
is parameterized as follows.
|
||||
\begin{SML}
|
||||
functor \mlrischref{instructions/labelExp.sml}{LabelExp}(Constant : \mlrischref{instructions/constant.sig}{CONSTANT})
|
||||
\end{SML}
|
||||
@@ -0,0 +1,25 @@
|
||||
\section{Labels}
|
||||
|
||||
\newdef{Labels} are used as symbolic names for address.
|
||||
The structure \mlrischref{instructions/labels.sml}{Label}
|
||||
defines the label datatype. The following operations are defined
|
||||
on labels:
|
||||
\begin{itemize}
|
||||
\item \sml{newLabel : string -> label} -- Generate a new label with
|
||||
a given name. If the name is \sml{""}, a new name is generated.
|
||||
\item \sml{nameOf : label -> string} -- Returns the name of
|
||||
a label
|
||||
\item \sml{id : label -> int} -- Return the unique id of a label
|
||||
\item \sml{reset : unit -> unit} -- Return the label id counter to 0.
|
||||
\end{itemize}
|
||||
|
||||
For machine code generation, the following two additional methods are
|
||||
defined.
|
||||
\begin{itemize}
|
||||
\item \sml{addrOf : label -> int} -- Return the address associated with
|
||||
a label
|
||||
\item \sml{setAddr : label * int -> unit} -- Set the address associated
|
||||
with a label
|
||||
\end{itemize}
|
||||
|
||||
See also \href{labelexp.html}{Label Expressions}.
|
||||
@@ -0,0 +1,40 @@
|
||||
\section{Line Counts}
|
||||
|
||||
\begin{Table}{|l|r|r|}{align=right} \hline
|
||||
& SML/NJ & MLRISC \\ \hline
|
||||
\begin{color}{#00aa00}Generic\end{color} & 3,023 & 6,814 \\
|
||||
\begin{color}{#00aa00}Hppa\end{color} & 725 & 2,285 \\
|
||||
\begin{color}{#00aa00}Alpha\end{color} & 614 & 2,316 \\ \hline
|
||||
TOTAL & 4,362 & 11,415 \\ \hline
|
||||
\end{Table}
|
||||
The table shows the number of lines involved in a basic MLRISC code
|
||||
generator for SML/NJ that only does graph coloring register
|
||||
allocation. The SML/NJ column shows the number of lines specific to
|
||||
SML/N and the MLRISC column shows the number of lines specific to
|
||||
MLRISC. The \begin{color}{#00aa00}Generic\end{color} shows the
|
||||
number of lines that are target independent for both SML/NJ and
|
||||
MLRISC. The \begin{color}{#00aa00}Hppa\end{color} and
|
||||
\begin{color}{#00aa00}Alpha\end{color} shows the number of lines that are
|
||||
target dependent for both the HP Hppa and DEC Alpha targets.
|
||||
|
||||
The bulk of the \sml{3,023} generic to SML/NJ is involved in the
|
||||
generation of MLRisc trees. Once this is done the incremental cost
|
||||
of adding a target is between \sml{600} to \sml{700} lines.
|
||||
|
||||
The MLRISC column shows that the bulk of MLRISC is quite generic and
|
||||
a client is saved from writing \sml{11,415} lines of code.
|
||||
|
||||
\begin{Table}{|l|r|r|}{align=left} \hline
|
||||
& SML/NJ & MLRISC \\ \hline
|
||||
\begin{color}{#00aa00}Generic\end{color} & 121 + 3,023 & 15,686 + 6,814\\
|
||||
\begin{color}{#00aa00}Hppa\end{color} & 32 + 725 & 920 + 2,285 \\
|
||||
\begin{color}{#00aa00}Alpha\end{color} & 614 & 2,316 \\ \hline
|
||||
TOTAL & 153 + 4,362 & 16,606 + 11,415 \\ \hline
|
||||
\end{Table}
|
||||
If one were to include the preliminary numbers for global acyclic
|
||||
scheduling in the above table, we find that the incremental cost
|
||||
required by the client is quite small -- approximately \sml{153}
|
||||
lines of which \sml{121} are generic. However, the scheduling
|
||||
infra structure is quite large, a lot of it being quite generic.
|
||||
|
||||
\br{left=clear}
|
||||
@@ -0,0 +1,53 @@
|
||||
\section{Machine Code Emitters}
|
||||
|
||||
\subsubsection{Overview}
|
||||
MLRISC lets the client to directly emit machine code and bypass the traditional
|
||||
assembly mechanism.
|
||||
|
||||
Machine code emitters in MLRISC satisfy the signature
|
||||
\mlrischref{emit/instruction-emitter.sig}{INSTRUCTION\_EMITTER},
|
||||
which is defined as:
|
||||
\begin{SML}
|
||||
signature INSTRUCTION_EMITTER =
|
||||
sig
|
||||
|
||||
structure I : \href{instructions.html}{INSTRUCTIONS}
|
||||
structure C : \href{cells.html}{CELLS}
|
||||
structure S : \href{streams.html}{INSTRUCTION_STREAM}
|
||||
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
|
||||
sharing I.C = C
|
||||
sharing S.P = P
|
||||
|
||||
val makeStream : Annotations.annotations ->
|
||||
((int -> int) -> I.instruction -> unit,
|
||||
unit,'b,'c,'d,'e) S.stream
|
||||
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The function \sml{makeStream} returns an instruction stream.
|
||||
The output, a stream of bytes, is direct to the client supplied
|
||||
structure which satisfy the
|
||||
\mlrischref{emit/code-string.sig}{CODE\_STRING} interface.
|
||||
This signature is defined as follows:
|
||||
\begin{SML}
|
||||
signature CODE_STRING = sig
|
||||
type code_string
|
||||
val init : int -> unit
|
||||
val update : int * Word8.word -> unit
|
||||
val getCodeString : unit -> code_string
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{More Details}
|
||||
|
||||
Machine code emitters are automatically generated by the
|
||||
\href{mlrisc-md.html}{MDGen} tool. Some specific generated
|
||||
emitters are listed below:
|
||||
\begin{enumerate}
|
||||
\item \mlrischref{sparc/emit/sparcMC.sml}{Sparc}
|
||||
\item \mlrischref{hppa/emit/hppaMC.sml}{Hppa}
|
||||
\item \mlrischref{alpha/emit/alphaMC.sml}{Alpha}
|
||||
\item \mlrischref{ppc/emit/ppcMC.sml}{Power PC}
|
||||
\item \mlrischref{x86/emit/x86MC.sml}{X86}
|
||||
\end{enumerate}
|
||||
@@ -0,0 +1,444 @@
|
||||
\section{The MLRISC Machine Description Language}
|
||||
|
||||
\subsection{ Overview }
|
||||
|
||||
\newdef{MDGen} is a machine description language
|
||||
is designed to automate
|
||||
various mundane and error prone tasks in developing a back-end for
|
||||
MLRISC. Currently, to target a new
|
||||
architecture the programmer must provide the following set of modules
|
||||
written in Standard ML:
|
||||
|
||||
\begin{itemize}
|
||||
\item \codehref{instructions/cells.sig}{CELLS} --
|
||||
the properties of the register set and (some part of) memory hierarchy.
|
||||
\item \codehref{instructions/instructions.sig}{INSTRUCTIONS} --
|
||||
the concrete instruction set representation.
|
||||
\item \codehref{instructions/insnProps.sig}{INSNS_PROPERTIES} --
|
||||
properties of the instructions.
|
||||
\item \codehref{instructions/shuffle.sig}{SHUFFLE} --
|
||||
methods to emit linearized code from parallel copies.
|
||||
\item \codehref{emit/instruction-emitter.sig}{ASSEMBLER} --
|
||||
the assembler
|
||||
\item \codehref{emit/instruction-emitter.sig}{MC} --
|
||||
the machine code emitter
|
||||
\item \codehref{../backpatch/sdi-jumps.sig}{ SDI_JUMPS } --
|
||||
methods for resolving span-dependent instructions.
|
||||
\item <a href="../backpatch/delaySlotProps.sig" target=code> DELAY_SLOTS_PROPERTIES
|
||||
</a> -- machine properties for delay slot filling, if a machine
|
||||
architecture contains branch delay slots or load delay slots.
|
||||
\item \codehref{../SSA/ssaProps.sig}{ SSA_PROPERTIES } --
|
||||
semantics properties for performing optimizations in Static Single
|
||||
Assignment form.
|
||||
\end{itemize}
|
||||
|
||||
In general, writing a backend is tedious even with
|
||||
SML's abstraction capabilities.
|
||||
Furthermore, the machine description is procedural in natural
|
||||
and must be checked by hand.
|
||||
|
||||
\subsection{ What is in MDGen? }
|
||||
The MDGen tool simplifies the process of developing a new MLRISC backend.
|
||||
MDGen provides the following:
|
||||
\begin{itemize}
|
||||
\item A representation description language for specifying the
|
||||
machine encoding of the instruction set,
|
||||
using an extension of ML's algebraic datatype facility.
|
||||
\item A semantics description language for specifying the abstract semantics
|
||||
of the instructions.
|
||||
\end{itemize}
|
||||
|
||||
Both sub-languages are based on ML's syntax and semantics, so
|
||||
they should be readily familiar to all MLRISC users.
|
||||
|
||||
A backend developer can specify a new machine architecture using the MDGen
|
||||
language, and in turn, the MDGen tool generates ML modules that are
|
||||
required by the MLRISC system.
|
||||
|
||||
The basic concepts of MDGen are inspired largely from
|
||||
Norman Ramsey's <a href="www.cs.virginia.edu/~nr/toolkit">
|
||||
New Jersey Machine Code Tool Kit </a> and
|
||||
Ramsey and Davidson's
|
||||
<a href="http://www.cs.virginia.edu/zephyr/csdl/lrtlindex.html">
|
||||
Lambda RTL </a>
|
||||
|
||||
\subsection{A Sample Description}
|
||||
|
||||
Here we present a sample MDGen description, using the Alpha as an example.
|
||||
We highlight all keywords in the MDGen language
|
||||
in. A typical machine description
|
||||
is structured as follows:
|
||||
|
||||
\begin{SML}
|
||||
architecture Alpha =
|
||||
struct
|
||||
|
||||
name "Alpha"
|
||||
|
||||
superscalar
|
||||
|
||||
little endian
|
||||
|
||||
<font color=#FF0000>lowercase assembly</font>
|
||||
|
||||
\href{#cells}{Storage cells and locations}
|
||||
\href{#encoding}{Instruction encoding formats specification}
|
||||
\href{#instruction}{Instruction definition}
|
||||
<font color=#FF0000>end</font>
|
||||
\end{SML}
|
||||
|
||||
Here, we declare that the Alpha is a superscalar machine using
|
||||
little endian encoding. Furthermore, assembly output should be displayed
|
||||
in lowercase-- this is for personal esthetic reasons only; most assemblers
|
||||
are case insensitive.
|
||||
|
||||
|
||||
|
||||
\subsubsection{ <a name="cells">Specifying Storage Cells and Locations </a>}
|
||||
|
||||
A <font color="#ff0000">cell</font> is an abstract resource location
|
||||
for holding data values. On typical machines, the types of
|
||||
cells include general purpose registers, floating point registers,
|
||||
and condition code registers.
|
||||
|
||||
The \sml{storage} declaration defines different
|
||||
<font color="#ff0000">cellkinds</font>. MLRISC requires the
|
||||
cellkinds \sml{GP}, \sml{FP}, \sml{CC} to be defined.
|
||||
These are the cellkinds for general purpose registers, floating point
|
||||
registers and condition code registers.
|
||||
|
||||
In the following sequence of declarations, a few things are defined:
|
||||
\begin{itemize}
|
||||
\item The cellkinds \sml{GP, FP, CC} are defined.
|
||||
Furthermore, the cellkinds \sml{MEM, CTRL}, which stand
|
||||
for memory and control (dependence), are also implicitly defined.
|
||||
\item The \sml{assembly as} clauses specify how a specific cell type is
|
||||
to be displayed. Here, we specify that register 30, the
|
||||
stack pointer, should be displayed specially as \sml{$sp}.
|
||||
\item The \sml{in cellset} clause, when attached, tells MDGen that
|
||||
the associated cellkind should be part of the
|
||||
\href{cellset.html}{ cellset }. The clause \sml{in cellset GP}
|
||||
tells MDGen that the a cell of type \sml{CC} should be treated
|
||||
the same as a \sml{GP}
|
||||
\item The \sml{locations} declarations define a few abbreviations:
|
||||
\sml{stackptrR} is the stack pointer, \sml{asmTmpR} is
|
||||
the assembly temporary, \sml{fasmTmp} is the floating point
|
||||
assembly temporary etc.
|
||||
\end{itemize}
|
||||
|
||||
<tt>
|
||||
\begin{SML}
|
||||
<font color=#FF0000>storage</font>
|
||||
GP = 32 <font color=#FF0000>cells <font color=#FF0000>of</font> 64 bits in cellset called</font> "register"
|
||||
<font color=#FF0000>assembly as</font> (fn 30 => "$sp"
|
||||
| r => "$"^Int.toString r)
|
||||
| FP = 32 <font color=#FF0000>cells <font color=#FF0000>of</font> 64 bits in cellset called</font> "floating point register"
|
||||
<font color=#FF0000>assembly as</font> (fn f => "f"^Int.toString f)
|
||||
| CC = <font color=#FF0000>cells <font color=#FF0000>of</font> 64 bits in cellset GP called</font> "condition code register"
|
||||
<font color=#FF0000>assembly as</font> "cc"
|
||||
<font color=#FF0000>locations</font>
|
||||
stackptrR = <font color=#008800>$</font>GP[30]
|
||||
<font color=#FF0000>and</font> asmTmpR = <font color=#008800>$</font>GP[28]
|
||||
<font color=#FF0000>and</font> fasmTmp = <font color=#008800>$</font>FP[30]
|
||||
<font color=#FF0000>and</font> GPReg r = <font color=#008800>$</font>GP[r]
|
||||
<font color=#FF0000>and</font> FPReg f = <font color=#008800>$</font>GP[f]
|
||||
\end{SML}
|
||||
|
||||
<h3> <a name="instruction">
|
||||
Specifying the Representation of Instructions</a></h3>
|
||||
\begin{SML}
|
||||
<font color=#FF0000>structure</font> Instruction =
|
||||
<font color=#FF0000>struct</font>
|
||||
<font color=#FF0000>datatype</font> ea =
|
||||
Direct <font color=#FF0000>of</font> <font color=#008800>$</font>GP
|
||||
| FDirect <font color=#FF0000>of</font> <font color=#008800>$</font>FP
|
||||
| Displace <font color=#FF0000>of</font> {base: <font color=#008800>$</font>GP, disp:int}
|
||||
|
||||
<font color=#FF0000>datatype</font> operand =
|
||||
REGop <font color=#FF0000>of</font> <font color=#008800>$</font>GP ``<GP>'' (GP)
|
||||
| IMMop <font color=#FF0000>of</font> int ``<int>''
|
||||
| HILABop <font color=#FF0000>of</font> LabelExp.labexp ``hi(<emit_labexp labexp>)''
|
||||
| LOLABop <font color=#FF0000>of</font> LabelExp.labexp ``lo(<emit_labexp labexp>)''
|
||||
| LABop <font color=#FF0000>of</font> LabelExp.labexp ``<emit_labexp labexp>''
|
||||
| CONSTop <font color=#FF0000>of</font> Constant.const ``<emit_const const>''
|
||||
|
||||
(*
|
||||
* When I say ! after the datatype</font> name XXX, it means generate a
|
||||
* function emit_XXX that converts the constructors into the corresponding
|
||||
* assembly text. By default, it uses the same name as the constructor,
|
||||
* but may be modified by the lowercase/uppercase assembly directive.
|
||||
*
|
||||
*)
|
||||
<font color=#FF0000>datatype</font> branch! =
|
||||
BR 0x30
|
||||
| BSR 0x34
|
||||
| BLBC 0x3
|
||||
| BEQ 0x39 | BLT 0x3a | BLE 0x3b
|
||||
| BLBS 0x3c | BNE 0x3d | BGE 0x3e
|
||||
| BGT 0x3f
|
||||
|
||||
<font color=#FF0000>datatype</font> fbranch! =
|
||||
FBEQ 0x31 | FBLT 0x32
|
||||
| FBLE 0x33 | FBNE 0x35
|
||||
| FBGE 0x36 | FBGT 0x37
|
||||
|
||||
<font color=#FF0000>datatype</font> load! = LDL 0x28 | LDL_L 0x2A | LDQ 0x29 | LDQ_L 0x2B | LDQ_U 0x0B
|
||||
<font color=#FF0000>datatype</font> store! = STL 0x2C | STQ 0x2D | STQ_U 0x0F
|
||||
<font color=#FF0000>datatype</font> fload[0x20..0x23]! = LDF | LDG | LDS | LDT
|
||||
<font color=#FF0000>datatype</font> fstore[0x24..0x27]! = STF | STG | STS | STT
|
||||
|
||||
(* non-trapping opcodes *)
|
||||
<font color=#FF0000>datatype</font> operate! = (* table C-5 *)
|
||||
ADDL (0wx10,0wx00) | ADDQ (0wx10,0wx20)
|
||||
| CMPBGE(0wx10,0wx0f) | CMPEQ (0wx10,0wx2d)
|
||||
| CMPLE (0wx10,0wx6d) | CMPLT (0wx10,0wx4d) | CMPULE (0wx10,0wx3d)
|
||||
| CMPULT(0wx10,0wx1d) | SUBL (0wx10,0wx09)
|
||||
| SUBQ (0wx10,0wx29)
|
||||
| S4ADDL(0wx10,0wx02) | S4ADDQ (0wx10,0wx22) | S4SUBL (0wx10,0wx0b)
|
||||
| S4SUBQ(0wx10,0wx2b) | S8ADDL (0wx10,0wx12) | S8ADDQ (0wx10,0wx32)
|
||||
| S8SUBL(0wx10,0wx1b) | S8SUBQ (0wx10,0wx3b)
|
||||
|
||||
| AND (0wx11,0wx00) | BIC (0wx11,0wx08) | BIS (0wx11,0wx20)
|
||||
| CMOVEQ(0wx11,0wx24) | CMOVLBC(0wx11,0wx16) | CMOVLBS(0wx11,0wx14)
|
||||
| CMOVGE(0wx11,0wx46) | CMOVGT (0wx11,0wx66) | CMOVLE (0wx11,0wx64)
|
||||
| CMOVLT(0wx11,0wx44) | CMOVNE (0wx11,0wx26) | EQV (0wx11,0wx48)
|
||||
| ORNOT (0wx11,0wx28) | XOR (0wx11,0wx40)
|
||||
|
||||
| EXTBL (0wx12,0wx06) | EXTLH (0wx12,0wx6a) | EXTLL(0wx12,0wx26)
|
||||
| EXTQH (0wx12,0wx7a) | EXTQL (0wx12,0wx36) | EXTWH(0wx12,0wx5a)
|
||||
| EXTWL (0wx12,0wx16) | INSBL (0wx12,0wx0b) | INSLH(0wx12,0wx67)
|
||||
| INSLL (0wx12,0wx2b) | INSQH (0wx12,0wx77) | INSQL(0wx12,0wx3b)
|
||||
| INSWH (0wx12,0wx57) | INSWL (0wx12,0wx1b) | MSKBL(0wx12,0wx02)
|
||||
| MSKLH (0wx12,0wx62) | MSKLL (0wx12,0wx22) | MSKQH(0wx12,0wx72)
|
||||
| MSKQL (0wx12,0wx32) | MSKWH (0wx12,0wx52) | MSKWL(0wx12,0wx12)
|
||||
| SLL (0wx12,0wx39) | SRA (0wx12,0wx3c) | SRL (0wx12,0wx34)
|
||||
| ZAP (0wx12,0wx30) | ZAPNOT (0wx12,0wx31)
|
||||
| MULL (0wx13,0wx00) | MULQ (0wx13,0wx20)
|
||||
| UMULH (0wx13,0wx30)
|
||||
| SGNXL "addl" (0wx10,0wx00) (* same as ADDL *)
|
||||
|
||||
(* conditional moves *)
|
||||
|
||||
<font color=#FF0000>datatype</font> pseudo_op! = DIVL | DIVLU
|
||||
|
||||
<font color=#FF0000>datatype</font> operateV! = (* table C-5 opc/func *)
|
||||
ADDLV (0wx10,0wx40) | ADDQV (0wx10,0wx60)
|
||||
| SUBLV (0wx10,0wx49) | SUBQV (0wx10,0wx69)
|
||||
| MULLV (0wx13,0wx00) | MULQV (0wx13,0wx60)
|
||||
|
||||
<font color=#FF0000>datatype</font> foperate! = (* table C-6 *)
|
||||
CPYS (0wx17,0wx20) | CPYSE (0wx17,0wx022) | CPYSN (0wx17,0wx021)
|
||||
| CVTLQ (0wx17,0wx010) | CVTQL (0wx17,0wx030) | CVTQLSV (0wx17,0wx530)
|
||||
| CVTQLV (0wx17,0wx130)
|
||||
| FCMOVEQ (0wx17,0wx02a) | FCMOVEGE (0wx17,0wx02d) | FCMOVEGT (0wx17,0wx02f)
|
||||
| FCMOVLE (0wx17,0wx02e) | FCMOVELT (0wx17,0wx02c) | FCMOVENE (0wx17,0wx02b)
|
||||
| MF_FPCR (0wx17,0wx025) | MT_FPCR (0wx17,0wx024)
|
||||
|
||||
(* table C-7 *)
|
||||
| CMPTEQ (0wx16,0wx0a5) | CMPTLT (0wx16,0wx0a6) | CMPTLE (0wx16,0wx0a7)
|
||||
| CMPTUN (0wx16,0wx0a4)
|
||||
|
||||
<font color=#FF0000>datatype</font> foperateV! =
|
||||
ADDSSUD 0wx5c0
|
||||
| ADDTSUD 0wx5e0
|
||||
| CVTQSC 0wx3c
|
||||
| CVTQTC 0wx3e
|
||||
| CVTTSC 0wx2c
|
||||
| CVTTQC 0wx2f
|
||||
| DIVSSUD 0wx5ec
|
||||
| DIVTSUD 0wx5c3
|
||||
| MULSSUD 0wx5c2
|
||||
| MULTSUD 0wx5e2
|
||||
| SUBSSUD 0wx5c1
|
||||
| SUBTSUD 0wx5e1
|
||||
|
||||
<font color=#FF0000>datatype</font> osf_user_palcode! =
|
||||
BPT 0x80 | BUGCHK 0x81 | CALLSYS 0x83
|
||||
| GENTRAP 0xaa | IMB 0x86 | RDUNIQUE 0x9e | WRUNIQUE 0x9f
|
||||
|
||||
end (* Instruction *)
|
||||
\end{SML}
|
||||
|
||||
<h3> <a name="encoding">
|
||||
Specifying the Instruction Encoding Formats </a></h3>
|
||||
|
||||
The Alpha has very simple instruction encoding formats.
|
||||
|
||||
<tt>
|
||||
\begin{SML}
|
||||
<font color=#FF0000>instruction formats 32 bits</font>
|
||||
Memory{opc:6, ra:5, rb:GP 5, disp: signed 16} (* p3-9 *)
|
||||
(* derived from Memory *)
|
||||
| LoadStore{opc,ra,rb,disp} =
|
||||
<font color=#FF00000>let val</font> disp =
|
||||
<font color=#FF00000>case</font> disp <font color=#FF0000>of</font>
|
||||
I.REGop rb => emit_GP rb
|
||||
| I.IMMop i => itow i
|
||||
| I.HILABop le => itow(LabelExp.valueOf le)
|
||||
| I.LOLABop le => itow(LabelExp.valueOf le)
|
||||
| I.LABop le => itow(LabelExp.valueOf le)
|
||||
| I.CONSTop c => itow(Constant.valueOf c)
|
||||
in Memory{opc,ra,rb,disp}
|
||||
end
|
||||
| ILoadStore{opc,r:GP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d}
|
||||
| FLoadStore{opc,r:FP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d}
|
||||
|
||||
| Jump{opc:6,ra:GP 5,rb:GP 5,h:2,disp:int signed 14} (* table C-3 *)
|
||||
| Memory_fun{opc:6, ra:GP 5, rb:GP 5, func:16} (* p3-9 *)
|
||||
| Branch{opc:branch 6, ra:GP 5, disp:signed 21} (* p3-10 *)
|
||||
| Fbranch{opc:fbranch 6, ra:FP 5, disp:signed 21} (* p3-10 *)
|
||||
(* p3-11 *)
|
||||
| Operate0{opc:6,ra:GP 5,rb:GP 5,sbz:13..15,_:1=0,func:5..11,rc:GP 5}
|
||||
(* p3-11 *)
|
||||
| Operate1{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5}
|
||||
| Operate{opc,ra,rb,func,rc} =
|
||||
(<font color=#FF00000>case</font> rb <font color=#FF0000>of</font>
|
||||
I.REGop rb => Operate0{opc,ra,rb,func,rc,sbz=0w0}
|
||||
| I.IMMop i => Operate1{opc,ra,lit=itow i,func,rc}
|
||||
| I.HILABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc}
|
||||
| I.LOLABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc}
|
||||
| I.LABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc}
|
||||
| I.CONSTop c => Operate1{opc,ra,lit=itow(Constant.valueOf c),func,rc}
|
||||
)
|
||||
| Foperate{opc:6,fa:FP 5,fb:FP 5,func:5..15,fc:FP 5}
|
||||
| Pal{opc:6=0,func:26}
|
||||
\end{SML}
|
||||
</tt>
|
||||
|
||||
\subsubsection{ Specifying the instruction set }
|
||||
<tt>
|
||||
\begin{SML}
|
||||
<font color=#FF0000>structure</font> MC =
|
||||
<font color=#FF0000>struct</font>
|
||||
(* compute displacement address *)
|
||||
<font color=#FF0000>fun</font> disp lab = itow(Label.addrOf lab - !loc - 4) ~>> 0w2
|
||||
<font color=#FF0000>end</font>
|
||||
|
||||
(*
|
||||
* The main instruction set definition consists <font color=#FF0000>of</font> the following:
|
||||
* 1) constructor-like declaration defines the view <font color=#FF0000>of</font> the instruction,
|
||||
* 2) assembly directive in funny quotes `` '',
|
||||
* 3) machine encoding expression,
|
||||
* 4) semantics expression in [[ ]],
|
||||
* 5) delay slot directives etc (not necessary in this architecture!)
|
||||
*)
|
||||
<font color=#FF0000>instruction</font>
|
||||
DEFFREG <font color=#FF0000>of</font> <font color=#008800>$</font>FP (* define a floating point register *)
|
||||
``deffreg <FP>''
|
||||
(* Pseudo instruction for the register allocator *)
|
||||
|
||||
(* Load/Store *)
|
||||
| LDA <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand} (* use of REGop is illegal *)
|
||||
``lda\t<r>, <d>()''
|
||||
ILoadStore{opc=0w08,r,b,d}
|
||||
|
||||
| LDAH <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand} (* use of REGop is illegal *)
|
||||
``ldah\t<r>, <d>()''
|
||||
ILoadStore{opc=0w09,r,b,d}
|
||||
|
||||
| LOAD <font color=#FF0000>of</font> {ldOp:load, r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
|
||||
``<ldOp>\t<r>, <d>()''
|
||||
ILoadStore{opc=emit_load ldOp,r,b,d}
|
||||
|
||||
| STORE <font color=#FF0000>of</font> {stOp:store, r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
|
||||
``<stOp>\t<r>, <d>()''
|
||||
ILoadStore{opc=emit_store stOp,r,b,d}
|
||||
|
||||
| FLOAD <font color=#FF0000>of</font> {ldOp:fload, r: <font color=#008800>$</font>FP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
|
||||
``<ldOp>\t<r>, <d>()''
|
||||
FLoadStore{opc=emit_fload ldOp,r,b,d}
|
||||
|
||||
| FSTORE <font color=#FF0000>of</font> {stOp:fstore, r: <font color=#008800>$</font>FP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
|
||||
``<stOp>\t<r>, <d>()''
|
||||
FLoadStore{opc=emit_fstore stOp,r,b,d}
|
||||
|
||||
(* Control Instructions *)
|
||||
| JMPL <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:int} * Label.label list
|
||||
``jmpl\t<r>, <d>()''
|
||||
Jump{opc=0wx1a,h=0w0,ra=r,rb=b,disp=d} (* table C-3 *)
|
||||
|
||||
| JSR <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:int} * C.cellset * C.cellset
|
||||
``jsr\t<r>, <d>()''
|
||||
Jump{opc=0wx1a,h=0w1,ra=r,rb=b,disp=d}
|
||||
|
||||
| RET <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:int}
|
||||
``ret\t<r>, <d>()''
|
||||
Jump{opc=0wx1a,h=0w2,ra=r,rb=b,disp=d}
|
||||
|
||||
| BRANCH <font color=#FF0000>of</font> branch * <font color=#008800>$</font>GP * Label.label
|
||||
``<branch> <GP>, <label>''
|
||||
Branch{opc=branch,ra=GP,disp=disp label}
|
||||
|
||||
| FBRANCH <font color=#FF0000>of</font> fbranch * <font color=#008800>$</font>FP * Label.label
|
||||
``<fbranch> <FP>, <label>''
|
||||
Fbranch{opc=fbranch,ra=FP,disp=disp label}
|
||||
|
||||
(* Integer Operate *)
|
||||
| OPERATE <font color=#FF0000>of</font> {oper:operate, ra: <font color=#008800>$</font>GP, rb:operand, rc: <font color=#008800>$</font>GP}
|
||||
``<oper>\t<ra>, <rb>, <rc>''
|
||||
(let val (opc,func) = emit_operate oper
|
||||
in Operate{opc,func,ra,rb,rc}
|
||||
end)
|
||||
|
||||
| OPERATEV <font color=#FF0000>of</font> {oper:operateV, ra: <font color=#008800>$</font>GP, rb:operand, rc: <font color=#008800>$</font>GP}
|
||||
``<oper>\t<ra>, <rb>, <rc>''
|
||||
(let val (opc,func) = emit_operateV oper
|
||||
in Operate{opc,func,ra,rb,rc}
|
||||
end)
|
||||
|
||||
| PSEUDOARITH <font color=#FF0000>of</font> {oper: pseudo_op, ra: <font color=#008800>$</font>GP, rb:operand, rc: <font color=#008800>$</font>GP,
|
||||
tmps: C.cellset}
|
||||
``<oper>\t<ra>, <rb>, <rc>''
|
||||
|
||||
(* Copy instructions *)
|
||||
| COPY <font color=#FF0000>of</font> {dst: <font color=#008800>$</font>GP list, src: <font color=#008800>$</font>GP list,
|
||||
impl:instruction list option ref, tmp: ea option}
|
||||
``<app emitInstr (Shuffle.shuffle{regmap,tmp,dst,src})>''
|
||||
| FCOPY <font color=#FF0000>of</font> {dst: <font color=#008800>$</font>FP list, src: <font color=#008800>$</font>FP list,
|
||||
impl:instruction list option ref, tmp: ea option}
|
||||
``<app emitInstr (Shuffle.shufflefp{regmap,tmp,dst,src})>''
|
||||
|
||||
(* Floating Point Operate *)
|
||||
| FOPERATE <font color=#FF0000>of</font> {oper:foperate, fa: <font color=#008800>$</font>FP, fb: <font color=#008800>$</font>FP, fc: <font color=#008800>$</font>FP}
|
||||
``<oper>\t<fa>, <fb>, <fc>''
|
||||
(let val (opc,func) = emit_foperate oper
|
||||
in Foperate{opc,func,fa,fb,fc}
|
||||
end)
|
||||
|
||||
(* Trapping versions <font color=#FF0000>of</font> the above *)
|
||||
| FOPERATEV <font color=#FF0000>of</font> {oper:foperateV, fa: <font color=#008800>$</font>FP, fb: <font color=#008800>$</font>FP, fc: <font color=#008800>$</font>FP}
|
||||
``<oper>\t<fa>, <fb>, <fc>''
|
||||
Foperate{opc=0wx16,func=emit_foperateV oper,fa,fb,fc}
|
||||
|
||||
(* Misc *)
|
||||
| TRAPB (* Trap barrier *)
|
||||
``trapb''
|
||||
Memory_fun{opc=0wx18,ra=31,rb=31,func=0wx0}
|
||||
|
||||
| CALL_PAL <font color=#FF0000>of</font> {code:osf_user_palcode, def: <font color=#008800>$</font>GP list, use: <font color=#008800>$</font>GP list}
|
||||
``call_pal <code>''
|
||||
Pal{func=emit_osf_user_palcode code}
|
||||
end
|
||||
\end{SML}
|
||||
</tt>
|
||||
|
||||
|
||||
\subsection{ 4 Machine Descriptions }
|
||||
Here are some machine descriptions in varing degree of completion.
|
||||
|
||||
\begin{itemize}
|
||||
\item \codehref{../sparc/sparc.mdl}{ Sparc }
|
||||
\item \codehref{../hppa/hppa.mdl}{ Hppa }
|
||||
\item \codehref{../alpha/alpha.mdl}{ Alpha }
|
||||
\item \codehref{../ppc/ppc.mdl}{ PowerPC }
|
||||
\item \codehref{../x86/x86.mdl}{ X86 }
|
||||
\end{itemize}
|
||||
|
||||
\subsection{ Syntax Highlighting Macros }
|
||||
|
||||
\begin{itemize}
|
||||
\item \href{md.vim}{ For vim 5.3 }
|
||||
\end{itemize}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
\section{The MIPS Back End}
|
||||
|
||||
No documentation yet.
|
||||
@@ -0,0 +1,115 @@
|
||||
\section{Architecture of MLRISC}
|
||||
|
||||
\subsection{Core Components}
|
||||
|
||||
The core components of MLRISC allow the client to quickly construct
|
||||
an backend for various architectures. These components include:
|
||||
\begin{itemize}
|
||||
\item The \href{mltree.html}{MLTREE} language,
|
||||
which is a RTL-like intermediate language
|
||||
that is used by the client
|
||||
to communicate to the MLRISC system. A client is
|
||||
responsible for writing the module that generates MLTREE from
|
||||
the source program representation.
|
||||
\item \href{instrsel.html}{Instruction selection modules},
|
||||
which generates target machine
|
||||
instructions from MLTREE.
|
||||
\item The \href{ra.html}{Register Allocator},
|
||||
which performs register allocation.
|
||||
\item \href{asm.html}{Assemblers}, which emits assembly code.
|
||||
\end{itemize}
|
||||
|
||||
For systems that require direct machine code generation, the following
|
||||
modules are included:
|
||||
\begin{itemize}
|
||||
\item \href{span-dep.html}{Span dependency resolution}
|
||||
modules, which compute addresses
|
||||
from symbolic addresses,
|
||||
fill delay slots, and expand instructions that are
|
||||
\newdef{span dependent}
|
||||
\item \href{mc.html}{Machine code emitters},
|
||||
which emit executable machine code into a binary stream.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Optimization Modules}
|
||||
|
||||
In addition, MLRISC has been enhanced to support various types of
|
||||
machine level optimizations. These include:
|
||||
|
||||
\begin{itemize}
|
||||
\item Core optimizations, which includes
|
||||
various types of control flow transformation,
|
||||
and architectural specific peephole optimizations.
|
||||
\item SSA based scalar optimizations
|
||||
\item ILP optimizations for superscalars
|
||||
\item ILP optimizations for VLIW/EPIC architectures
|
||||
\item GC safety analysis
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Basic Concepts}
|
||||
|
||||
Basic concepts in MLRISC are:
|
||||
\begin{itemize}
|
||||
\item \href{instructions.html}{Instructions} --
|
||||
the instruction set of the target architecture.
|
||||
\item \href{cells.html}{Cells} -- which describes registers,
|
||||
memory and other mutable resources in the machine.
|
||||
\item \href{regions.html}{Regions} -- a client defined
|
||||
abstract type used to represent aliasing information available from
|
||||
the front-end.
|
||||
\item \href{constants.html}{Constants} -- a client defined
|
||||
place holder used to represent constants whose values are unknown
|
||||
in the front-end.
|
||||
\item \href{pseudo-ops.html}{Pseudo Ops} -- a client defined
|
||||
|
||||
\item \href{annotations.html}{Annotations} -- this is
|
||||
a generic mechinism for propagating information in the MLRISC sstem.
|
||||
The client may attach arbitrary annotation of various granularity
|
||||
to MLRISC's program representation,
|
||||
which can then be propagated to later phases.
|
||||
These can be information related to profiling frequency, dependence,
|
||||
comments, and/or types.
|
||||
The same mechanism is also used to propagate
|
||||
analysis information one optimization phase to
|
||||
another.
|
||||
\item \href{streams.html}{Instruction Streams} -- an abstraction
|
||||
for describing a stream of instructions. Instruction streams are
|
||||
used to connect modules such as instruction selection, assembler,
|
||||
machine code emitter, and
|
||||
control flow graph builder.
|
||||
\item \href{regmap.html}{Regmap} -- a mapping between registers
|
||||
names. MLRISC register allocators represent the result of register
|
||||
allocation as a regmap.
|
||||
\item \href{labels.html}{Labels} -- a type representing
|
||||
symbolic labels.
|
||||
\item \href{labelexp.html}{Label Expressions} -- a type representing
|
||||
constant expressions
|
||||
involving symbolic labels.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{How Things Are Fit Together}
|
||||
|
||||
MLRISC uses two different program representations, clusters and MLRISC IR.
|
||||
\begin{itemize}
|
||||
\item \href{cluster.html}{Cluster} is light-weight representation
|
||||
that is used when only the most basic optimizations are required.
|
||||
\item \href{mlrisc-ir.html}{MLRISC IR} is more heavy-weight
|
||||
representation that is built from the
|
||||
\href{graphs.html}{MLRISC graph library} and the
|
||||
\href{compiler-graphs.html}{MLRISC compiler graph library}.
|
||||
MLRISC IR allows more complex transformations and analysis of the
|
||||
program graph.
|
||||
\end{itemize}
|
||||
Conversion modules between the two representations are provided.
|
||||
|
||||
In general MLRISC optimization phases are transformations applied on one
|
||||
of these representations. Optimizations may be chained together to form
|
||||
a compiler backend. For example, a minimal backend consists of
|
||||
\begin{itemize}
|
||||
\item the instruction selection module, which translates
|
||||
\href{mltree.html}{MLTree} into target instructions,
|
||||
\item the flowgraph builder, which conversts a stream of target instructions
|
||||
into a cluster,
|
||||
\item the register allocator, which performs register allocation, and
|
||||
\item the assembly code emitter, which generates assembly output
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,54 @@
|
||||
\section{MLRISC Based Compiler}
|
||||
A traditional compiler will typically consist of a
|
||||
\begin{color}{#dd0000}lex/yacc\end{color} based front end, an
|
||||
\begin{color}{#DD0000}optimization\end{color}
|
||||
phase that is repeatedly invoked
|
||||
over some intermediate representation, and finally a
|
||||
\begin{color}{#DD0000}back end\end{color}
|
||||
code generation phase. The intermediate
|
||||
representation is usually at a level of detail appropriate to the
|
||||
optimization being performed, and may be far removed from the
|
||||
native instructions of the target architecture. The back end
|
||||
proceeds by translating the intermediate representation into
|
||||
instructions and registers for an abstract machine that is much
|
||||
closer to the target architecture. Retargetting is then achieved
|
||||
by mapping the registers and instructions of the abstract machine
|
||||
to registers and instructions of the target architecture.
|
||||
|
||||
\br{clear=left}
|
||||
|
||||
\image{MLRISC based compiler}{pictures/png/compiler-2.png}{align=right}
|
||||
|
||||
An MLRISC based compiler, on the other hand, translates the
|
||||
intermediate representation into MLRISC instructions and it is the
|
||||
MLRISC instructions that get mapped onto instructions of the target
|
||||
architecture. Another possibility is to translate the front end
|
||||
abstract machine instructions instead of the intermediate
|
||||
representation. Once MLRISC instructions have been generated,
|
||||
nearly all aspects of high quality code generation come for free. A
|
||||
long story would be cut short if MLRISC were just another abstract
|
||||
machine.
|
||||
|
||||
\begin{color}{#580000} The key idea behind MLRISC is that there is no
|
||||
single MLRISC instruction set or intermediate program
|
||||
representation, \end{color} but the MLRISC intermediate representation
|
||||
is specialized to the needs of the front end source language being
|
||||
compiled. The specialization does not stop there, but the:
|
||||
\begin{itemize}
|
||||
\item \begin{color}{#005500}target instruction set\end{color},
|
||||
\item \begin{color}{#005500}flowgraph\end{color}, and
|
||||
\item \begin{color}{#005500}entire optimization suite\end{color}
|
||||
\end{itemize}
|
||||
|
||||
are specialized to the needs of the front end. The ability to
|
||||
consistently specialize each of these to create a back end for a
|
||||
specific language, summarizes the characteristics of MLRISC that
|
||||
distinguishes it from other retargetable backends.
|
||||
|
||||
\begin{color}{#580000} It is important to emphasize that little
|
||||
optimizations performed on the MLRISC intermediate
|
||||
representation. \end{color} Most optimizations are done on a flowgraph of
|
||||
target machine instructions, to enable optimizations that take advantage
|
||||
of the characteristics of each architectural.
|
||||
The MLRISC intermediate representation is just used as a stepping
|
||||
stone to get to the flowgraph.
|
||||
@@ -0,0 +1,60 @@
|
||||
\section{MLRisc Generation}
|
||||
Every compiler will eventually compile down to an abstract machine
|
||||
that it believes will execute source programs efficiently. The
|
||||
abstract machine will typically consists of abstract machine
|
||||
registers and instructions, one or more stacks, and parameter
|
||||
passing conventions. The hope is that all this will map down
|
||||
efficiently onto the target machine. Indeed, the abstract machine
|
||||
should be reasonably close to architectures that are envisioned as
|
||||
possible targets. Several step need to be followed in the generation
|
||||
of MLRisc.
|
||||
|
||||
\begin{enumerate}
|
||||
\item The first step in generating target machine code is to define
|
||||
the MLRisc intermediate representation after it has been
|
||||
appropriately specialized. The interfaces that describe the
|
||||
dimensions of specialization are quite simple. Depending on the
|
||||
compiler, these may be target dependent; for example, in the SML/NJ
|
||||
compiler, the encoding of registers used to indicate the roots of
|
||||
garbage collection depend on how the runtime system decodes the
|
||||
information.
|
||||
|
||||
\item The only real connection between the MLRisc intermediate
|
||||
representation and the target machine is that the first
|
||||
$0..K-1$ MLRisc registers map onto the first $K$
|
||||
physical registers on the target machine. Thus some mapping of
|
||||
dedicated abstract machine registers to physical target registers is
|
||||
required. It is not always necessary to map abstract machine
|
||||
registers to physical machine registers. For example, on
|
||||
architectures like the x86 with few registers, some abstract machine
|
||||
registers may be mapped to fixed memory locations. Thus an abstract
|
||||
machine register like the \sml{maskReg} may have something like:
|
||||
\begin{SML}
|
||||
LOAD(32, LABEL maskRegLab)
|
||||
\end{SML}
|
||||
spliced instead.
|
||||
|
||||
\item The unit of compilation is called a
|
||||
\href{cluster.html}{cluster} which
|
||||
is the smallest unit for inter-procedural optimizations. A cluster
|
||||
will typically consist of several entry points that may call each
|
||||
other, as well as call local functions in the module. For maximum
|
||||
flexibility, the parameter passing convention for local functions
|
||||
should be specialized by the \href{mlrisc-ra.html}{register allocator}.
|
||||
|
||||
Once the MLRisc trees for a cluster have been built, they must
|
||||
be converted into target assembly or machine code. This is done by
|
||||
building up a function (\newdef{codegen}) that
|
||||
glues together optimizations modules that have been specialized. For
|
||||
example, the target instruction set must be specialized to hold the
|
||||
MLRisc constants; the flowgraph must be specialized to carry these
|
||||
instructions as well as the MLRisc pseudo-ops; the optimization
|
||||
modules must know about several front end constraints such as how to
|
||||
spill registers.
|
||||
\end{enumerate}
|
||||
|
||||
If the module that translates the abstract machine instructions
|
||||
into MLRisc instructions has been appropriately parameterized, then
|
||||
it can be reused for multiple target architectures. For high level
|
||||
languages it is better to generate MLRisc instructions from the high
|
||||
level intermediate form used by the front end of the compiler.
|
||||
@@ -0,0 +1,31 @@
|
||||
\section{Graphical Interface}
|
||||
All the major data structures and intermediate program states can be
|
||||
viewed graphically using
|
||||
\externhref{http://www.Informatik.Uni-Bremen.DE/~davinci/}{\begin{color}{red}daVinci\end{color}} and
|
||||
\externhref{http://www.cs.uni-sb.de/RW/users/sander/html/gsvcg1.html}{\begin{color}{red}vcg\end{color}}
|
||||
The following screen dumps are intended to represent the range of
|
||||
possibilities. Graphical tools like these are an indispensible
|
||||
debugging aid. Each of the dumps below were taken when generating
|
||||
code for the \begin{color}{red}mandelbrot\end{color} on the HPPA
|
||||
architecture. It will be necessary to make netscape fill the size of
|
||||
the screen to view these easily. Even though some of these graphs
|
||||
look quite complex, daVinci has several \emph{navigational} modes
|
||||
that allow walking to successors, or predecessors, or navigating
|
||||
through a scaled down map of the graph. The navigational view is
|
||||
shown as another window, and the view into the graph that is being
|
||||
displayed is usually outlined in \begin{color}{blue}blue\end{color}.
|
||||
|
||||
\begin{description}
|
||||
\item[\href{graphics/mandelbrot-opt.gif}{Control Flowgraph after Optimization:}] Each basic block is shown with its dynamic profile and
|
||||
code before and after a specific optimization. This view
|
||||
saves having to pour through pages of assembly code listings --
|
||||
a tedious and frustrating activity.
|
||||
\item[\href{graphics/mandelbrot-ssa.gif}{SSA form:}]
|
||||
The generated flow graph is converted to SSA form which
|
||||
makes many code improvement optimizations easy and efficient.
|
||||
\item[\href{graphics/mandelbrot-ddg.gif}{Data Dependency Graph}]
|
||||
A graphical view of the data dependency graph and the various
|
||||
kinds of dependencies decorating the edges, provides a useful clue to
|
||||
why instructions got rearranged the way they did. The navigational
|
||||
view helps to control the complexity in the display.
|
||||
\end{description}
|
||||
@@ -0,0 +1,158 @@
|
||||
\section{MLRISC Intermediate Representation}
|
||||
The MLRISC intermediate language is called
|
||||
\newdef{MLTREE} At the lowest level, the core of MLTREE is a
|
||||
\italics{Register Transfer Language (RTL)}
|
||||
but represented in tree form. The tree
|
||||
form makes it convenient to use tree pattern matching tools like
|
||||
BURG (where appropriate) to do target instruction selection. Thus a
|
||||
tree such as:
|
||||
|
||||
\begin{SML}
|
||||
MV(32, t,
|
||||
ADDT(32, MULT(32, REG(32, b), REG(32, b)),
|
||||
MULT(32, MULT(REG(32, a), LI(4)), REG(32, c))))
|
||||
\end{SML}
|
||||
|
||||
computes \sml{t := b*b + 4*a*c} to 32-bit precision.
|
||||
The nodes \sml{ADDT} and
|
||||
\sml{MULT} are the trapping form of addition and multiplication,
|
||||
and \sml{LI} is used for integer constants. An infinite number
|
||||
of registers are assumed by the model, however depending on the
|
||||
target machine the first \sml{0..K} registers map onto the first
|
||||
\sml{K} registers on the target machine. Everything else is
|
||||
assumed to be a pseudo-register. The \sml{REG} node is used to
|
||||
indicate a general purpose register.
|
||||
|
||||
|
||||
The core MLTREE language makes no assumptions about instructions or
|
||||
calling convections of the target architecture. Trees can be
|
||||
created and combined in almost any form, with certain meaningless
|
||||
trees such as \sml{LOAD(32, FLOAD(64, LI 0))} being forbidden by the
|
||||
MLTREE type structure.
|
||||
|
||||
Such pure trees are nice but inadequate in real compilers. One
|
||||
needs to be able to propagate front end specific information, such
|
||||
as frame sizes and frame offsets where the actual values are only
|
||||
available after register allocation and spilling. One could add
|
||||
support for frames in MLRISC, however this becomes a slippery slope
|
||||
because some compilers (e.g. SML/NJ) do not have a conventional
|
||||
notion of frames --- indeed there is no runtime stack in the
|
||||
execution of SML/NJ. A frame organization for one person may not
|
||||
meet the needs for another, and so on. In MLRISC, the special
|
||||
requirements of different compilers is communicated into the MLTREE
|
||||
language, and subsequently into the optimizations phases, by
|
||||
specializing the MLTREE data structure with client specific
|
||||
information. There are currently \emph{five} dimensions over
|
||||
which one could specialize the MLTREE language.
|
||||
|
||||
\begin{description}
|
||||
\item[Constants] Constants are an
|
||||
abstraction for integer literals whose value is known after
|
||||
certain phases of code generation. Frame sizes and offsets are an
|
||||
example.
|
||||
\image{MLRISC intermediate representation}{pictures/png/mlrisc-ir.png}{align=right}
|
||||
\item[Regions] While the data
|
||||
dependencies between arithmetic operations is implicit in the
|
||||
instruction, the data dependencies between memory operations is
|
||||
not. Regions are an abstract view of memory that make this
|
||||
dependence explicit and is specially useful for instruction
|
||||
reordering.
|
||||
|
||||
\item[Pseudo-ops] Pseudo-ops are
|
||||
intended to correspond to pseudo-op directives provided by native
|
||||
assemblers to lay out data, jump tables, and perform alignment.
|
||||
|
||||
\item[Annotations]
|
||||
\href{annotations.html}{Annotations} are used
|
||||
for injecting semantics and other program information from the front-end
|
||||
into the backend. For example, a probability annotation can be
|
||||
attached to a branch instruction. Similarly, line number annotations
|
||||
can be attached to basic blocks to aid debugging.
|
||||
In many language implementations function local variables are
|
||||
spilled to activation frames on the stack. Spill slots contribute
|
||||
to the size of a function's frame. When an instruction produces a
|
||||
spill, we may need to update the frame associated to that
|
||||
instruction (increase the size of its spilling area). The frame
|
||||
for the current function can be injected in an annotation, which
|
||||
can be later examined by the spill callback during register allocation.
|
||||
|
||||
Annotations are
|
||||
implemented as an universal type and can be arbitrarily extended.
|
||||
Individual annotations can be associated
|
||||
with compiler objects of varying granularity,
|
||||
from compilation units, to regions, basic blocks, flow edges,
|
||||
and down to the instructions.
|
||||
|
||||
|
||||
\item[User Defined Extensions]
|
||||
In the most extreme case, the basic constructors defined in the MLTREE
|
||||
language may be inadequate for the task at hand.
|
||||
MLTREE allows the client to arbitrarily extend
|
||||
the set of statements and expressions to more closely match the
|
||||
source language and the target architecture(s).
|
||||
|
||||
For example, when using MLRISC for the backend of a DSP compiler
|
||||
it may be useful to extend the set of MLRISC operators to include
|
||||
fix point and saturated arithmetic.
|
||||
Similarly, when developing a language for loop parallelization, it may
|
||||
be useful to extend the MLTREE language with higher-level loop
|
||||
constructs.
|
||||
\end{description}
|
||||
|
||||
\subsection{Examples}
|
||||
|
||||
In the SML/NJ compiler, an encoding of a list of registers
|
||||
is passed to the garbage collector as the roots of live
|
||||
variables. This encoding cannot be computed until register
|
||||
allocation has been performed, therefore the integer literal
|
||||
encoding is represented as an abstract
|
||||
\href{constants.html}{constant}.
|
||||
|
||||
Again, in the SML/NJ compiler, most stores are for initializing
|
||||
records in the allocation space, therefore representing every slot in
|
||||
the allocation space as a unique region allows one to commute
|
||||
most store instructions. Similarly, most loads are from
|
||||
\emph{immutable} records, and a simple analysis marks these are
|
||||
being accesses to \emph{read-only} memory. Read-only memory is
|
||||
characterized as having multiple \emph{uses} but no
|
||||
\emph{definitions}.
|
||||
|
||||
In the TIL compiler, a \emph{trace table} is generated for
|
||||
every call site that records the set of live variables, their
|
||||
location (register or stack offset), and the type associated with
|
||||
the variable. This table is integrated into the program using the
|
||||
abstract pseudo-op mechanism. An interesting aspect of these tables
|
||||
is that they may need adjustment based on the results of register
|
||||
spilling.
|
||||
|
||||
The more convention use of the psuedo-op abstraction is to
|
||||
propagate function prologue and epilogue information.
|
||||
|
||||
The constants abstraction are created by a tree node called
|
||||
\sml{CONST}. In the SML/NJ compiler, the tree that communicates
|
||||
garbage collection information looks like:
|
||||
|
||||
\begin{verbatim}
|
||||
MV(32, maskReg, CONST{r110,r200,r300,r400 ...})
|
||||
\end{verbatim}
|
||||
|
||||
where \sml{maskReg} is a dedicated register. On the DEC Alpha,
|
||||
this would get translated to:
|
||||
|
||||
\begin{verbatim}
|
||||
LDA maskReg, {encode(r110,r200,r300,r400, ...)}
|
||||
\end{verbatim}
|
||||
|
||||
which indicates that the alpha instruction set (and optimization
|
||||
suite) know about these types of values. Further, after
|
||||
register allocation, the \sml{LDA} instruction may not be
|
||||
sufficient as the encoding may result in a value that is too large
|
||||
as an operand to \sml{LDA}. Two instructions may ultimately be
|
||||
required to load the encoding into the \sml{maskReg}
|
||||
register. This expansion is done during
|
||||
\href{span-dep.html}{span-dependency resolution}.
|
||||
|
||||
All these examples are intended to indicate that one
|
||||
intermediate representation and optimization suite does not fit
|
||||
all, but that the intermediate representation and optimization
|
||||
suite needs to be specialized to the needs of the client.
|
||||
@@ -0,0 +1,609 @@
|
||||
\section{The MLRISC IR}
|
||||
\subsection{Introduction}
|
||||
|
||||
In this section we will describe the MLRISC intermediate representation.
|
||||
|
||||
\subsubsection{Control Flow Graph}
|
||||
The control flow graph is the main view of the IR.
|
||||
A control flow graph satisfies the following signature:
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/mlrisc-cfg.sig}{CONTROL_FLOW_GRAPH} = sig
|
||||
structure I : INSTRUCTIONS
|
||||
structure P : PSEUDO_OPS
|
||||
structure C : CELLS
|
||||
structure W : FIXED_POINT
|
||||
sharing I.C = C
|
||||
|
||||
\italics{definitions}
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The following structures nested within a CFG:
|
||||
\begin{itemize}
|
||||
\item \sml{I : INSTRUCTIONS} is the instruction structure.
|
||||
\item \sml{P : PSEUDO_OPS} is the structure with the definition
|
||||
of pseudo ops.
|
||||
\item \sml{C : CELLS} is the cells structure describing the
|
||||
register conventions of the architecture.
|
||||
\item \sml{W : FIXED_POINT} is a structure that contains
|
||||
a fixed point type used in execution frequency annotations.
|
||||
\end{itemize}
|
||||
|
||||
The type \sml{weight} below is used in execution frequency annotations:
|
||||
\begin{SML}
|
||||
type weight = W.fixed_point
|
||||
\end{SML}
|
||||
|
||||
There are a few different kinds of basic blocks, described
|
||||
by the type \sml{block_kind} below:
|
||||
\begin{SML}
|
||||
datatype block_kind =
|
||||
START
|
||||
| STOP
|
||||
| FUNCTION_ENTRY
|
||||
| NORMAL
|
||||
| HYPERBLOCK
|
||||
\end{SML}
|
||||
|
||||
A basic block is defined as the datatype \sml{block}, defined below:
|
||||
\begin{SML}
|
||||
and data = LABEL of Label.label
|
||||
| PSEUDO of P.pseudo_op
|
||||
|
||||
and block =
|
||||
BLOCK of
|
||||
\{ id : int,
|
||||
kind : block_kind,
|
||||
name : B.name,
|
||||
freq : weight ref,
|
||||
data : data list ref,
|
||||
labels : Label.label list ref,
|
||||
insns : I.instruction list ref,
|
||||
annotations : Annotations.annotations ref
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
Edges in a CFG are annotated with the type \sml{edge_info},
|
||||
defined below:
|
||||
\begin{SML}
|
||||
and edge_kind = ENTRY
|
||||
| EXIT
|
||||
| JUMP
|
||||
| FALLSTHRU
|
||||
| BRANCH of bool
|
||||
| SWITCH of int
|
||||
| SIDEEXIT of int
|
||||
|
||||
and edge_info =
|
||||
EDGE of \{ k : edge_kind,
|
||||
w : weight ref,
|
||||
a : Annotations.annotations ref
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
Type \sml{cfg} below defines a control flow graph:
|
||||
\begin{SML}
|
||||
type edge = edge_info edge
|
||||
type node = block node
|
||||
|
||||
datatype info =
|
||||
INFO of \{ regmap : C.regmap,
|
||||
annotations : Annotations.annotations ref,
|
||||
firstBlock : int ref,
|
||||
reorder : bool ref
|
||||
\}
|
||||
type cfg = (block,edge_info,info) graph
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Low-level Interface}
|
||||
The following subsection describes the low-level interface to a CFG.
|
||||
These functions should be used with care since they do not
|
||||
always maintain high-level structural invariants imposed on
|
||||
the representation. In general, higher level interfaces exist
|
||||
so knowledge of this interface is usually not necessary for customizing
|
||||
MLRISC.
|
||||
|
||||
Various kinds of annotations on basic blocks are defined below:
|
||||
\begin{SML}
|
||||
exception LIVEOUT of C.cellset
|
||||
exception CHANGED of unit -> unit
|
||||
exception CHANGEDONCE of unit -> unit
|
||||
\end{SML}
|
||||
The annotation \sml{LIVEOUT} is used record live-out information
|
||||
on an escaping block.
|
||||
The annotations \sml{CHANGED} and \sml{CHANGEDONCE} are used
|
||||
internally for maintaining views on a CFG. These should not be used
|
||||
directly.
|
||||
|
||||
The following are low-level functions for building new basic blocks.
|
||||
The functions \sml{new}\emph{XXX} build empty basic blocks of a specific
|
||||
type. The function \sml{defineLabel} returns a label to a basic block;
|
||||
and if one does not exist then a new label will be generated automatically.
|
||||
The functions \sml{emit} and \sml{show_block} are low-level
|
||||
routines for displaying a basic block.
|
||||
\begin{SML}
|
||||
val newBlock : int * B.name -> block
|
||||
val newStart : int -> block
|
||||
val newStop : int -> block
|
||||
val newFunctionEntry : int -> block
|
||||
val copyBlock : int * block -> block
|
||||
val defineLabel : block -> Label.label
|
||||
val emit : C.regmap -> block -> unit
|
||||
val show_block : C.regmap -> block -> string
|
||||
\end{SML}
|
||||
|
||||
Methods for building a CFG are listed as follows:
|
||||
\begin{SML}
|
||||
val cfg : info -> cfg
|
||||
val new : C.regmap -> cfg
|
||||
val subgraph : cfg -> cfg
|
||||
val init : cfg -> unit
|
||||
val changed : cfg -> unit
|
||||
val removeEdge : cfg -> edge -> unit
|
||||
\end{SML}
|
||||
Again, these methods should be used only with care.
|
||||
|
||||
The following functions allow the user to extract low-level information
|
||||
from a flowgraph. Function \sml{regmap} returns the current register map.
|
||||
Function \sml{regmap} returns a function that lookups the current register
|
||||
map. Function \sml{liveOut} returns liveOut information from a block;
|
||||
it returns the empty cellset if the block is not an escaping block.
|
||||
Function \sml{fallsThruFrom} takes a node id $v$ and locates the
|
||||
block $u$ (if any) that flows into $v$ without going through a branch
|
||||
instruction. Similarly, the function \sml{fallsThruTo} takes
|
||||
a node id $u$ and locates the block (if any) that $u$ flows into
|
||||
with going through a branch instruction. If $u$ falls through to
|
||||
$v$ in any feasible code layout $u$ must preceed $v$.
|
||||
\begin{SML}
|
||||
val regmap : cfg -> C.regmap
|
||||
val reglookup : cfg -> C.register -> C.register
|
||||
val liveOut : block -> C.cellset
|
||||
val fallsThruFrom : cfg * node_id -> node_id option
|
||||
val fallsThruTo : cfg * node_id -> node_id option
|
||||
\end{SML}
|
||||
|
||||
To support graph viewing of a CFG, the following low-level
|
||||
primitives are provided:
|
||||
\begin{SML}
|
||||
val viewStyle : cfg -> (block,edge_info,info) GraphLayout.style
|
||||
val viewLayout : cfg -> GraphLayout.layout
|
||||
val headerText : block -> string
|
||||
val footerText : block -> string
|
||||
val subgraphLayout : { cfg : cfg, subgraph : cfg } -> GraphLayout.layout
|
||||
\end{SML}
|
||||
|
||||
Finally, a miscellany function for control dependence graph building.
|
||||
\begin{SML}
|
||||
val cdgEdge : edge_info -> bool
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{IR}
|
||||
The MLRISC intermediate representation is a composite
|
||||
view of various compiler data structures, including the control
|
||||
flow graph, (post-)dominator trees, control dependence graph, and
|
||||
loop nesting tree. Basic compiler optimizations in MLRISC
|
||||
operate on this data structure; advance optimizations
|
||||
operate on more complex representations which use this
|
||||
representation as the base layer.
|
||||
\begin{wrapfigure}{r}{4.5in}
|
||||
\begin{Boxit}
|
||||
% \psfig{figure=../pictures/eps/mlrisc-IR.eps,width=4.5in}
|
||||
\includegraphics[width=4.5in]{../pictures/pdf/mlrisc-IR}
|
||||
\end{Boxit}
|
||||
\caption{The MLRISC IR}
|
||||
\end{wrapfigure}
|
||||
|
||||
This IR provides a few additional functionalities:
|
||||
\begin{itemize}
|
||||
\item Edge frequencies -- execution frequencies
|
||||
are maintained on all control flow edges.
|
||||
\item Extensible annotations -- semantics information can be
|
||||
represented as annotations on the graph.
|
||||
\item Multiple facets --
|
||||
Facets are high-level views that automatically keep themselves
|
||||
up-to-date. Computed facets are cached and out-of-date facets
|
||||
are recomputed by demand.
|
||||
The IR defines a mechanism to attach multiple facets to the IR.
|
||||
\end{itemize}
|
||||
|
||||
The signature of the IR is listed below
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/mlrisc-ir.sig}{MLRISC_IR} = sig
|
||||
structure I : INSTRUCTIONS
|
||||
structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure Dom : DOMINATOR_TREE
|
||||
structure CDG : CONTROL_DEPENDENCE_GRAPH
|
||||
structure Loop : LOOP_STRUCTURE
|
||||
structure Util : CFG_UTIL
|
||||
sharing Util.CFG = CFG
|
||||
sharing CFG.I = I
|
||||
sharing Loop.Dom = CDG.Dom = Dom
|
||||
|
||||
type cfg = CFG.cfg
|
||||
type IR = CFG.cfg
|
||||
type dom = (CFG.block,CFG.edge_info,CFG.info) Dom.dominator_tree
|
||||
type pdom = (CFG.block,CFG.edge_info,CFG.info) Dom.postdominator_tree
|
||||
type cdg = (CFG.block,CFG.edge_info,CFG.info) CDG.cdg
|
||||
type loop = (CFG.block,CFG.edge_info,CFG.info) Loop.loop_structure
|
||||
|
||||
val dom : IR -> dom
|
||||
val pdom : IR -> pdom
|
||||
val cdg : IR -> cdg
|
||||
val loop : IR -> loop
|
||||
|
||||
val changed : IR -> unit
|
||||
val memo : (IR -> 'facet) -> IR -> 'facet
|
||||
val addLayout : string -> (IR -> GraphLayout.layout) -> unit
|
||||
val view : string -> IR -> unit
|
||||
val views : string list -> IR -> unit
|
||||
val viewSubgraph : IR -> cfg -> unit
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The following facets are predefined: dominator, post-dominator tree,
|
||||
control dependence graph and loop nesting structure.
|
||||
The functions \sml{dom}, \sml{pdom}, \sml{cdg}, \sml{loop}
|
||||
are \newdef{facet extraction} methods that
|
||||
compute up-to-date views of these facets.
|
||||
|
||||
The following protocol is used for facets:
|
||||
\begin{itemize}
|
||||
\item When the IR is changed,
|
||||
the function \sml{changed} should be called to
|
||||
signal that all facets attached to the IR should be updated.
|
||||
\item To add a new facet of type \sml{F} that is computed by demand,
|
||||
the programmer has to provide a facet construction
|
||||
function \sml{f : IR -> F}. Call the function \sml{mem}
|
||||
to register the new facet. For example, let \sml{val g = memo f}.
|
||||
Then the function \sml{g} can be used to as a new facet extraction
|
||||
function for facet \sml{F}.
|
||||
\item To register a graph viewing function, call
|
||||
the function \sml{addLayout} and provide an appropriate
|
||||
graph layout function. For example, we can say
|
||||
\sml{addLayout "F" layoutF} to register a graph layout function
|
||||
for a facet called ``F''.
|
||||
\end{itemize}
|
||||
|
||||
To view an IR, the functions \sml{view}, \sml{views} or
|
||||
\sml{viewSubgraph} can be used. They have the following interpretation:
|
||||
\begin{itemize}
|
||||
\item \sml{view} computes a layout for one facet of the IR and displays
|
||||
it. The predefined facets are called
|
||||
``dom'', ``pdom'', ``cdg'', ``loop.'' The IR can be
|
||||
viewed as the facet ``cfg.'' In addition, there is a layout
|
||||
named ``doms'' which displays the dominator tree and the post-dominator
|
||||
tree together, with the post-dominator inverted.
|
||||
\item \sml{views} computes a set of facets and displays it together
|
||||
in one single picture.
|
||||
\item \sml{viewSubgraph} layouts a subgraph of the IR.
|
||||
This creates a picture with the subgraph highlighted and embedded
|
||||
in the whole IR.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Building a CFG}
|
||||
|
||||
There are two basic methods of building a CFG:
|
||||
\begin{itemize}
|
||||
\item convert a sequence of machine instructions
|
||||
into a CFG through the emitter interface, described below, and
|
||||
\item convert it from a \newdef{cluster}, which is
|
||||
the basic linearized representation used in the MLRISC system.
|
||||
\end{itemize}
|
||||
The first method requires you to perform instruction selection
|
||||
from a compiler front-end, but allows you to bypass all other
|
||||
MLRISC phases if desired. The second method allows you
|
||||
to take advantage of various MLRISC's instruction selection modules
|
||||
currently available. We describe these methods in this section.
|
||||
|
||||
\paragraph{Directly from Instructions}
|
||||
Signature \sml{CODE_EMITTER} below describes an abstract emitter interface
|
||||
for accepting a linear stream of instructions from a source
|
||||
and perform a sequence of actions based on this
|
||||
stream\footnote{Unlike the signature {\tt EMITTER\_NEW} or
|
||||
{\tt FLOWGRAPH\_GEN}, it has the advantage that it is not
|
||||
tied into any form of specific flowgraph representation.}.
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{extensions/code-emitter.sig}{CODE_EMITTER} = sig
|
||||
structure I : INSTRUCTIONS
|
||||
structure C : CELLS
|
||||
structure P : PSEUDO_OPS
|
||||
sharing I.C = C
|
||||
|
||||
type emitter =
|
||||
\{ defineLabel : Label.label -> unit,
|
||||
entryLabel : Label.label -> unit,
|
||||
exitBlock : C.cellset -> unit,
|
||||
pseudoOp : P.pseudo_op -> unit,
|
||||
emitInstr : I.instruction -> unit,
|
||||
comment : string -> unit,
|
||||
init : int -> unit,
|
||||
finish : unit -> unit
|
||||
\}
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The code emitter interface has the following informal protocol.
|
||||
\begin{methods}
|
||||
init($n$) & Initializes the emitter and signals that
|
||||
the back-end should
|
||||
allocate space for $n$ bytes of machine code.
|
||||
The number is ignored for non-machine code back-ends. \\
|
||||
defineLabel($l$) & Defines a new label $l$ at the current position.\\
|
||||
entryLabel($l$) & Defines a new entry label $l$ at the current position.
|
||||
An entry label defines an entry point into the current flow graph.
|
||||
Note that multiple entry points are allowed\\
|
||||
exitBlock($c$) & Defines an exit at the current position.
|
||||
The cellset $c$ represents the live-out information \\
|
||||
pseudOp($p$) & Emits an pseudo op $p$ at the current position \\
|
||||
emitInstr($i$) & Emits an instruction $i$ at the current position \\
|
||||
blockName($b$) & Changes the block name to $b$ \\
|
||||
comment($msg$) & Emits a comment $msg$ at the current position \\
|
||||
finish & Signals that the use of the emitter is finished.
|
||||
The emitter is free to perform its post-processing functions.
|
||||
When this is finished the CFG is built.
|
||||
\end{methods}
|
||||
|
||||
The functor \sml{ControlFlowGraphGen} below can be
|
||||
used to create a CFG builder that uses the \sml{CODE_EMITTER} interface.
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/mlrisc-cfg-gen.sig}{CONTROL_FLOW_GRAPH_GEN} = sig
|
||||
structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure Emitter : CODE_EMITTER
|
||||
sharing Emitter.I = CFG.I
|
||||
sharing Emitter.P = CFG.P
|
||||
val emitter : CFG.cfg -> Emitter.emitter
|
||||
end
|
||||
functor \mlrischref{IR/mlrisc-cfg-gen.sml}{ControlFlowGraphGen}
|
||||
(structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure Emitter : CODE_EMITTER
|
||||
structure P : INSN_PROPERTIES
|
||||
sharing CFG.I = Emitter.I = P.I
|
||||
sharing CFG.P = Emitter.P
|
||||
sharing CFG.B = Emitter.B
|
||||
) : CONTROL_FLOW_GRAPH_GEN
|
||||
\end{SML}
|
||||
|
||||
\paragraph{Cluster to CFG}
|
||||
|
||||
The core \MLRISC{} system implements many instruction selection
|
||||
front-ends. The result of an instruction selection module is a linear
|
||||
code layout block called a cluster. The functor \sml{Cluster2CFG} below
|
||||
generates a translator that translates a cluster into a CFG:
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/mlrisc-cluster2cfg.sig}{CLUSTER2CFG} = sig
|
||||
structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure F : FLOWGRAPH
|
||||
sharing CFG.I = F.I
|
||||
sharing CFG.P = F.P
|
||||
sharing CFG.B = F.B
|
||||
val cluster2cfg : F.cluster -> CFG.cfg
|
||||
end
|
||||
functor \mlrischref{IR/mlrisc-cluster2cfg.sml}{Cluster2CFG}
|
||||
(structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure F : FLOWGRAPH
|
||||
structure P : INSN_PROPERTIES
|
||||
sharing CFG.I = F.I = P.I
|
||||
sharing CFG.P = F.P
|
||||
sharing CFG.B = F.B
|
||||
) : CLUSTER2CFG
|
||||
\end{SML}
|
||||
|
||||
\paragraph{CFG to Cluster}
|
||||
|
||||
The basic \MLRISC{} system also implements many back-end functions
|
||||
such as register allocation, assembly output and machine code output.
|
||||
These modules all utilize the cluster representation. The
|
||||
functor \mlrischref{IR/mlrisc-cfg2cluster.sml}{CFG2Cluster}
|
||||
below generates a translator
|
||||
that converts a CFG into a cluster. With the previous functor,
|
||||
the CFG and the cluster presentation can be freely inter-converted.
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/mlrisc-cfg2cluster.sig}{CFG2CLUSTER} = sig
|
||||
structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure F : FLOWGRAPH
|
||||
sharing CFG.I = F.I
|
||||
sharing CFG.P = F.P
|
||||
sharing CFG.B = F.B
|
||||
val cfg2cluster : { cfg : CFG.cfg, relayout : bool } -> F.cluster
|
||||
end
|
||||
functor \mlrischref{IR/mlrisc-cfg2cluster.sml}{CFG2Cluster}
|
||||
(structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure F : FLOWGRAPH
|
||||
sharing CFG.I = F.I
|
||||
sharing CFG.P = F.P
|
||||
sharing CFG.B = F.B
|
||||
val patchBranch : {instr:CFG.I.instruction, backwards:bool} ->
|
||||
CFG.I.instruction list
|
||||
) : CFG2CLUSTER
|
||||
\end{SML}
|
||||
|
||||
When a CFG originates from a cluster, we try to preserve
|
||||
the same code layout through out all optimizations when possible.
|
||||
The function \sml{cfg2cluster} takes an optional flag
|
||||
that specifies we should force the recomputation of
|
||||
the code layout of a control flow graph when translating a CFG
|
||||
back into a cluster.
|
||||
|
||||
\subsubsection{Basic CFG Transformations}
|
||||
|
||||
Basic CFG transformations are implemented in the functor
|
||||
\sml{CFGUtil}. These transformations include splitting edges, merging
|
||||
edges, removing unreachable code and tail duplication.
|
||||
\begin{SML}
|
||||
functor \mlrischref{IR/mlrisc-cfg-util.sml}{CFGUtil}
|
||||
(structure CFG : CONTROL_FLOW_GRAPH
|
||||
structure P : INSN_PROPERTIES
|
||||
sharing P.I = CFG.I
|
||||
) : CFG_UTIL
|
||||
\end{SML}
|
||||
|
||||
The signature of \sml{CFGUtil} is defined below:
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/mlrisc-cfg-util.sig}{CFG_UTIL} = sig
|
||||
structure CFG : CONTROL_FLOW_GRAPH
|
||||
val updateJumpLabel : CFG.cfg -> node_id -> unit
|
||||
val mergeEdge : CFG.cfg -> CFG.edge -> bool
|
||||
val eliminateJump : CFG.cfg -> node_id -> bool
|
||||
val insertJump : CFG.cfg -> node_id -> bool
|
||||
val splitEdge : CFG.cfg -> { edge : CFG.edge, jump : bool }
|
||||
-> { edge : CFG.edge, node : CFG.node }
|
||||
val isMerge : CFG.cfg -> node_id -> bool
|
||||
val isSplit : CFG.cfg -> node_id -> bool
|
||||
val hasSideExits : CFG.cfg -> node_id -> bool
|
||||
val isCriticalEdge : CFG.cfg -> CFG.edge -> bool
|
||||
val splitAllCriticalEdges : CFG.cfg -> unit
|
||||
val ceed : CFG.cfg -> node_id * node_id -> bool
|
||||
val tailDuplicate : CFG.cfg -> \{ subgraph : CFG.cfg, root : node_id \}
|
||||
-> \{ nodes : CFG.node list,
|
||||
edges : CFG.edge list \}
|
||||
val removeUnreachableCode : CFG.cfg -> unit
|
||||
val mergeAllEdges : CFG.cfg -> unit
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
These functions have the following meanings:
|
||||
\begin{itemize}
|
||||
\item \sml{updateJumpLabel} $G u$. This function
|
||||
updates the label of the branch instruction in a block $u$
|
||||
to be consistent with the control flow edges with source $u$.
|
||||
This is an nop if the CFG is already consistent.
|
||||
\item \sml{mergeEdge} $G e$. This function merges edge
|
||||
$e \equiv u \edge{} v$
|
||||
in the graph $G$ if possible. This is successful only if
|
||||
there are no other edges flowing into $v$ and no other edges
|
||||
flowing out from $u$. It returns true if the merge
|
||||
operation is successful. If successful, the nodes $u$ and $v$
|
||||
will be coalesced into the block $u$. The jump instruction (if any)
|
||||
in the node $u$ will also be elided.
|
||||
\item \sml{eliminateJump} $G u$. This function eliminate the
|
||||
jump instruction at the end of block $u$ if it is feasible.
|
||||
\item \sml{insertJump} $G u$. This function inserts a jump
|
||||
instruction in block $u$ if it is feasible.
|
||||
\item \sml{splitEdge} $G e$. This function
|
||||
split the control flow edge $e$, and return a new edge $e'$ and the
|
||||
new block $u$ as return values. It addition, it takes as
|
||||
argument a flag \sml{jump}. If this flag is true,
|
||||
then a jump instruction is always placed in the
|
||||
split; otherwise, we try to eliminate the jump when feasible.
|
||||
\item \sml{isMerge} $G u$. This function tests whether block $u$
|
||||
is a \newdef{merge} node. A merge node is a node that
|
||||
has two or more incoming flow edges.
|
||||
\item \sml{isSplit} $G u$. This function tests whether block $u$
|
||||
is a \newdef{split} node. A split node is a node that
|
||||
has two or more outgoing flow edges.
|
||||
\item \sml{hasSideExits} $G u$. This function tests whether
|
||||
a block has side exits $G$. This assumes that $u$
|
||||
is a hyperblock.
|
||||
\item \sml{isCriticalEdge} $G e$. This function tests whether
|
||||
the edge $e$ is a \newdef{critical} edge. The
|
||||
edge $e \equiv u \edge{} v$ is critical iff
|
||||
there are $u$ is merge node and $v$ is a split node.
|
||||
\item \sml{splitAllCriticalEdges} $G$. This function goes
|
||||
through the CFG $G$ and splits
|
||||
all critical edges in the CFG.
|
||||
This can introduce extra jumps and basic blocks in the program.
|
||||
\item \sml{mustPreceed} $G (u,v)$. This function
|
||||
checks whether two blocks $u$ and $v$ are necessarily adjacent.
|
||||
Blocks $u$ and $v$ must be adjacent iff $u$ must preceed $v$
|
||||
in any feasible code layout.
|
||||
\item \sml{tailDuplicate}.
|
||||
\begin{SML}
|
||||
val tailDuplicate : CFG.cfg -> \{ subgraph : CFG.cfg, root : node_id \}
|
||||
-> \{ nodes : CFG.node list,
|
||||
edges : CFG.edge list \}
|
||||
\end{SML}
|
||||
\begin{Figure}
|
||||
\begin{boxit}
|
||||
%\cpsfig{figure=../pictures/eps/tail-duplication.eps,width=3in}
|
||||
\begin{center}
|
||||
\includegraphics[width=3in]{../pictures/pdf/tail-duplication}
|
||||
\end{center}%
|
||||
\end{boxit}
|
||||
\label{fig:tail-duplication}
|
||||
\caption{Tail-duplication}
|
||||
\end{Figure}
|
||||
|
||||
This function tail-duplicates the region \sml{subgraph}
|
||||
until it only has a single entry \sml{root}.
|
||||
Return the set of new nodes and new edges.
|
||||
The region is represented as a subgraph view of the CFG.
|
||||
Figure~\ref{fig:tail-duplication} illustrates
|
||||
this transformation.
|
||||
|
||||
\item \sml{removeUnreachableCode} $G$. This function
|
||||
removes all unreachable code from the graph.
|
||||
\item \sml{mergeAllEdges} $G$. This function tries to merge all
|
||||
the edges in the flowgraph $G$. Merging is performed in the
|
||||
non-increasing order of edge frequencies.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Dataflow Analysis}
|
||||
MLRISC provides a simple customizable module for performing
|
||||
iterative dataflow analysis. A dataflow analyzer
|
||||
has the following signature:
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/dataflow.sig}{DATAFLOW_ANALYZER} = sig
|
||||
structure CFG : CONTROL_FLOW_GRAPH
|
||||
type dataflow_info
|
||||
val analyze : CFG.cfg * dataflow_info -> dataflow_info
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
A dataflow problem is described by the signature \sml{DATAFLOW_PROBLEM},
|
||||
described below:
|
||||
\begin{SML}
|
||||
signature \mlrischref{IR/dataflow.sig}{DATAFLOW_PROBLEM} = sig
|
||||
structure CFG : CONTROL_FLOW_GRAPH
|
||||
type domain
|
||||
type dataflow_info
|
||||
val forward : bool
|
||||
val bot : domain
|
||||
val == : domain * domain -> bool
|
||||
val join : domain list -> domain
|
||||
val prologue : CFG.cfg * dataflow_info ->
|
||||
CFG.block node ->
|
||||
\{ input : domain,
|
||||
output : domain,
|
||||
transfer : domain -> domain
|
||||
\}
|
||||
val epilogue : CFG.cfg * dataflow_info ->
|
||||
\{ node : CFG.block node,
|
||||
input : domain,
|
||||
output : domain
|
||||
\} -> unit
|
||||
end
|
||||
\end{SML}
|
||||
This description contains the following items
|
||||
\begin{itemize}
|
||||
\item \sml{type domain} is the abstract lattice domain $D$.
|
||||
\item \sml{type dataflow_info} is where the dataflow information
|
||||
is stored.
|
||||
\item \sml{forward} is true iff the dataflow problem is in the
|
||||
forward direction
|
||||
\item \sml{bot} is the bottom element of $D$.
|
||||
\item \sml{==} is the equality function on $D$.
|
||||
\item \sml{join} is the least-upper-bound function on $D$.
|
||||
\item \sml{prologue} is a user-supplied function that performs
|
||||
pre-processing and setup. For each CFG node $X$, this function
|
||||
computes
|
||||
\begin{itemize}
|
||||
\item \sml{input} -- which is the initial input value of $X$
|
||||
\item \sml{output} -- which is the initial output value of $X$
|
||||
\item \sml{transfer} -- which is the transfer function on $X$.
|
||||
\end{itemize}
|
||||
\item \sml{epilogue} is a function that performs post-processing.
|
||||
It visits each node $X$ in the flowgraph and return the resulting
|
||||
\sml{input} and \sml{output} value for $X$.
|
||||
\end{itemize}
|
||||
|
||||
To generate a new dataflow analyzer from a dataflow problem,
|
||||
the functor \sml{Dataflow} can be used:
|
||||
\begin{SML}
|
||||
functor \mlrischref{IR/dataflow.sml}{Dataflow}(P : DATAFLOW_PROBLEM) : DATAFLOW_ANALYZER =
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Static Branch Prediction}
|
||||
|
||||
\subsubsection{Branch Optimizations}
|
||||
@@ -0,0 +1,662 @@
|
||||
\section{Machine Description}
|
||||
\subsection{Overview}
|
||||
|
||||
\newdef{MDGen} is a simple tool for generating
|
||||
various modules in the MLRISC customizable code generator
|
||||
directly from machine descriptions. These descriptions
|
||||
contain architectural information such as:
|
||||
\begin{enumerate}
|
||||
\item How the the register file(s) are organized.
|
||||
\item How instructions are encoded in machine code: MLRISC uses
|
||||
this information to generate machine instructions directly into a byte stream.
|
||||
Directly machine code generation is used in the SML/NJ compiler.
|
||||
\item How instructions are pretty printed in assembly: this is used
|
||||
for debugging and also for assembly output for other non-SML/NJ backends.
|
||||
\item How instructions are internally represented in MLRISC.
|
||||
\item Other information needed for performing optimizations, which
|
||||
include:
|
||||
\begin{enumerate}
|
||||
\item The register transfer list (RTL) that defines the
|
||||
operational semantics of the instruction.
|
||||
\item Delay slot mechanisms.
|
||||
\item Information for performing span dependency resolution.
|
||||
\item Pipeline and reservation table characteristics.
|
||||
\end{enumerate}
|
||||
\end{enumerate}
|
||||
|
||||
Currently, item 5 is not ready for prime time.
|
||||
|
||||
\subsubsection{Why MDGen?}
|
||||
MLRISC manipulates all instruction sets via a set of abstract
|
||||
interfaces, which allows the programmer to arbitrarily choose an
|
||||
instruction representation that is most convenient for a particular
|
||||
architecture. However, various functions that manipulate
|
||||
this representation must be provided by the instruction set's programmer.
|
||||
As the number and complexities of each optimizations grow, and as
|
||||
the number of architectures increases, the functions
|
||||
for manipulating the instructions become more numerous and complex.
|
||||
In order to keep the effort of developing and maintaining
|
||||
an instruction set manageable,
|
||||
the MDGen tool is developed to (partially) automate this task.
|
||||
|
||||
\subsubsection{Syntax}
|
||||
|
||||
MDGen's machine descriptions are written in a syntax that is very
|
||||
much like that of
|
||||
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/sml.html}{Standard ML}.
|
||||
Most core SML constructs are recognized.
|
||||
In addition, new declaration forms specific to MDGen are
|
||||
used to specify architectural information.
|
||||
|
||||
\paragraph{Reserved Words}
|
||||
All SML keywords are reserved words in MDGen.
|
||||
In addition, the following keywords are also reserved:
|
||||
|
||||
\begin{verbatim}
|
||||
always architecture assembly at backwards big bits branching called
|
||||
candidate cell cells cellset debug delayslot dependent endian field
|
||||
fields formats forwards instruction internal little locations lowercase
|
||||
name never nodelayslot nullified opcode ordering padded pipeline predicated
|
||||
register rtl signed span storage superscalar unsigned uppercase
|
||||
verbatim version vliw when
|
||||
\end{verbatim}
|
||||
|
||||
Two kinds are quotations marks are also reserved:
|
||||
\begin{SML}
|
||||
[[ ]]
|
||||
`` ''
|
||||
\end{SML}
|
||||
|
||||
The first \sml{[[ ]]} is for describing semantics. The
|
||||
second \sml{`` ''} is for describing assembly syntax.
|
||||
|
||||
\paragraph{Syntactic Sugar}
|
||||
|
||||
MDGen recognizes the following syntactic sugar.
|
||||
\begin{description}
|
||||
\item[Record abbreviations]
|
||||
Record expressions such as \sml{{x=x,y=y,z=z}}
|
||||
can be simplified to just \sml{{x,y,z}}.
|
||||
\item[Binary literals]
|
||||
Literals in binary can be written with the prefix \sml{0b} (for integer types)
|
||||
or \sml{0wb} (for word types). For example, \sml{0wb101111} is the same
|
||||
as \sml{0wx2f} and \sml{0w79}.
|
||||
\item[Bit slices]
|
||||
A bit slice, which extracts a range of bits from a word, can be written
|
||||
using an \sml{at} expression. For example, \sml{w at [16..18]}
|
||||
means the same thing as \verb|Word32.andb(Word32.>>(w, 0w16),0w7)|, i.e.
|
||||
it extracts bit 16 to 18 from \sml{w}.
|
||||
The least significant bit the zeroth bit.
|
||||
|
||||
In general, we can write:
|
||||
\begin{SML}
|
||||
w at [range1, range2, ..., rangen]
|
||||
\end{SML}
|
||||
to extract a sequence of slices from $w$ and concatenate them together.
|
||||
For example, the expression
|
||||
\begin{SML}
|
||||
0wxabcd at [0..3, 4..7, 8..11, 12..15]
|
||||
\end{SML}
|
||||
swap the 4 nybbles from the 16-bit word, and evaluates to \sml{0wxdcba}.
|
||||
|
||||
\item[Signature]
|
||||
Signature declarations of the form
|
||||
\begin{SML}
|
||||
val x y z : int -> int
|
||||
\end{SML}
|
||||
can be used as a shorthand for the more verbose:
|
||||
\begin{SML}
|
||||
val x : int -> int
|
||||
val y : int -> int
|
||||
val z : int -> int
|
||||
\end{SML}
|
||||
\end{description}
|
||||
|
||||
\subsubsection{Elaboration Semantics}
|
||||
|
||||
Unfortunately, there is no complete formal semantics of how
|
||||
an MDGen specification elaborates.
|
||||
But generally speaking, a machine description is a just a structure
|
||||
(in the SML sense). Different components of this structure describe
|
||||
different aspects of the architecture.
|
||||
|
||||
\paragraph{Syntactic Overloading}
|
||||
In general, the syntactic overloading are used heavily in MDGen.
|
||||
There are three types of definitions:
|
||||
\begin{itemize}
|
||||
\item Definitions that defines properties of the instruction set.
|
||||
\item Definitions of functions and terms that are in the RTL meta-language.
|
||||
The syntax of MDGen's RTL language is borrowed heavily from Lambda-RTL,
|
||||
which in turns is borrowed heavily from SML.
|
||||
\item Definitions of functions and types that are to be included in the
|
||||
output generated by the MDGen tool. These are usually auxiliary
|
||||
helper functions and definitions.
|
||||
\end{itemize}
|
||||
In general, entities of type 2, when appearing in other context, are
|
||||
properly meta-quoted in the semantics quotations \sml{[[ ]]}.
|
||||
|
||||
\subsubsection{Basic Structure of A Machine Description}
|
||||
|
||||
The machine description for an architecture are defined via
|
||||
an \sml{architecture} declaration, which has the following general
|
||||
form.
|
||||
|
||||
\begin{SML}
|
||||
architecture name =
|
||||
struct
|
||||
\Term{architecture type declaration}
|
||||
\Term{endianess declaration}
|
||||
\Term{storage class declarations}
|
||||
\Term{locations declarations}
|
||||
\Term{assembly case declarations}
|
||||
\Term{delayslot declaration}
|
||||
\Term{instruction machine encoding format declarations}
|
||||
\Term{nested structure declarations}
|
||||
\Term{instruction definition}
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
\subsection{Describing the Architecture}
|
||||
|
||||
\subsubsection{Architecture type}
|
||||
Architecture type declaration specifies whether the architecture is
|
||||
a superscalar or a VLIW/EPIC machine. Currently, this information is
|
||||
ignored.
|
||||
|
||||
\begin{SML}
|
||||
\Term{architecture type declaration} ::= superscalar | vliw
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Storage class}
|
||||
|
||||
Storage class declarations specify various information about the
|
||||
registers in the architecture. For example, the Alpha has 32 general
|
||||
purpose registers and 32 floating point registers. In addition, MLRISC
|
||||
requires that each architecture specifies a (pseudo) register
|
||||
type\footnote{Called cellkind in MLRISC.} for
|
||||
holding condition codes (\sml{CC}).
|
||||
To specify these information in MDGen, we can say:
|
||||
|
||||
\begin{SML}
|
||||
storage
|
||||
GP "r" = 32 cells of 64 bits in cellset called "register"
|
||||
assembly as (fn (30,_) => "$sp"
|
||||
| (r,_) => "$"^Int.toString r
|
||||
)
|
||||
| FP "f" = 32 cells of 64 bits in cellset called "floating point register"
|
||||
assembly as (fn (f,_) => "$f"^Int.toString f)
|
||||
| CC "cc" = cells of 64 bits in cellset GP called "condition code register"
|
||||
assembly as "cc"
|
||||
\end{SML}
|
||||
|
||||
\begin{itemize}
|
||||
\item There are 32 64-bit general purpose registers,
|
||||
32 64-bit floating point registers, while \sml{CC} is not a
|
||||
real register type.
|
||||
\item Cellsets
|
||||
are used by MLRISC for annotating liveness information in the program.
|
||||
The clause \sml{in cellset} states that register type \sml{GP}
|
||||
and \sml{FP} are allotted their own components in the cellset,
|
||||
while the register type \sml{CC} are put
|
||||
in the same cellset component as \sml{GP}.
|
||||
\item The clause \sml{assembly as} specifies
|
||||
how each register is to be pretty printed. On the Alpha, general
|
||||
purpose register are pretty printed with prefix \sml{$}, while
|
||||
floating point registers are pretty printed with the prefix \sml{$f}.
|
||||
A special case is made for register 30, which is the stack pointer, and
|
||||
is pretty printing as \sml{$sp}. Pseudo condition code registers
|
||||
are pretty printed with the prefix \sml{cc}.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Locations}
|
||||
|
||||
Special locations in the register files can be declared using the
|
||||
\sml{locations} declarations. On the Alpha, GPR
|
||||
30 is the stack pointer, GPR 28 and floating point register 30
|
||||
are used as the assembly temporaries. This special constants
|
||||
can be defined as follows:
|
||||
|
||||
\begin{SML}
|
||||
locations
|
||||
stackptrR = $GP[30]
|
||||
and asmTmpR = $GP[28]
|
||||
and fasmTmp = $FP[30]
|
||||
\end{SML}
|
||||
|
||||
\subsection{Specifying the Machine Encoding}
|
||||
\subsubsection{Endianess}
|
||||
|
||||
The endianess declaration specifies whether the machine is little
|
||||
endian or big endian so that the correct machine instruction encoding
|
||||
functions can be generated. The general syntax of this is:
|
||||
|
||||
\begin{SML}
|
||||
\Term{endianess declaration} ::= little endian | big endian
|
||||
\end{SML}
|
||||
|
||||
The Alpha is little endian, so we just say:
|
||||
\begin{SML}
|
||||
little endian
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Defining New Instruction Formats}
|
||||
|
||||
How instructions are encoded are specified using
|
||||
\sml{instruction format} declarations. An instruction format declaration
|
||||
has the following syntax:
|
||||
\begin{SML}
|
||||
\Term{instruction machine encoding format declarations} ::=
|
||||
instruction formats n bits
|
||||
\Term{format}1
|
||||
| \Term{format}2
|
||||
| \Term{format}3
|
||||
| ...
|
||||
| \Term{format}n-1
|
||||
| \Term{format}n
|
||||
\end{SML}
|
||||
|
||||
Each encoding format can be a primitive format, or a derived format.
|
||||
|
||||
\paragraph{Primitive formats}
|
||||
|
||||
A primitive format is simply specified by giving it a name and specifying
|
||||
the position, names and types of its fields. This is usually the same
|
||||
way it is described in a architectural reference manual.
|
||||
|
||||
|
||||
Here is how we specify some of the (32 bit) primitive instruction formats
|
||||
used in the Alpha.
|
||||
\begin{SML}
|
||||
instruction formats 32 bits
|
||||
Memory\{opc:6, ra:5, rb:GP 5, disp: signed 16\}
|
||||
| Jump\{opc:6=0wx1a,ra:GP 5,rb:GP 5,h:2,disp:int signed 14\}
|
||||
| Memory_fun\{opc:6, ra:GP 5, rb:GP 5, func:16\}
|
||||
| Branch\{opc:branch 6, ra:GP 5, disp:signed 21\}
|
||||
| Fbranch\{opc:fbranch 6, ra:FP 5, disp:signed 21\}
|
||||
| Operate0\{opc:6,ra:GP 5,rb:GP 5,sbz:13..15=0,_:1=0,func:5..11,rc:GP 5\}
|
||||
| Operate1\{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5\}
|
||||
\end{SML}
|
||||
|
||||
For example, the format \sml{Memory}
|
||||
\begin{SML}
|
||||
Memory\{opc:6, ra:5, rb:GP 5, disp: signed 16\}
|
||||
\end{SML}
|
||||
has a 6-bit opcode field, a 5-bit \sml{ra} field, a 5-bit \sml{rb}
|
||||
field which always hold a general purpose register, and a 16-bit
|
||||
sign-extended displacement field. The field to the left is positioned
|
||||
at the most significant bits, while the field to the right is positioned
|
||||
at the least. The widths of these fields must add up to 32 bits.
|
||||
|
||||
|
||||
Similarly, the format \sml{Jump}
|
||||
\begin{SML}
|
||||
Jump{opc:6=0wx1a,ra:GP 5,rb:GP 5,h:2,disp:int signed 14}
|
||||
\end{SML}
|
||||
contains a 6-bit opcode field which always hold the constant \sml{0x1a},
|
||||
two 5-bit fields \sml{ra} and \sml{rb} which are of type \sml{GP},
|
||||
and a 14-bit sign-extended field of type integer.
|
||||
|
||||
Each field in a primitive format has one of 5 forms:
|
||||
\begin{SML}
|
||||
\Term{name} : \Term{position}
|
||||
\Term{name} : \Term{position} = \Term{value}
|
||||
\Term{name} : \Term{type} \Term{position}
|
||||
\Term{name} : \Term{type} \Term{position} = \Term{value}
|
||||
_ : \Term{position} = \Term{value}
|
||||
\end{SML}
|
||||
where \Term{position} is either a width, or a bits range
|
||||
$n$\sml{..}$m$,
|
||||
with an optional \sml{signed} prefix. The last form, with a wild card
|
||||
for the field name, can be used to specify an anonymous field that
|
||||
always has a fixed value.
|
||||
|
||||
|
||||
By default, a field has type \sml{Word32.word}. If a type $T$
|
||||
is specified, then the function \sml{emit_}$T$ is implicitly called
|
||||
to convert the type into the appropriate encoding. The function
|
||||
\sml{emit_}$T$ are generated automatically by MDGen if it is a cellkind
|
||||
defined by the \sml{storage} class declaration, or if it is a primitive
|
||||
type such as integer or boolean.
|
||||
There are also other ways to automatically generate this function
|
||||
(more on this later.)
|
||||
|
||||
For example, the format \sml{Operate1}
|
||||
\begin{SML}
|
||||
Operate1\{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5\}
|
||||
\end{SML}
|
||||
states that bits 26 to 31 are allocated to field \sml{opc},
|
||||
bits 21 to 25 are allocated to field \sml{ra}, which is of type
|
||||
\sml{GP}, bits 13 to 20 are allocated to field \sml{lit}, bit 12
|
||||
is a single bit of value 1, etc.
|
||||
|
||||
|
||||
MDGen generates a function for each primitive format declaration of
|
||||
the same name that can be used for emitting the instruction.
|
||||
In the case of the Alpha, the following functions are generated:
|
||||
\begin{SML}
|
||||
val Memory : \{opc:Word32.word, ra:Word32.word,
|
||||
rb:int, disp:Word32.word\} -> unit
|
||||
val Jump : \{ra:int, rb:int, disp:Word32.word\} -> unit
|
||||
val Operate1 : \{opc:Word32.word, ra:int, lit:Word32.word,
|
||||
func:Word32.word, rc:int\} -> unit
|
||||
\end{SML}
|
||||
|
||||
\paragraph{Derived formats}
|
||||
|
||||
Derived formats are simply instruction formats that are defined
|
||||
in terms of other formats. On the alpha, we have a \sml{Operate}
|
||||
format that simplifies to either \sml{Operate0} or \sml{Operate1},
|
||||
depending on whether the second argument is a literal or a register.
|
||||
\begin{SML}
|
||||
Operate\{opc,ra,rb,func,rc\} =
|
||||
(case rb of
|
||||
I.REGop rb => Operate0\{opc,ra,rb,func,rc\}
|
||||
| I.IMMop i => Operate1\{opc,ra,lit=itow i,func,rc\}
|
||||
| I.HILABop le => Operate1\{opc,ra,lit=High{le=le},func,rc\}
|
||||
| I.LOLABop le => Operate1\{opc,ra,lit=Low{le=le},func,rc\}
|
||||
| I.LABop le => Operate1\{opc,ra,lit=itow(LabelExp.valueOf le),func,rc\}
|
||||
)
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Generating Encoding Functions}
|
||||
|
||||
In MLRISC, we represent an instruction as a set of ML datatypes.
|
||||
Some of these datatypes represent specific fields or
|
||||
opcodes of the instructions.
|
||||
MDGen lets us to associate a machine encoding to each datatype constructor
|
||||
directly in the specification, and automatically generates an
|
||||
encoding function for these datatypes.
|
||||
|
||||
There are two different ways of specifying an encoding. The first way
|
||||
is just to write the machine encoding directly next the constructor.
|
||||
Here's an example directly from the Alpha description:
|
||||
\begin{SML}
|
||||
structure Instruction =
|
||||
struct
|
||||
datatype branch! = (* table C-2 *)
|
||||
BR 0x30
|
||||
| BSR 0x34
|
||||
| BLBC 0x38
|
||||
| BEQ 0x39 | BLT 0x3a | BLE 0x3b
|
||||
| BLBS 0x3c | BNE 0x3d | BGE 0x3e
|
||||
| BGT 0x3f
|
||||
|
||||
datatype fbranch! = (* table C-2 *)
|
||||
FBEQ 0x31 | FBLT 0x32
|
||||
| FBLE 0x33 | FBNE 0x35
|
||||
| FBGE 0x36 | FBGT 0x37
|
||||
|
||||
...
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The datatypes \sml{branch} and \sml{fbranch} represent specific
|
||||
branch opcodes for integer branches \sml{BRANCH}, or floating point
|
||||
branches \sml{FBRANCH}. On the Alpha, instruction \sml{BR} is encoded
|
||||
with an opcode of \sml{0x30}, instruction \sml{BSR} is encoded
|
||||
as \sml{0x34} etc. MDGen automatically generates two functions
|
||||
\begin{SML}
|
||||
val emit_branch : branch -> Word32.word
|
||||
val emit_fbranch : branch -> Word32.word
|
||||
\end{SML}
|
||||
that perform this encoding.
|
||||
|
||||
In the specification for the instruction set, we state that the
|
||||
\sml{BRANCH} instruction should be encoded using format \sml{Branch},
|
||||
while the \sml{FBRANCH} instruction should be encoded using
|
||||
format \sml{Fbranch}.
|
||||
\begin{SML}
|
||||
structure MC =
|
||||
struct
|
||||
(* Auxiliary function for computing the displacement of a label *)
|
||||
fun disp ... = ...
|
||||
...
|
||||
end
|
||||
|
||||
...
|
||||
|
||||
instruction
|
||||
...
|
||||
|
||||
| BRANCH of branch * $GP * Label.label
|
||||
Branch\{opc=branch,ra=GP,disp=disp label\}
|
||||
|
||||
| FBRANCH of fbranch * $FP * Label.label
|
||||
Fbranch\{opc=fbranch,ra=FP,disp=disp label\}
|
||||
|
||||
| ...
|
||||
\end{SML}
|
||||
|
||||
Since the primitive instructions formats \sml{Branch} and \sml{FBranch}
|
||||
are defined with branch and fbranch as the type in the opcode field
|
||||
\begin{SML}
|
||||
| Branch\{opc:branch 6, ra:GP 5, disp:signed 21\}
|
||||
| Fbranch\{opc:fbranch 6, ra:FP 5, disp:signed 21\}
|
||||
\end{SML}
|
||||
the functions \sml{emit_branch} and \sml{emit_fbranch} are implicitly
|
||||
called.
|
||||
|
||||
|
||||
Another way to specify an encoding is to specify a range, as
|
||||
in the following example:
|
||||
\begin{SML}
|
||||
datatype fload[0x20..0x23]! = LDF | LDG | LDS | LDT
|
||||
|
||||
datatype fstore[0x24..0x27]! = STF | STG | STS | STT
|
||||
\end{SML}
|
||||
|
||||
This states that \sml{LDF} should be assigned the encoding \sml{0x20},
|
||||
\sml{LDG} the encoding \sml{0x21} etc. This form is useful for
|
||||
specifying a consecutive range.
|
||||
|
||||
\subsubsection{Encoding Variable Length Instructions}
|
||||
|
||||
Most architectures nowadays have fixed length encodings for instructions.
|
||||
There are some notatable exceptions, however.
|
||||
The Intel x86 architecture uses a legacy
|
||||
variable length encoding. Modern RISC machines developed for
|
||||
embedded systems may utilize space-reduction compression schemes in their
|
||||
instruction sets. Finally, VLIW machines usually have some form
|
||||
of NOP compression scheme for compacting issue packets.
|
||||
|
||||
\subsection{Specifying the Assembly Formats}
|
||||
|
||||
\subsubsection{Assembly Case Declaration}
|
||||
|
||||
The assembly case declaration specifies whether the assembly should be
|
||||
emitted in lower case, upper case, or verbatim. If either lower case
|
||||
or upper case is specified, all literal strings are converted to the
|
||||
appropriate case. The general syntax of this declaration is:
|
||||
|
||||
\begin{SML}
|
||||
\Term{assembly case declaration} ::=
|
||||
lowercase assembly
|
||||
| uppercase assembly
|
||||
| verbatim assembly
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Assembly Annotations}
|
||||
|
||||
Assembly output are specified in the assembly meta quotations
|
||||
\sml{`` ''}, or string quotations \sml{" "}.
|
||||
For example, here is a fragment from the Alpha description:
|
||||
|
||||
\begin{SML}
|
||||
instruction
|
||||
...
|
||||
| LOAD of \{ldOp:load, r: $GP, b: $GP, d:operand, mem:Region.region\}
|
||||
``<ldOp>\t<r>, <d>()<mem>''
|
||||
|
||||
| STORE of \{stOp:store, r: $GP, b: $GP, d:operand, mem:Region.region\}
|
||||
``<stOp>\t<r>, <d>()<mem>''
|
||||
|
||||
| BRANCH of branch * $GP * Label.label
|
||||
``<branch>\t<GP>, <label>''
|
||||
|
||||
| FBRANCH of fbranch * $FP * Label.label
|
||||
``<fbranch>\t<FP>, <label>''
|
||||
|
||||
| CMOVE of \{oper:cmove, ra: $GP, rb:operand, rc: $GP\}
|
||||
``<oper>\t<ra>, <rb>, <rc>''
|
||||
|
||||
| FOPERATE of \{oper:foperate, fa: $FP, fb: $FP, fc: $FP\}
|
||||
``<oper>\t<fa>, <fb>, <fc>''
|
||||
|
||||
| ...
|
||||
\end{SML}
|
||||
|
||||
All characters within the quotations \sml{`` ''} have the same
|
||||
interpretation as in the string quotation \sml{" "}, except when
|
||||
they are delimited by the \newdef{backquotes}
|
||||
\verb|< >|.
|
||||
Here's how the backquote is interpreted:
|
||||
\begin{itemize}
|
||||
\item If it is \verb|<|$x$\verb.>. and $x$ is a variable name of type $t$,
|
||||
and if an assembly function of type $t$ is defined, then it will be invoked
|
||||
to convert $x$ to the appropriate text.
|
||||
\item If it is \verb|<|$x$\verb.>. and $x$ is a variable name of type $t$,
|
||||
and if an assembly function of type $t$ is NOT defined,
|
||||
then the function \sml{emit_}$x$ will be called to pretty print $x$.
|
||||
\item If it is \verb|<|$e$\verb.>. where $e$ is a general expression, then
|
||||
it will be used directly.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Generating Assembly Functions}
|
||||
Similar to machine encodings, we can attach assembly annotations to
|
||||
datatype definitions and let MDGen generate the assembly functions for us.
|
||||
Annotations take two forms, explicit or implicit.
|
||||
Explicit annotations are enclosed within assembly quotations \sml{`` ''}.
|
||||
|
||||
|
||||
For example, on the Alpha the datatype \sml{operand} is used to represent
|
||||
an integer operand. This datatype is defined as follows:
|
||||
\begin{SML}
|
||||
datatype operand =
|
||||
REGop of $GP ``<GP>''
|
||||
| IMMop of int ``<int>''
|
||||
| HILABop of LabelExp.labexp ``hi(<labexp>)''
|
||||
| LOLABop of LabelExp.labexp ``lo(<labexp>)''
|
||||
| LABop of LabelExp.labexp ``<labexp>''
|
||||
| CONSTop of Constant.const ``<const>''
|
||||
\end{SML}
|
||||
Basicaly this states that \sml{REGop r} should be pretty printed
|
||||
as \sml{$r}, \sml{IMMop i}
|
||||
as \sml{i}, \sml{HILABexp le}
|
||||
as \sml{hi(le)},
|
||||
etc.
|
||||
|
||||
Implicit assembly annotations are specified by simply attaching
|
||||
an exclamation mark at the end of the datatype name. This states
|
||||
that the assembly output is the same as the name of the datatype
|
||||
constructor\footnote{But appropriately modified by the assembly case
|
||||
declaration.}. For example,
|
||||
the datatype \sml{operate} is a listing of all integer opcodes
|
||||
used in MLRISC.
|
||||
\begin{SML}
|
||||
datatype operate! = (* table C-5 *)
|
||||
ADDL (0wx10,0wx00) | ADDQ (0wx10,0wx20)
|
||||
| CMPBGE(0wx10,0wx0f) | CMPEQ (0wx10,0wx2d)
|
||||
| CMPLE (0wx10,0wx6d) | CMPLT (0wx10,0wx4d) | CMPULE (0wx10,0wx3d)
|
||||
| CMPULT(0wx10,0wx1d) | SUBL (0wx10,0wx09)
|
||||
| SUBQ (0wx10,0wx29)
|
||||
| S4ADDL(0wx10,0wx02) | S4ADDQ (0wx10,0wx22) | S4SUBL (0wx10,0wx0b)
|
||||
| S4SUBQ(0wx10,0wx2b) | S8ADDL (0wx10,0wx12) | S8ADDQ (0wx10,0wx32)
|
||||
| S8SUBL(0wx10,0wx1b) | S8SUBQ (0wx10,0wx3b)
|
||||
|
||||
| AND (0wx11,0wx00) | BIC (0wx11,0wx08) | BIS (0wx11,0wx20)
|
||||
| EQV (0wx11,0wx48)
|
||||
| ORNOT (0wx11,0wx28) | XOR (0wx11,0wx40)
|
||||
|
||||
| EXTBL (0wx12,0wx06) | EXTLH (0wx12,0wx6a) | EXTLL(0wx12,0wx26)
|
||||
| EXTQH (0wx12,0wx7a) | EXTQL (0wx12,0wx36) | EXTWH(0wx12,0wx5a)
|
||||
| EXTWL (0wx12,0wx16) | INSBL (0wx12,0wx0b) | INSLH(0wx12,0wx67)
|
||||
| INSLL (0wx12,0wx2b) | INSQH (0wx12,0wx77) | INSQL(0wx12,0wx3b)
|
||||
| INSWH (0wx12,0wx57) | INSWL (0wx12,0wx1b) | MSKBL(0wx12,0wx02)
|
||||
| MSKLH (0wx12,0wx62) | MSKLL (0wx12,0wx22) | MSKQH(0wx12,0wx72)
|
||||
| MSKQL (0wx12,0wx32) | MSKWH (0wx12,0wx52) | MSKWL(0wx12,0wx12)
|
||||
| SLL (0wx12,0wx39) | SRA (0wx12,0wx3c) | SRL (0wx12,0wx34)
|
||||
| ZAP (0wx12,0wx30) | ZAPNOT (0wx12,0wx31)
|
||||
| MULL (0wx13,0wx00) | MULQ (0wx13,0wx20)
|
||||
| UMULH (0wx13,0wx30)
|
||||
| SGNXL "addl" (0wx10,0wx00) (* same as ADDL *)
|
||||
\end{SML}
|
||||
This definitions states that \sml{ADDL} should be pretty printed
|
||||
as \sml{addl}, \sml{ADDQ} as \sml{addq}, etc. However, the opcode
|
||||
\sml{SGNXL} is pretty printed as \sml{addl} since it has been explicitly
|
||||
overridden.
|
||||
|
||||
\subsection{Defining the Instruction Set}
|
||||
|
||||
How the instruction set is represented is declared using the
|
||||
\sml{instruction} declaration. For example, here's how the Alpha instruction
|
||||
set is defined:
|
||||
\begin{SML}
|
||||
instruction
|
||||
DEFFREG of $FP
|
||||
| LDA of \{r: $GP, b: $GP, d:operand\}
|
||||
| LDAH of \{r: $GP, b: $GP, d:operand\}
|
||||
| LOAD of \{ldOp:load, r: $GP, b: $GP, d:operand, mem:Region.region\}
|
||||
| STORE of \{stOp:store, r: $GP, b: $GP, d:operand, mem:Region.region\}
|
||||
| FLOAD of \{ldOp:fload, r: $FP, b: $GP, d:operand, mem:Region.region\}
|
||||
| FSTORE of \{stOp:fstore, r: $FP, b: $GP, d:operand, mem:Region.region\}
|
||||
| JMPL of \{r: $GP, b: $GP, d:int\} * Label.label list
|
||||
| JSR of \{r: $GP, b: $GP, d:int\} * C.cellset * C.cellset * Region.region
|
||||
| RET of \{r: $GP, b: $GP, d:int\}
|
||||
| BRANCH of branch * $GP * Label.label
|
||||
| FBRANCH of fbranch * $FP * Label.label
|
||||
| ...
|
||||
\end{SML}
|
||||
|
||||
The \sml{instruction} declaration defines a datatype and specifies
|
||||
that this datatype is used to represent the instruction set. Generally
|
||||
speaking, the instruction set's designer has complete freedom in how the
|
||||
datatype is structured, but there are a few simple rules that she should
|
||||
follow:
|
||||
\begin{itemize}
|
||||
\item If a field represents a register, it should be typed
|
||||
with the appropriate storage types \sml{$GP},
|
||||
\sml{$FP}, etc.~instead
|
||||
of \sml{int}. MDGen will treat its value in the correct manner; for
|
||||
example, during assembly emission a field declared type \sml{int} is
|
||||
printed as an integer, while a field declared type \sml{$GP} is displayed
|
||||
as a general purpose register.
|
||||
\item MDGen recognizes the following special
|
||||
types: \sml{label}, \sml{labexp}, \sml{region}, and \sml{cellset}.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Specifying Instruction Semantics}
|
||||
MLRISC performs all optimizations at
|
||||
the granulariy of individual instructions,
|
||||
specialized to the architecture at hand. Many
|
||||
optimizations are possible only if the ``semantics'' of the
|
||||
instructions set to are properly specified. MDGen contains a
|
||||
\emph{register transfer language} (RTL) sub-language that let us to describe
|
||||
instruction semantics in a modular and succinct manner.
|
||||
|
||||
The semantics of this RTL sub-language has been borrowed heavily from
|
||||
Norman Ramsey's and Jack Davidson's Lambda RTL. There
|
||||
are a few main differences, however:
|
||||
\begin{itemize}
|
||||
\item The syntax of our RTL language
|
||||
is closer to that of ML than Lambda RTL.
|
||||
\item Our RTL language, like that of MDGen, is tied closely to MLRISC.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{How to Run the Tool}
|
||||
|
||||
\subsection{Machine Description}
|
||||
Here are some machine descriptions in varing degree of completion.
|
||||
|
||||
\begin{itemize}
|
||||
\item \mlrischref{sparc/sparc.mdl}{Sparc}
|
||||
\item \mlrischref{hppa/hppa.mdl}{Hppa}
|
||||
\item \mlrischref{alpha/alpha.mdl}{Alpha}
|
||||
\item \mlrischref{ppc/ppc.mdl}{PowerPC}
|
||||
\item \mlrischref{x86/x86.mdl}{X86}
|
||||
\end{itemize}
|
||||
|
||||
\subsection{ Syntax Highlighting Macros }
|
||||
|
||||
\begin{itemize}
|
||||
\item \href{md.vim}{For vim 5.3}
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,94 @@
|
||||
\section{Register Allocation}
|
||||
All the optimization modules are written in a generic fashion but
|
||||
parameterized over architecture and client information. The Standard
|
||||
ML module system is a central mechanism to the design and
|
||||
organization of MLRISC. Parameterized modules in Standard ML are
|
||||
provided by \newdef{functors}, that takes the
|
||||
specification of input modules and produces a module that matches some
|
||||
output specification. In particular, SML/NJ modules are
|
||||
\emph{higher order}, which means that a functor can yield functors as a
|
||||
result. I will use register allocation as an example.
|
||||
|
||||
\image{Back end optimizations}{pictures/png/hof-1.png}{align=left}
|
||||
|
||||
The register allocator is written has a higher order functor which
|
||||
when applied to suitable arguments produces an integer or floating
|
||||
point register allocator. The figure is simplifed because the output
|
||||
functor is not restricted to integer and floating point allocators
|
||||
but could also be other types of allocators, for example, condition
|
||||
code. The integer and floating point register allocators are
|
||||
functors that only take \emph{client specific} parameters as
|
||||
input, whereas the higher-order takes architectural parameters as
|
||||
input. The client specific parameters include:
|
||||
\begin{SML}
|
||||
nFreeRegs : int
|
||||
dedicated : int list
|
||||
spill : ..
|
||||
reload : ..
|
||||
\end{SML}
|
||||
|
||||
where:
|
||||
\begin{description}
|
||||
\item[\sml{nFreeRegs}] is the number of free registers or
|
||||
essentially the number of colors available for coloring the
|
||||
interference graph.
|
||||
|
||||
\item[\sml{dedicated}] is the list of dedicated registers. It
|
||||
is useful to exclude these from the graph-color process to reduce
|
||||
the size of the data structures created.
|
||||
|
||||
\item[\sml{spill/reload}] are functions that describe how to
|
||||
spill and reload registers that need to be spilled or reloaded in
|
||||
an instruction. These two functions are perhaps the most
|
||||
complicated pieces of information that need to be supplied by a
|
||||
client of MLRISC.
|
||||
\end{description}
|
||||
|
||||
The architecture specific parameters supplied to the higher-order
|
||||
functor include:
|
||||
\begin{SML}
|
||||
firstPseudoReg : int
|
||||
maxPseudoR : unit -> int
|
||||
defUse : instruction -> (int list * int list)
|
||||
\end{SML}
|
||||
|
||||
where:
|
||||
\begin{description}
|
||||
\item[\sml{firstPseudoR}] is an integer representing the first
|
||||
pseudo register. Any register below this value is a physical
|
||||
register.
|
||||
|
||||
\item[\sml{maxPseudoR}] is a function that returns an
|
||||
integer indicating the number of the highest pseudo-register that
|
||||
has been used in the program. This number is useful in estimating
|
||||
the intial size of various tables.
|
||||
|
||||
\item[\sml{defUse}] is a function that returns the
|
||||
registers defined and used by an instruction.
|
||||
\end{description}
|
||||
|
||||
These parameters are largely self explanatory, however, there are
|
||||
addition architectural parameters that relate to the internal
|
||||
representation of instructions that would be ugly to explain. For
|
||||
example there is the need for a module that does liveness analysis
|
||||
over the register class that is being allocated. This type of
|
||||
complexity can be shielded from a user. For the DEC Alpha the
|
||||
situation is as shown in the figure:
|
||||
|
||||
\image{Back end optimizations}{pictures/png/hof-2.png}{align=center}
|
||||
|
||||
The client only sees the functors on the right, to which only client
|
||||
specific information need be provided. There is the illusion of a
|
||||
dedicated DEC Alpha integer and floating point register
|
||||
allocator. There are several advantages to this:
|
||||
\begin{itemize}
|
||||
\item The architectural parameters that are implementation specific
|
||||
do not need to be explained to a user, and are supplied by someone
|
||||
that intimately understands the port to the target architecture.
|
||||
|
||||
\item The number of parameters that a client supplies is
|
||||
reduced.
|
||||
|
||||
\item The parameters that the client supplies is restricted to
|
||||
things that concern the front end.
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,150 @@
|
||||
\documentclass{article}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{mltex}
|
||||
\usepackage{wrapfig}
|
||||
\usepackage{float}
|
||||
\usepackage{alltt}
|
||||
%\usepackage{floatfig}
|
||||
\usepackage{fancyheadings}
|
||||
%\usepackage{draftcopy}
|
||||
%\usepackage{bookman}
|
||||
\usepackage{utopia}
|
||||
%\usepackage{times}
|
||||
%\usepackage{ncntrsbk}
|
||||
%\usepackage{palatino}
|
||||
|
||||
\setlength{\textwidth}{6.5in}
|
||||
\setlength{\evensidemargin}{0in}
|
||||
\setlength{\oddsidemargin}{0in}
|
||||
\setlength{\textheight}{8in}
|
||||
\setlength{\topmargin}{-0.5in}
|
||||
|
||||
\pagestyle{fancyplain}
|
||||
%\addtolength{\headwidth}{\marginparsep}
|
||||
%\addtolength{\headwidth}{\marginparwidth}
|
||||
|
||||
\newcommand{\edge}[1]{\rightarrow_{#1}}
|
||||
\newcommand{\union}{\cup}
|
||||
\newcommand{\Union}{\bigcup}
|
||||
\newcommand{\overrides}{overrides}
|
||||
\newcommand{\defas}{\stackrel{\rm as}{=}}
|
||||
|
||||
\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
|
||||
\renewcommand{\subsectionmark}[1]{\markright{\thesubsection\ #1}}
|
||||
\newcommand{\Term}[1]{\mbox{\it #1}}
|
||||
\lhead[\fancyplain{}{\bfseries\thepage}]%
|
||||
{\fancyplain{}{\bfseries\rightmark}}
|
||||
\rhead[\fancyplain{}{\bfseries\leftmark}]%
|
||||
{\fancyplain{}{\bfseries\thepage}}
|
||||
\cfoot{}
|
||||
|
||||
\newenvironment{Figure}{\begin{figure}[htbp]}{\end{figure}}
|
||||
|
||||
\begin{document}
|
||||
\title{\bf \LARGE MLRISC \\ \large A framework for retargetable and optimizing compiler back ends}
|
||||
\author{\begin{tabular}{c}
|
||||
Lal George \\ \\
|
||||
Bell Laboratories \\
|
||||
600--700 Mountain Ave. \\
|
||||
Murray Hill, NJ 07974--0636. \\
|
||||
{\tt george@research.bell-labs.com}
|
||||
\end{tabular}
|
||||
\and
|
||||
\begin{tabular}{c}
|
||||
Allen Leung \\ \\
|
||||
New York University \\
|
||||
719 Broadway, Rm. 708 \\
|
||||
New York, NY 10003. \\
|
||||
{\tt leunga@cs.nyu.edu}
|
||||
\end{tabular}
|
||||
}
|
||||
|
||||
\date{\today}
|
||||
\bibliographystyle{alpha}
|
||||
|
||||
\maketitle
|
||||
|
||||
\begin{abstract}
|
||||
Writing native code generators for modern processors is a significant
|
||||
investment. Unfortunately it is difficult
|
||||
to reuse this investment for other architectures, and even more
|
||||
difficult to reuse for other source language compilers. MLRISC is
|
||||
a customizable optimizing back-end written in
|
||||
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/sml.html}{Standard ML}
|
||||
and has been successfully retargeted to multiple architectures.
|
||||
MLRISC deals elegantly with the special requirements imposed by the
|
||||
execution model of different high-level, typed languages, by allowing
|
||||
many components of the system to be customized to fit the source language
|
||||
semantics and runtime system requirements.
|
||||
\end{abstract}
|
||||
\tableofcontents
|
||||
\newpage
|
||||
|
||||
\majorsection{MLRISC}
|
||||
\include{INTRO}
|
||||
\include{contributors}
|
||||
\include{requirements}
|
||||
\include{availability}
|
||||
\majorsection{Overview}
|
||||
\include{problem}
|
||||
\include{contributions}
|
||||
\include{mlrisc-compiler}
|
||||
\include{mlrisc-ir-rep}
|
||||
\include{mlrisc-gen}
|
||||
\include{backend-opt}
|
||||
\include{mlrisc-ra}
|
||||
\include{mlrisc-md}
|
||||
\include{gc}
|
||||
\include{sys-integration}
|
||||
\include{optimizations}
|
||||
\include{mlrisc-graphics}
|
||||
\include{line-counts}
|
||||
\include{systems}
|
||||
\include{future-work}
|
||||
|
||||
\majorsection{System}
|
||||
\include{mlrisc-arch}
|
||||
\include{mltree}
|
||||
\include{mltree-ext}
|
||||
\include{mltree-util}
|
||||
\include{instrsel}
|
||||
\include{asm}
|
||||
\include{mc}
|
||||
\include{delayslots}
|
||||
\include{span-dep}
|
||||
%\include{md}
|
||||
|
||||
\include{graphs}
|
||||
\include{graphics}
|
||||
\include{compiler-graphs}
|
||||
\include{mlrisc-ir}
|
||||
\include{SSA}
|
||||
\include{ILP}
|
||||
\include{VLIW}
|
||||
\include{ra}
|
||||
|
||||
\majorsection{Back Ends}
|
||||
\include{alpha}
|
||||
\include{hppa}
|
||||
\include{sparc}
|
||||
\include{x86}
|
||||
\include{ppc}
|
||||
\include{mips}
|
||||
\include{C6}
|
||||
|
||||
\majorsection{Basic Types}
|
||||
\include{annotations}
|
||||
\include{cells}
|
||||
\include{cluster}
|
||||
\include{constants}
|
||||
\include{pseudo-ops}
|
||||
\include{instructions}
|
||||
\include{streams}
|
||||
\include{labelexp}
|
||||
\include{labels}
|
||||
\include{regions}
|
||||
\include{regmap}
|
||||
|
||||
\bibliography{mlrisc}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,73 @@
|
||||
%
|
||||
% This is derived from alltt.sty
|
||||
%
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{mltex}[2000/2/12 defines mltex environment]
|
||||
|
||||
\usepackage{latexsym}
|
||||
%\usepackage{psfig}
|
||||
\usepackage{fancyheadings}
|
||||
\usepackage{sml}
|
||||
\usepackage{color}
|
||||
\usepackage{verbatim}
|
||||
|
||||
|
||||
% Sectioning
|
||||
|
||||
\newcommand{\Chapter}[1]{\chapter{#1}}
|
||||
\newcommand{\Section}[1]{\section{#1}}
|
||||
\newcommand{\Subsection}[1]{\subsection{#1}}
|
||||
\newcommand{\Subsubsection}[1]{\subsubsection{#1}}
|
||||
\newcommand{\Paragraph}[1]{\paragraph{#1}}
|
||||
\newcommand{\majorsection}[1]{}
|
||||
|
||||
% Frames
|
||||
\newsavebox{\savepar}
|
||||
\newenvironment{boxit}{\begin{lrbox}{\savepar}
|
||||
\begin{minipage}[b]{\columnwidth}}
|
||||
{\end{minipage}\end{lrbox}\begin{center}\framebox[\columnwidth]{\usebox{\savepar}}\end{center}}
|
||||
\newenvironment{Boxit}{\begin{tabular}{|c|}\hline}{\\\hline\end{tabular}}
|
||||
|
||||
|
||||
% Table
|
||||
\newenvironment{Table}[2]{\begin{tabular}{#1}}{\end{tabular}}
|
||||
|
||||
% Images and Figures
|
||||
\newcommand{\image}[3]{}
|
||||
%\newcommand{\cpsfig}[1]{\centerline{\psfig{#1}}}
|
||||
|
||||
% Formatting
|
||||
\newenvironment{Bold}{\begingroup\bf}{\endgroup}
|
||||
\newenvironment{Italics}{\begingroup\it}{\endgroup}
|
||||
\newenvironment{Emph}{\begingroup\em}{\endgroup}
|
||||
|
||||
\newcommand{\italics}[1]{{\it #1}}
|
||||
\newcommand{\bold}[1]{{\bf #1}}
|
||||
%\newcommand{\emph}[1]{{\em #1}}
|
||||
|
||||
% New definitions
|
||||
\newcommand{\newdef}[1]{{\em #1}}
|
||||
\newcommand{\newtype}[1]{{\tt #1}}
|
||||
|
||||
% Enviroments
|
||||
\newenvironment{SML}{\begin{smldisplay}}{\end{smldisplay}}
|
||||
\newenvironment{methods}{\begin{center}\begin{tabular}{@{\tt}ll}}%
|
||||
{\end{tabular}\end{center}}
|
||||
\newenvironment{address}{}{}
|
||||
|
||||
% HTML
|
||||
\newcommand{\href}[2]{#2\footnote{url: \tt #1}}
|
||||
\newcommand{\externhref}[2]{#2\footnote{url: \tt #1}}
|
||||
\newcommand{\mlrischref}[2]{\sml{#2}\footnote{{\bf file:} {\tt #1}}}
|
||||
|
||||
\newcommand{\br}[1]{}
|
||||
\newcommand{\hr}{\rule{1em}{\textwidth}}
|
||||
|
||||
% Color
|
||||
\renewenvironment{color}[1]{}{}
|
||||
|
||||
% Misc
|
||||
\newcommand{\MLRISC}{MLRISC}
|
||||
\newcommand{\MLTeX}{\mbox{$\mbox{MLT}_{\mbox{E}}\mbox{X}$}}
|
||||
|
||||
\endinput
|
||||
@@ -0,0 +1,120 @@
|
||||
\section{\MLTeX}
|
||||
\newdef{\MLTeX} is a special \newdef{\LaTeX} package for writing
|
||||
\MLRISC{} documentation. It is similar to the
|
||||
\newdef{latex2html}~\cite{latex2html} tool
|
||||
except that \MLTeX{} has special environments for documenting
|
||||
Standard ML code. In addition, there is an accompanying tool
|
||||
called \newdef{mltex2html} for generating HTML pages.
|
||||
This page, for example, is formatted by \MLTeX.
|
||||
|
||||
\subsection{Macros}
|
||||
|
||||
Environments defined in \MLTeX{} are:
|
||||
\begin{description}
|
||||
\item[SML] This environment is used to display MLRISC code.
|
||||
For example,
|
||||
\begin{verbatim}
|
||||
\begin{SML}
|
||||
datatype 'a tree =
|
||||
EMPTY
|
||||
| LEAF of 'a
|
||||
| NODE of 'a * 'a tree * 'a tree
|
||||
\end{SML}
|
||||
\end{verbatim}
|
||||
generates:
|
||||
\begin{SML}
|
||||
datatype 'a tree =
|
||||
EMPTY
|
||||
| LEAF of 'a
|
||||
| NODE of 'a * 'a tree * 'a tree
|
||||
\end{SML}
|
||||
|
||||
\item[methods] This environment can be used to document a list of
|
||||
methods to an interface. For example,
|
||||
\begin{verbatim}
|
||||
\begin{methods}
|
||||
\sml{+ : int * int -> int} & addition \\
|
||||
\sml{- : int * int -> int} & subtraction \\
|
||||
\sml{* : int * int -> int} & multiplication \\
|
||||
\sml{/ : int * int -> int} & division \\
|
||||
\end{methods}
|
||||
\end{verbatim}
|
||||
generates:
|
||||
\begin{methods}
|
||||
\sml{+ : int * int -> int} & addition \\
|
||||
\sml{- : int * int -> int} & subtraction \\
|
||||
\sml{* : int * int -> int} & multiplication \\
|
||||
\sml{/ : int * int -> int} & division \\
|
||||
\end{methods}
|
||||
\end{description}
|
||||
|
||||
Macros defined in \MLTeX{} are:
|
||||
\begin{description}
|
||||
\item[sml] This macro can be used inline for formating SML code fragment.
|
||||
For example the fragment
|
||||
\begin{verbatim}
|
||||
\begin{quotation}
|
||||
\begin{tabular}{l}
|
||||
\sml{val toString : int -> string} \\
|
||||
\sml{val map : ('a -> 'b) -> 'a list -> 'a list}
|
||||
\end{tabular}
|
||||
\end{quotation}
|
||||
\end{verbatim}
|
||||
\noindent is formated as:
|
||||
\begin{quotation}
|
||||
\begin{tabular}{l}
|
||||
\sml{val toString : int -> string} \\
|
||||
\sml{val map : ('a -> 'b) -> 'a list -> 'a list}
|
||||
\end{tabular}
|
||||
\end{quotation}
|
||||
\item[href] This macro generates a html hypertext link to a
|
||||
page within the same logical document. For example, we can say
|
||||
\begin{verbatim}
|
||||
\href{url}{text}
|
||||
\end{verbatim}
|
||||
\item[mlrischref] This macro generates a html hypertext link to MLRISC
|
||||
code. The general syntax is:
|
||||
\begin{verbatim}
|
||||
\mlrischref{path}{text}
|
||||
\end{verbatim}
|
||||
The \verb|path| parameter is a relative path in the MLRISC hierarchy.
|
||||
\item[externhref]
|
||||
This macro generates an external hypertext link to a document outside
|
||||
of the same logical document. The general syntax is:
|
||||
\begin{verbatim}
|
||||
\externhref{url}{text}
|
||||
\end{verbatim}
|
||||
\item[newdef] This macro defines a new term. The general syntax is
|
||||
\begin{verbatim}
|
||||
\newdef{text}
|
||||
\end{verbatim}
|
||||
\end{description}
|
||||
|
||||
\subsection{Other Stuff}
|
||||
In addition to the above, \MLTeX{} understands the following \LaTeX{}
|
||||
environments and macros, and will translate them into HTML equivalents.
|
||||
\begin{verbatim}
|
||||
\begin{itemize} \end{itemize}
|
||||
\begin{description} \end{description}
|
||||
\begin{enumerate} \end{enumerate}
|
||||
\verb
|
||||
\begin{tabular} \end{tabular}
|
||||
\begin{figure} \end{figure} \caption
|
||||
\begin{wrapfigure} \end{wrapfigure}
|
||||
\section \subsection \subsubsection \paragraph
|
||||
\ref \label
|
||||
\noindent \linebreak
|
||||
\psfig
|
||||
\end{verbatim}
|
||||
|
||||
\subsection{Bugs and Shortcomings}
|
||||
There are too many to list. But the things to watch for are:
|
||||
\begin{itemize}
|
||||
\item A macro and all its arguments must appear in the same line.
|
||||
\item The tool can get confused if too many macros appear on the same line.
|
||||
\item Nesting of macros may not be handled correctly.
|
||||
\item Math mode is not robust.
|
||||
\end{itemize}
|
||||
|
||||
Please send bug fixes and comments to
|
||||
\href{mailto:leunga@cs.nyu.edu}{Allen Leung}.
|
||||
@@ -0,0 +1,76 @@
|
||||
\documentclass{article}
|
||||
\usepackage{mltex}
|
||||
\usepackage{wrapfig}
|
||||
\usepackage{float}
|
||||
%\usepackage{floatfig}
|
||||
\usepackage{fancyheadings}
|
||||
%\usepackage{draftcopy}
|
||||
%\usepackage{bookman}
|
||||
\usepackage{utopia}
|
||||
%\usepackage{times}
|
||||
%\usepackage{ncntrsbk}
|
||||
%\usepackage{palatino}
|
||||
|
||||
\setlength{\textwidth}{6.5in}
|
||||
\setlength{\evensidemargin}{0in}
|
||||
\setlength{\oddsidemargin}{0in}
|
||||
\setlength{\textheight}{8in}
|
||||
\setlength{\topmargin}{-0.5in}
|
||||
|
||||
\pagestyle{fancyplain}
|
||||
%\addtolength{\headwidth}{\marginparsep}
|
||||
%\addtolength{\headwidth}{\marginparwidth}
|
||||
|
||||
\newcommand{\edge}[1]{\rightarrow_{#1}}
|
||||
\newcommand{\union}{\cup}
|
||||
\newcommand{\Union}{\bigcup}
|
||||
\newcommand{\overrides}{overrides}
|
||||
\newcommand{\defas}{\stackrel{\rm as}{=}}
|
||||
|
||||
\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
|
||||
\renewcommand{\subsectionmark}[1]{\markright{\thesubsection\ #1}}
|
||||
\newcommand{\Term}[1]{\mbox{\it #1}}
|
||||
\lhead[\fancyplain{}{\bfseries\thepage}]%
|
||||
{\fancyplain{}{\bfseries\rightmark}}
|
||||
\rhead[\fancyplain{}{\bfseries\leftmark}]%
|
||||
{\fancyplain{}{\bfseries\thepage}}
|
||||
\cfoot{}
|
||||
|
||||
\newenvironment{Figure}{\begin{figure}[htbp]}{\end{figure}}
|
||||
|
||||
\begin{document}
|
||||
\title{\bf \LARGE \MLTeX}
|
||||
\author{\begin{tabular}{c}
|
||||
Allen Leung \\ \\
|
||||
New York University \\
|
||||
719 Broadway, Rm. 714 \\
|
||||
New York, NY 10003. \\
|
||||
{\tt leunga@cs.nyu.edu}
|
||||
\end{tabular}
|
||||
\and
|
||||
\begin{tabular}{c}
|
||||
Lal George \\ \\
|
||||
Bell Laboratories \\
|
||||
600--700 Mountain Ave. \\
|
||||
Murray Hill, NJ 07974--0636. \\
|
||||
{\tt george@research.bell-labs.com}
|
||||
\end{tabular}
|
||||
}
|
||||
|
||||
\date{\today}
|
||||
\bibliographystyle{alpha}
|
||||
|
||||
\maketitle
|
||||
|
||||
\begin{abstract}
|
||||
\newdef{\MLTeX} is a special \newdef{\LaTeX} package for writing
|
||||
\MLRISC{} documentation. It is similar to the \newdef{latex2html}
|
||||
tool except that \MLTeX{} has special environments for documenting
|
||||
Standard ML code. In addition, there is an accompanying tool
|
||||
called \newdef{mltex2html} for generating HTML pages.
|
||||
\end{abstract}
|
||||
|
||||
|
||||
\include{mltex}
|
||||
\bibliography{mlrisc}
|
||||
\end{document}
|
||||
@@ -0,0 +1,283 @@
|
||||
\section{MLTree Extensions} \label{sec:mltree-extension}
|
||||
Pattern matching over the MLTREE intermediate representation
|
||||
may not be sufficient to provide access to all the registers or
|
||||
operations provided on a specific architecture. MLTREE extensions is a
|
||||
method of extending the MLTREE intermediate language so that it is a
|
||||
better match for the target architecture.
|
||||
|
||||
|
||||
\subsection{Why Extensions}
|
||||
|
||||
Pattern matching over the MLTREE intermediate representation
|
||||
may not be sufficient to provide access to all the registers or
|
||||
operations provided on a specific architecture. MLTREE extensions is a
|
||||
method of extending the MLTREE intermediate language so that it is a
|
||||
better match for the target architecture.
|
||||
|
||||
For example there may be special registers to support the
|
||||
increment-and-test operation on loop indices, or
|
||||
support for complex mathematical functions such as
|
||||
square root, or access to hardware specific registers such as the
|
||||
current register window pointer on the SPARC architecture. It is not
|
||||
usually possible to write expression trees that would directly
|
||||
generate these instructions.
|
||||
Some complex operations can be generated by performing a peephole
|
||||
optimization over simpler instructions, however this is not always the
|
||||
most convenient or simple thing to do.
|
||||
|
||||
\subsection{Cyclic Dependency}
|
||||
|
||||
The easiest way to provide extensions is to parameterize the MLTREE
|
||||
interface with types that extend the various kinds of trees. Thus if
|
||||
the type \sml{sext} represented statement extensions, we might define
|
||||
MLTREE statement trees as :
|
||||
\begin{SML}
|
||||
datatype stm
|
||||
= ...
|
||||
| SEXT of sext * mlrisc list * stm list
|
||||
|
||||
and mlrisc = GPR of rexp | FPR of fexp | CCR of ccexp
|
||||
\end{SML}
|
||||
where the constructor \sml{SEXT} applies the extension to a list of
|
||||
arguments. This approach is unsatisfactory in several ways, for
|
||||
example, if one wanted to extend MLTREEs with for-loops, then the
|
||||
following could be generated:
|
||||
\begin{SML}
|
||||
SEXT(FORLOOP, [GPR from, GPR to, GPR step], body)
|
||||
\end{SML}
|
||||
First, the loop arguments have to be wrapped up in \sml{GPR} and there
|
||||
is little self documentation on the order of elements that are
|
||||
arguments to the for-loop. It would be better to be able to write
|
||||
something like:
|
||||
\begin{SML}
|
||||
SEXT(FORLOOP\{from=f, to=t, step=s, body=b\})
|
||||
\end{SML}
|
||||
|
||||
Where \sml{f}, \sml{t}, and \sml{s} are \sml{rexp} trees representing
|
||||
the loop index start, end, and step size; \sml{b} is a stm list
|
||||
representing the body of the loop. Unfortunately, there is a cyclic
|
||||
dependency as MLTREEs are defined in terms of \sml{sext}, and {\tt
|
||||
sext} is defined in terms of MLTREEs. The usual way to deal with
|
||||
cyclic dependencies is to use polymorphic type variables.
|
||||
|
||||
\subsection{MLTREE EXTENSION}
|
||||
|
||||
The statement extension type \sml{sext}, is now a type constructor
|
||||
with arity four, i.e.
|
||||
\sml{('s, 'r, 'f, 'c) sx} where \sml{sx} is used instead of {\tt
|
||||
sext}, and \sml{'s}, \sml{'r}, \sml{'f}, and \sml{'c} represents
|
||||
MLTREE statement expressions, register expressions, floating point
|
||||
expressions, and condition code expressions. Thus the for-loop
|
||||
extension could be declared using something like:
|
||||
\begin{SML}
|
||||
datatype ('s,'r,'f,'c) sx
|
||||
= FORLOOP of \{from: 'r, to: 'r, step: 'r, body: 's\}
|
||||
\end{SML}
|
||||
and the MLTREE interface is defined as:
|
||||
\begin{SML}
|
||||
signature MLTREE = sig
|
||||
type ('s, 'r, 'f, 'c) sx
|
||||
|
||||
datatype stm =
|
||||
= ...
|
||||
| SEXT of sext
|
||||
|
||||
withtype sext = (stm, rexp, fexp, cexp) sx
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
where \sml{sext} is the user defined statement extension but the
|
||||
type variables have been instantiated to the final form the the MLTREE
|
||||
\sml{stm}, \sml{rexp}, \sml{fexp}, and \sml{cexp} components.
|
||||
|
||||
\subsection{Compilation}
|
||||
|
||||
There are dedicated modules that perform pattern matching over MLTREEs
|
||||
and emit native instructions, and similar modules must be written for
|
||||
extensions. However, the same kinds of choices used in regular MLTREE
|
||||
patterns must be repeated for extensions. For example, one may define
|
||||
an extension for the Intel IA32 of the form:
|
||||
|
||||
\begin{SML}
|
||||
datatype ('s,'r,'f,'c) sx = PUSHL of 'r | POPL of 'r | ...
|
||||
\end{SML}
|
||||
|
||||
that translate directly to the Intel push and pop instructions; the
|
||||
operands in each case are either memory locations or registers, but
|
||||
immediates are allowed in the case of \sml{PUSHL}. Considerable effort
|
||||
has been invested into pattern matching the extensive set of
|
||||
addressing modes for the Intel architecture, and
|
||||
one would like to reuse this when compiling extensions. The pattern
|
||||
matching functions are exposed by a set of functions exported from the
|
||||
instruction selection module, and provided in the MLTREE
|
||||
interface. They are:
|
||||
|
||||
\begin{SML}
|
||||
struture I : INSTRUCTIONS
|
||||
datatype reducer =
|
||||
REDUCER of \{
|
||||
reduceRexp : rexp -> reg,
|
||||
reduceFexp : fexp -> reg,
|
||||
reduceCCexp : ccexp -> reg,
|
||||
reduceStm : stm * an list -> unit,
|
||||
operand : rexp -> I.operand,
|
||||
reduceOperand : I.operand -> reg,
|
||||
addressOf : rexp -> I.addressing_mode,
|
||||
emit : I.instr * an list -> unit,
|
||||
instrStream : (I.instr, I.regmap, I.cellset) stream,
|
||||
mltreeStream : (stm, I.regmap, mlrisc list) stream
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
where \sml{I} is the native instruction set.
|
||||
\begin{description}
|
||||
\item[\tt reduceRexp]: reduces an MLTREE \sml{rexp} to a register, and
|
||||
similarly for \sml{reduceFexp} and \sml{reduceCCexp}.
|
||||
\item[\tt reduceStm]: reduces an MLTREE \sml{stm} to a set of instructions
|
||||
that implement the set of statements.
|
||||
\item[\tt operand]: reduced an MLTREE \sml{rexp} into an instruction
|
||||
operand --- usually an immediate or memory address.
|
||||
\item[\tt operand]: moves a native operand into a register.
|
||||
\item[\tt addressOf]: reduces an MLTREE \sml{rexp} into a memory address.
|
||||
\item[\tt emit]: emits an instruction together with an annotation.
|
||||
\item[\tt instrStream]: is the native instruction output stream, and
|
||||
\item[\tt mltreeStream]: is the MLTREE output stream.
|
||||
\end{description}
|
||||
|
||||
Each extension must provide a function \sml{compileSext} that compiles
|
||||
a statement extension into native instructions. In the
|
||||
\sml{MLTREE_EXTENSION_COMP} interface we have:
|
||||
\begin{SML}
|
||||
val compileSext: reducer -> {stm: MLTREE.sexp, an:MLTREE.an list} -> unit
|
||||
\end{SML}
|
||||
|
||||
The use of extensions must follow a special structure.
|
||||
\begin{enumerate}
|
||||
\item A module defining the extension type using a type constructor
|
||||
of arity four. Let us call this structure \sml{ExtTy} and must match
|
||||
the \sml{MLTREE_EXTENSION} interface.
|
||||
\item The extension module must be used to specialize MLTREEs.
|
||||
\item A module that describes how to compile the extension must be
|
||||
created, and must match the \sml{MLTREE_EXTENSION_COMP} interace.
|
||||
This module will typically be functorized over the MLTREE interface.
|
||||
Let us call the result of applying the functor, \sml{ExtComp}.
|
||||
\item The extension compiler must be passed as a parameter to the
|
||||
instruction selection module that will invoke it whenever an extension
|
||||
is seen.
|
||||
\end{enumerate}
|
||||
|
||||
|
||||
\subsection{Multiple Extensions}
|
||||
|
||||
Multiple extensions are handled in a similar fashion, except that the
|
||||
extension type used to specialize MLTREEs is a tagged union of the
|
||||
individual extensions. The functor to compile the extension dispatches
|
||||
to the compilation modules for the individual extensions.
|
||||
|
||||
\subsection{Example}
|
||||
Suppose you are in the process of writing a compiler for a digital
|
||||
signal processing(\newdef{DSP}) programming language using the MLRISC
|
||||
framework. This wonderful language that you are developing allows the
|
||||
programmer to specify high level looping and iteration, and
|
||||
aggregation constructs that are common in DSP applications.
|
||||
Furthermore, since saturated and fixed point arithmetic are common
|
||||
constructs in DSP applications, the language and consequently the
|
||||
compiler should directly support these operators. For simplicity, we
|
||||
would like to have a unified intermediate representation that can be
|
||||
used to directly represent high level constructs in our language, and
|
||||
low level constructs that are already present in MLTree. Since,
|
||||
MLTree does not directly support these constructs, it seems that it is
|
||||
not possible to use MLRISC for such a compiler infrastructure without
|
||||
substantial rewrite of the core components.
|
||||
|
||||
Let us suppose that for illustration that we would like to
|
||||
implement high level looping and aggregation constructs such as
|
||||
\begin{verbatim}
|
||||
for i := lower bound ... upper bound
|
||||
body
|
||||
x := sum{i := lower bound ... upper bound} expression
|
||||
\end{verbatim}
|
||||
together with saturated arithmetic mentioned above.
|
||||
|
||||
Here is a first attempt:
|
||||
\begin{SML}
|
||||
structure DSPMLTreeExtension
|
||||
struct
|
||||
structure Basis = MLTreeBasis
|
||||
datatype ('s,'r,'f,'c) sx =
|
||||
FOR of Basis.var * 'r * 'r * 's
|
||||
and ('s,'r,'f,'c) rx =
|
||||
SUM of Basis.var * 'r * 'r * 'r
|
||||
| SADD of 'r * 'r
|
||||
| SSUB of 'r * 'r
|
||||
| SMUL of 'r * 'r
|
||||
| SDIV of 'r * 'r
|
||||
type ('s,'r,'f,'c) fx = unit
|
||||
type ('s,'r,'f,'c) ccx = unit
|
||||
end
|
||||
structure DSPMLTree : MLTreeF
|
||||
(structure Extension = DSPMLTreeExtension
|
||||
...
|
||||
)
|
||||
\end{SML}
|
||||
In the above signature, we have defined two new datatypes \newtype{sx}
|
||||
and \newtype{rx} that are used for representing the DSP statement
|
||||
and integer expression extensions. Integer expression extensions
|
||||
include the high level sum construct, and the low levels saturated
|
||||
arithmetic operators. The recursive type definition is
|
||||
necessary to ``inject'' these new constructors into the basic MLTree
|
||||
definition.
|
||||
|
||||
The following is an example of how these new constructors that we have defined can be used. Suppose the source program in our DSP language is:
|
||||
\begin{verbatim}
|
||||
for i := a ... b
|
||||
{ s := sadd(s, table[i]);
|
||||
}
|
||||
\end{verbatim}
|
||||
\noindent where \verb|sadd| is the saturated add operator.
|
||||
For simplicity, let us also assume that all operations and addresses
|
||||
are in 32-bits.
|
||||
Then the translation of the above into our extended DSP-MLTree could be:
|
||||
\begin{SML}
|
||||
EXT(FOR(\(i\), REG(32, \(a\)), REG(32, \(b\)),
|
||||
MV(32, \(s\), REXT(32, SADD(REG(32, \(s\)),
|
||||
LOAD(32,
|
||||
ADD(32, REG(32, \(table\)),
|
||||
SLL(32, REG(32, \(i\)), LI 2)),
|
||||
\(region\)))))
|
||||
))
|
||||
\end{SML}
|
||||
|
||||
One potential short coming of our DSP extension to MLTree is that
|
||||
the extension does not allow any further extensions. This restriction
|
||||
may be entirely satisfactory if DSP-MLTree is only used in your compiler
|
||||
applications and no where else. However, if DSP-MLTree is intended
|
||||
to be an extension library for MLRISC, then we must build in the flexibility
|
||||
for extension. This can be done in the same way as in the base MLTree
|
||||
definition, like this:
|
||||
\begin{SML}
|
||||
functor ExtensibleDSPMLTreeExtension
|
||||
(Extension : \mlrischref{mltree/mltree-extension.sig}{MLTREE_EXTENSION}) =
|
||||
struct
|
||||
structure Basis = MLTreeBasis
|
||||
structure Extension = Extension
|
||||
datatype ('s,'r,'f,'c) sx =
|
||||
FOR of Basis.var * 'r * 'r * 's
|
||||
| EXT of ('s,'r,'f,'c) Extension.sx
|
||||
and ('s,'r,'f,'c) rx =
|
||||
SUM of Basis.var * 'r * 'r * 'r
|
||||
| SADD of 'r * 'r
|
||||
| SSUB of 'r * 'r
|
||||
| SMUL of 'r * 'r
|
||||
| SDIV of 'r * 'r
|
||||
| REXT of ('s,'r,'f,'c) Extension.rx
|
||||
withtype
|
||||
('s,'r,'f,'c) fx = ('s,'r,'f,'c) Extension.fx
|
||||
and ('s,'r,'f,'c) ccx = ('s,'r,'f,'c) Extension.ccx
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
As in MLTREE, we provide two new extension
|
||||
constructors \verb|EXT| and \verb|REXT| in
|
||||
the definition of \sml{DSP_MLTREE}, which can
|
||||
be used to further enhance the extended MLTREE language.
|
||||
@@ -0,0 +1,260 @@
|
||||
\section{MLTree Utilities}
|
||||
|
||||
The \MLRISC{} system contains numerous utilities for working with
|
||||
MLTree datatypes. Some of the following utilizes are also useful for clients
|
||||
use:
|
||||
\begin{description}
|
||||
\item[MLTreeUtils] implements basic hashing, equality and pretty
|
||||
printing functions,
|
||||
\item[MLTreeFold] implements a fold function over the MLTree datatypes,
|
||||
\item[MLTreeRewrite] implements a generic rewriting engine,
|
||||
\item[MLTreeSimplify] implements a simplifier that performs algebraic
|
||||
simplification and constant folding.
|
||||
\end{description}
|
||||
\subsubsection{Hashing, Equality, Pretty Printing}
|
||||
|
||||
The functor \mlrischref{mltree/mltree-utils.sml}{MLTreeUtils} provides
|
||||
the basic utilities for hashing an MLTree term, comparing two
|
||||
MLTree terms for equality and pretty printing. The hashing and comparision
|
||||
functions are useful for building hash tables using MLTree datatype as keys.
|
||||
The signature of the functor is:
|
||||
\begin{SML}
|
||||
signature \mlrischref{mltree/mltree-utils.sig}{MLTREE_UTILS} =
|
||||
sig
|
||||
structure T : MLTREE
|
||||
|
||||
(*
|
||||
* Hashing
|
||||
*)
|
||||
val hashStm : T.stm -> word
|
||||
val hashRexp : T.rexp -> word
|
||||
val hashFexp : T.fexp -> word
|
||||
val hashCCexp : T.ccexp -> word
|
||||
|
||||
(*
|
||||
* Equality
|
||||
*)
|
||||
val eqStm : T.stm * T.stm -> bool
|
||||
val eqRexp : T.rexp * T.rexp -> bool
|
||||
val eqFexp : T.fexp * T.fexp -> bool
|
||||
val eqCCexp : T.ccexp * T.ccexp -> bool
|
||||
val eqMlriscs : T.mlrisc list * T.mlrisc list -> bool
|
||||
|
||||
(*
|
||||
* Pretty printing
|
||||
*)
|
||||
val show : (string list * string list) -> T.printer
|
||||
|
||||
val stmToString : T.stm -> string
|
||||
val rexpToString : T.rexp -> string
|
||||
val fexpToString : T.fexp -> string
|
||||
val ccexpToString : T.ccexp -> string
|
||||
|
||||
end
|
||||
functor \mlrischref{mltree/mltree-utils.sml}{MLTreeUtils}
|
||||
(structure T : MLTREE
|
||||
(* Hashing extensions *)
|
||||
val hashSext : T.hasher -> T.sext -> word
|
||||
val hashRext : T.hasher -> T.rext -> word
|
||||
val hashFext : T.hasher -> T.fext -> word
|
||||
val hashCCext : T.hasher -> T.ccext -> word
|
||||
|
||||
(* Equality extensions *)
|
||||
val eqSext : T.equality -> T.sext * T.sext -> bool
|
||||
val eqRext : T.equality -> T.rext * T.rext -> bool
|
||||
val eqFext : T.equality -> T.fext * T.fext -> bool
|
||||
val eqCCext : T.equality -> T.ccext * T.ccext -> bool
|
||||
|
||||
(* Pretty printing extensions *)
|
||||
val showSext : T.printer -> T.sext -> string
|
||||
val showRext : T.printer -> T.ty * T.rext -> string
|
||||
val showFext : T.printer -> T.fty * T.fext -> string
|
||||
val showCCext : T.printer -> T.ty * T.ccext -> string
|
||||
) : MLTREE_UTILS =
|
||||
\end{SML}
|
||||
|
||||
The types \sml{hasher}, \sml{equality},
|
||||
and \sml{printer} represent functions for hashing,
|
||||
equality and pretty printing. These are defined as:
|
||||
\begin{SML}
|
||||
type hasher =
|
||||
\{stm : T.stm -> word,
|
||||
rexp : T.rexp -> word,
|
||||
fexp : T.fexp -> word,
|
||||
ccexp : T.ccexp -> word
|
||||
\}
|
||||
|
||||
type equality =
|
||||
\{ stm : T.stm * T.stm -> bool,
|
||||
rexp : T.rexp * T.rexp -> bool,
|
||||
fexp : T.fexp * T.fexp -> bool,
|
||||
ccexp : T.ccexp * T.ccexp -> bool
|
||||
\}
|
||||
type printer =
|
||||
\{ stm : T.stm -> string,
|
||||
rexp : T.rexp -> string,
|
||||
fexp : T.fexp -> string,
|
||||
ccexp : T.ccexp -> string,
|
||||
dstReg : T.ty * T.var -> string,
|
||||
srcReg : T.ty * T.var -> string
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
For example, to instantiate a \sml{Utils} module for our \sml{DSPMLTree},
|
||||
we can write:
|
||||
\begin{SML}
|
||||
structure U = MLTreeUtils
|
||||
(structure T = DSPMLTree
|
||||
fun hashSext \{stm, rexp, fexp, ccexp\} (FOR(i, a, b, s)) =
|
||||
Word.fromIntX i + rexp a + rexp b + stm s
|
||||
and hashRext \{stm, rexp, fexp, ccexp\} e =
|
||||
(case e of
|
||||
SUM(i,a,b,c) => Word.fromIntX i + rexp a + rexp b + rexp c
|
||||
| SADD(a,b) => rexp a + rexp b
|
||||
| SSUB(a,b) => 0w12 + rexp a + rexp b
|
||||
| SMUL(a,b) => 0w123 + rexp a + rexp b
|
||||
| SDIV(a,b) => 0w1245 + rexp a + rexp b
|
||||
)
|
||||
fun hashFext _ _ = 0w0
|
||||
fun hashCCext _ _ = 0w0
|
||||
fun eqSext \{stm, rexp, fexp, ccexp\}
|
||||
(FOR(i, a, b, s), FOR(i', a', b', s')) =
|
||||
i=i' andalso rexp(a,a') andalso rexp(b,b') andalso stm(s,s')
|
||||
fun eqRext \{stm, rexp, fexp, ccexp\} (e,e') =
|
||||
(case (e,e') of
|
||||
(SUM(i,a,b,c),SUM(i',a',b',c')) =>
|
||||
i=i' andalso rexp(a,a') andalso rexp(b,b') andalso stm(c,c')
|
||||
| (SADD(a,b),SADD(a',b')) => rexp(a,a') andalso rexp(b,b')
|
||||
| (SSUB(a,b),SSUB(a',b')) => rexp(a,a') andalso rexp(b,b')
|
||||
| (SMUL(a,b),SMUL(a',b')) => rexp(a,a') andalso rexp(b,b')
|
||||
| (SDIV(a,b),SDIV(a',b')) => rexp(a,a') andalso rexp(b,b')
|
||||
| _ => false
|
||||
)
|
||||
fun eqFext _ _ = true
|
||||
fun eqCCext _ _ = true
|
||||
|
||||
fun showSext \{stm, rexp, fexp, ccexp, dstReg, srcReg\}
|
||||
(FOR(i, a, b, s)) =
|
||||
"for("^dstReg i^":="^rexp a^".."^rexp b^")"^stm s
|
||||
fun ty t = "."^Int.toString t
|
||||
fun showRext \{stm, rexp, fexp, ccexp, dstReg, srcReg\} e =
|
||||
(case (t,e) of
|
||||
SUM(i,a,b,c) =>
|
||||
"sum"^ty t^"("^dstReg i^":="^rexp a^".."^rexp b^")"^rexp c
|
||||
| SADD(a,b) => "sadd"^ty t^"("rexp a^","^rexp b^")"
|
||||
| SSUB(a,b) => "ssub"^ty t^"("rexp a^","^rexp b^")"
|
||||
| SMUL(a,b) => "smul"^ty t^"("rexp a^","^rexp b^")"
|
||||
| SDIV(a,b) => "sdiv"^ty t^"("rexp a^","^rexp b^")"
|
||||
)
|
||||
fun showFext _ _ = ""
|
||||
fun showCCext _ _ = ""
|
||||
)
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{MLTree Fold}
|
||||
The functor \mlrischref{mltree/mltree-fold.sml}{MLTreeFold}
|
||||
provides the basic functionality for implementing various forms of
|
||||
aggregation function over the MLTree datatypes. Its signature is
|
||||
\begin{SML}
|
||||
signature \mlrischref{mltree/mltree-fold.sig}{MLTREE_FOLD} =
|
||||
sig
|
||||
structure T : MLTREE
|
||||
|
||||
val fold : 'b folder -> 'b folder
|
||||
end
|
||||
functor \mlrischref{mltree/mltree-fold.sml}{MLTreeFold}
|
||||
(structure T : MLTREE
|
||||
(* Extension mechnism *)
|
||||
val sext : 'b T.folder -> T.sext * 'b -> 'b
|
||||
val rext : 'b T.folder -> T.ty * T.rext * 'b -> 'b
|
||||
val fext : 'b T.folder -> T.fty * T.fext * 'b -> 'b
|
||||
val ccext : 'b T.folder -> T.ty * T.ccext * 'b -> 'b
|
||||
) : MLTREE_FOLD =
|
||||
\end{SML}
|
||||
The type \newtype{folder} is defined as:
|
||||
\begin{SML}
|
||||
type 'b folder =
|
||||
\{ stm : T.stm * 'b -> 'b,
|
||||
rexp : T.rexp * 'b -> 'b,
|
||||
fexp : T.fexp * 'b -> 'b,
|
||||
ccexp : T.ccexp * 'b -> 'b
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
|
||||
\subsubsection{MLTree Rewriting}
|
||||
|
||||
The functor \mlrischref{mltree/mltree-rewrite.sml}{MLTreeRewrite}
|
||||
implements a generic term rewriting engine which is useful for performing
|
||||
various transformations on MLTree terms. Its signature is
|
||||
\begin{SML}
|
||||
signature \mlrischref{mltree/mltree-rewrite.sig}{MLTREE_REWRITE} =
|
||||
sig
|
||||
structure T : MLTREE
|
||||
|
||||
val rewrite :
|
||||
(* User supplied transformations *)
|
||||
\{ rexp : (T.rexp -> T.rexp) -> (T.rexp -> T.rexp),
|
||||
fexp : (T.fexp -> T.fexp) -> (T.fexp -> T.fexp),
|
||||
ccexp : (T.ccexp -> T.ccexp) -> (T.ccexp -> T.ccexp),
|
||||
stm : (T.stm -> T.stm) -> (T.stm -> T.stm)
|
||||
\} -> T.rewriters
|
||||
end
|
||||
functor \mlrischref{mltre/mltree-rewrite.sml}{MLTreeRewrite}
|
||||
(structure T : MLTREE
|
||||
(* Extension *)
|
||||
val sext : T.rewriter -> T.sext -> T.sext
|
||||
val rext : T.rewriter -> T.rext -> T.rext
|
||||
val fext : T.rewriter -> T.fext -> T.fext
|
||||
val ccext : T.rewriter -> T.ccext -> T.ccext
|
||||
) : MLTREE_REWRITE =
|
||||
\end{SML}
|
||||
|
||||
The type \newtype{rewriter} is defined in signature
|
||||
\mlrischref{mltree/mltree.sig}{MLTREE} as:
|
||||
\begin{SML}
|
||||
type rewriter =
|
||||
\{ stm : T.stm -> T.stm,
|
||||
rexp : T.rexp -> T.rexp,
|
||||
fexp : T.fexp -> T.fexp,
|
||||
ccexp : T.ccexp -> T.ccexp
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{MLTree Simplifier}
|
||||
|
||||
The functor \mlrischref{mltree/mltree-simplify.sml}{MLTreeSimplify}
|
||||
implements algebraic simplification and constant folding for MLTree.
|
||||
Its signature is:
|
||||
\begin{SML}
|
||||
signature \mlrischref{mltree/mltree-simplify.sig}{MLTREE_SIMPLIFIER} =
|
||||
sig
|
||||
|
||||
structure T : MLTREE
|
||||
|
||||
val simplify :
|
||||
{ addressWidth : int } -> T.simplifier
|
||||
|
||||
end
|
||||
functor \mlrischref{mltree/mltree-simplify.sml}{MLTreeSimplifier}
|
||||
(structure T : MLTREE
|
||||
(* Extension *)
|
||||
val sext : T.rewriter -> T.sext -> T.sext
|
||||
val rext : T.rewriter -> T.rext -> T.rext
|
||||
val fext : T.rewriter -> T.fext -> T.fext
|
||||
val ccext : T.rewriter -> T.ccext -> T.ccext
|
||||
) : MLTREE_SIMPLIFIER =
|
||||
\end{SML}
|
||||
|
||||
Where type \newdef{simplifier} is defined in signature
|
||||
\mlrischref{mltree/mltree.sig}{MLTREE} as:
|
||||
\begin{SML}
|
||||
type simplifier =
|
||||
\{ stm : T.stm -> T.stm,
|
||||
rexp : T.rexp -> T.rexp,
|
||||
fexp : T.fexp -> T.fexp,
|
||||
ccexp : T.ccexp -> T.ccexp
|
||||
\}
|
||||
\end{SML}
|
||||
|
||||
|
||||
@@ -0,0 +1,659 @@
|
||||
\section{The MLTREE Language}
|
||||
|
||||
\newdef{MLTree} is the
|
||||
register transfer language used in the MLRISC system.
|
||||
It serves two important purposes:
|
||||
\image{MLTree}{pictures/png/mlrisc-ir.png}{align=right}
|
||||
\begin{enumerate}
|
||||
\item As an intermediate representation for a compiler front-end
|
||||
to talk to the MLRISC system,
|
||||
\item As specifications for instruction semantics
|
||||
\end{enumerate}
|
||||
The latter is needed for optimizations which require precise knowledge of such;
|
||||
for example, algebraic simplification and constant folding.
|
||||
|
||||
MLTree is a low-level \newdef{typed} language:
|
||||
all operations are typed by its width or precision.
|
||||
Operations on floating point, integer, and condition code
|
||||
are also segregated, to prevent accidental misuse.
|
||||
MLTree is also \emph{tree-oriented} so that it is possible to write efficient
|
||||
MLTree transformation routines that uses SML pattern matching.
|
||||
|
||||
Here are a few examples of MLTree statements.
|
||||
\begin{SML}
|
||||
MV(32,t,
|
||||
ADDT(32,
|
||||
MULT(32,REG(32,b),REG(32,b)),
|
||||
MULT(32,
|
||||
MULT(32,LI(4),REG(32,a)),REG(32,c))))
|
||||
\end{SML}
|
||||
computes \sml{t := b*b + 4*a*c}, all in 32-bit precision and overflow
|
||||
trap enabled; while
|
||||
\begin{SML}
|
||||
MV(32,t,
|
||||
ADD(32,
|
||||
CVTI2I(32,SIGN_EXTEND,8,
|
||||
LOAD(8,
|
||||
ADD(32,REG(32,a),REG(32,i))))))
|
||||
\end{SML}
|
||||
loads the byte in address \sml{a+i} and sign extend it to a 32-bit
|
||||
value.
|
||||
|
||||
The statement
|
||||
\begin{SML}
|
||||
IF([],CMP(64,GE,REG(64,a),LI 0),
|
||||
MV(64, t, REG(64, a)),
|
||||
MV(64, t, NEG(64, REG(64, a)))
|
||||
)
|
||||
\end{SML}
|
||||
in more traditional form means:
|
||||
\begin{verbatim}
|
||||
if a >= 0 then
|
||||
t := a
|
||||
else
|
||||
t := -a
|
||||
\end{verbatim}
|
||||
This example can be also expressed in a few different ways:
|
||||
\begin{enumerate}
|
||||
\item With the conditional move construct described in
|
||||
Section~\ref{sec:cond-move}:
|
||||
\begin{SML}
|
||||
MV(64, t,
|
||||
COND(CMP(64, GE, REG(64, a)),
|
||||
REG(64, a),
|
||||
NEG(64, REG(64, a))))
|
||||
\end{SML}
|
||||
\item With explicit branching using the conditional branch
|
||||
construct \verb|BCC|:
|
||||
\begin{SML}
|
||||
MV(64, t, REG(64, a));
|
||||
BCC([], CMP(64, GE, REG(64, a)), L1);
|
||||
MV(64, t, NEG(64, REG(64, a)));
|
||||
DEFINE L1;
|
||||
\end{SML}
|
||||
\end{enumerate}
|
||||
\subsection{The Definitions}
|
||||
|
||||
MLTree is defined in the signature \mlrischref{mltree/mltree.sig}{\sml{MLTREE}}
|
||||
and the functor \mlrischref{mltree/mltree.sml}{\sml{MLTreeF}}
|
||||
|
||||
The functor \sml{MLTreeF} is parameterized in terms of
|
||||
the label expression type, the client supplied region datatype,
|
||||
the instruction stream type, and the client defined MLTree extensions.
|
||||
\begin{SML}
|
||||
functor MLTreeF
|
||||
(structure LabelExp : \href{labelexp.html}{LABELEXP}
|
||||
structure Region : \href{regions.html}{REGION}
|
||||
structure Stream : \href{streams.html}{INSTRUCTION_STREAM}
|
||||
structure Extension : \mlrischref{mltree/mltree-extension.sig}{MLTREE_EXTENSION}
|
||||
) : MLTREE
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Basic Types}
|
||||
|
||||
The basic types in MLTree are statements (\newtype{stm})
|
||||
integer expressions (\newtype{rexp}),
|
||||
floating point expression (\newtype{fexp}),
|
||||
and conditional expressions (\newtype{ccexp}).
|
||||
Statements are evaluated for their effects,
|
||||
while expressions are evaluated for their value. (Some expressions
|
||||
could also have trapping effects. The semantics of traps are unspecified.)
|
||||
These types are parameterized by an extension
|
||||
type, which we can use to extend the set of MLTree
|
||||
operators. How this is used is described in Section~\ref{sec:mltree-extension}.
|
||||
|
||||
References to registers are represented internally as integers, and are denoted
|
||||
as the type \sml{reg}. In addition, we use the types \sml{src} and \sml{dst}
|
||||
as abbreviations for source and destination registers.
|
||||
\begin{SML}
|
||||
type reg = int
|
||||
type src = reg
|
||||
type dst = reg
|
||||
\end{SML}
|
||||
|
||||
All operators on MLTree are \emph{typed}
|
||||
by the number of bits that
|
||||
they work on. For example, 32-bit addition between \sml{a} and \sml{b}
|
||||
is written as \sml{ADD(32,a,b)}, while 64-bit addition between the same
|
||||
is written as \sml{ADD(64,a,b)}. Floating point operations are
|
||||
denoted in the same manner. For example, IEEE single-precision floating
|
||||
point add is written as \sml{FADD(32,a,b)}, while the same in
|
||||
double-precision is written as \sml{FADD(64,a,b)}
|
||||
|
||||
Note that these types are low level. Higher level distinctions such
|
||||
as signed and unsigned integer value, are not distinguished by the type.
|
||||
Instead, operators are usually partitioned into signed and unsigned versions,
|
||||
and it is legal (and often useful!) to mix signed and unsigned operators in
|
||||
an expression.
|
||||
|
||||
Currently, we don't provide a direct way to specify non-IEEE floating point
|
||||
together with
|
||||
IEEE floating point arithmetic. If this distinction is needed then
|
||||
it can be encoded using the extension mechanism described
|
||||
in Section~\ref{sec:mltree-extension}.
|
||||
|
||||
We use the types \sml{ty} and \sml{fty} to stand for the number of
|
||||
bits in integer and floating point operations.
|
||||
\begin{SML}
|
||||
type ty = int
|
||||
type fty = int
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{The Basis}
|
||||
The signature \mlrischref{mltree/mltree-basis.sig}{MLTREE\_BASIS}
|
||||
defines the basic helper types used in the MLTREE signature.
|
||||
\begin{SML}
|
||||
signature MLTREE_BASIS =
|
||||
sig
|
||||
|
||||
datatype cond = LT | LTU | LE | LEU | EQ | NE | GE | GEU | GT | GTU
|
||||
|
||||
datatype fcond =
|
||||
? | !<=> | == | ?= | !<> | !?>= | < | ?< | !>= | !?> |
|
||||
<= | ?<= | !> | !?<= | > | ?> | !<= | !?< | >= | ?>= |
|
||||
!< | !?= | <> | != | !? | <=> | ?<>
|
||||
|
||||
datatype ext = SIGN_EXTEND | ZERO_EXTEND
|
||||
|
||||
datatype rounding_mode = TO_NEAREST | TO_NEGINF | TO_POSINF | TO_ZERO
|
||||
|
||||
type ty = int
|
||||
type fty = int
|
||||
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The most important of these are the
|
||||
types \newtype{cond} and \newtype{fcond}, which represent the set of integer
|
||||
and floating point comparisions. These types can be combined with
|
||||
the comparison constructors \verb|CMP| and \verb|FCMP| to form
|
||||
integer and floating point comparisions.
|
||||
\begin{Table}{|c|c|}{align=left} \hline
|
||||
Operator & Comparison \\ \hline
|
||||
\sml{LT} & Signed less than \\
|
||||
\sml{LTU} & Unsigned less than \\
|
||||
\sml{LE} & Signed less than or equal \\
|
||||
\sml{LEU} & Unsigned less than or equal \\
|
||||
\sml{EQ} & Equal \\
|
||||
\sml{NE} & Not equal \\
|
||||
\sml{GE} & Signed greater than or equal \\
|
||||
\sml{GEU} & Unsigned greater than or equal \\
|
||||
\sml{GT} & Signed greater than \\
|
||||
\sml{GTU} & Unsigned greater than \\
|
||||
\hline
|
||||
\end{Table}
|
||||
|
||||
Floating point comparisons can be ``decoded'' as follows.
|
||||
In IEEE floating point, there are four different basic comparisons
|
||||
tests that we can performed given two numbers $a$ and $y$:
|
||||
\begin{description}
|
||||
\item[$a < b$] Is $a$ less than $b$?
|
||||
\item[$a = b$] Is $a$ equal to $b$?
|
||||
\item[$a > b$] Is $a$ greater than to $b$?
|
||||
\item[$a ? b$] Are $a$ and $b$ unordered (incomparable)?
|
||||
\end{description}
|
||||
Comparisons can be joined together. For example,
|
||||
given two double-precision floating point expressions $a$ and $b$,
|
||||
the expression \verb|FCMP(64,<=>,a,b)|
|
||||
asks whether $a$ is less than, equal to or greater than $b$, i.e.~whether
|
||||
$a$ and $b$ are comparable.
|
||||
The special symbol \verb|!| negates
|
||||
the meaning the of comparison. For example, \verb|FCMP(64,!>=,a,b)|
|
||||
means testing whether $a$ is less than or incomparable with $b$.
|
||||
|
||||
\subsection{Integer Expressions}
|
||||
|
||||
A reference to the $i$th
|
||||
integer register with an $n$-bit value is written
|
||||
as \sml{REG(}$n$,$i$\sml{)}. The operators \sml{LI}, \sml{LI32},
|
||||
and \sml{LABEL}, \sml{CONST} are used to represent constant expressions
|
||||
of various forms. The sizes of these constants are inferred from context.
|
||||
\begin{SML}
|
||||
REG : ty * reg -> rexp
|
||||
LI : int -> rexp
|
||||
LI32 : Word32.word -> rexp
|
||||
LABEL : LabelExp.labexp -> rexp
|
||||
CONST : Constant.const -> rexp
|
||||
\end{SML}
|
||||
|
||||
The following figure lists all the basic integer operators and their
|
||||
intuitive meanings. All operators except \sml{NOTB, NEG, NEGT} are binary
|
||||
and have the type
|
||||
\begin{SML}
|
||||
ty * rexp * rexp -> rexp
|
||||
\end{SML}
|
||||
The operators \sml{NOTB, NEG, NEGT} have the type
|
||||
\begin{SML}
|
||||
ty * rexp -> rexp
|
||||
\end{SML}
|
||||
|
||||
\begin{tabular}{|l|l|} \hline
|
||||
\sml{ADD} & Twos complement addition \\
|
||||
\sml{NEG} & negation \\
|
||||
\sml{SUB} & Twos complement subtraction \\
|
||||
\sml{MULS} & Signed multiplication \\
|
||||
\sml{DIVS} & Signed division, round to zero (nontrapping) \\
|
||||
\sml{QUOTS} & Signed division, round to negative infinity (nontrapping) \\
|
||||
\sml{REMS} & Signed remainder (???) \\
|
||||
\sml{MULU} & Unsigned multiplication \\
|
||||
\sml{DIVU} & Unsigned division \\
|
||||
\sml{REMU} & Unsigned remainder \\
|
||||
\sml{NEGT} & signed negation, trap on overflow \\
|
||||
\sml{ADDT} & Signed addition, trap on overflow \\
|
||||
\sml{SUBT} & Signed subtraction, trap on overflow \\
|
||||
\sml{MULT} & Signed multiplication, trap on overflow \\
|
||||
\sml{DIVT} & Signed division, round to zero,
|
||||
trap on overflow or division by zero \\
|
||||
\sml{QUOTT} & Signed division, round to negative infinity, trap on overflow or division by zero \\
|
||||
\sml{REMT} & Signed remainder, trap on division by zero \\
|
||||
\sml{ANDB} & bitwise and \\
|
||||
\sml{ORB} & bitwise or \\
|
||||
\sml{XORB} & bitwise exclusive or \\
|
||||
\sml{NOTB} & ones complement \\
|
||||
\sml{SRA} & arithmetic right shift \\
|
||||
\sml{SRL} & logical right shift \\
|
||||
\sml{SLL} & logical left shift \\
|
||||
\hline\end{tabular}
|
||||
|
||||
\subsubsection{Sign and Zero Extension}
|
||||
Sign extension and zero extension are written using the operator
|
||||
\sml{CVTI2I}. \sml{CVTI2I(}$m$,\sml{SIGN_EXTEND},$n$,$e$\sml{)}
|
||||
sign extends the $n$-bit value $e$ to an $m$-bit value, i.e. the
|
||||
$n-1$th bit is of $e$ is treated as the sign bit. Similarly,
|
||||
\sml{CVTI2I(}$m$,\sml{ZERO_EXTEND},$n$,$e$\sml{)}
|
||||
zero extends an $n$-bit value to an $m$-bit
|
||||
value. If $m \le n$, then
|
||||
\sml{CVTI2I(}$m$,\sml{SIGN_EXTEND},$n$,$e$\sml{)} =
|
||||
\sml{CVTI2I}($m$,\sml{ZERO_EXTEND},$n$,$e$\sml{)}.
|
||||
|
||||
\begin{SML}
|
||||
datatype ext = SIGN_EXTEND | ZERO_EXTEND
|
||||
CVTI2I : ty * ext * ty * rexp -> rexp
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Conditional Move} \label{sec:cond-move}
|
||||
Most new superscalar architectures incorporate conditional move
|
||||
instructions in their ISAs.
|
||||
Modern VLIW architectures also directly support full predication.
|
||||
Since branching (especially with data dependent branches) can
|
||||
introduce extra latencies in highly pipelined architectures,
|
||||
condtional moves should be used in place of short branch sequences.
|
||||
MLTree provide a conditional move instruction \sml{COND},
|
||||
to make it possible to directly express conditional moves without using
|
||||
branches.
|
||||
\begin{SML}
|
||||
COND : ty * ccexp * rexp * rexp -> rexp
|
||||
\end{SML}
|
||||
|
||||
Semantically, \sml{COND(}\emph{ty},\emph{cc},$a$,$b$\sml{)} means to evaluate
|
||||
\emph{cc}, and if \emph{cc} evaluates to true then the value of the entire expression is
|
||||
$a$; otherwise the value is $b$. Note that $a$ and $b$ are allowed to be
|
||||
\emph{eagerly}
|
||||
evaluated. In fact, we are allowed to evaluate to \emph{both}
|
||||
branches, one branch, or neither~\footnote{When possible.}.
|
||||
|
||||
Various idioms of the \sml{COND} form are useful for expressing common
|
||||
constructs in many programming languages. For example, MLTree does not
|
||||
provide a primitive construct for converting an integer value \sml{x} to a
|
||||
boolean value (0 or 1). But using \sml{COND}, this is expressible as
|
||||
\sml{COND(32,CMP(32,NE,x,LI 0),LI 1,LI 0)}. SML/NJ represents
|
||||
the boolean values true and false as machine integers 3 and 1 respectively.
|
||||
To convert a boolean condition $e$ into an ML boolean value, we can use
|
||||
\begin{SML}
|
||||
COND(32,e,LI 3,LI 1)
|
||||
\end{SML}
|
||||
|
||||
Common C idioms can be easily mapped into the \sml{COND} form. For example,
|
||||
\begin{itemize}
|
||||
\item \verb|if (e1) x = y| translates into
|
||||
\sml{MV(32,x,COND(32,e1,REG(32,y),REG(32,x)))}
|
||||
\item
|
||||
\begin{verbatim}
|
||||
x = e1;
|
||||
if (e2) x = y
|
||||
\end{verbatim}
|
||||
translates into
|
||||
\sml{MV(32,x,COND(32,e2,REG(32,y),e1))}
|
||||
\item \verb|x = e1 == e2| translates into
|
||||
\sml{MV(32,x,COND(32,CMP(32,EQ,e1,e2),LI 1,LI 0)}
|
||||
\item \verb|x = ! e| translates into
|
||||
\sml{MV(32,x,COND(32,CMP(32,NE,e,LI 0),LI 1,LI 0)}
|
||||
\item \verb|x = e ? y : z| translates into
|
||||
\sml{MV(32,x,COND(32,e,REG(32,y),REG(32,z)))}, and
|
||||
\item \verb|x = y < z ? y : z| translates into
|
||||
\begin{alltt}
|
||||
MV(32,x,
|
||||
COND(32,
|
||||
CMP(32,LT,REG(32,y),REG(32,z)),
|
||||
REG(32,y),REG(32,z)))
|
||||
\end{alltt}
|
||||
\end{itemize}
|
||||
|
||||
In general, the \sml{COND} form should be used in place of MLTree's branching
|
||||
constructs whenever possible, since the former is usually highly
|
||||
optimized in various MLRISC backends.
|
||||
|
||||
\subsubsection{Integer Loads}
|
||||
|
||||
Integer loads are written using the constructor \verb|LOAD|.
|
||||
\begin{SML}
|
||||
LOAD : ty * rexp * Region.region -> rexp
|
||||
\end{SML}
|
||||
The client is required to specify a \href{regions.html}{region} that
|
||||
serves as aliasing information for the load.
|
||||
|
||||
\subsubsection{Miscellaneous Integer Operators}
|
||||
|
||||
An expression of the \sml{LET}($s$,$e$) evaluates the statement $s$ for
|
||||
its effect, and then return the value of expression $e$.
|
||||
\begin{SML}
|
||||
LET : stm * rexp -> rexp
|
||||
\end{SML}
|
||||
Since the order of evaluation is MLTree operators are
|
||||
\emph{unspecified}
|
||||
the use of this operator should be severely restricted to only
|
||||
\emph{side-effect}-free forms.
|
||||
|
||||
\subsection{Floating Point Expressions}
|
||||
|
||||
Floating registers are referenced using the term \sml{FREG}. The
|
||||
$i$th floating point register with type $n$ is written
|
||||
as \sml{FREG(}$n$,$i$\sml{)}.
|
||||
\begin{SML}
|
||||
FREG : fty * src -> fexp
|
||||
\end{SML}
|
||||
|
||||
Built-in floating point operations include addition (\sml{FADD}),
|
||||
subtraction (\sml{FSUB}), multiplication (\sml{FMUL}), division
|
||||
(\sml{FDIV}), absolute value (\sml{FABS}), negation (\sml{FNEG})
|
||||
and square root (\sml{FSQRT}).
|
||||
\begin{SML}
|
||||
FADD : fty * fexp * fexp -> fexp
|
||||
FSUB : fty * fexp * fexp -> fexp
|
||||
FMUL : fty * fexp * fexp -> fexp
|
||||
FDIV : fty * fexp * fexp -> fexp
|
||||
FABS : fty * fexp -> fexp
|
||||
FNEG : fty * fexp -> fexp
|
||||
FSQRT : fty * fexp -> fexp
|
||||
\end{SML}
|
||||
|
||||
A special operator is provided for manipulating signs.
|
||||
To combine the sign of $a$ with the magnitude of $b$, we can
|
||||
write \sml{FCOPYSIGN(}$a$,$b$\sml{)}\footnote{What should
|
||||
happen if $a$ or $b$ is nan?}.
|
||||
\begin{SML}
|
||||
FCOPYSIGN : fty * fexp * fexp -> fexp
|
||||
\end{SML}
|
||||
|
||||
To convert an $n$-bit signed integer $e$ into an $m$-bit floating point value,
|
||||
we can write \sml{CVTI2F(}$m$,$n$,$e$\sml{)}\footnote{What happen to unsigned integers?}.
|
||||
\begin{SML}
|
||||
CVTI2F : fty * ty * rexp -> fexp
|
||||
\end{SML}
|
||||
|
||||
Similarly, to convert an $n$-bit floating point value $e$ to an $m$-bit
|
||||
floating point value, we can write \sml{CVTF2F(}$m$,$n$,$e$\sml{)}\footnote{
|
||||
What is the rounding semantics?}.
|
||||
\begin{SML}
|
||||
CVTF2F : fty * fty * -> fexp
|
||||
\end{SML}
|
||||
|
||||
\begin{SML}
|
||||
datatype rounding_mode = TO_NEAREST | TO_NEGINF | TO_POSINF | TO_ZERO
|
||||
CVTF2I : ty * rounding_mode * fty * fexp -> rexp
|
||||
\end{SML}
|
||||
|
||||
\begin{SML}
|
||||
FLOAD : fty * rexp * Region.region -> fexp
|
||||
\end{SML}
|
||||
|
||||
\subsection{Condition Expressions}
|
||||
Unlike languages like C, MLTree makes the distinction between condition
|
||||
expressions and integer expressions. This distinction is necessary for
|
||||
two purposes:
|
||||
\begin{itemize}
|
||||
\item It clarifies the proper meaning intended in a program, and
|
||||
\item It makes to possible for a MLRISC backend to map condition
|
||||
expressions efficiently onto various machine architectures with different
|
||||
condition code models. For example, architectures like the Intel x86,
|
||||
Sparc V8, and PowerPC contains dedicated condition code registers, which
|
||||
are read from and written to by branching and comparison instructions.
|
||||
On the other hand, architectures such as the Texas Instrument C6, PA RISC,
|
||||
Sparc V9, and Alpha does not include dedicated condition code registers.
|
||||
Conditional code registers in these architectures
|
||||
can be simulated by integer registers.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
A conditional code register bit can be referenced using the constructors
|
||||
\sml{CC} and \sml{FCC}. Note that the \emph{condition} must be specified
|
||||
together with the condition code register.
|
||||
\begin{SML}
|
||||
CC : Basis.cond * src -> ccexp
|
||||
FCC : Basis.fcond * src -> ccexp
|
||||
\end{SML}
|
||||
For example, to test the \verb|Z| bit of the \verb|%psr| register on the
|
||||
Sparc architecture, we can used \sml{CC(EQ,SparcCells.psr)}.
|
||||
|
||||
The comparison operators \sml{CMP} and \sml{FCMP} performs integer and
|
||||
floating point tests. Both of these are \emph{typed} by the precision
|
||||
in which the test must be performed under.
|
||||
\begin{SML}
|
||||
CMP : ty * Basis.cond * rexp * rexp -> ccexp
|
||||
FCMP : fty * Basis.fcond * fexp * fexp -> ccexp
|
||||
\end{SML}
|
||||
|
||||
Condition code expressions may be combined with the following
|
||||
logical connectives, which have the obvious meanings.
|
||||
\begin{SML}
|
||||
TRUE : ccexp
|
||||
FALSE : ccexp
|
||||
NOT : ccexp -> ccexp
|
||||
AND : ccexp * ccexp -> ccexp
|
||||
OR : ccexp * ccexp -> ccexp
|
||||
XOR : ccexp * ccexp -> ccexp
|
||||
\end{SML}
|
||||
|
||||
\subsection{Statements}
|
||||
|
||||
Statement forms in MLTree includes assignments, parallel copies,
|
||||
jumps and condition branches, calls and returns, stores, sequencing,
|
||||
and annotation.
|
||||
|
||||
\subsubsection{Assignments}
|
||||
|
||||
Assignments are segregated among the integer, floating point and
|
||||
conditional code types. In addition, all assignments are \emph{typed}
|
||||
by the precision of destination register.
|
||||
|
||||
\begin{SML}
|
||||
MV : ty * dst * rexp -> stm
|
||||
FMV : fty * dst * fexp -> stm
|
||||
CCMV : dst * ccexp -> stm
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Parallel Copies}
|
||||
|
||||
Special forms are provided for parallel copies for integer and
|
||||
floating point registers. It is important to emphasize that
|
||||
the semantics is that all assignments are performed in parallel.
|
||||
|
||||
\begin{SML}
|
||||
COPY : ty * dst list * src list -> stm
|
||||
FCOPY : fty * dst list * src list -> stm
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{Jumps and Conditional Branches}
|
||||
|
||||
Jumps and conditional branches in MLTree take two additional set of
|
||||
annotations. The first represents the \newdef{control flow} and is denoted
|
||||
by the type \sml{controlflow}. The second represent
|
||||
\newdef{control-dependence} and \newdef{anti-control-dependence}
|
||||
and is denoted by the type \sml{ctrl}.
|
||||
|
||||
\begin{SML}
|
||||
type controlflow = Label.label list
|
||||
type ctrl = reg list
|
||||
\end{SML}
|
||||
Control flow annotation is simply a list of labels, which represents
|
||||
the set of possible targets of the associated jump. Control dependence
|
||||
annotations attached to a branch or jump instruction represents the
|
||||
new definition of \newdef{pseudo control dependence predicates}. These
|
||||
predicates have no associated dynamic semantics; rather they are used
|
||||
to constraint the set of potential code motion in an optimizer
|
||||
(more on this later).
|
||||
|
||||
The primitive jumps and conditional branch forms are represented
|
||||
by the constructors \sml{JMP}, \sml{BCC}.
|
||||
\begin{SML}
|
||||
JMP : ctrl * rexp * controlflow -> stm
|
||||
BCC : ctrl * ccexp * Label.label -> stm
|
||||
\end{SML}
|
||||
|
||||
In addition to \sml{JMP} and \sml{BCC},
|
||||
there is a \emph{structured} if/then/else statement.
|
||||
\begin{SML}
|
||||
IF : ctrl * ccexp * stm * stm -> stm
|
||||
\end{SML}
|
||||
|
||||
Semantically, \sml{IF}($c,x,y,z$) is identical to
|
||||
\begin{SML}
|
||||
BCC(\(c\), \(x\), L1)
|
||||
\(z\)
|
||||
JMP([], L2)
|
||||
DEFINE L1
|
||||
\(y\)
|
||||
DEFINE L2
|
||||
\end{SML}
|
||||
where \verb|L1| and \verb|L2| are new labels, as expected.
|
||||
|
||||
Here's an example of how control dependence predicates are used.
|
||||
Consider the following MLTree statement:
|
||||
\begin{SML}
|
||||
IF([p], CMP(32, NE, REG(32, a), LI 0),
|
||||
MV(32, b, PRED(LOAD(32, m, ...)), p),
|
||||
MV(32, b, LOAD(32, n, ...)))
|
||||
\end{SML}
|
||||
In the first alternative of the \verb|IF|, the \verb|LOAD|
|
||||
expression is constrainted by the control dependence
|
||||
predicate \verb|p| defined in the \verb|IF|,
|
||||
using the predicate constructor \verb|PRED|. These states that
|
||||
the load is \emph{control dependent} on the test of the branch,
|
||||
and thus it may not be legally hoisted above the branch without
|
||||
potentially violating the semantics of the program.
|
||||
For example,
|
||||
semantics violation may happen if the value of \verb|m| and \verb|a|
|
||||
is corrolated, and whenever \verb|a| = 0, the address in \verb|m| is
|
||||
not a legal address.
|
||||
|
||||
Note that on architectures with speculative loads,
|
||||
the control dependence information can be used to
|
||||
guide the transformation of control dependent loads into speculative loads.
|
||||
|
||||
Now in constrast, the \verb|LOAD| in the second alternative is not
|
||||
control dependent on the control dependent predicate \verb|p|, and
|
||||
thus it is safe and legal to hoist the load above the test, as in
|
||||
\begin{SML}
|
||||
MV(32, b, LOAD(32, n, ...));
|
||||
IF([p], CMP(32, NE, REG(32, a), LI 0),
|
||||
MV(32, b, PRED(LOAD(32, m, ...)), p),
|
||||
SEQ []
|
||||
)
|
||||
\end{SML}
|
||||
Of course, such transformation is only performed if the optimizer
|
||||
phases think that it can benefit performance. Thus the control dependence
|
||||
information does \emph{not} directly specify any transformations, but it
|
||||
is rather used to indicate when aggressive code motions are legal and safe.
|
||||
|
||||
\subsubsection{Calls and Returns}
|
||||
|
||||
Calls and returns in MLTree are specified using the constructors
|
||||
\verb|CALL| and \verb|RET|, which have the following types.
|
||||
\begin{SML}
|
||||
CALL : rexp * controlflow * mlrisc * mlrisc *
|
||||
ctrl * ctrl * Region.region -> stm
|
||||
RET : ctrl * controlflow -> stm
|
||||
\end{SML}
|
||||
|
||||
The \verb|CALL| form is particularly complex, and require some explanation.
|
||||
Basically the seven parameters are, in order:
|
||||
\begin{description}
|
||||
\item[address] of the called routine.
|
||||
\item[control flow] annotation for this call. This information
|
||||
specifies the potential targets of this call instruction. Currently
|
||||
this information is ignored but will be useful for interprocedural
|
||||
optimizations in the future.
|
||||
\item[definition and use] These lists specify the list of
|
||||
potential definition and uses during the execution of the call.
|
||||
Definitions and uses are represented as the type \newtype{mlrisc} list.
|
||||
The contructors for this type is:
|
||||
\begin{SML}
|
||||
CCR : ccexp -> mlrisc
|
||||
GPR : rexp -> mlrisc
|
||||
FPR : fexp -> mlrisc
|
||||
\end{SML}
|
||||
\item[definition of control and anti-control dependence]
|
||||
These two lists specifies definitions of control and anti-control dependence.
|
||||
\item[region] annotation for the call, which summarizes
|
||||
the set of potential memory references during execution of the call.
|
||||
\end{description}
|
||||
|
||||
The matching return statement constructor \verb|RET| has two
|
||||
arguments. These are:
|
||||
\begin{description}
|
||||
\item[anti-control dependence] This parameter represents
|
||||
the set of anti-control dependence predicates defined by the return
|
||||
statement.
|
||||
\item[control flow] This parameter specifies the set of matching
|
||||
procedure entry points of this return. For example, suppose we have
|
||||
a procedure with entry points \verb|f| and \verb|f'|.
|
||||
Then the MLTree statements
|
||||
\begin{verbatim}
|
||||
f: ...
|
||||
JMP L1
|
||||
f': ...
|
||||
L1: ...
|
||||
RET ([], [f, f'])
|
||||
\end{verbatim}
|
||||
\noindent can be used to specify that the return is either from
|
||||
the entries \verb|f| or \verb|f'|.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{Stores}
|
||||
Stores to integer and floating points are specified using the
|
||||
constructors \verb|STORE| and \verb|FSTORE|.
|
||||
\begin{SML}
|
||||
STORE : ty * rexp * rexp * Region.region -> stm
|
||||
FSTORE : fty * rexp * fexp * Region.region -> stm
|
||||
\end{SML}
|
||||
|
||||
The general form is
|
||||
\begin{SML}
|
||||
STORE(\(width\), \(address\), \(data\), \(region\))
|
||||
\end{SML}
|
||||
|
||||
Stores for condition codes are not provided.
|
||||
\subsubsection{Miscelleneous Statements}
|
||||
|
||||
Other useful statement forms of MLTree are for sequencing (\verb|SEQ|),
|
||||
defining a local label (\verb|DEFINE|).
|
||||
\begin{SML}
|
||||
SEQ : stm list -> stm
|
||||
DEFINE : Label.label -> stm
|
||||
\end{SML}
|
||||
The constructor \sml{DEFINE L} has the same meaning as
|
||||
executing the method \sml{defineLabel L} in the
|
||||
\href{stream.html}{stream interface}.
|
||||
|
||||
\subsection{Annotations}
|
||||
\href{annotations.html}{Annotations} are used as the generic mechanism for
|
||||
exchanging information between different phases of the MLRISC system, and
|
||||
between a compiler front end and the MLRISC back end.
|
||||
The following constructors can be used to annotate a MLTree term with
|
||||
an annotation:
|
||||
\begin{SML}
|
||||
MARK : rexp * Annotations.annotation -> rexp
|
||||
FMARK : fexp * Annotations.annotation -> fexp
|
||||
CCMARK : ccexp * Annotations.annotation -> ccexp
|
||||
ANNOTATION : stm * Annotations.annotation -> stm
|
||||
\end{SML}
|
||||
@@ -0,0 +1,60 @@
|
||||
\section{Optimizations}
|
||||
|
||||
MLRISC assumes that all high level optimizations (target
|
||||
independent) have already been performed. This includes things like
|
||||
inlining, array dependence analysis, and array bounds check
|
||||
elimination. The target dependent optimizations that remain include
|
||||
register allocation, scheduling and traditional optimizations to
|
||||
support scheduling.
|
||||
|
||||
\subsection{Register allocation}
|
||||
|
||||
MLRISC includes a state-of-the-art graph-coloring based register
|
||||
allocator that has an aggressive algorithm for copy-propagation. The
|
||||
latter guarantees to eliminate copy instructions without introducing
|
||||
spills.
|
||||
|
||||
Spills in the register allocator are under the control of the
|
||||
client via call-backs to the front end. Where to spill registers and
|
||||
the associated information that must be maintained is client specific
|
||||
and varies with the compiler.
|
||||
|
||||
\subsection{Scheduling for Superscalar Architectures}
|
||||
Several algorithms for acyclic global scheduling are provided. These
|
||||
include:
|
||||
|
||||
\begin{itemize}
|
||||
\item Superblock,
|
||||
\item a variant of Bernstein/Rodeh, and
|
||||
\item Percolation based scheduling.
|
||||
\end{itemize}
|
||||
|
||||
These algorithms tend to be quite complex and require a large number
|
||||
of support data structures and analysis. These include data structures
|
||||
such as:
|
||||
|
||||
\begin{itemize}
|
||||
\item dominator/post dominator trees,
|
||||
\item loop nesting tree,
|
||||
\item control dependency graphs, and
|
||||
\item data dependency graphs.
|
||||
\end{itemize}
|
||||
|
||||
Support analysis and optimization include:
|
||||
|
||||
\begin{itemize}
|
||||
\item constant propagation,
|
||||
\item global value numbering,
|
||||
\item global code motion, and
|
||||
\item loop invariant hoisting.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{VLIW Compilation}
|
||||
MLRISC also contains a framework for the compilation of
|
||||
predicated VLIW architectures.
|
||||
Currently, the following algorithms have been implemented.
|
||||
\begin{itemize}
|
||||
\item hyperblock formation
|
||||
\item hyperblock scheduling
|
||||
\item modulo scheduling
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,3 @@
|
||||
\section{The PowerPC Back End}
|
||||
|
||||
No documentation yet.
|
||||
@@ -0,0 +1,42 @@
|
||||
\section{Problem Statement}
|
||||
|
||||
Writing a native code generator for any language is a significant
|
||||
investment, especially for todays modern processors with require extensive
|
||||
compiler support to achieve high performance. The algorithms that must
|
||||
be used to generate high quality code are complex, sometimes quite
|
||||
delicate, and require substantial infrastructure.
|
||||
|
||||
\image{Retargeting compiler}{pictures/png/uncol2.png}{align=right}
|
||||
A specific architecture has a
|
||||
relatively short life time in relation to the time taken to build
|
||||
the code generator, and one quickly needs the ability to retarget
|
||||
to new versions of the architecture, or to different target
|
||||
architectures. This is by no means an open problem. There are many
|
||||
compilers today that target multiple architectures, however the
|
||||
quality of code varies. For example,
|
||||
\begin{color}{red}\begin{Italics}lcc\end{Italics}\end{color}
|
||||
by Chris Fraser and David Hansen does
|
||||
no back end optimizations;
|
||||
\begin{color}{red}\begin{Italics}gcc\end{Italics}\end{color}
|
||||
from the Free Software Foundation does extensive peephole and simple
|
||||
data flow optimizations, and falls short on advanced superscalar
|
||||
optimizations; and finally the
|
||||
\begin{color}{red}\begin{Italics}IMPACT\end{Italics}\end{color}
|
||||
compiler done by the Impact group at the
|
||||
University of Illinois specializes in more advanced superscalar
|
||||
and predicated architectures.
|
||||
|
||||
\br{clear=right}
|
||||
|
||||
\image{UNCOL?}{pictures/png/uncol.png}{align=left} Assuming
|
||||
the retargeting issue is solved, one would like to use all the
|
||||
developed infrastructure for multiple source languages. This
|
||||
problem is far from solved; even though \italics{gcc} has been used
|
||||
for multiple languages like Ada, Pascal, and Modula III, each of
|
||||
these have similiar execution models or were forced to adopt C
|
||||
conventions. \italics{gcc} cannot be used directly for languages
|
||||
such as Lisp, Smalltalk, Haskell, or ML that have radically
|
||||
different execution models and special requirements to support
|
||||
advanced language features.
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
\section{Client Defined Pseudo Ops}
|
||||
\subsection{Introduction}
|
||||
\newdef{Pseudo ops}
|
||||
are client defined instruction stream markers. They
|
||||
can be used to represent assembly directives.
|
||||
Pseudo ops should satisfy the following signature:
|
||||
\begin{SML}
|
||||
signature \mlrischref{instructions/pseudoOps.sig}{PSEUDO_OPS} = sig
|
||||
type pseudo_op
|
||||
val toString : pseudo_op -> string
|
||||
val emitValue : {pOp:pseudo_op, loc:int, emit:Word8.word -> unit} -> unit
|
||||
val sizeOf : pseudo_op * int -> int
|
||||
val adjustLabels : pseudo_op * int -> bool
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The method that is required is:
|
||||
\begin{itemize}
|
||||
\item \sml{toString} -- pretty printing the pseudo in assembly format.
|
||||
\end{itemize}
|
||||
|
||||
When machine code generation is used, we also have to implement
|
||||
the following methods:
|
||||
\begin{itemize}
|
||||
\item \sml{emitValue} --
|
||||
emit value of pseudo op give current location counter and output
|
||||
stream. The value emitted should respect the endianness of the
|
||||
target machine.
|
||||
\item \sml{sizeOf} --
|
||||
Size of the pseudo op in bytes given the current location counter
|
||||
The location counter is provided in case some pseudo ops are
|
||||
dependent on alignment considerations.
|
||||
\item \sml{adjustLabels} --
|
||||
adjust the value of labels in the pseudo op given the current
|
||||
location counter.
|
||||
\end{itemize}
|
||||
These methods are involved during the
|
||||
\href{span-dep.html}{span dependence resolution} phase to determine
|
||||
the size and layout of the pseudo ops.
|
||||
@@ -0,0 +1,8 @@
|
||||
\section{Register Allocator}
|
||||
|
||||
The MLRISC register allocator implements the iterated-coalescing algorithm
|
||||
described in POPL '96 [George, Appel]. The details are described in these
|
||||
papers
|
||||
\begin{enumerate}
|
||||
\item \externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/compiler-notes/new-ra.ps}{A New MLRISC Register Allocator}
|
||||
\end{enumerate}
|
||||
@@ -0,0 +1,26 @@
|
||||
\section{Regions}
|
||||
\subsubsection{Overview}
|
||||
|
||||
The MLRISC system uses user defined type called
|
||||
\newdef{regions} to propagate
|
||||
aliasing information to the backend. This type is
|
||||
abstract and no constraint is imposed on how it is implemented.
|
||||
The advantage of this is that the client can optimize the representation
|
||||
of the region information according to the semantics of the source language.
|
||||
The downside of this freedom is that the client has to implement
|
||||
various modules to extract information from the regions datatype
|
||||
required by various optimization phases.
|
||||
|
||||
For clients that do not want to implement their own regions datatype,
|
||||
there is now a new generic mechanism, called
|
||||
\newdef{MLRiscRegions}, built on top of
|
||||
the regions concept, for propagating both:
|
||||
\begin{itemize}
|
||||
\item Aliasing information, and
|
||||
\item Control dependence/anti-control dependence information
|
||||
\end{itemize}
|
||||
Both kinds of information are crucial for extracting parallelism
|
||||
from the target code, and are used in all optimizations that perform code
|
||||
motion, such as SSA optimizations and all scheduling optimizations.
|
||||
|
||||
\subsubsection{MLRisc Regions}
|
||||
@@ -0,0 +1,16 @@
|
||||
\section{Regmap}
|
||||
A \newdef{regmap}
|
||||
is a mapping from virtual register to virtual or physical
|
||||
register, and is used by MLRISC register allocators to
|
||||
represent the current binding of virtual registers. Regmaps are implemented
|
||||
as \mlrischref{library/intmap.sml}{Intmap}
|
||||
in MLRISC, and are defined in the
|
||||
\href{cells.html}{CELLS} interface.
|
||||
|
||||
Regmaps are used in phases such as
|
||||
\href{asm.html}{assembly generation} and
|
||||
\href{mc.html}{machine code}. MLRISC program representations such
|
||||
\href{cluster.html}{clusters} and \href{mlrisc-ir.html}{IR}
|
||||
each contains a global regmap per compilation unit. Representations
|
||||
such as \href{hyperblock.html}{hyperblock} may contain its own
|
||||
regmap, which overrides the global regmap.
|
||||
@@ -0,0 +1,3 @@
|
||||
\section{Requirements}
|
||||
The most up-to-date MLRISC system requires
|
||||
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/index.html}{Standard ML of New Jersey} version 110.0.3 or later.
|
||||
@@ -0,0 +1,390 @@
|
||||
%
|
||||
% This is derived from alltt.sty
|
||||
%
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{sml}[1998/12/17 defines sml environment]
|
||||
|
||||
%
|
||||
% Font for typesetting sml code, default is \tt
|
||||
%
|
||||
\newcommand{\smlFont}{\verbatim@font}
|
||||
\newcommand{\smlCommentSize}{\small}
|
||||
\newcommand{\smlCommentFont}{\it}
|
||||
\newcommand{\smlNumberFont}{\smlFont}
|
||||
\newcommand{\smlNumberStyle}[1]{\arabic{#1}}
|
||||
\newcommand{\sml@font}{\smlFont}
|
||||
|
||||
|
||||
%
|
||||
% Turn on and off dollar sign
|
||||
%
|
||||
\newif\ifsml@dollar
|
||||
\newcommand{\smlDollarOn}{\sml@dollartrue}
|
||||
\newcommand{\smlDollarOff}{\sml@dollarfalse}
|
||||
\smlDollarOff
|
||||
|
||||
%
|
||||
% Font for typesetting sml type variables, default is \it
|
||||
%
|
||||
\newcommand{\smlTypeVarFont}{\it}
|
||||
|
||||
%
|
||||
% Commands for typesetting type variables and keywords.
|
||||
% Can be overridden by user.
|
||||
%
|
||||
\newcommand{\makeSmlTypeVar}[1]{'{\smlTypeVarFont#1}}
|
||||
\newcommand{\makeSmlKeyword}[1]{{\bf#1}}
|
||||
\newcommand{\BeginSmlComment}{\begingroup\smlCommentSize\smlCommentFont}
|
||||
\newcommand{\EndSmlComment}{\endgroup}
|
||||
|
||||
%
|
||||
% Command to declare a new type variable translation
|
||||
% and keywords
|
||||
%
|
||||
\newcommand{\smlTypeVar}[2]{
|
||||
\expandafter\newcommand\csname smltv@#1\endcsname{#2}
|
||||
}
|
||||
\newcommand{\smlRemoveTypeVar}[1]{
|
||||
\expandafter\newcommand\csname smltv@#1\endcsname\relax
|
||||
}
|
||||
\newcommand{\smlNewKeyword}[1]{
|
||||
\expandafter\def\csname smlkw@#1\endcsname{\makeSmlKeyword{#1}}
|
||||
}
|
||||
\newcommand{\smlDefineNewKeyword}[2]{
|
||||
\expandafter\def\csname smlkw@#1\endcsname{#2}
|
||||
}
|
||||
\newcommand{\smlRemoveKeyword}[1]{
|
||||
\expandafter\newcommand\csname smlkw@#1\endcsname\relax
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\newcommand{\sml@expandtv}[1]{%
|
||||
\if\csname smltv@#1\endcsname\relax\makeSmlTypeVar{#1}\else%
|
||||
\csname smltv@#1\endcsname\fi}
|
||||
|
||||
\newcommand{\sml@expandkw}[1]{%
|
||||
\if\csname smlkw@#1\endcsname\relax{#1}\else\csname smlkw@#1\endcsname\fi}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% This is a lexer that translates type variables and keywords
|
||||
% #1 is the eof character
|
||||
% #2 is the current state (actually a macro)
|
||||
% which can be:
|
||||
% 0 -- program text
|
||||
% 1 -- type variable
|
||||
% 2 -- program text found (
|
||||
% 3 -- in comment
|
||||
% 4 -- in comment type variable
|
||||
% 5 -- in comment found *
|
||||
% #3 is the current string
|
||||
% #4 is the next token
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\newcommand{\sml@startlexer}[1]{\sml@lexer{#1}{0}{}}
|
||||
\newcommand{\sml@lexer}[4]{%
|
||||
\ifx#4a\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4b\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4c\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4d\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4e\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4f\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4g\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4h\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4i\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4j\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4k\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4l\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4m\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4n\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4o\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4p\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4q\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4r\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4s\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4t\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4u\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4v\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4w\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4x\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4y\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4z\let\sml@nexttok=\sml@getletter%
|
||||
\else\ifx#4_\let\sml@nexttok=\sml@getletter%
|
||||
\else%
|
||||
\let\sml@nexttok=\sml@transition% is not a letter
|
||||
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
|
||||
\sml@nexttok{#1}{#2}{#3}{#4}%
|
||||
}
|
||||
|
||||
\newcommand{\sml@getletter}[4]{\sml@lexer{#1}{#2}{#3#4}} % get more character
|
||||
|
||||
%
|
||||
% Do something according to the lookahead character
|
||||
%
|
||||
\newcommand{\sml@transition}[4]{%
|
||||
%\message{|#3|}%
|
||||
\if\noexpand#4'%
|
||||
\let\sml@nextaction=\sml@tokenizetv%
|
||||
\else\if\noexpand#4#1%
|
||||
\let\sml@nextaction=\sml@endlexer%
|
||||
\else\ifx#4(%
|
||||
\let\sml@nextaction=\sml@lparen%
|
||||
\else\ifx#4)%
|
||||
\let\sml@nextaction=\sml@rparen%
|
||||
\else\ifx#4*%
|
||||
\let\sml@nextaction=\sml@star%
|
||||
\else%
|
||||
\let\sml@nextaction=\sml@tokenizekw%
|
||||
\fi\fi\fi\fi\fi%
|
||||
\sml@nextaction{#1}{#2}{#3}{#4}%
|
||||
}
|
||||
|
||||
% 0 -- program text
|
||||
% 1 -- type variable
|
||||
% 2 -- program text found (
|
||||
% 3 -- in comment
|
||||
% 4 -- in comment type variable
|
||||
% 5 -- in comment found *
|
||||
\newcommand{\sml@expand}[2]{%
|
||||
\ifcase#1\let\sml@process=\sml@expandkw\or%
|
||||
\let\sml@process=\sml@expandtv\or%
|
||||
\let\sml@process=\sml@expandkw\or%
|
||||
\let\sml@process=\sml@expandkw\or%
|
||||
\let\sml@process=\sml@expandtv\or%
|
||||
\let\sml@process=\sml@expandkw%
|
||||
\else\ERROR%
|
||||
\fi%
|
||||
\sml@process{#2}%
|
||||
}
|
||||
\newcommand{\sml@tokenizekw}[4]{\sml@expand{#2}{#3}#4\sml@lexer{#1}{\sml@deltakw{#2}}{}}
|
||||
\newcommand{\sml@tokenizetv}[4]{\sml@expand{#2}{#3}\sml@lexer{#1}{\sml@deltatv{#2}}{}}
|
||||
\newcommand{\sml@endlexer}[4]{\sml@expand{#2}{#3}}
|
||||
\newcommand{\sml@lparen}[4]{\sml@expand{#2}{#3}%
|
||||
(\sml@lexer{#1}{\sml@deltal{#2}}{}}
|
||||
\newcommand{\sml@rparen}[4]{\sml@expand{#2}{#3}%
|
||||
\sml@closecomment{#2})\sml@lexer{#1}{\sml@deltar{#2}}{}}
|
||||
\newcommand{\sml@star}[4]{\sml@expand{#2}{#3}*%
|
||||
\sml@opencomment{#2}\sml@lexer{#1}{\sml@deltas{#2}}{}}
|
||||
|
||||
% 0 -- program text
|
||||
% 1 -- type variable
|
||||
% 2 -- program text found (
|
||||
% 3 -- in comment
|
||||
% 4 -- in comment type variable
|
||||
% 5 -- in comment found *
|
||||
\newcommand{\sml@opencomment}[1]{\if2#1\BeginSmlComment\else\fi}
|
||||
\newcommand{\sml@closecomment}[1]{\if5#1\EndSmlComment\else\fi}
|
||||
\newcommand{\sml@deltakw}[1]{\ifcase#1 0\or0\or0\or3\or3\or3\else\ERROR\fi}
|
||||
\newcommand{\sml@deltatv}[1]{\ifcase#1 1\or1\or1\or4\or4\or4\else\ERROR\fi}
|
||||
\newcommand{\sml@deltal}[1]{\ifcase#1 2\or2\or2\or3\or3\or3\else\ERROR\fi}
|
||||
\newcommand{\sml@deltas}[1]{\ifcase#1 0\or0\or3\or5\or5\or5\else\ERROR\fi}
|
||||
\newcommand{\sml@deltar}[1]{\ifcase#1 0\or0\or0\or3\or3\or0\else\ERROR\fi}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% How to process type variables as active character:
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\newcommand{\sml@processtypevar}{\sml@lexty{}}
|
||||
\newcommand{\sml@lexty}[2]{\ifcat\noexpand#2a\let\sml@nextty=\sml@morety\else\let\sml@nextty=\sml@donety\fi\sml@nextty{#1}#2}
|
||||
\newcommand{\sml@morety}[2]{\sml@lexty{#1#2}}
|
||||
\newcommand{\sml@donety}[1]{\sml@expandtv{#1}}
|
||||
\newcommand{\sml@aftertypevar}{}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Macros for setting up verbatim mode
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Set up catcodes for verbatim mode
|
||||
%
|
||||
\begingroup
|
||||
\lccode`\~=`\'
|
||||
\lowercase{\endgroup
|
||||
\newcommand{\sml@settick}{\catcode`\'=\active\let~=\sml@processtypevar}
|
||||
\newcommand{\sml@verbatimmode}{%
|
||||
\let\sml@origprime=~%
|
||||
\sml@font%
|
||||
\@noligs%
|
||||
\catcode`\^=12%
|
||||
\catcode`\_=12%
|
||||
\ifsml@dollar\else\catcode`\$=12\fi%
|
||||
\catcode`\#=12%
|
||||
\catcode`\&=12%
|
||||
\catcode`\~=12%
|
||||
\catcode`\%=12%
|
||||
\everymath\expandafter{\the\everymath\sml@mathmode}%
|
||||
\everydisplay\expandafter{\the\everydisplay\sml@mathmode}%
|
||||
\everypar\expandafter{\the\everypar\unpenalty}%
|
||||
\sml@settick%
|
||||
\frenchspacing\@vobeyspaces% Preserve all spaces
|
||||
}
|
||||
|
||||
%
|
||||
% Set up catcodes for math mode
|
||||
%
|
||||
\newcommand{\sml@mathmode}{
|
||||
\catcode`\^=7 % Superscript
|
||||
\catcode`\_=8 % Subscript
|
||||
\catcode`\'=12 % prime
|
||||
\let~=\sml@origprime%
|
||||
}
|
||||
}
|
||||
|
||||
%
|
||||
% Set up display format
|
||||
%
|
||||
\newcommand{\sml@begindisplay}{%
|
||||
\begingroup
|
||||
%\trivlist \item
|
||||
\if@minipage% Insert paragraph break
|
||||
\else
|
||||
\vskip\parskip
|
||||
\fi
|
||||
\leftskip\@totalleftmargin
|
||||
\rightskip\z@skip
|
||||
\parindent\z@
|
||||
\parfillskip\@flushglue
|
||||
\parskip\z@skip
|
||||
\@@par
|
||||
\@tempswafalse
|
||||
\def\par{%
|
||||
\if@tempswa
|
||||
\leavevmode\null\@@par\penalty\interlinepenalty
|
||||
\else
|
||||
\@tempswatrue
|
||||
\ifhmode\@@par\penalty\interlinepenalty\fi
|
||||
\fi}
|
||||
\obeylines % Lines breaks are meaningful
|
||||
}
|
||||
|
||||
%
|
||||
% End display format
|
||||
%
|
||||
%\newcommand{\sml@enddisplay}{\endtrivlist\endgroup}
|
||||
\newcommand{\sml@enddisplay}{\endgroup}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% The main macros
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\newenvironment{smldisplay}{\sml@begindisplay\trivlist\item\sml@verbatimmode}{\endtrivlist\sml@enddisplay}
|
||||
|
||||
\newcommand{\sml}{\begingroup\sml@verbatimmode\sml@verb}
|
||||
\newcommand{\sml@verb}[1]{#1\endgroup}
|
||||
|
||||
\newsavebox{\sml@box}
|
||||
\newenvironment{sml@boxit}{\begin{lrbox}{\sml@box}
|
||||
\begin{minipage}[b]{\columnwidth}}
|
||||
{\end{minipage}\end{lrbox}\begin{center}\framebox[\columnwidth]{\usebox{\sml@box}}\end{center}}
|
||||
|
||||
\newenvironment{smlboxeddisplay}{\begin{sml@boxit}\begin{smldisplay}}{\end{smldisplay}\end{sml@boxit}}
|
||||
|
||||
\newcounter{sml@linecount}
|
||||
\newcounter{sml@increment}
|
||||
\newcommand{\sml@setuplineno}[2]{%
|
||||
\setcounter{sml@linecount}{#1}%
|
||||
\setcounter{sml@increment}{1}%
|
||||
\newcommand{\sml@showlinecount}%
|
||||
{\llap{\smlNumberFont\smlNumberStyle{sml@linecount}\ }}%
|
||||
\newcommand{\sml@inclineno}{\addtocounter{sml@increment}{-1}%
|
||||
\ifnum\value{sml@increment}=0\sml@showlinecount\setcounter{sml@increment}{#2}\else \fi%
|
||||
\addtocounter{sml@linecount}{1}}%
|
||||
\everypar{\sml@inclineno}%
|
||||
}
|
||||
|
||||
\newenvironment{smllisting}[2]%
|
||||
{\sml@begindisplay\sml@verbatimmode\sml@setuplineno{#1}{#2}}%
|
||||
{\sml@enddisplay}
|
||||
\newenvironment{smlboxedlisting}[2]%
|
||||
{\begin{sml@boxit}\begin{smllisting}{#1}{#2}}{\end{smllisting}\end{sml@boxit}}
|
||||
\newenvironment{smldisplay*}[1]{%
|
||||
\sml@begindisplay
|
||||
\let\sml@settick=\relax
|
||||
\sml@verbatimmode
|
||||
\sml@startlexer{#1}
|
||||
}{\sml@enddisplay}
|
||||
\newenvironment{smlboxeddisplay*}[1]%
|
||||
{\begin{sml@boxit}\begin{smldisplay*}{#1}}{\end{smldisplay*}\end{sml@boxit}}
|
||||
|
||||
|
||||
\begingroup
|
||||
\catcode`\^^A=12%
|
||||
\catcode`\<=1%
|
||||
\catcode`\>=2%
|
||||
\catcode`\?=0%
|
||||
\catcode`\{=12%
|
||||
\catcode`\}=12%
|
||||
%\catcode`\\=12%
|
||||
\lowercase<\endgroup%
|
||||
\def\sml@glob#1\end<\sml@startlexer<^^A>#1^^A\sml@enddisplay\end>%
|
||||
\def\smldisp<%
|
||||
\sml@begindisplay%
|
||||
\let\sml@settick=\relax%
|
||||
\sml@verbatimmode%
|
||||
\catcode`\^^A=12%
|
||||
\sml@glob%
|
||||
>
|
||||
\def\endsmldisp<>
|
||||
>
|
||||
|
||||
\begingroup
|
||||
\catcode`\^^A=12
|
||||
\lowercase{\endgroup
|
||||
\newcommand{\Sml}{%
|
||||
\begingroup%
|
||||
\let\sml@settick=\relax%
|
||||
\sml@verbatimmode%
|
||||
\catcode`\^^A=12%
|
||||
\long\def\sml@grab##1{\sml@startlexer{^^A}##1^^A\endgroup}%
|
||||
\sml@grab%
|
||||
}
|
||||
}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Set up the default keywords
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\newcommand{\smlSetupAllKeywords}
|
||||
{ \smlNewKeyword{functor}
|
||||
\smlNewKeyword{structure}
|
||||
\smlNewKeyword{signature}
|
||||
\smlNewKeyword{struct}
|
||||
\smlNewKeyword{sharing}
|
||||
\smlNewKeyword{sig}
|
||||
\smlNewKeyword{include}
|
||||
\smlNewKeyword{fun}
|
||||
\smlNewKeyword{val}
|
||||
\smlNewKeyword{rec}
|
||||
\smlNewKeyword{type}
|
||||
\smlNewKeyword{datatype}
|
||||
\smlNewKeyword{case}
|
||||
\smlNewKeyword{of}
|
||||
\smlNewKeyword{and}
|
||||
\smlNewKeyword{where}
|
||||
\smlNewKeyword{withtype}
|
||||
\smlNewKeyword{end}
|
||||
\smlNewKeyword{let}
|
||||
\smlNewKeyword{in}
|
||||
\smlNewKeyword{end}
|
||||
\smlNewKeyword{handle}
|
||||
\smlNewKeyword{raise}
|
||||
\smlNewKeyword{exception}
|
||||
\smlNewKeyword{local}
|
||||
\smlNewKeyword{open}
|
||||
\smlNewKeyword{if}
|
||||
\smlNewKeyword{then}
|
||||
\smlNewKeyword{else}
|
||||
\smlNewKeyword{infix}
|
||||
\smlNewKeyword{infixr}
|
||||
\smlNewKeyword{nonfix}
|
||||
}
|
||||
|
||||
\smlSetupAllKeywords
|
||||
|
||||
\endinput
|
||||
@@ -0,0 +1,277 @@
|
||||
\documentclass{article}
|
||||
\usepackage{sml}
|
||||
\title{Package {\tt sml}}
|
||||
\author{Allen Leung}
|
||||
\begin{document}
|
||||
\maketitle
|
||||
\section{Introduction}
|
||||
The \verb|sml| package defines a \verb|verbatim|-like environment
|
||||
called \verb|smldisplay|
|
||||
for typesetting Standard ML programs.
|
||||
Like the \verb|alltt| environment,
|
||||
backslashes `\verb|\|' and the braces \verb|{|
|
||||
and \verb|}| have their usual meaning in \verb|smldisplay|,
|
||||
so it is possible to use other
|
||||
macros and commands within the \verb|smldisplay| environment.
|
||||
Meta-characters such as \verb|#|, \verb|%|,
|
||||
\verb|$|, \verb|_| and \verb|^| are disabled and appears verbatim.
|
||||
|
||||
To enter math mode, the user can use \verb|\(| \ldots \verb|)| or
|
||||
\verb|\[| \ldots \verb|\]|. But unlike the \verb|alltt| environment,
|
||||
the superscripts \verb|^| and subscripts \verb|_| characters
|
||||
are available inside math mode.
|
||||
|
||||
The character \verb|'| is interpreted as the beginning of a ML
|
||||
type variable. Type variables are typeset
|
||||
in italics within the \verb|smldisplay| environment. For example,
|
||||
\begin{verbatim}
|
||||
\begin{smldisplay}
|
||||
datatype 'a tree = EMPTY
|
||||
| NODE of 'a * 'a tree list
|
||||
\end{smldisplay}
|
||||
\end{verbatim}
|
||||
is typeset as follows:
|
||||
\begin{smldisplay}
|
||||
datatype 'a tree = EMPTY
|
||||
| NODE of 'a * 'a tree list
|
||||
\end{smldisplay}
|
||||
|
||||
The environment \verb|smlboxeddisplay| is similar to \verb|smldisplay|
|
||||
except that a box is also drawn around the displayed program.
|
||||
For example, if we write:
|
||||
\begin{verbatim}
|
||||
\begin{smlboxeddisplay}
|
||||
datatype 'a tree = EMPTY
|
||||
| NODE of 'a * 'a tree list
|
||||
\end{smlboxeddisplay}
|
||||
\end{verbatim}
|
||||
we get:
|
||||
\begin{smlboxeddisplay}
|
||||
datatype 'a tree = EMPTY
|
||||
| NODE of 'a * 'a tree list
|
||||
\end{smlboxeddisplay}
|
||||
|
||||
\subsection{Highlighting keywords}
|
||||
A similar environment, called \verb|smldisp|, can be used to highlight
|
||||
all SML keywords. However, math mode and other macros are {\em unavailable}
|
||||
in this environment. For example, in \verb|smldisp| we can write:
|
||||
\begin{verbatim}
|
||||
\begin{smldisp}
|
||||
(* A n-ary tree *)
|
||||
datatype 'a tree = EMPTY
|
||||
| NODE of 'a * 'a tree list
|
||||
(* Flatten a tree as a list in preorder *)
|
||||
fun flatten(EMPTY) = []
|
||||
| flatten(NODE(x,children)) = [x] @ List.concat(map flatten children)
|
||||
\end{smldisp}
|
||||
\end{verbatim}
|
||||
and get the following result:
|
||||
\begin{smldisp}
|
||||
(* A n-ary tree *)
|
||||
datatype 'a tree = EMPTY
|
||||
| NODE of 'a * 'a tree list
|
||||
(* Flatten a tree as a list in preorder *)
|
||||
fun flatten(EMPTY) = []
|
||||
| flatten(NODE(x,children)) = [x] @ List.concat(map flatten children)
|
||||
\end{smldisp}
|
||||
|
||||
Note that the keywords ``datatype'' and ``of'' have been typeset as
|
||||
\Sml{datatype} and \Sml{of}. Furthermore, comments are typeset
|
||||
in small italics font.
|
||||
|
||||
The following macros control how keywords and comments are typeset
|
||||
in this environment:
|
||||
\begin{verbatim}
|
||||
\newcommand{\makeSmlKeyword}[1]{{\bf #1}}
|
||||
\newcommand{\smlCommentSize}{\small}
|
||||
\newcommand{\smlCommentFont}{\it}
|
||||
\newcommand{\BeginSmlComment}{\begingroup\smlCommentSize\smlCommentFont}
|
||||
\newcommand{\EndSmlComment}{\endgroup}
|
||||
\end{verbatim}
|
||||
These can be redefined by the user if necessary.
|
||||
|
||||
\subsection{Type Variable Translations}
|
||||
It is possible to define type variable translations for
|
||||
\verb|smldisplay| and \verb|smldisp| environments. For example,
|
||||
if we write:
|
||||
\begin{verbatim}
|
||||
\smlTypeVar{a}{\(\alpha\)}
|
||||
\smlTypeVar{foo}{\(\underline\beta\)}
|
||||
\begin{smldisplay}
|
||||
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
|
||||
type 'foo foo = ('foo * 'foo) tree
|
||||
type 'c seq = 'c list
|
||||
\end{smldisplay}
|
||||
\end{verbatim}
|
||||
we get:
|
||||
\smlTypeVar{a}{\(\alpha\)}
|
||||
\smlTypeVar{foo}{\(\underline\beta\)}
|
||||
\begin{smldisplay}
|
||||
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
|
||||
type 'foo foo = ('foo * 'foo) tree
|
||||
type 'c seq = 'c list
|
||||
\end{smldisplay}
|
||||
|
||||
Note that all occurrances of \verb|'a| has been translated into
|
||||
$\alpha$, while all occurrances of \verb|'foo| has been translated
|
||||
into $\underline\beta$.
|
||||
|
||||
A type variable translation declared by \verb|smlTypeVar| is active
|
||||
in its scope until it is removed by
|
||||
the macro \verb|\smlRemoveTypeVar|.
|
||||
For example, we can write:
|
||||
\begin{verbatim}
|
||||
\smlRemoveTypeVar{foo}
|
||||
\end{verbatim}
|
||||
to remove the translation on type variable \verb|'foo|.
|
||||
|
||||
|
||||
\subsection{{\tt $\backslash${verb}}-like macros}
|
||||
A \verb|\verb|-like macro called \verb|\sml| is available for typesetting
|
||||
short SML program fragments within running text.
|
||||
For example, we can write the following:
|
||||
\begin{verbatim}
|
||||
\begin{quotation}
|
||||
The datatype \sml{'a tree} implements a polymorphic n-ary tree.
|
||||
The function \sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
|
||||
\end{quotation}
|
||||
\end{verbatim}
|
||||
and obtain:
|
||||
\begin{quotation}
|
||||
The datatype \sml{'a tree} implements a polymorphic n-ary tree.
|
||||
The function \sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
|
||||
\end{quotation}
|
||||
The macro \verb|\sml| behaves very much like the \verb|smldisplay|
|
||||
environment, except that newlines are not interpreted verbatim.
|
||||
|
||||
Similarly, there is a \verb|\verb|-like macro called \verb|\Sml| that
|
||||
behaves like the \verb|smldisp| environment. For example, writing
|
||||
\begin{verbatim}
|
||||
\begin{quotation}
|
||||
The datatype \Sml{'a tree} implements a polymorphic n-ary tree.
|
||||
The function \Sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
|
||||
\end{quotation}
|
||||
\end{verbatim}
|
||||
we obtain:
|
||||
\begin{quotation}
|
||||
The datatype \Sml{'a tree} implements a polymorphic n-ary tree.
|
||||
The function \Sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
|
||||
\end{quotation}
|
||||
|
||||
\subsection{Changing the Fonts}
|
||||
The macros \verb|\smlFont| and \verb|\smlTypeVarFont|
|
||||
define the fonts used for typesetting ML text and type variables.
|
||||
They are predefined as follows:
|
||||
\begin{verbatim}
|
||||
\newcommand{\smlFont}{\verbatim@font}
|
||||
\newcommand{\smlTypeVarFont}{\it}
|
||||
\end{verbatim}
|
||||
Furthermore, the default method of typesetting a type variable
|
||||
is defined as:
|
||||
\begin{verbatim}
|
||||
\newcommand{\makeSmlTypeVar}[1]{'{\smlTypeVarFont #1}}
|
||||
\end{verbatim}
|
||||
These can be overridden by the user if desired.
|
||||
|
||||
\subsection{Enabling {\tt \$}}
|
||||
By default, the math shift character \verb|$|
|
||||
is disabled within the environment \verb|smldisplay|
|
||||
and the macro \verb|sml|. It is possible to
|
||||
enable this character by declaring:
|
||||
\begin{verbatim}
|
||||
\smlDollarOn
|
||||
\end{verbatim}
|
||||
\noindent in the prologue of a document.
|
||||
For example, we can write:
|
||||
\begin{verbatim}
|
||||
\smlDollarOn
|
||||
\begin{smldisplay}
|
||||
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
|
||||
\textrm{A balanced tree with $n$ nodes has height $O(\log n)$}
|
||||
\end{smldisplay}
|
||||
\end{verbatim}
|
||||
and obtain:
|
||||
\smlDollarOn
|
||||
\begin{smldisplay}
|
||||
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
|
||||
\textrm{A balanced tree with $n$ nodes has height $O(\log n)$}
|
||||
\end{smldisplay}
|
||||
|
||||
To turn off the math shift character \verb|$|, we can
|
||||
write
|
||||
\begin{verbatim}
|
||||
\smlDollarOff
|
||||
\end{verbatim}
|
||||
|
||||
\subsection{Numbered Program Listings}
|
||||
|
||||
Numbered program listings can be displayed using the
|
||||
\verb|smllisting| environment, which behaves exactly like
|
||||
\verb|smldisplay| except that every line is prefixed by a
|
||||
line number. For example, when we write:
|
||||
\begin{verbatim}
|
||||
\smlTypeVar{n}{\(\alpha\)}
|
||||
\smlTypeVar{e}{\(\beta\)}
|
||||
\smlTypeVar{g}{\(\gamma\)}
|
||||
\begin{smllisting}{1}{1}
|
||||
signature SINGLE_SOURCE_SHORTEST_PATHS =
|
||||
sig
|
||||
|
||||
val single_source_shortest_paths :
|
||||
\{ weight : 'e Graph.edge -> 'w,
|
||||
< : 'w * 'w -> bool,
|
||||
+ : 'w * 'w -> 'w,
|
||||
zero : 'w,
|
||||
inf : 'w
|
||||
\} ->
|
||||
('n,'e,'g) Graph.graph ->
|
||||
Graph.node_id ->
|
||||
\{ dist : 'w Array.array,
|
||||
pred : Graph.node_id Array.array
|
||||
\}
|
||||
end
|
||||
\end{smllisting}
|
||||
\end{verbatim}
|
||||
\noindent we get:
|
||||
\smlTypeVar{n}{\(\alpha\)}
|
||||
\smlTypeVar{e}{\(\beta\)}
|
||||
\smlTypeVar{g}{\(\gamma\)}
|
||||
\begin{smllisting}{1}{1}
|
||||
signature SINGLE_SOURCE_SHORTEST_PATHS =
|
||||
sig
|
||||
|
||||
val single_source_shortest_paths :
|
||||
\{ weight : 'e Graph.edge -> 'w,
|
||||
< : 'w * 'w -> bool,
|
||||
+ : 'w * 'w -> 'w,
|
||||
zero : 'w,
|
||||
inf : 'w
|
||||
\} ->
|
||||
('n,'e,'g) Graph.graph ->
|
||||
Graph.node_id ->
|
||||
\{ dist : 'w Array.array,
|
||||
pred : Graph.node_id Array.array
|
||||
\}
|
||||
end
|
||||
\end{smllisting}
|
||||
|
||||
The environment \verb|smllisting| requires two numeric parameters.
|
||||
The first parameter determines the initial line number of the
|
||||
listing, while the second parameter determines how often the line
|
||||
number should be printed. For example, if the second parameter
|
||||
is 2, then the line number appears every two lines.
|
||||
|
||||
The environment \verb|smlboxedlisting| is similar to
|
||||
\verb|smllisting| except that a box is also drawn around the program
|
||||
listing.
|
||||
|
||||
The following macros control how the numbers are displayed
|
||||
\begin{verbatim}
|
||||
\newcommand{\smlNumberFont}{\smlFont}
|
||||
\newcommand{\smlNumberStyle}[1]{\arabic{#1}}
|
||||
\end{verbatim}
|
||||
The first macro \verb|\smlNumberFont| controls the font used
|
||||
for line numbering, which by default is \verb|\tt|.
|
||||
The second macro \verb|\smlNumberStyle| displays the line count as
|
||||
arabic numerals.
|
||||
\end{document}
|
||||
@@ -0,0 +1,106 @@
|
||||
\section{Span Dependency Resolution} \label{sec:span-dep}
|
||||
|
||||
The span dependency resolution phase is used to resolve the values of
|
||||
client defined \href{constants.html}{constants} and \href{labels.html}{labels}
|
||||
in a program. An instruction whose immediate operand field contains a
|
||||
constant or \href{labexp.html}{label expression} which
|
||||
is too large is rewritten into a sequence of instructions to compute
|
||||
the same result. Similarly, short branches referencing labels that are
|
||||
too far are rewritten into the long form. For architectures
|
||||
that require the filling of delay slots, this is performed at the same
|
||||
time as span depedency resolution, to ensure maximum benefit results.
|
||||
|
||||
\subsubsection{The Interface}
|
||||
|
||||
The signature \sml{SDI_JUMPS} describes
|
||||
architectural information about span dependence resolution.
|
||||
|
||||
\begin{SML}
|
||||
signature \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS} = sig
|
||||
structure I : \href{instructions.html}{INSTRUCTIONS}
|
||||
structure C : \href{cells.html}{CELLS}
|
||||
sharing I.C = C
|
||||
|
||||
val branchDelayedArch : bool
|
||||
val isSdi : I.instruction -> bool
|
||||
val minSize : I.instruction -> int
|
||||
val maxSize : I.instruction -> int
|
||||
val sdiSize : I.instruction * (C.cell -> C.cell)
|
||||
* (Label.label -> int) * int -> int
|
||||
val expand : I.instruction * int * int -> I.instruction list
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
The components in this interface are:
|
||||
\begin{description}
|
||||
\item[branchDelayedArch] A flag indicating whether the architecture
|
||||
contains delay slots. For example, this would be true on the MIPS,
|
||||
Sparc, PA RISC; but would be false on the x86 and on the Alpha.
|
||||
\item[isSdi] This function returns true if the instruction is
|
||||
\newdef{span dependent}, i.e.~its size depends either on some unresolved
|
||||
constants, or on its position in the code stream.
|
||||
\item[sdiSize] This function takes a span dependent instruction,
|
||||
a \href{regmap.html}{regmap},
|
||||
a mapping from labels to code stream position, and
|
||||
its current code stream position and returns the size of its
|
||||
expansion in bytes.
|
||||
\item[expand] This function takes a span dependent instruction,
|
||||
its size, and its location and return its expansion.
|
||||
\end{description}
|
||||
|
||||
The signature \sml{BBSCHED} is the signature of the phase that performs
|
||||
span depedennce resolution and code generation.
|
||||
\begin{SML}
|
||||
signature \mlrischref{backpatch/bbsched.sig}{BBSCHED} = sig
|
||||
structure F : \href{cluster.html}{FLOWGRAPH}
|
||||
|
||||
val bbsched : F.cluster -> unit
|
||||
val finish : unit -> unit
|
||||
val cleanUp : unit -> unit
|
||||
end
|
||||
\end{SML}
|
||||
|
||||
\subsubsection{The Modules}
|
||||
|
||||
Three different functors are present in the \MLRISC{} system for
|
||||
performing span dependence resolution and code generator.
|
||||
Functor \sml{BBSched2} is the simplest one, which does not perform
|
||||
delay slot filling.
|
||||
\begin{SML}
|
||||
functor BBSched2
|
||||
(structure Flowgraph : \mlrischref{cluster/flowgraph.sig}{FLOWGRAPH}
|
||||
structure Jumps : \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS}
|
||||
structure Emitter : \href{mc.html}{INSTRUCTION_EMITTER}
|
||||
sharing Emitter.P = Flowgraph.P
|
||||
sharing Flowgraph.I = Jumps.I = Emitter.I
|
||||
): BBSCHED
|
||||
\end{SML}
|
||||
|
||||
Functor \sml{SpanDependencyResolution} performs both span dependence
|
||||
resolution and delay slot filling at the same time.
|
||||
\begin{SML}
|
||||
functor SpanDependencyResolution
|
||||
(structure Flowgraph : \mlrischref{cluster/flowgraph.sig}{FLOWGRAPH}
|
||||
structure Emitter : \href{mc.html}{INSTRUCTION_EMITTER}
|
||||
structure Jumps : \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS}
|
||||
structure DelaySlot : \href{delayslots.html}{DELAY_SLOT_PROPERTIES}
|
||||
structure Props : \mlrischref{instructions/insnProps.sig}{INSN_PROPERTIES}
|
||||
sharing Flowgraph.P = Emitter.P
|
||||
sharing Flowgraph.I = Jumps.I = DelaySlot.I = Props.I = Emitter.I
|
||||
) : BBSCHED
|
||||
\end{SML}
|
||||
|
||||
Finally, functor \sml{BackPatch} is a span dependency resolution
|
||||
module specially written for the \href{x86.html}{x86} architecture.
|
||||
\begin{SML}
|
||||
functor BackPatch
|
||||
(structure CodeString : \mlrischref{emit/code-string.sig}{CODE_STRING}
|
||||
structure Jumps: \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS}
|
||||
structure Props : \mlrischref{instructions/insnProps.sig}{INSN_PROPERTIES}
|
||||
structure Emitter : \mlrischref{backpatch/vlBatchPatch.sig}{MC_EMIT}
|
||||
structure Flowgraph : \href{cluster.html}{FLOWGRAPH}
|
||||
structure Asm : \href{asm.html}{INSTRUCTION_EMITTER}
|
||||
sharing Emitter.I = Jumps.I = Flowgraph.I = Props.I = Asm.I) : BBSCHED
|
||||
\end{SML}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
\section{The Sparc Back End}
|
||||
|
||||
The Sparc back end can function in two different modes:
|
||||
\begin{description}
|
||||
\item[Sparc V8] This is V8 instruction set is used. In this mode the processor
|
||||
behaves like a 32-bit processor. In this mode we assume we
|
||||
have 16 floating point registers numbered \verb|%f0, %f2, %f4, ..., %f30|.
|
||||
These are all in IEEE double precision.
|
||||
\item[Sparc V9] This generates code assuming the V9 instruction set is used.
|
||||
In this mode the processor functions at 64-bit. In this mode the
|
||||
floating point processors can number from \verb|%f0, %f2, %f4, ..., %f62|.
|
||||
These are all in IEEE double precision.
|
||||
|
||||
New V9 instructions include the 64-bit extended version of multiplications,
|
||||
divisions, shifts, and load and store.
|
||||
\begin{verbatim}
|
||||
MULX SMULX DIVX SLLX SRLX SRAX LDX STX
|
||||
\end{verbatim}
|
||||
|
||||
Also, V9 includes conditional moves and more general form of branches.
|
||||
\begin{description}
|
||||
\item[MOVcc] conditional moves on condition code
|
||||
\item[FMOVcc] conditional moves on condition code
|
||||
\item[MOVR] conditional moves on integer condition
|
||||
\item[BR] branch on integer register with prediction
|
||||
\item[BP] branch on integer condition with prediction
|
||||
\end{description}
|
||||
\end{description}
|
||||
|
||||
\subsection{General Setup for V8}
|
||||
|
||||
The SPARC architecture has 32 general purpose registers
|
||||
(\verb|%g0| is always 0)
|
||||
and 32 single precision floating point registers.
|
||||
|
||||
Some Ugliness: double precision floating point registers are
|
||||
register pairs. There are no double precision moves, negation and absolute
|
||||
values. These require two single precision operations. I've created
|
||||
composite instructions \verb|FMOVd|,
|
||||
\verb|FNEGd| and
|
||||
\verb|FABSd| to stand for these.
|
||||
|
||||
All integer arithmetic instructions can optionally set the condition
|
||||
code register. We use this to simplify certain comparisons with zero
|
||||
in the instruction selection process.
|
||||
|
||||
Integer multiplication, division and conversion from integer to floating
|
||||
go thru the pseudo instruction interface, since older sparcs do not
|
||||
implement these instructions in hardware.
|
||||
|
||||
In addition, the trap instruction for detecting overflow is a parameter.
|
||||
This allows different trap vectors to be used.
|
||||
|
||||
\subsection{General Setup for V9}
|
||||
|
||||
\subsection{Specializing the Sparc Back End}
|
||||
@@ -0,0 +1,72 @@
|
||||
\section{Instruction Streams}
|
||||
|
||||
\subsubsection{Overview}
|
||||
An \newdef{instruction stream}
|
||||
is an abstraction used by MLRISC to describe linearized instructions.
|
||||
This abstraction turns out to fit the function of
|
||||
many MLRISC modules. For example,
|
||||
a phase such as \href{instrsel.html}{Instruction Selection}
|
||||
can be viewed as taking an stream of
|
||||
\href{mltree.html}{MLTREE} statements and return a
|
||||
stream of \href{instructions.html}{instructions}. Similarly,
|
||||
phases such as \href{asm.html}{assembly output} and
|
||||
\href{mc.html}{machine code generation} can be seen
|
||||
as taking a stream of instructions and
|
||||
returning a stream of characters and a stream of bytes.
|
||||
|
||||
\subsubsection{The Details}
|
||||
An instruction stream satisfy the following abstract signature:
|
||||
\begin{SML}
|
||||
signature \mlrischref{instructions/stream.sig}{INSTRUCTION_STREAM} =
|
||||
sig
|
||||
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
|
||||
|
||||
datatype ('a,'b,'c,'d,'e,'f) stream =
|
||||
STREAM of
|
||||
\{ beginCluster: int -> 'b,
|
||||
endCluster : 'c -> unit,
|
||||
emit : 'a,
|
||||
pseudoOp : P.pseudo_op -> unit,
|
||||
defineLabel : Label.label -> unit,
|
||||
entryLabel : Label.label -> unit,
|
||||
comment : string -> unit,
|
||||
annotation : Annotations.annotation -> unit,
|
||||
exitBlock : 'd -> unit,
|
||||
alias : 'e -> unit,
|
||||
phi : 'f -> unit
|
||||
\}
|
||||
end
|
||||
\end{SML}
|
||||
This type is specialized in other modules as such the
|
||||
\href{asm.html}{assembler}, the \href{mc.html}{machine code emitter},
|
||||
and the \href{instrsel.html}{instruction selection modules}.
|
||||
\subsubsection{The protocol}
|
||||
All instruction streams, irrespective of their actual types,
|
||||
follow the following protocol:
|
||||
\begin{itemize}
|
||||
\item The method \sml{beginCluster} should be called at the beginning of
|
||||
the stream to mark the start of a new compilation unit.
|
||||
The integer passed to this method is the number
|
||||
of bytes in the stream. This integer is only used for
|
||||
machine code emitter, which uses it to allocate space for the
|
||||
code string.
|
||||
\item The method \sml{endCluster} should be called when the entire
|
||||
compilation unit has been sent.
|
||||
\item In between these calls, the following methods can be called in any
|
||||
order:
|
||||
\begin{itemize}
|
||||
\item \sml{emit} -- this method emits an instruction. It takes
|
||||
a \href{regmap.html}{regmap} as argument.
|
||||
\item \sml{pseudoOp} -- this method emits a pseudo op.
|
||||
\item \sml{defineLabel} -- this method defines a \emph{local} label, i.e.
|
||||
a label that is only referenced within the same compilation unit.
|
||||
\item \sml{entryLabel} -- this method defines an \emph{enternal} label that
|
||||
marks an procedure entry, and may be referenced from other
|
||||
compilation units.
|
||||
\item \sml{comment} -- this emits a comment string
|
||||
\item \sml{annotation} -- this function attaches an annotation to
|
||||
the current basic block.
|
||||
\item \sml{exitBlock} --
|
||||
this marks the current block as an procedure exit.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,43 @@
|
||||
\section{System Integration}
|
||||
In a heavily parameterized system like this, one very quickly ends up
|
||||
with a large number of modules and dependencies making it very
|
||||
easy to mix things up in the wrong way.
|
||||
\image{module dependencies}{pictures/png/sharing1.png}{align=center}
|
||||
\br{clear=left}
|
||||
For example, MLRisc is parameterised over pseudo-ops,
|
||||
constants, and regions. An instruction set must be parameterized
|
||||
over constants so that instructions that carry immediate operands
|
||||
can also carry these abstract constants. Instructions must also be
|
||||
parameterized over regions so that memory operations can be
|
||||
appropriately annotated. Finally, the flowgraph module must be
|
||||
parameterized over instructions it carries in basic blocks and
|
||||
pseudo-ops that describe data layout and alignment constraints.
|
||||
|
||||
\image{sharing constraints}{pictures/png/sharing2.png}{align=right}
|
||||
\br{clear=left}
|
||||
In integrating a system that involves these modules, it must be the
|
||||
case that they were created with the same base modules. That is to
|
||||
say the pseudo-ops in flowgraphs must be the same abstraction that
|
||||
was used to define the MLRisc intermediate
|
||||
representation. Alternatively, we want
|
||||
\begin{color}{#ff0000}sharing constraints\end{color}
|
||||
that assert that identity of modules used to
|
||||
specialize other modules. In Standard ML, this is a complete
|
||||
non-issue. A single line that says exactly that is all that is
|
||||
needed to maintain consistency, and the module system does the rest
|
||||
to ensure that the final system is built correctly.
|
||||
|
||||
\image{Back end optimizations}{pictures/png/sharing3.png}{align=left}
|
||||
\br{clear=right}
|
||||
In certain cases one wants to write a specific module for a
|
||||
particular architecture. For instance it may be desirable to collapse
|
||||
trap barriers on the DEC Alpha where it is legal to do so. The
|
||||
INSTRUCTIONS interface is abstract with no built-in knowledge of
|
||||
trap barriers as not all architectures have them.
|
||||
Further the DEC Alpha has fairly unique trap barrier semantics,
|
||||
that one may want to write an optimization module specific and
|
||||
dedicated to the Alpha instruction set and architecture, and forget
|
||||
about writing anything generic. In this case, the Standard ML module
|
||||
system allows one to say that a specific abstraction actually is or
|
||||
matches a more detailed interface. That is to say the INSTRUCTION
|
||||
interface is really the DEC Alpha instruction set.
|
||||
@@ -0,0 +1,17 @@
|
||||
\section{Systems Using MLRISC}
|
||||
Currently these are the systems that are known to be using MLRISC.
|
||||
\begin{itemize}
|
||||
\item \externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/index.html}{SML/NJ},
|
||||
a Standard ML compiler.
|
||||
\item \externhref{http://www.dcs.gla.ac.uk/~reig/c--/index.html}{C--},
|
||||
a portable assembly language.
|
||||
\item \externhref{http://www.cs.bu.edu/groups/church/}{The Church Project}:
|
||||
compilation with flow types.
|
||||
\item \externhref{http://compiler.kaist.ac.kr/projects/lgic}{The LGIC Project}:
|
||||
a compiler for the CHILL language, targeting PowerPC.
|
||||
\item \externhref{http://www.cs.bell-labs.com/who/jhr/moby/index.html}{The Moby Language}
|
||||
\end{itemize}
|
||||
|
||||
\begin{small}
|
||||
Please send additions to \href{mailto:leunga@cs.nyu.edu}{Allen Leung}
|
||||
\end{small}
|
||||
@@ -0,0 +1,3 @@
|
||||
\section{The Intel x86 Back End}
|
||||
|
||||
No documentation yet.
|
||||
@@ -0,0 +1,74 @@
|
||||
EPS= eps/big-pict.eps \
|
||||
eps/big-pict2.eps \
|
||||
eps/cfg-rev.eps \
|
||||
eps/cfg.eps \
|
||||
eps/compiler-2.eps \
|
||||
eps/compiler.eps \
|
||||
eps/compiler2.eps \
|
||||
eps/hyperblock-formation.eps \
|
||||
eps/if-conversion.eps \
|
||||
eps/layers.eps \
|
||||
eps/mlrisc-ir-archive.eps \
|
||||
eps/mlrisc-IR.eps \
|
||||
eps/phg.eps \
|
||||
eps/region-builder.eps \
|
||||
eps/subgraph.eps \
|
||||
eps/tail-dupl.eps \
|
||||
eps/tail-duplication.eps \
|
||||
eps/trace.eps \
|
||||
eps/uncol.eps \
|
||||
eps/viewer.eps
|
||||
|
||||
PDF= pdf/big-pict.pdf \
|
||||
pdf/big-pict2.pdf \
|
||||
pdf/cfg-rev.pdf \
|
||||
pdf/cfg.pdf \
|
||||
pdf/compiler-2.pdf \
|
||||
pdf/compiler.pdf \
|
||||
pdf/compiler2.pdf \
|
||||
pdf/hyperblock-formation.pdf \
|
||||
pdf/if-conversion.pdf \
|
||||
pdf/layers.pdf \
|
||||
pdf/mlrisc-ir-archive.pdf \
|
||||
pdf/mlrisc-IR.pdf \
|
||||
pdf/phg.pdf \
|
||||
pdf/region-builder.pdf \
|
||||
pdf/subgraph.pdf \
|
||||
pdf/tail-dupl.pdf \
|
||||
pdf/tail-duplication.pdf \
|
||||
pdf/trace.pdf \
|
||||
pdf/uncol.pdf \
|
||||
pdf/viewer.pdf
|
||||
|
||||
PNG= png/compiler-1.png \
|
||||
png/compiler-2.png \
|
||||
png/hof-1.png \
|
||||
png/hof-2.png \
|
||||
png/mlrisc-ir-archive.png \
|
||||
png/optimization.png \
|
||||
png/sharing1.png \
|
||||
png/sharing2.png \
|
||||
png/sharing3.png \
|
||||
png/uncol.png \
|
||||
png/uncol1.png \
|
||||
png/uncol2.png
|
||||
|
||||
|
||||
all: mkdir $(PNG) $(PDF)
|
||||
|
||||
clean:
|
||||
rm -f $(EPS) $(PNG) $(PDF)
|
||||
|
||||
mkdir:
|
||||
# @if [ ! -d eps ]; then mkdir eps; fi
|
||||
@if [ ! -d pdf ]; then mkdir pdf; fi
|
||||
@if [ ! -d png ]; then mkdir png; fi
|
||||
|
||||
eps/%.eps: fig/%.fig
|
||||
fig2dev -L ps $< $@
|
||||
pdf/%.pdf: fig/%.fig
|
||||
fig2dev -L pdf $< $@
|
||||
jpeg/%.jpg: fig/%.fig
|
||||
fig2dev -L jpeg $< $@
|
||||
png/%.png: fig/%.fig
|
||||
fig2dev -L png $< $@
|
||||
@@ -0,0 +1,90 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 1800 5775 4125 7275
|
||||
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
1800 5775 4094 5775 4094 7275 1800 7275 1800 5775
|
||||
4 0 0 100 0 18 22 0.0000 4 225 840 2400 6225 Basic\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 2040 1875 6750 Optimizations\001
|
||||
-6
|
||||
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2250 2175 4350 2175 4350 3225 2250 3225 2250 2175
|
||||
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
4275 4200 6900 4200 6900 5400 4275 5400 4275 4200
|
||||
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
6225 2250 8625 2250 8625 3375 6225 3375 6225 2250
|
||||
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
6975 5850 9600 5850 9600 7350 6975 7350 6975 5850
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
6375 5400 7875 5850
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
4575 5400 2850 5775
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
3525 3225 5100 4200
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
6900 3375 5625 4200
|
||||
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
8925 3975 11475 3975 11475 5400 8925 5400 8925 3975
|
||||
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
4650 600 6975 600 6975 1800 4650 1800 4650 600
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
5550 1800 5325 4200
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
6900 4800 8925 4725
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
2400 8400 3975 8400 3975 9600 2400 9600 2400 8400
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
4950 8400 6525 8400 6525 9600 4950 9600 4950 8400
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
7500 8400 9075 8400 9075 9600 7500 9600 7500 8400
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
9750 7875 11325 7875 11325 9075 9750 9075 9750 7875
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3375 8400 3525 8100
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6150 8400 6150 8100
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
8100 8400 7950 8025
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
10575 7875 10350 7575
|
||||
3 3 0 1 0 30 100 0 -1 0.000 0 0 0 11
|
||||
9000 1500 11700 3525 12075 6450 9225 7800 3825 8100 975 7350
|
||||
1050 5100 1425 2475 3600 750 5250 225 7875 675
|
||||
-1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
|
||||
-1.000 -1.000 -1.000
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1635 4875 4875 MLRISC IR\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 645 2625 2775 SSA\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 2040 6375 3150 Optimizations\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 1770 6450 2850 Superscalar\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 750 7350 6300 VLIW\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 2040 7350 6690 Optimizations\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 1230 9375 4500 Register\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1320 9375 4890 Allocator\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1530 5100 975 Instruction\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1365 5100 1365 Selection\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 795 2775 8925 Hppa\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 855 5100 8925 Alpha\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 525 7875 8925 X86\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 870 10050 8400 Sparc\001
|
||||
@@ -0,0 +1,94 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 225 150 12750 9600
|
||||
6 1800 5775 4125 7275
|
||||
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
|
||||
1800 5775 4094 5775 4094 7275 1800 7275 1800 5775
|
||||
4 0 0 100 0 18 22 0.0000 4 225 840 2400 6225 Basic\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 2040 1875 6750 Optimizations\001
|
||||
-6
|
||||
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
|
||||
2250 2175 4350 2175 4350 3225 2250 3225 2250 2175
|
||||
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
|
||||
4275 4200 6900 4200 6900 5400 4275 5400 4275 4200
|
||||
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
|
||||
6225 2250 8625 2250 8625 3375 6225 3375 6225 2250
|
||||
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
|
||||
6975 5850 9600 5850 9600 7350 6975 7350 6975 5850
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
6375 5400 7875 5850
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
4575 5400 2850 5775
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
3525 3225 5100 4200
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
6900 3375 5625 4200
|
||||
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
|
||||
8925 3975 11475 3975 11475 5400 8925 5400 8925 3975
|
||||
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
|
||||
4650 600 6975 600 6975 1800 4650 1800 4650 600
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
5550 1800 5325 4200
|
||||
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
6900 4800 8925 4725
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
2400 8400 3975 8400 3975 9600 2400 9600 2400 8400
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
4950 8400 6525 8400 6525 9600 4950 9600 4950 8400
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
7500 8400 9075 8400 9075 9600 7500 9600 7500 8400
|
||||
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
|
||||
9750 7875 11325 7875 11325 9075 9750 9075 9750 7875
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3375 8400 3525 8100
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6150 8400 6150 8100
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
8100 8400 7950 8025
|
||||
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
10575 7875 10350 7575
|
||||
3 3 0 1 0 30 100 0 -1 0.000 0 0 0 11
|
||||
9000 1500 11700 3525 12075 6450 9225 7800 3825 8100 975 7350
|
||||
1050 5100 1425 2475 3600 750 5250 225 7875 675
|
||||
-1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
|
||||
-1.000 -1.000 -1.000
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1635 4875 4875 MLRISC IR\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 645 2625 2775 SSA\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 2040 6375 3150 Optimizations\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 1770 6450 2850 Superscalar\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 750 7350 6300 VLIW\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 2040 7350 6690 Optimizations\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 1230 9375 4500 Register\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1320 9375 4890 Allocator\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1530 5100 975 Instruction\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 1365 5100 1365 Selection\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 795 2775 8925 Hppa\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 855 5100 8925 Alpha\001
|
||||
4 0 0 100 0 18 22 0.0000 4 225 525 7875 8925 X86\001
|
||||
4 0 0 100 0 18 22 0.0000 4 285 870 10050 8400 Sparc\001
|
||||
-6
|
||||
2 2 0 0 0 2 100 0 35 0.000 0 0 -1 0 0 5
|
||||
600 300 11250 300 11250 9375 600 9375 600 300
|
||||
@@ -0,0 +1,90 @@
|
||||
#FIG 3.1
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
1200 2
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
2149 3862 3102 3862 3102 4498 2149 4498 2149 3862
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
1725 7358 3526 7358 3526 8100 1725 8100 1725 7358
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2361 4498 1937 7358
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3375 450 5176 450 5176 1192 3375 1192 3375 450
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3975 1200 3339 1729
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3900 3825 4854 3825 4854 4461 3900 4461 3900 3825
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3150 2400 2475 3900
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3375 2400 4275 3825
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
2497 5250 3450 5250 3450 5886 2497 5886 2497 5250
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2550 4500 2700 5250
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3750 6375 4703 6375 4703 7011 3750 7011 3750 6375
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
2400 6300 3354 6300 3354 6936 2400 6936 2400 6300
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2925 5925 2775 6300
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3225 5925 3975 6375
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
2797 1689 3750 1689 3750 2325 2797 2325 2797 1689
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
1071 5175 2025 5175 2025 5811 1071 5811 1071 5175
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1500 5850 1875 7350
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2250 4500 1500 5175
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3300 2325 3225 5250
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2925 2325 1275 5175
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 6
|
||||
1 1 1.00 60.00 120.00
|
||||
1200 5850 975 6375 525 6225 300 5550 1125 4050 2775 2250
|
||||
0.00 0.00 1177.04 6178.28 1120.79 6309.53 813.57 6447.49
|
||||
620.89 6320.89 381.17 6081.17 282.38 5744.08 342.40 5083.03
|
||||
893.72 4372.32 1372.41 3705.19 1784.91 3255.19 0.00 0.00
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 5
|
||||
1 1 1.00 60.00 120.00
|
||||
4500 1200 5325 3525 5175 6375 4650 7575 3525 7875
|
||||
0.00 0.00 5055.35 2507.18 5261.60 3088.43 5422.78 4198.39
|
||||
5330.63 5717.68 5103.57 6676.68 4930.53 7334.12 4462.97 7735.59
|
||||
4181.72 7810.59 0.00 0.00
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 212 2467 4286 B\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 2679 4921 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 657 2361 7782 EXIT\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 996 3782 980 ENTRY\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 3495 1435 T\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 212 4206 4286 C\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 212 3102 2145 A\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 212 2785 5686 D\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 2790 6780 E\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 4106 6780 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 2577 6246 T\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 3725 2900 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 2948 3275 T\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 233 1444 5567 G\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 765 6713 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 3315 3338 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 2490 3338 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 2118 5027 T\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 1815 4763 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 1377 6396 T\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 3633 6117 F\001
|
||||
4 0 -1 0 0 18 20 0.0000 4 233 191 4676 1556 F\001
|
||||
@@ -0,0 +1,85 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1200 3525 1650 3900
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2325 3525 1725 3900
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1575 4350 1200 4725
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 4350 2325 4725
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1200 5175 1725 5475
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2400 5175 1875 5475
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 5925 1575 6825
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1725 2625 1200 3075
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1875 2625 2325 3075
|
||||
2 1 1 1 -1 3 0 0 -1 4.000 0 0 -1 0 0 1
|
||||
1425 4800
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1650 1575 1725 2175
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
675 6825 1950 6825 1950 7350 675 7350 675 6825
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
1425 5475 2100 5475 2100 5925 1425 5925 1425 5475
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
1950 4725 2625 4725 2625 5175 1950 5175 1950 4725
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
900 4725 1575 4725 1575 5175 900 5175 900 4725
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
1350 3900 2025 3900 2025 4350 1350 4350 1350 3900
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
900 3075 1575 3075 1575 3525 900 3525 900 3075
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
1950 3075 2625 3075 2625 3525 1950 3525 1950 3075
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
1500 2175 2175 2175 2175 2625 1500 2625 1500 2175
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
|
||||
975 975 2325 975 2325 1575 975 1575 975 975
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 0 1 4
|
||||
1 1 1.00 60.00 120.00
|
||||
1050 3525 600 4350 525 5550 1050 6825
|
||||
0.000 -1.000 -1.000 0.000
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 0 1 7
|
||||
1 1 1.00 60.00 120.00
|
||||
2025 5925 2625 6075 3075 4800 3000 2550 2325 1800 2025 1800
|
||||
1875 2175
|
||||
0.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.000
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 1725 2550 A\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 1125 3450 B\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 2250 3450 C\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 1575 4200 D\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 1125 5025 E\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2250 5025 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 1650 5775 G\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 735 1350 1425 ENTRY\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 450 975 7125 EXIT\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 1275 2925 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 2925 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 750 3825 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 1275 3825 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 1200 4575 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 4575 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 1575 6300 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2100 6225 F\001
|
||||
@@ -0,0 +1,85 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1200 3525 1650 3900
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2325 3525 1725 3900
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1575 4350 1200 4725
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 4350 2325 4725
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1200 5175 1725 5475
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2400 5175 1875 5475
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 5925 1575 6825
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1650 1575 1725 2175
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
900 3075 1575 3075 1575 3525 900 3525 900 3075
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1950 3075 2625 3075 2625 3525 1950 3525 1950 3075
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1350 3900 2025 3900 2025 4350 1350 4350 1350 3900
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1950 4725 2625 4725 2625 5175 1950 5175 1950 4725
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1500 2175 2175 2175 2175 2625 1500 2625 1500 2175
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1425 5475 2100 5475 2100 5925 1425 5925 1425 5475
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1725 2625 1200 3075
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1875 2625 2325 3075
|
||||
2 1 1 1 -1 3 0 0 -1 4.000 0 0 -1 0 0 1
|
||||
1425 4800
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
975 975 2325 975 2325 1575 975 1575 975 975
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
675 6825 1950 6825 1950 7350 675 7350 675 6825
|
||||
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
900 4725 1575 4725 1575 5175 900 5175 900 4725
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 4
|
||||
1 1 1.00 60.00 120.00
|
||||
1050 3525 600 4350 525 5550 1050 6825
|
||||
0.000 -1.000 -1.000 0.000
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 7
|
||||
1 1 1.00 60.00 120.00
|
||||
2025 5925 2625 6075 3075 4800 3000 2550 2325 1800 2025 1800
|
||||
1875 2175
|
||||
0.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.000
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 1725 2550 A\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 1125 3450 B\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 2250 3450 C\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 1575 4200 D\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 1125 5025 E\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2250 5025 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 1650 5775 G\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 735 1350 1425 ENTRY\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 450 975 7125 EXIT\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 1275 2925 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 2925 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 750 3825 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 1275 3825 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 1200 4575 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 4575 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 1575 6300 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 2100 6225 F\001
|
||||
@@ -0,0 +1,35 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
0
|
||||
1200 2
|
||||
5 1 0 1 0 7 0 0 -1 0.000 0 1 1 0 8256.137 3282.955 8250 3675 8625 3150 7875 3375
|
||||
1 1 1.00 60.00 120.00
|
||||
2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
4540 4367 5115 4367 5307 3409 4732 3409 4540 4367
|
||||
2 2 0 1 -1 29 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8753 3075 9136 3075 9136 5132 8753 5132 8753 3075
|
||||
2 2 0 2 -1 11 1 0 20 0.000 0 0 -1 0 0 5
|
||||
7221 3409 8226 3409 8226 4367 7221 4367 7221 3409
|
||||
2 2 0 2 -1 2 1 0 20 0.000 0 0 -1 0 0 5
|
||||
5689 3409 6694 3409 6694 4367 5689 4367 5689 3409
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5175 3900 5700 3900
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6675 3900 7200 3900
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
8250 3900 8775 3900
|
||||
4 1 -1 0 0 26 10 0.0000 4 135 574 6120 3936 lex/yacc\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 106 508 4827 4654 Source\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 135 622 4827 4826 Program\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 106 612 8944 5467 Abstract\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 106 632 8944 5639 machine\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 95 862 8944 5811 instructions\001
|
||||
4 0 0 0 0 26 9 0.0000 4 124 632 7461 3936 optimize\001
|
||||
@@ -0,0 +1,73 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
0
|
||||
1200 2
|
||||
5 1 0 1 0 7 0 0 -1 0.000 0 1 1 0 5556.137 4182.955 5550 4575 5925 4050 5175 4275
|
||||
1 1 1.00 60.00 120.00
|
||||
6 6825 4200 7125 5475
|
||||
4 1 0 0 0 2 12 0.0000 4 135 165 6975 4350 M\001
|
||||
4 1 0 0 0 2 12 0.0000 4 135 120 6975 4575 L\001
|
||||
4 1 0 0 0 2 12 0.0000 4 135 135 6975 4800 R\001
|
||||
4 1 0 0 0 2 12 0.0000 4 135 45 6975 5025 i\001
|
||||
4 1 0 0 0 2 12 0.0000 4 90 90 6975 5250 s\001
|
||||
4 1 0 0 0 2 12 0.0000 4 90 90 6975 5475 c\001
|
||||
-6
|
||||
2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1840 5267 2415 5267 2607 4309 2032 4309 1840 5267
|
||||
2 2 0 2 -1 11 1 0 20 0.000 0 0 -1 0 0 5
|
||||
4521 4309 5526 4309 5526 5267 4521 5267 4521 4309
|
||||
2 2 0 2 -1 2 1 0 20 0.000 0 0 -1 0 0 5
|
||||
2989 4309 3994 4309 3994 5267 2989 5267 2989 4309
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2475 4800 3000 4800
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3975 4800 4500 4800
|
||||
2 2 0 1 -1 30 0 0 20 0.000 0 0 -1 0 0 5
|
||||
6053 3975 6436 3975 6436 6032 6053 6032 6053 3975
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5550 4950 6900 5625
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5550 4725 6900 4050
|
||||
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
7125 4875 7425 5025
|
||||
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
7125 4725 7425 4575
|
||||
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
7125 4650 7500 4275
|
||||
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5550 4800 6075 4800
|
||||
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
7125 4950 7575 5400
|
||||
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
7125 5025 7425 5700
|
||||
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
7125 4500 7350 3975
|
||||
4 1 -1 0 0 26 10 0.0000 4 150 705 3420 4836 lex/yacc\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 90 480 2127 5554 Source\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 120 570 2127 5726 Program\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 90 525 6244 6367 Abstract\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 90 585 6244 6539 machine\001
|
||||
4 1 -1 0 0 26 9 0.0000 4 90 825 6244 6711 instructions\001
|
||||
4 0 0 0 0 26 9 0.0000 4 120 630 4761 4836 optimize\001
|
||||
4 0 0 0 0 26 9 0.0000 4 120 390 7380 4247 Alpha\001
|
||||
4 0 0 0 0 26 9 0.0000 4 120 360 7421 4654 Hppa\001
|
||||
4 0 0 0 0 26 9 0.0000 4 90 255 7461 5102 X86\001
|
||||
4 0 0 0 0 26 9 0.0000 4 90 270 7502 5509 PPC\001
|
||||
4 0 0 0 0 26 9 0.0000 4 120 375 7425 5850 Sparc\001
|
||||
4 0 0 0 0 26 9 0.0000 4 90 255 7350 3975 C6x\001
|
||||
@@ -0,0 +1,41 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
0
|
||||
1200 2
|
||||
2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1800 5100 2700 5100 3000 3600 2100 3600 1800 5100
|
||||
2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 3.00 180.00 360.00
|
||||
2925 4500 3525 4500
|
||||
2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 3.00 180.00 360.00
|
||||
5250 4500 5925 4500
|
||||
2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 3.00 180.00 360.00
|
||||
7650 4500 8325 4500
|
||||
2 2 0 1 -1 29 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8400 3075 9000 3075 9000 6300 8400 6300 8400 3075
|
||||
2 2 0 2 -1 11 1 0 20 0.000 0 0 -1 0 0 5
|
||||
6000 3600 7575 3600 7575 5100 6000 5100 6000 3600
|
||||
2 2 0 2 -1 2 1 0 20 0.000 0 0 -1 0 0 5
|
||||
3600 3600 5175 3600 5175 5100 3600 5100 3600 3600
|
||||
3 2 0 2 -1 7 0 0 -1 0.000 0 1 0 6
|
||||
0 0 2.00 120.00 240.00
|
||||
7575 3900 7800 3600 7800 3300 7425 3150 7125 3300 7125 3600
|
||||
0.000 -1.000 -1.000 -1.000 -1.000 0.000
|
||||
4 1 -1 0 0 26 16 0.0000 4 225 1035 4275 4425 lex/yacc\001
|
||||
4 1 -1 0 0 26 14 0.0000 4 165 795 2250 5550 Source\001
|
||||
4 1 -1 0 0 26 14 0.0000 4 210 975 2250 5820 Program\001
|
||||
4 1 -1 0 0 26 14 0.0000 4 165 960 8700 6825 Abstract\001
|
||||
4 1 -1 0 0 26 14 0.0000 4 165 990 8700 7095 machine\001
|
||||
4 1 -1 0 0 26 14 0.0000 4 150 1350 8700 7365 instructions\001
|
||||
4 0 7 0 0 26 16 0.0000 4 225 765 10950 3300 Alpha\001
|
||||
4 0 7 0 0 26 16 0.0000 4 225 705 11025 4050 Hppa\001
|
||||
4 0 7 0 0 26 16 0.0000 4 180 480 11100 4875 X86\001
|
||||
4 0 7 0 0 26 16 0.0000 4 180 585 11175 5625 PPC\001
|
||||
4 0 0 0 0 26 14 0.0000 4 195 990 6375 4425 optimize\001
|
||||
@@ -0,0 +1,65 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 1 7 7 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
1800 5100 2700 5100 3000 3600 2100 3600 1800 5100
|
||||
2 2 0 2 7 7 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3600 3600 5175 3600 5175 5100 3600 5100 3600 3600
|
||||
2 2 0 2 7 7 0 0 20 0.000 0 0 -1 0 0 5
|
||||
6000 3600 7575 3600 7575 5100 6000 5100 6000 3600
|
||||
2 1 0 3 7 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 3.00 180.00 360.00
|
||||
7650 4500 8325 4500
|
||||
2 1 0 3 7 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 3.00 180.00 360.00
|
||||
5250 4500 5925 4500
|
||||
2 1 0 3 7 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 3.00 180.00 360.00
|
||||
2925 4500 3525 4500
|
||||
2 2 0 1 7 7 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8400 3075 9000 3075 9000 6300 8400 6300 8400 3075
|
||||
2 1 0 2 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 2.00 120.00 240.00
|
||||
7652 4134 9902 3534
|
||||
2 1 0 2 0 0 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 2.00 120.00 240.00
|
||||
7671 4748 9921 5648
|
||||
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 2.00 120.00 240.00
|
||||
10050 4500 11100 3375
|
||||
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 2.00 120.00 240.00
|
||||
10125 4575 11250 4200
|
||||
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 2.00 120.00 240.00
|
||||
10125 4800 10950 4800
|
||||
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 2.00 120.00 240.00
|
||||
10125 5025 11325 5400
|
||||
3 2 0 2 7 7 0 0 -1 0.000 0 1 0 6
|
||||
0 0 2.00 120.00 240.00
|
||||
7575 3900 7800 3600 7800 3300 7425 3150 7125 3300 7125 3600
|
||||
0.000 -1.000 -1.000 -1.000 -1.000 0.000
|
||||
4 1 -1 0 0 26 16 0.0000 4 180 240 9900 4050 M\001
|
||||
4 1 -1 0 0 26 16 0.0000 4 180 180 9900 4335 L\001
|
||||
4 1 -1 0 0 26 16 0.0000 4 180 210 9900 4620 R\001
|
||||
4 1 -1 0 0 26 16 0.0000 4 180 90 9900 4905 i\001
|
||||
4 1 -1 0 0 26 16 0.0000 4 120 120 9900 5190 s\001
|
||||
4 1 -1 0 0 26 16 0.0000 4 120 135 9900 5475 c\001
|
||||
4 1 7 0 0 26 14 0.0000 4 210 975 2250 5820 Program\001
|
||||
4 1 7 0 0 26 14 0.0000 4 165 795 2250 5550 Source\001
|
||||
4 1 7 0 0 26 16 0.0000 4 225 1035 4275 4425 lex/yacc\001
|
||||
4 1 7 0 0 26 16 0.0000 4 225 1140 6750 4425 optimize\001
|
||||
4 1 7 0 0 26 14 0.0000 4 165 960 8700 6825 Abstract\001
|
||||
4 1 7 0 0 26 14 0.0000 4 165 990 8700 7095 machine\001
|
||||
4 1 7 0 0 26 14 0.0000 4 150 1350 8700 7365 instructions\001
|
||||
4 0 0 0 0 26 16 0.0000 4 225 765 10950 3300 Alpha\001
|
||||
4 0 0 0 0 26 16 0.0000 4 225 705 11025 4050 Hppa\001
|
||||
4 0 0 0 0 26 16 0.0000 4 180 480 11100 4875 X86\001
|
||||
4 0 0 0 0 26 16 0.0000 4 180 585 11175 5625 PPC\001
|
||||
@@ -0,0 +1,56 @@
|
||||
#FIG 3.1
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
1200 2
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4500 1050 5775 1050 5775 1575 4500 1575 4500 1050
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4275 2025 4950 2025 4950 2475 4275 2475 4275 2025
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3825 2850 4500 2850 4500 3300 3825 3300 3825 2850
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4800 2850 5475 2850 5475 3300 4800 3300 4800 2850
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
5700 2850 6375 2850 6375 3300 5700 3300 5700 2850
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
5250 3600 5925 3600 5925 4050 5250 4050 5250 3600
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
6075 3600 6750 3600 6750 4050 6075 4050 6075 3600
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
6975 3600 7650 3600 7650 4050 6975 4050 6975 3600
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3750 3675 5025 3675 5025 4200 3750 4200 3750 3675
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5025 1575 4650 2025
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4500 2475 4125 2850
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4725 2475 5100 2850
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4875 2475 5925 2850
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5850 3300 5550 3600
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6150 3300 6300 3600
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6300 3300 7275 3600
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4650 2475 4650 3675
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 705 4800 1425 ENTRY\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 4575 2400 A\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 4125 3225 B\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 5025 3225 C\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 5925 3150 D\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 5550 3900 E\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 6300 3900 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 7200 3900 G\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 465 4125 4050 EXIT\001
|
||||
@@ -0,0 +1,106 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Flush left
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
0
|
||||
1200 2
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
790 1189 1492 1189 1492 1891 790 1891 790 1189
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
321 1658 790 1658
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
321 1423 790 1423
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1492 1423 1960 1423
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1492 1658 1960 1658
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3941 2023 4643 2023 4643 2725 3941 2725 3941 2023
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3473 2491 3941 2491
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3473 2257 3941 2257
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4643 2257 5111 2257
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4643 2491 5111 2491
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3988 75 4689 75 4689 777 3988 777 3988 75
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3519 543 3988 543
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3519 309 3988 309
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4689 309 5158 309
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4689 543 5158 543
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
1960 1306 1960 1774 2195 1774 2078 1540 2195 1306 1960 1306
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5112 2193 5112 2669 5350 2669 5232 2430 5350 2193 5112 2193
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
3472 2148 3472 2623 3234 2623 3352 2385 3234 2148 3472 2148
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
3519 201 3519 677 3280 677 3399 438 3280 201 3519 201
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5159 201 5159 677 5397 677 5278 438 5397 201 5159 201
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
321 1314 321 1789 82 1789 201 1551 82 1314 321 1314
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
790 1189 1492 1189 1492 1891 790 1891 790 1189
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
321 1658 790 1658
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
321 1423 790 1423
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1492 1423 1960 1423
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1492 1658 1960 1658
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3941 2023 4643 2023 4643 2725 3941 2725 3941 2023
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3473 2491 3941 2491
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3473 2257 3941 2257
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4643 2257 5111 2257
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4643 2491 5111 2491
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3988 75 4689 75 4689 777 3988 777 3988 75
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3519 543 3988 543
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3519 309 3988 309
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4689 309 5158 309
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4689 543 5158 543
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
321 1314 321 1789 82 1789 201 1551 82 1314 321 1314
|
||||
2 1 0 1 0 24 0 0 20 0.000 0 0 -1 0 0 6
|
||||
1960 1306 1960 1774 2195 1774 2078 1540 2195 1306 1960 1306
|
||||
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
|
||||
3519 201 3519 677 3280 677 3399 438 3280 201 3519 201
|
||||
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
|
||||
3472 2148 3472 2623 3234 2623 3352 2385 3234 2148 3472 2148
|
||||
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5159 201 5159 677 5397 677 5278 438 5397 201 5159 201
|
||||
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5112 2193 5112 2669 5350 2669 5232 2430 5350 2193 5112 2193
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
2 1 1.00 60.00 120.00
|
||||
2160 1511 3226 723
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
2 1 1.00 60.00 120.00
|
||||
2160 1557 3180 2159
|
||||
4 0 0 0 0 26 8 0.0000 4 120 1020 4060 1186 Floating Pt RA\001
|
||||
4 0 0 0 0 26 8 0.0000 4 90 540 4848 3178 Functor\001
|
||||
4 0 0 0 0 26 8 0.0000 4 90 540 5219 1186 Functor\001
|
||||
4 0 -1 0 0 26 10 0.0000 4 150 1110 307 2345 Higher Order \001
|
||||
4 0 0 0 0 26 10 0.0000 4 120 645 956 2484 Functor\001
|
||||
4 0 -1 0 0 26 10 0.0000 4 150 1500 1445 2335 Register Allocator\001
|
||||
4 0 0 0 0 26 8 0.0000 4 120 705 4014 3178 Integer RA\001
|
||||
@@ -0,0 +1,119 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
0
|
||||
1200 2
|
||||
2 2 0 1 7 4 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
10800 600 11100 600 11100 900 10800 900 10800 600
|
||||
2 2 0 1 7 4 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
10800 600 11100 600 11100 900 10800 900 10800 600
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
1109 1269 1862 1269 1862 2022 1109 2022 1109 1269
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
609 1771 1109 1771
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
609 1519 1109 1519
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1862 1519 2364 1519
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1862 1771 2364 1771
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4486 2161 5238 2161 5238 2915 4486 2915 4486 2161
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3984 2664 4486 2664
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3984 2412 4486 2412
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5238 2412 5739 2412
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5238 2664 5739 2664
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4536 75 5287 75 5287 827 4536 827 4536 75
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4034 577 4536 577
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4034 326 4536 326
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5287 326 5789 326
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5287 577 5789 577
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
2364 1394 2364 1895 2614 1895 2490 1644 2614 1394 2364 1394
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5740 2345 5740 2854 5996 2854 5868 2598 5996 2345 5740 2345
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
3983 2295 3983 2804 3728 2804 3854 2549 3728 2295 3983 2295
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
4033 210 4033 721 3777 721 3904 465 3777 210 4033 210
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5790 210 5790 721 6045 721 5917 465 6045 210 5790 210
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
608 1401 608 1912 352 1912 479 1655 352 1401 608 1401
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
1109 1269 1862 1269 1862 2022 1109 2022 1109 1269
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
609 1771 1109 1771
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
609 1519 1109 1519
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1862 1519 2364 1519
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
1862 1771 2364 1771
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4486 2161 5238 2161 5238 2915 4486 2915 4486 2161
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3984 2664 4486 2664
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
3984 2412 4486 2412
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5238 2412 5739 2412
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5238 2664 5739 2664
|
||||
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4536 75 5287 75 5287 827 4536 827 4536 75
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4034 577 4536 577
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
4034 326 4536 326
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5287 326 5789 326
|
||||
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
|
||||
5287 577 5789 577
|
||||
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
|
||||
608 1401 608 1912 352 1912 479 1655 352 1401 608 1401
|
||||
2 1 0 1 0 24 0 0 20 0.000 0 0 -1 0 0 6
|
||||
2364 1394 2364 1895 2614 1895 2490 1644 2614 1394 2364 1394
|
||||
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
|
||||
4033 210 4033 721 3777 721 3904 465 3777 210 4033 210
|
||||
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
|
||||
3983 2295 3983 2804 3728 2804 3854 2549 3728 2295 3983 2295
|
||||
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5790 210 5790 721 6045 721 5917 465 6045 210 5790 210
|
||||
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
|
||||
5740 2345 5740 2854 5996 2854 5868 2598 5996 2345 5740 2345
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
2 1 1.00 60.00 120.00
|
||||
2578 1613 3719 770
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
2 1 1.00 60.00 120.00
|
||||
2578 1663 3670 2309
|
||||
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
|
||||
339 1407 96 1407 96 1912 359 1912 480 1649 359 1407
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
2 1 1.00 60.00 120.00
|
||||
543 1018 245 1415
|
||||
4 0 0 0 0 26 9 0.0000 4 120 1020 4613 1266 Floating Pt RA\001
|
||||
4 0 0 0 0 26 9 0.0000 4 120 705 4563 3400 Integer RA\001
|
||||
4 0 0 0 0 26 9 0.0000 4 90 540 5458 3400 Functor\001
|
||||
4 0 0 0 0 26 9 0.0000 4 90 540 5854 1266 Functor\001
|
||||
4 0 -1 0 0 26 10 0.0000 4 150 1110 592 2507 Higher Order \001
|
||||
4 0 0 0 0 26 10 0.0000 4 120 645 1288 2655 Functor\001
|
||||
4 0 -1 0 0 26 10 0.0000 4 150 1500 1685 2507 Register Allocator\001
|
||||
4 0 0 0 0 26 10 0.0000 4 150 390 444 969 Spec\001
|
||||
4 0 4 0 0 26 10 0.0000 4 150 870 245 820 DEC Alpha\001
|
||||
4 0 4 0 0 26 9 0.0000 4 120 705 4613 1068 DEC Alpha\001
|
||||
4 0 4 0 0 26 9 0.0000 4 120 705 4563 3202 DEC Alpha\001
|
||||
@@ -0,0 +1,156 @@
|
||||
#FIG 3.1
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
1200 2
|
||||
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1350 6075 825 7050
|
||||
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
525 525 1200 1800
|
||||
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4875 450 5550 1725
|
||||
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5925 6000 4800 6975
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
5250 1725 6000 1725 6000 2250 5250 2250 5250 1725
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4800 2700 5550 2700 5550 3225 4800 3225 4800 2700
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4575 3600 5325 3600 5325 4125 4575 4125 4575 3600
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5550 2250 5100 2700
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5100 3225 4875 3600
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5325 3225 6000 4275
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5175 4125 5925 4275
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4950 4125 4800 4425
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4875 4950 5775 5475
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6150 4800 5850 5475
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5775 2250 6525 2925
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
5400 5475 6450 5475 6450 6000 5400 6000 5400 5475
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
5775 4275 6750 4275 6750 4800 5775 4800 5775 4275
|
||||
2 2 0 1 -1 6 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
6375 2925 7350 2925 7350 3450 6375 3450 6375 2925
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4500 4425 5550 4425 5550 4950 4500 4950 4500 4425
|
||||
2 2 0 1 -1 6 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
6900 5475 7950 5475 7950 6000 6900 6000 6900 5475
|
||||
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
6975 3450 7275 5475
|
||||
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
7425 6000 4875 6975
|
||||
2 1 0 5 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 300.00 300.00
|
||||
3000 4125 4050 4125
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
900 1800 1650 1800 1650 2325 900 2325 900 1800
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
450 2775 1200 2775 1200 3300 450 3300 450 2775
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
225 3675 975 3675 975 4200 225 4200 225 3675
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1200 2325 750 2775
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
750 3300 525 3675
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
975 3300 1650 4350
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
825 4200 1575 4350
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 4200 450 4500
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
525 5025 1425 5550
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 4875 1500 5550
|
||||
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1425 2325 2175 3000
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
1050 5550 2100 5550 2100 6075 1050 6075 1050 5550
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
1425 4350 2400 4350 2400 4875 1425 4875 1425 4350
|
||||
2 2 0 1 -1 6 0 0 -1 0.000 0 0 -1 0 0 5
|
||||
2025 3000 3000 3000 3000 3525 2025 3525 2025 3000
|
||||
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
|
||||
150 4500 1200 4500 1200 5025 150 5025 150 4500
|
||||
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 3
|
||||
1 1 1.00 60.00 120.00
|
||||
2625 3525 2625 5025 1650 5550
|
||||
3 3 1 1 -1 6 0 0 -1 4.000 0 0 0 13
|
||||
2100 2325 1575 3150 2100 4050 2775 4350 2475 5850 1650 6450
|
||||
225 6000 75 5100 225 3150 675 1725 1575 1575 2100 2025
|
||||
2100 2325
|
||||
2120.95 2253.06 2031.72 2559.48 1580.82 2848.69 1568.80 3471.04
|
||||
1902.56 3873.14 2239.98 4175.38 2656.70 4121.44 3019.98 4823.33
|
||||
2694.05 5508.02 2328.92 6078.06 1938.75 6402.97 1227.01 6518.90
|
||||
527.64 6348.53 40.22 5787.20 84.34 5311.32 54.97 4647.04
|
||||
138.94 3594.33 290.76 2810.49 326.47 2027.64 887.80 1540.22
|
||||
1329.37 1506.56 1761.15 1626.87 2019.64 1850.28 2134.87 2100.80
|
||||
2120.95 2253.06 2031.72 2559.48
|
||||
3 3 1 1 -1 6 0 0 -1 4.000 0 0 0 13
|
||||
6300 2325 5775 3150 6300 4050 6975 4350 6675 5850 5850 6450
|
||||
4425 6000 4275 5100 4425 3150 4875 1725 5775 1575 6300 2025
|
||||
6300 2325
|
||||
6320.95 2253.06 6231.72 2559.48 5780.82 2848.69 5768.80 3471.04
|
||||
6102.56 3873.14 6439.98 4175.38 6856.70 4121.44 7219.98 4823.33
|
||||
6894.05 5508.02 6528.92 6078.06 6138.75 6402.97 5427.01 6518.90
|
||||
4727.64 6348.53 4240.22 5787.20 4284.34 5311.32 4254.97 4647.04
|
||||
4338.94 3594.33 4490.76 2810.49 4526.47 2027.64 5087.80 1540.22
|
||||
5529.37 1506.56 5961.15 1626.87 6219.64 1850.28 6334.87 2100.80
|
||||
6320.95 2253.06 6231.72 2559.48
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 450 5400 2100 x>0\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 240 450 4875 3150 y>0\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 450 4725 4050 x=1\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 900 4575 4875 v:=v+1\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 900 5850 4800 v:=v-1\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 180 900 6450 3375 v:=v*x\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 225 900 5475 5775 u:=v+y\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 6150 2475 f\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 5175 2475 t\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 225 900 6975 5775 u:=v+y\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 450 1050 2175 x>0\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 240 450 525 3225 y>0\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 450 375 4125 x=1\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 900 225 4950 v:=v+1\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 195 900 1500 4875 v:=v-1\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 180 900 2100 3450 v:=v*x\001
|
||||
4 0 -1 0 0 14 16 0.0000 4 225 900 1125 5850 u:=v+y\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 1800 2550 f\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 825 2550 t\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 525 3600 t\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 1200 3600 f\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 1200 4275 f\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 375 4500 t\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 4875 3525 t\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 5550 3525 f\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 4725 4425 t\001
|
||||
4 0 -1 0 0 18 16 0.0000 4 210 75 5550 4200 f\001
|
||||
@@ -0,0 +1,79 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 0 1 0 4 100 0 -1 4.000 0 0 -1 0 0 5
|
||||
150 2625 2625 2625 2625 7725 150 7725 150 2625
|
||||
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
|
||||
1558 5263 2277 5263 2277 5598 1558 5598 1558 5263
|
||||
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
|
||||
1079 5886 1798 5886 1798 6221 1079 6221 1079 5886
|
||||
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
|
||||
1127 4640 1846 4640 1846 4975 1127 4975 1127 4640
|
||||
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
|
||||
648 3969 1367 3969 1367 4304 648 4304 648 3969
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
983 4304 1415 4640
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
888 4304 888 5263
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
1463 4975 983 5263
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
1463 4975 1846 5215
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
983 5598 1367 5886
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
1894 5598 1463 5886
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
935 3298 935 3969
|
||||
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
1127 6796 1894 6796 1894 7227 1127 7227 1127 6796
|
||||
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
744 2963 1367 2963 1367 3298 744 3298 744 2963
|
||||
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
1654 3394 2229 3394 2229 3730 1654 3730 1654 3394
|
||||
2 1 0 3 0 4 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
2038 3730 1942 5215
|
||||
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
|
||||
648 5263 1367 5263 1367 5598 648 5598 648 5263
|
||||
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
|
||||
3450 3825 4200 3825 4200 6225 3450 6225 3450 3825
|
||||
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
4344 3265 4967 3265 4967 3600 4344 3600 4344 3265
|
||||
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
3519 6790 4142 6790 4142 7125 3519 7125 3519 6790
|
||||
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
4477 4690 5100 4690 5100 5025 4477 5025 4477 4690
|
||||
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
3369 2965 3992 2965 3992 3300 3369 3300 3369 2965
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 4.00 38.33 76.66
|
||||
1415 6221 1415 6844
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 60.00 120.00
|
||||
3750 3375 3750 3825
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 60.00 120.00
|
||||
4725 3600 4725 4725
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 60.00 120.00
|
||||
3825 6225 3825 6825
|
||||
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 60.00 120.00
|
||||
4650 5025 4125 6825
|
||||
2 1 0 12 15 4 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 12.00 180.00 90.00
|
||||
2700 5025 3375 5025
|
||||
@@ -0,0 +1,19 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 1 0 26 100 0 20 0.000 0 0 -1 0 0 4
|
||||
3375 7275 1275 8100 5400 8100 3375 7275
|
||||
2 1 0 1 0 22 100 0 20 0.000 0 0 -1 0 0 4
|
||||
3375 6750 1275 7575 5400 7575 3375 6750
|
||||
2 1 0 1 0 18 100 0 20 0.000 0 0 -1 0 0 4
|
||||
3375 6225 1275 7050 5400 7050 3375 6225
|
||||
2 1 0 1 14 26 100 0 20 0.000 0 0 -1 0 0 4
|
||||
3375 5700 1275 6525 5400 6525 3375 5700
|
||||
2 1 0 1 0 10 100 0 20 0.000 0 0 -1 0 0 4
|
||||
3375 5175 1275 6000 5400 6000 3375 5175
|
||||
@@ -0,0 +1,346 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 6698 75 9600 2475
|
||||
6 7289 840 9097 2301
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7636 840 8228 840 8228 1084 7636 1084 7636 840
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7532 1292 7845 1292 7845 1501 7532 1501 7532 1292
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7324 1675 7636 1675 7636 1884 7324 1884 7324 1675
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7776 1675 8089 1675 8089 1884 7776 1884 7776 1675
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8193 1675 8505 1675 8505 1884 8193 1884 8193 1675
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7985 2023 8297 2023 8297 2232 7985 2232 7985 2023
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8367 2023 8680 2023 8680 2232 8367 2232 8367 2023
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8784 2023 9097 2023 9097 2232 8784 2232 8784 2023
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7289 2058 7880 2058 7880 2301 7289 2301 7289 2058
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
7880 1084 7706 1292
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
7636 1501 7463 1675
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
7741 1501 7915 1675
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
7810 1501 8297 1675
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
8262 1884 8124 2023
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
8402 1884 8471 2023
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
8471 1884 8924 2023
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 27.82 55.64
|
||||
7706 1501 7706 2058
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 360 7776 1014 ENTRY\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 75 7671 1466 A\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 75 7463 1849 B\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 75 7880 1849 C\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 75 8297 1814 D\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 60 8124 2162 E\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 60 8471 2162 F\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 75 8889 2162 G\001
|
||||
4 0 -1 0 0 18 7 0.0000 4 75 225 7463 2232 EXIT\001
|
||||
-6
|
||||
2 1 0 1 4 4 100 0 -1 0.000 0 0 -1 0 0 4
|
||||
7950 110 9549 2440 6733 2440 7950 110
|
||||
-6
|
||||
6 6525 2543 10275 5325
|
||||
6 7251 2724 9568 4297
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7831 4297 8534 4297 8534 4007 7831 4007 7831 4297
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7582 3800 7954 3800 7954 3552 7582 3552 7582 3800
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7251 3386 7623 3386 7623 3138 7251 3138 7251 3386
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7706 3386 8078 3386 8078 3138 7706 3138 7706 3386
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8202 3386 8574 3386 8574 3138 8202 3138 8202 3386
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8948 3800 9319 3800 9319 3552 8948 3552 8948 3800
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8368 2973 8740 2973 8740 2724 8368 2724 8368 2973
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
8160 4007 7789 3800
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
8285 4007 9112 3800
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8327 3800 8698 3800 8698 3552 8327 3552 8327 3800
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8865 3303 9568 3303 9568 3014 8865 3014 8865 3303
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
7665 3552 7457 3386
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
7747 3552 7871 3386
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
7871 3552 8368 3386
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
8410 3138 8534 2973
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
8244 4007 8492 3800
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.10 66.20
|
||||
8534 3552 9154 3303
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 75 7416 3303 E\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 75 7871 3303 F\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 90 8327 3303 D\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 90 8492 2890 C\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 450 8989 3180 ENTRY\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 90 9072 3718 B\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 90 8492 3718 A\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 285 8037 4173 EXIT\001
|
||||
4 0 -1 0 0 18 8 0.0000 4 90 90 7747 3718 G\001
|
||||
-6
|
||||
2 1 0 1 4 4 100 0 -1 0.000 0 0 -1 0 0 4
|
||||
6585 2603 10215 2603 8400 5265 6585 2603
|
||||
-6
|
||||
6 2925 225 6225 8100
|
||||
6 3150 750 6000 7125
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3975 3300 4425 3675
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5100 3300 4500 3675
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4350 4125 3975 4500
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4575 4125 5100 4500
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3975 4950 4500 5250
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5175 4950 4650 5250
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4575 5700 4350 6600
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4425 1350 4500 1950
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3675 2850 4350 2850 4350 3300 3675 3300 3675 2850
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4725 2850 5400 2850 5400 3300 4725 3300 4725 2850
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4125 3675 4800 3675 4800 4125 4125 4125 4125 3675
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4725 4500 5400 4500 5400 4950 4725 4950 4725 4500
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4275 1950 4950 1950 4950 2400 4275 2400 4275 1950
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
4200 5250 4875 5250 4875 5700 4200 5700 4200 5250
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4500 2400 3975 2850
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4650 2400 5100 2850
|
||||
2 1 1 1 -1 3 0 0 -1 4.000 0 0 -1 0 0 1
|
||||
4200 4575
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3750 750 5100 750 5100 1350 3750 1350 3750 750
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3450 6600 4725 6600 4725 7125 3450 7125 3450 6600
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
3675 4500 4350 4500 4350 4950 3675 4950 3675 4500
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 4
|
||||
1 1 1.00 60.00 120.00
|
||||
3825 3300 3375 4125 3300 5325 3825 6600
|
||||
0.000 -1.000 -1.000 0.000
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 7
|
||||
1 1 1.00 60.00 120.00
|
||||
4800 5700 5400 5850 5850 4575 5775 2325 5100 1575 4800 1575
|
||||
4650 1950
|
||||
0.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.000
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 4500 2325 A\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 150 3900 3225 B\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 5025 3225 C\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 4350 3975 D\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 3900 4800 E\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 5025 4800 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 165 4425 5550 G\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 735 4125 1200 ENTRY\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 450 3750 6900 EXIT\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 4050 2700 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 4950 2700 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 3525 3600 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 4050 3600 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 3975 4350 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 4950 4350 F\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 120 4350 6075 T\001
|
||||
4 0 -1 0 0 18 14 0.0000 4 165 135 4875 6000 F\001
|
||||
-6
|
||||
3 1 0 5 4 4 100 0 -1 0.000 0 0 0 8
|
||||
5325 675 6150 2925 6000 6000 4725 8025 3150 7575 3000 3150
|
||||
3675 300 5025 375
|
||||
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
|
||||
-6
|
||||
6 5475 5025 9750 10050
|
||||
6 5925 5700 8943 9975
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7042 7607 7575 7607 7575 7962 7042 7962 7042 7607
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
6805 9561 7812 9561 7812 9975 6805 9975 6805 9561
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7160 7962 6924 9561
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7727 5700 8734 5700 8734 6114 7727 6114 7727 5700
|
||||
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
8063 6120 7708 6415
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
8021 7586 8554 7586 8554 7942 8021 7942 8021 7586
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7601 6790 7225 7628
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7727 6790 8231 7586
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7237 8382 7769 8382 7769 8738 7237 8738 7237 8382
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7267 7963 7351 8382
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7937 9011 8470 9011 8470 9366 7937 9366 7937 9011
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7183 8969 7716 8969 7716 9324 7183 9324 7183 8969
|
||||
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7476 8759 7392 8969
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7643 8759 8063 9011
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
7404 6393 7937 6393 7937 6748 7404 6748 7404 6393
|
||||
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
|
||||
6440 8341 6973 8341 6973 8696 6440 8696 6440 8341
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
6679 8717 6889 9555
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7099 7963 6679 8341
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7685 6748 7643 8382
|
||||
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 33.53 67.06
|
||||
7476 6748 6553 8341
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 6
|
||||
1 1 1.00 33.53 67.06
|
||||
6511 8717 6386 9011 6135 8927 6009 8550 6470 7712 7392 6706
|
||||
0.000 -1.000 -1.000 -1.000 -1.000 0.000
|
||||
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 5
|
||||
1 1 1.00 33.53 67.06
|
||||
8357 6120 8817 7418 8733 9011 8440 9681 7811 9849
|
||||
0.000 -1.000 -1.000 -1.000 0.000
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 105 7220 7844 B\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 7339 8198 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 360 7160 9797 EXIT\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 555 7955 5996 ENTRY\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 105 7795 6251 T\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 120 8192 7844 C\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 120 7575 6647 A\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 105 7398 8626 D\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 7400 9237 E\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 8136 9237 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 105 7281 8939 T\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 7923 7069 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 105 7488 7279 T\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 120 6648 8560 G\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 6268 9200 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 7694 7314 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 7233 7314 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 105 7025 8257 T\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 6856 8110 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 105 6611 9023 T\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 7872 8867 F\001
|
||||
4 0 -1 0 0 18 11 0.0000 4 120 90 8454 6318 F\001
|
||||
-6
|
||||
3 1 0 1 4 4 100 0 -1 4.000 0 0 0 8
|
||||
7725 5025 9750 6375 9300 9600 7950 10050 6225 10050 5475 8775
|
||||
6750 5850 7725 5025
|
||||
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
|
||||
-6
|
||||
6 825 900 2550 3000
|
||||
2 2 0 1 0 24 100 0 10 4.000 0 0 -1 0 0 5
|
||||
1050 1200 2250 1200 2250 1725 1050 1725 1050 1200
|
||||
2 2 0 1 0 24 100 0 10 4.000 0 0 -1 0 0 5
|
||||
1050 2175 2250 2175 2250 2700 1050 2700 1050 2175
|
||||
2 1 0 1 0 24 100 0 10 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1650 1725 1650 2175
|
||||
2 2 0 1 4 24 100 0 -1 4.000 0 0 -1 0 0 5
|
||||
825 900 2550 900 2550 3000 825 3000 825 900
|
||||
-6
|
||||
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
|
||||
1 1 5.00 60.00 120.00
|
||||
1 1 5.00 60.00 120.00
|
||||
5550 6675 6225 6975
|
||||
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
|
||||
1 1 5.00 60.00 120.00
|
||||
1 1 5.00 60.00 120.00
|
||||
6075 4725 7650 4275
|
||||
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
|
||||
1 1 5.00 60.00 120.00
|
||||
1 1 5.00 60.00 120.00
|
||||
5775 1800 7200 1500
|
||||
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
|
||||
1 1 5.00 60.00 120.00
|
||||
1 1 5.00 60.00 120.00
|
||||
1703 2999 3087 3451
|
||||
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
|
||||
1 1 5.00 60.00 120.00
|
||||
1 1 5.00 60.00 120.00
|
||||
3187 6131 1950 6900
|
||||
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
|
||||
1 1 5.00 60.00 120.00
|
||||
1 1 5.00 60.00 120.00
|
||||
3487 7256 2250 8025
|
||||
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
|
||||
1 1 5.00 60.00 120.00
|
||||
1 1 5.00 60.00 120.00
|
||||
3071 5302 1645 5602
|
||||
3 1 1 1 4 24 100 0 -1 4.000 0 0 0 9
|
||||
1350 5325 1800 6225 2100 7575 2325 8325 1950 9225 1125 9000
|
||||
375 7125 375 5025 975 4200
|
||||
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
|
||||
1.000
|
||||
4 0 4 100 0 16 24 0.0000 4 360 690 1050 825 loop\001
|
||||
4 0 4 100 0 16 24 0.0000 4 285 705 8625 825 dom\001
|
||||
4 0 4 100 0 16 24 0.0000 4 360 915 9525 4050 pdom\001
|
||||
4 0 4 100 0 16 24 0.0000 4 285 825 9000 5925 CDG\001
|
||||
4 0 4 100 0 16 36 0.0000 4 405 1110 5400 675 CFG\001
|
||||
4 0 4 100 0 16 24 5.0615 4 285 1995 825 6150 Other facets\001
|
||||
@@ -0,0 +1,27 @@
|
||||
#FIG 3.2
|
||||
Portrait
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
0
|
||||
1200 2
|
||||
1 2 0 1 0 14 0 0 20 0.000 1 0.0000 5077 4580 38 50 5039 4596 5113 4564
|
||||
2 1 0 1 -1 24 0 0 20 0.000 0 0 -1 0 0 9
|
||||
5039 6644 5039 6644 5016 6836 4892 6836 4892 6900 5212 6900
|
||||
5212 6836 5113 6836 5089 6644
|
||||
2 1 0 1 0 12 0 0 20 0.000 0 0 -1 0 0 4
|
||||
4376 6644 5753 6644 5064 6004 4376 6644
|
||||
2 1 0 1 0 13 0 0 20 0.000 0 0 -1 0 0 4
|
||||
4475 6132 5654 6132 5064 5620 4475 6132
|
||||
2 1 0 1 0 14 0 0 20 0.000 0 0 -1 0 0 4
|
||||
4572 5748 5556 5748 5064 5236 4572 5748
|
||||
2 1 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 4
|
||||
4671 5364 5458 5364 5064 4596 4671 5364
|
||||
4 0 7 0 0 0 12 0.0000 4 15 45 4050 7350 .\001
|
||||
4 0 7 0 0 0 12 0.0000 4 15 45 6225 4425 .\001
|
||||
4 0 8 0 0 26 5 0.0000 4 120 555 5630 6004 Regions\001
|
||||
4 0 8 0 0 26 5 0.0000 4 90 630 5507 5620 Constants\001
|
||||
4 0 8 0 0 26 5 0.0000 4 120 765 5433 5108 Pseudo Ops\001
|
||||
4 0 8 0 0 26 5 0.0000 4 90 630 5605 6388 Core RTL\001
|
||||