diff options
author | zakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-08-26 17:39:27 +0000 |
---|---|---|
committer | zakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-08-26 17:39:27 +0000 |
commit | 6bf20c78f5b69d40bcc4931df93d29198435ab67 (patch) | |
tree | e3eda937a05d7db42de725b7013bd0344b987f34 /lcc/doc | |
parent | 872d4d7f55af706737ffb361bb76ad13e7496770 (diff) | |
download | ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.tar.gz ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.zip |
newlines fixed
git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'lcc/doc')
-rwxr-xr-x | lcc/doc/4.html | 1508 | ||||
-rwxr-xr-x | lcc/doc/bprint.1 | 166 | ||||
-rwxr-xr-x | lcc/doc/install.html | 1592 | ||||
-rwxr-xr-x | lcc/doc/lcc.1 | 1210 |
4 files changed, 2238 insertions, 2238 deletions
diff --git a/lcc/doc/4.html b/lcc/doc/4.html index 0158d8b..a2e1213 100755 --- a/lcc/doc/4.html +++ b/lcc/doc/4.html @@ -1,754 +1,754 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-
-<head>
-<link HREF="mailto:drh@microsoft.com" REV="made" TITLE="David R. Hanson">
-<title>The lcc 4.1 Code-Generation Interface</title>
-</head>
-
-<body>
-
-<h1>The lcc 4.1 Code-Generation Interface</h1>
-
-<p ALIGN="LEFT"><strong><a HREF="http://www.research.microsoft.com/~cwfraser/">Christopher
-W. Fraser</a> and <a HREF="http://www.research.microsoft.com/~drh/">David R. Hanson</a>, <a
-HREF="http://www.research.microsoft.com/">Microsoft Research</a></strong></p>
-
-<h2>Contents</h2>
-
-<dir>
- <li><a HREF="#intro">Introduction</a> </li>
- <li><a HREF="#metrics">5.1 Type Metrics</a></li>
- <li><a HREF="#symbols">5.3 Symbols</a> </li>
- <li><a HREF="#operators">5.5 Dag Operators</a></li>
- <li><a HREF="#flags">5.6 Interface Flags</a></li>
- <li><a HREF="#definitions">5.8 Definitions</a></li>
- <li><a HREF="#constants">5.9 Constants</a></li>
- <li><a HREF="#upcalls">5.12 Upcalls</a></li>
-</dir>
-
-<h2><a NAME="intro">Introduction</a></h2>
-
-<p>Version 4.1 is the latest release of <a
-HREF="http://www.cs.princeton.edu/software/lcc/">lcc</a>, the ANSI C compiler described in
-our book <cite>A Retargetable C Compiler: Design and Implementation</cite>
-(Addison-Wesley, 1995, ISBN 0-8053-1670-1). This document summarizes the differences
-between the 4.1 code-generation interface and the 3.x interface described in Chap. 5 of <cite>A
-Retargetable C Compiler</cite>.</p>
-
-<p>Previous versions of lcc supported only three sizes of integers, two sizes of floats,
-and insisted that pointers fit in unsigned integers (see Sec. 5.1 of <cite>A Retargetable
-C Compiler</cite>). These assumptions simplified the compiler, and were suitable for
-32-bit architectures. But on 64-bit architectures, such as the DEC ALPHA, it's natural to
-have four sizes of integers and perhaps three sizes of floats, and on 16-bit
-architectures, 32-bit pointers don't fit in unsigned integers. Also, the 3.x constaints
-limited the use of lcc's back ends for other languages, such as Java.</p>
-
-<p>Version 4.x removes all of these restrictions: It supports any number of sizes for
-integers and floats, and the size of pointers need not be related to the size of any of
-the integer types. The major changes in the code-generation interface are:
-
-<ul>
- <li>The number of type suffixes has been reduced to 6.</li>
- <li>Dag operators are composed of a generic operator, a type suffix, and a size.</li>
- <li>Unsigned variants of several operators have been added.</li>
- <li>Several interface functions have new signatures.</li>
-</ul>
-
-<p>In addition, version 4.x is written in ANSI C and uses the standard I/O library and
-other standard C functions.</p>
-
-<p>The sections below parallel the subsections of Chap. 5 of <cite>A Retargetable C
-Compiler</cite> and summarize the differences between the 3.x and 4.x code-generation
-interface. Unaffected subsections are omitted. Page citations refer to pages in <cite>A
-Retargetable C Compiler</cite>.</p>
-
-<h2><a NAME="metrics">5.1 Type Metrics</a></h2>
-
-<p>There are now 10 metrics in an interface record:</p>
-
-<pre>Metrics charmetric;
-Metrics shortmetric;
-Metrics intmetric;
-Metrics longmetric;
-Metrics longlongmetric;
-Metrics floatmetric;
-Metrics doublemetric;
-Metrics longdoublemetric;
-Metrics ptrmetric;
-Metrics structmetric;</pre>
-
-<p>Each of these specifies the size and alignment of the corresponding type. <code>ptrmetric</code>
-describes all pointers.</p>
-
-<h2><a NAME="symbols">5.3 Symbols</a></h2>
-
-<p>The actual value of a constant is stored in the <code>u.c.v</code> field of a symbol,
-which holds a <code>Value</code>:</p>
-
-<pre>typedef union value {
- long i;
- unsigned long u;
- long double d;
- void *p;
- void (*g)(void);
-} Value;</pre>
-
-<p>The value is stored in the appropriate field according to its type, which is given by
-the symbol's <code>type</code> field.</p>
-
-<h2><a NAME="operators">5.5 Dag Operators</a></h2>
-
-<p>The <code>op</code> field a of <code>node</code> structure holds a dag operator, which
-consists of a generic operator, a type suffix, and a size indicator. The type suffixes
-are:</p>
-
-<pre>enum {
- F=FLOAT,
- I=INT,
- U=UNSIGNED,
- P=POINTER,
- V=VOID,
- B=STRUCT
-};
-
-#define sizeop(n) ((n)<<10)</pre>
-
-<p>Given a generic operator <code>o</code>, a type suffix <code>t</code>, and a size <code>s</code>,
-a type- and size-specific operator is formed by <code>o+t+sizeop(s)</code>. For example, <code>ADD+F+sizeop(4)</code>
-forms the operator <code>ADDF4</code>, which denotes the sum of two 4-byte floats.
-Similarly, <code>ADD+F+sizeop(8)</code> forms <code>ADDF8</code>, which denotes 8-byte
-floating addition. In the 3.x code-generation interface, <code>ADDF</code> and <code>ADDD</code>
-denoted these operations. There was no size indicator in the 3.x operators because the
-type suffix supplied both a type and a size.</p>
-
-<p>Table 5.1 lists each generic operator, its valid type suffixes, and the number of <code>kids</code>
-and <code>syms</code> that it uses; multiple values for <code>kids</code> indicate
-type-specific variants. The notations in the <strong>syms</strong> column give the number
-of <code>syms</code> values and a one-letter code that suggests their uses: 1V indicates
-that <code>syms[0]</code> points to a symbol for a variable, 1C indicates that <code>syms[0]</code>
-is a constant, and 1L indicates that <code>syms[0]</code> is a label. For 1S, <code>syms[0]</code>
-is a constant whose value is a size in bytes; 2S adds <code>syms[1]</code>, which is a
-constant whose value is an alignment. For most operators, the type suffix and size
-indicator denote the type and size of operation to perform and the type and size of the
-result.</p>
-
-<table WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">
- <tr>
- <td COLSPAN="6" ALIGN="CENTER"><strong>Table 5.1<img SRC="/~drh/resources/dot_clear.gif"
- ALT="|" WIDTH="18" HEIGHT="1">Node Operators.</strong></td>
- </tr>
- <tr>
- <td><strong>syms</strong></td>
- <td><strong>kids</strong></td>
- <td><strong>Operator</strong></td>
- <td><strong>Type Suffixes</strong></td>
- <td><strong>Sizes</strong></td>
- <td><strong>Operation</strong></td>
- </tr>
- <tr>
- <td>1V</td>
- <td>0</td>
- <td><code>ADDRF</code></td>
- <td><code>...P..</code></td>
- <td>p</td>
- <td>address of a parameter</td>
- </tr>
- <tr>
- <td>1V</td>
- <td>0</td>
- <td><code>ADDRG</code></td>
- <td><code>...P..</code></td>
- <td>p</td>
- <td>address of a global</td>
- </tr>
- <tr>
- <td>1V</td>
- <td>0</td>
- <td><code>ADDRL</code></td>
- <td><code>...P..</code></td>
- <td>p</td>
- <td>address of a local</td>
- </tr>
- <tr>
- <td>1C</td>
- <td>0</td>
- <td><code>CNST</code></td>
- <td><code>FIUP..</code></td>
- <td>fdx csilh p</td>
- <td>constant</td>
- </tr>
- <tr ALIGN="LEFT" VALIGN="TOP">
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td></td>
- <td>1</td>
- <td><code>BCOM</code></td>
- <td><code>.IU...</code></td>
- <td>ilh</td>
- <td>bitwise complement</td>
- </tr>
- <tr>
- <td>1S</td>
- <td>1</td>
- <td><code>CVF</code></td>
- <td><code>FI....</code></td>
- <td>fdx ilh</td>
- <td>convert from float</td>
- </tr>
- <tr>
- <td>1S</td>
- <td>1</td>
- <td><code>CVI</code></td>
- <td><code>FIU...</code></td>
- <td>fdx csilh csilhp</td>
- <td>convert from signed integer</td>
- </tr>
- <tr>
- <td>1S</td>
- <td>1</td>
- <td><code>CVP</code></td>
- <td><code>..U..</code></td>
- <td>p</td>
- <td>convert from pointer</td>
- </tr>
- <tr>
- <td>1S</td>
- <td>1</td>
- <td><code>CVU</code></td>
- <td><code>.IUP..</code></td>
- <td>csilh p</td>
- <td>convert from unsigned integer</td>
- </tr>
- <tr>
- <td></td>
- <td>1</td>
- <td><code>INDIR</code></td>
- <td><code>FIUP.B</code></td>
- <td>fdx csilh p</td>
- <td>fetch</td>
- </tr>
- <tr>
- <td></td>
- <td>1</td>
- <td><code>NEG</code></td>
- <td><code>FI....</code></td>
- <td>fdx ilh</td>
- <td>negation</td>
- </tr>
- <tr>
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>ADD</code></td>
- <td><code>FIUP..</code></td>
- <td>fdx ilh ilhp p</td>
- <td>addition</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>BAND</code></td>
- <td><code>.IU...</code></td>
- <td>ilh</td>
- <td>bitwise AND</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>BOR</code></td>
- <td><code>.IU...</code></td>
- <td>ilh</td>
- <td>bitwise inclusive OR</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>BXOR</code></td>
- <td><code>.IU...</code></td>
- <td>ilh</td>
- <td>bitwise exclusive OR</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>DIV</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh</td>
- <td>division</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>LSH</code></td>
- <td><code>.IU...</code></td>
- <td>ilh</td>
- <td>left shift</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>MOD</code></td>
- <td><code>.IU...</code></td>
- <td>ilh</td>
- <td>modulus</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>MUL</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh</td>
- <td>multiplication</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>RSH</code></td>
- <td><code>.IU...</code></td>
- <td>ilh</td>
- <td>right shift</td>
- </tr>
- <tr>
- <td></td>
- <td>2</td>
- <td><code>SUB</code></td>
- <td><code>FIUP..</code></td>
- <td>fdx ilh ilhp p</td>
- <td>subtraction</td>
- </tr>
- <tr>
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td>2S</td>
- <td>2</td>
- <td><code>ASGN</code></td>
- <td><code>FIUP.B</code></td>
- <td>fdx csilh p</td>
- <td>assignment</td>
- </tr>
- <tr>
- <td>1L</td>
- <td>2</td>
- <td><code>EQ</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh ilhp</td>
- <td>jump if equal</td>
- </tr>
- <tr>
- <td>1L</td>
- <td>2</td>
- <td><code>GE</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh ilhp</td>
- <td>jump if greater than or equal</td>
- </tr>
- <tr>
- <td>1L</td>
- <td>2</td>
- <td><code>GT</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh ilhp</td>
- <td>jump if greater than</td>
- </tr>
- <tr>
- <td>1L</td>
- <td>2</td>
- <td><code>LE</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh ilhp</td>
- <td>jump if less than or equal</td>
- </tr>
- <tr>
- <td>1L</td>
- <td>2</td>
- <td><code>LT</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh ilhp</td>
- <td>jump if less than</td>
- </tr>
- <tr>
- <td>1L</td>
- <td>2</td>
- <td><code>NE</code></td>
- <td><code>FIU...</code></td>
- <td>fdx ilh ilhp</td>
- <td>jump if not equal</td>
- </tr>
- <tr>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td>2S</td>
- <td>1</td>
- <td><code>ARG</code></td>
- <td><code>FIUP.B</code></td>
- <td>fdx ilh p</td>
- <td>argument</td>
- </tr>
- <tr>
- <td>1</td>
- <td>1 or 2</td>
- <td><code>CALL</code></td>
- <td><code>FIUPVB</code></td>
- <td>fdx ilh p</td>
- <td>function call</td>
- </tr>
- <tr>
- <td></td>
- <td>1</td>
- <td><code>RET</code></td>
- <td><code>FIUPV.</code></td>
- <td>fdx ilh p</td>
- <td>return from function</td>
- </tr>
- <tr>
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr>
- <td></td>
- <td>1</td>
- <td><code>JUMP</code></td>
- <td><code>....V.</code></td>
- <td></td>
- <td>unconditional jump</td>
- </tr>
- <tr>
- <td>1L</td>
- <td>0</td>
- <td><code>LABEL</code></td>
- <td><code>....V.</code></td>
- <td></td>
- <td>label definition</td>
- </tr>
-</table>
-
-<p>The entries in the <strong>Sizes</strong> column indicate sizes of the operators that
-back ends must implement. Letters denote the size of float (f), double (d), long double
-(x), character (c), short integer (s), integer (i), long integer (l), "long
-long" integer (h) , and pointer (p). These sizes are separated into sets for each
-type suffix, except that a single set is used for both I and U when the set for I is
-identical to the set for U.</p>
-
-<p>The actual values for the size indicators, fdxcsilhp, depend on the target. A
-specification like <code>ADDF</code>f denotes the operator <code>ADD+F+sizeop(</code>f<code>)</code>,
-where "f" is replaced by a target-dependent value, e.g., <code>ADDF4</code> and <code>ADDF8</code>.
-For example, back ends must implement the following <code>CVI</code> and <code>MUL</code>
-operators.</p>
-
-<blockquote>
- <p><code>CVIF</code>f <code>CVIF</code>d <code>CVIF</code>x<br>
- <code>CVII</code>c <code>CVII</code>s <code>CVII</code>i <code>CVII</code>l <code>CVII</code>h<br>
- <code>CVIU</code>c <code>CVIU</code>s <code>CVIU</code>i <code>CVIU</code>l <code>CVIU</code>h
- <code>CVIU</code>p<br>
- <br>
- <code>MULF</code>f <code>MULF</code>d <code>MULF</code>x<br>
- <code>MULI</code>i <code>MULI</code>l <code>MULI</code>h<br>
- <code>MULU</code>i <code>MULU</code>l <code>MULU</code>h</p>
-</blockquote>
-
-<p>On most platforms, there are fewer than three sizes of floats and six sizes of
-integers, and pointers are usually the same size as one of the integers. And lcc doesn't
-support the "long long" type, so h is not currently used. So the set of
-platform-specific operators is usually smaller than the list above suggests. For example,
-the X86, SPARC, and MIPS back ends implement the following <code>CVI</code> and <code>MUL</code>
-operators.</p>
-
-<blockquote>
- <p><code>CVIF</code>4 <code>CVIF</code>8<br>
- <code>CVII</code>1 <code>CVII</code>2 <code>CVII</code>4<br>
- <code>CVIU</code>1 <code>CVIU</code>2 <code>CVIU</code>4 <br>
- <br>
- <code>MULF</code>4 <code>MULF</code>8<br>
- <code>MULI</code>4<br>
- <code>MULU</code>4</p>
-</blockquote>
-
-<p>The set of operators is thus target-dependent; for example, <code>ADDI8</code> appears
-only if the target supports an 8-byte integer type. <a
-HREF="ftp://ftp.cs.princeton.edu/pub/packages/lcc/contrib/ops.c"><code>ops.c</code></a> is
-a program that, given a set of sizes, prints the required operators and their values,
-e.g.,</p>
-
-<blockquote>
- <pre>% <em>ops c=1 s=2 i=4 l=4 h=4 f=4 d=8 x=8 p=4</em>
-...
- CVIF4=4225 CVIF8=8321
- CVII1=1157 CVII2=2181 CVII4=4229
- CVIU1=1158 CVIU2=2182 CVIU4=4230
-...
- MULF4=4561 MULF8=8657
- MULI4=4565
- MULU4=4566
-...
-131 operators</pre>
-</blockquote>
-
-<p>The type suffix for a conversion operator denotes the type of the result and the size
-indicator gives the size of the result. For example, <code>CVUI4</code> converts an
-unsigned (<code>U</code>) to a 4-byte signed integer (<code>I4</code>). The <code>syms[0]</code>
-field points to a symbol-table entry for a integer constant that gives the size of the
-source operand. For example, if <code>syms[0]</code> in a <code>CVUI4</code> points to a
-symbol-table entry for 2, the conversion widens a 2-byte unsigned integer to a 4-byte
-signed integer. Conversions that widen unsigned integers zero-extend; those that widen
-signed integers sign-extend.</p>
-
-<p>The front end composes conversions between types <em>T</em><sub>1</sub> and <em>T</em><sub>2</sub>
-by widening <em>T</em><sub>1</sub> to it's "supertype", if necessary, converting
-that result to <em>T</em><sub>2</sub>'s supertype, then narrowing the result to <em>T</em><sub>2</sub>,
-if necessary. The following table lists the supertypes; omitted entries are their own
-supertypes.</p>
-
-<blockquote>
- <table BORDER="0" CELLPADDING="0" CELLSPACING="0">
- <tr>
- <td><strong>Type</strong></td>
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
- <td><strong>Supertype</strong></td>
- </tr>
- <tr>
- <td>signed char</td>
- <td></td>
- <td>int</td>
- </tr>
- <tr>
- <td>signed short</td>
- <td></td>
- <td>int</td>
- </tr>
- <tr ALIGN="LEFT" VALIGN="TOP">
- <td>unsigned char</td>
- <td></td>
- <td>int, if sizeof (char) < sizeof (int)<br>
- unsigned, otherwise</td>
- </tr>
- <tr ALIGN="LEFT" VALIGN="TOP">
- <td>unsigned short</td>
- <td></td>
- <td>int, if sizeof (short) < sizeof (int)<br>
- unsigned, otherwise</td>
- </tr>
- <tr ALIGN="LEFT" VALIGN="TOP">
- <td>void *</td>
- <td></td>
- <td>an unsigned type as large as a pointer</td>
- </tr>
- </table>
-</blockquote>
-
-<p>Pointers are converted to an unsigned type of the same size, even when that type is not
-one of the integer types.</p>
-
-<p>For example, the front end converts a signed short to a float by first converting it to
-an int and then to a float. It converts an unsigned short to an int with a single <code>CVUI</code>i
-conversion, when shorts are smaller than ints.</p>
-
-<p>There are now signed and unsigned variants of <code>ASGN</code>, <code>INDIR</code>, <code>BCOM</code>,
-<code>BOR</code>, <code>BXOR</code>, <code>BAND</code>, <code>ARG</code>, <code>CALL</code>,
-and <code>RET</code> to simplify code generation on platforms that use different
-instructions or register set for signed and unsigned operations. Likewise there are now
-pointer variants of <code>ASGN</code>, <code>INDIR</code>, <code>ARG</code>, <code>CALL</code>,
-and <code>RET</code>.</p>
-
-<h2><a NAME="flags">5.6 Interface Flags</a></h2>
-
-<pre>unsigned unsigned_char:1;</pre>
-
-<p>tells the front end whether plain characters are signed or unsigned. If it's zero, char
-is a signed type; otherwise, char is an unsigned type.</p>
-
-<p>All the interface flags can be set by command-line options, e.g., <code>-Wf-unsigned_char=1</code>
-causes plain characters to be unsigned.</p>
-
-<h2><a NAME="definitions">5.8 Definitions</a></h2>
-
-<p>The front end announces local variables by calling</p>
-
-<pre>void (*local)(Symbol);</pre>
-
-<p>It announces temporaries likewise; these have the symbol's <code>temporary</code> flag
-set, which indicates that the symbol will be used only in the next call to <code>gen</code>.
-If a temporary's <code>u.t.cse</code> field is nonnull, it points to the node that
-computes the value assigned to the temporary; see page 346.</p>
-
-<p>The front end calls</p>
-
-<pre>void (*address)(Symbol p, Symbol q, long n);</pre>
-
-<p>to initialize <code>q</code> to a symbol that represents an address of the form <em>x</em>+<code>n</code>,
-where <em>x</em> is the address represented by <code>p</code> and the long integer <code>n</code>
-is positive or negative.</p>
-
-<h2><a NAME="constants">5.9 Constants</a></h2>
-
-<p>The interface function</p>
-
-<pre>void (*defconst)(int suffix, int size, Value v);</pre>
-
-<p>initializes constants. defconst emits directives to define a cell and initialize it to
-a constant value. v is the constant value, suffix identifies the type of the value, and
-size is the size of the value in bytes. The value of suffix indicates which field of v
-holds the value, as shown in the following table.</p>
-
-<blockquote>
- <table BORDER="0" CELLPADDING="1" CELLSPACING="1">
- <tr>
- <td><strong>suffix</strong></td>
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
- <td><strong>v Field</strong></td>
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
- <td><strong>size</strong></td>
- </tr>
- <tr>
- <td><code>F</code></td>
- <td></td>
- <td><code>v.d</code></td>
- <td></td>
- <td>float, double, long double</td>
- </tr>
- <tr>
- <td><code>I</code></td>
- <td></td>
- <td><code>v.i</code></td>
- <td></td>
- <td>signed char, signed short, signed int, signed long</td>
- </tr>
- <tr>
- <td><code>U</code></td>
- <td></td>
- <td><code>v.u</code></td>
- <td></td>
- <td>unsigned char, unsigned short, unsigned int, unsigned long</td>
- </tr>
- <tr>
- <td><code>P</code></td>
- <td></td>
- <td><code>v.p</code></td>
- <td></td>
- <td>void *</td>
- </tr>
- </table>
-</blockquote>
-
-<p><code>defconst</code> must narrow <code>v.</code>x when <code>size</code> is less than <code>sizeof</code>
-<code>v.</code>x; e.g., to emit an unsigned char, <code>defconst</code> should emit <code>(unsigned
-char)v.i</code>.</p>
-
-<h2><a NAME="upcalls">5.12 Upcalls</a></h2>
-
-<p>lcc 4.x uses standard I/O and its I/O functions have been changed accordingly. lcc
-reads input from the standard input, emits code to the standard output, and writes
-diagnostics to the standard error output. It uses <code>freopen</code> to redirect these
-streams to explicit files, when necessary.</p>
-
-<p><code>bp</code>, <code>outflush</code>, and <code>outs</code> have been eliminated.</p>
-
-<pre>extern void fprint(FILE *f, const char *fmt, ...);
-extern void print(const char *fmt, ...);</pre>
-
-<p>print formatted data to file <code>f</code> (<code>fprint</code>) or the standard
-output (<code>print</code>). These functions are like standard C's <code>printf</code> and
-<code>fprintf</code>, but support only some of the standard conversion specifiers and do
-not support flags, precision, and field-width specifications. They support the following
-new conversion specifiers in addition to those described on page 99.</p>
-
-<blockquote>
- <table BORDER="0" CELLPADDING="0" CELLSPACING="0">
- <tr>
- <td><strong>Specifiers</strong></td>
- <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
- <td><strong>Corresponding printf Specifiers</strong></td>
- </tr>
- <tr>
- <td><code>%c</code></td>
- <td></td>
- <td><code>%c</code></td>
- </tr>
- <tr>
- <td><code>%d %D</code></td>
- <td></td>
- <td><code>%d %ld</code></td>
- </tr>
- <tr>
- <td><code>%u %U</code></td>
- <td></td>
- <td><code>%u %lu</code></td>
- </tr>
- <tr>
- <td><code>%x %X</code></td>
- <td></td>
- <td><code>%x %lx</code></td>
- </tr>
- <tr>
- <td><code>%f %e %g</code></td>
- <td></td>
- <td><code>%e %f %g</code></td>
- </tr>
- <tr ALIGN="LEFT" VALIGN="TOP">
- <td><code>%p</code></td>
- <td></td>
- <td>Converts the corresponding void * argument to unsigned long and prints it with the <code>printf</code>
- <code>%#x</code> specifier or just <code>%x</code> when the argument is null.</td>
- </tr>
- <tr ALIGN="LEFT" VALIGN="TOP">
- <td><code>%I</code></td>
- <td></td>
- <td>Prints the number of spaces given by the corresponding argument.</td>
- </tr>
- </table>
-</blockquote>
-
-<pre>#define generic(op) ((op)&0x3F0)
-#define specific(op) ((op)&0x3FF)</pre>
-
-<p><code>generic(op)</code> returns the generic variant of <code>op</code>; that is,
-without its type suffix and size indicator. <code>specific(op)</code> returns the
-type-specific variant of <code>op</code>; that is, without its size indicator.</p>
-
-<p><code>newconst</code> has been replaced by</p>
-
-<pre>extern Symbol intconst(int n);</pre>
-
-<p>which installs the integer constant <code>n</code> in the symbol table, if necessary,
-and returns a pointer to the symbol-table entry.</p>
-
-<hr>
-
-<address>
- <a HREF="http://www.research.microsoft.com/~cwfraser/">Chris Fraser</a> / <a
- HREF="mailto:cwfraser@microsoft.com">cwfraser@microsoft.com</a><br>
- <a HREF="http://www.research.microsoft.com/~drh/">David Hanson</a> / <a
- HREF="mailto:drh@microsoft.com">drh@microsoft.com</a><br>
- $Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $
-</address>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> + +<head> +<link HREF="mailto:drh@microsoft.com" REV="made" TITLE="David R. Hanson"> +<title>The lcc 4.1 Code-Generation Interface</title> +</head> + +<body> + +<h1>The lcc 4.1 Code-Generation Interface</h1> + +<p ALIGN="LEFT"><strong><a HREF="http://www.research.microsoft.com/~cwfraser/">Christopher +W. Fraser</a> and <a HREF="http://www.research.microsoft.com/~drh/">David R. Hanson</a>, <a +HREF="http://www.research.microsoft.com/">Microsoft Research</a></strong></p> + +<h2>Contents</h2> + +<dir> + <li><a HREF="#intro">Introduction</a> </li> + <li><a HREF="#metrics">5.1 Type Metrics</a></li> + <li><a HREF="#symbols">5.3 Symbols</a> </li> + <li><a HREF="#operators">5.5 Dag Operators</a></li> + <li><a HREF="#flags">5.6 Interface Flags</a></li> + <li><a HREF="#definitions">5.8 Definitions</a></li> + <li><a HREF="#constants">5.9 Constants</a></li> + <li><a HREF="#upcalls">5.12 Upcalls</a></li> +</dir> + +<h2><a NAME="intro">Introduction</a></h2> + +<p>Version 4.1 is the latest release of <a +HREF="http://www.cs.princeton.edu/software/lcc/">lcc</a>, the ANSI C compiler described in +our book <cite>A Retargetable C Compiler: Design and Implementation</cite> +(Addison-Wesley, 1995, ISBN 0-8053-1670-1). This document summarizes the differences +between the 4.1 code-generation interface and the 3.x interface described in Chap. 5 of <cite>A +Retargetable C Compiler</cite>.</p> + +<p>Previous versions of lcc supported only three sizes of integers, two sizes of floats, +and insisted that pointers fit in unsigned integers (see Sec. 5.1 of <cite>A Retargetable +C Compiler</cite>). These assumptions simplified the compiler, and were suitable for +32-bit architectures. But on 64-bit architectures, such as the DEC ALPHA, it's natural to +have four sizes of integers and perhaps three sizes of floats, and on 16-bit +architectures, 32-bit pointers don't fit in unsigned integers. Also, the 3.x constaints +limited the use of lcc's back ends for other languages, such as Java.</p> + +<p>Version 4.x removes all of these restrictions: It supports any number of sizes for +integers and floats, and the size of pointers need not be related to the size of any of +the integer types. The major changes in the code-generation interface are: + +<ul> + <li>The number of type suffixes has been reduced to 6.</li> + <li>Dag operators are composed of a generic operator, a type suffix, and a size.</li> + <li>Unsigned variants of several operators have been added.</li> + <li>Several interface functions have new signatures.</li> +</ul> + +<p>In addition, version 4.x is written in ANSI C and uses the standard I/O library and +other standard C functions.</p> + +<p>The sections below parallel the subsections of Chap. 5 of <cite>A Retargetable C +Compiler</cite> and summarize the differences between the 3.x and 4.x code-generation +interface. Unaffected subsections are omitted. Page citations refer to pages in <cite>A +Retargetable C Compiler</cite>.</p> + +<h2><a NAME="metrics">5.1 Type Metrics</a></h2> + +<p>There are now 10 metrics in an interface record:</p> + +<pre>Metrics charmetric; +Metrics shortmetric; +Metrics intmetric; +Metrics longmetric; +Metrics longlongmetric; +Metrics floatmetric; +Metrics doublemetric; +Metrics longdoublemetric; +Metrics ptrmetric; +Metrics structmetric;</pre> + +<p>Each of these specifies the size and alignment of the corresponding type. <code>ptrmetric</code> +describes all pointers.</p> + +<h2><a NAME="symbols">5.3 Symbols</a></h2> + +<p>The actual value of a constant is stored in the <code>u.c.v</code> field of a symbol, +which holds a <code>Value</code>:</p> + +<pre>typedef union value { + long i; + unsigned long u; + long double d; + void *p; + void (*g)(void); +} Value;</pre> + +<p>The value is stored in the appropriate field according to its type, which is given by +the symbol's <code>type</code> field.</p> + +<h2><a NAME="operators">5.5 Dag Operators</a></h2> + +<p>The <code>op</code> field a of <code>node</code> structure holds a dag operator, which +consists of a generic operator, a type suffix, and a size indicator. The type suffixes +are:</p> + +<pre>enum { + F=FLOAT, + I=INT, + U=UNSIGNED, + P=POINTER, + V=VOID, + B=STRUCT +}; + +#define sizeop(n) ((n)<<10)</pre> + +<p>Given a generic operator <code>o</code>, a type suffix <code>t</code>, and a size <code>s</code>, +a type- and size-specific operator is formed by <code>o+t+sizeop(s)</code>. For example, <code>ADD+F+sizeop(4)</code> +forms the operator <code>ADDF4</code>, which denotes the sum of two 4-byte floats. +Similarly, <code>ADD+F+sizeop(8)</code> forms <code>ADDF8</code>, which denotes 8-byte +floating addition. In the 3.x code-generation interface, <code>ADDF</code> and <code>ADDD</code> +denoted these operations. There was no size indicator in the 3.x operators because the +type suffix supplied both a type and a size.</p> + +<p>Table 5.1 lists each generic operator, its valid type suffixes, and the number of <code>kids</code> +and <code>syms</code> that it uses; multiple values for <code>kids</code> indicate +type-specific variants. The notations in the <strong>syms</strong> column give the number +of <code>syms</code> values and a one-letter code that suggests their uses: 1V indicates +that <code>syms[0]</code> points to a symbol for a variable, 1C indicates that <code>syms[0]</code> +is a constant, and 1L indicates that <code>syms[0]</code> is a label. For 1S, <code>syms[0]</code> +is a constant whose value is a size in bytes; 2S adds <code>syms[1]</code>, which is a +constant whose value is an alignment. For most operators, the type suffix and size +indicator denote the type and size of operation to perform and the type and size of the +result.</p> + +<table WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0"> + <tr> + <td COLSPAN="6" ALIGN="CENTER"><strong>Table 5.1<img SRC="/~drh/resources/dot_clear.gif" + ALT="|" WIDTH="18" HEIGHT="1">Node Operators.</strong></td> + </tr> + <tr> + <td><strong>syms</strong></td> + <td><strong>kids</strong></td> + <td><strong>Operator</strong></td> + <td><strong>Type Suffixes</strong></td> + <td><strong>Sizes</strong></td> + <td><strong>Operation</strong></td> + </tr> + <tr> + <td>1V</td> + <td>0</td> + <td><code>ADDRF</code></td> + <td><code>...P..</code></td> + <td>p</td> + <td>address of a parameter</td> + </tr> + <tr> + <td>1V</td> + <td>0</td> + <td><code>ADDRG</code></td> + <td><code>...P..</code></td> + <td>p</td> + <td>address of a global</td> + </tr> + <tr> + <td>1V</td> + <td>0</td> + <td><code>ADDRL</code></td> + <td><code>...P..</code></td> + <td>p</td> + <td>address of a local</td> + </tr> + <tr> + <td>1C</td> + <td>0</td> + <td><code>CNST</code></td> + <td><code>FIUP..</code></td> + <td>fdx csilh p</td> + <td>constant</td> + </tr> + <tr ALIGN="LEFT" VALIGN="TOP"> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + </tr> + <tr> + <td></td> + <td>1</td> + <td><code>BCOM</code></td> + <td><code>.IU...</code></td> + <td>ilh</td> + <td>bitwise complement</td> + </tr> + <tr> + <td>1S</td> + <td>1</td> + <td><code>CVF</code></td> + <td><code>FI....</code></td> + <td>fdx ilh</td> + <td>convert from float</td> + </tr> + <tr> + <td>1S</td> + <td>1</td> + <td><code>CVI</code></td> + <td><code>FIU...</code></td> + <td>fdx csilh csilhp</td> + <td>convert from signed integer</td> + </tr> + <tr> + <td>1S</td> + <td>1</td> + <td><code>CVP</code></td> + <td><code>..U..</code></td> + <td>p</td> + <td>convert from pointer</td> + </tr> + <tr> + <td>1S</td> + <td>1</td> + <td><code>CVU</code></td> + <td><code>.IUP..</code></td> + <td>csilh p</td> + <td>convert from unsigned integer</td> + </tr> + <tr> + <td></td> + <td>1</td> + <td><code>INDIR</code></td> + <td><code>FIUP.B</code></td> + <td>fdx csilh p</td> + <td>fetch</td> + </tr> + <tr> + <td></td> + <td>1</td> + <td><code>NEG</code></td> + <td><code>FI....</code></td> + <td>fdx ilh</td> + <td>negation</td> + </tr> + <tr> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>ADD</code></td> + <td><code>FIUP..</code></td> + <td>fdx ilh ilhp p</td> + <td>addition</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>BAND</code></td> + <td><code>.IU...</code></td> + <td>ilh</td> + <td>bitwise AND</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>BOR</code></td> + <td><code>.IU...</code></td> + <td>ilh</td> + <td>bitwise inclusive OR</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>BXOR</code></td> + <td><code>.IU...</code></td> + <td>ilh</td> + <td>bitwise exclusive OR</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>DIV</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh</td> + <td>division</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>LSH</code></td> + <td><code>.IU...</code></td> + <td>ilh</td> + <td>left shift</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>MOD</code></td> + <td><code>.IU...</code></td> + <td>ilh</td> + <td>modulus</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>MUL</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh</td> + <td>multiplication</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>RSH</code></td> + <td><code>.IU...</code></td> + <td>ilh</td> + <td>right shift</td> + </tr> + <tr> + <td></td> + <td>2</td> + <td><code>SUB</code></td> + <td><code>FIUP..</code></td> + <td>fdx ilh ilhp p</td> + <td>subtraction</td> + </tr> + <tr> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + </tr> + <tr> + <td>2S</td> + <td>2</td> + <td><code>ASGN</code></td> + <td><code>FIUP.B</code></td> + <td>fdx csilh p</td> + <td>assignment</td> + </tr> + <tr> + <td>1L</td> + <td>2</td> + <td><code>EQ</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh ilhp</td> + <td>jump if equal</td> + </tr> + <tr> + <td>1L</td> + <td>2</td> + <td><code>GE</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh ilhp</td> + <td>jump if greater than or equal</td> + </tr> + <tr> + <td>1L</td> + <td>2</td> + <td><code>GT</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh ilhp</td> + <td>jump if greater than</td> + </tr> + <tr> + <td>1L</td> + <td>2</td> + <td><code>LE</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh ilhp</td> + <td>jump if less than or equal</td> + </tr> + <tr> + <td>1L</td> + <td>2</td> + <td><code>LT</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh ilhp</td> + <td>jump if less than</td> + </tr> + <tr> + <td>1L</td> + <td>2</td> + <td><code>NE</code></td> + <td><code>FIU...</code></td> + <td>fdx ilh ilhp</td> + <td>jump if not equal</td> + </tr> + <tr> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + </tr> + <tr> + <td>2S</td> + <td>1</td> + <td><code>ARG</code></td> + <td><code>FIUP.B</code></td> + <td>fdx ilh p</td> + <td>argument</td> + </tr> + <tr> + <td>1</td> + <td>1 or 2</td> + <td><code>CALL</code></td> + <td><code>FIUPVB</code></td> + <td>fdx ilh p</td> + <td>function call</td> + </tr> + <tr> + <td></td> + <td>1</td> + <td><code>RET</code></td> + <td><code>FIUPV.</code></td> + <td>fdx ilh p</td> + <td>return from function</td> + </tr> + <tr> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td> + <td></td> + <td></td> + <td></td> + <td></td> + <td></td> + </tr> + <tr> + <td></td> + <td>1</td> + <td><code>JUMP</code></td> + <td><code>....V.</code></td> + <td></td> + <td>unconditional jump</td> + </tr> + <tr> + <td>1L</td> + <td>0</td> + <td><code>LABEL</code></td> + <td><code>....V.</code></td> + <td></td> + <td>label definition</td> + </tr> +</table> + +<p>The entries in the <strong>Sizes</strong> column indicate sizes of the operators that +back ends must implement. Letters denote the size of float (f), double (d), long double +(x), character (c), short integer (s), integer (i), long integer (l), "long +long" integer (h) , and pointer (p). These sizes are separated into sets for each +type suffix, except that a single set is used for both I and U when the set for I is +identical to the set for U.</p> + +<p>The actual values for the size indicators, fdxcsilhp, depend on the target. A +specification like <code>ADDF</code>f denotes the operator <code>ADD+F+sizeop(</code>f<code>)</code>, +where "f" is replaced by a target-dependent value, e.g., <code>ADDF4</code> and <code>ADDF8</code>. +For example, back ends must implement the following <code>CVI</code> and <code>MUL</code> +operators.</p> + +<blockquote> + <p><code>CVIF</code>f <code>CVIF</code>d <code>CVIF</code>x<br> + <code>CVII</code>c <code>CVII</code>s <code>CVII</code>i <code>CVII</code>l <code>CVII</code>h<br> + <code>CVIU</code>c <code>CVIU</code>s <code>CVIU</code>i <code>CVIU</code>l <code>CVIU</code>h + <code>CVIU</code>p<br> + <br> + <code>MULF</code>f <code>MULF</code>d <code>MULF</code>x<br> + <code>MULI</code>i <code>MULI</code>l <code>MULI</code>h<br> + <code>MULU</code>i <code>MULU</code>l <code>MULU</code>h</p> +</blockquote> + +<p>On most platforms, there are fewer than three sizes of floats and six sizes of +integers, and pointers are usually the same size as one of the integers. And lcc doesn't +support the "long long" type, so h is not currently used. So the set of +platform-specific operators is usually smaller than the list above suggests. For example, +the X86, SPARC, and MIPS back ends implement the following <code>CVI</code> and <code>MUL</code> +operators.</p> + +<blockquote> + <p><code>CVIF</code>4 <code>CVIF</code>8<br> + <code>CVII</code>1 <code>CVII</code>2 <code>CVII</code>4<br> + <code>CVIU</code>1 <code>CVIU</code>2 <code>CVIU</code>4 <br> + <br> + <code>MULF</code>4 <code>MULF</code>8<br> + <code>MULI</code>4<br> + <code>MULU</code>4</p> +</blockquote> + +<p>The set of operators is thus target-dependent; for example, <code>ADDI8</code> appears +only if the target supports an 8-byte integer type. <a +HREF="ftp://ftp.cs.princeton.edu/pub/packages/lcc/contrib/ops.c"><code>ops.c</code></a> is +a program that, given a set of sizes, prints the required operators and their values, +e.g.,</p> + +<blockquote> + <pre>% <em>ops c=1 s=2 i=4 l=4 h=4 f=4 d=8 x=8 p=4</em> +... + CVIF4=4225 CVIF8=8321 + CVII1=1157 CVII2=2181 CVII4=4229 + CVIU1=1158 CVIU2=2182 CVIU4=4230 +... + MULF4=4561 MULF8=8657 + MULI4=4565 + MULU4=4566 +... +131 operators</pre> +</blockquote> + +<p>The type suffix for a conversion operator denotes the type of the result and the size +indicator gives the size of the result. For example, <code>CVUI4</code> converts an +unsigned (<code>U</code>) to a 4-byte signed integer (<code>I4</code>). The <code>syms[0]</code> +field points to a symbol-table entry for a integer constant that gives the size of the +source operand. For example, if <code>syms[0]</code> in a <code>CVUI4</code> points to a +symbol-table entry for 2, the conversion widens a 2-byte unsigned integer to a 4-byte +signed integer. Conversions that widen unsigned integers zero-extend; those that widen +signed integers sign-extend.</p> + +<p>The front end composes conversions between types <em>T</em><sub>1</sub> and <em>T</em><sub>2</sub> +by widening <em>T</em><sub>1</sub> to it's "supertype", if necessary, converting +that result to <em>T</em><sub>2</sub>'s supertype, then narrowing the result to <em>T</em><sub>2</sub>, +if necessary. The following table lists the supertypes; omitted entries are their own +supertypes.</p> + +<blockquote> + <table BORDER="0" CELLPADDING="0" CELLSPACING="0"> + <tr> + <td><strong>Type</strong></td> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td> + <td><strong>Supertype</strong></td> + </tr> + <tr> + <td>signed char</td> + <td></td> + <td>int</td> + </tr> + <tr> + <td>signed short</td> + <td></td> + <td>int</td> + </tr> + <tr ALIGN="LEFT" VALIGN="TOP"> + <td>unsigned char</td> + <td></td> + <td>int, if sizeof (char) < sizeof (int)<br> + unsigned, otherwise</td> + </tr> + <tr ALIGN="LEFT" VALIGN="TOP"> + <td>unsigned short</td> + <td></td> + <td>int, if sizeof (short) < sizeof (int)<br> + unsigned, otherwise</td> + </tr> + <tr ALIGN="LEFT" VALIGN="TOP"> + <td>void *</td> + <td></td> + <td>an unsigned type as large as a pointer</td> + </tr> + </table> +</blockquote> + +<p>Pointers are converted to an unsigned type of the same size, even when that type is not +one of the integer types.</p> + +<p>For example, the front end converts a signed short to a float by first converting it to +an int and then to a float. It converts an unsigned short to an int with a single <code>CVUI</code>i +conversion, when shorts are smaller than ints.</p> + +<p>There are now signed and unsigned variants of <code>ASGN</code>, <code>INDIR</code>, <code>BCOM</code>, +<code>BOR</code>, <code>BXOR</code>, <code>BAND</code>, <code>ARG</code>, <code>CALL</code>, +and <code>RET</code> to simplify code generation on platforms that use different +instructions or register set for signed and unsigned operations. Likewise there are now +pointer variants of <code>ASGN</code>, <code>INDIR</code>, <code>ARG</code>, <code>CALL</code>, +and <code>RET</code>.</p> + +<h2><a NAME="flags">5.6 Interface Flags</a></h2> + +<pre>unsigned unsigned_char:1;</pre> + +<p>tells the front end whether plain characters are signed or unsigned. If it's zero, char +is a signed type; otherwise, char is an unsigned type.</p> + +<p>All the interface flags can be set by command-line options, e.g., <code>-Wf-unsigned_char=1</code> +causes plain characters to be unsigned.</p> + +<h2><a NAME="definitions">5.8 Definitions</a></h2> + +<p>The front end announces local variables by calling</p> + +<pre>void (*local)(Symbol);</pre> + +<p>It announces temporaries likewise; these have the symbol's <code>temporary</code> flag +set, which indicates that the symbol will be used only in the next call to <code>gen</code>. +If a temporary's <code>u.t.cse</code> field is nonnull, it points to the node that +computes the value assigned to the temporary; see page 346.</p> + +<p>The front end calls</p> + +<pre>void (*address)(Symbol p, Symbol q, long n);</pre> + +<p>to initialize <code>q</code> to a symbol that represents an address of the form <em>x</em>+<code>n</code>, +where <em>x</em> is the address represented by <code>p</code> and the long integer <code>n</code> +is positive or negative.</p> + +<h2><a NAME="constants">5.9 Constants</a></h2> + +<p>The interface function</p> + +<pre>void (*defconst)(int suffix, int size, Value v);</pre> + +<p>initializes constants. defconst emits directives to define a cell and initialize it to +a constant value. v is the constant value, suffix identifies the type of the value, and +size is the size of the value in bytes. The value of suffix indicates which field of v +holds the value, as shown in the following table.</p> + +<blockquote> + <table BORDER="0" CELLPADDING="1" CELLSPACING="1"> + <tr> + <td><strong>suffix</strong></td> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td> + <td><strong>v Field</strong></td> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td> + <td><strong>size</strong></td> + </tr> + <tr> + <td><code>F</code></td> + <td></td> + <td><code>v.d</code></td> + <td></td> + <td>float, double, long double</td> + </tr> + <tr> + <td><code>I</code></td> + <td></td> + <td><code>v.i</code></td> + <td></td> + <td>signed char, signed short, signed int, signed long</td> + </tr> + <tr> + <td><code>U</code></td> + <td></td> + <td><code>v.u</code></td> + <td></td> + <td>unsigned char, unsigned short, unsigned int, unsigned long</td> + </tr> + <tr> + <td><code>P</code></td> + <td></td> + <td><code>v.p</code></td> + <td></td> + <td>void *</td> + </tr> + </table> +</blockquote> + +<p><code>defconst</code> must narrow <code>v.</code>x when <code>size</code> is less than <code>sizeof</code> +<code>v.</code>x; e.g., to emit an unsigned char, <code>defconst</code> should emit <code>(unsigned +char)v.i</code>.</p> + +<h2><a NAME="upcalls">5.12 Upcalls</a></h2> + +<p>lcc 4.x uses standard I/O and its I/O functions have been changed accordingly. lcc +reads input from the standard input, emits code to the standard output, and writes +diagnostics to the standard error output. It uses <code>freopen</code> to redirect these +streams to explicit files, when necessary.</p> + +<p><code>bp</code>, <code>outflush</code>, and <code>outs</code> have been eliminated.</p> + +<pre>extern void fprint(FILE *f, const char *fmt, ...); +extern void print(const char *fmt, ...);</pre> + +<p>print formatted data to file <code>f</code> (<code>fprint</code>) or the standard +output (<code>print</code>). These functions are like standard C's <code>printf</code> and +<code>fprintf</code>, but support only some of the standard conversion specifiers and do +not support flags, precision, and field-width specifications. They support the following +new conversion specifiers in addition to those described on page 99.</p> + +<blockquote> + <table BORDER="0" CELLPADDING="0" CELLSPACING="0"> + <tr> + <td><strong>Specifiers</strong></td> + <td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td> + <td><strong>Corresponding printf Specifiers</strong></td> + </tr> + <tr> + <td><code>%c</code></td> + <td></td> + <td><code>%c</code></td> + </tr> + <tr> + <td><code>%d %D</code></td> + <td></td> + <td><code>%d %ld</code></td> + </tr> + <tr> + <td><code>%u %U</code></td> + <td></td> + <td><code>%u %lu</code></td> + </tr> + <tr> + <td><code>%x %X</code></td> + <td></td> + <td><code>%x %lx</code></td> + </tr> + <tr> + <td><code>%f %e %g</code></td> + <td></td> + <td><code>%e %f %g</code></td> + </tr> + <tr ALIGN="LEFT" VALIGN="TOP"> + <td><code>%p</code></td> + <td></td> + <td>Converts the corresponding void * argument to unsigned long and prints it with the <code>printf</code> + <code>%#x</code> specifier or just <code>%x</code> when the argument is null.</td> + </tr> + <tr ALIGN="LEFT" VALIGN="TOP"> + <td><code>%I</code></td> + <td></td> + <td>Prints the number of spaces given by the corresponding argument.</td> + </tr> + </table> +</blockquote> + +<pre>#define generic(op) ((op)&0x3F0) +#define specific(op) ((op)&0x3FF)</pre> + +<p><code>generic(op)</code> returns the generic variant of <code>op</code>; that is, +without its type suffix and size indicator. <code>specific(op)</code> returns the +type-specific variant of <code>op</code>; that is, without its size indicator.</p> + +<p><code>newconst</code> has been replaced by</p> + +<pre>extern Symbol intconst(int n);</pre> + +<p>which installs the integer constant <code>n</code> in the symbol table, if necessary, +and returns a pointer to the symbol-table entry.</p> + +<hr> + +<address> + <a HREF="http://www.research.microsoft.com/~cwfraser/">Chris Fraser</a> / <a + HREF="mailto:cwfraser@microsoft.com">cwfraser@microsoft.com</a><br> + <a HREF="http://www.research.microsoft.com/~drh/">David Hanson</a> / <a + HREF="mailto:drh@microsoft.com">drh@microsoft.com</a><br> + $Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $ +</address> +</body> +</html> diff --git a/lcc/doc/bprint.1 b/lcc/doc/bprint.1 index 794c957..8cf9971 100755 --- a/lcc/doc/bprint.1 +++ b/lcc/doc/bprint.1 @@ -1,83 +1,83 @@ -.\" $Id: bprint.1 145 2001-10-17 21:53:10Z timo $
-.TH BPRINT 1 "local \- $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $"
-.SH NAME
-bprint \- expression profiler
-.SH SYNOPSIS
-.B bprint
-[
-.I option ...
-]
-[
-.I file ...
-]
-.SH DESCRIPTION
-.I bprint
-produces on the standard output a listing of the programs compiled by
-.I lcc
-with the
-.B \-b
-option.
-Executing an
-.B a.out
-so compiled appends profiling data to
-.BR prof.out .
-The first token of each expression in the listing is preceded
-by the number of times it was executed
-enclosed in angle brackets as determined from the data in
-.BR prof.out .
-.I bprint
-interprets the following options.
-.TP
-.B \-c
-Compress the
-.B prof.out
-file, which otherwise grows with every execution of
-.BR a.out .
-.TP
-.B \-b
-Print an annotated listing as described above.
-.TP
-.B \-n
-Include line numbers in the listing.
-.TP
-.B \-f
-Print only the number of invocations of each function.
-A second
-.B \-f
-summarizes call sites instead of callers.
-.TP
-.BI \-I \*Sdir
-specifies additional directories in which to seek
-files given in
-.B prof.out
-that do not begin with `/'.
-.PP
-If any file names are given, only the requested data for those files are printed
-in the order presented.
-If no options are given,
-.B \-b
-is assumed.
-.SH FILES
-.PP
-.ta \w'$LCCDIR/liblcc.{a,lib}XX'u
-.nf
-prof.out profiling data
-$LCCDIR/liblcc.{a,lib} \fIlcc\fP-specific library
-.SH "SEE ALSO"
-.IR lcc (1),
-.IR prof (1)
-.SH BUGS
-Macros and comments can confuse
-.I bprint
-because it uses post-expansion source coordinates
-to annotate pre-expansion source files.
-If
-.I bprint
-sees that it's about to print a statement count
-.I inside
-a number or identifier, it moves the count to just
-.I before
-the token.
-.PP
-Can't cope with an ill-formed
-.BR prof.out .
+.\" $Id: bprint.1 145 2001-10-17 21:53:10Z timo $ +.TH BPRINT 1 "local \- $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $" +.SH NAME +bprint \- expression profiler +.SH SYNOPSIS +.B bprint +[ +.I option ... +] +[ +.I file ... +] +.SH DESCRIPTION +.I bprint +produces on the standard output a listing of the programs compiled by +.I lcc +with the +.B \-b +option. +Executing an +.B a.out +so compiled appends profiling data to +.BR prof.out . +The first token of each expression in the listing is preceded +by the number of times it was executed +enclosed in angle brackets as determined from the data in +.BR prof.out . +.I bprint +interprets the following options. +.TP +.B \-c +Compress the +.B prof.out +file, which otherwise grows with every execution of +.BR a.out . +.TP +.B \-b +Print an annotated listing as described above. +.TP +.B \-n +Include line numbers in the listing. +.TP +.B \-f +Print only the number of invocations of each function. +A second +.B \-f +summarizes call sites instead of callers. +.TP +.BI \-I \*Sdir +specifies additional directories in which to seek +files given in +.B prof.out +that do not begin with `/'. +.PP +If any file names are given, only the requested data for those files are printed +in the order presented. +If no options are given, +.B \-b +is assumed. +.SH FILES +.PP +.ta \w'$LCCDIR/liblcc.{a,lib}XX'u +.nf +prof.out profiling data +$LCCDIR/liblcc.{a,lib} \fIlcc\fP-specific library +.SH "SEE ALSO" +.IR lcc (1), +.IR prof (1) +.SH BUGS +Macros and comments can confuse +.I bprint +because it uses post-expansion source coordinates +to annotate pre-expansion source files. +If +.I bprint +sees that it's about to print a statement count +.I inside +a number or identifier, it moves the count to just +.I before +the token. +.PP +Can't cope with an ill-formed +.BR prof.out . diff --git a/lcc/doc/install.html b/lcc/doc/install.html index fd9c88b..3cc59a8 100755 --- a/lcc/doc/install.html +++ b/lcc/doc/install.html @@ -1,796 +1,796 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-
-<head>
-<link HREF="mailto:drh@cs.princeton.edu" REV="made" TITLE="David R. Hanson">
-<title>Installing lcc</title>
-</head>
-
-<body>
-
-<h1>Installing lcc</h1>
-
-<p ALIGN="LEFT"><strong><a HREF="http://www.research.microsoft.com/~cwfraser/">Christopher
-W. Fraser</a> and <a HREF="http://www.research.microsoft.com/~drh/">David R. Hanson</a>, <a
-HREF="http://www.research.microsoft.com/">Microsoft Research</a></strong></p>
-
-<h2>Contents</h2>
-
-<dir>
- <li><a HREF="#intro">Introduction</a></li>
- <li><a HREF="#unix">Installation on UNIX</a></li>
- <li><a HREF="#driver">Building the Driver</a></li>
- <li><a HREF="#rcc">Building the Compiler and Accessories</a></li>
- <li><a HREF="#win32">Installation on Windows NT 4.0 and Windows 95/98</a></li>
- <li><a HREF="#bugs">Reporting Bugs</a></li>
- <li><a HREF="#mailinglist">Keeping in Touch</a></li>
-</dir>
-
-<h2><a NAME="intro">Introduction</a></h2>
-
-<p><a HREF="http://www.cs.princeton.edu/software/lcc/">lcc</a> is the ANSI C compiler
-described in our book <cite>A Retargetable C Compiler: Design and Implementation</cite>
-(Addison-Wesley, 1995, ISBN 0-8053-1670-1).</p>
-
-<p>If you're installing lcc on a UNIX system, read the remainder of this section and
-continue with the next section. If you're installing lcc on a Windows NT 4.0 or Windows
-95/98 system, and you intend only to <u>use</u> lcc, you can run the <a
-href="ftp://ftp.cs.princeton.edu/pub/packages/lcc/lcc41.exe">InstallShield executable</a>,
-which installs the binaries and the documentation. If you want to <u>modify</u> lcc or <u>rebuild</u>
-it from the source files, you need the <a
-href="ftp://ftp.cs.princeton.edu/packages/lcc/lcc41.zip">complete distribution</a>, and
-you should read the rest of the section, the following three sections, and the <a
-HREF="#win32">Windows NT/95/98</a> section.</p>
-
-<p>Extract the distribution into its own directory. All non-absolute paths below are
-relative to this directory. The distribution holds the following subdirectories.</p>
-
-<blockquote>
- <table BORDER="0" CELLPADDING="1" CELLSPACING="1" WIDTH="80%">
- <tr>
- <td><a HREF="../src"><code>src</code></a></td>
- <td></td>
- <td>source code</td>
- </tr>
- <tr>
- <td><a HREF="../etc"><code>etc</code></a></td>
- <td></td>
- <td>driver, accessories</td>
- </tr>
- <tr>
- <td><a HREF="../lib"><code>lib</code></a></td>
- <td></td>
- <td>runtime library source code</td>
- </tr>
- <tr>
- <td><a HREF="../cpp"><code>cpp</code></a></td>
- <td></td>
- <td>preprocessor source code</td>
- </tr>
- <tr>
- <td><a HREF="../lburg"><code>lburg</code></a></td>
- <td></td>
- <td>code-generator generator source code</td>
- </tr>
- <tr>
- <td><a HREF="../doc"><code>doc</code></a></td>
- <td></td>
- <td>this document, man pages</td>
- </tr>
- <tr>
- <td><code><a HREF="../include">include</a>/*/*</code></td>
- <td></td>
- <td>include files</td>
- </tr>
- <tr>
- <td><a HREF="../tst"><code>tst</code></a></td>
- <td></td>
- <td>test suite</td>
- </tr>
- <tr>
- <td><code><a HREF="../alpha">alpha</a>/*/tst</code></td>
- <td></td>
- <td>ALPHA test outputs</td>
- </tr>
- <tr>
- <td><code><a HREF="../mips">mips</a>/*/tst</code></td>
- <td></td>
- <td>MIPS test outputs</td>
- </tr>
- <tr>
- <td><code><a HREF="../sparc">sparc</a>/*/tst</code></td>
- <td></td>
- <td>SPARC test outputs</td>
- </tr>
- <tr>
- <td><code><a HREF="../x86">x86</a>/*/tst</code></td>
- <td></td>
- <td>X86 test outputs</td>
- </tr>
- </table>
-</blockquote>
-
-<p><code>doc/install.html</code> is the HTML file for this document. <a HREF="4.html"><code>doc/4.html</code></a>
-describes the internal differences between lcc 3.x and 4.1.</p>
-
-<p>The installation makefile is designed so that lcc can be installed from a read-only
-file system or directory, which is common in networked environments, so the distribution
-can be unloaded on a central file server. <strong>You will need an existing ANSI/ISO C
-compiler to build and install lcc.</strong></p>
-
-<h2><a NAME="unix">Installation on UNIX</a></h2>
-
-<p>The compilation components (the preprocessor, include files, and compiler proper, etc.)
-are installed in a single <em>build directory</em>. On multi-platform systems supported by
-a central file server, it's common to store the build directory in a location specific to
-the platform and to the version of lcc, and to point a symbolic link to this location. For
-example,</p>
-
-<blockquote>
- <pre>% ln -s /usr/local/lib/lcc-4.1/sparc-solaris /usr/local/lib/lcc</pre>
-</blockquote>
-
-<p>points <code>/usr/local/lib/lcc</code> to a build directory for lcc version 4.1 on the
-SPARC under Solaris. Links into <code>/usr/local/lib</code> are created for the programs <code>lcc</code>
-and <code>bprint</code>. Thus, a new distribution can be installed by building it in its
-own build directory and changing one symbolic link to point to that directory. If these
-conventions or their equivalents are followed, the host-specific parts of the driver
-program, <code>lcc</code>, can be used unmodified.</p>
-
-<p>Installation on a UNIX system involves the following steps. Below, the build directory
-is referred to as <code>BUILDDIR</code>.
-
-<ol>
- <li>Create the build directory, using a version- and platform-specific naming convention as
- suggested above, and record the name of this directory in the <code>BUILDDIR</code>
- environment variable:<blockquote>
- <pre>% setenv BUILDDIR /usr/local/lib/lcc-4.1/sparc-solaris
-% mkdir -p $BUILDDIR</pre>
- </blockquote>
- <p>Here and below, commands assume the C shell. Also, you'll need a version of <code>mkdir</code>
- that supports the <code>-p</code> option, which creates intermediate directories as
- necessary.</p>
- </li>
- <li>Copy the man pages to the repository for local man pages, e.g.,<blockquote>
- <pre>% cp doc/*.1 /usr/local/man/man1</pre>
- </blockquote>
- <p>Some users copy the man pages to the build directory and create the appropriate
- symbolic links, e.g., </p>
- <blockquote>
- <pre>% cp doc/*.1 $BUILDDIR
-% ln -s $BUILDDIR/*.1 /usr/local/man/man1</pre>
- </blockquote>
- </li>
- <li>Platform-specific include files are in directories named <code>include/</code><em>target</em><code>/</code><em>os</em>.
- Create the include directory in the build directory, and copy the include hierarchy for
- your platform to this directory, e.g.,<blockquote>
- <pre>% mkdir $BUILDDIR/include
-% cp -p -R include/sparc/solaris/* $BUILDDIR/include</pre>
- </blockquote>
- <p>Again, some users create a symbolic link to the appropriate directory in the
- distribution instead of copying the include files. For example, at Princeton, the
- distributions are stored under <code>/proj/pkg/lcc</code>, so the included files are
- "installed" by creating one symbolic link: </p>
- <blockquote>
- <pre>% ln -s /proj/pkg/lcc/4.1/include/sparc/solaris $BUILDDIR/include</pre>
- </blockquote>
- <p>If you're installing lcc on Linux, you <em>must</em> also plant a symbolic link named <code>gcc</code>
- to gcc's library directory, because lcc uses gcc's C preprocessor and most of gcc's header
- files:</p>
- <blockquote>
- <pre>% ln -s /usr/lib/gcc-lib/i486-linux/2.7.2.2 $BUILDDIR/gcc</pre>
- </blockquote>
- <p>The library directory shown above may be different on your Linux machine; to determine
- the correct directory, browse <code>/usr/lib/gcc-lib</code>, or execute</p>
- <blockquote>
- <pre>% cc -v tst/8q.c</pre>
- </blockquote>
- <p>and examine the diagnostic output. Make sure that <code>$BUILDDIR/gcc/cpp</code> and <code>$BUILDDIR/gcc/include</code>
- point to, respectively, gcc's C preprocessor and header files. On Linux, lcc looks for
- include files in <code>$BUILDDIR/include</code>, <code>$BUILDDIR/gcc/include</code>, and <code>/usr/include</code>,
- in that order; see <a HREF="#driver"><em>Building the Driver</em></a> and <a
- href="../etc/linux.c"><code>etc/linux.c</code></a> for details.</p>
- </li>
- <li>The <a HREF="../makefile"><code>makefile</code></a> includes the file named by the <code>CUSTOM</code>
- macro; the default is <code>custom.mk</code>, and an empty <code>custom.mk</code> is
- included in the distribution. If desired, prepare a site-specification customization file
- and define <code>CUSTOM</code> to the path of that file when invoking make in steps 5 and
- 6, e.g.,<blockquote>
- <pre>make CUSTOM=/users/drh/solaris.mk</pre>
- </blockquote>
- <p>You can, for example, use customization files to record site-specific values for macros
- instead of using environment variables, and to record targets for the steps in this list.</p>
- </li>
- <li>Build the host-specific driver, creating a custom host-specific part, if necessary. See <a
- HREF="#driver"><em>Building the Driver</em></a>.</li>
- <li>Build the preprocessor, compiler proper, library, and other accessories. See <a
- HREF="#rcc"><em>Building the Compiler</em></a>.</li>
- <li>Plant symbolic links to the build directory and to the installed programs, e.g.,<blockquote>
- <pre>% ln -s $BUILDDIR /usr/local/lib/lcc
-% ln -s /usr/local/lib/{lcc,bprint} /usr/local/bin</pre>
- </blockquote>
- <p>Some users copy <code>bprint</code> and <code>lcc</code> into <code>/usr/local/bin</code>
- instead of creating symbolic links. The advantange of creating the links for <code>lcc</code>
- and <code>bprint</code> as shown is that, once established, they point indirectly to
- whatever <code>/usr/local/lib/lcc</code> points to; installing a new version of lcc, say,
- 4.2, can be done by changing <code>/usr/local/lib/lcc</code> to point to the 4.2 build
- directory.</p>
- </li>
-</ol>
-
-<h2><a NAME="driver">Building the Driver</a></h2>
-
-<p>The preprocessor, compiler, assembler, and loader are invoked by a driver program, <code>lcc</code>,
-which is similar to <code>cc</code> on most systems. It's described in the man page <code>doc/lcc.1</code>.
-The driver is built by combining the host-independent part, <a href="../etc/lcc.c"><code>etc/lcc.c</code></a>,
-with a small host-specific part. Distributed host-specific parts are named <code>etc/</code><em>os</em><code>.c</code>,
-where <em>os</em> is the name of the operating system for the host on which <code>lcc</code>
-is being installed. If you're following the installations conventions described above, you
-can probably use one of the host-specific parts unmodified; otherwise, pick one that is
-closely related to your platform, copy it to <em>whatever</em><code>.c</code>, and edit it
-as described below. You should not have to edit <code>etc/lcc.c</code>.</p>
-
-<p>We'll use <a HREF="../etc/solaris.c"><code>etc/solaris.c</code></a> as an example in
-describing how the host-specific part works. This example illustrates all the important
-features. Make sure you have the environment variable <code>BUILDDIR</code> set correctly,
-and build the driver with a <code>make</code> command, e.g.,</p>
-
-<blockquote>
- <pre>% make HOSTFILE=etc/solaris.c lcc
-cc -g -c -DTEMPDIR=\"/tmp\" -o /usr/local/lib/lcc-4.1/sparc-solaris/lcc.o etc/lcc.c
-cc -g -c -o /usr/local/lib/lcc-4.1/sparc-solaris/host.o etc/solaris.c
-cc -g -o /usr/local/lib/lcc-4.1/sparc-solaris/lcc /usr/local/lib/lcc-4.1/sparc-solaris/lcc.o /usr/local/lib/lcc-4.1/sparc-solaris/host.o</pre>
-</blockquote>
-
-<p>The symbolic name <code>HOSTFILE</code> specifies the path to the host-specific part,
-either one in the distribution or <em>whatever</em><code>.c</code>. Some versions of make
-may require the <code>-e</code> option in order to read the environment.</p>
-
-<p>Here's <code>etc/solaris.c</code>:</p>
-
-<blockquote>
- <pre>/* Sparcs running Solaris 2.5.1 at CS Dept., Princeton University */
-
-#include <string.h>
-
-static char rcsid[] = "$ Id: solaris.c,v 1.10 1998/09/14 20:36:33 drh Exp $";
-
-#ifndef LCCDIR
-#define LCCDIR "/usr/local/lib/lcc/"
-#endif
-#ifndef SUNDIR
-#define SUNDIR "/opt/SUNWspro/SC4.2/lib/"
-#endif
-
-char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 };
-char inputs[256] = "";
-char *cpp[] = { LCCDIR "cpp",
- "-D__STDC__=1", "-Dsparc", "-D__sparc__", "-Dsun", "-D__sun__", "-Dunix",
- "$1", "$2", "$3", 0 };
-char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include",
- "-I/usr/include", 0 };
-char *com[] = { LCCDIR "rcc", "-target=sparc/solaris",
- "$1", "$2", "$3", 0 };
-char *as[] = { "/usr/ccs/bin/as", "-Qy", "-s", "-o", "$3", "$1", "$2", 0 };
-char *ld[] = { "/usr/ccs/bin/ld", "-o", "$3", "$1",
- SUNDIR "crti.o", SUNDIR "crt1.o",
- SUNDIR "values-xa.o", "$2", "",
- "-Y", "P," SUNDIR ":/usr/ccs/lib:/usr/lib", "-Qy",
- "-L" LCCDIR, "-llcc", "-lm", "-lc", SUNDIR "crtn.o", 0 };
-
-extern char *concat(char *, char *);
-
-int option(char *arg) {
- if (strncmp(arg, "-lccdir=", 8) == 0) {
- cpp[0] = concat(&arg[8], "/cpp");
- include[0] = concat("-I", concat(&arg[8], "/include"));
- ld[12] = concat("-L", &arg[8]);
- com[0] = concat(&arg[8], "/rcc");
- } else if (strcmp(arg, "-p") == 0) {
- ld[5] = SUNDIR "mcrt1.o";
- ld[10] = "P," SUNDIR "libp:/usr/ccs/lib/libp:/usr/lib/libp:"
- SUNDIR ":/usr/ccs/lib:/usr/lib";
- } else if (strcmp(arg, "-b") == 0)
- ;
- else if (strncmp(arg, "-ld=", 4) == 0)
- ld[0] = &arg[4];
- else
- return 0;
- return 1;
-}</pre>
-</blockquote>
-
-<p><code>LCCDIR</code> defaults to <code>"/usr/local/lib/lcc/"</code> unless
-it's defined by a <code>-D</code> option as part of <code>CFLAGS</code> in the make
-command, e.g.,</p>
-
-<blockquote>
- <pre>% make HOSTFILE=etc/solaris.c CFLAGS='-DLCCDIR=\"/v/lib/lcc/\"' lcc</pre>
-</blockquote>
-
-<p>Note the trailing slash; <code>SUNDIR</code> is provided so you can use <code>etc/solaris.c</code>
-even if you have a different version of the Sun Pro compiler suite. If you're using the
-gcc compiler tools instead of the Sun Pro tools, see <a HREF="../etc/gcc-solaris.c"><code>etc/gcc-solaris.c</code></a>.</p>
-
-<p>Most of the host-specific code is platform-specific data and templates for the commands
-that invoke the preprocessor, compiler, assembler, and loader. The <code>suffixes</code>
-array lists the file name suffixes for C source files, preprocessed source files, assembly
-language source files, object files, and executable files. <code>suffixes</code> must be
-terminated with a null pointer, as shown above. The initialization of <code>suffixes</code>
-in <code><a HREF="../etc/solaris.c">etc/solaris.c</a></code> are the typical ones for UNIX
-systems. Each element of <code>suffixes</code> is actually a list of suffixes, separated
-by semicolons; <code><a HREF="../etc/win32.c">etc/win32.c</a></code> holds an example:</p>
-
-<blockquote>
- <pre>char *suffixes[] = { ".c;.C", ".i;.I", ".asm;.ASM;.s;.S", ".obj;.OBJ", ".exe", 0 };</pre>
-</blockquote>
-
-<p>When a list is given, the first suffix is used whenever lcc needs to generate a file
-name. For example, with <code><a HREF="../etc/win32.c">etc/win32.c</a></code>, lcc emits
-the generated assembly code into <code>.asm</code> files.</p>
-
-<p>The <code>inputs</code> array holds a null-terminated string of directories separated
-by colons or semicolons. These are used as the default value of <code>LCCINPUTS</code>, if
-the environment variable <code>LCCINPUTS</code> is not set; see the <a HREF="lcc.pdf">man
-page</a>.</p>
-
-<p>Each command template is an array of pointers to strings terminated with a null
-pointer; the strings are full path names of commands, arguments, or argument placeholders,
-which are described below. Commands are executed in a child process, and templates can
-contain multiple commands by separating commands with newlines. The driver runs each
-command in a new process.</p>
-
-<p>The <code>cpp</code> array gives the command for running lcc's preprocessor, <code>cpp</code>.
-Literal arguments specified in templates, e.g., <code>"-Dsparc"</code> in the <code>cpp</code>
-command above, are passed to the command as given.</p>
-
-<p>The strings <code>"$1"</code>, <code>"$2"</code>, and <code>"$3"</code>
-in templates are placeholders for <em>lists</em> of arguments that are substituted in a
-copy of the template before the command is executed. <code>$1</code> is replaced by the <em>options</em>
-specified by the user; for the preprocessor, this list always contains at least <code>-D__LCC__</code>.
-<code>$2</code> is replaced by the <em>input</em> files, and <code>$3</code> is replaced
-by the <em>output</em> file.</p>
-
-<p>Zero-length arguments after replacement are removed from the argument list before the
-command is invoked. So, for example, if the preprocessor is invoked without an output
-file, <code>"$3"</code> becomes <code>""</code>, which is removed from
-the final argument list.</p>
-
-<p>The <code>include</code> array is a list of <code>-I</code> options that specify which
-directives should be searched to satisfy include directives. These directories are
-searched in the order given. The first directory should be the one to which the ANSI
-header files were copied as described in <a HREF="#unix">UNIX</a> or <a HREF="#win32">Windows</a>
-installation instructions. The driver adds these options to <code>cpp</code>'s arguments
-when it invokes the preprocessor, except when <code>-N</code> is specified.</p>
-
-<p><code>com</code> gives the command for invoking the compiler. This template can appear
-as shown above in a custom host-specific part, but the option <code>-target=sparc/solaris</code>
-should be edited to the <em>target</em><code>/</code><em>os</em> for your platform. If <code>com[1]</code>
-includes the string "<code>win32</code>", the driver assumes it's running on
-Windows. lcc can generate code for <em>all</em> of the <em>target</em><code>/</code><em>os</em>
-combinations listed in the file <code>src/bind.c</code>. The <code>-target</code> option
-specifies the default combination. The driver's <code>-Wf</code> option can be used to
-specify other combinations; the <a HREF="lcc.pdf">man page</a> elaborates.</p>
-
-<p><code>as</code> gives the command for invoking the assembler. On Linux, you must be
-running at least version 2.8.1 of the GNU assembler; earlier versions mis-assemble some
-instructions emitted by lcc.</p>
-
-<p><code>ld</code> gives the command for invoking the loader. For the other commands, the
-list <code>$2</code> contains a single file; for <code>ld</code>, <code>$2</code> contains
-all ".o" files and libraries, and <code>$3</code> is <code>a.out</code>, unless
-the <code>-o</code> option is specified. As suggested in the code above, <code>ld</code>
-must also specify the appropriate startup code and default libraries, including the lcc
-library, <code>liblcc.a</code>.</p>
-
-<p>The <code>option</code> function is described below; the minimal <code>option</code>
-function just returns 0.</p>
-
-<p>You can test <code>lcc</code> with the options <code>-v -v</code> to display the
-commands that would be executed, e.g.,</p>
-
-<blockquote>
- <pre>% $BUILDDIR/lcc -v -v foo.c baz.c mylib.a -lX11
-/usr/local/lib/lcc-4.1/lcc $ Id: solaris.c,v 1.10 1998/09/14 20:36:33 drh Exp $
-foo.c:
-/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__ -I/usr/local/lib/lcc/include -I/usr/local/include -I/usr/include foo.c /tmp/lcc266290.i
-/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc266290.i /tmp/lcc266291.
-s
-/usr/ccs/bin/as -Qy -s -o /tmp/lcc266292.o /tmp/lcc266291.s
-baz.c:
-/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__ -I/usr/local/lib/lcc/include -I/usr/local/include -I/usr/include baz.c /tmp/lcc266290.i
-/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc266290.i /tmp/lcc266291.s
-/usr/ccs/bin/as -Qy -s -o /tmp/lcc266293.o /tmp/lcc266291.s
-/usr/ccs/bin/ld -o a.out /opt/SUNWspro/SC4.2/lib/crti.o /opt/SUNWspro/SC4.2/lib/crt1.o /opt/SUNWspro/SC4.2/lib/values-xa.o /tmp/lcc266292.o /tmp/lcc266293.o mylib.a -lX11 -Y P,/opt/SUNWspro/SC4.2/lib/:/usr/ccs/lib:/usr/lib -Qy -L/usr/local/lib/lcc/ -llcc -lm -lc /opt/SUNWspro/SC4.2/lib/crtn.o
-rm /tmp/lcc266293.o /tmp/lcc266290.i /tmp/lcc266291.s /tmp/lcc266292.o</pre>
-</blockquote>
-
-<p>As the output shows, <code>lcc</code> places temporary files in <code>/tmp</code>; if
-any of the environment variables <code>TMP</code>, <code>TEMP</code>, and <code>TMPDIR</code>
-are set, they override this default (in the order shown) as does the <code>-tempdir=</code><em>dir</em>
-option. The default can be changed by defining <code>TEMPDIR</code> in <code>CFLAGS</code>
-when building the driver.</p>
-
-<p>The <code>option</code> function is called for the options <code>-Wo</code>, <code>-g</code>,
-<code>-p</code>, <code>-pg</code>, and <code>-b</code> because these compiler options
-might also affect the loader's arguments. For these options, the driver calls <code>option(arg)</code>
-to give the host-specific code an opportunity to edit the <code>ld</code> command, if
-necessary. <code>option</code> can change <code>ld</code>, if necessary, and return 1 to
-announce its acceptance of the option. If the option is unsupported, <code>option</code>
-should return 0.</p>
-
-<p>For example, in response to <code>-g</code>, the <code>option</code> function shown
-above accepts the option but does nothing else, because the <code>ld</code> and <code>as</code>
-commands don't need to be modified on the SPARC. <code>-g</code> will also be added to the
-compiler's options by the host-independent part of the driver. The <code>-p</code> causes <code>option</code>
-to change the name of the startup code and changed the list of libraries. The <code>-b</code>
-option turns on <code>lcc</code>'s per-expression profiling, the code for which is in <code>liblcc.a</code>,
-so <code>option</code> need no nothing.</p>
-
-<p>On SPARCs, the driver also recognizes <code>-Bstatic</code> and <code>-Bdynamic</code>
-as linker options. The driver recognizes but ignores "<code>-target</code> <em>name</em>"
-option.</p>
-
-<p>The option <code>-Wo</code><em>arg</em> causes the driver to pass <em>arg</em> to <code>option</code>.
-Such options have no other effect; this mechanism is provided to support system-specific
-options that affect the commands executed by the driver. As illustrated above,
-host-specific parts should support the <code>-Wo-lccdir=</code><em>dir</em> option, which
-causes lcc's compilation components to be found in <em>dir</em>, because this option is
-used by the test scripts, and because the driver simulates a <code>-Wo-lccdir</code>
-option with the value of the environment variable <code>LCCDIR</code>, if it's defined.
-The code above rebuilds the paths to the include files, preprocessor, compiler, and
-library by calling <code>concat</code>, which is defined in <code>etc/lcc.c</code>.</p>
-
-<h2><a NAME="rcc">Building the Compiler and Accessories</a></h2>
-
-<p>To build the rest of compilation components make sure <code>BUILDDIR</code> is set
-appropriately and type "<code>make all</code>". This command builds <code>librcc.a</code>
-(the compiler's private library), <code>rcc</code> (the compiler proper), <code>lburg</code>
-(the code-generator generator), <code>cpp</code> (the preprocessor), <code>liblcc.a</code>
-(the runtime library), and <code>bprint</code> (the profile printer), all in <code>BUILDDIR</code>.
-There may be warnings, but there should be no errors. If you're using an ANSI/ISO compiler
-other than <code>cc</code>, specify its name with the <code>CC=</code> option, e.g.,
-"<code>make CC=gcc all</code>". If you're running on a DEC ALPHA, use "<code>make
-CC='cc -std1' all</code>"; the <code>-std1</code> option is essential on the ALPHA.
-If you're on a DEC 5000 running Ultrix 4.3, use "<code>make CC=c89 all</code>".</p>
-
-<p>Once <code>rcc</code> is built with the host C compiler, run the test suite to verify
-that <code>rcc</code> is working correctly. If any of the steps below fail, contact us
-(see <a HREF="#bugs"><em>Reporting Bugs</em></a>). The commands in the makefile run the
-shell script <code>src/run.sh</code> on each C program in the test suite, <code>tst/*.c</code>.
-It uses the driver, <code>$BUILDDIR/lcc</code>, so you must have the driver in the build
-directory before testing <code>rcc</code>. The <em>target</em><code>/</code><em>os</em>
-combination is read from the variable <code>TARGET</code>, which must be specified when
-invoking <code>make</code>:</p>
-
-<blockquote>
- <pre>% make TARGET=sparc/solaris test
-mkdir -p /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/8q.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/array.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cf.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cq.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cvt.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/fields.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/front.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/incr.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/init.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/limits.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/paranoia.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/sort.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/spill.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/stdarg.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/struct.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/switch.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/wf1.s:
-/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/yacc.s:</pre>
-</blockquote>
-
-<p>Each line in the output above is of the form</p>
-
-<blockquote>
- <p><code>$BUILDDIR/rcc -target=</code><em>target</em><code>/</code><em>os</em><code>$BUILDDIR/</code><em>target</em><code>/</code><em>os</em><code>/</code><em>X</em><code>.s:</code></p>
-</blockquote>
-
-<p>where <em>X</em> is the base name of the C program <em>X</em><code>.c</code> in the
-test suite. This output identifies the compiler and the target, e.g., "<code>$BUILDDIR/rcc</code>
-is generating code for a <code>sparc</code> running the <code>solaris</code> operating
-system."</p>
-
-<p>For each program in the test suite, <code>src/run.sh</code> compiles the program, drops
-the generated assembly language code in <code>BUILDDIR</code>/<em>target</em><code>/</code><em>os</em>,
-and uses <code>diff</code> to compare the generated assembly code with the expected code
-(the code expected for <code>tst/8q.c</code> on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.sbk</code>,
-etc.). If there are differences, the script executes the generated code with the input
-given in <code>tst</code> (the input for <code>tst/8q.c</code> is in <code>tst/8q.0</code>,
-etc.) and compares the output with the expected output (the expected output from <code>tst/8q.c</code>
-on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.1bk</code>, etc.). The script
-also compares the diagnostics from the compiler with the expected diagnostics.</p>
-
-<p>On some systems, there may be a few differences between the generated code and the
-expected code. These differences occur because the expected code is generated by cross
-compilation and the least significant bits of some floating-point constants differ from
-those bits in constants generated on your system. On Linux, there may be differences
-because of differences in the header files between our system and yours. There should be
-no differences in the output from executing the test programs.</p>
-
-<p>Next, run the "triple test", which builds <code>rcc</code> using itself:</p>
-
-<blockquote>
- <pre>% make triple
-/usr/local/lib/lcc-4.1/sparc-solaris/lcc -o /usr/local/lib/lcc-4.1/sparc-solaris/1rcc -d0.6 -Wo-lccdir=/usr/local/lib/lcc-4.1/sparc-solaris -B/usr/local/lib/lcc-4.1/sparc-solaris/ -Isrc src/*.c
-src/alloc.c:
-...
-src/x86.c:
-/usr/local/lib/lcc-4.1/sparc-solaris/lcc -o /usr/local/lib/lcc-4.1/sparc-solaris/1rcc -d0.6 -Wo-lccdir=/usr/local/lib/lcc-4.1/sparc-solaris -B/usr/local/lib/lcc-4.1/sparc-solaris/ -Isrc src/*.c
-src/alloc.c:
-...
-src/x86.c:
-strip /usr/local/lib/lcc-4.1/sparc-solaris/[12]rcc
-dd if=/usr/local/lib/lcc-4.1/sparc-solaris/1rcc of=/usr/local/lib/lcc-4.1/sparc-solaris/rcc1 bs=512 skip=1
-769+1 records in
-769+1 records out
-dd if=/usr/local/lib/lcc-4.1/sparc-solaris/2rcc of=/usr/local/lib/lcc-4.1/sparc-solaris/rcc2 bs=512 skip=1
-769+1 records in
-769+1 records out
-if cmp /usr/local/lib/lcc-4.1/sparc-solaris/rcc[12]; then \
- mv /usr/local/lib/lcc-4.1/sparc-solaris/2rcc /usr/local/lib/lcc-4.1/sparc-solaris/rcc; \
- rm -f /usr/local/lib/lcc-4.1/sparc-solaris/1rcc /usr/local/lib/lcc-4.1/sparc-solaris/rcc[12]; fi</pre>
-</blockquote>
-
-<p>This command builds <code>rcc</code> twice; once using the <code>rcc</code> built by <code>cc</code>
-and again using the <code>rcc</code> built by <code>lcc</code>. The resulting binaries are
-compared. They should be identical, as shown at the end of the output above. If they
-aren't, our compiler is generating incorrect code; <a HREF="#bugs">contact</a> us.</p>
-
-<p>The final version of <code>rcc</code> should also pass the test suite; that is, the
-output from</p>
-
-<blockquote>
- <pre>% make TARGET=sparc/solaris test</pre>
-</blockquote>
-
-<p>should be identical to that from the previous <code>make test</code>.</p>
-
-<p>The command "<code>make clean</code>" cleans up, but does not remove <code>rcc</code>,
-etc., and "<code>make clobber</code>" cleans up and removes <code>lcc</code>, <code>rcc</code>,
-and the other accessories. Test directories under <code>BUILDDIR</code> are <em>not</em>
-removed; you'll need to remove these by hand, e.g.,</p>
-
-<blockquote>
- <pre>% rm -fr $BUILDDIR/sparc</pre>
-</blockquote>
-
-<p>The code generators for the other targets can be tested by specifying the desired <em>target</em><code>/</code><em>os</em>
-and setting an environment variable that controls what <code>src/run.sh</code> does. For
-example, to test the MIPS code generator, type</p>
-
-<blockquote>
- <pre>% setenv REMOTEHOST noexecute
-% make TARGET=mips/irix test</pre>
-</blockquote>
-
-<p>As above, <code>src/run.sh</code> compares the MIPS code generated with what's
-expected. There should be no differences. Setting <code>REMOTEHOST</code> to <code>noexecute</code>
-suppresses the assembly and execution of the generated code. If you set <code>REMOTEHOST</code>
-to the name of a MIPS machine to which you can <code>rlogin</code>, <code>src/run.sh</code>
-will <code>rcp</code> the generated code to that machine and execute it there, if
-necessary. See <code>src/run.sh</code> for the details.</p>
-
-<p>You can use lcc as a cross compiler. The options <code>-S</code> and <code>-Wf-target=</code><em>target/os</em>
-generate assembly code for the specified target, which is any of those listed in the file <code>src/bind.c</code>.
-For example, </p>
-
-<blockquote>
- <pre>% lcc -Wf-target=mips/irix -S tst/8q.c</pre>
-</blockquote>
-
-<p>generates MIPS code for <code>tst/8q.c</code> in <code>8q.s</code>.</p>
-
-<p>lcc can also generate code for a "symbolic" target. This target is used
-routinely in front-end development, and its output is a printable representation of the
-input program, e.g., the dags constructed by the front end are printed, and other
-interface functions print their arguments. You can specify this target with the option <code>-Wf-target=symbolic</code>.
-For example,</p>
-
-<blockquote>
- <pre>% lcc -Wf-target=symbolic -S tst/8q.c</pre>
-</blockquote>
-
-<p>generates symbolic output for <code>tst/8q.c</code> in <code>8q.s</code>. Adding <code>-Wf-html</code>
-causes the symbolic target to emit HTML instead of plain text. Finally, the option <code>-Wf-target=null</code>
-specifies the "null" target for which lcc emits nothing and thus only checks the
-syntax and semantics of its input files.</p>
-
-<h2><a NAME="win32">Installation on Windows NT 4.0 or Windows 95/98</a></h2>
-
-<p>On Windows NT 4.0 and Windows 95/98, lcc is designed to work with Microsoft's Visual
-C++ 5.0 (VC) and Microsoft's Assembler, MASM 6.11d. It uses the VC header files,
-libraries, and command-line tools, and it uses MASM to assemble the code it generates. If
-you have MASM 6.11, make sure you <a
-HREF="http://support.microsoft.com/support/kb/articles/Q138/9/83.asp">upgrade to 6.11d</a>,
-because earlier 6.11 releases do not generate correct COFF object files.</p>
-
-<p>Building the distribution components from the ground up requires Microsoft's Visual
-C/C++ 5.0 compiler, Microsoft's make, <code>nmake</code>, and the standard Windows command
-interpreter. <a HREF="../makefile.nt"><code>makefile.nt</code></a> is written to use only <code>nmake</code>.
-As on UNIX systems, the compilation components are installed in a single <em>build
-directory</em>, and the top-level programs, <code>lcc.exe</code> and <code>bprint.exe</code>,
-are installed in a directory on the PATH. If the conventions used below are followed, the
-Windows-specific parts of the driver program, <code>lcc.exe</code>, can be used
-unmodified.</p>
-
-<p>Building from the source distribution on a Windows system involves the following steps.
-Below, the build directory is referred to as <code>BUILDDIR</code>, and the distribution
-is in <code>\dist\lcc\4.1</code>.
-
-<ol>
- <li>Create the build directory, perhaps using a version- and platform-specific naming
- convention as suggested in <a HREF="#unix"><em>Installation on UNIX</em></a>, and record
- the name of this directory in the <code>BUILDDIR</code> environment variable:<blockquote>
- <pre>C:\dist\lcc\4.1>set BUILDDIR=\progra~1\lcc\4.1\bin
-C:\dist\lcc\4.1>mkdir %BUILDDIR%</pre>
- </blockquote>
- <p>The default build, or installation, directory is <code>\Program Files\lcc\4.1\bin</code>,
- but the <code>nmake</code> commands require that you use the corresponding 8.3 file name, <code>progra~1</code>,
- instead of <code>Program Files</code>.</p>
- </li>
- <li><a HREF="../etc/win32.c"><code>etc\win32.c</code></a> is the Windows-specific part of
- the driver. It assumes that environment variable <code>include</code> gives the locations
- of the VC header files and that the linker (<code>link.exe</code>) and the assembler (<code>ml.exe</code>)
- are on the PATH. It also assumes that the macro <code>LCCDIR</code> gives the build
- directory. If necessary, revise a copy of <a HREF="../etc/win32.c"><code>etc\win32.c</code></a>
- to reflect the conventions on your computer (see <a HREF="#driver"><em>Building the Driver</em></a>),
- then build the driver, specifying the default temporary directory, if necessary:<blockquote>
- <pre>C:\dist\lcc\4.1>nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=etc/win32.c lcc
-...
- cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -DTEMPDIR=\"\\temp\" -Fo\progra~1\lcc\4.1\bin\lcc.obj etc/lcc.c
-lcc.c
- cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -Fo\progra~1\lcc\4.1\bin\host.obj etc/win32.c
-win32.c
- cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -Fe\progra~1\lcc\4.1\bin\lcc.exe \progra~1\lcc\4.1\bin\lcc.obj \progra~1\lcc\4.1\bin\host.obj</pre>
- </blockquote>
- <p>If you make a copy of <code>etc\win32.c</code>, specify the path of the copy as the
- value of <code>HOSTFILE</code>. For example, if you copy <code>etc\win32.c</code> to <code>BUILDDIR</code>
- and edit it, use the command</p>
- <blockquote>
- <pre>C:\dist\lcc\4.1>nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=%BUILDDIR%\win32.c lcc</pre>
- </blockquote>
- </li>
- <li>Build the preprocessor, compiler proper, library, and other accessories (see <a
- HREF="#rcc"><em>Building the Compiler</em></a>):<blockquote>
- <pre>C:\dist\lcc\4.1>nmake -f makefile.nt all</pre>
- </blockquote>
- <p>This command uses the VC command-line tools <code>cl</code> and <code>lib</code> to
- build <code>bprint.exe</code>, <code>cpp.exe</code>, <code>lburg.exe</code>, <code>liblcc.lib</code>,
- <code>librcc.lib</code>, and <code>rcc.exe</code>, all in <code>BUILDDIR</code>. There may
- be some warnings, but there should be no warnings.</p>
- </li>
- <li>Create a test directory and run the test suite:<blockquote>
- <pre>C:\dist\lcc\4.1>mkdir %BUILDDIR%\x86\win32\tst
-C:\dist\lcc\4.1>nmake -f makefile.nt test</pre>
- </blockquote>
- <p>This command compiles each program in <a HREF="../tst">tst</a>, compares the generated
- assembly code and diagnostics with the expected assembly code and diagnostics, executes
- the program, and compares the output with the expected output (using <code>fc</code>). For
- example, when the nmake command compiles <a HREF="../tst/8q.c"><code>tst\8q.c</code></a>,
- it leaves the generated assembly code and diagnostic output in <code>%BUILDDIR%\x86\win32\tst\8q.s</code>
- and <code>%BUILDDIR%\x86\win32\tst\8q.2</code>, and it compares them with the expected
- results in <code>x86\win32\tst\8q.sbk</code>. It builds the executable program in <code>%BUILDDIR%\x86\win32\tst\8q.exe</code>,
- runs it, and redirects the output to <code>%BUILDDIR%\x86\win32\tst\8q.1</code>, which it
- compares with <code>x86\win32\tst\8q.1bk</code>. The output from this step is voluminous,
- but there should be no differences and no errors.</p>
- </li>
- <li>Run the "triple" test, which compiles <code>rcc</code> with itself and
- verifies the results:<blockquote>
- <pre>C:\dist\lcc\4.1>nmake -f makefile.nt triple
-...
-\progra~1\lcc\4.1\bin\x86.c:
- Assembling: C:/TEMP/lcc2001.asm
- fc /b \progra~1\lcc\4.1\bin\1rcc.exe \progra~1\lcc\4.1\bin\2rcc.exe
-Comparing files \progra~1\lcc\4.1\bin\1rcc.exe and \progra~1\lcc\4.1\bin\2RCC.EXE
-00000088: B4 D5</pre>
- </blockquote>
- <p>This command builds <code>rcc</code> twice; once using the <code>rcc</code> built by VC
- and again using the <code>rcc</code> built by <code>lcc</code>. The resulting binaries are
- compared using <code>fc</code>. They should be identical, except for one or two bytes of
- timestamp data, as shown at the end of the output above. If they aren't, our compiler is
- generating incorrect code; <a HREF="#bugs">contact</a> us.</p>
- </li>
- <li>Copy <code>lcc.exe</code> and <code>bprint.exe</code> to a directory on your PATH, e.g.,<blockquote>
- <pre>C:\dist\lcc\4.1>copy %BUILDDIR%\lcc.exe \bin
- 1 file(s) copied.
-
-C:\dist\lcc\4.1>copy %BUILDDIR%\bprint.exe \bin
- 1 file(s) copied.</pre>
- </blockquote>
- </li>
- <li>Finally, clean up:<blockquote>
- <pre>C:\dist\lcc\4.1>nmake -f makefile.nt clean</pre>
- </blockquote>
- <p>This command removes the derived files in <code>BUILDDIR</code>, but does not remove <code>rcc.exe</code>,
- etc.; "<code>nmake -f makefile.nt clobber</code>" cleans up and removes all
- executables and libraries. Test directories under <code>BUILDDIR</code> are <em>not</em>
- removed; you'll need to remove these by hand, e.g.,</p>
- <blockquote>
- <pre>C:\dist\lcc\4.1>rmdir %BUILDDIR%\x86 /s
-\progra~1\lcc\4.1\bin\x86, Are you sure (Y/N)? y</pre>
- </blockquote>
- </li>
-</ol>
-
-<h2><a NAME="bugs">Reporting Bugs</a></h2>
-
-<p>lcc is a large, complex program. We find and repair errors routinely. If you think that
-you've found a error, follow the steps below, which are adapted from the instructions in
-Chapter 1 of <cite>A Retargetable C Compiler: Design and Implementation</cite>.
-
-<ol>
- <li>If you don't have a source file that displays the error, create one. Most errors are
- exposed when programmers try to compile a program they think is valid, so you probably
- have a demonstration program already.</li>
- <li>Preprocess the source file and capture the preprocessor output. Discard the original
- code.</li>
- <li>Prune your source code until it can be pruned no more without sending the error into
- hiding. We prune most error demonstrations to fewer than five lines.</li>
- <li>Confirm that the source file displays the error with the <em>distributed</em> version of
- lcc. If you've changed lcc and the error appears only in your version, then you'll have to
- chase the error yourself, even if it turns out to be our fault, because we can't work on
- your code.</li>
- <li>Annotate your code with comments that explain why you think that lcc is wrong. If lcc
- dies with an assertion failure, please tell us where it died. If lcc crashes, please
- report the last part of the call chain if you can. If lcc is rejecting a program you think
- is valid, please tell us why you think it's valid, and include supporting page numbers in
- the ANSI Standard, Appendix A in <cite>The C Programming Language</cite>, or the
- appropriate section in <cite>C: A Reference Manual</cite>, 4th edition by S. B. Harbison
- and G. L. Steele, Jr. (Prentice Hall, 1995). If lcc silently generates incorrect code for
- some construct, please include the corrupt assembly code in the comments and flag the
- incorrect instructions if you can.</li>
- <li>Confirm that your error hasn't been fixed already. The latest version of lcc is always
- available for anonymous <code>ftp</code> from <code>ftp.cs.princeton.edu</code> in <a
- HREF="ftp://ftp.cs.princeton.edu/pub/lcc"><code>pub/lcc</code></a>. A <a
- HREF="ftp://ftp.cs.princeton.edu/pub/lcc/README"><code>README</code></a> file there gives
- acquistion details, and the <a HREF="../LOG"><code>LOG</code></a> file reports what errors
- were fixed and when they were fixed. If you report a error that's been fixed, you might
- get a canned reply.</li>
- <li>Send your program by electronic mail to <code>lcc-bugs@cs.princeton.edu</code>. Please
- send only valid C programs; put all remarks in C comments so that we can process reports
- semiautomatically.</li>
-</ol>
-
-<h2><a NAME="mailinglist">Keeping in Touch</a></h2>
-
-<p>There is an lcc mailing list for general information about lcc. To be added to the
-list, send a message with the 1-line body</p>
-
-<blockquote>
- <pre>subscribe lcc</pre>
-</blockquote>
-
-<p>to <code>majordomo@cs.princeton.edu</code>. This line must appear in the message body;
-"Subject:" lines are ignored. To learn more about mailing lists served by <code>majordomo</code>,
-send a message with the 1-word body "<code>help</code>" to <code>majordomo@cs.princeton.edu</code>.
-Mail sent to <code>lcc@cs.princeton.edu</code> is forwarded to everyone on the mailing
-list.</p>
-
-<p>There is also an <code>lcc-bugs</code> mailing list for reporting bugs; subscribe to it
-by sending a message with the 1-line body </p>
-
-<blockquote>
- <pre>subscribe lcc-bugs</pre>
-</blockquote>
-
-<p>to <code>majordomo@cs.princeton.edu</code>. Mail addressed to <var>lcc-bugs@cs.princeton.edu</var>
-is forwarded to everyone on this list.</p>
-
-<hr>
-
-<address>
- <a HREF="http://www.research.microsoft.com/~cwfraser/">Chris Fraser</a> / <a
- HREF="mailto:cwfraser@microsoft.com">cwfraser@microsoft.com</a><br>
- <a HREF="http://www.research.microsoft.com/~drh/">David Hanson</a> / <a
- HREF="mailto:drh@microsoft.com">drh@microsoft.com</a><br>
- $Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $
-</address>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> + +<head> +<link HREF="mailto:drh@cs.princeton.edu" REV="made" TITLE="David R. Hanson"> +<title>Installing lcc</title> +</head> + +<body> + +<h1>Installing lcc</h1> + +<p ALIGN="LEFT"><strong><a HREF="http://www.research.microsoft.com/~cwfraser/">Christopher +W. Fraser</a> and <a HREF="http://www.research.microsoft.com/~drh/">David R. Hanson</a>, <a +HREF="http://www.research.microsoft.com/">Microsoft Research</a></strong></p> + +<h2>Contents</h2> + +<dir> + <li><a HREF="#intro">Introduction</a></li> + <li><a HREF="#unix">Installation on UNIX</a></li> + <li><a HREF="#driver">Building the Driver</a></li> + <li><a HREF="#rcc">Building the Compiler and Accessories</a></li> + <li><a HREF="#win32">Installation on Windows NT 4.0 and Windows 95/98</a></li> + <li><a HREF="#bugs">Reporting Bugs</a></li> + <li><a HREF="#mailinglist">Keeping in Touch</a></li> +</dir> + +<h2><a NAME="intro">Introduction</a></h2> + +<p><a HREF="http://www.cs.princeton.edu/software/lcc/">lcc</a> is the ANSI C compiler +described in our book <cite>A Retargetable C Compiler: Design and Implementation</cite> +(Addison-Wesley, 1995, ISBN 0-8053-1670-1).</p> + +<p>If you're installing lcc on a UNIX system, read the remainder of this section and +continue with the next section. If you're installing lcc on a Windows NT 4.0 or Windows +95/98 system, and you intend only to <u>use</u> lcc, you can run the <a +href="ftp://ftp.cs.princeton.edu/pub/packages/lcc/lcc41.exe">InstallShield executable</a>, +which installs the binaries and the documentation. If you want to <u>modify</u> lcc or <u>rebuild</u> +it from the source files, you need the <a +href="ftp://ftp.cs.princeton.edu/packages/lcc/lcc41.zip">complete distribution</a>, and +you should read the rest of the section, the following three sections, and the <a +HREF="#win32">Windows NT/95/98</a> section.</p> + +<p>Extract the distribution into its own directory. All non-absolute paths below are +relative to this directory. The distribution holds the following subdirectories.</p> + +<blockquote> + <table BORDER="0" CELLPADDING="1" CELLSPACING="1" WIDTH="80%"> + <tr> + <td><a HREF="../src"><code>src</code></a></td> + <td></td> + <td>source code</td> + </tr> + <tr> + <td><a HREF="../etc"><code>etc</code></a></td> + <td></td> + <td>driver, accessories</td> + </tr> + <tr> + <td><a HREF="../lib"><code>lib</code></a></td> + <td></td> + <td>runtime library source code</td> + </tr> + <tr> + <td><a HREF="../cpp"><code>cpp</code></a></td> + <td></td> + <td>preprocessor source code</td> + </tr> + <tr> + <td><a HREF="../lburg"><code>lburg</code></a></td> + <td></td> + <td>code-generator generator source code</td> + </tr> + <tr> + <td><a HREF="../doc"><code>doc</code></a></td> + <td></td> + <td>this document, man pages</td> + </tr> + <tr> + <td><code><a HREF="../include">include</a>/*/*</code></td> + <td></td> + <td>include files</td> + </tr> + <tr> + <td><a HREF="../tst"><code>tst</code></a></td> + <td></td> + <td>test suite</td> + </tr> + <tr> + <td><code><a HREF="../alpha">alpha</a>/*/tst</code></td> + <td></td> + <td>ALPHA test outputs</td> + </tr> + <tr> + <td><code><a HREF="../mips">mips</a>/*/tst</code></td> + <td></td> + <td>MIPS test outputs</td> + </tr> + <tr> + <td><code><a HREF="../sparc">sparc</a>/*/tst</code></td> + <td></td> + <td>SPARC test outputs</td> + </tr> + <tr> + <td><code><a HREF="../x86">x86</a>/*/tst</code></td> + <td></td> + <td>X86 test outputs</td> + </tr> + </table> +</blockquote> + +<p><code>doc/install.html</code> is the HTML file for this document. <a HREF="4.html"><code>doc/4.html</code></a> +describes the internal differences between lcc 3.x and 4.1.</p> + +<p>The installation makefile is designed so that lcc can be installed from a read-only +file system or directory, which is common in networked environments, so the distribution +can be unloaded on a central file server. <strong>You will need an existing ANSI/ISO C +compiler to build and install lcc.</strong></p> + +<h2><a NAME="unix">Installation on UNIX</a></h2> + +<p>The compilation components (the preprocessor, include files, and compiler proper, etc.) +are installed in a single <em>build directory</em>. On multi-platform systems supported by +a central file server, it's common to store the build directory in a location specific to +the platform and to the version of lcc, and to point a symbolic link to this location. For +example,</p> + +<blockquote> + <pre>% ln -s /usr/local/lib/lcc-4.1/sparc-solaris /usr/local/lib/lcc</pre> +</blockquote> + +<p>points <code>/usr/local/lib/lcc</code> to a build directory for lcc version 4.1 on the +SPARC under Solaris. Links into <code>/usr/local/lib</code> are created for the programs <code>lcc</code> +and <code>bprint</code>. Thus, a new distribution can be installed by building it in its +own build directory and changing one symbolic link to point to that directory. If these +conventions or their equivalents are followed, the host-specific parts of the driver +program, <code>lcc</code>, can be used unmodified.</p> + +<p>Installation on a UNIX system involves the following steps. Below, the build directory +is referred to as <code>BUILDDIR</code>. + +<ol> + <li>Create the build directory, using a version- and platform-specific naming convention as + suggested above, and record the name of this directory in the <code>BUILDDIR</code> + environment variable:<blockquote> + <pre>% setenv BUILDDIR /usr/local/lib/lcc-4.1/sparc-solaris +% mkdir -p $BUILDDIR</pre> + </blockquote> + <p>Here and below, commands assume the C shell. Also, you'll need a version of <code>mkdir</code> + that supports the <code>-p</code> option, which creates intermediate directories as + necessary.</p> + </li> + <li>Copy the man pages to the repository for local man pages, e.g.,<blockquote> + <pre>% cp doc/*.1 /usr/local/man/man1</pre> + </blockquote> + <p>Some users copy the man pages to the build directory and create the appropriate + symbolic links, e.g., </p> + <blockquote> + <pre>% cp doc/*.1 $BUILDDIR +% ln -s $BUILDDIR/*.1 /usr/local/man/man1</pre> + </blockquote> + </li> + <li>Platform-specific include files are in directories named <code>include/</code><em>target</em><code>/</code><em>os</em>. + Create the include directory in the build directory, and copy the include hierarchy for + your platform to this directory, e.g.,<blockquote> + <pre>% mkdir $BUILDDIR/include +% cp -p -R include/sparc/solaris/* $BUILDDIR/include</pre> + </blockquote> + <p>Again, some users create a symbolic link to the appropriate directory in the + distribution instead of copying the include files. For example, at Princeton, the + distributions are stored under <code>/proj/pkg/lcc</code>, so the included files are + "installed" by creating one symbolic link: </p> + <blockquote> + <pre>% ln -s /proj/pkg/lcc/4.1/include/sparc/solaris $BUILDDIR/include</pre> + </blockquote> + <p>If you're installing lcc on Linux, you <em>must</em> also plant a symbolic link named <code>gcc</code> + to gcc's library directory, because lcc uses gcc's C preprocessor and most of gcc's header + files:</p> + <blockquote> + <pre>% ln -s /usr/lib/gcc-lib/i486-linux/2.7.2.2 $BUILDDIR/gcc</pre> + </blockquote> + <p>The library directory shown above may be different on your Linux machine; to determine + the correct directory, browse <code>/usr/lib/gcc-lib</code>, or execute</p> + <blockquote> + <pre>% cc -v tst/8q.c</pre> + </blockquote> + <p>and examine the diagnostic output. Make sure that <code>$BUILDDIR/gcc/cpp</code> and <code>$BUILDDIR/gcc/include</code> + point to, respectively, gcc's C preprocessor and header files. On Linux, lcc looks for + include files in <code>$BUILDDIR/include</code>, <code>$BUILDDIR/gcc/include</code>, and <code>/usr/include</code>, + in that order; see <a HREF="#driver"><em>Building the Driver</em></a> and <a + href="../etc/linux.c"><code>etc/linux.c</code></a> for details.</p> + </li> + <li>The <a HREF="../makefile"><code>makefile</code></a> includes the file named by the <code>CUSTOM</code> + macro; the default is <code>custom.mk</code>, and an empty <code>custom.mk</code> is + included in the distribution. If desired, prepare a site-specification customization file + and define <code>CUSTOM</code> to the path of that file when invoking make in steps 5 and + 6, e.g.,<blockquote> + <pre>make CUSTOM=/users/drh/solaris.mk</pre> + </blockquote> + <p>You can, for example, use customization files to record site-specific values for macros + instead of using environment variables, and to record targets for the steps in this list.</p> + </li> + <li>Build the host-specific driver, creating a custom host-specific part, if necessary. See <a + HREF="#driver"><em>Building the Driver</em></a>.</li> + <li>Build the preprocessor, compiler proper, library, and other accessories. See <a + HREF="#rcc"><em>Building the Compiler</em></a>.</li> + <li>Plant symbolic links to the build directory and to the installed programs, e.g.,<blockquote> + <pre>% ln -s $BUILDDIR /usr/local/lib/lcc +% ln -s /usr/local/lib/{lcc,bprint} /usr/local/bin</pre> + </blockquote> + <p>Some users copy <code>bprint</code> and <code>lcc</code> into <code>/usr/local/bin</code> + instead of creating symbolic links. The advantange of creating the links for <code>lcc</code> + and <code>bprint</code> as shown is that, once established, they point indirectly to + whatever <code>/usr/local/lib/lcc</code> points to; installing a new version of lcc, say, + 4.2, can be done by changing <code>/usr/local/lib/lcc</code> to point to the 4.2 build + directory.</p> + </li> +</ol> + +<h2><a NAME="driver">Building the Driver</a></h2> + +<p>The preprocessor, compiler, assembler, and loader are invoked by a driver program, <code>lcc</code>, +which is similar to <code>cc</code> on most systems. It's described in the man page <code>doc/lcc.1</code>. +The driver is built by combining the host-independent part, <a href="../etc/lcc.c"><code>etc/lcc.c</code></a>, +with a small host-specific part. Distributed host-specific parts are named <code>etc/</code><em>os</em><code>.c</code>, +where <em>os</em> is the name of the operating system for the host on which <code>lcc</code> +is being installed. If you're following the installations conventions described above, you +can probably use one of the host-specific parts unmodified; otherwise, pick one that is +closely related to your platform, copy it to <em>whatever</em><code>.c</code>, and edit it +as described below. You should not have to edit <code>etc/lcc.c</code>.</p> + +<p>We'll use <a HREF="../etc/solaris.c"><code>etc/solaris.c</code></a> as an example in +describing how the host-specific part works. This example illustrates all the important +features. Make sure you have the environment variable <code>BUILDDIR</code> set correctly, +and build the driver with a <code>make</code> command, e.g.,</p> + +<blockquote> + <pre>% make HOSTFILE=etc/solaris.c lcc +cc -g -c -DTEMPDIR=\"/tmp\" -o /usr/local/lib/lcc-4.1/sparc-solaris/lcc.o etc/lcc.c +cc -g -c -o /usr/local/lib/lcc-4.1/sparc-solaris/host.o etc/solaris.c +cc -g -o /usr/local/lib/lcc-4.1/sparc-solaris/lcc /usr/local/lib/lcc-4.1/sparc-solaris/lcc.o /usr/local/lib/lcc-4.1/sparc-solaris/host.o</pre> +</blockquote> + +<p>The symbolic name <code>HOSTFILE</code> specifies the path to the host-specific part, +either one in the distribution or <em>whatever</em><code>.c</code>. Some versions of make +may require the <code>-e</code> option in order to read the environment.</p> + +<p>Here's <code>etc/solaris.c</code>:</p> + +<blockquote> + <pre>/* Sparcs running Solaris 2.5.1 at CS Dept., Princeton University */ + +#include <string.h> + +static char rcsid[] = "$ Id: solaris.c,v 1.10 1998/09/14 20:36:33 drh Exp $"; + +#ifndef LCCDIR +#define LCCDIR "/usr/local/lib/lcc/" +#endif +#ifndef SUNDIR +#define SUNDIR "/opt/SUNWspro/SC4.2/lib/" +#endif + +char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 }; +char inputs[256] = ""; +char *cpp[] = { LCCDIR "cpp", + "-D__STDC__=1", "-Dsparc", "-D__sparc__", "-Dsun", "-D__sun__", "-Dunix", + "$1", "$2", "$3", 0 }; +char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include", + "-I/usr/include", 0 }; +char *com[] = { LCCDIR "rcc", "-target=sparc/solaris", + "$1", "$2", "$3", 0 }; +char *as[] = { "/usr/ccs/bin/as", "-Qy", "-s", "-o", "$3", "$1", "$2", 0 }; +char *ld[] = { "/usr/ccs/bin/ld", "-o", "$3", "$1", + SUNDIR "crti.o", SUNDIR "crt1.o", + SUNDIR "values-xa.o", "$2", "", + "-Y", "P," SUNDIR ":/usr/ccs/lib:/usr/lib", "-Qy", + "-L" LCCDIR, "-llcc", "-lm", "-lc", SUNDIR "crtn.o", 0 }; + +extern char *concat(char *, char *); + +int option(char *arg) { + if (strncmp(arg, "-lccdir=", 8) == 0) { + cpp[0] = concat(&arg[8], "/cpp"); + include[0] = concat("-I", concat(&arg[8], "/include")); + ld[12] = concat("-L", &arg[8]); + com[0] = concat(&arg[8], "/rcc"); + } else if (strcmp(arg, "-p") == 0) { + ld[5] = SUNDIR "mcrt1.o"; + ld[10] = "P," SUNDIR "libp:/usr/ccs/lib/libp:/usr/lib/libp:" + SUNDIR ":/usr/ccs/lib:/usr/lib"; + } else if (strcmp(arg, "-b") == 0) + ; + else if (strncmp(arg, "-ld=", 4) == 0) + ld[0] = &arg[4]; + else + return 0; + return 1; +}</pre> +</blockquote> + +<p><code>LCCDIR</code> defaults to <code>"/usr/local/lib/lcc/"</code> unless +it's defined by a <code>-D</code> option as part of <code>CFLAGS</code> in the make +command, e.g.,</p> + +<blockquote> + <pre>% make HOSTFILE=etc/solaris.c CFLAGS='-DLCCDIR=\"/v/lib/lcc/\"' lcc</pre> +</blockquote> + +<p>Note the trailing slash; <code>SUNDIR</code> is provided so you can use <code>etc/solaris.c</code> +even if you have a different version of the Sun Pro compiler suite. If you're using the +gcc compiler tools instead of the Sun Pro tools, see <a HREF="../etc/gcc-solaris.c"><code>etc/gcc-solaris.c</code></a>.</p> + +<p>Most of the host-specific code is platform-specific data and templates for the commands +that invoke the preprocessor, compiler, assembler, and loader. The <code>suffixes</code> +array lists the file name suffixes for C source files, preprocessed source files, assembly +language source files, object files, and executable files. <code>suffixes</code> must be +terminated with a null pointer, as shown above. The initialization of <code>suffixes</code> +in <code><a HREF="../etc/solaris.c">etc/solaris.c</a></code> are the typical ones for UNIX +systems. Each element of <code>suffixes</code> is actually a list of suffixes, separated +by semicolons; <code><a HREF="../etc/win32.c">etc/win32.c</a></code> holds an example:</p> + +<blockquote> + <pre>char *suffixes[] = { ".c;.C", ".i;.I", ".asm;.ASM;.s;.S", ".obj;.OBJ", ".exe", 0 };</pre> +</blockquote> + +<p>When a list is given, the first suffix is used whenever lcc needs to generate a file +name. For example, with <code><a HREF="../etc/win32.c">etc/win32.c</a></code>, lcc emits +the generated assembly code into <code>.asm</code> files.</p> + +<p>The <code>inputs</code> array holds a null-terminated string of directories separated +by colons or semicolons. These are used as the default value of <code>LCCINPUTS</code>, if +the environment variable <code>LCCINPUTS</code> is not set; see the <a HREF="lcc.pdf">man +page</a>.</p> + +<p>Each command template is an array of pointers to strings terminated with a null +pointer; the strings are full path names of commands, arguments, or argument placeholders, +which are described below. Commands are executed in a child process, and templates can +contain multiple commands by separating commands with newlines. The driver runs each +command in a new process.</p> + +<p>The <code>cpp</code> array gives the command for running lcc's preprocessor, <code>cpp</code>. +Literal arguments specified in templates, e.g., <code>"-Dsparc"</code> in the <code>cpp</code> +command above, are passed to the command as given.</p> + +<p>The strings <code>"$1"</code>, <code>"$2"</code>, and <code>"$3"</code> +in templates are placeholders for <em>lists</em> of arguments that are substituted in a +copy of the template before the command is executed. <code>$1</code> is replaced by the <em>options</em> +specified by the user; for the preprocessor, this list always contains at least <code>-D__LCC__</code>. +<code>$2</code> is replaced by the <em>input</em> files, and <code>$3</code> is replaced +by the <em>output</em> file.</p> + +<p>Zero-length arguments after replacement are removed from the argument list before the +command is invoked. So, for example, if the preprocessor is invoked without an output +file, <code>"$3"</code> becomes <code>""</code>, which is removed from +the final argument list.</p> + +<p>The <code>include</code> array is a list of <code>-I</code> options that specify which +directives should be searched to satisfy include directives. These directories are +searched in the order given. The first directory should be the one to which the ANSI +header files were copied as described in <a HREF="#unix">UNIX</a> or <a HREF="#win32">Windows</a> +installation instructions. The driver adds these options to <code>cpp</code>'s arguments +when it invokes the preprocessor, except when <code>-N</code> is specified.</p> + +<p><code>com</code> gives the command for invoking the compiler. This template can appear +as shown above in a custom host-specific part, but the option <code>-target=sparc/solaris</code> +should be edited to the <em>target</em><code>/</code><em>os</em> for your platform. If <code>com[1]</code> +includes the string "<code>win32</code>", the driver assumes it's running on +Windows. lcc can generate code for <em>all</em> of the <em>target</em><code>/</code><em>os</em> +combinations listed in the file <code>src/bind.c</code>. The <code>-target</code> option +specifies the default combination. The driver's <code>-Wf</code> option can be used to +specify other combinations; the <a HREF="lcc.pdf">man page</a> elaborates.</p> + +<p><code>as</code> gives the command for invoking the assembler. On Linux, you must be +running at least version 2.8.1 of the GNU assembler; earlier versions mis-assemble some +instructions emitted by lcc.</p> + +<p><code>ld</code> gives the command for invoking the loader. For the other commands, the +list <code>$2</code> contains a single file; for <code>ld</code>, <code>$2</code> contains +all ".o" files and libraries, and <code>$3</code> is <code>a.out</code>, unless +the <code>-o</code> option is specified. As suggested in the code above, <code>ld</code> +must also specify the appropriate startup code and default libraries, including the lcc +library, <code>liblcc.a</code>.</p> + +<p>The <code>option</code> function is described below; the minimal <code>option</code> +function just returns 0.</p> + +<p>You can test <code>lcc</code> with the options <code>-v -v</code> to display the +commands that would be executed, e.g.,</p> + +<blockquote> + <pre>% $BUILDDIR/lcc -v -v foo.c baz.c mylib.a -lX11 +/usr/local/lib/lcc-4.1/lcc $ Id: solaris.c,v 1.10 1998/09/14 20:36:33 drh Exp $ +foo.c: +/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__ -I/usr/local/lib/lcc/include -I/usr/local/include -I/usr/include foo.c /tmp/lcc266290.i +/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc266290.i /tmp/lcc266291. +s +/usr/ccs/bin/as -Qy -s -o /tmp/lcc266292.o /tmp/lcc266291.s +baz.c: +/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__ -I/usr/local/lib/lcc/include -I/usr/local/include -I/usr/include baz.c /tmp/lcc266290.i +/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc266290.i /tmp/lcc266291.s +/usr/ccs/bin/as -Qy -s -o /tmp/lcc266293.o /tmp/lcc266291.s +/usr/ccs/bin/ld -o a.out /opt/SUNWspro/SC4.2/lib/crti.o /opt/SUNWspro/SC4.2/lib/crt1.o /opt/SUNWspro/SC4.2/lib/values-xa.o /tmp/lcc266292.o /tmp/lcc266293.o mylib.a -lX11 -Y P,/opt/SUNWspro/SC4.2/lib/:/usr/ccs/lib:/usr/lib -Qy -L/usr/local/lib/lcc/ -llcc -lm -lc /opt/SUNWspro/SC4.2/lib/crtn.o +rm /tmp/lcc266293.o /tmp/lcc266290.i /tmp/lcc266291.s /tmp/lcc266292.o</pre> +</blockquote> + +<p>As the output shows, <code>lcc</code> places temporary files in <code>/tmp</code>; if +any of the environment variables <code>TMP</code>, <code>TEMP</code>, and <code>TMPDIR</code> +are set, they override this default (in the order shown) as does the <code>-tempdir=</code><em>dir</em> +option. The default can be changed by defining <code>TEMPDIR</code> in <code>CFLAGS</code> +when building the driver.</p> + +<p>The <code>option</code> function is called for the options <code>-Wo</code>, <code>-g</code>, +<code>-p</code>, <code>-pg</code>, and <code>-b</code> because these compiler options +might also affect the loader's arguments. For these options, the driver calls <code>option(arg)</code> +to give the host-specific code an opportunity to edit the <code>ld</code> command, if +necessary. <code>option</code> can change <code>ld</code>, if necessary, and return 1 to +announce its acceptance of the option. If the option is unsupported, <code>option</code> +should return 0.</p> + +<p>For example, in response to <code>-g</code>, the <code>option</code> function shown +above accepts the option but does nothing else, because the <code>ld</code> and <code>as</code> +commands don't need to be modified on the SPARC. <code>-g</code> will also be added to the +compiler's options by the host-independent part of the driver. The <code>-p</code> causes <code>option</code> +to change the name of the startup code and changed the list of libraries. The <code>-b</code> +option turns on <code>lcc</code>'s per-expression profiling, the code for which is in <code>liblcc.a</code>, +so <code>option</code> need no nothing.</p> + +<p>On SPARCs, the driver also recognizes <code>-Bstatic</code> and <code>-Bdynamic</code> +as linker options. The driver recognizes but ignores "<code>-target</code> <em>name</em>" +option.</p> + +<p>The option <code>-Wo</code><em>arg</em> causes the driver to pass <em>arg</em> to <code>option</code>. +Such options have no other effect; this mechanism is provided to support system-specific +options that affect the commands executed by the driver. As illustrated above, +host-specific parts should support the <code>-Wo-lccdir=</code><em>dir</em> option, which +causes lcc's compilation components to be found in <em>dir</em>, because this option is +used by the test scripts, and because the driver simulates a <code>-Wo-lccdir</code> +option with the value of the environment variable <code>LCCDIR</code>, if it's defined. +The code above rebuilds the paths to the include files, preprocessor, compiler, and +library by calling <code>concat</code>, which is defined in <code>etc/lcc.c</code>.</p> + +<h2><a NAME="rcc">Building the Compiler and Accessories</a></h2> + +<p>To build the rest of compilation components make sure <code>BUILDDIR</code> is set +appropriately and type "<code>make all</code>". This command builds <code>librcc.a</code> +(the compiler's private library), <code>rcc</code> (the compiler proper), <code>lburg</code> +(the code-generator generator), <code>cpp</code> (the preprocessor), <code>liblcc.a</code> +(the runtime library), and <code>bprint</code> (the profile printer), all in <code>BUILDDIR</code>. +There may be warnings, but there should be no errors. If you're using an ANSI/ISO compiler +other than <code>cc</code>, specify its name with the <code>CC=</code> option, e.g., +"<code>make CC=gcc all</code>". If you're running on a DEC ALPHA, use "<code>make +CC='cc -std1' all</code>"; the <code>-std1</code> option is essential on the ALPHA. +If you're on a DEC 5000 running Ultrix 4.3, use "<code>make CC=c89 all</code>".</p> + +<p>Once <code>rcc</code> is built with the host C compiler, run the test suite to verify +that <code>rcc</code> is working correctly. If any of the steps below fail, contact us +(see <a HREF="#bugs"><em>Reporting Bugs</em></a>). The commands in the makefile run the +shell script <code>src/run.sh</code> on each C program in the test suite, <code>tst/*.c</code>. +It uses the driver, <code>$BUILDDIR/lcc</code>, so you must have the driver in the build +directory before testing <code>rcc</code>. The <em>target</em><code>/</code><em>os</em> +combination is read from the variable <code>TARGET</code>, which must be specified when +invoking <code>make</code>:</p> + +<blockquote> + <pre>% make TARGET=sparc/solaris test +mkdir -p /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/8q.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/array.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cf.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cq.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cvt.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/fields.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/front.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/incr.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/init.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/limits.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/paranoia.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/sort.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/spill.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/stdarg.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/struct.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/switch.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/wf1.s: +/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/yacc.s:</pre> +</blockquote> + +<p>Each line in the output above is of the form</p> + +<blockquote> + <p><code>$BUILDDIR/rcc -target=</code><em>target</em><code>/</code><em>os</em><code>$BUILDDIR/</code><em>target</em><code>/</code><em>os</em><code>/</code><em>X</em><code>.s:</code></p> +</blockquote> + +<p>where <em>X</em> is the base name of the C program <em>X</em><code>.c</code> in the +test suite. This output identifies the compiler and the target, e.g., "<code>$BUILDDIR/rcc</code> +is generating code for a <code>sparc</code> running the <code>solaris</code> operating +system."</p> + +<p>For each program in the test suite, <code>src/run.sh</code> compiles the program, drops +the generated assembly language code in <code>BUILDDIR</code>/<em>target</em><code>/</code><em>os</em>, +and uses <code>diff</code> to compare the generated assembly code with the expected code +(the code expected for <code>tst/8q.c</code> on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.sbk</code>, +etc.). If there are differences, the script executes the generated code with the input +given in <code>tst</code> (the input for <code>tst/8q.c</code> is in <code>tst/8q.0</code>, +etc.) and compares the output with the expected output (the expected output from <code>tst/8q.c</code> +on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.1bk</code>, etc.). The script +also compares the diagnostics from the compiler with the expected diagnostics.</p> + +<p>On some systems, there may be a few differences between the generated code and the +expected code. These differences occur because the expected code is generated by cross +compilation and the least significant bits of some floating-point constants differ from +those bits in constants generated on your system. On Linux, there may be differences +because of differences in the header files between our system and yours. There should be +no differences in the output from executing the test programs.</p> + +<p>Next, run the "triple test", which builds <code>rcc</code> using itself:</p> + +<blockquote> + <pre>% make triple +/usr/local/lib/lcc-4.1/sparc-solaris/lcc -o /usr/local/lib/lcc-4.1/sparc-solaris/1rcc -d0.6 -Wo-lccdir=/usr/local/lib/lcc-4.1/sparc-solaris -B/usr/local/lib/lcc-4.1/sparc-solaris/ -Isrc src/*.c +src/alloc.c: +... +src/x86.c: +/usr/local/lib/lcc-4.1/sparc-solaris/lcc -o /usr/local/lib/lcc-4.1/sparc-solaris/1rcc -d0.6 -Wo-lccdir=/usr/local/lib/lcc-4.1/sparc-solaris -B/usr/local/lib/lcc-4.1/sparc-solaris/ -Isrc src/*.c +src/alloc.c: +... +src/x86.c: +strip /usr/local/lib/lcc-4.1/sparc-solaris/[12]rcc +dd if=/usr/local/lib/lcc-4.1/sparc-solaris/1rcc of=/usr/local/lib/lcc-4.1/sparc-solaris/rcc1 bs=512 skip=1 +769+1 records in +769+1 records out +dd if=/usr/local/lib/lcc-4.1/sparc-solaris/2rcc of=/usr/local/lib/lcc-4.1/sparc-solaris/rcc2 bs=512 skip=1 +769+1 records in +769+1 records out +if cmp /usr/local/lib/lcc-4.1/sparc-solaris/rcc[12]; then \ + mv /usr/local/lib/lcc-4.1/sparc-solaris/2rcc /usr/local/lib/lcc-4.1/sparc-solaris/rcc; \ + rm -f /usr/local/lib/lcc-4.1/sparc-solaris/1rcc /usr/local/lib/lcc-4.1/sparc-solaris/rcc[12]; fi</pre> +</blockquote> + +<p>This command builds <code>rcc</code> twice; once using the <code>rcc</code> built by <code>cc</code> +and again using the <code>rcc</code> built by <code>lcc</code>. The resulting binaries are +compared. They should be identical, as shown at the end of the output above. If they +aren't, our compiler is generating incorrect code; <a HREF="#bugs">contact</a> us.</p> + +<p>The final version of <code>rcc</code> should also pass the test suite; that is, the +output from</p> + +<blockquote> + <pre>% make TARGET=sparc/solaris test</pre> +</blockquote> + +<p>should be identical to that from the previous <code>make test</code>.</p> + +<p>The command "<code>make clean</code>" cleans up, but does not remove <code>rcc</code>, +etc., and "<code>make clobber</code>" cleans up and removes <code>lcc</code>, <code>rcc</code>, +and the other accessories. Test directories under <code>BUILDDIR</code> are <em>not</em> +removed; you'll need to remove these by hand, e.g.,</p> + +<blockquote> + <pre>% rm -fr $BUILDDIR/sparc</pre> +</blockquote> + +<p>The code generators for the other targets can be tested by specifying the desired <em>target</em><code>/</code><em>os</em> +and setting an environment variable that controls what <code>src/run.sh</code> does. For +example, to test the MIPS code generator, type</p> + +<blockquote> + <pre>% setenv REMOTEHOST noexecute +% make TARGET=mips/irix test</pre> +</blockquote> + +<p>As above, <code>src/run.sh</code> compares the MIPS code generated with what's +expected. There should be no differences. Setting <code>REMOTEHOST</code> to <code>noexecute</code> +suppresses the assembly and execution of the generated code. If you set <code>REMOTEHOST</code> +to the name of a MIPS machine to which you can <code>rlogin</code>, <code>src/run.sh</code> +will <code>rcp</code> the generated code to that machine and execute it there, if +necessary. See <code>src/run.sh</code> for the details.</p> + +<p>You can use lcc as a cross compiler. The options <code>-S</code> and <code>-Wf-target=</code><em>target/os</em> +generate assembly code for the specified target, which is any of those listed in the file <code>src/bind.c</code>. +For example, </p> + +<blockquote> + <pre>% lcc -Wf-target=mips/irix -S tst/8q.c</pre> +</blockquote> + +<p>generates MIPS code for <code>tst/8q.c</code> in <code>8q.s</code>.</p> + +<p>lcc can also generate code for a "symbolic" target. This target is used +routinely in front-end development, and its output is a printable representation of the +input program, e.g., the dags constructed by the front end are printed, and other +interface functions print their arguments. You can specify this target with the option <code>-Wf-target=symbolic</code>. +For example,</p> + +<blockquote> + <pre>% lcc -Wf-target=symbolic -S tst/8q.c</pre> +</blockquote> + +<p>generates symbolic output for <code>tst/8q.c</code> in <code>8q.s</code>. Adding <code>-Wf-html</code> +causes the symbolic target to emit HTML instead of plain text. Finally, the option <code>-Wf-target=null</code> +specifies the "null" target for which lcc emits nothing and thus only checks the +syntax and semantics of its input files.</p> + +<h2><a NAME="win32">Installation on Windows NT 4.0 or Windows 95/98</a></h2> + +<p>On Windows NT 4.0 and Windows 95/98, lcc is designed to work with Microsoft's Visual +C++ 5.0 (VC) and Microsoft's Assembler, MASM 6.11d. It uses the VC header files, +libraries, and command-line tools, and it uses MASM to assemble the code it generates. If +you have MASM 6.11, make sure you <a +HREF="http://support.microsoft.com/support/kb/articles/Q138/9/83.asp">upgrade to 6.11d</a>, +because earlier 6.11 releases do not generate correct COFF object files.</p> + +<p>Building the distribution components from the ground up requires Microsoft's Visual +C/C++ 5.0 compiler, Microsoft's make, <code>nmake</code>, and the standard Windows command +interpreter. <a HREF="../makefile.nt"><code>makefile.nt</code></a> is written to use only <code>nmake</code>. +As on UNIX systems, the compilation components are installed in a single <em>build +directory</em>, and the top-level programs, <code>lcc.exe</code> and <code>bprint.exe</code>, +are installed in a directory on the PATH. If the conventions used below are followed, the +Windows-specific parts of the driver program, <code>lcc.exe</code>, can be used +unmodified.</p> + +<p>Building from the source distribution on a Windows system involves the following steps. +Below, the build directory is referred to as <code>BUILDDIR</code>, and the distribution +is in <code>\dist\lcc\4.1</code>. + +<ol> + <li>Create the build directory, perhaps using a version- and platform-specific naming + convention as suggested in <a HREF="#unix"><em>Installation on UNIX</em></a>, and record + the name of this directory in the <code>BUILDDIR</code> environment variable:<blockquote> + <pre>C:\dist\lcc\4.1>set BUILDDIR=\progra~1\lcc\4.1\bin +C:\dist\lcc\4.1>mkdir %BUILDDIR%</pre> + </blockquote> + <p>The default build, or installation, directory is <code>\Program Files\lcc\4.1\bin</code>, + but the <code>nmake</code> commands require that you use the corresponding 8.3 file name, <code>progra~1</code>, + instead of <code>Program Files</code>.</p> + </li> + <li><a HREF="../etc/win32.c"><code>etc\win32.c</code></a> is the Windows-specific part of + the driver. It assumes that environment variable <code>include</code> gives the locations + of the VC header files and that the linker (<code>link.exe</code>) and the assembler (<code>ml.exe</code>) + are on the PATH. It also assumes that the macro <code>LCCDIR</code> gives the build + directory. If necessary, revise a copy of <a HREF="../etc/win32.c"><code>etc\win32.c</code></a> + to reflect the conventions on your computer (see <a HREF="#driver"><em>Building the Driver</em></a>), + then build the driver, specifying the default temporary directory, if necessary:<blockquote> + <pre>C:\dist\lcc\4.1>nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=etc/win32.c lcc +... + cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -DTEMPDIR=\"\\temp\" -Fo\progra~1\lcc\4.1\bin\lcc.obj etc/lcc.c +lcc.c + cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -Fo\progra~1\lcc\4.1\bin\host.obj etc/win32.c +win32.c + cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -Fe\progra~1\lcc\4.1\bin\lcc.exe \progra~1\lcc\4.1\bin\lcc.obj \progra~1\lcc\4.1\bin\host.obj</pre> + </blockquote> + <p>If you make a copy of <code>etc\win32.c</code>, specify the path of the copy as the + value of <code>HOSTFILE</code>. For example, if you copy <code>etc\win32.c</code> to <code>BUILDDIR</code> + and edit it, use the command</p> + <blockquote> + <pre>C:\dist\lcc\4.1>nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=%BUILDDIR%\win32.c lcc</pre> + </blockquote> + </li> + <li>Build the preprocessor, compiler proper, library, and other accessories (see <a + HREF="#rcc"><em>Building the Compiler</em></a>):<blockquote> + <pre>C:\dist\lcc\4.1>nmake -f makefile.nt all</pre> + </blockquote> + <p>This command uses the VC command-line tools <code>cl</code> and <code>lib</code> to + build <code>bprint.exe</code>, <code>cpp.exe</code>, <code>lburg.exe</code>, <code>liblcc.lib</code>, + <code>librcc.lib</code>, and <code>rcc.exe</code>, all in <code>BUILDDIR</code>. There may + be some warnings, but there should be no warnings.</p> + </li> + <li>Create a test directory and run the test suite:<blockquote> + <pre>C:\dist\lcc\4.1>mkdir %BUILDDIR%\x86\win32\tst +C:\dist\lcc\4.1>nmake -f makefile.nt test</pre> + </blockquote> + <p>This command compiles each program in <a HREF="../tst">tst</a>, compares the generated + assembly code and diagnostics with the expected assembly code and diagnostics, executes + the program, and compares the output with the expected output (using <code>fc</code>). For + example, when the nmake command compiles <a HREF="../tst/8q.c"><code>tst\8q.c</code></a>, + it leaves the generated assembly code and diagnostic output in <code>%BUILDDIR%\x86\win32\tst\8q.s</code> + and <code>%BUILDDIR%\x86\win32\tst\8q.2</code>, and it compares them with the expected + results in <code>x86\win32\tst\8q.sbk</code>. It builds the executable program in <code>%BUILDDIR%\x86\win32\tst\8q.exe</code>, + runs it, and redirects the output to <code>%BUILDDIR%\x86\win32\tst\8q.1</code>, which it + compares with <code>x86\win32\tst\8q.1bk</code>. The output from this step is voluminous, + but there should be no differences and no errors.</p> + </li> + <li>Run the "triple" test, which compiles <code>rcc</code> with itself and + verifies the results:<blockquote> + <pre>C:\dist\lcc\4.1>nmake -f makefile.nt triple +... +\progra~1\lcc\4.1\bin\x86.c: + Assembling: C:/TEMP/lcc2001.asm + fc /b \progra~1\lcc\4.1\bin\1rcc.exe \progra~1\lcc\4.1\bin\2rcc.exe +Comparing files \progra~1\lcc\4.1\bin\1rcc.exe and \progra~1\lcc\4.1\bin\2RCC.EXE +00000088: B4 D5</pre> + </blockquote> + <p>This command builds <code>rcc</code> twice; once using the <code>rcc</code> built by VC + and again using the <code>rcc</code> built by <code>lcc</code>. The resulting binaries are + compared using <code>fc</code>. They should be identical, except for one or two bytes of + timestamp data, as shown at the end of the output above. If they aren't, our compiler is + generating incorrect code; <a HREF="#bugs">contact</a> us.</p> + </li> + <li>Copy <code>lcc.exe</code> and <code>bprint.exe</code> to a directory on your PATH, e.g.,<blockquote> + <pre>C:\dist\lcc\4.1>copy %BUILDDIR%\lcc.exe \bin + 1 file(s) copied. + +C:\dist\lcc\4.1>copy %BUILDDIR%\bprint.exe \bin + 1 file(s) copied.</pre> + </blockquote> + </li> + <li>Finally, clean up:<blockquote> + <pre>C:\dist\lcc\4.1>nmake -f makefile.nt clean</pre> + </blockquote> + <p>This command removes the derived files in <code>BUILDDIR</code>, but does not remove <code>rcc.exe</code>, + etc.; "<code>nmake -f makefile.nt clobber</code>" cleans up and removes all + executables and libraries. Test directories under <code>BUILDDIR</code> are <em>not</em> + removed; you'll need to remove these by hand, e.g.,</p> + <blockquote> + <pre>C:\dist\lcc\4.1>rmdir %BUILDDIR%\x86 /s +\progra~1\lcc\4.1\bin\x86, Are you sure (Y/N)? y</pre> + </blockquote> + </li> +</ol> + +<h2><a NAME="bugs">Reporting Bugs</a></h2> + +<p>lcc is a large, complex program. We find and repair errors routinely. If you think that +you've found a error, follow the steps below, which are adapted from the instructions in +Chapter 1 of <cite>A Retargetable C Compiler: Design and Implementation</cite>. + +<ol> + <li>If you don't have a source file that displays the error, create one. Most errors are + exposed when programmers try to compile a program they think is valid, so you probably + have a demonstration program already.</li> + <li>Preprocess the source file and capture the preprocessor output. Discard the original + code.</li> + <li>Prune your source code until it can be pruned no more without sending the error into + hiding. We prune most error demonstrations to fewer than five lines.</li> + <li>Confirm that the source file displays the error with the <em>distributed</em> version of + lcc. If you've changed lcc and the error appears only in your version, then you'll have to + chase the error yourself, even if it turns out to be our fault, because we can't work on + your code.</li> + <li>Annotate your code with comments that explain why you think that lcc is wrong. If lcc + dies with an assertion failure, please tell us where it died. If lcc crashes, please + report the last part of the call chain if you can. If lcc is rejecting a program you think + is valid, please tell us why you think it's valid, and include supporting page numbers in + the ANSI Standard, Appendix A in <cite>The C Programming Language</cite>, or the + appropriate section in <cite>C: A Reference Manual</cite>, 4th edition by S. B. Harbison + and G. L. Steele, Jr. (Prentice Hall, 1995). If lcc silently generates incorrect code for + some construct, please include the corrupt assembly code in the comments and flag the + incorrect instructions if you can.</li> + <li>Confirm that your error hasn't been fixed already. The latest version of lcc is always + available for anonymous <code>ftp</code> from <code>ftp.cs.princeton.edu</code> in <a + HREF="ftp://ftp.cs.princeton.edu/pub/lcc"><code>pub/lcc</code></a>. A <a + HREF="ftp://ftp.cs.princeton.edu/pub/lcc/README"><code>README</code></a> file there gives + acquistion details, and the <a HREF="../LOG"><code>LOG</code></a> file reports what errors + were fixed and when they were fixed. If you report a error that's been fixed, you might + get a canned reply.</li> + <li>Send your program by electronic mail to <code>lcc-bugs@cs.princeton.edu</code>. Please + send only valid C programs; put all remarks in C comments so that we can process reports + semiautomatically.</li> +</ol> + +<h2><a NAME="mailinglist">Keeping in Touch</a></h2> + +<p>There is an lcc mailing list for general information about lcc. To be added to the +list, send a message with the 1-line body</p> + +<blockquote> + <pre>subscribe lcc</pre> +</blockquote> + +<p>to <code>majordomo@cs.princeton.edu</code>. This line must appear in the message body; +"Subject:" lines are ignored. To learn more about mailing lists served by <code>majordomo</code>, +send a message with the 1-word body "<code>help</code>" to <code>majordomo@cs.princeton.edu</code>. +Mail sent to <code>lcc@cs.princeton.edu</code> is forwarded to everyone on the mailing +list.</p> + +<p>There is also an <code>lcc-bugs</code> mailing list for reporting bugs; subscribe to it +by sending a message with the 1-line body </p> + +<blockquote> + <pre>subscribe lcc-bugs</pre> +</blockquote> + +<p>to <code>majordomo@cs.princeton.edu</code>. Mail addressed to <var>lcc-bugs@cs.princeton.edu</var> +is forwarded to everyone on this list.</p> + +<hr> + +<address> + <a HREF="http://www.research.microsoft.com/~cwfraser/">Chris Fraser</a> / <a + HREF="mailto:cwfraser@microsoft.com">cwfraser@microsoft.com</a><br> + <a HREF="http://www.research.microsoft.com/~drh/">David Hanson</a> / <a + HREF="mailto:drh@microsoft.com">drh@microsoft.com</a><br> + $Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $ +</address> +</body> +</html> diff --git a/lcc/doc/lcc.1 b/lcc/doc/lcc.1 index 53c2cc5..fe91bca 100755 --- a/lcc/doc/lcc.1 +++ b/lcc/doc/lcc.1 @@ -1,605 +1,605 @@ -.\" $Id: lcc.1 145 2001-10-17 21:53:10Z timo $
-.TH LCC 1 "local \- $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $"
-.SH NAME
-lcc \- ANSI C compiler
-.SH SYNOPSIS
-.B lcc
-[
-.I option
-|
-.I file
-]...
-.br
-.SH DESCRIPTION
-.PP
-.I lcc
-is an ANSI C compiler for a variety of platforms.
-.PP
-Arguments whose names end with `.c' (plus `.C' under Windows) are taken to be
-C source programs; they are preprocessed, compiled, and
-each object program is left on the file
-whose name is that of the source with `.o' (UNIX) or `.obj' (Windows)
-substituted for the extension.
-Arguments whose names end with `.i' are treated similarly,
-except they are not preprocessed.
-In the same way,
-arguments ending with `.s' (plus `.S', `.asm', and `.ASM', under Windows)
-are taken to be assembly source programs
-and are assembled, producing an object file.
-If there are no arguments,
-.I lcc
-summarizes its options on the standard error.
-.PP
-.I lcc
-deletes an object file if and only if exactly one
-source file is mentioned and no other file
-(source, object, library) or
-.B \-l
-option is mentioned.
-.PP
-If the environment variable
-.B LCCINPUTS
-is set,
-.I lcc
-assumes it gives a semicolon- or colon-separated list of directories in which to
-look for source and object files whose names do not begin with `/'.
-These directories are also added to the list of directories
-searched for libraries.
-If
-.B LCCINPUTS
-is defined, it must contain `.' in order for the current directory
-to be searched for input files.
-.PP
-.I lcc
-uses ANSI standard header files (see `FILES' below).
-Include files not found in the ANSI header files
-are taken from the normal default include areas,
-which usually includes
-.BR /usr/include .
-Under Windows, if the environment variable
-.B include
-is defined, it gives a semicolon-separated list of directories in which to search for
-header files.
-.PP
-.I lcc
-interprets the following options; unrecognized options are
-taken as loader options (see
-.IR ld (1))
-unless
-.BR \-c ,
-.BR \-S ,
-or
-.B \-E
-precedes them.
-Except for
-.BR \-l ,
-all options are processed before any of the files
-and apply to all of the files.
-Applicable options are passed to each compilation phase in the order given.
-.TP
-.B \-c
-Suppress the loading phase of the compilation, and force
-an object file to be produced even if only one program is compiled.
-.TP
-.B \-g
-Produce additional symbol table information for the local debuggers.
-.I lcc
-warns when
-.B \-g
-is unsupported.
-.TP
-.BI \-Wf\-g n , x
-Set the debugging level to
-.I n
-and emit source code as comments into the generated assembly code;
-.I x
-must be the assembly language comment character.
-If
-.I n
-is omitted, it defaults to 1, which is similar to
-.BR \-g .
-Omitting
-.BI , x
-just sets the debugging level to
-.IR n .
-.TP
-.B \-w
-Suppress warning diagnostics, such as those
-announcing unreferenced statics, locals, and parameters.
-The line
-.I
-#pragma ref id
-simulates a reference to the variable
-.IR id .
-.TP
-.BI \-d n
-Generate jump tables for switches whose density is at least
-.IR n ,
-a floating point constant between zero and one.
-The default is 0.5.
-.TP
-.B \-A
-Warns about
-declarations and casts of function types without prototypes,
-assignments between pointers to ints and pointers to enums, and
-conversions from pointers to smaller integral types.
-A second
-.B \-A
-warns about
-unrecognized control lines,
-nonANSI language extensions and source characters in literals,
-unreferenced variables and static functions,
-declaring arrays of incomplete types,
-and exceeding
-.I some
-ANSI environmental limits, like more than 257 cases in switches.
-It also arranges for duplicate global definitions in separately compiled
-files to cause loader errors.
-.TP
-.B \-P
-Writes declarations for all defined globals on standard error.
-Function declarations include prototypes;
-editing this output can simplify conversion to ANSI C.
-This output may not correspond to the input when
-there are several typedefs for the same type.
-.TP
-.B \-n
-Arrange for the compiler to produce code
-that tests for dereferencing zero pointers.
-The code reports the offending file and line number and calls
-.IR abort (3).
-.TP
-.B \-O
-is ignored.
-.TP
-.B \-S
-Compile the named C programs, and leave the
-assembler-language output on corresponding files suffixed `.s' or `.asm'.
-.TP
-.B \-E
-Run only the preprocessor on the named C programs
-and unsuffixed file arguments,
-and send the result to the standard output.
-.TP
-.BI \-o " output"
-Name the output file
-.IR output .
-If
-.B \-c
-or
-.B \-S
-is specified and there is exactly one source file,
-this option names the object or assembly file, respectively.
-Otherwise, this option names the final executable
-file generated by the loader, and `a.out' (UNIX) or `a.exe' (Windows) is left undisturbed.
-.I lcc
-warns if
-.B \-o
-and
-.B \-c
-or
-.B \-S
-are given with more than one source file and ignores the
-.B \-o
-option.
-.TP
-.BI \-D name=def
-Define the
-.I name
-to the preprocessor, as if by `#define'.
-If
-.I =def
-is omitted, the name is defined as "1".
-.TP
-.BI \-U name
-Remove any initial definition of
-.IR name .
-.TP
-.BI \-I dir
-`#include' files
-whose names do not begin with `/' are always
-sought first in the directory of the
-.I file
-arguments, then in directories named in
-.B \-I
-options, then in directories on a standard list.
-.TP
-.B \-N
-Do not search
-.I any
-of the standard directories for `#include' files.
-Only those directories specified by subsequent explicit
-.B \-I
-options will be searched, in the order given.
-.TP
-.BI \-B str
-Use the compiler
-.BI "" str rcc
-instead of the default version.
-Note that
-.I str
-often requires a trailing slash.
-On Sparcs only,
-.B \-Bstatic
-and
-.BI \-Bdynamic
-are passed to the loader; see
-.IR ld (1).
-.TP
-.BI \-Wo\-lccdir= dir
-Find the preprocessor, compiler proper, and include directory
-in the directory
-.I dir/
-or
-.I
-dir\\.
-If the environment variable
-.B LCCDIR
-is defined, it gives this directory.
-.I lcc
-warns when this option is unsupported.
-.TP
-.B \-Wf-unsigned_char=1
-.br
-.ns
-.TP
-.B \-Wf-unsigned_char=0
-makes plain
-.B char
-an unsigned (1) or signed (0) type; by default,
-.B char
-is signed.
-.TP
-.B \-Wf\-wchar_t=unsigned_char
-.br
-.ns
-.TP
-.B \-Wf\-wchar_t=unsigned_short
-.br
-.ns
-.TP
-.B \-Wf\-wchar_t=unsigned_int
-Makes wide characters the type indicated; by default,
-wide characters are unsigned short ints, and
-.B wchar_t
-is a typedef for unsigned short defined in stddef.h.
-The definition for
-.B wchar_t
-in stddef.h must correspond to the type specified.
-.TP
-.B \-v
-Print commands as they are executed; some of the executed
-programs are directed to print their version numbers.
-More than one occurrence of
-.B \-v
-causes the commands to be printed, but
-.I not
-executed.
-.TP
-.BR \-help " or " \-?
-Print a message on the standard error summarizing
-.IR lcc 's
-options and giving the values of the environment variables
-.B LCCINPUTS
-and
-.BR LCCDIR ,
-if they are defined.
-Under Windows, the values of
-.B include
-and
-.B lib
-are also given, if they are defined.
-.TP
-.B \-b
-Produce code that counts the number of times each expression is executed.
-If loading takes place, arrange for a
-.B prof.out
-file to be written when the object program terminates.
-A listing annotated with execution counts can then be generated with
-.IR bprint (1).
-.I lcc
-warns when
-.B \-b
-is unsupported.
-.B \-Wf\-C
-is similar, but counts only the number of function calls.
-.TP
-.B \-p
-Produce code that counts the number of times each function is called.
-If loading takes place, replace the standard startup
-function by one that automatically calls
-.IR monitor (3)
-at the start and arranges to write a
-.B mon.out
-file when the object program terminates normally.
-An execution profile can then be generated with
-.IR prof (1).
-.I lcc
-warns when
-.B \-p
-is unsupported.
-.TP
-.B \-pg
-Causes the compiler to produce counting code like
-.BR \-p ,
-but invokes a run-time recording mechanism that keeps more
-extensive statistics and produces a
-.B gmon.out
-file at normal termination.
-Also, a profiling library is searched, in lieu of the standard C library.
-An execution profile can then be generated with
-.IR gprof (1).
-.I lcc
-warns when
-.B \-pg
-is unsupported.
-.TP
-.BI \-t name
-.br
-.ns
-.TP
-.BI \-t
-Produce code to print the name of the function, an activation number,
-and the name and value of each argument at function entry.
-At function exit, produce code to print
-the name of the function, the activation number, and the return value.
-By default,
-.I printf
-does the printing; if
-.I name
-appears, it does.
-For null
-.I char*
-values, "(null)" is printed.
-.BI \-target
-.I name
-is accepted, but ignored.
-.TP
-.BI \-tempdir= dir
-Store temporary files in the directory
-.I dir/
-or
-.I
-dir\\.
-The default is usually
-.BR /tmp .
-.TP
-.BI \-W xarg
-pass argument
-.I arg
-to the program indicated by
-.IR x ;
-.I x
-can be one of
-.BR p ,
-.BR f ,
-.BR a ,
-or
-.BR l ,
-which refer, respectively, to the preprocessor, the compiler proper,
-the assembler, and the loader.
-.I arg
-is passed as given; if a
-.B \-
-is expected, it must be given explicitly.
-.BI \-Wo arg
-specifies a system-specific option,
-.IR arg .
-.PP
-Other arguments
-are taken to be either loader option arguments, or C-compatible
-object programs, typically produced by an earlier
-.I lcc
-run, or perhaps libraries of C-compatible routines.
-Duplicate object files are ignored.
-These programs, together with the results of any
-compilations specified, are loaded (in the order
-given) to produce an executable program with name
-.BR a.out
-(UNIX) or
-.BR a.exe
-(Windows).
-.PP
-.I lcc
-assigns the most frequently referenced scalar parameters and
-locals to registers whenever possible.
-For each block,
-explicit register declarations are obeyed first;
-remaining registers are assigned to automatic locals if they
-are `referenced' at least 3 times.
-Each top-level occurrence of an identifier
-counts as 1 reference. Occurrences in a loop,
-either of the then/else arms of an if statement, or a case
-in a switch statement each count, respectively, as 10, 1/2, or 1/10 references.
-These values are adjusted accordingly for nested control structures.
-.B \-Wf\-a
-causes
-.I lcc
-to read a
-.B prof.out
-file from a previous execution and to use the data therein
-to compute reference counts (see
-.BR \-b ).
-.PP
-.I lcc
-is a cross compiler;
-.BI \-Wf\-target= target/os
-causes
-.I lcc
-to generate code for
-.I target
-running the operating system denoted by
-.IR os .
-The supported
-.I target/os
-combinations may include
-.PP
-.RS
-.ta \w'sparc/solarisxx'u
-.nf
-alpha/osf ALPHA, OSF 3.2
-mips/irix big-endian MIPS, IRIX 5.2
-mips/ultrix little-endian MIPS, ULTRIX 4.3
-sparc/solaris SPARC, Solaris 2.3
-x86/win32 x86, Windows NT 4.0/Windows 95/98
-x86/linux x86, Linux
-symbolic text rendition of the generated code
-null no output
-.fi
-.RE
-.PP
-For
-.BR \-Wf\-target=symbolic ,
-the option
-.B \-Wf-html
-causes the text rendition to be emitted as HTML.
-.B
-.SH LIMITATIONS
-.PP
-.I lcc
-accepts the C programming language
-as described in the ANSI standard.
-If
-.I lcc
-is used with the GNU C preprocessor, the
-.B \-Wp\-trigraphs
-option is required to enable trigraph sequences.
-.PP
-Plain int bit fields are signed.
-Bit fields are aligned like unsigned integers but are otherwise laid out
-as by most standard C compilers.
-Some compilers, such as the GNU C compiler,
-may choose other, incompatible layouts.
-.PP
-Likewise, calling conventions are intended to be compatible with
-the host C compiler,
-except possibly for passing and returning structures.
-Specifically,
-.I lcc
-passes and returns structures like host ANSI C compilers
-on most targets, but some older host C compilers use different conventions.
-Consequently, calls to/from such functions compiled with
-older C compilers may not work.
-Calling a function that returns
-a structure without declaring it as such violates
-the ANSI standard and may cause a fault.
-.SH FILES
-.PP
-The file names listed below are
-.IR typical ,
-but vary among installations; installation-dependent variants
-can be displayed by running
-.I lcc
-with the
-.B \-v
-option.
-.PP
-.RS
-.ta \w'$LCCDIR/liblcc.{a,lib}XX'u
-.nf
-file.{c,C} input file
-file.{s,asm} assembly-language file
-file.{o,obj} object file
-a.{out,exe} loaded output
-/tmp/lcc* temporary files
-$LCCDIR/cpp preprocessor
-$LCCDIR/rcc compiler
-$LCCDIR/liblcc.{a,lib} \fIlcc\fP-specific library
-/lib/crt0.o runtime startup (UNIX)
-/lib/[gm]crt0.o startups for profiling (UNIX)
-/lib/libc.a standard library (UNIX)
-$LCCDIR/include ANSI standard headers
-/usr/local/include local headers
-/usr/include traditional headers
-prof.out file produced for \fIbprint\fR(1)
-mon.out file produced for \fIprof\fR(1)
-gmon.out file produced for \fIgprof\fR(1)
-.fi
-.RE
-.PP
-.I lcc
-predefines the macro
-.B __LCC__
-on all systems.
-It may also predefine some installation-dependent symbols; option
-.B \-v
-exposes them.
-.SH "SEE ALSO"
-.PP
-C. W. Fraser and D. R. Hanson,
-.I A Retargetable C Compiler: Design and Implementation,
-Addison-Wesley, 1995. ISBN 0-8053-1670-1.
-.PP
-The World-Wide Web page at http://www.cs.princeton.edu/software/lcc/.
-.PP
-S. P. Harbison and G. L. Steele, Jr.,
-.I C: A Reference Manual,
-4th ed., Prentice-Hall, 1995.
-.PP
-B. W. Kernighan and D. M. Ritchie,
-.I The C Programming Language,
-2nd ed., Prentice-Hall, 1988.
-.PP
-American National Standards Inst.,
-.I American National Standard for Information Systems\(emProgramming
-.IR Language\(emC ,
-ANSI X3.159-1989, New York, 1990.
-.br
-.SH BUGS
-Mail bug reports along with the shortest preprocessed program
-that exposes them and the details reported by
-.IR lcc 's
-.B \-v
-option to lcc-bugs@princeton.edu. The WWW page at
-URL http://www.cs.princeton.edu/software/lcc/
-includes detailed instructions for reporting bugs.
-.PP
-The ANSI standard headers conform to the specifications in
-the Standard, which may be too restrictive for some applications,
-but necessary for portability.
-Functions given in the ANSI headers may be missing from
-some local C libraries (e.g., wide-character functions)
-or may not correspond exactly to the local versions;
-for example, the ANSI standard
-stdio.h
-specifies that
-.IR printf ,
-.IR fprintf ,
-and
-.I sprintf
-return the number of characters written to the file or array,
-but some existing libraries don't implement this convention.
-.PP
-On the MIPS and SPARC, old-style variadic functions must use
-varargs.h
-from MIPS or Sun. New-style is recommended.
-.PP
-With
-.BR \-b ,
-files compiled
-.I without
-.B \-b
-may cause
-.I bprint
-to print erroneous call graphs.
-For example, if
-.B f
-calls
-.B g
-calls
-.B h
-and
-.B f
-and
-.B h
-are compiled with
-.BR \-b ,
-but
-.B g
-is not,
-.B bprint
-will report that
-.B f
-called
-.BR h .
-The total number of calls is correct, however.
+.\" $Id: lcc.1 145 2001-10-17 21:53:10Z timo $ +.TH LCC 1 "local \- $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $" +.SH NAME +lcc \- ANSI C compiler +.SH SYNOPSIS +.B lcc +[ +.I option +| +.I file +]... +.br +.SH DESCRIPTION +.PP +.I lcc +is an ANSI C compiler for a variety of platforms. +.PP +Arguments whose names end with `.c' (plus `.C' under Windows) are taken to be +C source programs; they are preprocessed, compiled, and +each object program is left on the file +whose name is that of the source with `.o' (UNIX) or `.obj' (Windows) +substituted for the extension. +Arguments whose names end with `.i' are treated similarly, +except they are not preprocessed. +In the same way, +arguments ending with `.s' (plus `.S', `.asm', and `.ASM', under Windows) +are taken to be assembly source programs +and are assembled, producing an object file. +If there are no arguments, +.I lcc +summarizes its options on the standard error. +.PP +.I lcc +deletes an object file if and only if exactly one +source file is mentioned and no other file +(source, object, library) or +.B \-l +option is mentioned. +.PP +If the environment variable +.B LCCINPUTS +is set, +.I lcc +assumes it gives a semicolon- or colon-separated list of directories in which to +look for source and object files whose names do not begin with `/'. +These directories are also added to the list of directories +searched for libraries. +If +.B LCCINPUTS +is defined, it must contain `.' in order for the current directory +to be searched for input files. +.PP +.I lcc +uses ANSI standard header files (see `FILES' below). +Include files not found in the ANSI header files +are taken from the normal default include areas, +which usually includes +.BR /usr/include . +Under Windows, if the environment variable +.B include +is defined, it gives a semicolon-separated list of directories in which to search for +header files. +.PP +.I lcc +interprets the following options; unrecognized options are +taken as loader options (see +.IR ld (1)) +unless +.BR \-c , +.BR \-S , +or +.B \-E +precedes them. +Except for +.BR \-l , +all options are processed before any of the files +and apply to all of the files. +Applicable options are passed to each compilation phase in the order given. +.TP +.B \-c +Suppress the loading phase of the compilation, and force +an object file to be produced even if only one program is compiled. +.TP +.B \-g +Produce additional symbol table information for the local debuggers. +.I lcc +warns when +.B \-g +is unsupported. +.TP +.BI \-Wf\-g n , x +Set the debugging level to +.I n +and emit source code as comments into the generated assembly code; +.I x +must be the assembly language comment character. +If +.I n +is omitted, it defaults to 1, which is similar to +.BR \-g . +Omitting +.BI , x +just sets the debugging level to +.IR n . +.TP +.B \-w +Suppress warning diagnostics, such as those +announcing unreferenced statics, locals, and parameters. +The line +.I +#pragma ref id +simulates a reference to the variable +.IR id . +.TP +.BI \-d n +Generate jump tables for switches whose density is at least +.IR n , +a floating point constant between zero and one. +The default is 0.5. +.TP +.B \-A +Warns about +declarations and casts of function types without prototypes, +assignments between pointers to ints and pointers to enums, and +conversions from pointers to smaller integral types. +A second +.B \-A +warns about +unrecognized control lines, +nonANSI language extensions and source characters in literals, +unreferenced variables and static functions, +declaring arrays of incomplete types, +and exceeding +.I some +ANSI environmental limits, like more than 257 cases in switches. +It also arranges for duplicate global definitions in separately compiled +files to cause loader errors. +.TP +.B \-P +Writes declarations for all defined globals on standard error. +Function declarations include prototypes; +editing this output can simplify conversion to ANSI C. +This output may not correspond to the input when +there are several typedefs for the same type. +.TP +.B \-n +Arrange for the compiler to produce code +that tests for dereferencing zero pointers. +The code reports the offending file and line number and calls +.IR abort (3). +.TP +.B \-O +is ignored. +.TP +.B \-S +Compile the named C programs, and leave the +assembler-language output on corresponding files suffixed `.s' or `.asm'. +.TP +.B \-E +Run only the preprocessor on the named C programs +and unsuffixed file arguments, +and send the result to the standard output. +.TP +.BI \-o " output" +Name the output file +.IR output . +If +.B \-c +or +.B \-S +is specified and there is exactly one source file, +this option names the object or assembly file, respectively. +Otherwise, this option names the final executable +file generated by the loader, and `a.out' (UNIX) or `a.exe' (Windows) is left undisturbed. +.I lcc +warns if +.B \-o +and +.B \-c +or +.B \-S +are given with more than one source file and ignores the +.B \-o +option. +.TP +.BI \-D name=def +Define the +.I name +to the preprocessor, as if by `#define'. +If +.I =def +is omitted, the name is defined as "1". +.TP +.BI \-U name +Remove any initial definition of +.IR name . +.TP +.BI \-I dir +`#include' files +whose names do not begin with `/' are always +sought first in the directory of the +.I file +arguments, then in directories named in +.B \-I +options, then in directories on a standard list. +.TP +.B \-N +Do not search +.I any +of the standard directories for `#include' files. +Only those directories specified by subsequent explicit +.B \-I +options will be searched, in the order given. +.TP +.BI \-B str +Use the compiler +.BI "" str rcc +instead of the default version. +Note that +.I str +often requires a trailing slash. +On Sparcs only, +.B \-Bstatic +and +.BI \-Bdynamic +are passed to the loader; see +.IR ld (1). +.TP +.BI \-Wo\-lccdir= dir +Find the preprocessor, compiler proper, and include directory +in the directory +.I dir/ +or +.I +dir\\. +If the environment variable +.B LCCDIR +is defined, it gives this directory. +.I lcc +warns when this option is unsupported. +.TP +.B \-Wf-unsigned_char=1 +.br +.ns +.TP +.B \-Wf-unsigned_char=0 +makes plain +.B char +an unsigned (1) or signed (0) type; by default, +.B char +is signed. +.TP +.B \-Wf\-wchar_t=unsigned_char +.br +.ns +.TP +.B \-Wf\-wchar_t=unsigned_short +.br +.ns +.TP +.B \-Wf\-wchar_t=unsigned_int +Makes wide characters the type indicated; by default, +wide characters are unsigned short ints, and +.B wchar_t +is a typedef for unsigned short defined in stddef.h. +The definition for +.B wchar_t +in stddef.h must correspond to the type specified. +.TP +.B \-v +Print commands as they are executed; some of the executed +programs are directed to print their version numbers. +More than one occurrence of +.B \-v +causes the commands to be printed, but +.I not +executed. +.TP +.BR \-help " or " \-? +Print a message on the standard error summarizing +.IR lcc 's +options and giving the values of the environment variables +.B LCCINPUTS +and +.BR LCCDIR , +if they are defined. +Under Windows, the values of +.B include +and +.B lib +are also given, if they are defined. +.TP +.B \-b +Produce code that counts the number of times each expression is executed. +If loading takes place, arrange for a +.B prof.out +file to be written when the object program terminates. +A listing annotated with execution counts can then be generated with +.IR bprint (1). +.I lcc +warns when +.B \-b +is unsupported. +.B \-Wf\-C +is similar, but counts only the number of function calls. +.TP +.B \-p +Produce code that counts the number of times each function is called. +If loading takes place, replace the standard startup +function by one that automatically calls +.IR monitor (3) +at the start and arranges to write a +.B mon.out +file when the object program terminates normally. +An execution profile can then be generated with +.IR prof (1). +.I lcc +warns when +.B \-p +is unsupported. +.TP +.B \-pg +Causes the compiler to produce counting code like +.BR \-p , +but invokes a run-time recording mechanism that keeps more +extensive statistics and produces a +.B gmon.out +file at normal termination. +Also, a profiling library is searched, in lieu of the standard C library. +An execution profile can then be generated with +.IR gprof (1). +.I lcc +warns when +.B \-pg +is unsupported. +.TP +.BI \-t name +.br +.ns +.TP +.BI \-t +Produce code to print the name of the function, an activation number, +and the name and value of each argument at function entry. +At function exit, produce code to print +the name of the function, the activation number, and the return value. +By default, +.I printf +does the printing; if +.I name +appears, it does. +For null +.I char* +values, "(null)" is printed. +.BI \-target +.I name +is accepted, but ignored. +.TP +.BI \-tempdir= dir +Store temporary files in the directory +.I dir/ +or +.I +dir\\. +The default is usually +.BR /tmp . +.TP +.BI \-W xarg +pass argument +.I arg +to the program indicated by +.IR x ; +.I x +can be one of +.BR p , +.BR f , +.BR a , +or +.BR l , +which refer, respectively, to the preprocessor, the compiler proper, +the assembler, and the loader. +.I arg +is passed as given; if a +.B \- +is expected, it must be given explicitly. +.BI \-Wo arg +specifies a system-specific option, +.IR arg . +.PP +Other arguments +are taken to be either loader option arguments, or C-compatible +object programs, typically produced by an earlier +.I lcc +run, or perhaps libraries of C-compatible routines. +Duplicate object files are ignored. +These programs, together with the results of any +compilations specified, are loaded (in the order +given) to produce an executable program with name +.BR a.out +(UNIX) or +.BR a.exe +(Windows). +.PP +.I lcc +assigns the most frequently referenced scalar parameters and +locals to registers whenever possible. +For each block, +explicit register declarations are obeyed first; +remaining registers are assigned to automatic locals if they +are `referenced' at least 3 times. +Each top-level occurrence of an identifier +counts as 1 reference. Occurrences in a loop, +either of the then/else arms of an if statement, or a case +in a switch statement each count, respectively, as 10, 1/2, or 1/10 references. +These values are adjusted accordingly for nested control structures. +.B \-Wf\-a +causes +.I lcc +to read a +.B prof.out +file from a previous execution and to use the data therein +to compute reference counts (see +.BR \-b ). +.PP +.I lcc +is a cross compiler; +.BI \-Wf\-target= target/os +causes +.I lcc +to generate code for +.I target +running the operating system denoted by +.IR os . +The supported +.I target/os +combinations may include +.PP +.RS +.ta \w'sparc/solarisxx'u +.nf +alpha/osf ALPHA, OSF 3.2 +mips/irix big-endian MIPS, IRIX 5.2 +mips/ultrix little-endian MIPS, ULTRIX 4.3 +sparc/solaris SPARC, Solaris 2.3 +x86/win32 x86, Windows NT 4.0/Windows 95/98 +x86/linux x86, Linux +symbolic text rendition of the generated code +null no output +.fi +.RE +.PP +For +.BR \-Wf\-target=symbolic , +the option +.B \-Wf-html +causes the text rendition to be emitted as HTML. +.B +.SH LIMITATIONS +.PP +.I lcc +accepts the C programming language +as described in the ANSI standard. +If +.I lcc +is used with the GNU C preprocessor, the +.B \-Wp\-trigraphs +option is required to enable trigraph sequences. +.PP +Plain int bit fields are signed. +Bit fields are aligned like unsigned integers but are otherwise laid out +as by most standard C compilers. +Some compilers, such as the GNU C compiler, +may choose other, incompatible layouts. +.PP +Likewise, calling conventions are intended to be compatible with +the host C compiler, +except possibly for passing and returning structures. +Specifically, +.I lcc +passes and returns structures like host ANSI C compilers +on most targets, but some older host C compilers use different conventions. +Consequently, calls to/from such functions compiled with +older C compilers may not work. +Calling a function that returns +a structure without declaring it as such violates +the ANSI standard and may cause a fault. +.SH FILES +.PP +The file names listed below are +.IR typical , +but vary among installations; installation-dependent variants +can be displayed by running +.I lcc +with the +.B \-v +option. +.PP +.RS +.ta \w'$LCCDIR/liblcc.{a,lib}XX'u +.nf +file.{c,C} input file +file.{s,asm} assembly-language file +file.{o,obj} object file +a.{out,exe} loaded output +/tmp/lcc* temporary files +$LCCDIR/cpp preprocessor +$LCCDIR/rcc compiler +$LCCDIR/liblcc.{a,lib} \fIlcc\fP-specific library +/lib/crt0.o runtime startup (UNIX) +/lib/[gm]crt0.o startups for profiling (UNIX) +/lib/libc.a standard library (UNIX) +$LCCDIR/include ANSI standard headers +/usr/local/include local headers +/usr/include traditional headers +prof.out file produced for \fIbprint\fR(1) +mon.out file produced for \fIprof\fR(1) +gmon.out file produced for \fIgprof\fR(1) +.fi +.RE +.PP +.I lcc +predefines the macro +.B __LCC__ +on all systems. +It may also predefine some installation-dependent symbols; option +.B \-v +exposes them. +.SH "SEE ALSO" +.PP +C. W. Fraser and D. R. Hanson, +.I A Retargetable C Compiler: Design and Implementation, +Addison-Wesley, 1995. ISBN 0-8053-1670-1. +.PP +The World-Wide Web page at http://www.cs.princeton.edu/software/lcc/. +.PP +S. P. Harbison and G. L. Steele, Jr., +.I C: A Reference Manual, +4th ed., Prentice-Hall, 1995. +.PP +B. W. Kernighan and D. M. Ritchie, +.I The C Programming Language, +2nd ed., Prentice-Hall, 1988. +.PP +American National Standards Inst., +.I American National Standard for Information Systems\(emProgramming +.IR Language\(emC , +ANSI X3.159-1989, New York, 1990. +.br +.SH BUGS +Mail bug reports along with the shortest preprocessed program +that exposes them and the details reported by +.IR lcc 's +.B \-v +option to lcc-bugs@princeton.edu. The WWW page at +URL http://www.cs.princeton.edu/software/lcc/ +includes detailed instructions for reporting bugs. +.PP +The ANSI standard headers conform to the specifications in +the Standard, which may be too restrictive for some applications, +but necessary for portability. +Functions given in the ANSI headers may be missing from +some local C libraries (e.g., wide-character functions) +or may not correspond exactly to the local versions; +for example, the ANSI standard +stdio.h +specifies that +.IR printf , +.IR fprintf , +and +.I sprintf +return the number of characters written to the file or array, +but some existing libraries don't implement this convention. +.PP +On the MIPS and SPARC, old-style variadic functions must use +varargs.h +from MIPS or Sun. New-style is recommended. +.PP +With +.BR \-b , +files compiled +.I without +.B \-b +may cause +.I bprint +to print erroneous call graphs. +For example, if +.B f +calls +.B g +calls +.B h +and +.B f +and +.B h +are compiled with +.BR \-b , +but +.B g +is not, +.B bprint +will report that +.B f +called +.BR h . +The total number of calls is correct, however. |