Completely rewrote the website.
authordtrg <none@none>
Tue, 24 Apr 2007 23:46:59 +0000 (23:46 +0000)
committerdtrg <none@none>
Tue, 24 Apr 2007 23:46:59 +0000 (23:46 +0000)
199 files changed:
.project [new file with mode: 0644]
build [new file with mode: 0755]
dat/alert-big.png [new file with mode: 0644]
dat/lua-big.png [new file with mode: 0644]
dat/lua.gif [new file with mode: 0644]
src/about.i [new file with mode: 0644]
src/alert.png [new file with mode: 0644]
src/background.png [new file with mode: 0644]
src/contents.js [new file with mode: 0644]
src/contents.xml [new file with mode: 0644]
src/global.css [new file with mode: 0644]
src/global.js [new file with mode: 0644]
src/index-leaf.png [new file with mode: 0644]
src/index-parent.png [new file with mode: 0644]
src/index.i [new file with mode: 0644]
src/logo.png [new file with mode: 0644]
src/logo.svg [new file with mode: 0644]
src/lua.png [new file with mode: 0644]
src/olddocs.i [new file with mode: 0644]
src/olddocs/6500.html [new file with mode: 0644]
src/olddocs/6500.pdf [new file with mode: 0644]
src/olddocs/LLgen.html [new file with mode: 0644]
src/olddocs/LLgen.pdf [new file with mode: 0644]
src/olddocs/ack.html [new file with mode: 0644]
src/olddocs/ack.pdf [new file with mode: 0644]
src/olddocs/ansi_C.html [new file with mode: 0644]
src/olddocs/ansi_C.pdf [new file with mode: 0644]
src/olddocs/basic.html [new file with mode: 0644]
src/olddocs/basic.pdf [new file with mode: 0644]
src/olddocs/ceg.html [new file with mode: 0644]
src/olddocs/ceg.pdf [new file with mode: 0644]
src/olddocs/cg.html [new file with mode: 0644]
src/olddocs/cg.pdf [new file with mode: 0644]
src/olddocs/crefman.html [new file with mode: 0644]
src/olddocs/crefman.pdf [new file with mode: 0644]
src/olddocs/ego.html [new file with mode: 0644]
src/olddocs/ego.pdf [new file with mode: 0644]
src/olddocs/em.html [new file with mode: 0644]
src/olddocs/em.pdf [new file with mode: 0644]
src/olddocs/grohtml-100191.png [new file with mode: 0644]
src/olddocs/grohtml-100601.png [new file with mode: 0644]
src/olddocs/grohtml-100602.png [new file with mode: 0644]
src/olddocs/grohtml-101091.png [new file with mode: 0644]
src/olddocs/grohtml-101092.png [new file with mode: 0644]
src/olddocs/grohtml-101093.png [new file with mode: 0644]
src/olddocs/grohtml-101094.png [new file with mode: 0644]
src/olddocs/grohtml-101481.png [new file with mode: 0644]
src/olddocs/grohtml-101482.png [new file with mode: 0644]
src/olddocs/grohtml-101483.png [new file with mode: 0644]
src/olddocs/grohtml-101484.png [new file with mode: 0644]
src/olddocs/grohtml-101485.png [new file with mode: 0644]
src/olddocs/grohtml-101486.png [new file with mode: 0644]
src/olddocs/grohtml-101487.png [new file with mode: 0644]
src/olddocs/grohtml-101488.png [new file with mode: 0644]
src/olddocs/grohtml-101489.png [new file with mode: 0644]
src/olddocs/grohtml-102111.png [new file with mode: 0644]
src/olddocs/grohtml-102411.png [new file with mode: 0644]
src/olddocs/grohtml-102412.png [new file with mode: 0644]
src/olddocs/grohtml-102413.png [new file with mode: 0644]
src/olddocs/grohtml-102721.png [new file with mode: 0644]
src/olddocs/grohtml-1027210.png [new file with mode: 0644]
src/olddocs/grohtml-1027211.png [new file with mode: 0644]
src/olddocs/grohtml-1027212.png [new file with mode: 0644]
src/olddocs/grohtml-1027213.png [new file with mode: 0644]
src/olddocs/grohtml-1027214.png [new file with mode: 0644]
src/olddocs/grohtml-1027215.png [new file with mode: 0644]
src/olddocs/grohtml-1027216.png [new file with mode: 0644]
src/olddocs/grohtml-1027217.png [new file with mode: 0644]
src/olddocs/grohtml-1027218.png [new file with mode: 0644]
src/olddocs/grohtml-1027219.png [new file with mode: 0644]
src/olddocs/grohtml-102722.png [new file with mode: 0644]
src/olddocs/grohtml-1027220.png [new file with mode: 0644]
src/olddocs/grohtml-1027221.png [new file with mode: 0644]
src/olddocs/grohtml-1027222.png [new file with mode: 0644]
src/olddocs/grohtml-1027223.png [new file with mode: 0644]
src/olddocs/grohtml-1027224.png [new file with mode: 0644]
src/olddocs/grohtml-1027225.png [new file with mode: 0644]
src/olddocs/grohtml-1027226.png [new file with mode: 0644]
src/olddocs/grohtml-1027227.png [new file with mode: 0644]
src/olddocs/grohtml-1027228.png [new file with mode: 0644]
src/olddocs/grohtml-1027229.png [new file with mode: 0644]
src/olddocs/grohtml-102723.png [new file with mode: 0644]
src/olddocs/grohtml-1027230.png [new file with mode: 0644]
src/olddocs/grohtml-1027231.png [new file with mode: 0644]
src/olddocs/grohtml-1027232.png [new file with mode: 0644]
src/olddocs/grohtml-1027233.png [new file with mode: 0644]
src/olddocs/grohtml-1027234.png [new file with mode: 0644]
src/olddocs/grohtml-1027235.png [new file with mode: 0644]
src/olddocs/grohtml-1027236.png [new file with mode: 0644]
src/olddocs/grohtml-1027237.png [new file with mode: 0644]
src/olddocs/grohtml-1027238.png [new file with mode: 0644]
src/olddocs/grohtml-1027239.png [new file with mode: 0644]
src/olddocs/grohtml-102724.png [new file with mode: 0644]
src/olddocs/grohtml-102725.png [new file with mode: 0644]
src/olddocs/grohtml-102726.png [new file with mode: 0644]
src/olddocs/grohtml-102727.png [new file with mode: 0644]
src/olddocs/grohtml-102728.png [new file with mode: 0644]
src/olddocs/grohtml-102729.png [new file with mode: 0644]
src/olddocs/grohtml-105631.png [new file with mode: 0644]
src/olddocs/grohtml-105632.png [new file with mode: 0644]
src/olddocs/grohtml-105633.png [new file with mode: 0644]
src/olddocs/grohtml-105634.png [new file with mode: 0644]
src/olddocs/grohtml-106061.png [new file with mode: 0644]
src/olddocs/grohtml-106062.png [new file with mode: 0644]
src/olddocs/grohtml-106063.png [new file with mode: 0644]
src/olddocs/grohtml-106064.png [new file with mode: 0644]
src/olddocs/grohtml-106561.png [new file with mode: 0644]
src/olddocs/grohtml-1065610.png [new file with mode: 0644]
src/olddocs/grohtml-1065611.png [new file with mode: 0644]
src/olddocs/grohtml-1065612.png [new file with mode: 0644]
src/olddocs/grohtml-1065613.png [new file with mode: 0644]
src/olddocs/grohtml-1065614.png [new file with mode: 0644]
src/olddocs/grohtml-106562.png [new file with mode: 0644]
src/olddocs/grohtml-106563.png [new file with mode: 0644]
src/olddocs/grohtml-106565.png [new file with mode: 0644]
src/olddocs/grohtml-106566.png [new file with mode: 0644]
src/olddocs/grohtml-106567.png [new file with mode: 0644]
src/olddocs/grohtml-106568.png [new file with mode: 0644]
src/olddocs/grohtml-106569.png [new file with mode: 0644]
src/olddocs/grohtml-107771.png [new file with mode: 0644]
src/olddocs/grohtml-107772.png [new file with mode: 0644]
src/olddocs/grohtml-107773.png [new file with mode: 0644]
src/olddocs/grohtml-96851.png [new file with mode: 0644]
src/olddocs/grohtml-96852.png [new file with mode: 0644]
src/olddocs/grohtml-96853.png [new file with mode: 0644]
src/olddocs/grohtml-96854.png [new file with mode: 0644]
src/olddocs/grohtml-96855.png [new file with mode: 0644]
src/olddocs/grohtml-96856.png [new file with mode: 0644]
src/olddocs/grohtml-96857.png [new file with mode: 0644]
src/olddocs/grohtml-97441.png [new file with mode: 0644]
src/olddocs/grohtml-974410.png [new file with mode: 0644]
src/olddocs/grohtml-974411.png [new file with mode: 0644]
src/olddocs/grohtml-974412.png [new file with mode: 0644]
src/olddocs/grohtml-974413.png [new file with mode: 0644]
src/olddocs/grohtml-974414.png [new file with mode: 0644]
src/olddocs/grohtml-974415.png [new file with mode: 0644]
src/olddocs/grohtml-974416.png [new file with mode: 0644]
src/olddocs/grohtml-974418.png [new file with mode: 0644]
src/olddocs/grohtml-974419.png [new file with mode: 0644]
src/olddocs/grohtml-97442.png [new file with mode: 0644]
src/olddocs/grohtml-974420.png [new file with mode: 0644]
src/olddocs/grohtml-97443.png [new file with mode: 0644]
src/olddocs/grohtml-97444.png [new file with mode: 0644]
src/olddocs/grohtml-97445.png [new file with mode: 0644]
src/olddocs/grohtml-97446.png [new file with mode: 0644]
src/olddocs/grohtml-97447.png [new file with mode: 0644]
src/olddocs/grohtml-97448.png [new file with mode: 0644]
src/olddocs/grohtml-97449.png [new file with mode: 0644]
src/olddocs/grohtml-99071.png [new file with mode: 0644]
src/olddocs/grohtml-99261.png [new file with mode: 0644]
src/olddocs/grohtml-99451.png [new file with mode: 0644]
src/olddocs/grohtml-99452.png [new file with mode: 0644]
src/olddocs/grohtml-99453.png [new file with mode: 0644]
src/olddocs/grohtml-99454.png [new file with mode: 0644]
src/olddocs/grohtml-99455.png [new file with mode: 0644]
src/olddocs/grohtml-99456.png [new file with mode: 0644]
src/olddocs/grohtml-99457.png [new file with mode: 0644]
src/olddocs/i80.html [new file with mode: 0644]
src/olddocs/i80.pdf [new file with mode: 0644]
src/olddocs/install.html [new file with mode: 0644]
src/olddocs/install.pdf [new file with mode: 0644]
src/olddocs/int.html [new file with mode: 0644]
src/olddocs/int.pdf [new file with mode: 0644]
src/olddocs/lint.html [new file with mode: 0644]
src/olddocs/lint.pdf [new file with mode: 0644]
src/olddocs/m2ref.html [new file with mode: 0644]
src/olddocs/m2ref.pdf [new file with mode: 0644]
src/olddocs/m68020.html [new file with mode: 0644]
src/olddocs/m68020.pdf [new file with mode: 0644]
src/olddocs/ncg.html [new file with mode: 0644]
src/olddocs/ncg.pdf [new file with mode: 0644]
src/olddocs/nopt.html [new file with mode: 0644]
src/olddocs/nopt.pdf [new file with mode: 0644]
src/olddocs/occam.html [new file with mode: 0644]
src/olddocs/occam.pdf [new file with mode: 0644]
src/olddocs/pascal.html [new file with mode: 0644]
src/olddocs/pascal.pdf [new file with mode: 0644]
src/olddocs/pcref.html [new file with mode: 0644]
src/olddocs/pcref.pdf [new file with mode: 0644]
src/olddocs/peep.html [new file with mode: 0644]
src/olddocs/peep.pdf [new file with mode: 0644]
src/olddocs/regadd.html [new file with mode: 0644]
src/olddocs/regadd.pdf [new file with mode: 0644]
src/olddocs/sparc.html [new file with mode: 0644]
src/olddocs/sparc.pdf [new file with mode: 0644]
src/olddocs/toolkit.html [new file with mode: 0644]
src/olddocs/toolkit.pdf [new file with mode: 0644]
src/olddocs/top.html [new file with mode: 0644]
src/olddocs/top.pdf [new file with mode: 0644]
src/olddocs/v7bugs.html [new file with mode: 0644]
src/olddocs/v7bugs.pdf [new file with mode: 0644]
src/olddocs/val.html [new file with mode: 0644]
src/olddocs/val.pdf [new file with mode: 0644]
src/olddocs/z80.html [new file with mode: 0644]
src/olddocs/z80.pdf [new file with mode: 0644]
testbuild [new file with mode: 0755]
tpl/_contents.xslt [new file with mode: 0644]
tpl/_htmlx.xslt [new file with mode: 0644]
tpl/standard.xslt [new file with mode: 0644]

diff --git a/.project b/.project
new file mode 100644 (file)
index 0000000..4a63a4e
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>ack-website</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+       </buildSpec>
+       <natures>
+       </natures>
+</projectDescription>
diff --git a/build b/build
new file mode 100755 (executable)
index 0000000..ef759bd
--- /dev/null
+++ b/build
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+SRC="$1"
+DST="$2"
+DESTURL="$3"
+
+extensionmap() {
+       case "$1" in
+               i) echo html;;
+               *) echo $1;;
+       esac
+}
+
+rebuild() {
+       mkdir -p `dirname $2`
+       case "$3" in
+               i)
+                       # echo xsltproc --novalid --stringparam THIS $(echo $4 | sed -e 's/^\.\///') --stringparam SRC "$SRC" --stringparam DESTURL "$DESTURL" tpl/standard.xslt "$1"
+                       xsltproc --novalid --stringparam THIS $(echo $4 | sed -e 's/^\.\///') --stringparam SRC "$SRC" --stringparam DESTURL "$DESTURL" tpl/standard.xslt "$1" > "$2"
+                       #sabcmd tpl/standard.xslt $1 "\$SRC=$SRC" "\$DESTURL=$DESTURL" > $2
+                       #xalan -xsl tpl/standard.xslt -in $1 -out $2
+                       ;;
+                       
+               *)
+                       cp $1 $2
+                       ;;
+       esac
+       
+       if [ $? != 0 ]; then
+               echo "Command failed"
+               rm -f $2
+               exit 1
+       fi
+}
+
+inputs=$(cd src && find -wholename "*/.*" -prune -o -type f -print)
+
+for f in $inputs; do
+       srcextension=${f##*.}
+       destextension=`extensionmap $srcextension`
+       extensionless=${f%.*}
+       source=$SRC/$f
+       dest=$DST/$extensionless.$destextension
+
+       echo $f
+       rebuild $source $dest $srcextension $f
+done
diff --git a/dat/alert-big.png b/dat/alert-big.png
new file mode 100644 (file)
index 0000000..50f653e
Binary files /dev/null and b/dat/alert-big.png differ
diff --git a/dat/lua-big.png b/dat/lua-big.png
new file mode 100644 (file)
index 0000000..2300c3c
Binary files /dev/null and b/dat/lua-big.png differ
diff --git a/dat/lua.gif b/dat/lua.gif
new file mode 100644 (file)
index 0000000..15abee4
Binary files /dev/null and b/dat/lua.gif differ
diff --git a/src/about.i b/src/about.i
new file mode 100644 (file)
index 0000000..2bf6403
--- /dev/null
@@ -0,0 +1,262 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+  <title>About the ACK</title>
+</head>
+
+<body>
+<h1>What is it?</h1>
+
+<p>The Amsterdam Compiler Kit is a venerable piece of software that dates
+back to the early 1980s. It was originally written by <a
+href="http://www.cs.vu.nl/%7East">Andrew Tanenbaum</a> and <a
+href="http://www.cs.vu.nl/%7Eceriel">Ceriel Jacobs</a> as a commercial
+product; for many years it was also used as Minix' native toolchain. After
+eventually failing as a commercial project, it was made open source under a
+BSD license in 2003 when it looked like it was going to be abandoned and the
+code lost.</p>
+
+<p>The ACK contains compilers for ANSI C, K&amp;R C, Pascal, Modula-2, Occam
+1, and a primitive Basic. It contains code generators for a large number of
+architectures, mostly 8 and 16 bit machines; there are also a set of generic
+optimisation, linker and librarian tools. Each language comes with its own
+runtime, so if you're a C programmer you also get a libc. Compared to gcc, it
+is far smaller, faster and easier to port.</p>
+
+<p>This project currently hosts two versions of the ACK.</p>
+<ul>
+  <li>ACK 5.6 is an incremental update of Vrije University's last release.
+    This has had minimum fixes necessary to make it run on modern Linux
+    machines; unfortunately, the build system is designed for the Unixes of
+    yesteryear and is not really up to modern standards. This version is the
+    most complete, but is probably not particularly useful as very few of the
+    platforms it targets exist any more. This version is provided for
+    reference and archival purposes and to provide a backup if the 6.0
+    release should fail.</li>
+  <li>ACK 6.0 is a ground-up reworking of the whole compiler suite, with a
+    lot of the more archaic features removed. It is intended to produce a
+    modern compiler toolchain with which actually useful work can be done,
+    and is where all the new development happens. Currently, not all of 5.6's
+    features have been ported, but those that have work considerably more
+    reliably.</li>
+</ul>
+
+<h1>What architectures does it support?</h1>
+
+<p>The following architectures are supported.</p>
+
+<table border="0">
+  <tbody>
+    <tr>
+      <th></th>
+      <th>5.6</th>
+      <th>6.0</th>
+    </tr>
+    <tr>
+      <td>6500</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>6800</td>
+      <td>-</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>6805</td>
+      <td>-</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>6809</td>
+      <td>-</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>ARM</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>i80</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>Z80</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>Z8000</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>i86</td>
+      <td>+</td>
+      <td>+</td>
+    </tr>
+    <tr>
+      <td>i386</td>
+      <td>+</td>
+      <td>+</td>
+    </tr>
+    <tr>
+      <td>68000</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>68020</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>NS32016</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>s2650</td>
+      <td>-</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>SPARC</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>VAX4</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>PDP11</td>
+      <td>+</td>
+      <td></td>
+    </tr>
+  </tbody>
+</table>
+
+<p>+ indicates that the particular architecture is supported by the code
+generator and assembler; - indicates that it is supported by the assembler
+only.</p>
+
+<p>Note: all the code generators <em>run</em> on 6.0, but as there are no
+platforms yet that use them they are not currently shipped. If you wish to
+use one, please ask and it can very easily be arranged. (Due to the way the
+ACK works, it is not really possible to produce code targeted at a particular
+architecture without also targeting it at a platform.)</p>
+
+<h1>What platforms does it support?</h1>
+
+<p>For 5.6:</p>
+
+<table border="0">
+  <tbody>
+    <tr>
+      <td>6500</td>
+      <td>BBC Microcomputer</td>
+    </tr>
+    <tr>
+      <td>ARM</td>
+      <td>Acorn Archimedes</td>
+    </tr>
+    <tr>
+      <td>i80</td>
+      <td>Hermac, Nascom</td>
+    </tr>
+    <tr>
+      <td>Z80</td>
+      <td>Hermac, Nascom, limited CP/M</td>
+    </tr>
+    <tr>
+      <td>Z8000</td>
+      <td>(board)</td>
+    </tr>
+    <tr>
+      <td>i86</td>
+      <td>PC/IX</td>
+    </tr>
+    <tr>
+      <td>i386</td>
+      <td>Xenix v3, Xenix SysV</td>
+    </tr>
+    <tr>
+      <td>68000</td>
+      <td>16 bit: MinixST; 32-bit: SunOS, Mantra, PMDS</td>
+    </tr>
+    <tr>
+      <td>68020</td>
+      <td>SysV</td>
+    </tr>
+    <tr>
+      <td>NS32016</td>
+      <td>(board)</td>
+    </tr>
+    <tr>
+      <td>SPARC</td>
+      <td>Solaris, SunOS</td>
+    </tr>
+    <tr>
+      <td>VAX4</td>
+      <td>BSD4.2</td>
+    </tr>
+    <tr>
+      <td>PDP11</td>
+      <td>UNIX v7</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>"(board)" signifies that the port was done to a bare development board
+with no operating system other than a monitor.</p>
+
+<p>For 6.0:</p>
+
+<table border="0">
+  <tbody>
+    <tr>
+      <td>i86</td>
+      <td>pc86 (bootable floppy disk images)</td>
+    </tr>
+    <tr>
+      <td>i386</td>
+      <td>linux386 (ELF Linux executables)</td>
+    </tr>
+  </tbody>
+</table>
+
+<h1>Haven't I seen this before somewhere?</h1>
+
+<p>Quite likely. The ACK has been used as the standard Minix compiler for
+years. While the ACK was still commercial, this was done by distributing
+binaries; when it get opened, a version was forked off and is now used as
+part of the Minix base build. You can find <a
+href="https://gforge.cs.vu.nl/plugins/scmsvn/viewcvs.php/trunk/bigports/ackpack/?root=minix">Minix's
+version here</a>. This is an extremely stripped down variant that supports
+only the Minix platform on the i386 and i86 architectures and was done by <a
+href="http://www.laurasia.com.au/ack">Michael Kennett</a>.</p>
+
+<p>In addition, the original 5.5 release is still available on <a
+href="http://www.cs.vu.nl/ack/">the Vrije University ACK page</a>.</p>
+
+<p>There may also be other versions elsewhere. The ACK is BSD licensed and as
+a result if people want to fork the codebase and use it elsewhere, they don't
+even need to ask, or indeed tell anyone. If you know of any other uses of the
+compiler, please let me (dtrg) know --- I'd like to put in a link.</p>
+
+<h1>What's the involvement of Andrew Tanenbaum, Ceriel Jacobs and Vrije
+University?</h1>
+
+<p>They have no official involvement.</p>
+
+<p>They're aware that I, dtrg, am doing this, and are quite happy with it and
+maintain an interest, but are not actively participating in the project. (Due
+to being busy people with other things to do.) I, dtrg, have nothing to do
+with Vrije University and have never even been to Holland.</p>
+</body>
+</html>
diff --git a/src/alert.png b/src/alert.png
new file mode 100644 (file)
index 0000000..bd32352
Binary files /dev/null and b/src/alert.png differ
diff --git a/src/background.png b/src/background.png
new file mode 100644 (file)
index 0000000..5dc9236
Binary files /dev/null and b/src/background.png differ
diff --git a/src/contents.js b/src/contents.js
new file mode 100644 (file)
index 0000000..08dd1bf
--- /dev/null
@@ -0,0 +1,9 @@
+/* Executed immediately after outputting the table of contents; ensures
+ * that it's shown or hidden as appropriate. */
+
+if (window.showTocToggle)
+{
+       var tocShowText = "show";
+       var tocHideText = "hide";
+       showTocToggle();
+} 
diff --git a/src/contents.xml b/src/contents.xml
new file mode 100644 (file)
index 0000000..309f896
--- /dev/null
@@ -0,0 +1,4 @@
+<page src="index.i">
+       <page src="about.i"/>
+       <page src="olddocs.i"/>
+</page>
diff --git a/src/global.css b/src/global.css
new file mode 100644 (file)
index 0000000..859f05b
--- /dev/null
@@ -0,0 +1,260 @@
+body
+{
+       font-family: "Bitstream Vera Sans", sans-serif;
+       color: #000;
+       background: #ddd url(background.png) no-repeat scroll top left;
+       margin: 0;
+       padding: 0;
+}
+
+div.nav
+{
+       float: left;
+       clear: left;
+       width: 9em;
+       margin: 0.5em;
+}
+
+div.nav-logo
+{
+       text-align: center;
+}
+
+div.nav-related h4, div.nav-children h4
+{
+       text-align: center;
+       font-size: 60%;
+       border-bottom: 1px solid #000;
+}
+
+div.nav-related ul, div.nav-children ul
+{
+       font-size: 60%;
+       padding: 0;
+}
+
+div.nav-related li, div.nav-children li
+{
+       list-style-type: none;
+       text-align: center;
+       padding: 0.2em 0 0.2em 0; 
+}
+
+div.nav-related .selected, div.nav-children .selected
+{
+       background: #eee;
+}
+
+div.nav-icons
+{
+       text-align: center;
+}
+
+div.nav-icons img
+{
+       border: 0;
+}
+
+div.page-path
+{
+       margin: 0 0 0 10em;
+}
+
+div.page-path > p
+{
+       font-size: 60%;
+}
+
+div.navigation-block
+{
+       margin: 0 1em 0 0;
+}
+
+div.navigation-block table
+{
+       width: 100%;
+       font-size: 60%;
+}
+
+.navigation-left
+{
+       text-align: left;
+}
+
+.navigation-right
+{
+       text-align: right;
+}
+
+div.page-body
+{
+       border: 1px solid #000;
+       margin: 0 1em 0 10em;
+       padding: 1em 0 1em 1em;
+       background: #fff;
+}
+
+div.page-body > p, div.page-body > ul, div.page-body > ol
+{
+       line-height: 150%;
+}
+
+div.page-body > ul li, div.page-body > ol li
+{
+       margin: 0.3em 0 0.3em 0;
+}
+
+div.body-copyright
+{
+       font-size: 60%;
+}
+
+.top-maintitle > h1
+{
+       font-size: large;
+       margin: 0;
+}
+
+.body-contents
+{
+       font-size: 60%;
+       border: 1px solid black;
+       padding: 0 0.5em 0 0.5em;
+       margin: 0 1em 0 0;
+       line-height: 1.2em;
+       color: #7d7d7d;
+       width: 50%;
+}
+
+.body-contents h4
+{
+       margin: 0.5em 0 0.5em 0;
+}
+
+div.body > div.path
+{
+       font-size: smaller;
+       font-weight: bold;
+       margin-top: 2em;
+}
+
+div.body > h1.title
+{
+       text-align: left;
+       font-size: large;
+       padding-bottom: 0.75em;
+       margin-bottom: 1.5em;
+       border-bottom: 1px solid #000;
+}
+
+div.bottom
+{
+       clear: both;
+}
+
+.boxed
+{
+       border: 1px solid #000;
+       background: #fff;
+       padding: 0.5em;
+}
+
+div.boxed > h4
+{
+       font-size: 100%;
+       text-align: center;
+       margin-bottom: 0.5em;
+       padding-bottom: 0.5em;
+       border-bottom: 1px solid #000;
+}
+
+.center
+{
+       text-align: center;
+}
+
+h1 { font-size: 120%; }
+h2 { font-size: 100%; }
+h3 { font-size: 100%; }
+h4 { font-size: 100%; }
+
+div.toclist > div
+{
+       padding-left: 9px;
+       text-indent: -9px;
+}
+
+div.toclist > div.parent:before { content: url(index-parent.png); }
+div.toclist > div.parent { background: #fee; }
+div.toclist > div.child:before { content: url(index-leaf.png); }
+div.toclist a.selected { font-weight: bold; }
+
+ol.toclist { margin-left: 10px; padding-left: 10px; }
+ol.toclist > li { list-style-position: outside; padding-top: 0.5ex; }
+
+hr
+{
+       display: block;
+       border: 1px inset black;
+       width: 1em;
+       height: 1em;
+       margin-top: 2em;
+       margin-bottom: 2em;
+}
+
+pre, tt
+{
+       font-family: monospace;
+}
+
+pre
+{
+       font-size: smaller;
+       border: 1px solid #000;
+       background: #eee;
+       padding: 1em;
+       margin: 1em;
+}
+
+blockquote.warning, blockquote.lua
+{
+       border: 1px solid #000;
+       padding: 0em 1em 0em 60px;
+       margin: 1em 1em 1em 2em;
+       background-repeat: no-repeat;
+       background-position: 16px 16px;
+       min-height: 64px;
+}
+
+blockquote.warning
+{
+       background-color: #fdd;
+       background-image: url('alert.png');
+}
+
+blockquote.lua
+{
+       background-color: #ddf;
+       background-image: url('lua.png');
+}
+
+div.page-body > table
+{
+       border-collapse: collapse;
+       border-style: hidden;
+       margin: 0 3em 0 3em;
+       font-size: 80%;
+}
+
+div.page-body > table td, div.page-body > table th
+{
+       text-align: left;
+       border: 1px solid #ccc;
+       /* border-bottom: 1px solid #ccc; */
+       padding: 0.5em 0.6em 0.5em 0.6em;
+}
+
+table.dl td.dl-left
+{
+       /* border-right: 1px solid #ccc; */
+}
diff --git a/src/global.js b/src/global.js
new file mode 100644 (file)
index 0000000..f29cfa4
--- /dev/null
@@ -0,0 +1,61 @@
+/* Stolen wholesale from Wikipedia */
+
+function showTocToggle()
+{
+       if (document.createTextNode)
+       {
+               /* Uses DOM calls to avoid document.write + XHTML issues */
+
+               var linkHolder = document.getElementById('toctitle')
+               if (!linkHolder)
+                       return;
+
+               var outerSpan = document.createElement('span');
+               outerSpan.className = 'toctoggle';
+
+               var toggleLink = document.createElement('a');
+               toggleLink.id = 'togglelink';
+               toggleLink.className = 'internal';
+               toggleLink.href = 'javascript:toggleToc()';
+               toggleLink.appendChild(document.createTextNode(tocShowText));
+
+               outerSpan.appendChild(document.createTextNode('['));
+               outerSpan.appendChild(toggleLink);
+               outerSpan.appendChild(document.createTextNode(']'));
+
+               linkHolder.appendChild(document.createTextNode(' '));
+               linkHolder.appendChild(outerSpan);
+
+               var cookiePos = document.cookie.indexOf("hidetoc=");
+               if ((cookiePos == -1) || (document.cookie.charAt(cookiePos + 8) == 0))
+                       toggleToc();
+       }
+}
+
+function changeText(el, newText)
+{
+       /* Safari work around */
+       if (el.innerText)
+               el.innerText = newText;
+       else if (el.firstChild && el.firstChild.nodeValue)
+               el.firstChild.nodeValue = newText;
+}
+
+function toggleToc()
+{
+       var toc = document.getElementById('toc').getElementsByTagName('ol')[0];
+       var toggleLink = document.getElementById('togglelink')
+
+       if (toc && toggleLink && toc.style.display == 'none')
+       {
+               changeText(toggleLink, tocHideText);
+               toc.style.display = 'block';
+               document.cookie = "hidetoc=0";
+       }
+       else
+       {
+               changeText(toggleLink, tocShowText);
+               toc.style.display = 'none';
+               document.cookie = "hidetoc=1";
+       }
+}
diff --git a/src/index-leaf.png b/src/index-leaf.png
new file mode 100644 (file)
index 0000000..07a81c1
Binary files /dev/null and b/src/index-leaf.png differ
diff --git a/src/index-parent.png b/src/index-parent.png
new file mode 100644 (file)
index 0000000..bf78057
Binary files /dev/null and b/src/index-parent.png differ
diff --git a/src/index.i b/src/index.i
new file mode 100644 (file)
index 0000000..91d6195
--- /dev/null
@@ -0,0 +1,147 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+  <title>The Amsterdam Compiler Kit</title>
+</head>
+
+<body>
+<h1>Introduction</h1>
+
+<p>The Amsterdam Compiler Kit is a cross-platform compiler and toolchain
+suite that is small, portable, extremely fast, and extremely flexible. It
+targets a number of low-end machines including the Z80, 8086 and 80386, but
+there are many other code generators available. It supports several
+languages, including ANSI C, Pascal and Modula-2, and contains integrated
+runtime libraries including a libc.</p>
+
+<p>The ACK runs on Unix systems; most development happens on Linux.</p>
+
+<p>For more information, see the <a href="about.html">About the ACK</a>
+page.</p>
+
+<h1>Getting it</h1>
+
+<p>You can download any release of the ACK from the <a
+href="http://sourceforge.net/project/showfiles.php?group_id=130811">Sourceforge
+download site</a>. Installation instructions are provided in the source
+package.</p>
+
+<h1>Documentation</h1>
+
+<p>Some fairly heavy maintenance is currently being done on the ACK, which
+means the documentation is not in very good shape. Most of the documentation
+is in the form of man pages, which are supplied with the source; however, a
+number of <a href="olddocs.html">rather old white papers</a> are also
+available, that may give some insight as to the design and architecture of
+the system.</p>
+
+<p>If you have queries, your best bit is probably to <a
+href="http://sourceforge.net/mail/?group_id=130811">join the mailing
+list</a>.</p>
+
+<h1>News</h1>
+
+<h2>2007-04-25</h2>
+
+<p>I'm pleased to announce 6.0pre2 has just hit the <a
+href="http://sourceforge.net/project/showfiles.php?group_id=130811">download
+page</a>. i386 Linux binaries now have limited support.</p>
+
+<p>This version has some substantial internal changes to simplify things all
+round. Syscalls are no longer routed through libmon and are considerably
+simpler and more lightweight to implement and use. The K&amp;R C compiler has
+been removed, as it does nothing that the ANSI C compiler doesn't do better.
+The built-in libc has been heavily ANSIfied and trimmed back to remove a lot
+of the ancient Unixisms.</p>
+
+<p>The distribution size is now under a megabyte.</p>
+
+<h2>2007-02-25</h2>
+
+<p>Finally, <i>finally</i>, after several years work, we finally have an
+initial release of the ACK 6.0! </p>
+
+<p>This is a preview release, and is extremely limited. It supports on
+platform, which will generate PC bootable floppy disk images containing 8086
+machine code. However, it does support ANSI C, K&amp;R C, Pascal, Modula-2,
+Basic and Occam, and should form a good basis for evaluation and further
+development. Let me know what you think. </p>
+
+<p>This is known to build cleanly on Ubuntu Edgy Linux and OpenBSD 4.0, both
+on i386. However, it hasn't had a lot of testing otherwise; Sourceforge have
+shut down their compile farm service, and I don't have access to many
+machines. Bug reports are extremely welcome. </p>
+
+<p>You can get it <a
+href="http://sourceforge.net/project/showfiles.php?group_id=130811">get it
+from the Sourceforge download page</a>. </p>
+
+<p>(Note that the ACK 5.6, using the old build mechanism, still remains
+available for those that wish to use it; it's in the 6.0pre1 download area as
+a previous version.) </p>
+
+<h2>2006-02-04</h2>
+
+<p>LLgen has just been released as a seperate package!</p>
+
+<p>LLgen is a LL(1) parser generator, quite similar to yacc or bison, that
+can generate recursive descent parsers from Extended Context-Free grammars
+(which makes it quite a bit more useful than yacc or bison). The ACK uses it
+extensively, but as it's a standalone component, I've decided that it would
+be useful to distribute this separately. LLgen's input files are almost
+identical to yacc's, so if you can use yacc and have been getting frustrated
+with its limitations, LLgen is for you.</p>
+
+<p>I've rewritten the build system and overhauled the source so it compiles
+cleanly with gcc; it should work fine on modern systems (and extremely
+quickly). The package contains full documentation, and LLgen is, like the
+ACK, licensed under the new-style BSD license.</p>
+
+<p>You can <a
+href="http://sourceforge.net/project/showfiles.php?group_id=130811">get it
+from the Sourceforge download page</a> right next to the ACK.</p>
+
+<h2>2005-06-25</h2>
+
+<p>We make our first release!</p>
+
+<p>Version 5.6 of the ACK has now hit Sourceforge and is <a
+href="http://sourceforge.net/project/showfiles.php?group_id=130811">ready to
+download</a>. This version has been tweaked and fiddled with until it
+compiles, very nearly cleanly, on Linux systems (all that were available for
+testing): it should work without too much hassle on most other platforms.
+This release contains full documentation, all the front ends, all the back
+ends, all the libraries, and all the binary conversion tools, and should
+actually be useful. Don't forget to <a
+href="http://sourceforge.net/mail/?group_id=130811">join the mailing list</a>
+if you want to use it! </p>
+
+<h2>2005-06-10</h2>
+
+<p>CVS repository goes live!</p>
+
+<p>After great efforts by Ceriel Jacobs, to which I am extremely grateful, we
+now have a complete copy of the original development repository. The original
+distribution mechanism doesn't quite work on modern machines, but I'm working
+on it, and in the meantime it makes fascinating browsing --- I believe we may
+now have some of the oldest timestamps on SourceForge. (Several of the files
+were last touched in 1985!)</p>
+
+<p>For casual perusal it's probably simplest <a
+href="http://cvs.sourceforge.net/viewcvs.py/tack/Ack/">to use CVSWeb</a>.
+Alternatively, check out the <tt>Ack</tt> module --- full instructions on the
+<a href="http://sourceforge.net/cvs/?group_id=130811">project CVS page</a>.
+</p>
+
+<h2>2005-02-14</h2>
+
+<p>Initial version of this web page set up.</p>
+
+<h2>2005-02-11</h2>
+
+<p>Converted the troff documentation into (dodgy) HTML and PDF files; see the
+documentation section for the list. The man pages haven't been converted yet,
+but at least the main documentation is available. </p>
+</body>
+</html>
diff --git a/src/logo.png b/src/logo.png
new file mode 100644 (file)
index 0000000..fd52804
Binary files /dev/null and b/src/logo.png differ
diff --git a/src/logo.svg b/src/logo.svg
new file mode 100644 (file)
index 0000000..48a0f85
--- /dev/null
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="64"
+   height="64"
+   id="svg1307"
+   sodipodi:version="0.32"
+   inkscape:version="0.45"
+   version="1.0"
+   sodipodi:docbase="/media/pyanfar-dg/shared/projects/ack-website/src"
+   sodipodi:docname="logo.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="TRUE">
+  <defs
+     id="defs1309">
+    <linearGradient
+       id="linearGradient5731">
+      <stop
+         style="stop-color:#7c7c7c;stop-opacity:1;"
+         offset="0"
+         id="stop5733" />
+      <stop
+         style="stop-color:#dddddd;stop-opacity:1;"
+         offset="1"
+         id="stop5735" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3072">
+      <stop
+         style="stop-color:#2420df;stop-opacity:1;"
+         offset="0"
+         id="stop3074" />
+      <stop
+         style="stop-color:#bcbbff;stop-opacity:1;"
+         offset="1"
+         id="stop3076" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3062">
+      <stop
+         style="stop-color:#002aff;stop-opacity:1;"
+         offset="0"
+         id="stop3064" />
+      <stop
+         id="stop3070"
+         offset="0.93023258"
+         style="stop-color:#002aff;stop-opacity:0.68627451;" />
+      <stop
+         style="stop-color:#002aff;stop-opacity:1;"
+         offset="1"
+         id="stop3066" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3054">
+      <stop
+         style="stop-color:#494949;stop-opacity:1;"
+         offset="0"
+         id="stop3056" />
+      <stop
+         style="stop-color:#6c6c6c;stop-opacity:1;"
+         offset="1"
+         id="stop3058" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5731"
+       id="linearGradient5737"
+       x1="0"
+       y1="88"
+       x2="28"
+       y2="116"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3054"
+       id="linearGradient2192"
+       gradientUnits="userSpaceOnUse"
+       x1="0"
+       y1="31.998454"
+       x2="64"
+       y2="31.998454"
+       gradientTransform="translate(-72,77.108438)" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.8906248"
+     inkscape:cx="103.44558"
+     inkscape:cy="24.871764"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:document-units="px"
+     inkscape:grid-bbox="true"
+     gridempspacing="8"
+     inkscape:grid-points="true"
+     inkscape:window-width="1337"
+     inkscape:window-height="852"
+     inkscape:window-x="33"
+     inkscape:window-y="0" />
+  <metadata
+     id="metadata1312">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer">
+    <text
+       xml:space="preserve"
+       style="font-size:15.04876995px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="9.457902"
+       y="16.515696"
+       id="text4836"
+       transform="scale(1.2540644,0.7974072)"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/media/pyanfar-dg/shared/projects/ack-website/src/logo.png"
+       inkscape:export-xdpi="180"
+       inkscape:export-ydpi="180"><tspan
+         sodipodi:role="line"
+         id="tspan4838"
+         x="9.457902"
+         y="16.515696"
+         style="font-size:15.04877186px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">THE</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:10.35101986px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="0.16414653"
+       y="21.650045"
+       id="text2200"
+       transform="scale(0.8625852,1.1593058)"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/media/pyanfar-dg/shared/projects/ack-website/src/logo.png"
+       inkscape:export-xdpi="180"
+       inkscape:export-ydpi="180"><tspan
+         sodipodi:role="line"
+         id="tspan2202"
+         x="0.16414653"
+         y="21.650045"
+         style="font-size:10.35102081px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">AMSTERDAM</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:11.6014576px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="-0.57780707"
+       y="35.59359"
+       id="text2204"
+       transform="scale(0.9667883,1.0343526)"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/media/pyanfar-dg/shared/projects/ack-website/src/logo.png"
+       inkscape:export-xdpi="180"
+       inkscape:export-ydpi="180"><tspan
+         sodipodi:role="line"
+         id="tspan2206"
+         x="-0.57780707"
+         y="35.59359"
+         style="font-size:11.6014595px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">COMPILER</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:15.04876995px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="11.09284"
+       y="60.43684"
+       id="text2208"
+       transform="scale(1.2540644,0.7974072)"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/media/pyanfar-dg/shared/projects/ack-website/src/logo.png"
+       inkscape:export-xdpi="180"
+       inkscape:export-ydpi="180"><tspan
+         sodipodi:role="line"
+         id="tspan2210"
+         x="11.09284"
+         y="60.43684"
+         style="font-size:15.04877186px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">KIT</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:8.11069965px;font-style:normal;font-weight:normal;line-height:125%;fill:#d40000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;opacity:0.61"
+       x="7.677043"
+       y="45.350349"
+       id="text2212"
+       transform="matrix(0.8170005,-0.6929092,0.6012273,0.7140805,0,0)"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/media/pyanfar-dg/shared/projects/ack-website/src/logo.png"
+       inkscape:export-xdpi="180"
+       inkscape:export-ydpi="180"><tspan
+         sodipodi:role="line"
+         id="tspan2214"
+         x="7.6770423"
+         y="45.350349"
+         style="font-size:8.11069965px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#d40000;font-family:Bitstream Vera Sans">PLACEHOLDER</tspan><tspan
+         sodipodi:role="line"
+         x="7.6770439"
+         y="55.488724"
+         style="font-size:8.11069965px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#d40000;font-family:Bitstream Vera Sans"
+         id="tspan2216">GRAPHIC</tspan></text>
+  </g>
+</svg>
diff --git a/src/lua.png b/src/lua.png
new file mode 100644 (file)
index 0000000..9417dae
Binary files /dev/null and b/src/lua.png differ
diff --git a/src/olddocs.i b/src/olddocs.i
new file mode 100644 (file)
index 0000000..55d6099
--- /dev/null
@@ -0,0 +1,188 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+  <title>White Papers</title>
+</head>
+
+<body>
+<h1>White Papers</h1>
+
+<p>These documents are all white papers that came with the full 5.5 release
+and have varying degrees of relevance to the 6.0 release. These are converted
+automatically into HTML and PDF from the original troff source files, and so
+the quality is not always the greatest. However, there should be enough here
+to give some insight into how the ACK works. </p>
+
+<table class="grid" border="0" cellpadding="2" cellspacing="2">
+    <tr>
+      <td>6500</td>
+      <td><a href="olddocs/6500.html">html</a></td>
+      <td><a href="olddocs/6500.pdf">pdf</a></td>
+      <td>the MOS 6500 code generator</td>
+    </tr>
+    <tr>
+      <td>LLgen</td>
+      <td><a href="olddocs/LLgen.html">html</a></td>
+      <td><a href="olddocs/LLgen.pdf">pdf</a></td>
+      <td>the LL(1) parser generator</td>
+    </tr>
+    <tr>
+      <td>ack</td>
+      <td><a href="olddocs/ack.html">html</a></td>
+      <td><a href="olddocs/ack.pdf">pdf</a></td>
+      <td>the description files used to drive the compiler front-end</td>
+    </tr>
+    <tr>
+      <td>ansi_C</td>
+      <td><a href="olddocs/ansi_C.html">html</a></td>
+      <td><a href="olddocs/ansi_C.pdf">pdf</a></td>
+      <td>the ANSI C compiler</td>
+    </tr>
+    <tr>
+      <td>basic</td>
+      <td><a href="olddocs/basic.html">html</a></td>
+      <td><a href="olddocs/basic.pdf">pdf</a></td>
+      <td>the BASIC compiler</td>
+    </tr>
+    <tr>
+      <td>ceg</td>
+      <td><a href="olddocs/ceg.html">html</a></td>
+      <td><a href="olddocs/ceg.pdf">pdf</a></td>
+      <td>the fast code generator</td>
+    </tr>
+    <tr>
+      <td>cg</td>
+      <td><a href="olddocs/cg.html">html</a></td>
+      <td><a href="olddocs/cg.pdf">pdf</a></td>
+      <td>the old code generator</td>
+    </tr>
+    <tr>
+      <td>crefman</td>
+      <td><a href="olddocs/crefman.html">html</a></td>
+      <td><a href="olddocs/crefman.pdf">pdf</a></td>
+      <td>the K&amp;R C compiler</td>
+    </tr>
+    <tr>
+      <td>ego</td>
+      <td><a href="olddocs/ego.html">html</a></td>
+      <td><a href="olddocs/ego.pdf">pdf</a></td>
+      <td>the EM optimiser</td>
+    </tr>
+    <tr>
+      <td>em</td>
+      <td><a href="olddocs/em.html">html</a></td>
+      <td><a href="olddocs/em.pdf">pdf</a></td>
+      <td>the EM intermediate code format &amp; virtual machine</td>
+    </tr>
+    <tr>
+      <td>i80</td>
+      <td><a href="olddocs/i80.html">html</a></td>
+      <td><a href="olddocs/i80.pdf">pdf</a></td>
+      <td>the Intel i80 code generator</td>
+    </tr>
+    <tr>
+      <td>install</td>
+      <td><a href="olddocs/install.html">html</a></td>
+      <td><a href="olddocs/install.pdf">pdf</a></td>
+      <td>installation instructions</td>
+    </tr>
+    <tr>
+      <td>int</td>
+      <td><a href="olddocs/int.html">html</a></td>
+      <td><a href="olddocs/int.pdf">pdf</a></td>
+      <td>the EM interpreter</td>
+    </tr>
+    <tr>
+      <td>lint</td>
+      <td><a href="olddocs/lint.html">html</a></td>
+      <td><a href="olddocs/lint.pdf">pdf</a></td>
+      <td>the off-line C program checker</td>
+    </tr>
+    <tr>
+      <td>m2ref</td>
+      <td><a href="olddocs/m2ref.html">html</a></td>
+      <td><a href="olddocs/m2ref.pdf">pdf</a></td>
+      <td>the Modula-2 compiler</td>
+    </tr>
+    <tr>
+      <td>m68020</td>
+      <td><a href="olddocs/m68020.html">html</a></td>
+      <td><a href="olddocs/m68020.pdf">pdf</a></td>
+      <td>the Motorola 68000-series code generator</td>
+    </tr>
+    <tr>
+      <td>ncg</td>
+      <td><a href="olddocs/ncg.html">html</a></td>
+      <td><a href="olddocs/ncg.pdf">pdf</a></td>
+      <td>the new code generator</td>
+    </tr>
+    <tr>
+      <td>nopt</td>
+      <td><a href="olddocs/nopt.html">html</a></td>
+      <td><a href="olddocs/nopt.pdf">pdf</a></td>
+      <td>the new peephole optimiser</td>
+    </tr>
+    <tr>
+      <td>occam</td>
+      <td><a href="olddocs/occam.html">html</a></td>
+      <td><a href="olddocs/occam.pdf">pdf</a></td>
+      <td>the Occam compiler</td>
+    </tr>
+    <tr>
+      <td>pascal</td>
+      <td><a href="olddocs/pascal.html">html</a></td>
+      <td><a href="olddocs/pascal.pdf">pdf</a></td>
+      <td>the Pascal compiler implementation</td>
+    </tr>
+    <tr>
+      <td>pcref</td>
+      <td><a href="olddocs/pcref.html">html</a></td>
+      <td><a href="olddocs/pcref.pdf">pdf</a></td>
+      <td>the Pascal compiler user reference</td>
+    </tr>
+    <tr>
+      <td>peep</td>
+      <td><a href="olddocs/peep.html">html</a></td>
+      <td><a href="olddocs/peep.pdf">pdf</a></td>
+      <td>the old peephole optimiser</td>
+    </tr>
+    <tr>
+      <td>regadd</td>
+      <td><a href="olddocs/regadd.html">html</a></td>
+      <td><a href="olddocs/regadd.pdf">pdf</a></td>
+      <td>report on adding support for register variables</td>
+    </tr>
+    <tr>
+      <td>toolkit</td>
+      <td><a href="olddocs/toolkit.html">html</a></td>
+      <td><a href="olddocs/toolkit.pdf">pdf</a></td>
+      <td>high-level overview</td>
+    </tr>
+    <tr>
+      <td>top</td>
+      <td><a href="olddocs/top.html">html</a></td>
+      <td><a href="olddocs/top.pdf">pdf</a></td>
+      <td>native assembly level optimiser</td>
+    </tr>
+    <tr>
+      <td>v7bugs</td>
+      <td><a href="olddocs/v7bugs.html">html</a></td>
+      <td><a href="olddocs/v7bugs.pdf">pdf</a></td>
+      <td>a list of bugs found in V7 Unix</td>
+    </tr>
+    <tr>
+      <td>val</td>
+      <td><a href="olddocs/val.html">html</a></td>
+      <td><a href="olddocs/val.pdf">pdf</a></td>
+      <td>Pascal validation suite report</td>
+    </tr>
+    <tr>
+      <td>z80</td>
+      <td><a href="olddocs/z80.html">html</a></td>
+      <td><a href="olddocs/z80.pdf">pdf</a></td>
+      <td>the Zilog Z80 code generator</td>
+    </tr>
+</table>
+</body>
+</html>
diff --git a/src/olddocs/6500.html b/src/olddocs/6500.html
new file mode 100644 (file)
index 0000000..5473ebd
--- /dev/null
@@ -0,0 +1,2168 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:16 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>A backend table for the 6500 microprocessor</title>
+</head>
+<body>
+
+<h1 align=center>A backend table for the 6500 microprocessor</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The MOS Technology MCS6500">2. The MOS Technology MCS6500</a><br>
+<a href="#3. The MCS6500 CPU programmable registers">3. The MCS6500 CPU programmable registers</a><br>
+<a href="#3.1. The accumulator A.">3.1. The accumulator A.</a><br>
+<a href="#3.2. The index register X.">3.2. The index register X.</a><br>
+<a href="#3.3. The index register Y.">3.3. The index register Y.</a><br>
+<a href="#3.4. The program counter PC">3.4. The program counter PC</a><br>
+<a href="#3.5. The stack pointer SP">3.5. The stack pointer SP</a><br>
+<a href="#3.6. The status register">3.6. The status register</a><br>
+<a href="#4. The MCS6500 memory layout.">4. The MCS6500 memory layout.</a><br>
+<a href="#4.1. Top page.">4.1. Top page.</a><br>
+<a href="#4.2. Zero page.">4.2. Zero page.</a><br>
+<a href="#4.3. The stack.">4.3. The stack.</a><br>
+<a href="#5. The memory adressing modes">5. The memory adressing modes</a><br>
+<a href="#5.1. direct addressing.">5.1. direct addressing.</a><br>
+<a href="#5.2. Base page, indexed addressing.">5.2. Base page, indexed addressing.</a><br>
+<a href="#5.3. Absolute indexed addressing.">5.3. Absolute indexed addressing.</a><br>
+<a href="#5.4. Indirect addressing.">5.4. Indirect addressing.</a><br>
+<a href="#5.4.1. Pre-indexed indirect addressing.">5.4.1. Pre-indexed indirect addressing.</a><br>
+<a href="#5.4.2. Post-indexed indirect addressing.">5.4.2. Post-indexed indirect addressing.</a><br>
+<a href="#6. What the CPU has and doesn&rsquo;t has.">6. What the CPU has and doesn&rsquo;t has.</a><br>
+<a href="#1. Description of the machine table.">1. Description of the machine table.</a><br>
+<a href="#1.1. Macro definitions.">1.1. Macro definitions.</a><br>
+<a href="#1.2. Constant definitions.">1.2. Constant definitions.</a><br>
+<a href="#2. Register definitions.">2. Register definitions.</a><br>
+<a href="#2.1. Token definitions">2.1. Token definitions</a><br>
+<a href="#2.2. Token expression definitions.">2.2. Token expression definitions.</a><br>
+<a href="#2.3. Code rules.">2.3. Code rules.</a><br>
+<a href="#2.3.1. The EM pattern.">2.3.1. The EM pattern.</a><br>
+<a href="#2.3.2. The stack pattern.">2.3.2. The stack pattern.</a><br>
+<a href="#2.3.3. The code part.">2.3.3. The code part.</a><br>
+<a href="#2.3.3.1. Stack cleanup.">2.3.3.1. Stack cleanup.</a><br>
+<a href="#2.3.3.2. Register allocation.">2.3.3.2. Register allocation.</a><br>
+<a href="#2.3.3.3. Code to be generated.">2.3.3.3. Code to be generated.</a><br>
+<a href="#2.3.4. stack replacement.">2.3.4. stack replacement.</a><br>
+<a href="#2.3.5. EM replacement.">2.3.5. EM replacement.</a><br>
+<a href="#2.3.6. Move definitions.">2.3.6. Move definitions.</a><br>
+<a href="#2.3.7. Test definitions.">2.3.7. Test definitions.</a><br>
+<a href="#2.3.8. Stack definitions.">2.3.8. Stack definitions.</a><br>
+<a href="#3. Some remarks.">3. Some remarks.</a><br>
+<a href="#1. Introduction.">1. Introduction.</a><br>
+<a href="#2. The instructions.">2. The instructions.</a><br>
+<a href="#2.1. The load instructions.">2.1. The load instructions.</a><br>
+<a href="#2.1.1. The lol instruction with indirect offsetting.">2.1.1. The lol instruction with indirect offsetting.</a><br>
+<a href="#2.1.2. The lol instruction whose offset is to big.">2.1.2. The lol instruction whose offset is to big.</a><br>
+<a href="#2.2. The store instructions.">2.2. The store instructions.</a><br>
+<a href="#2.2.1. The stl instruction with indirect offsetting.">2.2.1. The stl instruction with indirect offsetting.</a><br>
+<a href="#2.2.2. The stl instruction whose offset is to big.">2.2.2. The stl instruction whose offset is to big.</a><br>
+<a href="#2.3. Integer arithmetic instructions.">2.3. Integer arithmetic instructions.</a><br>
+<a href="#2.3.1. The adi instruction.">2.3.1. The adi instruction.</a><br>
+<a href="#2.3.2. The mli instruction.">2.3.2. The mli instruction.</a><br>
+<a href="#2.4. The unsgned arithmetic instructions.">2.4. The unsgned arithmetic instructions.</a><br>
+<a href="#2.4.1. Unsigned addition.">2.4.1. Unsigned addition.</a><br>
+<a href="#2.5. Floating point arithmetic.">2.5. Floating point arithmetic.</a><br>
+<a href="#2.6. Pointer arithmetic instructions.">2.6. Pointer arithmetic instructions.</a><br>
+<a href="#2.7. Increment, decrement and zero instructions.">2.7. Increment, decrement and zero instructions.</a><br>
+<a href="#2.8. Convert instructions.">2.8. Convert instructions.</a><br>
+<a href="#2.8.1. The in line conversion.">2.8.1. The in line conversion.</a><br>
+<a href="#2.9. Logical instructions.">2.9. Logical instructions.</a><br>
+<a href="#2.9.1. The logical and on 2-byte groups.">2.9.1. The logical and on 2-byte groups.</a><br>
+<a href="#2.10. Set manipulation instructions.">2.10. Set manipulation instructions.</a><br>
+<a href="#2.11. Array instructions.">2.11. Array instructions.</a><br>
+<a href="#2.12. Compare instructions.">2.12. Compare instructions.</a><br>
+<a href="#2.13. Branch instructions.">2.13. Branch instructions.</a><br>
+<a href="#2.14. Procedure call instructions.">2.14. Procedure call instructions.</a><br>
+<a href="#2.15. Miscellaneous instructions.">2.15. Miscellaneous instructions.</a><br>
+<a href="#1. Introduction.">1. Introduction.</a><br>
+<a href="#1. Testing Pascal statements.">1. Testing Pascal statements.</a><br>
+<a href="#2. The results.">2. The results.</a><br>
+<a href="#3. Pascal statements which don&rsquo;t have a C equivalent.">3. Pascal statements which don&rsquo;t have a C equivalent.</a><br>
+<a href="#4. Length tests.">4. Length tests.</a><br>
+<a href="#1. Summary">1. Summary</a><br>
+<a href="#1. REFERENCES.">1. REFERENCES.</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Jan van Dalen</i></p>
+
+<p>The backend table is part of the Amsterdam Compiler Kit
+(ACK). It translates the intermediate language family EM to
+a machine code for the MCS6500 microprocessor family.</p>
+
+<p align=center><b>THE MCS6500 MICROPROCESSOR.</b></p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>Why a back end table for the MCS6500 microprocessor
+family. Although the MCS6500 microprocessor family has an
+simple instruction set and internal structure, it is used in
+a variety of microcomputers and homecomputers. This is
+because of is low cost. As an example the Apple II, a well
+known and width spread microprocessor, uses the MCS6502 CPU.
+Also the BBC homecomputer, whose popularity is growing day
+by day uses the MCS6502 CPU. The BBC homecomputer is based
+on the MCS6502 CPU although better and stronger
+microprocessors are available. The designers of Acorn
+computer Industries have probably choosen for the MCS6502
+because of the amount of software available for this CPU.
+Since its width spreaded use, a variaty of software will be
+needed for it. One can think of games!!, administration
+programs, teaching programs, basic interpreters and other
+application programs. Even do it will not be possible to run
+the total compiler kit on a MCS6500 based computer, it is
+possible to write application programs in a high level
+language, such as Pascal or C on a minicomputer. These
+application programs can be tested and compiled on that
+minicomputer and put in a ROM (Read Only Memory), for
+example, cso that it an be executed by a MCS6500 CPU. The
+strategy of writing testprograms on a minicomputer, compile
+it and then execute it on a MCS6500 based microprocessor is
+used by the development of the back end. The minicomputer
+used is M68000 based one, manufactured by Bleasdale Computer
+Systems Ltd.. The micro- or homecomputer used is a BBC
+microcomputer, manufactured by Acorn Computer Ltd..</p>
+<a name="2. The MOS Technology MCS6500"></a>
+<h2>2. The MOS Technology MCS6500</h2>
+
+<p>The MCS6500 is as a family of CPU devices developed by
+MOS Technology [1]. The members of the MCS6500 family are
+the same chips in a different housing. The MCS6502, the big
+brother in the family, can handle 64k bytes of memory, while
+for example the MCS6504 can only handle 8k bytes of memory.
+This difference is due to the fact that the MCS6502 is in a
+40 pins house and the MCS6504 has a 28 pins house, so less
+address lines are available.</p>
+<a name="3. The MCS6500 CPU programmable registers"></a>
+<h2>3. The MCS6500 CPU programmable registers</h2>
+
+<p>The MCS6500 series is based on the same chip so all have
+the same programmable registers.</p>
+<a name="3.1. The accumulator A."></a>
+<h2>3.1. The accumulator A.</h2>
+
+<p>The accumulator A is the only register on which the
+arithmetic and logical instructions can be used. For
+example, the instruction ADC (add with carry) adds the
+contents of the accumulator A and a byte from memory or
+data.</p>
+<a name="3.2. The index register X."></a>
+<h2>3.2. The index register X.</h2>
+
+<p>As the name suggests this register can be used for some
+indirect addressing modes. The modes are explaned below.</p>
+<a name="3.3. The index register Y."></a>
+<h2>3.3. The index register Y.</h2>
+
+<p>This register is, just as the index register X, used for
+certain indirect addressing modes. These addressing modes
+are different from the modes which use index register X.</p>
+<a name="3.4. The program counter PC"></a>
+<h2>3.4. The program counter PC</h2>
+
+<p>This is the only 16-bit register available. It is used
+to point to the next instruction to be carried out.</p>
+<a name="3.5. The stack pointer SP"></a>
+<h2>3.5. The stack pointer SP</h2>
+
+<p>The stack pointer is an 8-bit register, so the stack can
+contain at most 256 bytes. The CPU always appends 00000001
+as highbyte of any stack address, which means that memory
+locations <b>0100</b> through <b>01FF</b> are permanently
+assigned to the stack.</p>
+<a name="3.6. The status register"></a>
+<h2>3.6. The status register</h2>
+
+<p>The status register maintains six status flags and a
+master interrupt control bit.<br>
+These are the six status flags: Carry (c) Zero (z) Overflow
+(o) Sign (n) Decimal mode (d) Break (b)</p>
+
+<p>The bit (i) is the master interrupt control bit.</p>
+<a name="4. The MCS6500 memory layout."></a>
+<h2>4. The MCS6500 memory layout.</h2>
+
+<p>In the MCS6500 memory space three area&rsquo;s have
+special meaning. These area&rsquo;s are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="6%"></td>
+<td width="18%">
+
+<p>Top page.</p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>Zero page.</p>
+</td>
+<td width="69%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3)</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>The stack.</p>
+</td>
+<td width="69%">
+</td>
+</table>
+
+<p>MCS6500 memory is divided up into pages. These pages
+consist 256 bytes. So in a memory address the highbyte
+denotes the page number and the lowbyte the offset within
+the page.</p>
+<a name="4.1. Top page."></a>
+<h2>4.1. Top page.</h2>
+
+<p>When a MCS6500 is restared it jumps indirect via memory
+address <b>FFFC.</b> At <b>FFFC</b> (lowbyte) and
+<b>FFFD</b> (highbyte) there must be the address of the
+bootstrap subroutine. When a break instruction (BRK) occurs
+or an interrupt takes place, the MCS6500 jumps indirect
+through memory address <b>FFFE. FFFE</b> and <b>FFFF</b>
+thus, must contain the address of the interrupt routine. The
+former only goes for maskeble interrupt. There also exist a
+nonmaskeble interrupt. This cause the MCS6500 to jump
+indirect through memory address <b>FFFA.</b> So the top six
+bytes of memory are used by the operating system and
+therefore not available for the back end.</p>
+<a name="4.2. Zero page."></a>
+<h2>4.2. Zero page.</h2>
+
+<p>This page has a special meaning in the sence that
+addressing this page uses special opcodes. Since a page
+consists of 256 bytes, only one byte is needed for
+addressing zero page. So an instruction which uses zero page
+occupies two bytes. It also uses less clock cycle&rsquo;s
+while carrying out the instruction. Zero page is also needed
+when indirect addressing is used. This means that when
+indirect addressing is used, the address must reside in zero
+page (two consecutive bytes). In this case (the back end),
+zero page is used, for example to hold the local base, the
+second local base, the stack pointer etc.</p>
+<a name="4.3. The stack."></a>
+<h2>4.3. The stack.</h2>
+
+<p>The stack is described in paragraph 3.5 about the
+MCS6500 programmable registers.</p>
+<a name="5. The memory adressing modes"></a>
+<h2>5. The memory adressing modes</h2>
+
+<p>MCS6500 memory reference instructions use direct
+addressing, indexed addressing, and indirect addressing.</p>
+<a name="5.1. direct addressing."></a>
+<h2>5.1. direct addressing.</h2>
+
+<p>Three-byte instructions use the second and third bytes
+of the object code to provide a direct 16-bit address:
+therefore, 65.536 bytes of memory can be addressed directly.
+The commonly used memory reference instructions also have a
+two-byte object code variation, where the second byte
+directly addresses one of the first 256 bytes.</p>
+<a name="5.2. Base page, indexed addressing."></a>
+<h2>5.2. Base page, indexed addressing.</h2>
+
+<p>In this case, the instruction has two bytes of object
+code. The contents of either the X or Y index registers are
+added to the second object code byte in order to compute a
+memory address. This may be illustrated as follows:</p>
+
+<p>Base page, indexed addressing, as illustrated above, is
+wraparound - which means that there is no carry. If the sum
+of the index register and second object code byte contents
+is more than <b>FF</b> , the carry bit will be dicarded.
+This may be illustrated as follows:</p>
+<a name="5.3. Absolute indexed addressing."></a>
+<h2>5.3. Absolute indexed addressing.</h2>
+
+<p>In this case, the contents of either the X or Y register
+are added to a 16-bit direct address provided by the second
+and third bytes of an instruction&rsquo;s object code. This
+may be illustrated as follows:</p>
+<a name="5.4. Indirect addressing."></a>
+<h2>5.4. Indirect addressing.</h2>
+
+<p>Instructions that use simple indirect addressing have
+three bytes of object code. The second and third object code
+bytes provide a 16-bit address; therefore, the indirect
+address can be located anywhere in memory. This is
+straightforward indirect addressing.</p>
+<a name="5.4.1. Pre-indexed indirect addressing."></a>
+<h2>5.4.1. Pre-indexed indirect addressing.</h2>
+
+<p>In this case, the object code consists of two bytes and
+the second object code byte provides an 8-bit address.
+Instructions that use pre-indexed indirect addressing add
+the contents of the X index register and the second object
+code byte to access a memory location in the first 256 bytes
+of memory, where the indirect address will be found:</p>
+
+<p>When using pre-indexed indirect addressing, once again
+wraparound addition is used, which means that when the X
+index register contents are added to the second object code
+byte, any carry will be discarded. Note that only the X
+index register can be used with pre-indexed addressing.</p>
+<a name="5.4.2. Post-indexed indirect addressing."></a>
+<h2>5.4.2. Post-indexed indirect addressing.</h2>
+
+<p>In this case, the object code consists of two bytes and
+the second object code byte provides an 8-bit address. Now
+the second object code byte indentifies a location in the
+first 256 bytes of memory where an indirect address will be
+found. The contents of the Y index register are added to
+this indirect address. This may be illustrated as
+follows:</p>
+
+<p>Note that only the Y index register can be used with
+post-indexed indirect addressing.</p>
+<a name="6. What the CPU has and doesn&rsquo;t has."></a>
+<h2>6. What the CPU has and doesn&rsquo;t has.</h2>
+
+<p>Although the designers of the MCS6500 CPUs family state
+that there is nothing very significant about the short stack
+(only 256 bytes) this stack caused problems for the back
+end. The designers say that a 256-byte stack usually is
+sufficient for any typical microcomputer, this is only true
+if the stack is used only for return addresses of the JSR
+(jump to subroutine) instruction. But since the EM machine
+is suppost to be a stack machine and high level languages
+need the ability of parameters and locals in there
+procedures and function, this short stack is unsufficiant.
+So an software stack is implemented in this back end,
+requiring two additional subroutines for stack handling.
+These two stack handling subroutines slow down the
+processing time of a program since the stack is used
+heavely.</p>
+
+<p>Since parameters and locals of EM procedures are
+offseted from the localbase of that procedure, indirect
+addressing is havily used. Offsets are positive (for
+parameters) and negative (for local variables). As explaned
+before the addressing modes the MCS6500 have a post indexed
+indirect addressing mode. This addressing mode can only
+handle positive offsets. This raises a problem for accessing
+the local variables I have chosen for the next solution. A
+second local base is introduced. This second local base is
+the real local base subtracted by a constant BASE. In the
+present situation of the back end the value of BASE is 240.
+This means that there are 240 bytes reseved for local
+variables to be indirect addressed and 14 bytes for the
+parameters.</p>
+
+<p align=center><b>THE CODE GENERATOR.</b></p>
+<a name="1. Description of the machine table."></a>
+<h2>1. Description of the machine table.</h2>
+
+<p>The machine description table consists of the following
+sections:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="44%">
+
+<p>The macro definitions.</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="42%">
+
+<p>Constant definitions.</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="42%">
+
+<p>Register definitions.</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>Token definitions.</p>
+</td>
+<td width="53%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>Token expressions.</p>
+</td>
+<td width="53%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6.</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>Code rules.</p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7.</p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>Move definitions.</p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>8.</p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>Test definitions.</p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>9.</p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>Stack definitions.</p>
+</td>
+<td width="53%">
+</td>
+</table>
+<a name="1.1. Macro definitions."></a>
+<h2>1.1. Macro definitions.</h2>
+
+<p>The macro definitions at the top of the table are
+expanded by the preprocessor on occurence in the rest of the
+table.</p>
+<a name="1.2. Constant definitions."></a>
+<h2>1.2. Constant definitions.</h2>
+
+<p>There are three constants which must be defined at
+first. The are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>EM_WSIZE:</p>
+</td>
+<td width="4%"></td>
+<td width="78%">
+
+<p>Number of bytes in a machine word. This is the number of
+bytes a simple <b>loc</b> instruction will put on the
+stack.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>EM_PSIZE:</p>
+</td>
+<td width="4%"></td>
+<td width="78%">
+
+<p>Number of bytes in a pointer. This is the number of
+bytes a <b>lal</b> instruction will put on the stack.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>EM_BSIZE:</p>
+</td>
+<td width="4%"></td>
+<td width="78%">
+
+<p>Number of bytes in the hole between AB and LB. The
+calling sequence only saves LB on the stack so this constant
+is equal to the pointer size.</p>
+</td>
+</table>
+<a name="2. Register definitions."></a>
+<h2>2. Register definitions.</h2>
+
+<p>The only important register definition is the definition
+of the registerpair AX. Since the rest of the
+machine&rsquo;s registers Y, PC, ST serve special purposes,
+the code generator cannot use them.</p>
+<a name="2.1. Token definitions"></a>
+<h2>2.1. Token definitions</h2>
+
+<p>There is a fake token. This token is put in the table,
+since the code generator generator complains if it cannot
+find one.</p>
+<a name="2.2. Token expression definitions."></a>
+<h2>2.2. Token expression definitions.</h2>
+
+<p>The token expression is also a fake one. This token
+expression is put in the table, since the code generator
+generator complains if it cannot find one.</p>
+<a name="2.3. Code rules."></a>
+<h2>2.3. Code rules.</h2>
+
+<p>The code rule section is the largest section in the
+table. They specify EM patterns, stack patterns, code to be
+generated, etc. The syntax is:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>code</p>
+</td>
+<td width="2%"></td>
+<td width="90%">
+
+<p>EM pattern &rsquo;|&rsquo; stack pattern &rsquo;|&rsquo;
+code &rsquo;|&rsquo; stack replacement &rsquo;|&rsquo; EM
+replacement &rsquo;|&rsquo;</p>
+</td>
+</table>
+
+<p>All patterns are optional, however there must be at
+least one pattern present. If the EM pattern is missing the
+rule becomes a rewriting rule or a <b>coercion</b> to be
+used when code generation cannot continue because of an
+invalid stack pattern. The code rules are preceeded by the
+word CODE:.</p>
+<a name="2.3.1. The EM pattern."></a>
+<h2>2.3.1. The EM pattern.</h2>
+
+<p>The EM pattern consists of a list of EM mnemonics
+followed by a boolean expression. Examples:</p>
+
+<p><b>loe</b></p>
+
+<p>will match a single <b>loe</b> instruction,</p>
+
+<p><b>loc loc cif</b> $1==2 &amp;&amp; $2==8</p>
+
+<p>is a pattern that will match</p>
+
+<p><b>loc</b> 2<b><br>
+loc</b> 8<b><br>
+cif</b></p>
+
+<p>and</p>
+
+<p><b>lol inc stl</b> $1==$3</p>
+
+<p>will match for example</p>
+
+<p><b>lol</b> 6<b><br>
+inc<br>
+stl</b> 6</p>
+
+<p>A missing boolean expession evaluates to TRUE.</p>
+
+<p>The code generator will match the longest EM pattern on
+every occasion, if two patterns of the same length match the
+first in the table will be chosen, while all patterns of
+length greater than or equal to three are considered to be
+of the same length.</p>
+<a name="2.3.2. The stack pattern."></a>
+<h2>2.3.2. The stack pattern.</h2>
+
+<p>The only stack pattern that can occur is R16, which
+means that the registerpair AX contains the word on top of
+the stack. If this is not the case a coersion occurs. This
+coersion generates a &quot;jsr Pop&quot;, which means that
+the top of the stack is popped and stored in the
+registerpair AX.</p>
+<a name="2.3.3. The code part."></a>
+<h2>2.3.3. The code part.</h2>
+
+<p>The code part consists of three parts, stack cleanup,
+register allocation, and code to be generated. All of these
+may be omitted.</p>
+<a name="2.3.3.1. Stack cleanup."></a>
+<h2>2.3.3.1. Stack cleanup.</h2>
+
+<p>When generating something like a branch instruction it
+might be needed to empty the fake stack, that is, remove the
+AX registerpair. This is done by the instruction
+remove(ALL)</p>
+<a name="2.3.3.2. Register allocation."></a>
+<h2>2.3.3.2. Register allocation.</h2>
+
+<p>If the machine code to be generated uses the
+registerpair AX, this is signaled to the code generator by
+the allocate(R16) instruction. If the registerpair AX
+resides on the fake stack, this will result in a &quot;jsr
+Push&quot;, which means that the registerpair AX is pushed
+on the stack and will be free for further use. If
+registerpair AX is not on the fake stack nothing
+happens.</p>
+<a name="2.3.3.3. Code to be generated."></a>
+<h2>2.3.3.3. Code to be generated.</h2>
+
+<p>Code to be generated is specified as a list of items of
+the following kind:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>A string in double quotes(&quot;This is a string&quot;).
+This is copied to the codefile and a newline (&rsquo;0) is
+appended. Inside the string all normal C string conventions
+are allowed, and substitutions can be made of the following
+sorts.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>a)</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>$1, $2 etc. These are the operand of the corresponding
+EM instructions and are printed according to there type. To
+put a real &rsquo;$&rsquo; inside the string it must be
+doubled (&rsquo;$$&rsquo;).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>b)</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>%[1], %[2.reg], %[b.1] etc. these have there obvious
+meaning. If they describe a complete token (%[1]) the
+printformat for the token is used. If they stand fo a basic
+term in an expression they will be printed according to
+their type. To put a real &rsquo;%&rsquo; inside the string
+it must be doubled (&rsquo;%%&rsquo;).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>c)</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>%( arbitrary expression %). This allows inclusion of
+arbitrary expressions inside strings. Usually not needed
+very often, so that the akward notation is not too bad. Note
+that %(%[1]%) is equivalent to %[1].</p>
+</td>
+</table>
+<a name="2.3.4. stack replacement."></a>
+<h2>2.3.4. stack replacement.</h2>
+
+<p>The stack replacement is a possibly empty list of items
+to be pushed on the fake stack. Three things can occur:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>%[1] is used if the registerpair AX was on the fake
+stack and is to be pushed back onto it.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>%[a] is used if the registerpair AX is allocated with
+allocate(R16) and is to be pushed onto the fake stack.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3)</p>
+</td>
+<td width="6%"></td>
+<td width="42%">
+
+<p>It can also be empty.</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<a name="2.3.5. EM replacement."></a>
+<h2>2.3.5. EM replacement.</h2>
+
+<p>In exeptional cases it might be useful to leave part of
+the an EM pattern undone. For example, a <b>sdl</b>
+instruction might be split into two <b>stl</b> instructions
+when there is no 4-byte quantity on the stack. The EM
+replacement part allows one to express this. Example:</p>
+
+<p><b>stl</b> $1 <b>stl</b> $1+2</p>
+
+<p>The instructions are inserted in the stream so they can
+match the first part of a pattern in the next step. Note
+that since the code generator traverses the EM instructions
+in a strict linear fashion, it is impossible to let the EM
+replacement match later parts of a pattern. So if there is a
+pattern</p>
+
+<p><b>loc stl</b> $1==0 and the input is</p>
+
+<p><b>loc</b> 0 <b>sdl</b> 4</p>
+
+<p>the <b>loc</b> 0 will be processed first, then the
+<b>sdl</b> might be split into two <b>stl</b></p>
+<a name="2.3.6. Move definitions."></a>
+<h2>2.3.6. Move definitions.</h2>
+
+<p>This definition is a fake. This definition is put in the
+table, since the code generator generator complains if it
+cannot find one.</p>
+<a name="2.3.7. Test definitions."></a>
+<h2>2.3.7. Test definitions.</h2>
+
+<p>Test definitions aren&rsquo;t used by the table.</p>
+<a name="2.3.8. Stack definitions."></a>
+<h2>2.3.8. Stack definitions.</h2>
+
+<p>When the generator has to push the registerpair AX, it
+must know how to do so. The machine code to be generated is
+defined here.</p>
+<a name="3. Some remarks."></a>
+<h2>3. Some remarks.</h2>
+
+<p>The above description of the machine table is a
+description of the table for the MCS6500. It uses only a
+part of the possibilities which the code generator generator
+offers. For a more precise and detailed description see
+[2].</p>
+
+<p align=center><b>THE BACK END TABLE.</b></p>
+<a name="1. Introduction."></a>
+<h2>1. Introduction.</h2>
+
+<p>The code rules are divided in 15 groups. These groups
+are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>Load instructions.</p>
+</td>
+<td width="53%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="38%">
+
+<p>Store instructions.</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="64%">
+
+<p>Integer arithmetic instructions.</p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="66%">
+
+<p>Unsigned arithmetic instructions.</p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="6%"></td>
+<td width="78%">
+
+<p>Floating point arithmetic instructions.</p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6.</p>
+</td>
+<td width="6%"></td>
+<td width="64%">
+
+<p>Pointer arithmetic instructions.</p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p>Increment, decrement and zero instructions.</p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>8.</p>
+</td>
+<td width="6%"></td>
+<td width="42%">
+
+<p>Convert instructions.</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>9.</p>
+</td>
+<td width="6%"></td>
+<td width="42%">
+
+<p>Logical instructions.</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>10.</p>
+</td>
+<td width="4%"></td>
+<td width="60%">
+
+<p>Set manipulation instructions.</p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>11.</p>
+</td>
+<td width="4%"></td>
+<td width="38%">
+
+<p>Array instructions.</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>12.</p>
+</td>
+<td width="4%"></td>
+<td width="42%">
+
+<p>Compare instructions.</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>13.</p>
+</td>
+<td width="4%"></td>
+<td width="40%">
+
+<p>Branch instructions.</p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>14.</p>
+</td>
+<td width="4%"></td>
+<td width="56%">
+
+<p>Procedure call instructions.</p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>15.</p>
+</td>
+<td width="4%"></td>
+<td width="54%">
+
+<p>Miscellaneous instructions.</p>
+</td>
+<td width="35%">
+</td>
+</table>
+
+<p>From all of these groups one or two typical EM pattern
+will be explained in the next paragraphs. Comment is placed
+between /* and */ (/* This is a comment */).</p>
+<a name="2. The instructions."></a>
+<h2>2. The instructions.</h2>
+<a name="2.1. The load instructions."></a>
+<h2>2.1. The load instructions.</h2>
+
+<p>In this group a typical instruction is <b>lol</b> A
+<b>lol</b> instruction pushes the word at local base +
+offset, where offset is the instructions argument, onto the
+stack. Since the MCS6500 can only offset by 256 bytes, as
+explaned at the memory addressing modes, there is a need for
+two code rules in the table. One which can offset directly
+and one that must explicit calculate the address of the
+local.</p>
+<a name="2.1.1. The lol instruction with indirect offsetting."></a>
+<h2>2.1.1. The lol instruction with indirect offsetting.</h2>
+
+<p>In this case an indirect offsetted load from the second
+local base is possible. The table content is:</p>
+
+<p><b>lol</b> IN($1) | |<br>
+allocate(R16) /* allocate registerpair AX */<br>
+&quot;ldy #BASE+$1&quot; /* load Y with the offset from the
+second<br>
+local base */<br>
+&quot;lda (LBl),y&quot; /* load indirect the lowbyte of the
+word */<br>
+&quot;tax&quot; /* move register A to register X */<br>
+&quot;iny&quot; /* increment register Y (offset) */<br>
+&quot;lda (LBl),y&quot; /* load indirect the highbyte of the
+word */<br>
+| %[a] | | /* push the word onto the fake stack */</p>
+<a name="2.1.2. The lol instruction whose offset is to big."></a>
+<h2>2.1.2. The lol instruction whose offset is to big.</h2>
+
+<p>In this case, the library subroutine &quot;Lol&quot; is
+used. This subroutine expects the offset in registerpair AX,
+then calculates the address of the local or parameter, and
+loads it into registerpair AX. The table content is:</p>
+
+<p><b>lol</b> | |<br>
+allocate(R16) /* allocate registerpair AX */<br>
+&quot;lda #[$1].h&quot; /* load highbyte of offset into
+register A */<br>
+&quot;ldx #[$1].l&quot; /* load lowbyte of offset into
+register X */<br>
+&quot;jsr Lol&quot; /* perform the subroutine */<br>
+| %[a] | | /* push word onto the fake stack */</p>
+<a name="2.2. The store instructions."></a>
+<h2>2.2. The store instructions.</h2>
+
+<p>In this group a typical instruction is <b>stl.</b> A
+<b>stl</b> instruction poppes a word from the stack and
+stores it in the word at local base + offset, where offset
+is the instructions argument. Here also is the need for two
+code rules in the table as a result of the offset
+limits.</p>
+<a name="2.2.1. The stl instruction with indirect offsetting."></a>
+<h2>2.2.1. The stl instruction with indirect offsetting.</h2>
+
+<p>In this case it an indirect offsetted store from the
+second local base is possible. The table content is:</p>
+
+<p><b>stl</b> IN($1) | R16 | /* expect registerpair AX on
+top of the<br>
+fake stack */<br>
+&quot;ldy #BASE+1+$1&quot; /* load Y with the offset from
+the<br>
+second local base */<br>
+&quot;sta (LBl),y&quot; /* store the highbyte of the word
+from A */<br>
+&quot;txa&quot; /* move register X to register A */<br>
+&quot;dey&quot; /* decrement offset */<br>
+&quot;sta (LBl),y&quot; /* store the lowbyte of the word
+from A */<br>
+| | |</p>
+<a name="2.2.2. The stl instruction whose offset is to big."></a>
+<h2>2.2.2. The stl instruction whose offset is to big.</h2>
+
+<p>In this case the library subroutine &rsquo;Stl&rsquo; is
+used. This subroutine expects the offset in registerpair AX,
+then calculates the address, poppes the word stores it at
+its place. The table content is:</p>
+
+<p><b>stl</b> | |<br>
+allocate(R16) /* allocate registerpair AX */<br>
+&quot;lda #[$1].h&quot; /* load highbyte of offset in
+register A */<br>
+&quot;ldx #[$1].l&quot; /* load lowbyte of offset in
+register X */<br>
+&quot;jsr Stl&quot; /* perform the subroutine */<br>
+| | |</p>
+<a name="2.3. Integer arithmetic instructions."></a>
+<h2>2.3. Integer arithmetic instructions.</h2>
+
+<p>In this group typical instructions are <b>adi</b> and
+<b>mli.</b> These instructions, in this table, are
+implemented for 2-byte and 4-byte integers. The only
+arithmetic instructions available on the MCS6500 are the ADC
+(add with carry), and SBC (subtract with not(carry)).
+Not(carry) here means that in a subtraction, the one&rsquo;s
+complement of the carry is taken. The absence of multiply
+and division instructions forces the use of subroutines to
+handle these cases. Because there are no registers left to
+perform on the multiply and division, zero page is used
+here. The 4-byte integer arithmetic is implemented, because
+in C there exists the integer type long. A user is freely to
+use the type long, but will pay in performance.</p>
+<a name="2.3.1. The adi instruction."></a>
+<h2>2.3.1. The adi instruction.</h2>
+
+<p>In case of the <b>adi</b> 2 (and <b>sbi</b> 2)
+instruction there are many EM patterns, so that the
+instruction can be performed in line in most cases. For the
+worst case there exists a subroutine in the library which
+deals with the EM instruction. In case of a <b>adi</b> 4 (or
+<b>sbi</b> 4) there only is a subroutine to deal with it. A
+table content is:</p>
+
+<p><b>lol lol adi</b> (IN($1) &amp;&amp; IN($2) &amp;&amp;
+$3==2) | | /* is it in range */<br>
+allocate(R16) /* allocate registerpair AX */<br>
+&quot;ldy #BASE+$1+1&quot; /* load Y with offset for first
+operand */<br>
+&quot;lda (LBl),y&quot; /* load indirect highbyte first
+operand */<br>
+&quot;pha&quot; /* save highbyte first operand on hard_stack
+*/<br>
+&quot;dey&quot; /* decrement offset first operand */<br>
+&quot;lda (LBl),y&quot; /* load indirect lowbyte first
+operand */<br>
+&quot;ldy #BASE+$2&quot; /* load Y with offset for second
+operand */<br>
+&quot;clc&quot; /* clear carry for addition */<br>
+&quot;adc (LBl),y&quot; /* add the lowbytes of the operands
+*/<br>
+&quot;tax&quot; /* store lowbyte of result in place */<br>
+&quot;iny&quot; /* increment offset second operand */<br>
+&quot;pla&quot; /* get highbyte first operand */<br>
+&quot;adc (LBl),y&quot; /* add the highbytes of the operands
+*/<br>
+| %[a] | | /* push the result onto the fake stack */</p>
+<a name="2.3.2. The mli instruction."></a>
+<h2>2.3.2. The mli instruction.</h2>
+
+<p>The <b>mli</b> 2 instruction uses most the subroutine
+&rsquo;Mlinp&rsquo;. This subroutine expects the
+multiplicand in zero page at locations ARTH, ARTH+1, while
+the multiplier is in zero page locations ARTH+2, ARTH+3. For
+a description of the algorithms used for multiplication and
+division, see [3]. A table content is:</p>
+
+<p><b>lol lol mli</b> (IN($1) &amp;&amp; IN($2) &amp;&amp;
+$3==2) | |<br>
+allocate(R16) /* allocate registerpair AX */<br>
+&quot;ldy #BASE+$1&quot; /* load Y with offset of
+multiplicand */<br>
+&quot;lda (LBl),y&quot; /* load indirect lowbyte of
+multiplicand */<br>
+&quot;sta ARTH&quot; /* store lowbyte in zero page */<br>
+&quot;iny&quot; /* increment offset of multiplicand */<br>
+&quot;lda (LBl),y&quot; /* load indirect highbyte of
+multiplicand */<br>
+&quot;sta ARTH+1&quot; /* store highbyte in zero page */<br>
+&quot;ldy #BASE+$2&quot; /* load Y with offset of multiplier
+*/<br>
+&quot;lda (LBl),y&quot; /* load indirect lowbyte of
+multiplier */<br>
+&quot;sta ARTH+2&quot; /* store lowbyte in zero page */<br>
+&quot;iny&quot; /* increment offset of multiplier */<br>
+&quot;lda (LBl),y&quot; /* load indirect highbyte of
+multiplier */<br>
+&quot;sta ARTH+3&quot; /* store highbyte in zero page */<br>
+&quot;jsr Mlinp&quot; /* perform the multiply */<br>
+| %[a] | | /* push result onto fake stack */</p>
+<a name="2.4. The unsgned arithmetic instructions."></a>
+<h2>2.4. The unsgned arithmetic instructions.</h2>
+
+<p>Since unsigned addition an subtraction is performed in
+the same way as signed addition and subtraction, these cases
+are dealt with by an EM replacement. For mutiplication and
+division there are special subroutines.</p>
+<a name="2.4.1. Unsigned addition."></a>
+<h2>2.4.1. Unsigned addition.</h2>
+
+<p>This is an example of the EM replacement strategy.</p>
+
+<p><b>lol lol adu</b> | | | | <b>lol</b> $1 <b>lol</b> $2
+<b>adi</b> $3 |</p>
+<a name="2.5. Floating point arithmetic."></a>
+<h2>2.5. Floating point arithmetic.</h2>
+
+<p>Floating point arithmetic isn&rsquo;t implemented in
+this table.</p>
+<a name="2.6. Pointer arithmetic instructions."></a>
+<h2>2.6. Pointer arithmetic instructions.</h2>
+
+<p>A typical pointer arithmetic instruction is <b>adp</b>
+2. This instruction adds an offset and a pointer. A table
+content is:</p>
+
+<p><b>adp</b> | | | | <b>loc</b> $1 <b>adi</b> 2 |</p>
+<a name="2.7. Increment, decrement and zero instructions."></a>
+<h2>2.7. Increment, decrement and zero instructions.</h2>
+
+<p>In this group a typical instruction is <b>inl</b> ,
+which increments a local or parameter. The MCS6500
+doesn&rsquo;t have an instruction to increment the
+accumulator A, so the &rsquo;ADC&rsquo; instruction must be
+used. A table content is:</p>
+
+<p><b>inl</b> IN($1) | |<br>
+allocate(R16) /* allocate registerpair AX */<br>
+&quot;ldy #BASE+$1&quot; /* load Y with offset of the local
+*/<br>
+&quot;clc&quot; /* clear carry for addition */<br>
+&quot;lda (LBl),y&quot; /* load indirect lowbyte of local
+*/<br>
+&quot;adc #1&quot; /* increment lowbyte */<br>
+&quot;sta (LBl),y&quot; /* restore indirect the incremented
+lowbyte */<br>
+&quot;bcc 1f&quot; /* if carry is clear then ready */<br>
+&quot;iny&quot; /* increment offset of local */<br>
+&quot;lda (LBl),y&quot; /* load indirect highbyte of local
+*/<br>
+&quot;adc #0&quot; /* add carry to highbyte */<br>
+&quot;sta (LBl),y\n1:&quot; /* restore indirect the highbyte
+*/</p>
+
+<p>If the offset of the local or parameter is to big, first
+the local or parameter is fetched, than incremented, and
+then restored.</p>
+<a name="2.8. Convert instructions."></a>
+<h2>2.8. Convert instructions.</h2>
+
+<p>In this case there are two convert instructions which
+really do something. One of them is in line code, and deals
+with the extension of a character (1-byte) to an integer.
+The other one is a subroutine which handles the conversion
+between 2-byte integers and 4-byte integers.</p>
+<a name="2.8.1. The in line conversion."></a>
+<h2>2.8.1. The in line conversion.</h2>
+
+<p>The table content is:</p>
+
+<p><b>loc loc cii</b> $1==1 &amp;&amp; $2==2 | R16 |<br>
+&quot;txa&quot; /* see if sign extension is needed */<br>
+&quot;bpl 1f&quot; /* there is no need for sign extension
+*/<br>
+&quot;lda #0FFh&quot; /* sign extension here */<br>
+&quot;bne 2f&quot; /* conversion ready */<br>
+&quot;1: lda #0\n2:&quot; /* no sign extension here */</p>
+<a name="2.9. Logical instructions."></a>
+<h2>2.9. Logical instructions.</h2>
+
+<p>A typical instruction in this group is the logical
+<b>and</b> on two 2-byte words. The logical <b>and</b> on
+groups of more than two bytes (max 254) is also possible and
+uses a library subroutine.</p>
+<a name="2.9.1. The logical and on 2-byte groups."></a>
+<h2>2.9.1. The logical and on 2-byte groups.</h2>
+
+<p>The table content is:</p>
+
+<p><b>and</b> $1==2 | R16 | /* one group must be on the
+fake stack */<br>
+&quot;sta ARTH+1&quot; /* temporary save of first group
+highbyte */<br>
+&quot;stx ARTH&quot; /* temporary save of first group
+lowbyte */<br>
+&quot;jsr Pop&quot; /* pop second group from the stack
+*/<br>
+&quot;and ARTH+1&quot; /* logical and on highbytes */<br>
+&quot;pha&quot; /* temporary save the result&rsquo;s
+highbyte */<br>
+&quot;txa&quot; /* logical and can only be done in A */<br>
+&quot;and ARTH&quot; /* logical and on lowbytes */<br>
+&quot;tax&quot; /* restore results lowbyte */<br>
+&quot;pla&quot; /* restore results highbyte */<br>
+| %[1] | | /* push result onto fake stack */</p>
+<a name="2.10. Set manipulation instructions."></a>
+<h2>2.10. Set manipulation instructions.</h2>
+
+<p>A typical EM pattern in this group is <b>loc inn zeq</b>
+$1&gt;0 &amp;&amp; $1&lt;16 &amp;&amp; $2==2. This EM
+pattern works on sets of 16 bits. Sets can be bigger (max
+256 bytes = 2048 bits), but than a library routine is used
+instead of in line code. The table content of the above EM
+pattern is:</p>
+
+<p><b>loc inn zeq</b> $1&gt;0 &amp;&amp; $1&lt;16
+&amp;&amp; $2==2 | R16 |<br>
+&quot;ldy #$1+1&quot; /* load Y with bit number */<br>
+&quot;stx ARTH&quot; /* cannot rotate X, so use zero page
+*/<br>
+&quot;1: lsr a&quot; /* right shift A */<br>
+&quot;ror ARTH&quot; /* right rotate zero page location
+*/<br>
+&quot;dey&quot; /* decrement Y */<br>
+&quot;bne 1b&quot; /* shift $1 times */<br>
+&quot;bcc $1&quot; /* no carry, so bit is zero */</p>
+<a name="2.11. Array instructions."></a>
+<h2>2.11. Array instructions.</h2>
+
+<p>In this group a typical EM pattern is <b>lae lar</b>
+defined(rom(1,3)) | | | | <b>lae</b> $1 <b>aar</b> $2
+<b>loi</b> rom(1,3). This pattern uses the <b>aar</b>
+instruction, which is part of a typical EM pattern:</p>
+
+<p><b>lae aar</b> $2==2 &amp;&amp; rom(1,3)==2 &amp;&amp;
+rom(1,1)==0 | R16 | /* registerpair AX contains the index in
+the array */<br>
+&quot;pha&quot; /* save highbyte of index */<br>
+&quot;txa&quot; /* move lowbyte of index to A */<br>
+&quot;asl a&quot; /* shift left lowbyte == 2 times lowbyte
+*/<br>
+&quot;tax&quot; /* restore lowbyte */<br>
+&quot;pla&quot; /* restore highbyte */<br>
+&quot;rol a&quot; /* rotate left highbyte == 2 times
+highbyte */<br>
+| %[1] | adi 2 | /* push new index, add to lowerbound array
+*/</p>
+<a name="2.12. Compare instructions."></a>
+<h2>2.12. Compare instructions.</h2>
+
+<p>In this group all EM patterns are performed by calling a
+subroutine. Subroutines are used here because comparison is
+only possible byte by byte. This means a lot of code, and
+since compare are used frequently a lot of in line code
+would be generated, and thus reducing the space left for the
+software stack. These subroutines can be found in the
+library.</p>
+<a name="2.13. Branch instructions."></a>
+<h2>2.13. Branch instructions.</h2>
+
+<p>A typical branch instruction is <b>beq.</b> The table
+content for it is:</p>
+
+<p><b>beq</b> | R16 |<br>
+&quot;sta BRANCH+1&quot; /* save highbyte second operand in
+zero page */<br>
+&quot;stx BRANCH&quot; /* save lowbyte second operand in
+zero page */<br>
+&quot;jsr Pop&quot; /* pop the first operand */<br>
+&quot;cmp BRANCH+1&quot; /* compare the highbytes */<br>
+&quot;bne 1f&quot; /* there not equal so go on */<br>
+&quot;cpx BRANCH&quot; /* compare the lowbytes */<br>
+&quot;beq $1\n1:&quot; /* lowbytes are also equal, so branch
+*/</p>
+
+<p>Another typical instruction in this group is <b>zeq.</b>
+The table content is:</p>
+
+<p><b>zeq</b> | R16 |<br>
+&quot;tay&quot; /* move A to Y for setting testbits */<br>
+&quot;bmi $1&quot; /* highbyte s minus so branch */<br>
+&quot;txa&quot; /* move X to A for setting testbits */<br>
+&quot;beq $1\n1:&quot; /* lowbyte also zero, thus branch
+*/</p>
+<a name="2.14. Procedure call instructions."></a>
+<h2>2.14. Procedure call instructions.</h2>
+
+<p>In this group one code generation might seem a little
+akward. It is the EM instruction <b>cai</b> which generates
+a &rsquo;jsr Indir&rsquo;. This is because there is no
+indirect jump_subroutine in the MCS6500. The only solution
+is to store the address in zero page, and then do a
+&rsquo;jsr&rsquo; to a known label. At this label there must
+be an indirect jump instruction, which perform a jump to the
+address stored in zero page. In this case the label is
+Indir, and the address is stored in zero page at the
+addresses ADDR, ADDR+1. The tabel content is:</p>
+
+<p><b>cai</b> | R16 |<br>
+&quot;stx ADDR&quot; /* store lowbyte of address in zero
+page */<br>
+&quot;sta ADDR+1&quot; /* store highbyte of address in zero
+page */<br>
+&quot;jsr Indir&quot; /* use the indirect jump */<br>
+| | |</p>
+<a name="2.15. Miscellaneous instructions."></a>
+<h2>2.15. Miscellaneous instructions.</h2>
+
+<p>In this group, as the name suggests, there is no typical
+EM instruction or EM pattern. Most of the MCS6500 code to be
+generated uses a library subroutine or is
+straightforward.</p>
+
+<p align=center><b>PERFORMANCE.</b></p>
+<a name="1. Introduction."></a>
+<h2>1. Introduction.</h2>
+
+<p>To measure the performance of the back end table some
+timing tests are done. What to time? In this case, the
+execution time of several Pascal statements are timed.
+Statements in C, which have a Pascal equivalence are timed
+also. The statements are timed as follows. A test program is
+been written, which executes two nested for_loops from 1 to
+1.000. Within these for_loops the statement, which is to be
+tested, is placed, so the statement will be executed
+1.000.000 times. Then the same program is executed without
+the test statement. The time difference between the two
+executions is the time neccesairy to execute the test
+statement 1.000.000 times. The total time to execute the
+test statement requires thus the time difference divided by
+1.000.000.</p>
+<a name="1. Testing Pascal statements."></a>
+<h2>1. Testing Pascal statements.</h2>
+
+<p>The next statements are tested.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>int1 := 0;</p>
+</td>
+<td width="69%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>int1 := int2 - 1;</p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3)</p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>int1 := int1 + 1;</p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4)</p>
+</td>
+<td width="6%"></td>
+<td width="44%">
+
+<p>int1 := icon1 - icon2;</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5)</p>
+</td>
+<td width="6%"></td>
+<td width="48%">
+
+<p>int1 := icon2 div icon1;</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6)</p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p>int1 := int2 * int3;</p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7)</p>
+</td>
+<td width="6%"></td>
+<td width="38%">
+
+<p>bool := (int1 &lt; 0);</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>8)</p>
+</td>
+<td width="6%"></td>
+<td width="38%">
+
+<p>bool := (int1 &lt; 3);</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>9)</p>
+</td>
+<td width="6%"></td>
+<td width="68%">
+
+<p>bool := ((int1 &gt; 3) or (int1 &lt; 3))</p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>10)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>case int1 of 1: bool := false; 2: bool := true end;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>11)</p>
+</td>
+<td width="4%"></td>
+<td width="54%">
+
+<p>if int1 = 0 then int2 := 3;</p>
+</td>
+<td width="35%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>12)</p>
+</td>
+<td width="4%"></td>
+<td width="70%">
+
+<p>while int1 &gt; 0 do int1 := int1 - 1;</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>13)</p>
+</td>
+<td width="4%"></td>
+<td width="20%">
+
+<p>m := a[k];</p>
+</td>
+<td width="69%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>14)</p>
+</td>
+<td width="4%"></td>
+<td width="38%">
+
+<p>let2 := [&rsquo;a&rsquo;..&rsquo;c&rsquo;];</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>15)</p>
+</td>
+<td width="4%"></td>
+<td width="12%">
+
+<p>P3(x);</p>
+</td>
+<td width="77%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>16)</p>
+</td>
+<td width="4%"></td>
+<td width="26%">
+
+<p>dum := F3(x);</p>
+</td>
+<td width="63%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>17)</p>
+</td>
+<td width="4%"></td>
+<td width="38%">
+
+<p>s.overhead := 5400;</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>18)</p>
+</td>
+<td width="4%"></td>
+<td width="54%">
+
+<p>with s do overhead := 5400;</p>
+</td>
+<td width="35%">
+</td>
+</table>
+
+<p>These statement were tested in a procedure test.</p>
+
+<p>procedure test;<br>
+var i, j, ... : integer;<br>
+bool : boolean;<br>
+let2 : set of char;<br>
+begin<br>
+for i := 1 to 1000<br>
+for j := 1 to 1000<br>
+STATEMENT<br>
+end;</p>
+
+<p>STATEMENT is one of the statements as shown above, or it
+is the empty statement. The assignment of used variables, if
+neccesairy, is done before the first for_loop. In case of
+the statement which uses the procedure call, statement 15, a
+dummy procedure is declared whose body is empty. In case of
+the statement which uses the function, statement 16, this
+function returns its argument. for the timing of C
+statements a similar test program was written.</p>
+
+<p>main()<br>
+{<br>
+int i, j, ...;<br>
+for (i = 1; i &lt;= 1000; i++)<br>
+for (j = 1; j &lt;= 1000; j++)<br>
+STATEMENT<br>
+}</p>
+<a name="2. The results."></a>
+<h2>2. The results.</h2>
+
+<p>Here are tables with the results of the time
+measurments. Times are in microseconds (10^-6). Some
+statements appear twice in the tables. In the second case an
+array of 200 integers was declerated before the variable to
+be tested, so this variable cannot be accessed by indirect
+addressing from the second local base. This results in a
+larger execution time of the statement to be tested. The
+column 68000 contains the times measured on a Bleasdale,
+M68000 based, computer. The times in column pdp are measured
+on a DEC pdp11/44, where the times from column 6500 come
+from a BBC microcomputer.</p>
+
+<p align=center><img src="grohtml-101481.png"></p>
+
+<p align=center><img src="grohtml-101482.png"></p>
+<a name="3. Pascal statements which don&rsquo;t have a C equivalent."></a>
+<h2>3. Pascal statements which don&rsquo;t have a C equivalent.</h2>
+
+<p>At first, the two statements who perform an operation on
+constants are left out. These are left out while the C front
+end does constant folding, while the Pascal front end
+doesn&rsquo;t. So in C the statements int1 = icon1 + icon2;
+and int1 = icon1 / icont2; will use the same amount of time
+since the expression is evaluated by the front end. The two
+other statements (let2 :=
+[&rsquo;a&rsquo;..&rsquo;c&rsquo;]; and <b>with</b> s
+<b>do</b> overhead := 5400;), aren&rsquo;t included in the C
+statement timing table, because there constructs do not
+exist in C. Although in C there can be direct bit
+manipulation, and thus can be used to implement sets I have
+not used it here. The <b>with</b> statement does not exists
+in C and there is nothing with the slightest resemblance to
+it.</p>
+
+<p>At first sight in the table , it looked if there is no
+much difference in the times for the M68000 and the
+pdp11/44, in comparison with the times needed by the
+MCS6500. To verify this impression, I calculated the
+correlation coefficient between the times of the M68000 and
+pdp11/44. It turned out to be 0.997 for both the Pascal time
+tests and the C time tests. Since the correlation
+coefficient is near to one and the difference between the
+times is small, they can be considered to be the same as
+seen from the times of the MCS6500. Then I have tried to
+make a grafic of the times from the M68000 and the MCS6500.
+Well, there was&rsquo;t any correlation to been seen, taken
+all the times. The only correlation one could see, with some
+effort, was in the times for the first three Pascal
+statements. The two first C statements show also a
+correlation, which two points always do.</p>
+
+<p>Also the three Pascal statements <b>case</b> , <b>if</b>
+, and <b>while</b> have a correlation coefficient of 0.999.
+This is probably because the <b>case</b> statement uses a
+subroutine in both cases and the other two statements
+<b>if</b> and, <b>while</b> generate in line code. The last
+two Pascal statements use the same time, since the front end
+wil generate the same EM code for both.</p>
+
+<p>The independence between the rest of the test times is
+because in these cases the object code for the MCS6500 uses
+library subroutines, while the other processors can handle
+the EM code with in line code.</p>
+
+<p>It is clear that the MCS6500 is a slower device, it
+needs longer execution times, the need of more library
+subroutines, but there is no constant factor between it
+execution times and those of other processors.</p>
+
+<p>The slowing down of the MCS6500 as result of the need of
+a library subroutine is illustrated by the muliplication
+statement. The MCS6500 needs a library subroutine, while the
+other two processors have a machine instruction to perform
+the multiply. This results in a factor of 48.5, when the
+operands can be accessed indirect by the MCS6500. When the
+MCS6500 cannot access the operands indirectly the situation
+is even worse. The slight differences between the MCS6500
+execution times for Pascal statements and C statements is
+probably the result of the front end, and thus beyond the
+scope of this discussion.</p>
+
+<p>Another timing test is done in C on the statement k = i
++ j + 1983. This statement is tested on many UNIX*</p>
+
+<p align=center><img src="grohtml-101483.png"></p>
+
+<p>systems. For a complete list see appendix A. The slowest
+one is the IBM XT, which runs on a 8088 microprocessor. The
+fasted one is the Amdahl computer. Here is short table to
+illustrate the performance of the MCS6500.</p>
+
+<p align=center><img src="grohtml-101484.png"></p>
+
+<p>The MCS6500 is three times slower than the IBM XT, but
+threehundred times slower than the Amdahl. The reason why
+the times on the IBM XT and the MCS6500 are the same for
+short&rsquo;s and int&rsquo;s, is that most C compilers make
+the types short and integer the same size on 16-bit
+machines. In this project the MCS6500 is regarded as a
+16-bit machine.</p>
+<a name="4. Length tests."></a>
+<h2>4. Length tests.</h2>
+
+<p>I have also compiled several programs written in Pascal
+and C to see if there is a resemblance between the number of
+bytes generated in the machine&rsquo;s language. In the
+tables:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>length:</p>
+</td>
+<td width="4%"></td>
+<td width="82%">
+
+<p>The number of bytes of the source program.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>68000:</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>The number of bytes of the a.out file for a M68000.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>pdp:</p>
+</td>
+<td width="10%"></td>
+<td width="82%">
+
+<p>The number of bytes of the a.out file for a
+pdp11/44.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>6500:</p>
+</td>
+<td width="8%"></td>
+<td width="82%">
+
+<p>The number of bytes of the a.out file for a MCS6500.</p>
+</td>
+</table>
+
+<p>These are the results:</p>
+
+<p align=center><img src="grohtml-101485.png"></p>
+
+<p align=center><img src="grohtml-101486.png"></p>
+
+<p>In contrast to the execution times of the test
+statements, the object code files sizes show a constant
+factor between them. After calculating the correlation
+coefficient, I have calculated the line fitted between
+sizes.</p>
+
+<p align=center><img src="grohtml-101487.png"></p>
+
+<p align=center><img src="grohtml-101488.png"></p>
+
+<p align=center><img src="grohtml-101489.png"></p>
+
+<p>As seen from the tables above the correlation
+coefficient for Pascal programs is better than the ones for
+C programs. Thus the line fits best for Pascal programs.
+With the formula of the best fitted line one can now
+estimate the size of the object code, which a program needs,
+for a MCS6500 without having the compiler at hand. One also
+can see from these formula that the object code generated
+for a MCS6500 is about 1.8 times more than for the other
+processors. Since the number of bytes in the source file
+havily depends on the programmer, how many spaces he or she
+uses, the size of the indenting in structured programs,
+etc., there is no correlation between the size of the source
+file and the size of the object file. Also the use of
+comments has its influence on the size.</p>
+
+<p align=center><b>SUMMARY.</b></p>
+<a name="1. Summary"></a>
+<h2>1. Summary</h2>
+
+<p>In this chapter some final conclusions are made.</p>
+
+<p>In spite of its simplicity, the MCS6500 is strong enough
+to implement a EM machine. A serious deficy of the MCS6500
+is the missing of 16-bit general purpose registers, and
+especially the missing of a 16-bit stackpointer. As pointed
+out before, one 16-bit register can be simulated by a pair
+of 8-bit registers, in fact, the accumulator A to hold the
+highbyte, and the index register X to hold the lowbyte of
+the word. By lack of a 16-bit stackpointer, zero page must
+be used to hold a stackpointer and there are also two
+subroutines needed for manipulating the stack (Push and
+Pop).</p>
+
+<p>As seen at the time tests, the simple instruction set of
+the MCS6500 forces the use of library subroutines. These
+library subroutines increas the execution time of the
+programs.</p>
+
+<p>The sizes of the object code files show a strong
+correlation in contrast to the execution times. With this
+correlatiuon one canestimate the size of a program if it is
+to be used on a MCS6500.</p>
+<a name="1. REFERENCES."></a>
+<h2>1. REFERENCES.</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Osborn, A., Jacobson, S., and Kane, J. The Mos
+Technology MCS6500. <b>An Introduction to Microcomputers
+,</b> Volume II, Some Real Products (june 1977) chap. 9.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A hardware description of some real existing CPU&rsquo;s,
+such as the Intel Z80, MCS6500, etc. is given in this
+book.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>van Staveren, H. The table driven code generator from
+the Amsterdam Compiler Kit. Vrije Universiteit, Amsterdam,
+(July 11, 1983).</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The defining document for writing a back end table.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Tanenbaum, A.S. Structured Computer Organization.
+Prentice Hall. (1976).</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>In this book computers are described as a hierarchy of
+levels, with each one performing some well-defined
+function.</p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/6500.pdf b/src/olddocs/6500.pdf
new file mode 100644 (file)
index 0000000..c5b0f7b
Binary files /dev/null and b/src/olddocs/6500.pdf differ
diff --git a/src/olddocs/LLgen.html b/src/olddocs/LLgen.html
new file mode 100644 (file)
index 0000000..758edc8
--- /dev/null
@@ -0,0 +1,1166 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:11 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>LLgen, an extended LL(1) parser generator</title>
+</head>
+<body>
+
+
+<h1 align=center>LLgen, an extended LL(1) parser generator</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The Extended Context-Free Syntax">2. The Extended Context-Free Syntax</a><br>
+<a href="#3. Grammar Specifications">3. Grammar Specifications</a><br>
+<a href="#4. Actions">4. Actions</a><br>
+<a href="#5. Error Recovery">5. Error Recovery</a><br>
+<a href="#6. Ambiguities and conflicts">6. Ambiguities and conflicts</a><br>
+<a href="#7. The LLgen working environment">7. The LLgen working environment</a><br>
+<a href="#8. Programs with more than one parser">8. Programs with more than one parser</a><br>
+<a href="#References">References</a><br>
+<a href="#References">References</a><br>
+<a href="#Appendix A : LLgen Input Syntax">Appendix A : LLgen Input Syntax</a><br>
+<a href="#Appendix B : An example">Appendix B : An example</a><br>
+<a href="#Appendix C. How to use LLgen .">Appendix C. How to use LLgen .</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Ceriel J. H. Jacobs</i><br>
+Dept. of Mathematics and Computer Science<br>
+Vrije Universiteit<br>
+Amsterdam, The Netherlands</p>
+
+<p><i>LLgen</i> provides a tool for generating an efficient
+recursive descent parser with no backtrack from an Extended
+Context Free syntax. The <i>LLgen</i> user specifies the
+syntax, together with code describing actions associated
+with the parsing process. <i>LLgen</i> turns this
+specification into a number of subroutines that handle the
+parsing process.</p>
+
+<p>The grammar may be ambiguous. <i>LLgen</i> contains both
+static and dynamic facilities to resolve these
+ambiguities.</p>
+
+<p>The specification can be split into several files, for
+each of which <i>LLgen</i> generates an output file
+containing the corresponding part of the parser.
+Furthermore, only output files that differ from their
+previous version are updated. Other output files are not
+affected in any way. This allows the user to recompile only
+those output files that have changed.</p>
+
+<p>The subroutine produced by <i>LLgen</i> calls a user
+supplied routine that must return the next token. This way,
+the input to the parser can be split into single characters
+or higher level tokens.</p>
+
+<p>An error recovery mechanism is generated almost
+completely automatically. It is based on so called
+<b>default choices</b>, which are implicitly or explicitly
+specified by the user.</p>
+
+<p><i>LLgen</i> has succesfully been used to create
+recognizers for Pascal, C, and Modula-2.</p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p><i>LLgen</i> provides a tool for generating an efficient
+recursive descent parser with no backtrack from an Extended
+Context Free syntax. A parser generated by <i>LLgen</i> will
+be called <i>LLparse</i> for the rest of this document. It
+is assumed that the reader has some knowledge of LL(1)
+grammars and recursive descent parsers. For a survey on the
+subject, see reference (2).</p>
+
+<p>Extended LL(1) parsers are an extension of LL(1)
+parsers. They are derived from an Extended Context-Free
+(ECF) syntax instead of a Context-Free (CF) syntax. ECF
+syntax is described in section 2. Section 3 provides an
+outline of a specification as accepted by <i>LLgen</i> and
+also discusses the lexical conventions of grammar
+specification files. Section 4 provides a description of the
+way the <i>LLgen</i> user can associate actions with the
+syntax. These actions must be written in the programming
+language C, <small><small>4</small></small> which also is
+the target language of <i>LLgen</i>. The error recovery
+technique is discussed in section 5. This section also
+discusses what the user can do about it. Section 6 discusses
+the facilities <i>LLgen</i> offers to resolve ambiguities
+and conflicts. <i>LLgen</i> offers facilities to resolve
+them both at parser generation time and during the execution
+of <i>LLparse</i>. Section 7 discusses the <i>LLgen</i>
+working environment. It also discusses the lexical analyzer
+that must be supplied by the user. This lexical analyzer
+must read the input stream and break it up into basic input
+items, called <b>tokens</b> for the rest of this document.
+Appendix A gives a summary of the <i>LLgen</i> input syntax.
+Appendix B gives an example. It is very instructive to
+compare this example with the one given in reference (3). It
+demonstrates the struggle <i>LLparse</i> and other LL(1)
+parsers have with expressions. Appendix C gives an example
+of the <i>LLgen</i> features allowing the user to recompile
+only those output files that have changed, using the
+<i>make</i> program. <small><small>1</small></small></p>
+<a name="2. The Extended Context-Free Syntax"></a>
+<h2>2. The Extended Context-Free Syntax</h2>
+
+<p>The extensions of an ECF syntax with respect to an
+ordinary CF syntax are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>An ECF syntax contains the repetition operator:
+&quot;N&quot; (N represents a positive integer).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>An ECF syntax contains the closure set operator without
+and with upperbound: &quot;*&quot; and &quot;*N&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>An ECF syntax contains the positive closure set operator
+without and with upperbound: &quot;+&quot; and
+&quot;+N&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>An ECF syntax contains the optional operator:
+&quot;?&quot;, which is a shorthand for &quot;*1&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>An ECF syntax contains parentheses &quot;[&quot; and
+&quot;]&quot; which can be used for grouping.</p>
+</td>
+</table>
+
+<p>We can describe the syntax of an ECF syntax with an ECF
+syntax :</p>
+<pre>     grammar         : rule +
+                     ;
+</pre>
+
+<p>This grammar rule states that a grammar consists of one
+or more rules.</p>
+<pre>     rule            : nonterminal &rsquo;:&rsquo; productionrule &rsquo;;&rsquo;
+                     ;
+</pre>
+
+<p>A rule consists of a left hand side, the nonterminal,
+followed by &quot;:&quot;, the <b>produce symbol</b>,
+followed by a production rule, followed by a &quot;;&quot;,
+indicating the end of the rule.</p>
+<pre>     productionrule  : production [ &rsquo;|&rsquo; production ]*
+                     ;
+</pre>
+
+<p>A production rule consists of one or more alternative
+productions separated by &quot;|&quot;. This symbol is
+called the <b>alternation symbol</b>.</p>
+<pre>     production      : term *
+                     ;
+</pre>
+
+<p>A production consists of a possibly empty list of terms.
+So, empty productions are allowed.</p>
+<pre>     term            : element repeats
+                     ;
+</pre>
+
+<p>A term is an element, possibly with a repeat
+specification.</p>
+<pre>     element         : LITERAL
+                     | IDENTIFIER
+                     | &rsquo;[&rsquo; productionrule &rsquo;]&rsquo;
+                     ;
+</pre>
+
+<p>An element can be a LITERAL, which basically is a single
+character between apostrophes, it can be an IDENTIFIER,
+which is either a nonterminal or a token, and it can be a
+production rule between square parentheses.</p>
+<pre>     repeats         : &rsquo;?&rsquo;
+                     | [ &rsquo;*&rsquo; | &rsquo;+&rsquo; ] NUMBER ?
+                     | NUMBER ?
+                     ;
+</pre>
+
+<p>These are the repeat specifications discussed above.
+Notice that this specification may be empty.</p>
+
+<p>The class of ECF languages is identical with the class
+of CF languages. However, in many cases recursive
+definitions of language features can now be replaced by
+iterative ones. This tends to reduce the number of
+nonterminals and gives rise to very efficient recursive
+descent parsers.</p>
+<a name="3. Grammar Specifications"></a>
+<h2>3. Grammar Specifications</h2>
+
+<p>The major part of a <i>LLgen</i> grammar specification
+consists of an ECF syntax specification. Names in this
+syntax specification refer to either tokens or nonterminal
+symbols. <i>LLgen</i> requires token names to be declared as
+such. This way it can be avoided that a typing error in a
+nonterminal name causes it to be accepted as a token name.
+The token declarations will be discussed later. A name will
+be regarded as a nonterminal symbol, unless it is declared
+as a token name. If there is no production rule for a
+nonterminal symbol, <i>LLgen</i> will complain.</p>
+
+<p>A grammar specification may also include some C
+routines, for instance the lexical analyzer and an error
+reporting routine. Thus, a grammar specification file can
+contain declarations, grammar rules and C-code.</p>
+
+<p>Blanks, tabs and newlines are ignored, but may not
+appear in names or keywords. Comments may appear wherever a
+name is legal (which is almost everywhere). They are
+enclosed in /* ... */, as in C. Comments do not nest.</p>
+
+<p>Names may be of arbitrary length, and can be made up of
+letters, underscore &quot;_&quot; and non-initial digits.
+Upper and lower case letters are distinct. Only the first 50
+characters are significant. Notice however, that the names
+for the tokens will be used by the C-preprocessor. The
+number of significant characters therefore depends on the
+underlying C-implementation. A safe rule is to make the
+identifiers distinct in the first six characters, case
+ignored.</p>
+
+<p>There are two kinds of tokens: those that are declared
+and are denoted by a name, and literals.</p>
+
+<p>A literal consists of a character enclosed in
+apostrophes &quot;&rsquo;&quot;. The &quot;\&quot; is an
+escape character within literals. The following escapes are
+recognized :</p>
+
+<p align=center><img src="grohtml-100191.png"></p>
+
+<p>Names representing tokens must be declared before they
+are used. This can be done using the
+&quot;<b>%token</b>&quot; keyword, by writing</p>
+<pre>%token  name1, name2, . . . ;
+</pre>
+
+<p><i>LLparse</i> is designed to recognize special
+nonterminal symbols called <b>start symbols</b>.
+<i>LLgen</i> allows for more than one start symbol. Thus,
+grammars with more than one entry point are accepted. The
+start symbols must be declared explicitly using the
+&quot;<b>%start</b>&quot; keyword. It can be used whenever a
+declaration is legal, f.i.:</p>
+<pre>%start LLparse, specification ;
+</pre>
+
+<p>declares &quot;specification&quot; as a start symbol and
+associates the identifier &quot;LLparse&quot; with it.
+&quot;LLparse&quot; will now be the name of the C-function
+that must be called to recognize
+&quot;specification&quot;.</p>
+<a name="4. Actions"></a>
+<h2>4. Actions</h2>
+
+<p><i>LLgen</i> allows arbitrary insertions of actions
+within the right hand side of a production rule in the ECF
+syntax. An action consists of a number of C statements,
+enclosed in the brackets &quot;{&quot; and
+&quot;}&quot;.</p>
+
+<p><i>LLgen</i> generates a parsing routine for each rule
+in the grammar. The actions supplied by the user are just
+inserted in the proper place. There may also be declarations
+before the statements in the action, as the &quot;{&quot;
+and &quot;}&quot; are copied into the target code along with
+the action. The scope of these declarations terminates with
+the closing bracket &quot;}&quot; of the action.</p>
+
+<p>In addition to actions, it is also possible to declare
+local variables in the parsing routine, which can then be
+used in the actions. Such a declaration consists of a number
+of C variable declarations, enclosed in the brackets
+&quot;{&quot; and &quot;}&quot;. It must be placed right in
+front of the &quot;:&quot; in the grammar rule. The scope of
+these local variables consists of the complete grammar
+rule.</p>
+
+<p>In order to facilitate communication between the actions
+and <i>LLparse</i>, the parsing routines can be given C-like
+parameters. Each parameter must be declared separately, and
+each of these declarations must end with a semicolon. For
+the last parameter, the semicolon is optional.</p>
+
+<p>So, for example</p>
+<pre>expr(int *pval;) { int fact; } :
+                /*
+                 * Rule with one parameter, a pointer to an int.
+                 * Parameter specifications are ordinary C declarations.
+                 * One local variable, of type int.
+                 */
+        factor (&amp;fact)          { *pval = fact; }
+                /*
+                 * factor is another nonterminal symbol.
+                 * One actual parameter is supplied.
+                 * Notice that the parameter passing mechanism is that
+                 * of C.
+                 */
+        [ &rsquo;+&rsquo; factor (&amp;fact)    { *pval += fact; } ]*
+                /*
+                 * remember the &rsquo;*&rsquo; means zero or more times
+                 */
+        ;
+
+</pre>
+
+<p>is a rule to recognize a number of factors, separated by
+&quot;+&quot;, and to compute their sum.</p>
+
+<p><i>LLgen</i> generates C code, so the parameter passing
+mechanism is that of C, as is shown in the example
+above.</p>
+
+<p>Actions often manipulate attributes of the token just
+read. For instance, when an identifier is read, its name
+must be looked up in a symbol table. Therefore, <i>LLgen</i>
+generates code such that at a number of places in the
+grammar rule it is defined which token has last been read.
+After a token, the last token read is this token. After a
+&quot;[&quot; or a &quot;|&quot;, the last token read is the
+next token to be accepted by <i>LLparse</i>. At all other
+places, it is undefined which token has last been read. The
+last token read is available in the global integer variable
+<i>LLsymb</i>.</p>
+
+<p>The user may also specify C-code wherever a
+<i>LLgen</i>-declaration is legal. Again, this code must be
+enclosed in the brackets &quot;{&quot; and &quot;}&quot;.
+This way, the user can define global declarations and
+C-functions. To avoid name-conflicts with identifiers
+generated by <i>LLgen</i>, <i>LLparse</i> only uses names
+beginning with &quot;LL&quot;; the user should avoid such
+names.</p>
+<a name="5. Error Recovery"></a>
+<h2>5. Error Recovery</h2>
+
+<p>The error recovery technique used by <i>LLgen</i> is a
+modification of the one presented in reference (7). It is
+based on <b>default choices</b>, which just are what the
+word says, default choices at every point in the grammar
+where there is a choice. Thus, in an alternation, one of the
+productions is marked as a default choice, and in a term
+with a non-fixed repetition specification there will also be
+a default choice (between doing the term (once more) and
+continuing with the rest of the production in which the term
+appears).</p>
+
+<p>When <i>LLparse</i> detects an error after having parsed
+the string <i>s</i>, the default choices enable it to
+compute one syntactically correct continuation, consisting
+of the tokens <i>t</i> <small><small>1</small></small>
+...<i>t <small><small>n</small></small></i> , such that
+<i>st</i> <small><small>1</small></small> ...<i>t
+<small><small>n</small></small></i> is a string of tokens
+that is a member of the language defined by the grammar.
+Notice, that the computation of this continuation must
+terminate, which implies that the default choices may not
+invoke recursive rules.</p>
+
+<p>At each point in this continuation, a certain number of
+other tokens could also be syntactically correct, f.i. the
+token <i>t</i> is syntactically correct at point <i>t
+<small><small>i</small></small></i> in this continuation, if
+the string <i>st</i> <small><small>1</small></small> ...<i>t
+<small><small>i</small></small> ts</i>
+<small><small>1</small></small> is a string of the language
+defined by the grammar for some string <i>s</i>
+<small><small>1</small></small> and i &gt;= 0.</p>
+
+<p>The set <i>T</i> containing all these tokens (including
+<i>t</i> <small><small>1</small></small> ,...,<i>t
+<small><small>n</small></small></i> ) is computed. Next,
+<i>LLparse</i> discards zero or more tokens from its input,
+until a token <i>t</i> &isin; <i>T</i> is found. The error
+is then corrected by inserting i (i &gt;= 0) tokens <i>t</i>
+<small><small>1</small></small> ...<i>t
+<small><small>i</small></small></i> , such that the string
+<i>st</i> <small><small>1</small></small> ...<i>t
+<small><small>i</small></small> ts</i>
+<small><small>1</small></small> is a string of the language
+defined by the grammar, for some <i>s</i>
+<small><small>1</small></small> . Then, normal parsing is
+resumed.</p>
+
+<p>The above is difficult to implement in a recursive
+decent parser, and is not the way <i>LLparse</i> does it,
+but the effect is the same. In fact, <i>LLparse</i>
+maintains a list of tokens that may not be discarded, which
+is adjusted as <i>LLparse</i> proceeds. This list is just a
+representation of the set <i>T</i> mentioned above. When an
+error occurs, <i>LLparse</i> discards tokens until a token
+<i>t</i> that is a member of this list is found. Then, it
+continues parsing, following the default choices, inserting
+tokens along the way, until this token <i>t</i> is legal.
+The selection of the default choices must guarantee that
+this will always happen.</p>
+
+<p>The default choices are explicitly or implicitly
+specified by the user. By default, the default choice in an
+alternation is the alternative with the shortest possible
+terminal production. The user can select one of the other
+productions in the alternation as the default choice by
+putting the keyword &quot;<b>%default</b>&quot; in front of
+it.</p>
+
+<p>By default, for terms with a repetition count containing
+&quot;*&quot; or &quot;?&quot; the default choice is to
+continue with the rest of the rule in which the term
+appears, and</p>
+<pre>                term+
+</pre>
+
+<p>is treated as</p>
+<pre>                term term* .
+</pre>
+
+<p>It is also clear, that it can never be the default
+choice to do the term (once more), because this could cause
+the parser to loop, inserting tokens forever. However, when
+the user does not want the parser to skip tokens that would
+not have been skipped if the term would have been the
+default choice, the skipping of such a term can be prevented
+by using the keyword &quot;<b>%persistent</b>&quot;. For
+instance, the rule</p>
+<pre>commandlist : command* ;
+</pre>
+
+<p>could be changed to</p>
+<pre>commandlist : [ %persistent command ]* ;
+</pre>
+
+<p>The effects of this in case of a syntax error are
+twofold: The set <i>T</i> mentioned above will be extended
+as if &quot;command&quot; were in the default production, so
+that fewer tokens will be skipped. Also, if the first token
+that is not skipped is a member of the subset of <i>T</i>
+arising from the grammar rule for &quot;command&quot;,
+<i>LLparse</i> will enter that rule. So, in fact the default
+choice is determined dynamically (by <i>LLparse</i>). Again,
+<i>LLgen</i> checks (statically) that <i>LLparse</i> will
+always terminate, and if not, <i>LLgen</i> will
+complain.</p>
+
+<p>An important property of this error recovery method is
+that, once a rule is started, it will be finished. This
+means that all actions in the rule will be executed
+normally, so that the user can be sure that there will be no
+inconsistencies in his data structures because of syntax
+errors. Also, as the method is in fact error correcting, the
+actions in a rule only have to deal with syntactically
+correct input.</p>
+<a name="6. Ambiguities and conflicts"></a>
+<h2>6. Ambiguities and conflicts</h2>
+
+<p>As <i>LLgen</i> generates a recursive descent parser
+with no backtrack, it must at all times be able to determine
+what to do, based on the current input symbol.
+Unfortunately, this cannot be done for all grammars. Two
+kinds of conflicts can arise :</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>the grammar rule is of the form &quot;production1 |
+production2&quot;, and <i>LLparse</i> cannot decide which
+production to chose. This we call an <b>alternation
+conflict</b>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>the grammar rule is of the form &quot;[ productionrule
+]...&quot;, where ... specifies a non-fixed repetition
+count, and <i>LLparse</i> cannot decide whether to choose
+&quot;productionrule&quot; once more, or to continue. This
+we call a <b>repetition conflict</b>.</p>
+</td>
+</table>
+
+<p>There can be several causes for conflicts: the grammar
+may be ambiguous, or the grammar may require a more complex
+parser than <i>LLgen</i> can construct. The conflicts can be
+examined by inspecting the verbose (-<b>v</b>) option output
+file. The conflicts can be resolved by rewriting the grammar
+or by using <b>conflict resolvers</b>. The mechanism
+described here is based on the attributed parsing of
+reference (6).</p>
+
+<p>An alternation conflict can be resolved by putting an
+<b>if condition</b> in front of the first conflicting
+production. It consists of a &quot;<b>%if</b>&quot; followed
+by a C-expression between parentheses. <i>LLparse</i> will
+then evaluate this expression whenever a token is met at
+this point on which there is a conflict, so the conflict
+will be resolved dynamically. If the expression evaluates to
+non-zero, the first conflicting production is chosen,
+otherwise one of the remaining ones is chosen.</p>
+
+<p>An alternation conflict can also be resolved using the
+keywords &quot;<b>%prefer</b>&quot; or
+&quot;<b>%avoid</b>&quot;. &quot;<b>%prefer</b>&quot; is
+equivalent in behaviour to &quot;<b>%if</b> (1)&quot;.
+&quot;<b>%avoid</b>&quot; is equivalent to &quot;<b>%if</b>
+(0)&quot;. In these cases however,
+&quot;<b>%prefer</b>&quot; and &quot;<b>%avoid</b>&quot;
+should be used, as they resolve the conflict statically and
+thus give rise to better C-code.</p>
+
+<p>A repetition conflict can be resolved by putting a
+<b>while condition</b> right after the opening parentheses.
+This while condition consists of a &quot;<b>%while</b>&quot;
+followed by a C-expression between parentheses. Again,
+<i>LLparse</i> will then evaluate this expression whenever a
+token is met at this point on which there is a conflict. If
+the expression evaluates to non-zero, the repeating part is
+chosen, otherwise the parser continues with the rest of the
+rule. Appendix B will give an example of these features.</p>
+
+<p>A useful aid in writing conflict resolvers is the
+&quot;<b>%first</b>&quot; keyword. It is used to declare a
+C-macro that forms an expression returning 1 if the
+parameter supplied can start a specified nonterminal,
+f.i.:</p>
+<pre>%first fmac, nonterm ;
+
+</pre>
+
+<p>declares &quot;fmac&quot; as a macro with one parameter,
+whose value is a token number. If the parameter X can start
+the nonterminal &quot;nonterm&quot;, &quot;fmac(X)&quot; is
+true, otherwise it is false.</p>
+<a name="7. The LLgen working environment"></a>
+<h2>7. The LLgen working environment</h2>
+
+<p><i>LLgen</i> generates a number of files: one for each
+input file, and two other files: <i>Lpars.c</i> and
+<i>Lpars.h</i>. <i>Lpars.h</i> contains
+&quot;#-define&quot;s for the tokennames. <i>Lpars.c</i>
+contains the error recovery routines and tables. Only those
+output files that differ from their previous version are
+updated. See appendix C for a possible application of this
+feature.</p>
+
+<p>The names of the output files are constructed as
+follows: in the input file name, the suffix after the last
+point is replaced by a &quot;c&quot;. If no point is present
+in the input file name, &quot;.c&quot; is appended to it.
+<i>LLgen</i> checks that the filename constructed this way
+in fact represents a previous version, or does not exist
+already.</p>
+
+<p>The user must provide some environment to obtain a
+complete program. Routines called <i>main</i> and
+<i>LLmessage</i> must be defined. Also, a lexical analyzer
+must be provided.</p>
+
+<p>The routine <i>main</i> must be defined, as it must be
+in every C-program. It should eventually call one of the
+startsymbol routines.</p>
+
+<p>The routine <i>LLmessage</i> must accept one parameter,
+whose value is a token number, zero or -1.<br>
+A zero parameter indicates that the current token (the one
+in the external variable <i>LLsymb</i>) is deleted.<br>
+A -1 parameter indicates that the parser expected end of
+file, but didn&rsquo;t get it. The parser will then skip
+tokens until end of file is detected.<br>
+A parameter that is a token number (a positive parameter)
+indicates that this token is to be inserted in front of the
+token currently in <i>LLsymb</i>. The user can give the
+token the proper attributes. Also, the user must take care,
+that the token currently in <i>LLsymb</i> is again returned
+by the <b>next</b> call to the lexical analyzer, with the
+proper attributes. So, the lexical analyzer must have a
+facility to push back one token.</p>
+
+<p>The user may also supply his own error recovery
+routines, or handle errors differently. For this purpose,
+the name of a routine to be called when an error occurs may
+be declared using the keyword <b>%onerror</b>. This routine
+takes two parameters. The first one is either the token
+number of the token expected, or 0. In the last case, the
+error occurred at a choice. In both cases, the routine must
+ensure that the next call to the lexical analyser returns
+the token that replaces the current one. Of course, that
+could well be the current one, in which case <i>LLparse</i>
+recovers from the error. The second parameter contains a
+list of tokens that are not skipped at the error point. The
+list is in the form of a null-terminated array of integers,
+whose address is passed.</p>
+
+<p>The user must supply a lexical analyzer to read the
+input stream and break it up into tokens, which are passed
+to <i>LLparse.</i> It should be an integer valued function,
+returning the token number. The name of this function can be
+declared using the &quot;<b>%lexical</b>&quot; keyword. This
+keyword can be used wherever a declaration is legal and may
+appear only once in the grammar specification, f.i.:</p>
+<pre>%lexical scanner ;
+</pre>
+
+<p>declares &quot;scanner&quot; as the name of the lexical
+analyzer. The default name for the lexical analyzer is
+&quot;yylex&quot;. The reason for this funny name is that a
+useful tool for constructing lexical analyzers is the
+<i>Lex</i> program, <small><small>5</small></small> which
+generates a routine of that name.</p>
+
+<p>The token numbers are chosen by <i>LLgen</i>. The token
+number for a literal is the numerical value of the character
+in the local character set. If the tokens have a name, the
+&quot;# define&quot; mechanism of C is used to give them a
+value and to allow the lexical analyzer to return their
+token numbers symbolically. These &quot;# define&quot;s are
+collected in the file <i>Lpars.h</i> which can be &quot;#
+include&quot;d in any file that needs the token-names. The
+maximum token number chosen is defined in the macro
+<i>LL_MAXTOKNO</i>.</p>
+
+<p>The lexical analyzer must signal the end of input to
+<i>LLparse</i> by returning a number less than or equal to
+zero.</p>
+<a name="8. Programs with more than one parser"></a>
+<h2>8. Programs with more than one parser</h2>
+
+<p><i>LLgen</i> offers a simple facility for having more
+than one parser in a program: in this case, the user can
+change the names of global procedures, variables, etc, by
+giving a different prefix, like this:</p>
+<pre>%prefix XX ;
+</pre>
+
+<p>The effect of this is that all global names start with
+XX instead of LL, for the parser that has this prefix. This
+holds for the variables <i>LLsymb</i>, which now is called
+<i>XXsymb</i>, for the routine <i>LLmessage</i>, which must
+now be called <i>XXmessage</i>, and for the macro
+<i>LL_MAXTOKNO</i>, which is now called <i>XX_MAXTOKNO</i>.
+<i>LL.output</i> is now <i>XX.output</i>, and <i>Lpars.c</i>
+and <i>Lpars.h</i> are now called <i>XXpars.c</i> and
+<i>XXpars.h</i>.</p>
+<a name="References"></a>
+<h2>References</h2>
+<a name="References"></a>
+<h2>References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>S. I. Feldman, &ldquo;Make - A Program for Maintaining
+Computer Programs,&rdquo; <i>Software - Practice and
+Experience,</i> 10, 8, pp. 255-265 (August 1979).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>M. Griffiths, &ldquo;LL(1) Grammars and Analysers&rdquo;
+in <i>Compiler Construction, An Advanced Course,</i> ed. F.
+L. Bauer and J. Eickel, Springer-Verlag, New York, N.Y.
+(1974).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>S. C. Johnson, &ldquo;Yacc: Yet Another Compiler
+Compiler,&rdquo; Comp. Sci. Tech. Rep. No. 32, Bell
+Laboratories, Murray Hill, New Jersey (1975).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>B. W. Kernighan and D. M. Ritchie, <i>The C Programming
+Language,</i> Prentice-Hall, Inc., Englewood Cliffs, New
+Jersey (1978).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>M. E. Lesk, &ldquo;Lex - A Lexical Analyser
+Generator,&rdquo; Comp. Sci. Tech. Rep. No. 39, Bell
+Laboratories, Murray Hill, New Jersey (October 1975).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>D. R. Milton, L. W. Kirchhoff, and B. R. Rowland,
+&ldquo;An ALL(1) Compiler Generator,&rdquo; <i>SIGPLAN
+Notices,</i> 14, 8, pp. 152-157 (August 1979).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>J. Rohrich, &ldquo;Methods for the Automatic
+Construction of Error Correcting Parsers,&rdquo; <i>Acta
+Informatica,</i> 13, pp. 115-139 (1980).</p>
+</td>
+</table>
+<a name="Appendix A : LLgen Input Syntax"></a>
+<h2>Appendix A : LLgen Input Syntax</h2>
+
+<p>This appendix has a description of the <i>LLgen</i>
+input syntax, as a <i>LLgen</i> specification. As a matter
+of fact, the current version of <i>LLgen</i> is written with
+<i>LLgen</i>.</p>
+<pre>/*
+ * First the declarations of the terminals
+ * The order is not important
+ */
+
+%token  IDENTIFIER;            /* terminal or nonterminal name */
+%token  NUMBER;
+%token  LITERAL;
+
+/*
+ * Reserved words
+ */
+
+%token  TOKEN;         /* %token */
+%token  START;         /* %start */
+%token  PERSISTENT;    /* %persistent */
+%token  IF;            /* %if */
+%token  WHILE;         /* %while */
+%token  AVOID;         /* %avoid */
+%token  PREFER;        /* %prefer */
+%token  DEFAULT;       /* %default */
+%token  LEXICAL;       /* %lexical */
+%token  PREFIX;        /* %prefix */
+%token  ONERROR;       /* %onerror */
+%token  FIRST;         /* %first */
+
+/*
+ * Declare LLparse to be a C-routine that recognizes &quot;specification&quot;
+ */
+
+%start  LLparse, specification;
+
+specification
+        : declaration*
+        ;
+
+declaration
+        : START
+                IDENTIFIER &rsquo;,&rsquo; IDENTIFIER
+          &rsquo;;&rsquo;
+        | &rsquo;{&rsquo;
+                /* Read C-declaration here */
+          &rsquo;}&rsquo;
+        | TOKEN
+                IDENTIFIER
+                [ &rsquo;,&rsquo; IDENTIFIER ]*
+          &rsquo;;&rsquo;
+        | FIRST
+                IDENTIFIER &rsquo;,&rsquo; IDENTIFIER
+          &rsquo;;&rsquo;
+        | LEXICAL
+                IDENTIFIER
+          &rsquo;;&rsquo;
+        | PREFIX
+                IDENTIFIER
+          &rsquo;;&rsquo;
+        | ONERROR
+                IDENTIFIER
+       &rsquo;;&rsquo;
+        | rule
+        ;
+
+rule    : IDENTIFIER parameters? ldecl?
+                &rsquo;:&rsquo; productions
+          &rsquo;;&rsquo;
+        ;
+
+ldecl   : &rsquo;{&rsquo;
+                /* Read C-declaration here */
+          &rsquo;}&rsquo;
+        ;
+
+productions
+        : simpleproduction
+          [ &rsquo;|&rsquo; simpleproduction ]*
+        ;
+
+simpleproduction
+        : DEFAULT?
+       [ IF &rsquo;(&rsquo; /* Read C-expression here */ &rsquo;)&rsquo;
+          | PREFER
+          | AVOID
+          ]?
+          [ element repeats ]*
+        ;
+
+element : &rsquo;{&rsquo;
+                /* Read action here */
+          &rsquo;}&rsquo;
+        | &rsquo;[&rsquo; [ WHILE &rsquo;(&rsquo; /* Read C-expression here */ &rsquo;)&rsquo; ]?
+                PERSISTENT?
+                productions
+          &rsquo;]&rsquo;
+        | LITERAL
+        | IDENTIFIER parameters?
+        ;
+
+parameters
+        : &rsquo;(&rsquo; /* Read C-parameters here */ &rsquo;)&rsquo;
+        ;
+
+repeats : /* empty */
+        | [ &rsquo;*&rsquo; | &rsquo;+&rsquo; ] NUMBER?
+        | NUMBER
+        | &rsquo;?&rsquo;
+        ;
+
+</pre>
+<a name="Appendix B : An example"></a>
+<h2>Appendix B : An example</h2>
+
+<p>This example gives the complete <i>LLgen</i>
+specification of a simple desk calculator. It has 26
+registers, labeled &quot;a&quot; through &quot;z&quot;, and
+accepts arithmetic expressions made up of the C operators +,
+-, *, /, %, &amp;, and |, with their usual priorities. The
+value of the expression is printed. As in C, an integer that
+begins with 0 is assumed to be octal; otherwise it is
+assumed to be decimal.</p>
+
+<p>Although the example is short and not very complicated,
+it demonstrates the use of if and while conditions. In the
+example they are in fact used to reduce the number of
+nonterminals, and to reduce the overhead due to the
+recursion that would be involved in parsing an expression
+with an ordinary recursive descent parser. In an ordinary
+LL(1) grammar there would be one nonterminal for each
+operator priority. The example shows how we can do it all
+with one nonterminal, no matter how many priority levels
+there are.</p>
+<pre>{
+#include &lt;stdio.h&gt;
+#include &lt;ctype.h&gt;
+#define MAXPRIO      5
+#define prio(op)     (ptab[op])
+
+struct token {
+        int     t_tokno;        /* token number */
+        int     t_tval;         /* Its attribute */
+} stok = { 0,0 }, tok;
+
+int     nerrors = 0;
+int     regs[26];               /* Space for the registers */
+int     ptab[128];              /* Attribute table */
+
+struct token
+nexttok() {  /* Read next token and return it */
+        register        c;
+        struct token    new;
+
+       while ((c = getchar()) == &rsquo; &rsquo; || c == &rsquo;\t&rsquo;) { /* nothing */ }
+        if (isdigit(c)) new.t_tokno = DIGIT;
+        else if (islower(c)) new.t_tokno = IDENT;
+        else new.t_tokno = c;
+        if (c &gt;= 0) new.t_tval = ptab[c];
+        return new;
+}   }
+
+%token  DIGIT, IDENT;
+%start  parse, list;
+
+list    : stat* ;
+
+stat    {       int     ident, val; } :
+        %if (stok = nexttok(),
+             stok.t_tokno == &rsquo;=&rsquo;)
+                    /* The conflict is resolved by looking one further
+                     * token ahead. The grammar is LL(2)
+                     */
+          IDENT
+                                {       ident = tok.t_tval; }
+          &rsquo;=&rsquo; expr(1,&amp;val) &rsquo;\n&rsquo;
+                                {       if (!nerrors) regs[ident] = val; }
+        | expr(1,&amp;val) &rsquo;\n&rsquo;
+                                {       if (!nerrors) printf(&quot;%d\n&quot;,val); }
+        | &rsquo;\n&rsquo;
+        ;
+
+expr(int level; int *val;) {       int     expr; } :
+          factor(val)
+          [ %while (prio(tok.t_tokno) &gt;= level)
+                    /* Swallow operators as long as their priority is
+                     * larger than or equal to the level of this invocation
+                     */
+              &rsquo;+&rsquo; expr(prio(&rsquo;+&rsquo;)+1,&amp;expr)
+                                {       *val += expr; }
+                    /* This states that &rsquo;+&rsquo; groups left to right. If it
+                     * should group right to left, the rule should read:
+                     * &rsquo;+&rsquo; expr(prio(&rsquo;+&rsquo;),&amp;expr)
+                     */
+            | &rsquo;-&rsquo; expr(prio(&rsquo;-&rsquo;)+1,&amp;expr)
+                                {       *val -= expr; }
+            | &rsquo;*&rsquo; expr(prio(&rsquo;*&rsquo;)+1,&amp;expr)
+                                {       *val *= expr; }
+            | &rsquo;/&rsquo; expr(prio(&rsquo;/&rsquo;)+1,&amp;expr)
+                                {       *val /= expr; }
+            | &rsquo;%&rsquo; expr(prio(&rsquo;%&rsquo;)+1,&amp;expr)
+                                {       *val %= expr; }
+            | &rsquo;&amp;&rsquo; expr(prio(&rsquo;&amp;&rsquo;)+1,&amp;expr)
+                                {       *val &amp;= expr; }
+            | &rsquo;|&rsquo; expr(prio(&rsquo;|&rsquo;)+1,&amp;expr)
+                                {       *val |= expr; }
+          ]*
+                    /* Notice the &quot;*&quot; here. It is important.
+                     */
+     ;
+
+factor(int *val;):
+            &rsquo;(&rsquo; expr(1,val) &rsquo;)&rsquo;
+          | &rsquo;-&rsquo; expr(MAXPRIO+1,val)
+                                {       *val = -*val; }
+          | number(val)
+          | IDENT
+                                {       *val = regs[tok.t_tval]; }
+        ;
+
+number(int *val;) {       int base; }
+        : DIGIT
+                                {       base = (*val=tok.t_tval)==0?8:10; }
+          [ DIGIT
+                                {       *val = base * *val + tok.t_tval; }
+          ]*        ;
+
+%lexical scanner ;
+{
+scanner() {
+        if (stok.t_tokno) { /* a token has been inserted or read ahead */
+                tok = stok;
+                stok.t_tokno = 0;
+                return tok.t_tokno;
+        }
+        if (nerrors &amp;&amp; tok.t_tokno == &rsquo;\n&rsquo;) {
+                printf(&quot;ERROR\n&quot;);
+                nerrors = 0;
+        }
+        tok = nexttok();
+        return tok.t_tokno;
+}
+
+LLmessage(insertedtok) {
+        nerrors++;
+        if (insertedtok) { /* token inserted, save old token */
+                stok = tok;
+                tok.t_tval = 0;
+                if (insertedtok &lt; 128) tok.t_tval = ptab[insertedtok];
+        }
+}
+
+main() {
+        register *p;
+
+       for (p = ptab; p &lt; &amp;ptab[128]; p++) *p = 0;
+        /* for letters, their attribute is their index in the regs array */
+        for (p = &amp;ptab[&rsquo;a&rsquo;]; p &lt;= &amp;ptab[&rsquo;z&rsquo;]; p++) *p = p - &amp;ptab[&rsquo;a&rsquo;];
+        /* for digits, their attribute is their value */
+        for (p = &amp;ptab[&rsquo;0&rsquo;]; p &lt;= &amp;ptab[&rsquo;9&rsquo;]; p++) *p = p - &amp;ptab[&rsquo;0&rsquo;];
+        /* for operators, their attribute is their priority */
+        ptab[&rsquo;*&rsquo;] = 4;
+        ptab[&rsquo;/&rsquo;] = 4;
+        ptab[&rsquo;%&rsquo;] = 4;
+        ptab[&rsquo;+&rsquo;] = 3;
+        ptab[&rsquo;-&rsquo;] = 3;
+        ptab[&rsquo;&amp;&rsquo;] = 2;
+        ptab[&rsquo;|&rsquo;] = 1;
+        parse();
+     exit(nerrors);
+}   }
+</pre>
+<a name="Appendix C. How to use LLgen ."></a>
+<h2>Appendix C. How to use LLgen .</h2>
+
+<p>This appendix demonstrates how <i>LLgen</i> can be used
+in combination with the <i>make</i> program, to make
+effective use of the <i>LLgen</i>-feature that it only
+changes output files when neccessary. <i>Make</i> uses a
+&quot;makefile&quot;, which is a file containing
+dependencies and associated commands. A dependency usually
+indicates that some files depend on other files. When a file
+depends on another file and is older than that other file,
+the commands associated with the dependency are
+executed.</p>
+
+<p>So, <i>make</i> seems just the program that we always
+wanted. However, it is not very good in handling programs
+that generate more than one file. As usual, there is a way
+around this problem. A sample makefile follows:</p>
+<pre># The grammar exists of the files decl.g, stat.g and expr.g.
+# The &quot;.o&quot;-files are the result of a C-compilation.
+
+GFILES = decl.g stat.g expr.g
+OFILES = decl.o stat.o expr.o Lpars.o
+LLOPT =
+
+# As make does&rsquo;nt handle programs that generate more than one
+# file well, we just don&rsquo;t tell make about it.
+# We just create a dummy file, and touch it whenever LLgen is
+# executed. This way, the dummy in fact depends on the grammar
+# files.
+# Then, we execute make again, to do the C-compilations and
+# such.
+
+all: dummy
+        make parser
+
+dummy:  $(GFILES)
+        LLgen $(LLOPT) $(GFILES)
+        touch dummy
+
+parser: $(OFILES)
+        $(CC) -o parser $(LDFLAGS) $(OFILES)
+
+# Some dependencies without actions :
+# make already knows what to do about them
+
+Lpars.o:        Lpars.h
+stat.o:         Lpars.h
+decl.o:         Lpars.h
+expr.o:         Lpars.h
+
+</pre>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/LLgen.pdf b/src/olddocs/LLgen.pdf
new file mode 100644 (file)
index 0000000..2222280
Binary files /dev/null and b/src/olddocs/LLgen.pdf differ
diff --git a/src/olddocs/ack.html b/src/olddocs/ack.html
new file mode 100644 (file)
index 0000000..df716cc
--- /dev/null
@@ -0,0 +1,1353 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:05 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>Ack Description File</title>
+</head>
+<body>
+
+<h1 align=center>Ack Description File</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. Which descriptions are used">2. Which descriptions are used</a><br>
+<a href="#3. Using the description file">3. Using the description file</a><br>
+<a href="#4. Conventions used in description files">4. Conventions used in description files</a><br>
+<a href="#5. Example">5. Example</a><br>
+
+<hr>
+
+<p><b>Reference Manual</b></p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p><small>The program <i>ack</i>(I) internally maintains a
+table of possible transformations and a table of string
+variables. The transformation table contains one entry for
+each possible transformation of a file. Which
+transformations are used depends on the suffix of the source
+file. Each transformation table entry tells which input
+suffixes are allowed and what suffix/name the output file
+has. When the output file does not already satisfy the
+request of the user (indicated with the flag
+<b>&minus;c.suffix</b>), the table is scanned starting with
+the next transformation in the table for another
+transformation that has as input suffix the output suffix of
+the previous transformation. A few special transformations
+are recognized, among them is the combiner, which is a
+program combining several files into one. When no stop
+suffix was specified (flag <b>&minus;c.suffix</b>)
+<i>ack</i> stops after executing the combiner with as
+arguments the &minus; possibly transformed &minus; input
+files and libraries. <i>Ack</i> will only perform the
+transformations in the order in which they are presented in
+the table.</small></p>
+
+<p><small>The string variables are used while creating the
+argument list and program call name for a particular
+transformation.</small></p>
+<a name="2. Which descriptions are used"></a>
+<h2>2. Which descriptions are used</h2>
+
+<p><small><i>Ack</i> always uses two description files: one
+to define the front-end transformations and one for the
+machine dependent back-end transformations. Each description
+has a name. First the way of determining the name of the
+descriptions needed is described.</small></p>
+
+<p><small>When the shell environment variable ACKFE is set
+<i>ack</i> uses that to determine the front-end table name,
+otherwise it uses <b>fe</b>.</small></p>
+
+<p><small>The way the backend table name is determined is
+more convoluted.<br>
+First, when the last filename in the program call name is
+not one of <i>ack</i> or the front-end call-names, this
+filename is used as the backend description name. Second,
+when the <b>&minus;m</b> is present the <b>&minus;m</b> is
+chopped of this flag and the rest is used as the backend
+description name. Third, when both failed the shell
+environment variable ACKM is used. Last, when also ACKM was
+not present the default backend is used, determined by the
+definition of ACKM in h/local.h. The presence and value of
+the definition of ACKM is determined at compile time of
+<i>ack</i>.</small></p>
+
+<p><small>Now, we have the names, but that is only the
+first step. <i>Ack</i> stores a few descriptions at compile
+time. This descriptions are simply files read in at compile
+time. At the moment of writing this document, the
+descriptions included are: pdp, fe, i86, m68k2, vax2 and
+int. The name of a description is first searched for
+internally, then in lib/descr/<i>name</i>, then in
+lib/<i>name</i>/descr, and finally in the current directory
+of the user.</small></p>
+<a name="3. Using the description file"></a>
+<h2>3. Using the description file</h2>
+
+<p><small>Before starting on a narrative of the description
+file, the introduction of a few terms is necessary. All
+these terms are used to describe the scanning of zero
+terminated strings, thereby producing another string or
+sequence of strings.</small></p>
+
+<p><small>Backslashing</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>All characters preceded by \ are modified to
+prevent recognition at further scanning. This modification
+is undone before a string is passed to the outside world as
+argument or message. When reading the description files the
+sequences \\, \# and \&lt;newline&gt; have a special
+meaning. \\ translates to a single \, \# translates to a
+single # that is not recognized as the start of comment, but
+can be used in recognition and finally, \&lt;newline&gt;
+translates to nothing at all, thereby allowing continuation
+lines.</small></p>
+</td>
+</table>
+
+<p><small>Variable replacement</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>The scan recognizes the sequences {{, {NAME} and
+{NAME?text} Where NAME can be any combination if characters
+excluding ? and } and text may be anything excluding }. ( \}
+is allowed of course ) The first sequence produces an
+unescaped single {. The second produces the contents of the
+NAME, definitions are done by <i>ack</i> and in description
+files. When the NAME is not defined an error message is
+produced on the diagnostic output. The last sequence
+produces the contents of NAME if it is defined and text
+otherwise.</small></p>
+</td>
+</table>
+
+<p><small>Expression replacement</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Syntax: (<i>suffix sequence</i>:<i>suffix
+sequence</i>=<i>text</i>)<br>
+Example: (.c.p.e:.e=tail_em)<br>
+If the two suffix sequences have a common member &minus; .e
+in this case &minus; the text is produced. When no common
+member is present the empty string is produced. Thus the
+example given is a constant expression. Normally, one of the
+suffix sequences is produced by variable replacement.
+<i>Ack</i> sets three variables while performing the diverse
+transformations: HEAD, TAIL and RTS. All three variables
+depend on the properties <i>rts</i> and <i>need</i> from the
+transformations used. Whenever a transformation is used for
+the first time, the text following the <i>need</i> is
+appended to both the HEAD and TAIL variable. The value of
+the variable RTS is determined by the first transformation
+used with a <i>rts</i> property.</small></p>
+<!-- INDENTATION -->
+<p><small>Two runtime flags have effect on the value of one
+or more of these variables. The flag <b>&minus;.suffix</b>
+has the same effect on these three variables as if a file
+with that <b>suffix</b> was included in the argument list
+and had to be translated. The flag <b>&minus;r.suffix</b>
+only has that effect on the TAIL variable. The program call
+names <i>acc</i> and <i>cc</i> have the effect of an
+automatic <b>&minus;.c</b> flag. <i>Apc</i> and <i>pc</i>
+have the effect of an automatic <b>&minus;.p</b>
+flag.</small></p>
+</td>
+</table>
+
+<p><small>Line splitting</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>The string is transformed into a sequence of
+strings by replacing the blank space by string separators
+(nulls).</small></p>
+</td>
+</table>
+
+<p><small>IO replacement</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>The &gt; in the string is replaced by the output
+file name. The &lt; in the string is replaced by the input
+file name. When multiple input files are present the string
+is duplicated for each input file name.</small></p>
+</td>
+</table>
+
+<p><small>Each description is a sequence of variable
+definitions followed by a sequence of transformation
+definitions. Variable definitions use a line each,
+transformations definitions consist of a sequence of lines.
+Empty lines are discarded, as are lines with nothing but
+comment. Comment is started by a # character, and continues
+to the end of the line. Three special two-characters
+sequences exist: \#, \\ and \&lt;newline&gt;. Their effect
+is described under &rsquo;backslashing&rsquo; above. Each
+&minus; nonempty &minus; line starts with a keyword,
+possibly preceded by blank space. The keyword can be
+followed by a further specification. The two are separated
+by blank space.</small></p>
+
+<p><small>Variable definitions use the keyword <i>var</i>
+and look like this:</small></p>
+<pre><small>   var NAME=text
+</small></pre>
+
+<p><small>The name can be any identifier, the text may
+contain any character. Blank space before the equal sign is
+not part of the NAME. Blank space after the equal is
+considered as part of the text. The text is scanned for
+variable replacement before it is associated with the
+variable name.</small></p>
+
+<p><small>The start of a transformation definition is
+indicated by the keyword <i>name</i>. The last line of such
+a definition contains the keyword <i>end</i>. The lines in
+between associate properties to a transformation and may be
+presented in any order. The identifier after the <i>name</i>
+keyword determines the name of the transformation. This name
+is used for debugging and by the <b>&minus;R</b> flag. The
+keywords are used to specify which input suffices are
+recognized by that transformation, the program to run, the
+arguments to be handed to that program and the name or
+suffix of the resulting output file. Two keywords are used
+to indicate which run-time startoffs and libraries are
+needed. The possible keywords are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small><i>from</i></small></p>
+</td>
+<td width="91%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>followed by a sequence of suffices. Each file with
+one of these suffices is allowed as input file. Preprocessor
+transformations do not need the <i>from</i> keyword. All
+other transformations do.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><i>to</i></small></p>
+</td>
+<td width="95%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>followed by the suffix of the output file name or
+in the case of a linker the output file name.</small></p>
+</td>
+</table>
+
+<p><small><i>program</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>followed by name of the load file of the program,
+a pathname most likely starts with either a / or {EM}. This
+keyword must be present, the remainder of the line is
+subject to backslashing and variable
+replacement.</small></p>
+</td>
+</table>
+
+<p><small><i>mapflag</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>The mapflags are used to grab flags given to
+<i>ack</i> and pass them on to a specific transformation.
+This feature uses a few simple pattern matching and
+replacement facilities. Multiple occurrences of this keyword
+are allowed. This text following the keyword is subjected to
+backslashing. The keyword is followed by a match expression
+and a variable assignment separated by blank space. As soon
+as both description files are read, <i>ack</i> looks at all
+transformations in these files to find a match for the flags
+given to <i>ack</i>. The flags <b>&minus;m</b>,
+<b>&minus;o</b>, <b>&minus;O</b>, <b>&minus;r</b>,
+<b>&minus;v</b>, <b>&minus;g</b>, &minus;<b>&minus;c</b>,
+<b>&minus;t</b>, <b>&minus;k</b>, <b>&minus;R</b> and
+&minus;<b>&minus;.</b> are specific to <i>ack</i> and not
+handed down to any transformation. The matching is performed
+in the order in which the entries appear in the definition.
+The scanning stops after first match is found. When a match
+is found, the variable assignment is executed. A * in the
+match expression matches any sequence of characters, a * in
+the right hand part of the assignment is replaced by the
+characters matched by the * in the expression. The right
+hand part is also subject to variable replacement. The
+variable will probably be used in the program arguments. The
+<b>&minus;l</b> flags are special, the order in which they
+are presented to <i>ack</i> must be preserved. The
+identifier LNAME is used in conjunction with the scanning of
+<b>&minus;l</b> flags. The value assigned to LNAME is used
+to replace the flag. The example further on shows the use of
+all this.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small><i>args</i></small></p>
+</td>
+<td width="91%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>The keyword is followed by the program call
+arguments. It is subject to backslashing, variable
+replacement, expression replacement, line splitting and IO
+replacement. The variables assigned to by <i>mapflags</i>
+will probably be used here. The flags not recognized by
+<i>ack</i> or any of the transformations are passed to the
+linker and inserted before all other arguments.</small></p>
+</td>
+</table>
+
+<p><small><i>stdin</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This keyword indicates that the transformation
+reads from standard input.</small></p>
+</td>
+</table>
+
+<p><small><i>stdout</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This keyword indicates that the transformation
+writes on standard output.</small></p>
+</td>
+</table>
+
+<p><small><i>optimizer</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>The presence of this keyword indicates that this
+transformation is an optimizer. It can be followed by a
+number, indicating the &quot;level&quot; of the optimizer
+(see description of the -O option in the ack(1ACK) manual
+page).</small></p>
+</td>
+</table>
+
+<p><small><i>priority</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This &minus; optional &minus; keyword is followed
+by a number. Positive priority means that the transformation
+is likely to be used, negative priority means that the
+transformation is unlikely to be used. Priorities can also
+be set with a ack(1ACK) command line option. Priorities come
+in handy when there are several implementations of a certain
+transformation. They can then be used to select a default
+one.</small></p>
+</td>
+</table>
+
+<p><small><i>linker</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This keyword indicates that this transformation is
+the linker.</small></p>
+</td>
+</table>
+
+<p><small><i>combiner</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This keyword indicates that this transformation is
+a combiner. A combiner is a program combining several files
+into one, but is not a linker. An example of a combiner is
+the global optimizer.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small><i>prep</i></small></p>
+</td>
+<td width="91%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This &minus; optional &minus; keyword is followed
+an option indicating its relation to the preprocessor. The
+possible options are:</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>always</small></p>
+<td width="13%"></td>
+<td width="6%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>the input files must be preprocessed<br>
+cond</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>the input files must be preprocessed when
+starting with #<br>
+is</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%"></td>
+<td width="10%">
+
+<p><small>this transformation is the
+preprocessor</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small><i>rts</i></small></p>
+</td>
+<td width="93%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This &minus; optional &minus; keyword indicates
+that the rest of the line must be used to set the variable
+RTS, if it was not already set. Thus the variable RTS is set
+by the first transformation executed which such a property
+or as a result from <i>ack</i>&rsquo;s program call name
+(acc, cc, apc or pc) or by the <b>&minus;.suffix</b>
+flag.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small><i>need</i></small></p>
+</td>
+<td width="91%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This &minus; optional &minus; keyword indicates
+that the rest of the line must be concatenated to the HEAD
+and TAIL variables. This is done once for every
+transformation used or indicated by one of the program call
+names mentioned above or indicated by the
+<b>&minus;.suffix</b> flag.</small></p></td>
+</table>
+<a name="4. Conventions used in description files"></a>
+<h2>4. Conventions used in description files</h2>
+
+<p><small><i>Ack</i> reads two description files. A few of
+the variables defined in the machine specific file are used
+by the descriptions of the front-ends. Other variables, set
+by <i>ack</i>, are of use to all
+transformations.</small></p>
+
+<p><small><i>Ack</i> sets the variable EM to the home
+directory of the Amsterdam Compiler Kit. The variable SOURCE
+is set to the name of the argument that is currently being
+massaged, this is useful for debugging. The variable SUFFIX
+is set to the suffix of the argument that is currently being
+massaged.<br>
+The variable M indicates the directory in lib/{M}/tail_.....
+and NAME is the string to be defined by the preprocessor
+with &minus;D{NAME}. The definitions of {w}, {s}, {l}, {d},
+{f} and {p} indicate EM_WSIZE, EM_SSIZE, EM_LSIZE, EM_DSIZE,
+EM_FSIZE and EM_PSIZE respectively.<br>
+The variable INCLUDES is used as the last argument to
+<i>cpp</i>. It is used to add directories to the list of
+directories containing #include files.</small></p>
+
+<p><small>The variables HEAD, TAIL and RTS are set by
+<i>ack</i> and used to compose the arguments for the
+linker.</small></p>
+<a name="5. Example"></a>
+<h2>5. Example</h2>
+
+<p><small>Description for front-end</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>name cpp</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># the C-preprocessor</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># no from, it&rsquo;s governed by the P
+property</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>to .i</small></p>
+</td>
+<td width="20%">
+
+<p><small># result files have suffix i</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>program {EM}/lib/cpp</small></p>
+</td>
+<td width="20%">
+
+<p><small># pathname of loadfile</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>mapflag &minus;I* CPP_F={CPP_F?}
+&minus;I*</small></p>
+</td>
+<td width="20%">
+
+<p><small># grab &minus;I.. &minus;U.. and</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>mapflag &minus;U* CPP_F={CPP_F?}
+&minus;U*</small></p>
+</td>
+<td width="20%">
+
+<p><small># &minus;D.. to use as arguments</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>mapflag &minus;D* CPP_F={CPP_F?}
+&minus;D*</small></p>
+</td>
+<td width="20%">
+
+<p><small># in the variable CPP_F</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>args {CPP_F?} {INCLUDES?} &minus;D{NAME}
+&minus;DEM_WSIZE={w} &minus;DEM_PSIZE={p} \</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>&minus;DEM_SSIZE={s} &minus;DEM_LSIZE={l}
+&minus;DEM_FSIZE={f} &minus;DEM_DSIZE={d} &lt;</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># The arguments are: first the
+&minus;[IUD]...</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># then the include dir&rsquo;s for this
+machine</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># then the NAME and size values
+finally</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># followed by the input file name</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>stdout</small></p>
+</td>
+<td width="20%">
+
+<p><small># Output on stdout</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>prep is</small></p>
+</td>
+<td width="20%">
+
+<p><small># Is preprocessor</small></p>
+</td>
+</table>
+
+<p><small>end</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>name cem</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># the C-compiler proper</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>from .c</small></p>
+</td>
+<td width="20%">
+
+<p><small># used for files with suffix .c</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>to .k</small></p>
+</td>
+<td width="20%">
+
+<p><small># produces compact code files</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>program {EM}/lib/em_cem</small></p>
+</td>
+<td width="20%">
+
+<p><small># pathname of loadfile</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>mapflag &minus;p CEM_F={CEM_F?}
+&minus;Xp</small></p>
+</td>
+<td width="20%">
+
+<p><small># pass &minus;p as &minus;Xp to cem</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>mapflag &minus;L CEM_F={CEM_F?}
+&minus;l</small></p>
+</td>
+<td width="20%">
+
+<p><small># pass &minus;L as &minus;l to cem</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>args &minus;Vw{w}i{w}p{p}f{f}s{s}l{l}d{d}
+{CEM_F?}</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># the arguments are the object sizes
+in</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># the &minus;V... flag and possibly &minus;l and
+&minus;Xp</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>stdin</small></p>
+</td>
+<td width="20%">
+
+<p><small># input from stdin</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>stdout</small></p>
+</td>
+<td width="20%">
+
+<p><small># output on stdout</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>prep always</small></p>
+</td>
+<td width="20%">
+
+<p><small># use cpp</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>rts .c</small></p>
+</td>
+<td width="20%">
+
+<p><small># use the C run-time system</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>need .c</small></p>
+</td>
+<td width="20%">
+
+<p><small># use the C libraries</small></p>
+</td>
+</table>
+
+<p><small>end</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>name decode</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># make human readable files from compact
+code</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>from .k.m</small></p>
+</td>
+<td width="20%">
+
+<p><small># accept files with suffix .k or .m</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>to .e</small></p>
+</td>
+<td width="20%">
+
+<p><small># produce .e files</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>program {EM}/lib/em_decode</small></p>
+</td>
+<td width="20%">
+
+<p><small># pathname of loadfile</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>args &lt;</small></p>
+</td>
+<td width="20%">
+
+<p><small># the input file name is the only
+argument</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>stdout</small></p>
+</td>
+<td width="20%">
+
+<p><small># the output comes on stdout</small></p>
+</td>
+</table>
+
+<p><small>end</small></p>
+<pre><small>Example of a backend, in this case the EM assembler/loader.
+
+
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var w=2</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># wordsize 2</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var p=2</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># pointersize 2</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var s=2</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># short size 2</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var l=4</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># long size 4</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var f=4</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># float size 4</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var d=8</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># double size 8</small></p>
+</td>
+</table>
+
+<p><small>var M=em22</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var NAME=em22</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># for cpp (NAME=em22 results in #define em22
+1)</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var LIB=lib/{M}/tail_</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># part of file name for libraries</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var RT=lib/{M}/head_</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># part of file name for run-time
+startoff</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var SIZE_FLAG=&minus;sm</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># default internal table size flag</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>var INCLUDES=&minus;I{EM}/include</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># use {EM}/include for #include files</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>name asld</small></p>
+</td>
+<td width="72%"></td>
+<td width="20%">
+
+<p><small># Assembler/loader</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>from .k.m.a</small></p>
+</td>
+<td width="20%">
+
+<p><small># accepts compact code and archives</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>to e.out</small></p>
+</td>
+<td width="20%">
+
+<p><small># output file name</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>program {EM}/lib/em_ass</small></p>
+</td>
+<td width="20%">
+
+<p><small># load file pathname</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>mapflag &minus;l* LNAME={EM}/{LIB}*</small></p>
+</td>
+<td width="20%">
+
+<p><small># e.g. &minus;ly becomes</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small>#{EM}/mach/int/lib/tail_y</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>mapflag &minus;+* ASS_F={ASS_F?} &minus;+* #
+recognize &minus;+ and &minus;&minus;</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>mapflag &minus;&minus;* ASS_F={ASS_F?}
+&minus;&minus;*</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+
+<p><small>mapflag &minus;s* SIZE_FLAG=&minus;s*</small></p>
+</td>
+<td width="20%">
+
+<p><small># overwrite old value of SIZE_FLAG</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>args {SIZE_FLAG} \</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>({RTS}:.c={EM}/{RT}cc) ({RTS}:.p={EM}/{RT}pc)
+&minus;o &gt; &lt; \</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>(.p:{TAIL}={EM}/{LIB}pc) \</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>(.c:{TAIL}={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g)
+\</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>(.c.p:{TAIL}={EM}/{LIB}mon)</small></p>
+</td>
+<td width="20%">
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># &minus;s[sml] must be first
+argument</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># the next line contains the choice for head_cc
+or head_pc</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># and the specification of in- and
+output.</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="72%">
+</td>
+<td width="20%">
+
+<p><small># the last three args lines choose
+libraries</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>linker</small></p>
+</td>
+<td width="20%">
+</td>
+</table>
+
+<p><small>end</small></p>
+
+<p><small>The command <i>ack &minus;mem22 &minus;v &minus;v
+&minus;I../h &minus;L &minus;ly prog.c</i> would result in
+the following calls (with exec(II)):</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>1)</small></p>
+</td>
+<td width="92%">
+
+<p><small>/lib/cpp &minus;I../h &minus;I/usr/em/include
+&minus;Dem22 &minus;DEM_WSIZE=2 &minus;DEM_PSIZE=2
+\</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p><small>&minus;DEM_SSIZE=2 &minus;DEM_LSIZE=4
+&minus;DEM_FSIZE=4 &minus;DEM_DSIZE=8 prog.c</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>2)</small></p>
+</td>
+<td width="92%">
+
+<p><small>/usr/em/lib/em_cem &minus;Vw2i2p2f4s2l4d8
+&minus;l</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>3)</small></p>
+</td>
+<td width="92%">
+
+<p><small>/usr/em/lib/em_ass &minus;sm
+/usr/em/lib/em22/head_cc &minus;o e.out prog.k</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p><small>/usr/em/lib/em22/tail_y
+/usr/em/lib/em22/tail_cc.1s</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p><small>/usr/em/lib/em22/tail_cc.2g
+/usr/em/lib/em22/tail_mon</small></p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/ack.pdf b/src/olddocs/ack.pdf
new file mode 100644 (file)
index 0000000..24da57f
Binary files /dev/null and b/src/olddocs/ack.pdf differ
diff --git a/src/olddocs/ansi_C.html b/src/olddocs/ansi_C.html
new file mode 100644 (file)
index 0000000..4dadd47
--- /dev/null
@@ -0,0 +1,1254 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:14 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>Amsterdam Compiler Kit-ANSI C compiler compliance statements</title>
+</head>
+<body>
+
+<h1 align=center>Amsterdam Compiler Kit-ANSI C compiler compliance statements</h1>
+<a href="#References">References</a><br>
+
+<hr>
+
+<p>This document specifies the implementation-defined
+behaviour of the ANSI-C front end of the Amsterdam Compiler
+Kit as required by ANS X3.159-1989. Since the
+implementation-defined behaviour sometimes depends on the
+machine compiling on or for, some items will be left
+unspecified in this document&dagger;.</p>
+
+<p align=center><img src="grohtml-101091.png"></p>
+
+<p>The compiler assumes that it runs on a UNIX system.</p>
+
+<p><b>ANS A.6.3.1:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Diagnostics are placed on the standard error output.
+They have the following specification:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>&quot;&lt;file&gt;&quot;, line &lt;nr&gt;:
+[(&lt;class&gt;)] &lt;diagnostic&gt;<br>
+There are three classes of diagnostics: &quot;error&quot;,
+&quot;strict&quot; and &quot;warning&quot;. When the class
+is &quot;error&quot;, the &lt;class&gt; is absent.<br>
+The class &quot;strict&quot; is used for violations of the
+standard which are not severe enough to stop compilation. An
+example is the the occurrence of non white-space after an
+&rsquo;#else&rsquo; or &rsquo;#endif&rsquo; pre-processing
+directive. The class &quot;warning&quot; is used for legal
+but dubious constructions. An example is overflow of
+constant expressions.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.2:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The function &rsquo;main&rsquo; can have two arguments.
+The first argument is an integer specifying the number of
+arguments on the command line. The second argument is a
+pointer to an array of pointers to the arguments (as
+strings).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p>Interactive devices are terminals.</p>
+</td>
+<td width="21%">
+</td>
+</table>
+
+<p><b>ANS A.6.3.3:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The number of significant characters is an option. By
+default it is 64. There is a distinction between upper and
+lower case.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.4:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The compiler assumes ASCII-characters in both the source
+and execution character set.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="70%">
+
+<p>There are no multi-byte characters.</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p>There 8 bits in a character.</p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Character constants with values that can not be
+represented in 8 bits are truncated.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Character constants that are more than 1 character wide
+will have the first character specified in the least
+significant byte.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="66%">
+
+<p>The only supported locale is &quot;C&quot;.</p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A plain &rsquo;char&rsquo; has the same range of values
+as &rsquo;signed char&rsquo;.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.5:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The compiler assumes that it works on and compiles for a
+2-complement binary-number system. Shorts will use 2 bytes
+and longs will use 4 bytes. The size of integers are machine
+dependent.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Converting an integer to a shorter signed integer is
+implemented by ignoring the high-order byte(s) of the
+former. Converting a unsigned integer to a signed integer of
+the same type is only done in administration. This means
+that the bit-pattern remains unchanged.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The result of bitwise operations on signed integers are
+what can be expected on a 2-complement machine.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>If either operand is negative, whether the result of the
+/ operator is the largest integer less than or equal to the
+algebraic quotient or the smallest integer greater than or
+equal to the algebraic quotient is machine dependent, as is
+the sign of the result of the % operator.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The right-shift of a negative value is negative.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.6:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The representation of floating-point values is
+machine-dependent. When native floating-point is not present
+an IEEE-emulation is used. The compiler uses high-precision
+floating-point for constant folding.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Truncation is always to the nearest floating-point
+number that can be represented.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.7:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The type returned by the sizeof-operator (also known as
+size_t) is &rsquo;unsigned int&rsquo;. This is done for
+backward compatibility reasons.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Casting an integer to a pointer or vice versa has no
+effect in bit-pattern when the sizes are equal. Otherwise
+the value will be truncated or zero-extended (depending on
+the direction of the conversion and the relative sizes).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>When a pointer is as large as an integer, the type of a
+&rsquo;ptrdiff_t&rsquo; will be &rsquo;int&rsquo;. Otherwise
+the type will be &rsquo;long&rsquo;.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.8:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Since the front end has only limited control over the
+registers, it can only make it more likely that variables
+that are declared as registers also end up in registers. The
+only things that can possibly be put into registers are :
+&rsquo;int&rsquo;, &rsquo;long&rsquo;, &rsquo;float&rsquo;,
+&rsquo;double&rsquo;, &rsquo;long double&rsquo; and
+pointers.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.9:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>When a member of a union object is accessed using a
+member of a different type, the resulting value will usually
+be garbage. The compiler makes no effort to catch these
+errors.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The alignment of types is a compile-time option. The
+alignment of a structure-member is the alignment of its
+type. Usually, the alignment is passed on to the compiler by
+the &rsquo;ack&rsquo; program. When a user wants to do this
+manually, he/she should be prepared for trouble.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A &quot;plain&quot; &rsquo;int&rsquo; bit-field is taken
+as a &rsquo;signed int&rsquo;. This means that a field with
+a size of 1 bit can only store the values 0 and -1.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The order of allocation of bit-fields is a compile-time
+option. By default, high-order bits are allocated first.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>An enum has the same size as a &quot;plain&quot;
+&rsquo;int&rsquo;.</p>
+</td>
+<td width="0%">
+</td>
+</table>
+
+<p><b>ANS A.6.3.10:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>An access to a volatile declared variable is done by
+just mentioning the variable. E.g. the statement
+&quot;x;&quot; where x is declared volatile, constitutes an
+access.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>There is no fixed limit on the number of declarators
+that may modify an arithmetic, structure or union type,
+although specifying too many may cause the compiler to run
+out of memory.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.12:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The maximum number of cases in a switch-statement is in
+the order of 1e9, although the compiler may run out of
+memory somewhat earlier.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.13:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Since both the pre-processor and the compiler assume
+ASCII-characters, a single character constant in a
+conditional-inclusion directive matches the same value in
+the execution character set.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The pre-processor recognizes -I... command-line options.
+The directories thus specified are searched first. After
+that, depending on the command that the preprocessor is
+called with, machine/system-dependant directories are
+searched. After that, ~em/include/_tail_ac and /usr/include
+are visited.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Quoted names are first looked for in the directory in
+which the file which does the include resides.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The characters in a h- or q- char-sequence are taken to
+be UNIX paths.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Neither the compiler nor the preprocessor know any
+pragmas.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Since the compiler runs on UNIX, __DATE__ and __TIME__
+will always be defined.</p>
+</td>
+</table>
+
+<p><b>ANS A.6.3.14:</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>NULL is defined as ((void *)0). This in order to flag
+dubious constructions like &quot;int x = NULL;&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The diagnostic printed by &rsquo;assert&rsquo; is as
+follows:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="17%"></td>
+<td width="82%">
+<p>&quot;Assertion &quot;&lt;expr&gt;&quot; failed, file
+&quot;&lt;file&gt;&quot;, line &lt;line&gt;&quot;,</p></td>
+</table>
+</td>
+</table>
+
+<p>where &lt;expr&gt; is the argument to the assert macro,
+printed as string. (the &lt;file&gt; and &lt;line&gt; should
+be clear)</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="70%">
+
+<p>The sets for character test macros.</p>
+</td>
+<td width="19%">
+</td>
+</table>
+
+<p align=center><img src="grohtml-101092.png"></p>
+
+<p>As an addition, there is an isascii() macro, which tests
+whether a character is an ascii character. Characters in the
+range from \000 to \177 are ascii characters.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The behaviour of mathematic functions on domain
+error:</p>
+</td>
+</table>
+
+<p align=center><img src="grohtml-101093.png"></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Underflow range errors do not cause errno to be set.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The function fmod() returns 0.0 and sets errno to EDOM
+when the second argument is 0.0.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The set of signals for the signal() function depends on
+the UNIX-system which the compiler is compiling for. The
+default handling, semantics and behaviour of these signals
+are those specified by the operating system vendor. The
+default handling is not reset when SIGILL is received.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A text-stream need not end in a new-line character.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>White space characters before a new-line appear when
+read in.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>There may be any number of null characters appended to a
+binary stream.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The file position indicator of an append mode stream is
+initially positioned at the beginning of the file.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A write on a text stream does not cause the associated
+file to be truncated beyond that point.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The buffering intended by the standard is fully
+supported.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="70%">
+
+<p>A zero-length file actually exists.</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A file name can consist of any character, except for the
+&rsquo;\0&rsquo; and the &rsquo;/&rsquo;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p>A file can be open multiple times.</p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>When a remove() is done on an open file, reading and
+writing behave just as can be expected from a non-removed
+file. When the associated stream is closed, all written data
+will be lost.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>When a file exists prior to a call to rename(), the
+behaviour is that of the underlying UNIX system. Normally,
+the call would fail.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The %p conversion in fprintf() has the same effect as
+%#x or %#lx, depending on the sizes of pointer and
+integer.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The %p conversion in fscanf() has the same effect as %x
+or %lx, depending on the sizes of pointer and integer.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A - character that is neither the first nor the last
+character in the scanlist for %[ conversion is taken to be a
+range indicator. When the first character has a higher
+ASCII-value than the second, the - will just be put into the
+scanlist.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The value of errno when fgetpos() or ftell() failed is
+that of lseek(). This means:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="14%">
+
+<p>EBADF &minus;</p>
+</td>
+<td width="6%"></td>
+<td width="56%">
+
+<p>when the stream is not valid</p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="16%">
+
+<p>ESPIPE &minus;</p>
+</td>
+<td width="4%"></td>
+<td width="70%">
+
+<p>when fildes is associated with a pipe (and on some
+systems: sockets)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="16%">
+
+<p>EINVAL &minus;</p>
+</td>
+<td width="4%"></td>
+<td width="70%">
+
+<p>the resulting file pointer would be negative</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The messages generated by perror() depend on the value
+of errno. The mapping of errors to strings is done by
+strerror().</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>When the requested size is zero, malloc(), calloc() and
+realloc() return a null-pointer.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>When abort() is called, output buffers will be flushed.
+Temporary files (made with the tmpfile() function) will have
+disappeared when SIGABRT is not caught or ignored.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The exit() function returns the low-order eight bits of
+its argument to the environment.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The predefined environment names are controlled by the
+user. Setting environment variables is done through the
+putenv() function. This function accepts a pointer to char
+as its argument. To set f.i. the environment variable TERM
+to a230 one writes</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="17%"></td>
+<td width="82%">
+<p>putenv(&quot;TERM=a230&quot;);</p></td>
+</table>
+</td>
+</table>
+
+<p>The argument to putenv() is stored in an internal table,
+so malloc&rsquo;ed strings can not be freed until another
+call to putenv() (which sets the same environment variable)
+is made. The function returns 1 if it fails, 0
+otherwise.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The argument to system is passed as argument to /bin/sh
+-c.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The strings returned by strerror() depend on errno in
+the following way:</p>
+</td>
+</table>
+
+<p align=center><img src="grohtml-101094.png"></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>everything else causes strerror() to return &quot;unknown
+error&quot;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The local time zone is per default MET (GMT + 1:00:00).
+This can be changed through the TZ environment variable, or
+by some changes in the sources.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The clock() function returns the number of ticks since
+process startup.</p>
+</td>
+</table>
+<a name="References"></a>
+<h2>References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[1]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>ANS X3.159-1989 <i>American National Standard for
+Information Systems - Programming Language C</i></p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/ansi_C.pdf b/src/olddocs/ansi_C.pdf
new file mode 100644 (file)
index 0000000..9447fa8
Binary files /dev/null and b/src/olddocs/ansi_C.pdf differ
diff --git a/src/olddocs/basic.html b/src/olddocs/basic.html
new file mode 100644 (file)
index 0000000..f2c1057
--- /dev/null
@@ -0,0 +1,3850 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:11 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The ABC compiler</title>
+</head>
+<body>
+
+<h1 align=center>The ABC compiler</h1>
+<a href="#INTRODUCTION.">INTRODUCTION.</a><br>
+<a href="#SYNTAX NOTATION">SYNTAX NOTATION</a><br>
+<a href="#1. GENERAL INFORMATION">1. GENERAL INFORMATION</a><br>
+<a href="#1.1. LINE FORMAT">1.1. LINE FORMAT</a><br>
+<a href="#1.2. CONSTANTS">1.2. CONSTANTS</a><br>
+<a href="#1.3. VARIABLES">1.3. VARIABLES</a><br>
+<a href="#1.4. EXPRESSIONS">1.4. EXPRESSIONS</a><br>
+<a href="#Arithmetic">Arithmetic</a><br>
+<a href="#Relational">Relational</a><br>
+<a href="#Logical">Logical</a><br>
+<a href="#Functional">Functional</a><br>
+<a href="#String operations">String operations</a><br>
+<a href="#1.5. ERROR MESSAGES">1.5. ERROR MESSAGES</a><br>
+<a href="#2. B-EM STATEMENTS">2. B-EM STATEMENTS</a><br>
+<a href="#2.1. CALL">2.1. CALL</a><br>
+<a href="#2.2. CLOSE">2.2. CLOSE</a><br>
+<a href="#2.3. DATA">2.3. DATA</a><br>
+<a href="#2.4. DEF FN">2.4. DEF FN</a><br>
+<a href="#2.5. DEFINT/SNG/DBL/STR">2.5. DEFINT/SNG/DBL/STR</a><br>
+<a href="#2.6. DIM">2.6. DIM</a><br>
+<a href="#2.7. END">2.7. END</a><br>
+<a href="#2.8. ERR and ERL">2.8. ERR and ERL</a><br>
+<a href="#2.9. ERROR">2.9. ERROR</a><br>
+<a href="#2.10. FIELD">2.10. FIELD</a><br>
+<a href="#2.11. FOR...NEXT">2.11. FOR...NEXT</a><br>
+<a href="#2.12. GET">2.12. GET</a><br>
+<a href="#2.13. GOSUB...RETURN">2.13. GOSUB...RETURN</a><br>
+<a href="#2.14. GOTO">2.14. GOTO</a><br>
+<a href="#2.15. IF...THEN">2.15. IF...THEN</a><br>
+<a href="#2.16. INPUT">2.16. INPUT</a><br>
+<a href="#2.17. INPUT [#]">2.17. INPUT [#]</a><br>
+<a href="#2.18. LET">2.18. LET</a><br>
+<a href="#2.19. LINE INPUT">2.19. LINE INPUT</a><br>
+<a href="#2.20. LINE INPUT [#]">2.20. LINE INPUT [#]</a><br>
+<a href="#2.21. LSET and RSET">2.21. LSET and RSET</a><br>
+<a href="#2.22. MID$">2.22. MID$</a><br>
+<a href="#2.23. ON ERROR GOTO">2.23. ON ERROR GOTO</a><br>
+<a href="#2.24. ON...GOSUB and ON ...GOTO">2.24. ON...GOSUB and ON ...GOTO</a><br>
+<a href="#2.25. OPEN">2.25. OPEN</a><br>
+<a href="#2.26. OPTION BASE">2.26. OPTION BASE</a><br>
+<a href="#2.27. POKE">2.27. POKE</a><br>
+<a href="#2.28. PRINT">2.28. PRINT</a><br>
+<a href="#2.29. PRINT USING">2.29. PRINT USING</a><br>
+<a href="#2.30. PUT">2.30. PUT</a><br>
+<a href="#2.31. RANDOMIZE">2.31. RANDOMIZE</a><br>
+<a href="#2.32. READ">2.32. READ</a><br>
+<a href="#2.33. REM">2.33. REM</a><br>
+<a href="#2.34. RESTORE">2.34. RESTORE</a><br>
+<a href="#2.35. STOP">2.35. STOP</a><br>
+<a href="#2.36. SWAP">2.36. SWAP</a><br>
+<a href="#2.37. TRON/TROFF">2.37. TRON/TROFF</a><br>
+<a href="#2.38. WHILE...WEND">2.38. WHILE...WEND</a><br>
+<a href="#2.39. WRITE">2.39. WRITE</a><br>
+<a href="#2.40. WRITE #">2.40. WRITE #</a><br>
+<a href="#3. FUNCTIONS">3. FUNCTIONS</a><br>
+<a href="#APPENDIX A DIFFERENCES WITH MICROSOFT BASIC">APPENDIX A DIFFERENCES WITH MICROSOFT BASIC</a><br>
+<a href="#APPENDIX B RESERVED WORDS IN BASIC-EM">APPENDIX B RESERVED WORDS IN BASIC-EM</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Martin L. Kersten<br>
+Gert-Jan Akkerman<br>
+Marcel Worring<br>
+Edo Westerhuis<br>
+Frans Kunst<br>
+Ronnie Lachniet</i><br>
+Department of Mathematics and Computer Science.<br>
+Free University<br>
+Amsterdam</p>
+
+<p>This manual describes the programming language BASIC and
+its compiler included in the Amsterdam Compiler Kit.</p>
+<a name="INTRODUCTION."></a>
+<h2>INTRODUCTION.</h2>
+
+<p>The BASIC-EM compiler is an extensive implementation of
+the programming language BASIC. The language structure and
+semantics are modelled after the BASIC interpreter/compiler
+of Microsoft (tr), a short comparison is provided in
+appendix A.</p>
+
+<p>The compiler generates code for a virtual machine, the
+EM machine [[ACM, etc]]. Using EM as an intermediate machine
+results in a highly portable compiler and BASIC code.<br>
+The drawback of EM is that it does not directly reflect one
+particular hardware design, which means that many of the low
+level operations available within BASIC are ill-defined or
+even inapplicable. To mention a few, the peek and poke
+instructions are likely to be behave errorneous, while line
+printer and tapedeck primitives are unknown.</p>
+
+<p>This manual is divided into three chapters.<br>
+Chapter 1 discusses the general language syntax and
+semantics.<br>
+Chapter 2 describes the statements available in
+BASIC-EM.<br>
+Chapter 3 describes the predefined functions, ordered
+alphabetically.</p>
+
+<p>Appendix A discusses the differences with Microsoft
+BASIC.<br>
+Appendix B describes all reserved symbols.</p>
+<a name="SYNTAX NOTATION"></a>
+<h2>SYNTAX NOTATION</h2>
+
+<p>The conventions for syntax presentation are as
+follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>CAPS</p>
+</td>
+<td width="12%"></td>
+<td width="80%">
+
+<p>Items are reserved words, must be input as shown.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>&lt;&gt;</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>Items in lowercase letters enclosed in angular brackets
+are to be supplied by the user.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>[]</p>
+</td>
+<td width="16%"></td>
+<td width="38%">
+
+<p>Items are optional.</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="82%">
+
+<p>Items may be repeated any number of times</p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>{}</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>A choice between two or more alternatives. At least one
+of the entries must be chosen.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>|</p>
+</td>
+<td width="18%"></td>
+<td width="80%">
+
+<p>Vertical bars separate the choices within braces.</p>
+</td>
+</table>
+
+<p>All punctuation must be included where shown.</p>
+<a name="1. GENERAL INFORMATION"></a>
+<h2>1. GENERAL INFORMATION</h2>
+
+<p>The BASIC-EM compiler is designed for a UNIX based
+environment. It accepts a text file with a BASIC program
+(suffix .b) and generates an executable file, called
+a.out.</p>
+<a name="1.1. LINE FORMAT"></a>
+<h2>1.1. LINE FORMAT</h2>
+
+<p>A BASIC program consists of a series of lines, starting
+with a positive line number in the range 0 to 32767. A line
+may consists of more than one physical line on a terminal,
+but is limited to 1024 characters. Multiple BASIC statements
+may be placed on a single line, provided they are separated
+by a colon (:).</p>
+<a name="1.2. CONSTANTS"></a>
+<h2>1.2. CONSTANTS</h2>
+
+<p>The BASIC compiler character set is comprised of
+alphabetic characters, numeric characters, and special
+characters shown below.</p>
+<pre>     = + - * / ^ ( ) % # $ \ _
+     ! [ ] , . ; : &amp; &rsquo; ? &gt; &lt;  \ (blanc)
+</pre>
+
+<p>BASIC uses two different types of constants during
+processing: numeric and string constants.<br>
+A string constant is a sequence of characters taken from the
+ASCII character set enclosed by double quotation marks.<br>
+Numeric constants are positive or negative numbers, grouped
+into five different classes.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="40%">
+
+<p>a) integer constants</p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="49%"></td>
+<td width="50%">
+<p>Whole numbers in the range of -32768 and 32767. Integer
+constants do not contain decimal points.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="48%">
+
+<p>b) fixed point constants</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="49%"></td>
+<td width="50%">
+<p>Positive or negative real numbers, i.e. numbers with a
+decimal point.</p>
+</td>
+</table>
+
+<p>c) floating point constants</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="49%"></td>
+<td width="50%">
+<p>Real numbers in scientific notation. A floating point
+constant consists of an optional signed integer or fixed
+point number followed by the letter E (or D) and an optional
+signed integer (the exponent). The allowable range of
+floating point constants is 10^-38 to 10^+38.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%">
+
+<p>d) Hex constants</p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="49%"></td>
+<td width="50%">
+<p>Hexadecimal numbers, denoted by the prefix &amp;H.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="36%">
+
+<p>e) Octal constants</p>
+</td>
+<td width="63%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="49%"></td>
+<td width="50%">
+<p>Octal numbers, denoted by the prefix &amp;O.</p></td>
+</table>
+<a name="1.3. VARIABLES"></a>
+<h2>1.3. VARIABLES</h2>
+
+<p>Variables are names used to represent values in a BASIC
+program. A variable is assigned a value by assigment
+specified in the program. Before a variable is assigned its
+value is assumed to be zero.<br>
+Variable names are composed of letters, digits or the
+decimal point, starting with a letter. Up to 40 characters
+are significant. A variable name can be followed by any of
+the following type declaration characters:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>%</p>
+</td>
+<td width="8%"></td>
+<td width="54%">
+
+<p>Defines an integer variable</p>
+</td>
+<td width="35%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>!</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Defines a single precision variable (see below)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>#</p>
+</td>
+<td width="8%"></td>
+<td width="70%">
+
+<p>Defines a double precision variable</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>$</p>
+</td>
+<td width="8%"></td>
+<td width="52%">
+
+<p>Defines a string variable.</p>
+</td>
+<td width="37%">
+</td>
+</table>
+
+<p>Beside single valued variables, values may be grouped
+into tables or arrays. Each element in an array is
+referenced by the array name and an index, such a variable
+is called a subscripted variable. An array has as many
+subscripts as there are dimensions in the array, the maximum
+of which is 11.<br>
+If a variable starts with FN it is assumed to be a call to a
+user defined function.<br>
+A variable name may not be a reserved word nor the name of a
+predefined function. A list of all reserved identifiers is
+included as Appendix B.</p>
+
+<p>NOTES:<br>
+Two variables with the same name but different type is
+considered illegal.<br>
+The type of a variable without typedeclaration-character is
+set, at it&rsquo;s first occurence in the program, to the
+defaulttype which is (in this implementation) double
+precision.<br>
+Multi-dimensional array&rsquo;s must be declared before use
+(see DIM-statement ).<br>
+BASIC-EM differs from Microsoft BASIC in supporting floats
+in one precision only (due to EM), eg doubles and floats
+have the same precision.</p>
+<a name="1.4. EXPRESSIONS"></a>
+<h2>1.4. EXPRESSIONS</h2>
+
+<p>When necessary the compiler will convert a numeric value
+from one type to another. A value is always converted to the
+precision of the variable it is assigned to. When a floating
+point value is converted to an integer the fractional
+portion is rounded. In an expression all values are
+converted to the same degree of precision, i.e. that of the
+most precise operand.<br>
+Division by zero results in the message &quot;Division by
+zero&quot;. If overflow (or underflow) occurs, the
+&quot;Overflow (underflow)&quot; message is displayed and
+execution is terminated (contrary to Microsoft).</p>
+<a name="Arithmetic"></a>
+<h2>Arithmetic</h2>
+
+<p>The arithmetic operators in order of precedence,a
+re:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>^</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Exponentiation</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>-</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Negation</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>*,/,\\\\,MOD</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>Multiplication, Division, Remainder</p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>+,-</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Addition, Substraction</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+
+<p>The operator \\ denotes integer division, its operands
+are rounded to integers before the operator is applied.
+Modulus arithmetic is denoted by the operator MOD, which
+yields the integer value that is the remainder of an integer
+division.<br>
+The order in which operators are performed can be changed
+with parentheses.</p>
+<a name="Relational"></a>
+<h2>Relational</h2>
+
+<p>The relational operators in order of precedence,
+are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>=</p>
+<td width="9%"></td>
+<td width="10%">
+
+<p>Equality<br>
+&lt;&gt;</p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Inequality<br>
+&lt;</p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Less than<br>
+&gt;</p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Greater than<br>
+&lt;=</p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Less than or equal to<br>
+&gt;=</p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Greater than or equal to</p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+</table>
+
+<p>The relational operators are used to compare two values
+and returns either &quot;true&quot; (-1) or
+&quot;false&quot; (0) (See IF statement). The precedence of
+the relational operators is lower then the arithmetic
+operators.</p>
+<a name="Logical"></a>
+<h2>Logical</h2>
+
+<p>The logical operators performs tests on multiple
+relations, bit manipulations, or boolean operations. The
+logical operators returns a bitwise result (&quot;true&quot;
+or &quot;false&quot;). In an expression, logical operators
+are performed after the relational and arithmetic operators.
+The logical operators work by converting their operands to
+signed two-complement integers in the range -32768 to
+32767.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>NOT</p>
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Bitwise negation<br>
+AND</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Bitwise and<br>
+OR</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Bitwise or<br>
+XOR</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Bitwise exclusive or<br>
+EQV</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Bitwise equivalence<br>
+IMP</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>Bitwise implies</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+<a name="Functional"></a>
+<h2>Functional</h2>
+
+<p>A function is used in an expression to call a system or
+user defined function. A list of predefined functions is
+presented in chapter 3.</p>
+<a name="String operations"></a>
+<h2>String operations</h2>
+
+<p>Strings can be concatenated by using +. Strings can be
+compared with the relational operators. String comparison is
+performed in lexicographic order.</p>
+<a name="1.5. ERROR MESSAGES"></a>
+<h2>1.5. ERROR MESSAGES</h2>
+
+<p>The occurence of an error results in termination of the
+program unless an ON....ERROR statement has been
+encountered.</p>
+<a name="2. B-EM STATEMENTS"></a>
+<h2>2. B-EM STATEMENTS</h2>
+
+<p>This chapter describes the statements available within
+the BASIC-EM compiler. Each description is formatted as
+follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>Shows the correct syntax for the statement. See
+introduction of syntax notation above.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Describes the purpose and details of the
+instructions.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>remarks</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Describes special cases, deviation from Microsoft BASIC
+etc.</p>
+</td>
+</table>
+<a name="2.1. CALL"></a>
+<h2>2.1. CALL</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="78%">
+
+<p>CALL &lt;variable name&gt;[(&lt;argument list&gt;)]</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>The CALL statement provides the means to execute
+procedures and functions written in another language
+included in the Amsterdam Compiler Kit. The argument list
+consist of (subscripted) variables. The BASIC compiler
+pushes the address of the arguments on the stack in order of
+encounter.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>remarks</b></p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>Not yet available.</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<a name="2.2. CLOSE"></a>
+<h2>2.2. CLOSE</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>CLOSE [[#]&lt;file number&gt;[,[#]&lt;file
+number...&gt;]]</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To terminate I/O on a disk file. &lt;file number&gt; is
+the number associated with the file when it was OPENed (See
+OPEN-statement). Ommission of parameters results in closing
+all files.</p>
+</td>
+</table>
+
+<p>The END statement and STOP statement always issue a
+CLOSE of all files.</p>
+<a name="2.3. DATA"></a>
+<h2>2.3. DATA</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="48%">
+
+<p>DATA &lt;list of constants&gt;</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>DATA statements are used to construct a data bank of
+values that are accessed by the program&rsquo;s READ
+statement. DATA statements are non-executable, the data
+items are assembled in a data file by the BASIC compiler.
+This file can be replaced, provided the layout remains the
+same (otherwise the RESTORE won&rsquo;t function
+properly).</p>
+</td>
+</table>
+
+<p>The list of data items consists of numeric and string
+constants as discussed in section 1. Moreover, string
+constants starting with a letter and not containing blancs,
+newlines, commas, colon need not be enclosed with the string
+quotes.</p>
+
+<p>DATA statements can be reread using the RESTORE
+statement.</p>
+<a name="2.4. DEF FN"></a>
+<h2>2.4. DEF FN</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>DEF FN&lt;name&gt;
+[(&lt;parameterlist&gt;)]=&lt;expression&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To define and name a function that is written by the
+user. &lt;name&gt; must be an identifier and should be
+preceded by FN, which is considered integral part of the
+function name. &lt;expression&gt; defines the expression to
+be evaluated upon function call.</p>
+</td>
+</table>
+
+<p>The parameter list is comprised of a comma separated
+list of variable names, used within the function definition,
+that are to replaced by values upon function call. The
+variable names defined in the parameterlist, called formal
+parameters, do not affect the definition and use of
+variables defined with the same name in the rest of the
+BASIC program.</p>
+
+<p>A type declaration character may be suffixed to the
+function name to designate the data type of the function
+result.</p>
+<a name="2.5. DEFINT/SNG/DBL/STR"></a>
+<h2>2.5. DEFINT/SNG/DBL/STR</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p>DEF&lt;type&gt; &lt;range of letters&gt;</p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Any undefined variable starting with the letter included
+in the range of letters is declared of type &lt;type&gt;
+unless a type declaration character is appended. The range
+of letters is a comma separated list of characters and
+character ranges (&lt;letter&gt;-&lt;letter&gt;).</p>
+</td>
+</table>
+<a name="2.6. DIM"></a>
+<h2>2.6. DIM</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p>DIM &lt;list of subscripted variable&gt;</p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>The DIM statement allocates storage for subscripted
+variables. If an undefined subscripted variable is used the
+maximum value of the array subscript is assumed to be 10. A
+subscript out of range is signalled by the program (when ACK
+works) The minimum subscript value is 0, unless the OPTION
+BASE statement has been encountered.</p>
+</td>
+</table>
+
+<p>All variables in a subscripted variable are initially
+zero.</p>
+
+<p>BUGS. Multi-dimensional arrays MUST be defined.
+Subscript out of range is left unnotified.</p>
+<a name="2.7. END"></a>
+<h2>2.7. END</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="6%">
+
+<p>END</p>
+</td>
+<td width="73%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>END terminates a BASIC program and returns to the UNIX
+shell. An END statement at the end of the BASIC program is
+optional.</p>
+</td>
+</table>
+<a name="2.8. ERR and ERL"></a>
+<h2>2.8. ERR and ERL</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="44%">
+
+<p>&lt;identifier name&gt;= ERR</p>
+</td>
+<td width="35%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>&lt;identifier name&gt;= ERL</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Whenever an error occurs the variable ERR contains the
+error number and ERL the BASIC line where the error
+occurred. The variables are usually used in error handling
+routines provided by the user.</p>
+</td>
+</table>
+<a name="2.9. ERROR"></a>
+<h2>2.9. ERROR</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="52%">
+
+<p>ERROR &lt;integer expression&gt;</p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To simulate the occurrence of a BASIC error. To define a
+private error code a value must be used that is not already
+in use by the BASIC runtime system. The list of error
+messages currently in use can be found in appendix B.</p>
+</td>
+</table>
+<a name="2.10. FIELD"></a>
+<h2>2.10. FIELD</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>To be implemented.</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<a name="2.11. FOR...NEXT"></a>
+<h2>2.11. FOR...NEXT</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>FOR &lt;variable&gt;=
+&lt;low&gt;TO&lt;high&gt;[STEP&lt;size&gt;]</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>......<br>
+NEXT [&lt;variable&gt;][,&lt;variable&gt;...]</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>The FOR statements allows a series of statements to be
+performed repeatedly. &lt;variable&gt; is used as a counter.
+During the first execution pass it is assigned the value
+&lt;low&gt;, an arithmetic expression. After each pass the
+counter is incremented (decremented) with the step size
+&lt;size&gt;, an expression. Ommission of the step size is
+intepreted as an increment of 1.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Execution of the program lines specified between the FOR
+and the NEXT statement is terminated as soon as &lt;low&gt;
+is greater (less) than &lt;high&gt;</p>
+<!-- INDENTATION -->
+<p>The NEXT statement is labeled with the name(s) of the
+counter to be incremented.</p>
+<!-- INDENTATION -->
+<p>The variables mentioned in the NEXT statement may be
+ommitted, in which case the variable of increment the
+counter of the most recent FOR statement. If a NEXT
+statement is encountered before its corresponding FOR
+statement, the error message &quot;NEXT without FOR&quot; is
+generated.</p></td>
+</table>
+<a name="2.12. GET"></a>
+<h2>2.12. GET</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="78%">
+
+<p>GET [#]&lt;file number&gt;[, &lt;record number&gt;]</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>To be implemented.</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<a name="2.13. GOSUB...RETURN"></a>
+<h2>2.13. GOSUB...RETURN</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="38%">
+
+<p>GOSUB &lt;line number&gt; ...</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>RETURN</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>The GOSUB statement branches to the first statement of a
+subroutine. The RETURN statement cause a branch back to the
+statement following the most recent GOSUB statement. A
+subroutine may contain more than one RETURN statement.</p>
+</td>
+</table>
+
+<p>Subroutines may be called recursively. Nesting of
+subroutine calls is limited, upon exceeding the maximum
+depth the error message &quot;XXXXX&quot; is displayed.</p>
+<a name="2.14. GOTO"></a>
+<h2>2.14. GOTO</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="36%">
+
+<p>GOTO &lt;line number&gt;</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To branch unconditionally to a specified line in the
+program. If &lt;line number&gt; does not exists, the
+compilation error message &quot;Line not defined&quot; is
+displayed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>remarks</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Microsoft BASIC continues at the first line equal or
+greater then the line specified.</p>
+</td>
+</table>
+<a name="2.15. IF...THEN"></a>
+<h2>2.15. IF...THEN</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="87%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>IF &lt;expression&gt; THEN {&lt;statements&gt;|&lt;line
+number&gt;} [ELSE {&lt;statements&gt;|&lt;line
+number&gt;}]</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>IF &lt;expression&gt; GOTO &lt;line number&gt; [ELSE
+{&lt;statements&gt;|&lt;line number&gt;}]</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>The IF statement is used to make a decision regarding
+the program flow based on the result of the expressions. If
+the expression is not zero, the THEN or GOTO clause is
+executed. If the result of &lt;expression&gt; is zero, the
+THEN or GOTO clause is ignored and the ELSE clause, if
+present is executed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>IF..THEN..ELSE statements may be nested. Nesting is
+limited by the length of the line. The ELSE clause matches
+with the closests unmatched THEN.</p>
+<!-- INDENTATION -->
+<p>When using IF to test equality for a value that is the
+result of a floating point expression, remember that the
+internal representation of the value may not be exact.
+Therefore, the test should be against a range to handle the
+relative error.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>remarks</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Microsoft BASIC allows a comma before THEN.</p>
+</td>
+</table>
+<a name="2.16. INPUT"></a>
+<h2>2.16. INPUT</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>INPUT [;][&lt;&quot;prompt string&quot;&gt;;]&lt;list of
+variables&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>An INPUT statement can be used to obtain values from the
+user at the terminal. When an INPUT statement is encountered
+a question mark is printed to indicate the program is
+awaiting data. IF &lt;&quot;prompt string&quot;&gt; is
+included, the string is printed before the the question
+mark. The question mark is suppressed when the prompt string
+is followed by a comma, rather then a semicolon.</p>
+</td>
+</table>
+
+<p>For each variable in the variable a list a value should
+be supplied. Data items presented should be separated by a
+comma.</p>
+
+<p>The type of the variable in the variable list must
+aggree with the type of the data item entered. Responding
+with too few or too many data items causes the message
+&quot;?Redo&quot;. No assignment of input values is made
+until an acceptable response is given.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>remarks</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>The option to disgard the carriage return with the
+semicolon after the input symbol is not yet implemented.</p>
+</td>
+</table>
+<a name="2.17. INPUT [#]"></a>
+<h2>2.17. INPUT [#]</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>INPUT #&lt;file number&gt;,&lt;list of variables&gt;</p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>The purpose of the INPUT# statement is to read data
+items from a sequential file and assign them to program
+variables. &lt;file number&gt; is the number used to open
+the file for input. The variables mentioned are
+(subscripted) variables. The type of the data items read
+should aggree with the type of the variables. A type
+mismatch results in the error message &quot;XXXXX&quot;.</p>
+</td>
+</table>
+
+<p>The data items on the sequential file are separated by
+commas and newlines. In scanning the file, leading spaces,
+new lines, tabs, and carriage returns are ignored. The first
+character encountered is assumed to be the state of a new
+item. String items need not be enclosed with double quotes,
+provided it does not contain spaces, tabs, newlines and
+commas,</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>remarks</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Microsoft BASIC won&rsquo;t assign values until the end
+of input statement. This means that the user has to supply
+all the information.</p>
+</td>
+</table>
+<a name="2.18. LET"></a>
+<h2>2.18. LET</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p>[LET]&lt;variable&gt;=&lt;expression&gt;</p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To assign the value of an expression to a (subscribted)
+variable. The type convertions as dictated in chapter 1
+apply.</p>
+</td>
+</table>
+<a name="2.19. LINE INPUT"></a>
+<h2>2.19. LINE INPUT</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>LINE INPUT [;][&lt;&quot;prompt
+string&quot;&gt;;]&lt;string variable&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>An entire line of input is assigned to the string
+variable. See INPUT for the meaning of the &lt;&quot;prompt
+string&quot;&gt; option.</p>
+</td>
+</table>
+<a name="2.20. LINE INPUT [#]"></a>
+<h2>2.20. LINE INPUT [#]</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>LINE INPUT #&lt;file number&gt;,&lt;string
+variable&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Read an entire line of text from a sequential file
+&lt;file number&gt; and assign it to a string variable.</p>
+</td>
+</table>
+<a name="2.21. LSET and RSET"></a>
+<h2>2.21. LSET and RSET</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>To be implemented</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<a name="2.22. MID$"></a>
+<h2>2.22. MID$</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>MID$(&lt;string expr1&gt;,n[,m])=&lt;string
+expr2&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To replace a portion of a string with another string
+value. The characters of &lt;string expr2&gt; replaces
+characters in &lt;string expr1&gt; starting at position n.
+If m is present, at most m characters are copied, otherwise
+all characters are copied. However, the string obtained
+never exceeds the length of string expr1.</p>
+</td>
+</table>
+<a name="2.23. ON ERROR GOTO"></a>
+<h2>2.23. ON ERROR GOTO</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="54%">
+
+<p>ON ERROR GOTO &lt;line number&gt;</p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To enable error handling within the BASIC program. An
+error may result from arithmetic errors, disk problems,
+interrupts, or as a result of the ERROR statement. After
+printing an error message the program is continued at the
+statements associated with &lt;line number&gt;.</p>
+</td>
+</table>
+
+<p>Error handling is disabled using ON ERROR GOTO 0.
+Subsequent errors result in an error message and program
+termination.</p>
+<a name="2.24. ON...GOSUB and ON ...GOTO"></a>
+<h2>2.24. ON...GOSUB and ON ...GOTO</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>ON &lt;expression&gt; GOSUB &lt;list of line
+numbers&gt;</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>ON &lt;expression&gt; GOTO &lt;list of line
+numbers&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To branch to one of several specified line numbers or
+subroutines, based on the result of the &lt;expression&gt;.
+The list of line numbers are considered the first, second,
+etc alternative. Branching to the first occurs when the
+expression evaluates to one, to the second alternative on
+two, etc. If the value of the expression is zero or greater
+than the number of alternatives, processing continues at the
+first statement following the ON..GOTO (ON GOSUB)
+statement.</p>
+</td>
+</table>
+
+<p>When the expression results in a negative number the an
+&quot;Illegal function call&quot; error occurs.</p>
+
+<p>BUG If the value of the expression is zero or greater
+than the number of alternatives, processing does NOT
+continue at the first statement following the ON..GOTO (ON
+GOSUB) statement.</p>
+<a name="2.25. OPEN"></a>
+<h2>2.25. OPEN</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>OPEN {&quot;i&quot; | &quot;o&quot; | &quot;r&quot; } ,
+[#]&lt;file number&gt; , &lt;file-name&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To open &lt;file-name&gt; (filename should be quoted)
+for input/reading or output. If file is not opened for
+output it has to be existent, otherwise an &quot;file not
+found&quot; error will occur.</p>
+</td>
+</table>
+<a name="2.26. OPTION BASE"></a>
+<h2>2.26. OPTION BASE</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="26%">
+
+<p>OPTION BASE n</p>
+</td>
+<td width="53%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To declare the lower bound of subsequent array
+subscripts as either 0 or 1. The default lower bound is
+zero.</p>
+</td>
+</table>
+<a name="2.27. POKE"></a>
+<h2>2.27. POKE</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p>POKE &lt;expr1&gt;,&lt;expr2&gt;</p>
+</td>
+<td width="39%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To poke around in memory. The use of this statement is
+not recommended, because it requires full understanding of
+both the implementation of the Amsterdam Compiler Kit and
+the hardware characteristics.</p>
+</td>
+</table>
+<a name="2.28. PRINT"></a>
+<h2>2.28. PRINT</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>PRINT &lt;list of variables and/or constants&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To print constants or the contents of variables on the
+terminal-device. If the variables or constants are seperated
+by comma&rsquo;s the values will be printed seperated by
+tabs. If the variables or constants are seperated by
+semi-colon&rsquo;s the values will be printed without spaces
+in between. The new-line generated at the end of the
+print-statement can be suppressed by a semi-colon at the end
+of list of variables or constants.</p>
+</td>
+</table>
+<a name="2.29. PRINT USING"></a>
+<h2>2.29. PRINT USING</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>To be implemented</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<a name="2.30. PUT"></a>
+<h2>2.30. PUT</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>To be implemented</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<a name="2.31. RANDOMIZE"></a>
+<h2>2.31. RANDOMIZE</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="48%">
+
+<p>RANDOMIZE [&lt;expression&gt;]</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To reset the random seed. When the expression is
+ommitted, the system will ask for a value between -32768 and
+32767. The random number generator returns the same sequence
+of values provided the same seed is used.</p>
+</td>
+</table>
+<a name="2.32. READ"></a>
+<h2>2.32. READ</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="48%">
+
+<p>READ &lt;list of variables&gt;</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To read values from the DATA statements and assign them
+to variables. The type of the variables should match to the
+type of the items being read, otherwise a &quot;Syntax
+error&quot; occurs. If all data is read the message
+&quot;Out of data&quot; will be displayed.</p>
+</td>
+</table>
+<a name="2.33. REM"></a>
+<h2>2.33. REM</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="24%">
+
+<p>REM &lt;remark&gt;</p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To include explantory information in a program. The REM
+statements are not executed. A single quote has the same
+effect as : REM, which allows for the inclusion of comment
+at the end of the line.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>remarks</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>Microsoft BASIC does not allow REM statements as part of
+DATA lines.</p>
+</td>
+</table>
+<a name="2.34. RESTORE"></a>
+<h2>2.34. RESTORE</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="48%">
+
+<p>RESTORE [&lt;line number&gt;]</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To allow DATA statements to be re-read from a specific
+line. After a RESTORE statement is executed, the next READ
+accesses the first item of the DATA statements. If &lt;line
+number&gt; is specified, the next READ accesses the first
+item in the specified line.</p>
+</td>
+</table>
+
+<p>Note that data statements result in a sequential
+datafile generated by the compiler, being read by the read
+statements. This data file may be replaced using the
+operating system functions with a modified version, provided
+the same layout of items (same number of lines and items per
+line) is used.</p>
+<a name="2.35. STOP"></a>
+<h2>2.35. STOP</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="8%">
+
+<p>STOP</p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To terminate the execution of a program and return to
+the operating system command interpreter. A STOP statement
+results in the message &quot;Break in line ???&quot;</p>
+</td>
+</table>
+<a name="2.36. SWAP"></a>
+<h2>2.36. SWAP</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="52%">
+
+<p>SWAP &lt;variable&gt;,&lt;variable&gt;</p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To exchange the values of two variables.</p>
+</td>
+<td width="0%">
+</td>
+</table>
+
+<p>BUG. Strings cannot be swapped !</p>
+<a name="2.37. TRON/TROFF"></a>
+<h2>2.37. TRON/TROFF</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="8%">
+
+<p>TRON</p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="10%">
+
+<p>TROFF</p>
+</td>
+<td width="69%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>As an aid in debugging the TRON statement results in a
+program listing each line being interpreted. TROFF disables
+generation of this code.</p>
+</td>
+</table>
+<a name="2.38. WHILE...WEND"></a>
+<h2>2.38. WHILE...WEND</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="36%">
+
+<p>WHILE &lt;expression&gt; ..... WEND</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To execute a series of BASIC statements as long as a
+conditional expression is true. WHILE...WEND loops may be
+nested.</p>
+</td>
+</table>
+<a name="2.39. WRITE"></a>
+<h2>2.39. WRITE</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="58%">
+
+<p>WRITE [&lt;list of expressions&gt;]</p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To write data at the terminal in DATA statement layout
+conventions. The expressions should be separated by
+commas.</p>
+</td>
+</table>
+<a name="2.40. WRITE #"></a>
+<h2>2.40. WRITE #</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><b>syntax</b></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>WRITE #&lt;file number&gt; ,&lt;list of
+expressions&gt;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><b>purpose</b></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>To write a sequential data file, being opened with the
+&quot;O&quot; mode. The values are being writting using the
+DATA statements layout conventions.</p>
+</td>
+</table>
+<a name="3. FUNCTIONS"></a>
+<h2>3. FUNCTIONS</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>ABS(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the absolute value of expression X</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>ASC(X$)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Returns the numeric value of the first character of the
+string. If X$ is not initialized an &quot;Illegal function
+call&quot; error is returned.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>ATN(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the arctangent of X in radians. Result is in the
+range of -pi/2 to pi/2.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>CDBL(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Converts X to a double precision number.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>CHR$(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Converts the integer value X to its ASCII character. X
+must be in the range of 0 to 257. It is used for cursor
+addressing and generating bel signals.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>CINT(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Converts X to an integer by rounding the fractional
+portion. If X is not in the range -32768 to 32767 an
+&quot;Overflow&quot; error occurs.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>COS(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the cosine of X in radians.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>CSNG(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Converts X to a single precision number.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="28%">
+
+<p>CVI(&lt;2-bytes&gt;)</p>
+</td>
+<td width="22%"></td>
+<td width="50%">
+
+<p>Convert two byte string value to integer number.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="28%">
+
+<p>CVS(&lt;4-bytes&gt;)</p>
+</td>
+<td width="22%"></td>
+<td width="50%">
+
+<p>Convert four byte string value to single precision
+number.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="28%">
+
+<p>CVD(&lt;8-bytes&gt;)</p>
+</td>
+<td width="22%"></td>
+<td width="50%">
+
+<p>Convert eight byte string value to double precision
+number.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="40%">
+
+<p>EOF[(&lt;file-number&gt;)]</p>
+</td>
+<td width="10%"></td>
+<td width="50%">
+
+<p>Returns -1 (true) if the end of a sequential file has
+been reached.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>EXP(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns e(base of natural logarithm) to the power of X.
+X should be less then 10000.0.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>FIX(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the truncated integer part of X. FIX(X) is
+equivalent to SGN(X)*INT(ABS(X)). The major difference
+between FIX and INT is that FIX does not return the next
+lower number for negative X.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>HEX$(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Returns the string which represents the hexadecimal
+value of the decimal argument. X is rounded to an integer
+using CINT before HEX$ is evaluated.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>INT(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the largest integer &lt;= X.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="28%">
+
+<p>INP$(X[,[#]Y])</p>
+</td>
+<td width="22%"></td>
+<td width="50%">
+
+<p>Returns the string of X characters read from the
+terminal or the designated file.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>LEN(X$)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Returns the number of characters in the string X$. Non
+printable and blancs are counted too.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="36%">
+
+<p>LOC(&lt;file number&gt;)</p>
+</td>
+<td width="14%"></td>
+<td width="50%">
+
+<p>For sequential files LOC returns position of the
+read/write head, counted in number of bytes. For random
+files the function returns the record number just read or
+written from a GET or PUT statement. If nothing was read or
+written 0 is returned.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>LOG(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the natural logarithm of X. X must be greater
+than zero.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p>MID$(X,I,[J])</p>
+</td>
+<td width="24%"></td>
+<td width="50%">
+
+<p>Returns first J characters from string X starting at
+position I in X. If J is omitted all characters starting of
+from position I in X are returned.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>MKI$(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Converts an integer expression to a two-byte string.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>MKS$(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Converts a single precision expression to a four-byte
+string.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>MKD$(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Converts a double precision expression to a eight-byte
+string.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>OCT$(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Returns the string which represents the octal value of
+the decimal argument. X is rounded to an integer using CINT
+before OCTS is evaluated.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>PEEK(I)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Returns the byte read from the indicated memory. (Of
+limited use in the context of ACK)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>POS(I)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the current cursor position. To be
+implemented.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>RIGHT$(X$,I)</p>
+</td>
+<td width="26%"></td>
+<td width="50%">
+
+<p>Returns the right most I characters of string X$. If I=0
+then the empty string is returned.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>RND(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns a random number between 0 and 1. X is a dummy
+argument.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>SGN(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>If X&gt;0 , SGN(X) returns 1.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="49%"></td>
+<td width="50%">
+<p>if X=0, SGN(X) returns 0.<br>
+if X&lt;0, SGN(X) returns -1.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>SIN(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the sine of X in radians.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>SPACE$(X)</p>
+</td>
+<td width="32%"></td>
+<td width="50%">
+
+<p>Returns a string of spaces length X. The expression X is
+rounded to an integer using CINT.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>STR$(X)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Returns the string representation value of X.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>STRING$(I,J)</p>
+</td>
+<td width="26%"></td>
+<td width="50%">
+
+<p>Returns thes string of length Iwhose characters all have
+ASCII code J. (or first character when J is a string)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>TAB(I)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Spaces to position I on the terminal. If the current
+print position is already beyond space I,TAB goes to that
+position on the next line. Space 1 is leftmost position, and
+the rightmost position is width minus 1. To be used within
+PRINT statements only.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>TAN(X)</p>
+</td>
+<td width="38%"></td>
+<td width="50%">
+
+<p>Returns the tangent of X in radians. If TAN overflows
+the &quot;Overflow&quot; message is displayed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>VAL(X$)</p>
+</td>
+<td width="36%"></td>
+<td width="50%">
+
+<p>Returns the numerical value of string X$. The VAL
+function strips leading blanks and tabs from the argument
+string.</p>
+</td>
+</table>
+<a name="APPENDIX A DIFFERENCES WITH MICROSOFT BASIC"></a>
+<h2>APPENDIX A DIFFERENCES WITH MICROSOFT BASIC</h2>
+
+<p>The following list of Microsoft commands and statements
+are not recognized by the compiler.</p>
+<pre>     SPC
+     USR
+     VARPTR
+     AUTO
+     CHAIN
+     CLEAR
+     CLOAD
+     COMMON
+     CONT
+     CSAVE
+     DELETE
+     EDIT
+     ERASE
+     FRE
+     KILL
+     LIST
+     LLIST
+     LOAD
+     LPRINT
+     MERGE
+     NAME
+     NEW
+     NULL
+     RENUM
+     RESUME
+     RUN
+     SAVE
+     WAIT
+     WIDTH LPRINT
+</pre>
+
+<p>Some statements are in the current implementation not
+available, but will be soon. These include:</p>
+<pre>     CALL
+     DEFUSR
+     FIELD
+     GET
+     INKEY
+     INPUT$
+     INSTR$
+     LEFT$
+     LSET
+     RSET
+     PUT
+</pre>
+<a name="APPENDIX B RESERVED WORDS IN BASIC-EM"></a>
+<h2>APPENDIX B RESERVED WORDS IN BASIC-EM</h2>
+
+<p>The following list of words/symbols/names/identifiers
+are reserved, which means that they can not be used for
+variable-names.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="11" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>ABS</p>
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>AND</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>ASC</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>AS<br>
+ATN</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>AUTO</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>BASE</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CALL<br>
+CDBL</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CHAIN</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CHR</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CINT<br>
+CLEAR</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CLOAD</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>CLOSE</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>COMMON<br>
+CONT</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>COS</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CSNG</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CSAVE<br>
+CVI</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CVS</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>CVD</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>DATA<br>
+DEFINT</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>DEFSNG</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>DEFDBL</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>DEFSTR<br>
+DEF</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>DELETE</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>DIM</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>EDIT<br>
+ELSE</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>END</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>EOF</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>ERASE<br>
+ERROR</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>ERR</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>ERL</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>ELSE<br>
+EQV</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>EXP</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>FIELD</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>FIX<br>
+FOR</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>FRE</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>GET</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>GOSUB<br>
+GOTO</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>HEX</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>IF</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>IMP<br>
+INKEY</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>INPUT</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>INP</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>INSTR<br>
+INT</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>KILL</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LEFT</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LEN</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LET</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LINE</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LIST</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LLIST<br>
+LOAD</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LOC</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LOG</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>LPOS<br>
+LPRINT</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>LSET</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>MERGE</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>MID<br>
+MKI</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>MKS</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>MKD</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>MOD<br>
+NAME</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>NEW</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>NEXT</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>NOT</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>NULL</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>ON</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>OCT</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>OPEN<br>
+OPTION</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>OR</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>OUT</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>PEEK<br>
+POKE</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>PRINT</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>POS</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>PUT<br>
+RANDOMIZE</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>READ</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>REM</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>RENUM<br>
+REN</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>RESTORE</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>RESUME</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>RETURN<br>
+RIGHT</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>RND</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>RUN</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>SAVE<br>
+STEP</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>SGN</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>SIN</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>SPACE<br>
+SPC</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>SQR</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>STOP</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>STRING<br>
+STR</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>SWAP</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>TAB</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>TAN<br>
+THEN</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>TO</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>TRON</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>TROFF<br>
+USING</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>USR</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>VAL</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>VARPTR<br>
+WAIT</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>WHILE</p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>WEND</p>
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>WIDTH<br>
+WRITE</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>XOR</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/basic.pdf b/src/olddocs/basic.pdf
new file mode 100644 (file)
index 0000000..0848c96
Binary files /dev/null and b/src/olddocs/basic.pdf differ
diff --git a/src/olddocs/ceg.html b/src/olddocs/ceg.html
new file mode 100644 (file)
index 0000000..9824842
--- /dev/null
@@ -0,0 +1,1917 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:36 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The Code Expander Generator</title>
+</head>
+<body>
+
+<h1 align=center>The Code Expander Generator</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The code expander generator">2. The code expander generator</a><br>
+<a href="#3. Description of the EM_table">3. Description of the EM_table</a><br>
+<a href="#3.1. Grammar">3.1. Grammar</a><br>
+<a href="#3.2. Semantics">3.2. Semantics</a><br>
+<a href="#3.2.1. Actions">3.2.1. Actions</a><br>
+<a href="#3.2.2. Labels">3.2.2. Labels</a><br>
+<a href="#3.2.3. Arguments of an EM instruction">3.2.3. Arguments of an EM instruction</a><br>
+<a href="#3.2.4. Conditionals">3.2.4. Conditionals</a><br>
+<a href="#3.2.5. Abbreviations">3.2.5. Abbreviations</a><br>
+<a href="#3.2.6. Implicit arguments">3.2.6. Implicit arguments</a><br>
+<a href="#3.2.7. Pseudo instructions">3.2.7. Pseudo instructions</a><br>
+<a href="#3.2.8. Storage instructions">3.2.8. Storage instructions</a><br>
+<a href="#3.3. User supplied definitions and functions">3.3. User supplied definitions and functions</a><br>
+<a href="#3.4. Generating assembly code">3.4. Generating assembly code</a><br>
+<a href="#4. Description of the as_table">4. Description of the as_table</a><br>
+<a href="#4.1. Grammar">4.1. Grammar</a><br>
+<a href="#4.2. Semantics">4.2. Semantics</a><br>
+<a href="#4.2.1. Rules">4.2.1. Rules</a><br>
+<a href="#4.2.2. Declaration of types.">4.2.2. Declaration of types.</a><br>
+<a href="#4.2.3. The function of the @-sign and the if-statement.">4.2.3. The function of the @-sign and the if-statement.</a><br>
+<a href="#4.2.4. References to operands">4.2.4. References to operands</a><br>
+<a href="#4.2.5. The functions assemble() and block_assemble()">4.2.5. The functions assemble() and block_assemble()</a><br>
+<a href="#4.3. Generating assembly code">4.3. Generating assembly code</a><br>
+<a href="#5. Building a code expander">5. Building a code expander</a><br>
+<a href="#5.1. Phase one">5.1. Phase one</a><br>
+<a href="#5.2. Phase two">5.2. Phase two</a><br>
+<a href="#6. Acknowledgements">6. Acknowledgements</a><br>
+<a href="#7. References">7. References</a><br>
+<a href="#References">References</a><br>
+<a href="#Appendix A, the back -primitives">Appendix A, the back -primitives</a><br>
+<a href="#Appendix B, description of ACK-a.out library">Appendix B, description of ACK-a.out library</a><br>
+
+<hr>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>A <b>code expander</b> (<b>ce</b> for short) is a part
+of the Amsterdam Compiler Kit
+<sup><small><small>1</small></small></sup> (<b>ACK</b>) and
+provides the user with high-speed generation of
+medium-quality code. Although conceptually equivalent to the
+more usual <b>code generator</b>, it differs in some
+aspects.</p>
+
+<p>Normally, a program to be compiled with <b>ACK</b> is
+first fed to the preprocessor. The output of the
+preprocessor goes into the appropriate front end, which
+produces EM <sup><small><small>2</small></small></sup> (a
+machine independent low level intermediate code). The
+generated EM code is fed into the peephole optimizer, which
+scans it with a window of a few instructions, replacing
+certain inefficient code sequences by better ones. After the
+peephole optimizer a back end follows, which produces
+high-quality assembly code. The assembly code goes via the
+target optimizer into the assembler and the object code then
+goes into the linker/loader, the final component in the
+pipeline.</p>
+
+<p>For various applications this scheme is too slow. When
+debugging, for example, compile time is more important than
+execution time of a program. For this purpose a new scheme
+is introduced:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>The code generator and assembler are replaced by a
+library, the <b>code expander</b>, consisting of a set of
+routines, one for every EM-instruction. Each routine expands
+its EM-instruction into relocatable object code. In
+contrast, the usual ACK code generator uses expensive
+pattern matching on sequences of EM-instructions. The
+peephole and target optimizer are not used.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>These routines replace the usual EM-generating routines
+in the front end; this eliminates the overhead of
+intermediate files.</p>
+</td>
+</table>
+
+<p>This results in a fast compiler producing object file,
+ready to be linked and loaded, at the cost of unoptimized
+object code.</p>
+
+<p>Because of the simple nature of the code expander, it is
+much easier to build, to debug, and to test. Experience has
+demonstrated that a code expander can be constructed,
+debugged, and tested in less than two weeks.</p>
+
+<p>This document describes the tools for automatically
+generating a <b>ce</b> (a library of C files) from two
+tables and a few machine-dependent functions. A thorough
+knowledge of EM is necessary to understand this
+document.</p>
+<a name="2. The code expander generator"></a>
+<h2>2. The code expander generator</h2>
+
+<p>The code expander generator (<b>ceg</b>) generates a
+code expander from two tables and a few machine-dependent
+functions. This section explains how <b>ceg</b> works. The
+first half describes the transformations that are done on
+the two tables. The second half tells how these
+transformations are done by the <b>ceg</b>.</p>
+
+<p>A code expander consists of a set of routines that
+convert EM-instructions directly to relocatable object code.
+These routines are called by a front end through the
+EM_CODE(3ACK) <sup><small><small>3</small></small></sup>
+interface. To free the table writer of the burden of
+building an object file, we supply a set of routines that
+build an object file in the ACK.OUT(5ACK)
+<sup><small><small>4</small></small></sup> format (see
+appendix B). This set of routines is called the
+<b>back</b>-primitives (see appendix A). In short, a code
+expander consists of a set of routines that map the EM_CODE
+interface on the <b>back</b>-primitives interface.</p>
+
+<p>To avoid repetition of the same sequences of
+<b>back</b>-primitives in different EM-instructions and to
+improve readability, the EM-to-object information must be
+supplied in two tables. The EM_table maps EM to an assembly
+language, and the as_table maps assembly code to
+<b>back</b>-primitives. The assembly language is chosen by
+the table writer. It can either be an actual assembly
+language or his ad-hoc designed language.</p>
+
+<p>The following picture shows the dependencies between the
+different components:</p>
+
+<p align=center><img src="grohtml-106561.png"></p>
+
+<p>The picture suggests that, during compilation, the EM
+instructions are first transformed into assembly
+instructions and then the assembly instructions are
+transformed into object-generating calls. This is not what
+happens in practice, although the user is free to think it
+does. Actually, however the EM_table and the as_table are
+combined during code expander generation time, yielding an
+imaginary compound table that results in routines from the
+EM_CODE interface that generate object code directly.</p>
+
+<p>As already indicated, the compound table does not exist
+either. Instead, each assembly instruction in the as_table
+is converted to a routine generating C
+<sup><small><small>5</small></small></sup> code to generate
+C code to call the <b>back</b>-primitives. The EM_table is
+converted into a program that for each EM instruction
+generates a routine, using the routines generated from the
+as_table. Execution of the latter program will then generate
+the code expander.</p>
+
+<p>This scheme allows great flexibility in the table
+writing, while still resulting in a very efficient code
+expander. One implication is that the as_table is
+interpreted twice and the EM_table only once. This has
+consequences for their structure.</p>
+
+<p>To illustrate what happens, we give an example. The
+example is an entry in the tables for the VAX-machine. The
+assembly language chosen is a subset of the VAX assembly
+language.</p>
+
+<p>One of the most fundamental operations in EM is
+&lsquo;&lsquo;loc c&rsquo;&rsquo;, load the value of c on
+the stack. To expand this instruction the tables contain the
+following information:</p>
+<pre>     EM_table   :
+        C_loc   ==&gt;   &quot;pushl $$$1&quot;.
+          /* $1 refers to the first argument of C_loc.
+           * $$ is a quoted $. */
+
+
+
+
+     as_table   :
+        pushl  src : CONST   ==&gt;
+                              @text1( 0xd0);
+                              @text1( 0xef);
+                              @text4( %$( src-&gt;num)).
+</pre>
+
+<p>The as_table is transformed in the following
+routine:</p>
+<pre>     pushl_instr(src)
+     t_operand *src;
+     /* &lsquo;&lsquo;t_operand&rsquo;&rsquo; is a struct defined by the
+      * table writer. */
+     {
+        printf(&quot;swtxt();&quot;);
+        printf(&quot;text1( 0xd0 );&quot;);
+        printf(&quot;text1( 0xef );&quot;);
+        printf(&quot;text4(%s);&quot;, substitute_dollar( src-&gt;num));
+     }
+</pre>
+
+<p>Using &lsquo;&lsquo;pushl_instr()&rsquo;&rsquo;, the
+following routine is generated from the EM_table:</p>
+<pre>     C_loc( c)
+     arith c;
+     /* text1() and text4() are library routines that fill the
+      * text segment. */
+     {
+         swtxt();
+         text1( 0xd0);
+         text1( 0xef);
+         text4( c);
+     }
+</pre>
+
+<p>A compiler call to &lsquo;&lsquo;C_loc()&rsquo;&rsquo;
+will cause the 1-byte numbers
+&lsquo;&lsquo;0xd0&rsquo;&rsquo; and
+&lsquo;&lsquo;0xef&rsquo;&rsquo; and the 4-byte value of the
+variable &lsquo;&lsquo;c&rsquo;&rsquo; to be stored in the
+text segment.</p>
+
+<p>The transformations on the tables are done automatically
+by the code expander generator. The code expander generator
+is made up of two tools: <b>emg</b> and <b>asg</b>.
+<b>Asg</b> transforms each assembly instruction into a C
+routine. These C routines generate calls to the
+<b>back</b>-primitives. The generated C routines are used by
+<b>emg</b> to generate the actual code expander from the
+EM_table.</p>
+
+<p>The link between <b>emg</b> and <b>asg</b> is an
+assembly language. We did not enforce a specific syntax for
+the assembly language; instead we have given the table
+writer the freedom to make an ad-hoc assembly language or to
+use an actual assembly language suitable for his purpose.
+Apart from a greater flexibility this has another advantage;
+if the table writer adopts the assembly language that runs
+on the machine at hand, he can test the EM_table
+independently from the as_table. Of course there is a price
+to pay: the table writer has to do the decoding of the
+operands himself. See section 4 for more details.</p>
+
+<p>Before we describe the structure of the tables in
+detail, we will give an overview of the four main
+phases.</p>
+
+<p>phase 1:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The as_table is transformed by <b>asg</b>. This results
+in a set of C routines. Each assembly-opcode generates one C
+routine. Note that a call to such a routine does not
+generate the corresponding object code; it generates C code,
+which, when executed, generates the desired object code.</p>
+</td>
+</table>
+
+<p>phase 2:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The C routines generated by <b>asg</b> are used by emg to
+expand the EM_table. This results in a set of C routines,
+the code expander, which conform to the procedural interface
+EM_CODE(3ACK). A call to such a routine does indeed generate
+the desired object code.</p>
+</td>
+</table>
+
+<p>phase 3:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The front end that uses the procedural interface is
+linked/loaded with the code expander generated in phase 2
+and the <b>back</b>-primitives (a supplied library). This
+results in a compiler.</p>
+</td>
+</table>
+
+<p>phase 4:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The compiler runs. The routines in the code expander are
+executed and produce object code.</p>
+</td>
+</table>
+<a name="3. Description of the EM_table"></a>
+<h2>3. Description of the EM_table</h2>
+
+<p>This section describes the EM_table. It contains four
+subsections. The first 3 sections describe the syntax of the
+EM_table, the semantics of the EM_table, and the functions
+and constants that must be present in the EM_table, in the
+file &lsquo;&lsquo;mach.c&rsquo;&rsquo; or in the file
+&lsquo;&lsquo;mach.h&rsquo;&rsquo;. The last section
+explains how a table writer can generate assembly code
+instead of object code. The section on semantics contains
+many examples.</p>
+<a name="3.1. Grammar"></a>
+<h2>3.1. Grammar</h2>
+
+<p>The following grammar describes the syntax of the
+EM_table.</p>
+
+<p align=center><img src="grohtml-106562.png"></p>
+
+<p>The &lsquo;&lsquo;(&rsquo;&rsquo;
+&lsquo;&lsquo;)&rsquo;&rsquo; brackets are used for
+grouping, &lsquo;&lsquo;[&rsquo;&rsquo; ...
+&lsquo;&lsquo;]&rsquo;&rsquo; means ... 0 or 1 time, a
+&lsquo;&lsquo;*&rsquo;&rsquo; means zero or more times, and
+a &lsquo;&lsquo;|&rsquo;&rsquo; means a choice between left
+or right. A <b>C_instr</b> is a name in the EM_CODE(3ACK)
+interface. <b>condition</b> is a C expression.
+<b>function-call</b> is a call of a C function.
+<b>label</b>, <b>mnemonic</b>, and <b>operand</b> are
+arbitrary strings. If an <b>operand</b> contains brackets,
+the brackets must match. There is an upper bound on the
+number of operands; the maximum number is defined by the
+constant MAX_OPERANDS in de file
+&lsquo;&lsquo;const.h&rsquo;&rsquo; in the directory
+assemble.c. Comments in the table should be placed between
+&lsquo;&lsquo;/*&rsquo;&rsquo; and
+&lsquo;&lsquo;*/&rsquo;&rsquo;. The table is processed by
+the C preprocessor, before being parsed by <b>emg</b>.</p>
+<a name="3.2. Semantics"></a>
+<h2>3.2. Semantics</h2>
+
+<p>The EM_table is processed by <b>emg</b>. <b>Emg</b>
+generates a C function for every instruction in the
+EM_CODE(3ACK). For every EM-instruction not mentioned in the
+EM_table, a C function that prints an error message is
+generated. It is possible to divide the
+EM_CODE(3ACK)-interface into four parts :</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="2%"></td>
+<td width="89%">
+
+<p>text instructions (e.g., C_loc, C_adi, ..)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="2%"></td>
+<td width="89%">
+
+<p>pseudo instructions (e.g., C_open, C_df_ilb, ..)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>3:</p>
+</td>
+<td width="2%"></td>
+<td width="89%">
+
+<p>storage instructions (e.g., C_rom_icon, ..)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>4:</p>
+</td>
+<td width="2%"></td>
+<td width="89%">
+
+<p>message instructions (e.g., C_mes_begin, ..)</p>
+</td>
+</table>
+
+<p>This section starts with giving the semantics of the
+grammar. The examples are text instructions. The section
+ends with remarks on the pseudo instructions and the storage
+instructions. Since message instructions are not useful for
+a code expander, they are ignored.</p>
+<a name="3.2.1. Actions"></a>
+<h2>3.2.1. Actions</h2>
+
+<p>The EM_table is made up of rules describing how to
+expand a <b>C_instr</b> defined by the
+EM_CODE(3ACK)-interface (corresponding to an EM instruction)
+into actions. There are two kinds of actions: assembly
+instructions and C function calls. An assembly instruction
+is defined as a mnemonic followed by zero or more operands
+separated by commas. The semantics of an assembly
+instruction is defined by the table writer. When the
+assembly language is not expressive enough, then, as an
+escape route, function calls can be made. However, this
+reduces the speed of the actual code expander. Finally,
+actions can be grouped into a list of actions; actions are
+separated by a semicolon and terminated by a
+&lsquo;&lsquo;.&rsquo;&rsquo;.</p>
+<pre>     C_nop   ==&gt; .
+            /* Empty action list : no operation. */
+
+
+     C_inc   ==&gt; &quot;incl (sp)&quot;.
+            /* Assembler instruction, which is evaluated
+             * during expansion of the EM_table */
+
+
+     C_slu   ==&gt; C_sli( $1).
+            /* Function call, which is evaluated during
+             *  execution of the compiler. */
+</pre>
+<a name="3.2.2. Labels"></a>
+<h2>3.2.2. Labels</h2>
+
+<p>Since an assembly language without instruction labels is
+a rather weak language, labels inside a contiguous block of
+assembly instructions are allowed. When using labels two
+rules must be observed:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>The name of a label should be unique inside an action
+list.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>The labels used in an assembler instruction should be
+defined in the same action list.</p>
+</td>
+</table>
+
+<p>The following example illustrates the usage of
+labels.</p>
+<pre>        /* Compare the two top elements on the stack. */
+     C_cmp      ==&gt;     &quot;pop bx&quot;;
+                        &quot;pop cx&quot;;
+                        &quot;xor ax, ax&quot;;
+                        &quot;cmp cx, bx&quot;;
+                     /* Forward jump to local label */
+                        &quot;je 2f&quot;;
+                        &quot;jb 1f&quot;;
+                        &quot;inc ax&quot;;
+                        &quot;jmp 2f&quot;;
+                        &quot;1: dec ax&quot;;
+                        &quot;2: push ax&quot;.
+</pre>
+
+<p>We will come back to labels in the section on the
+as_table.</p>
+<a name="3.2.3. Arguments of an EM instruction"></a>
+<h2>3.2.3. Arguments of an EM instruction</h2>
+
+<p>In most cases the translation of a <b>C_instr</b>
+depends on its arguments. The arguments of a <b>C_instr</b>
+are numbered from 1 to <i>n</i>, where <i>n</i> is the total
+number of arguments of the current <b>C_instr</b> (there are
+a few exceptions, see Implicit arguments). The table writer
+may refer to an argument as $<i>i</i>. If a plain $-sign is
+needed in an assembly instruction, it must be preceded by a
+extra $-sign.</p>
+
+<p>There are two groups of <b>C_instr</b>s whose arguments
+are handled specially:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>1: Instructions dealing with local offsets</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>The value of the $<i>i</i> argument referring to a
+parameter ($<i>i</i> &gt;= 0) is increased by
+&lsquo;&lsquo;EM_BSIZE&rsquo;&rsquo;.
+&lsquo;&lsquo;EM_BSIZE&rsquo;&rsquo; is the size of the
+return status block and must be defined in the file
+&lsquo;&lsquo;mach.h&rsquo;&rsquo; (see section 3.3). For
+example :</p>
+<!-- INDENTATION -->
+<pre>     C_lol   ==&gt;     &quot;push $1(bp)&quot;.
+            /* automatic conversion of $1 */
+</pre>
+</td>
+</table>
+<!-- INDENTATION -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>2: Instructions using global names or instruction
+labels</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>All the arguments referring to global names or
+instruction labels will be transformed into a unique
+assembly name. To prevent name clashes with library names
+the table writer has to provide the conversions in the file
+&lsquo;&lsquo;mach.h&rsquo;&rsquo;. For example :</p>
+<!-- INDENTATION -->
+<pre>     C_bra   ==&gt;     &quot;jmp $1&quot;.
+             /* automatic conversion of $1 */
+             /* type arith is converted to string */
+</pre>
+</td>
+</table>
+<a name="3.2.4. Conditionals"></a>
+<h2>3.2.4. Conditionals</h2>
+
+<p>The rules in the EM_table can be divided into two
+groups: simple rules and conditional rules. The simple rules
+are made up of a <b>C_instr</b> followed by a list of
+actions, as described above. The conditional rules
+(COND_SEQUENCE) allow the table writer to select an action
+list depending on the value of a condition.</p>
+
+<p>A CONDITIONAL is a list of a boolean expression with the
+corresponding simple rule. If the expression evaluates to
+true then the corresponding simple rule is carried out. If
+more than one condition evaluates to true, the first one is
+chosen. The last case of a COND_SEQUENCE of a <b>C_instr</b>
+must handle the default case. The boolean expressions in a
+COND_SEQUENCE must be C expressions. Besides the ordinary C
+operators and constants, $<i>i</i> references can be used in
+an expression.</p>
+<pre>         /* Load address of LB $1 levels back. */
+     C_lxl
+         $1 == 0    ==&gt;    &quot;pushl fp&quot;.
+         $1 == 1    ==&gt;    &quot;pushl 4(ap)&quot;.
+         default    ==&gt;    &quot;movl $$$1, r0&quot;;
+                           &quot;jsb .lxl&quot;;
+                           &quot;pushl r0&quot;.
+</pre>
+<a name="3.2.5. Abbreviations"></a>
+<h2>3.2.5. Abbreviations</h2>
+
+<p>EM instructions with an external as an argument come in
+three variants in the EM_CODE(3ACK) interface. In most cases
+it will be possible to take these variants together. For
+this purpose the &lsquo;&lsquo;..&rsquo;&rsquo; notation is
+introduced. For the code expander there is no difference
+between the following instructions.</p>
+<pre>     C_loe_dlb    ==&gt;    &quot;pushl $1 + $2&quot;.
+     C_loe_dnam   ==&gt;    &quot;pushl $1 + $2&quot;.
+     C_loe        ==&gt;    &quot;pushl $1 + $2&quot;.
+</pre>
+
+<p>So it can be written in the following way.</p>
+<pre>     C_loe..      ==&gt;    &quot;pushl $1 + $2&quot;.
+</pre>
+<a name="3.2.6. Implicit arguments"></a>
+<h2>3.2.6. Implicit arguments</h2>
+
+<p>In the last example &lsquo;&lsquo;C_loe&rsquo;&rsquo;
+has two arguments, but in the EM_CODE interface it has one
+argument. This argument depends on the current
+&lsquo;&lsquo;hol&rsquo;&rsquo; block; in the EM_table this
+is made explicit. Every <b>C_instr</b> whose argument
+depends on a &lsquo;&lsquo;hol&rsquo;&rsquo; block has one
+extra argument; argument 1 refers to the
+&lsquo;&lsquo;hol&rsquo;&rsquo; block.</p>
+<a name="3.2.7. Pseudo instructions"></a>
+<h2>3.2.7. Pseudo instructions</h2>
+
+<p>Most pseudo instructions are machine independent and are
+provided by <b>ceg</b>. The table writer has only to supply
+the following functions, which are used to build a
+stackframe:</p>
+<pre>     C_prolog()
+     /* Performs the prolog, for example save
+      * return address */
+
+
+     C_locals( n)
+     arith n;
+     /* Allocate n bytes for locals on the stack */
+
+
+     C_jump( label)
+     char *label;
+     /* Generates code for a jump to &lsquo;&lsquo;label&rsquo;&rsquo; */
+</pre>
+
+<p>These functions can be defined in
+&lsquo;&lsquo;mach.c&rsquo;&rsquo; or in the EM_table (see
+section 3.3).</p>
+<a name="3.2.8. Storage instructions"></a>
+<h2>3.2.8. Storage instructions</h2>
+
+<p>The storage instructions
+&lsquo;&lsquo;C_bss_<i>cstp()</i>&rsquo;&rsquo;,
+&lsquo;&lsquo;C_hol_<i>cstp()</i>&rsquo;&rsquo;, dealing
+with constants of type string (C_..._icon, C_..._ucon,
+C_..._fcon), are generated automatically. No information is
+needed in the table. To generate the C_..._icon, C_..._ucon,
+C_..._fcon instructions <b>ceg</b> only has to know how to
+convert a number of type string to bytes; this can be
+defined with the constants ONE_BYTE, TWO_BYTES, and
+FOUR_BYTES. C_rom_icon, C_con_icon, C_bss_icon, C_hol_icon
+can be abbreviated by ..icon. This also holds for ..ucon and
+..fcon. For example :</p>
+<pre>     \.\.icon
+         $2 == 1   ==&gt;  gen1( (ONE_BYTE) atoi( $1)).
+         $2 == 2   ==&gt;  gen2( (TWO_BYTES) atoi( $1)).
+         $2 == 4   ==&gt;  gen4( (FOUR_BYTES) atol( $1)).
+         default   ==&gt;   arg_error( &quot;..icon&quot;, $2).
+</pre>
+
+<p>Gen1(), gen2() and gen4() are <b>back</b>-primitives
+(see appendix A), and generate one, two, or four byte
+constants. Atoi() is a C library function that converts
+strings to integers. The constants
+&lsquo;&lsquo;ONE_BYTE&rsquo;&rsquo;,
+&lsquo;&lsquo;TWO_BYTES&rsquo;&rsquo;, and
+&lsquo;&lsquo;FOUR_BYTES&rsquo;&rsquo; must be defined in
+the file &lsquo;&lsquo;mach.h&rsquo;&rsquo;.</p>
+<a name="3.3. User supplied definitions and functions"></a>
+<h2>3.3. User supplied definitions and functions</h2>
+
+<p>If the table writer uses all the default functions he
+has only to supply the following constants and functions
+:</p>
+
+<p align=center><img src="grohtml-106563.png"></p>
+
+<p>An example of the file
+&lsquo;&lsquo;mach.h&rsquo;&rsquo; for the vax4.</p>
+
+<p align=center><img src="grohtml-106565.png"></p>
+
+<p>Notice that EM_BSIZE is zero. The vax
+&lsquo;&lsquo;call&rsquo;&rsquo; instruction takes
+automatically care of the base block.</p>
+
+<p>There are three primitives that have to be defined by
+the table writer, either as functions in the file
+&lsquo;&lsquo;mach.c&rsquo;&rsquo; or as rules in the
+EM_table. For example, for the 8086 they look like this:</p>
+<pre>     C_jump       ==&gt;       &quot;jmp $1&quot;.
+
+
+     C_prolog     ==&gt;       &quot;push bp&quot;;
+                          &quot;mov bp, sp&quot;.
+
+
+     C_locals
+       $1  == 0   ==&gt;     .
+       $1  == 2   ==&gt;     &quot;push ax&quot;.
+       $1  == 4   ==&gt;     &quot;push ax&quot;;
+                          &quot;push ax&quot;.
+       default    ==&gt;     &quot;sub sp, $1&quot;.
+</pre>
+<a name="3.4. Generating assembly code"></a>
+<h2>3.4. Generating assembly code</h2>
+
+<p>When the code expander generator is used for generating
+assembly instead of object code (see section 5), additional
+print formats have to be defined in
+&lsquo;&lsquo;mach.h&rsquo;&rsquo;. The following table
+lists these formats.</p>
+
+<p align=center><img src="grohtml-106566.png"></p>
+<a name="4. Description of the as_table"></a>
+<h2>4. Description of the as_table</h2>
+
+<p>This section describes the as_table. Like the previous
+section, it is divided into four parts: the first two parts
+describe the grammar and the semantics of the as_table; the
+third part gives an overview of the functions and the
+constants that must be present in the as_table (in the file
+&lsquo;&lsquo;as.h&rsquo;&rsquo; or in the file
+&lsquo;&lsquo;as.c&rsquo;&rsquo;); the last part describes
+the case when assembly is generated instead of object code.
+The part on semantics contains examples that appear in the
+as_table for the VAX or for the 8086.</p>
+<a name="4.1. Grammar"></a>
+<h2>4.1. Grammar</h2>
+
+<p>The form of the as_table is given by the following
+grammar :</p>
+
+<p align=center><img src="grohtml-106567.png"></p>
+
+<p><b>mnemonic</b>, <b>operand</b>, and <b>type</b> are all
+C identifiers; <b>condition</b> is a normal C expression;
+<b>function-call</b> must be a C function call. A function
+can be called with standard C arguments or with a reference
+(see section 4.2.4). Since the as_table is interpreted
+during code expander generation as well as during code
+expander execution, two levels of calls are present in it. A
+&lsquo;&lsquo;function-call&rsquo;&rsquo; is done during
+code expander generation, a
+&lsquo;&lsquo;@function-call&rsquo;&rsquo; during code
+expander execution.</p>
+<a name="4.2. Semantics"></a>
+<h2>4.2. Semantics</h2>
+
+<p>The as_table is made up of rules that map assembly
+instructions onto <b>back</b>-primitives, a set of functions
+that construct an object file. The table is processed by
+<b>asg</b>, which generates a C functions for each assembler
+mnemonic. The names of these functions are the assembler
+mnemonics postfixed with &lsquo;&lsquo;_instr&rsquo;&rsquo;
+(e.g., &lsquo;&lsquo;add&rsquo;&rsquo; becomes
+&lsquo;&lsquo;add_instr()&rsquo;&rsquo;). These functions
+will be used by the function assemble() during the expansion
+of the EM_table. After explaining the semantics of the
+as_table the function assemble() will be described.</p>
+<a name="4.2.1. Rules"></a>
+<h2>4.2.1. Rules</h2>
+
+<p>A rule in the as_table is made up of a left and a right
+hand side; the left hand side describes an assembler
+instruction (mnemonic and operands); the right hand side
+gives the corresponding actions as <b>back</b>-primitives or
+as functions defined by the table writer, which call
+<b>back-primitives</b>. Two simple examples from the VAX
+as_table and the 8086 as_table, resp.:</p>
+<pre>     movl src, dst  ==&gt; @text1( 0xd0);
+                        gen_operand( src);
+                        gen_operand( dst).
+         /* &lsquo;&lsquo;gen_operand&rsquo;&rsquo; is a function that encodes
+          * operands by calling back-primitives. */
+
+
+     rep ens:MOVS   ==&gt;  @text1( 0xf3);
+                         @text1( 0xa5).
+
+
+</pre>
+<a name="4.2.2. Declaration of types."></a>
+<h2>4.2.2. Declaration of types.</h2>
+
+<p>In general, a machine instruction is encoded as an
+opcode followed by zero or more the operands. There are two
+methods for mapping assembler mnemonics onto opcodes: the
+mnemonic determines the opcode, or mnemonic and operands
+together determine the opcode. Both cases can be easily
+expressed in the as_table. The first case is obvious. The
+second case is handled by introducing type fields for the
+operands.</p>
+
+<p>When mnemonic and operands together determine the
+opcode, the table writer has to give several rules for each
+combination of mnemonic and operands. The rules differ in
+the type fields of the operands. The table writer has to
+supply functions that check the type of the operand. The
+name of such a function is the name of the type; it has one
+argument: a pointer to a struct of type <i>t_operand</i>; it
+returns non-zero when the operand is of this type, otherwise
+it returns 0.</p>
+
+<p>This will usually lead to a list of rules per mnemonic.
+To reduce the amount of work an abbreviation is supplied.
+Once the mnemonic is specified it can be referred to in the
+following rules by &lsquo;&lsquo;...&rsquo;&rsquo;. One has
+to make sure that each mnemonic is mentioned only once in
+the as_table, otherwise <b>asg</b> will generate more than
+one function with the same name.</p>
+
+<p>The following example shows the usage of type
+fields.</p>
+<pre>      mov dst:REG, src:EADDR  ==&gt;
+               @text1( 0x8b);                /* opcode */
+               mod_RM( %d(dst-&gt;reg), src). /* operands */
+
+
+      ... dst:EADDR, src:REG  ==&gt;
+               @text1( 0x89);                /* opcode */
+               mod_RM( %d(src-&gt;reg), dst). /* operands */
+</pre>
+
+<p>The table-writer must supply the restriction functions,
+<tt>REG</tt> and <tt>EADDR</tt> in the previous example, in
+&lsquo;&lsquo;as.c&rsquo;&rsquo; or
+&rsquo;&rsquo;as.h&rsquo;&rsquo;.</p>
+<a name="4.2.3. The function of the @-sign and the if-statement."></a>
+<h2>4.2.3. The function of the @-sign and the if-statement.</h2>
+
+<p>The right hand side of a rule is made up of function
+calls. Since the as_table is interpreted on two levels,
+during code expander generation and during code expander
+execution, two levels of calls are present in it. A
+function-call without an &lsquo;&lsquo;@&rsquo;&rsquo;-sign
+is called during code expander generation (e.g., the
+<tt>gen_operand()</tt> in the first example). A function
+call with an &lsquo;&lsquo;@&rsquo;&rsquo;-sign is called
+during code expander execution (e.g., the
+<b>back</b>-primitives). So the last group will be part of
+the compiler.</p>
+
+<p>The need for the &lsquo;&lsquo;@&rsquo;&rsquo;-sign
+construction arises, for example, when implementing push/pop
+optimization (e.g., &lsquo;&lsquo;push x&rsquo;&rsquo;
+followed by &lsquo;&lsquo;pop y&rsquo;&rsquo; can be
+replaced by &lsquo;&lsquo;move x, y&rsquo;&rsquo;). In this
+case flags need to be set, unset, and tested during the
+execution of the compiler:</p>
+<pre>PUSH src  ==&gt;   /* save in ax */
+                mov_instr( AX_oper, src);
+                /* set flag */
+                @assign( push_waiting, TRUE).
+</pre>
+<pre>     POP dst   ==&gt;   @if ( push_waiting)
+                            /* &lsquo;&lsquo;mov_instr&rsquo;&rsquo; is asg-generated */
+                            mov_instr( dst, AX_oper);
+                            @assign( push_waiting, FALSE).
+                     @else
+                            /* &lsquo;&lsquo;pop_instr&rsquo;&rsquo; is asg-generated */
+                            pop_instr( dst).
+                     @fi.
+</pre>
+
+<p>Although the @-sign is followed syntactically by a
+function name, this function can very well be the name of a
+macro defined in C. This is in fact the case with
+&lsquo;&lsquo;@assign()&rsquo;&rsquo; in the above
+example.</p>
+
+<p>The case may arise when information is needed that is
+not known until execution of the compiler. For example one
+needs to know if a &lsquo;&lsquo;$<i>i</i>&rsquo;&rsquo;
+argument fits in one byte. In this case one can use a
+special if-statement provided by <b>asg</b>: @if, @elsif,
+@else, @fi. This means that the conditions will be evaluated
+at run time of the <b>ce</b>. In such a condition one may of
+course refer to the &rsquo;&rsquo;$<i>i</i>&rsquo;&rsquo;
+arguments. For example, constants can be packed into one or
+two byte arguments as follows:</p>
+<pre>     mov dst:ACCU, src:DATA ==&gt;
+                            @if ( fits_byte( %$(dst-&gt;expr)))
+                                 @text1( 0xc0);
+                                 @text1( %$(dst-&gt;expr)).
+                            @else
+                                 @text1( 0xc8);
+                                 @text2( %$(dst-&gt;expr)).
+                            @fi.
+</pre>
+<a name="4.2.4. References to operands"></a>
+<h2>4.2.4. References to operands</h2>
+
+<p>As noted before, the operands of an assembler
+instruction may be used as pointers to the struct
+<i>t_operand</i> in the right hand side of the table.
+Because of the free format assembler, the types of the
+fields in the struct <i>t_operand</i> are unknown to
+<b>asg</b>. As these fields can appear in calls to
+functions, <b>asg</b> must know these types. This section
+explains how these types must be specified.</p>
+
+<p>References to operands come in three forms: ordinary
+operands, operands that contain
+&lsquo;&lsquo;$<i>i</i>&rsquo;&rsquo; references, and
+operands that refer to names of local labels. The
+&lsquo;&lsquo;$<i>i</i>&rsquo;&rsquo; in operands represent
+names or numbers of a <b>C_instr</b> and must be given as
+arguments to the <b>back</b>-primitives. Labels in operands
+must be converted to a number that tells the distance, the
+number of bytes, between the label and the current position
+in the text-segment.</p>
+
+<p>All these three cases are treated in an uniform way.
+When the table writer makes a reference to an operand of an
+assembly instruction, he must describe the type of the
+operand in the following way.</p>
+
+<p align=center><img src="grohtml-106568.png"></p>
+
+<p>The three cases differ only in the conversion field. The
+printformat conversion applies to ordinary operands. The
+&lsquo;&lsquo;%$&rsquo;&rsquo; applies to operands that
+contain a &lsquo;&lsquo;$<i>i</i>&rsquo;&rsquo;. The
+expression between parentheses must result in a pointer to a
+char. The result of &lsquo;&lsquo;%$&rsquo;&rsquo; is of the
+type of &lsquo;&lsquo;$<i>i</i>&rsquo;&rsquo;. The
+&lsquo;&lsquo;%dist&rsquo;&rsquo; applies to operands that
+refer to a local label. The expression between the brackets
+must result in a pointer to a char. The result of
+&lsquo;&lsquo;%dist&rsquo;&rsquo; is of type arith.</p>
+
+<p>The following example illustrates the usage of
+&lsquo;&lsquo;%$&rsquo;&rsquo;. (For an example that
+illustrates the usage of ordinary fields see the section on
+&lsquo;&lsquo;User supplied definitions and
+functions&rsquo;&rsquo;).</p>
+<pre>     jmp dst ==&gt;
+         @text1( 0xe9);
+         @reloc2( %$(dst-&gt;lab), %$(dst-&gt;off), PC_REL).
+</pre>
+
+<p>A useful function concerning $<i>i</i>s is arg_type(),
+which takes as input a string starting with $<i>i</i> and
+returns the type of the <i>i</i>&rsquo;&rsquo;th argument of
+the current EM-instruction, which can be STRING, ARITH or
+INT. One may need this function while decoding operands if
+the context of the $<i>i</i> does not give enough
+information. If the function arg_type() is used, the file
+arg_type.h must contain the definition of STRING, ARITH and
+INT.</p>
+
+<p>%dist is only guaranteed to work when called as a
+parameter of text1(), text2() or text4(). The goal of the
+%dist conversion is to reduce the number of reloc1(),
+reloc2() and reloc4() calls, saving space and time (no
+relocation at compiler run time). The following example
+illustrates the usage of
+&lsquo;&lsquo;%dist&rsquo;&rsquo;.</p>
+<pre>      jmp dst:ILB    ==&gt; /* label in an instruction list */
+          @text1( 0xeb);
+          @text1( %dist( dst-&gt;lab)).
+
+
+      ... dst:LABEL  ==&gt; /* global label */
+          @text1( 0xe9);
+          @reloc2( %$(dst-&gt;lab), %$(dst-&gt;off), PC_REL).
+</pre>
+
+<a name="4.2.5. The functions assemble() and block_assemble()"></a>
+
+<h2>4.2.5. The functions assemble() and block_assemble()</h2>
+
+<p>The functions assemble() and block_assemble() are
+provided by <b>ceg</b>. If, however, the table writer is not
+satisfied with the way they work he can supply his own
+assemble() or block_assemble(). The default function
+assemble() splits an assembly string into a label, mnemonic,
+and operands and performs the following actions on them:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>It processes the local label; it records the name and
+current position. Thereafter it calls the function
+process_label() with one argument of type string, the label.
+The table writer has to define this function.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>Thereafter it calls the function process_mnemonic() with
+one argument of type string, the mnemonic. The table writer
+has to define this function.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>3:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>It calls process_operand() for each operand.
+Process_operand() must be written by the table-writer since
+no fixed representation for operands is enforced. It has two
+arguments: a string (the operand to decode) and a pointer to
+the struct <i>t_operand</i>. The declaration of the struct
+<i>t_operand</i> must be given in the file
+&lsquo;&lsquo;as.h&rsquo;&rsquo;, and the table-writer can
+put all the information needed for encoding the operand in
+machine format in it.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>4:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>It examines the mnemonic and calls the associated
+function, generated by <b>asg</b>, with pointers to the
+decoded operands as arguments. This makes it possible to use
+the decoded operands in the right hand side of a rule (see
+below).</p>
+</td>
+</table>
+
+<p>If the default assemble() does not work the way the
+table writer wants, he can supply his own version of it.
+Assemble() has the following arguments:</p>
+<pre>     assemble( instruction )
+         char *instruction;
+</pre>
+
+<p><i>instruction</i> points to a null-terminated
+string.</p>
+
+<p>The default function block_assemble() is called with a
+sequence of assembly instructions that belong to one action
+list. It calls assemble() for every assembly instruction in
+this block. But if a special action is required on a block
+of assembly instructions, the table writer only has to
+rewrite this function to get a new <b>ceg</b> that obliges
+to his wishes. The function block_assemble has the following
+arguments:</p>
+<pre>     block_assemble( instructions, nr, first, last)
+           char   **instruction;
+           int      nr, first, last;
+</pre>
+
+<p><i>Instruction</i> point to an array of pointers to
+strings representing assembly instructions. <i>Nr</i> is the
+number of instructions that must be assembled. <i>First</i>
+and <i>last</i> have no function in the default
+block_assemble(), but are useful when optimizations are done
+in block_assemble().</p>
+
+<p>Four things have to be specified in
+&lsquo;&lsquo;as.h&rsquo;&rsquo; and
+&lsquo;&lsquo;as.c&rsquo;&rsquo;. First the user must give
+the declaration of struct <i>t_operand</i> in
+&lsquo;&lsquo;as.h&rsquo;&rsquo;, and the functions
+process_operand(), process_mnemonic(), and process_label()
+must be given in &lsquo;&lsquo;as.c&rsquo;&rsquo;. If the
+right hand side of the as_table contains function calls
+other than the <b>back</b>-primitives, these functions must
+also be present in &lsquo;&lsquo;as.c&rsquo;&rsquo;. Note
+that both the &lsquo;&lsquo;@&rsquo;&rsquo;-sign (see 4.2.3)
+and &lsquo;&lsquo;references&rsquo;&rsquo; (see 4.2.4) also
+work in the functions defined in
+&lsquo;&lsquo;as.c&rsquo;&rsquo;.</p>
+
+<p>The following example shows the representative and
+essential parts of the 8086 &lsquo;&lsquo;as.h&rsquo;&rsquo;
+and &lsquo;&lsquo;as.c&rsquo;&rsquo; files.</p>
+<pre><small>/* Constants and type definitions in as.h */
+
+
+#define        UNKNOWN                0
+#define        IS_REG                 0x1
+#define        IS_ACCU                0x2
+#define        IS_DATA                0x4
+#define        IS_LABEL               0x8
+#define        IS_MEM                 0x10
+#define        IS_ADDR                0x20
+#define        IS_ILB                 0x40
+
+
+#define AX                0
+#define BX                3
+#define CL                1
+#define SP                4
+#define BP                5
+#define SI                6
+#define DI                7
+
+
+#define REG( op)         ( op-&gt;type &amp; IS_REG)
+#define ACCU( op)        ( op-&gt;type &amp; IS_REG  &amp;&amp;  op-&gt;reg == AX)
+#define REG_CL( op)      ( op-&gt;type &amp; IS_REG  &amp;&amp;  op-&gt;reg == CL)
+#define DATA( op)        ( op-&gt;type &amp; IS_DATA)
+#define LABEL( op)       ( op-&gt;type &amp; IS_LABEL)
+#define ILB( op)         ( op-&gt;type &amp; IS_ILB)
+#define MEM( op)         ( op-&gt;type &amp; IS_MEM)
+#define ADDR( op)        ( op-&gt;type &amp; IS_ADDR)
+#define EADDR( op)       ( op-&gt;type &amp; ( IS_ADDR | IS_MEM | IS_REG))
+#define CONST1( op)      ( op-&gt;type &amp; IS_DATA  &amp;&amp; strcmp( &quot;1&quot;, op-&gt;expr) == 0)
+#define MOVS( op)        ( op-&gt;type &amp; IS_LABEL&amp;&amp;strcmp(&quot;
+#define IMMEDIATE( op)   ( op-&gt;type &amp; ( IS_DATA | IS_LABEL))
+
+
+struct t_operand {
+        unsigned type;
+        int reg;
+        char *expr, *lab, *off;
+       };
+
+
+extern struct t_operand saved_op, *AX_oper;
+</small></pre>
+<pre><small>/* Some functions in as.c. */
+
+
+#include &quot;arg_type.h&quot;
+#include &quot;as.h&quot;
+
+
+#define last( s)     ( s + strlen( s) - 1)
+#define LEFT         &rsquo;(&rsquo;
+#define RIGHT        &rsquo;)&rsquo;
+#define DOLLAR       &rsquo;$&rsquo;
+
+
+process_operand( str, op)
+char *str;
+struct t_operand *op;
+
+
+/*        expr            -&gt;        IS_DATA en IS_LABEL
+ *        reg             -&gt;        IS_REG en IS_ACCU
+ *        (expr)          -&gt;        IS_ADDR
+ *        expr(reg)       -&gt;        IS_MEM
+ */
+{
+        char *ptr, *index();
+
+
+        op-&gt;type = UNKNOWN;
+        if ( *last( str) == RIGHT) {
+                ptr = index( str, LEFT);
+                *last( str) = &rsquo; &rsquo;;
+                *ptr = &rsquo; &rsquo;;
+                if ( is_reg( ptr+1, op)) {
+                        op-&gt;type = IS_MEM;
+                        op-&gt;expr = ( *str == &rsquo; &rsquo; ? &quot;0&quot; : str);
+                }
+                else {
+                        set_label( ptr+1, op);
+                        op-&gt;type = IS_ADDR;
+                }
+        }
+        else
+                if ( is_reg( str, op))
+                        op-&gt;type = IS_REG;
+                else {
+                        if ( contains_label( str))
+                                set_label( str, op);
+                        else {
+                                op-&gt;type = IS_DATA;
+                                op-&gt;expr = str;
+                        }
+                }
+}
+
+
+/*********************************************************************/
+
+
+mod_RM( reg, op)
+int reg;
+struct t_operand *op;
+
+
+/* This function helps to decode operands in machine format.
+ * Note the $-operators
+ */
+{
+      if ( REG( op))
+              R233( 0x3, reg, op-&gt;reg);
+      else if ( ADDR( op)) {
+              R233( 0x0, reg, 0x6);
+              @reloc2( %$(op-&gt;lab), %$(op-&gt;off), ABSOLUTE);
+      }
+      else if ( strcmp( op-&gt;expr, &quot;0&quot;) == 0)
+              switch( op-&gt;reg) {
+                case SI : R233( 0x0, reg, 0x4);
+                          break;
+
+
+                case DI : R233( 0x0, reg, 0x5);
+                          break;
+
+
+                case BP : R233( 0x1, reg, 0x6);        /* exception! */
+                          @text1( 0);
+                          break;
+
+
+                case BX : R233( 0x0, reg, 0x7);
+                          break;
+
+
+                default : fprint( STDERR, &quot;Wrong index register %d\n&quot;,
+                                  op-&gt;reg);
+              }
+      else {
+              @if ( fit_byte( %$(op-&gt;expr)))
+                      switch( op-&gt;reg) {
+                          case SI : R233( 0x1, reg, 0x4);
+                                  break;
+
+
+                        case DI : R233( 0x1, reg, 0x5);
+                                  break;
+
+
+                        case BP : R233( 0x1, reg, 0x6);
+                                  break;
+
+
+                        case BX : R233( 0x1, reg, 0x7);
+                                  break;
+
+
+                        default : fprint( STDERR, &quot;Wrong index register %d\n&quot;,
+                                          op-&gt;reg);
+                      }
+                      @text1( %$(op-&gt;expr));
+              @else
+                      switch( op-&gt;reg) {
+                        case SI : R233( 0x2, reg, 0x4);
+                                  break;
+
+
+                        case DI : R233( 0x2, reg, 0x5);
+                                  break;
+
+
+                        case BP : R233( 0x2, reg, 0x6);
+                                  break;
+
+
+                        case BX : R233( 0x2, reg, 0x7);
+                                  break;
+
+
+                        default : fprint( STDERR, &quot;Wrong index register %d\n&quot;,
+                                          op-&gt;reg);
+                      }
+                      @text2( %$(op-&gt;expr));
+              @fi
+      }
+}
+</small></pre>
+<a name="4.3. Generating assembly code"></a>
+<h2>4.3. Generating assembly code</h2>
+
+<p>It is possible to generate assembly instead of object
+files (see section 5), in which case there is no need to
+supply &lsquo;&lsquo;as_table&rsquo;&rsquo;,
+&lsquo;&lsquo;as.h&rsquo;&rsquo;, and
+&lsquo;&lsquo;as.c&rsquo;&rsquo;. This option is useful for
+debugging the EM_table.</p>
+<a name="5. Building a code expander"></a>
+<h2>5. Building a code expander</h2>
+
+<p>This section describes how to generate a code expander
+in two phases. In phase one, the EM_table is written and
+assembly code is generated. If the assembly code is an
+actual language, the EM_table can be tested by assembling
+and running the generated code. If an ad-hoc assembly
+language is used by the table writer, it is not possible to
+test the EM_table, but the code generated is at least in
+readable form. In the second phase, the as_table is written
+and object code is generated. After the generated object
+code is fed into the loader, it can be tested.</p>
+<a name="5.1. Phase one"></a>
+<h2>5.1. Phase one</h2>
+
+<p>The following is a list of instructions to make a code
+expander that generates assembly instructions.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="2%"></td>
+<td width="54%">
+
+<p>Create a new directory.</p>
+</td>
+<td width="34%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>Create the &lsquo;&lsquo;EM_table&rsquo;&rsquo;,
+&lsquo;&lsquo;mach.h&rsquo;&rsquo;, and
+&lsquo;&lsquo;mach.c&rsquo;&rsquo; files; there is no need
+for &lsquo;&lsquo;as_table&rsquo;&rsquo;,
+&lsquo;&lsquo;as.h&rsquo;&rsquo;, and
+&lsquo;&lsquo;as.c&rsquo;&rsquo; at this moment.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>3:</p>
+</td>
+<td width="2%"></td>
+<td width="9%">
+
+<p>type</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><tt>install_ceg -as</tt><br>
+install_ceg will create a Makefile and three directories :
+ceg, ce, and back. Ceg will contain the program ceg; this
+program will be used to turn
+&lsquo;&lsquo;EM_table&rsquo;&rsquo; into a set of C source
+files (in the ce directory), one for each EM-instruction.
+All these files will be compiled and put in a library called
+<b>ce.a</b>.<br>
+The option <tt>-as</tt> means that a <b>back</b>-library
+will be generated (in the directory
+&lsquo;&lsquo;back&rsquo;&rsquo;) that supports the
+generation of assembly language. The library is named
+&lsquo;&lsquo;back.a&rsquo;&rsquo;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>4:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>Link a front end, &lsquo;&lsquo;ce.a&rsquo;&rsquo;, and
+&lsquo;&lsquo;back.a&rsquo;&rsquo; together resulting in a
+compiler that generates assembly code.</p>
+</td>
+</table>
+
+<p>If the table writer has chosen an actual assembly
+language, the EM_table can be tested (e.g., by running the
+compiler on the EM test set). If an error occurs, change the
+EM_table and type</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><tt>update_ceg</tt> <b>C_instr</b></p>
+</td>
+</table>
+
+<p>where <b>C_instr</b> stands for the name of the
+erroneous EM-instruction. If the table writer has chosen an
+ad-hoc assembly language, he can at least read the generated
+code and look for possible errors. If an error is found, the
+same procedure as described above can be followed.</p>
+<a name="5.2. Phase two"></a>
+<h2>5.2. Phase two</h2>
+
+<p>The next phase is to generate a <b>ce</b> that produces
+relocatable object code.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="2%"></td>
+<td width="89%">
+
+<p>Remove the &lsquo;&lsquo;ce&rsquo;&rsquo;,
+&lsquo;&lsquo;ceg&rsquo;&rsquo;, and
+&lsquo;&lsquo;back&rsquo;&rsquo; directories.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="2%"></td>
+<td width="89%">
+
+<p>Write the &lsquo;&lsquo;as_table&rsquo;&rsquo;,
+&lsquo;&lsquo;as.h&rsquo;&rsquo;, and
+&lsquo;&lsquo;as.c&rsquo;&rsquo; files.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>3:</p>
+</td>
+<td width="2%"></td>
+<td width="9%">
+
+<p>type</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p><tt>install_ceg -obj</tt></p>
+
+<p>The option <tt>-obj</tt> means that
+&lsquo;&lsquo;back.a&rsquo;&rsquo; will contain a library
+for generating ACK.OUT(5ACK) object files, see appendix B.
+If the writer does not want to use the default
+&lsquo;&lsquo;back.a&rsquo;&rsquo;, the <tt>-obj</tt> flag
+must omitted and a &lsquo;&lsquo;back.a&rsquo;&rsquo; should
+be supplied that generates the generates object code in the
+desired format.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>4:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>Link a front end, &lsquo;&lsquo;ce.a&rsquo;&rsquo;, and
+&lsquo;&lsquo;back.a&rsquo;&rsquo; together resulting in a
+compiler that generates object code.</p>
+</td>
+</table>
+
+<p>The as_table is ready to be tested. If an error occurs,
+adapt the table. Then there are two ways to proceed:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="2%"></td>
+<td width="68%">
+
+<p>recompile the whole EM_table,</p>
+</td>
+<td width="20%">
+</td>
+</table>
+
+<p><tt>update_ceg ALL</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="1%"></td>
+<td width="90%">
+
+<p>recompile just the few EM-instructions that contained
+the error,</p>
+</td>
+</table>
+
+<p><tt>update_ceg</tt> <b>C_instr</b></p>
+
+<p>where <b>C_instr</b> is an erroneous EM-instruction.
+This has to be done for every EM-instruction that contained
+the erroneous assembly instruction.</p>
+<a name="6. Acknowledgements"></a>
+<h2>6. Acknowledgements</h2>
+
+<p>We want to thank Henri Bal, Dick Grune, and Ceriel
+Jacobs for their valuable suggestions and the critical
+reading of this paper.</p>
+<a name="7. References"></a>
+<h2>7. References</h2>
+<a name="References"></a>
+<h2>References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="5%"></td>
+<td width="90%">
+
+<p>A.S. Tanenbaum, H. v. Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;APractical Toolkit For Making
+Compilers,&rdquo; <i>Communications of the ACM,</i> 26, 9
+(September 1983).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="5%"></td>
+<td width="90%">
+
+<p>A.S. Tanenbuum, H. v. Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;Description of a Machine Architecture for
+Use with Block Structured Languages,&rdquo; IR-81, Dept.
+Mathematics and Computer Science, Vrije Universiteit,
+Amsterdam (August 1983).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="5%"></td>
+<td width="90%">
+
+<p>ACK Documentation, <i>EM_CODE(3ACK),</i> Dept.
+Mathematics and Computer Science, Vrije Universiteit,
+Amsterdam.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="5%"></td>
+<td width="90%">
+
+<p>ACK Documentation, <i>ACK.OUT(5ACK),</i> Dept.
+Mathematics and Computer Science, Vrije Universiteit,
+Amsterdam.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="5%"></td>
+<td width="90%">
+
+<p>B.W. Kernighan and D.M. Ritchie, <i>The C Programming
+Language,</i> Prentice-Hall Inc., Englewood Cliffs, New
+Jersey (1978).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6.</p>
+</td>
+<td width="5%"></td>
+<td width="90%">
+
+<p>ACK Documentation, <i>PRINT(3ACK),</i> Dept. Mathematics
+and Computer Science, Vrije Universiteit, Amsterdam.</p>
+</td>
+</table>
+<a name="Appendix A, the back -primitives"></a>
+<h2>Appendix A, the back -primitives</h2>
+
+<p>This appendix describes the routines available to
+generate relocatable object code. If the default back.a is
+used, the object code is in ACK.OUT(5ACK) format. In de
+default back.a, the names defined here are remapped to more
+hidden names, to avoid name conflicts with for instance
+names used in the front-end. This remapping is done in an
+include-file, &quot;back.h&quot;. A user-implemented back.a
+should do the same thing.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>A1.</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Text and data generation; with ONE_BYTE b;
+TWO_BYTES w; FOUR_BYTES l; arith n;</small></p>
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-106569.png"></small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>A2.</small></p>
+</td>
+<td width="4%"></td>
+<td width="82%">
+
+<p><small>Relocation; with char *s; arith o; int
+r;</small></p>
+</td>
+<td width="7%">
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-1065610.png"></small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>A3.</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Symbol table interaction; with int seg; char
+*s;</small></p>
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-1065611.png"></small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>A4.</small></p>
+</td>
+<td width="4%"></td>
+<td width="64%">
+
+<p><small>Start/end actions; with char *f;</small></p>
+</td>
+<td width="25%">
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-1065612.png"></small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>A5.</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Label generation routines; with int n; arith g;
+char *l; These routines all return a &quot;char *&quot; to a
+static area, which is overwritten at each call.</small></p>
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-1065613.png"></small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>A6.</small></p>
+</td>
+<td width="4%"></td>
+<td width="84%">
+
+<p><small>Some miscellaneous routines, with char
+*l;</small></p>
+</td>
+<td width="5%">
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-1065614.png"></small></p>
+<a name="Appendix B, description of ACK-a.out library"></a>
+<h2>Appendix B, description of ACK-a.out library</h2>
+
+<p>The object file produced by <b>ce</b> is by default in
+ACK.OUT(5ACK) format. The object file is made up of one
+header, followed by four segment headers, followed by text,
+data, relocation information, symbol table, and the string
+area. The object file is tuned for the ACK-LED, so there are
+some special things done just before the object file is
+dumped. First, four relocation records are added which
+contain the names of the four segments. Second, all the
+local relocation is resolved. This is done by the function
+do_relo(). If there is a record belonging to a local name
+this address is relocated in the segment to which the record
+belongs. Besides doing the local relocation, do_relo()
+changes the &lsquo;&lsquo;nami&rsquo;&rsquo;-field of the
+local relocation records. This field receives the index of
+one of the four relocation records belonging to a segment.
+After the local relocation has been resolved the routine
+output_back() dumps the ACK object file.</p>
+
+<p>If a different a.out format is wanted, one can choose
+between three strategies:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="3%"></td>
+<td width="90%">
+
+<p>The most simple one is to use a conversion program,
+which converts the ACK a.out format to the wanted a.out
+format. This program exists for all most all machines on
+which ACK runs. However, not all conversion programs can
+generate relocation information. The disadvantage is that
+the compiler will become slower.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="3%"></td>
+<td width="90%">
+
+<p>A better solution is to change the functions
+output_back(), do_relo(), open_back(), and close_back() in
+such a way that they produce the wanted a.out format. This
+strategy saves a lot of I/O.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="4%">
+
+<p>3:</p>
+</td>
+<td width="3%"></td>
+<td width="90%">
+
+<p>If this still is not satisfactory, the
+<b>back</b>-primitives can be adapted to produce the wanted
+a.out format.</p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/ceg.pdf b/src/olddocs/ceg.pdf
new file mode 100644 (file)
index 0000000..2f4b0f7
Binary files /dev/null and b/src/olddocs/ceg.pdf differ
diff --git a/src/olddocs/cg.html b/src/olddocs/cg.html
new file mode 100644 (file)
index 0000000..b8dbcbe
--- /dev/null
@@ -0,0 +1,4597 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:07 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The table driven code generator from</title>
+</head>
+<body>
+
+<h1 align=center>The table driven code generator from</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. Global overview of the workings of the code generator.">2. Global overview of the workings of the code generator.</a><br>
+<a href="#3. Description of the machine table">3. Description of the machine table</a><br>
+<a href="#3.1. Some constants">3.1. Some constants</a><br>
+<a href="#3.2. Register definition">3.2. Register definition</a><br>
+<a href="#3.3. Stack token definition">3.3. Stack token definition</a><br>
+<a href="#3.4. Token expressions">3.4. Token expressions</a><br>
+<a href="#3.5. Expressions">3.5. Expressions</a><br>
+<a href="#3.6. Code rules">3.6. Code rules</a><br>
+<a href="#3.6.1. The EM pattern">3.6.1. The EM pattern</a><br>
+<a href="#3.6.2. The stack pattern">3.6.2. The stack pattern</a><br>
+<a href="#3.6.3. The code part">3.6.3. The code part</a><br>
+<a href="#3.6.3.1. Stack cleanup">3.6.3.1. Stack cleanup</a><br>
+<a href="#3.6.3.2. Register allocation">3.6.3.2. Register allocation</a><br>
+<a href="#3.6.3.3. Code">3.6.3.3. Code</a><br>
+<a href="#3.6.4. Stack replacement">3.6.4. Stack replacement</a><br>
+<a href="#3.6.5. EM replacement">3.6.5. EM replacement</a><br>
+<a href="#3.6.6. Cost">3.6.6. Cost</a><br>
+<a href="#3.6.7. Examples">3.6.7. Examples</a><br>
+<a href="#3.7. Move code rules">3.7. Move code rules</a><br>
+<a href="#3.8. Test code rules">3.8. Test code rules</a><br>
+<a href="#3.9. Stacking code rules.">3.9. Stacking code rules.</a><br>
+<a href="#4. The files mach.h and mach.c">4. The files mach.h and mach.c</a><br>
+<a href="#4.1. Types in the code generator">4.1. Types in the code generator</a><br>
+<a href="#4.2. Global variables to work with">4.2. Global variables to work with</a><br>
+<a href="#4.3. Macros in mach.h">4.3. Macros in mach.h</a><br>
+<a href="#4.3.1. Example mach.h for the PDP-11">4.3.1. Example mach.h for the PDP-11</a><br>
+<a href="#4.4. Functions in mach.c">4.4. Functions in mach.c</a><br>
+<a href="#4.4.1. Example mach.c for the PDP-11">4.4.1. Example mach.c for the PDP-11</a><br>
+<a href="#5. Coercions">5. Coercions</a><br>
+<a href="#6. Internal workings of the code generator.">6. Internal workings of the code generator.</a><br>
+<a href="#6.1. Description of tables.c and tables.h contents">6.1. Description of tables.c and tables.h contents</a><br>
+<a href="#6.1.1. Tables.c">6.1.1. Tables.c</a><br>
+<a href="#6.1.2. tables.h">6.1.2. tables.h</a><br>
+<a href="#6.2. Other important data structures">6.2. Other important data structures</a><br>
+<a href="#6.3. A tour through the sources">6.3. A tour through the sources</a><br>
+<a href="#6.3.1. codegen.c">6.3.1. codegen.c</a><br>
+<a href="#6.3.1.1. DO_NEXTEM">6.3.1.1. DO_NEXTEM</a><br>
+<a href="#6.3.1.2. DO_COERC">6.3.1.2. DO_COERC</a><br>
+<a href="#6.3.1.3. DO_XMATCH">6.3.1.3. DO_XMATCH</a><br>
+<a href="#6.3.1.4. DO_MATCH">6.3.1.4. DO_MATCH</a><br>
+<a href="#6.3.1.5. DO_REMOVE">6.3.1.5. DO_REMOVE</a><br>
+<a href="#6.3.1.6. DO_DEALLOCATE">6.3.1.6. DO_DEALLOCATE</a><br>
+<a href="#6.3.1.7. DO_REALLOCATE">6.3.1.7. DO_REALLOCATE</a><br>
+<a href="#6.3.1.8. DO_ALLOCATE">6.3.1.8. DO_ALLOCATE</a><br>
+<a href="#6.3.1.9. DO_LOUTPUT">6.3.1.9. DO_LOUTPUT</a><br>
+<a href="#6.3.1.10. DO_ROUTPUT">6.3.1.10. DO_ROUTPUT</a><br>
+<a href="#6.3.1.11. DO_MOVE">6.3.1.11. DO_MOVE</a><br>
+<a href="#6.3.1.12. DO_ERASE">6.3.1.12. DO_ERASE</a><br>
+<a href="#6.3.1.13. DO_TOKREPLACE">6.3.1.13. DO_TOKREPLACE</a><br>
+<a href="#6.3.1.14. DO_EMREPLACE">6.3.1.14. DO_EMREPLACE</a><br>
+<a href="#6.3.1.15. DO_COST">6.3.1.15. DO_COST</a><br>
+<a href="#6.3.1.16. DO_RETURN">6.3.1.16. DO_RETURN</a><br>
+<a href="#6.3.2. compute.c">6.3.2. compute.c</a><br>
+<a href="#6.3.3. equiv.c">6.3.3. equiv.c</a><br>
+<a href="#6.3.4. fillem.c">6.3.4. fillem.c</a><br>
+<a href="#6.3.5. gencode.c">6.3.5. gencode.c</a><br>
+<a href="#6.3.6. glosym.c">6.3.6. glosym.c</a><br>
+<a href="#6.3.7. main.c">6.3.7. main.c</a><br>
+<a href="#6.3.8. move.c">6.3.8. move.c</a><br>
+<a href="#6.3.9. nextem.c">6.3.9. nextem.c</a><br>
+<a href="#6.3.10. reg.c">6.3.10. reg.c</a><br>
+<a href="#6.3.11. salloc.c">6.3.11. salloc.c</a><br>
+<a href="#6.3.12. state.c">6.3.12. state.c</a><br>
+<a href="#6.3.13. subr.c">6.3.13. subr.c</a><br>
+<a href="#6.3.13.1. match">6.3.13.1. match</a><br>
+<a href="#6.3.13.2. instance,cinstance">6.3.13.2. instance,cinstance</a><br>
+<a href="#6.3.13.3. eqtoken">6.3.13.3. eqtoken</a><br>
+<a href="#6.3.13.4. distance">6.3.13.4. distance</a><br>
+<a href="#6.3.13.5. split">6.3.13.5. split</a><br>
+<a href="#6.3.13.6. docoerc">6.3.13.6. docoerc</a><br>
+<a href="#6.3.13.7. stackupto">6.3.13.7. stackupto</a><br>
+<a href="#6.3.13.8. findcoerc">6.3.13.8. findcoerc</a><br>
+<a href="#6.3.14. var.c">6.3.14. var.c</a><br>
+
+<hr>
+
+<p><b>the Amsterdam Compiler Kit</b></p>
+
+<p align=center><i><small>ABSTRACT</small></i></p>
+
+<p align=center><i><small>Hans van
+Staveren</small></i><small><br>
+Dept. of Mathematics and Computer Science<br>
+Vrije Universiteit<br>
+Amsterdam, The Netherlands</small></p>
+
+<p><small>It is possible to automate the process of
+compiler building to a great extent using collections of
+tools. The Amsterdam Compiler Kit is such a collection of
+tools. This document provides a description of the internal
+workings of the table driven code generator in the Amsterdam
+Compiler Kit, and a description of syntax and semantics of
+the driving table.</small></p>
+
+<p><small>&gt;&gt;&gt; NOTE &lt;&lt;&lt;<br>
+This document pertains to the <b>old</b> code generator.
+Refer to the &quot;Second Revised Edition&quot; for the new
+code generator.</small></p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p><small>Part of the Amsterdam Compiler Kit is a code
+generator system consisting of a code generator generator
+(<i>cgg</i> for short) and some machine independent C code.
+<i>Cgg</i> reads a machine description table and creates two
+files, tables.h and tables.c. These are then used together
+with other C code to produce a code generator for the
+machine at hand.</small></p>
+
+<p><small>This in turn reads compact EM code and produces
+assembly code. The remainder of this document will first
+broadly describe the working of the code generator, then a
+description of the machine table follows after which the
+internal workings of the code generator will be
+explained.</small></p>
+
+<p><small>The reader is assumed to have at least a vague
+notion about the semantics of the intermediary EM code.
+Someone wishing to write a table for a new machine should be
+thoroughly acquainted with EM code and the assembly code of
+the machine at hand.</small></p>
+<a name="2. Global overview of the workings of the code generator."></a>
+<h2>2. Global overview of the workings of the code generator.</h2>
+
+<p><small>The code generator or <i>cg</i> tries to generate
+good code by simulating the runtime stack of the program
+compiled and delaying emission of code as long as possible.
+It also keeps track of register contents, which enables it
+to eliminate redundant moves, and tries to eliminate
+redundant tests by keeping information about condition code
+status, if applicable for the machine.</small></p>
+
+<p><small><i>Cg</i> maintains a &lsquo;fakestack&rsquo;
+containing &lsquo;tokens&rsquo; that are built by executing
+the pseudo code contained in the code rules given by the
+table writer. One can think of the fakestack as a logical
+extension of the real stack the program compiled will have
+when run. During code generation tokens will be kept on the
+fakestack as long as possible but when they are moved to the
+real stack, by generating code for the push, all tokens
+above*</small></p>
+
+
+<p align=center><small><img src="grohtml-99261.png"></small></p>
+
+<p><small>the tokens pushed will be pushed also, so that
+the fakestack will not contain holes.</small></p>
+
+<p><small>The main loop of <i>cg</i> is this:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>find a pattern of EM instructions starting at the
+current one to generate code for. This pattern will usually
+be of length one but longer patterns can be
+used.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Select one of the possibly many stack patterns
+that go with this EM pattern on the basis of heuristics
+and/or lookahead.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Force the current fakestack contents to match the
+pattern. This may involve copying tokens to registers,
+making dummy transformations, e.g. to transform a
+&quot;local&quot; into an &quot;register offsetted&quot; or
+might even cause to have the complete fakestack contents put
+to the real stack and then back into registers if no
+suitable transformations were provided by the table
+writer.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Execute the pseudocode associated with the code
+rule just selected, this may cause registers to be
+allocated, code to be emitted etc..</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>5)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Put tokens onto the fakestack to reflect the
+result of the operation.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>6)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Insert some EM instructions into the stream, this
+is possible but not common.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>7)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Account for the cost. The cost is kept in a
+(space, time) vector and lookahead decisions are based on a
+linear combination of these.</small></p>
+</td>
+</table>
+
+<p><small>The table that drives <i>cg</i> is not read in
+every time, but instead is used at compiletime of <i>cg</i>
+to set parameters and to load pseudocode tables. A program
+called <i>cgg</i> reads the table and produces large lists
+of numbers that are compiled together with machine
+independent code to produce a code generator for the machine
+at hand.</small></p>
+<a name="3. Description of the machine table"></a>
+<h2>3. Description of the machine table</h2>
+
+<p><small>The machine description table consists of the
+following sections:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>Constant definitions</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>Register definitions</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p><small>Token definitions</small></p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4)</small></p>
+</td>
+<td width="6%"></td>
+<td width="56%">
+
+<p><small>Token expression definitions</small></p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>5)</small></p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p><small>Code rules</small></p>
+</td>
+<td width="69%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>6)</small></p>
+</td>
+<td width="6%"></td>
+<td width="32%">
+
+<p><small>Move definitions</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>7)</small></p>
+</td>
+<td width="6%"></td>
+<td width="32%">
+
+<p><small>Test definitions</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>8)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>Stacking definitions</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+
+<p><small>Input is in free format, white space and newlines
+may be used at will to improve legibility. Identifiers used
+in the table have the same syntax as C identifiers, upper
+and lower case considered different, all characters
+significant. There is however one exception: identifiers
+must be more than one character long for parsing reasons. C
+style comments are accepted</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>/* this is a comment */</small></p>
+</table>
+
+<p><small>and #define macros may be used if the need
+arises.</small></p>
+<a name="3.1. Some constants"></a>
+<h2>3.1. Some constants</h2>
+
+<p><small>Before anything else three constants must be
+defined, all with the syntax NAME=value, value being an
+integer. These constants are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>EM_WSIZE</small></p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p><small>Number of bytes in a machine word. This is the
+number of bytes a simple <b>loc</b> instruction will put on
+the stack.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>EM_PSIZE</small></p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p><small>Number of bytes in a pointer. This is the number
+of bytes a <b>lal</b> instruction will put on the
+stack.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>EM_BSIZE</small></p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p><small>Number of bytes in the hole between AB and LB. If
+the calling sequence just saves PC and LB this size will be
+twice the pointersize.</small></p>
+</td>
+</table>
+
+<p><small>EM_WSIZE and EM_PSIZE are checked when a program
+is compiled with the resulting code generator. EM_BSIZE is
+used by <i>cg</i> to add to the offset of instructions
+dealing with locals having positive offsets, i.e.
+parameters.</small></p>
+
+<p><small>Optionally one can give here the factors with
+which the size and time parts of the cost function have to
+be multiplied to ensure they have the same order of
+magnitude. This can be done as</small></p>
+<pre><small>     TIMEFACTOR = C1/C2
+     SIZEFACTOR = C3/C4
+</small></pre>
+
+<p><small>Above numbers must be read as rational numbers.
+Defaults are 1/1 for both of them. These constants set the
+default size/time tradeoff in the code generator, so if
+TIMEFACTOR and SIZEFACTOR are both 1 the code generator will
+choose at random between two codesequences where one has
+cost (10,4) and the other has cost (8,6). See also the
+description of the cost field below.</small></p>
+
+<p><small>Also optional is the definition of a printformat
+for integers in the codefile. This is given as</small></p>
+<pre><small>     FORMAT = string
+</small></pre>
+
+<p><small>The default for string is &quot;%ld&quot;. For
+example on the PDP 11 one can use</small></p>
+<pre><small>     FORMAT= &quot;0%lo&quot;
+</small></pre>
+
+<p><small>to satisfy the old UNIX assembler that reads
+octal unless followed by a period, and the ACK assembler
+that follows C conventions.</small></p>
+<a name="3.2. Register definition"></a>
+<h2>3.2. Register definition</h2>
+
+<p><small>The next part of the tables describes the various
+registers of the machine and defines identifiers to be used
+in later parts of the tables. Example for the
+PDP-11:</small></p>
+<pre><small>REGISTERS:
+R0 = ( &quot;r0&quot;,2), REG.
+R1 = ( &quot;r1&quot;,2), REG, ODDREG.
+R2 = ( &quot;r2&quot;,2), REG.
+R3 = ( &quot;r3&quot;,2), REG, ODDREG.
+R4 = ( &quot;r4&quot;,2), REG.
+LB = ( &quot;r5&quot;,2), LOCALBASE.
+R01= ( &quot;r0&quot;,4,R0,R1), REGPAIR.
+R23= ( &quot;r2&quot;,4,R2,R3), REGPAIR.
+FR0= ( &quot;r0&quot;,4), FREG.
+FR1= ( &quot;r1&quot;,4), FREG.
+FR2= ( &quot;r2&quot;,4), FREG.
+FR3= ( &quot;r3&quot;,4), FREG.
+DR0= ( &quot;r0&quot;,8,FR0), DREG.
+DR1= ( &quot;r1&quot;,8,FR1), DREG.
+DR2= ( &quot;r2&quot;,8,FR2), DREG.
+DR3= ( &quot;r3&quot;,8,FR3), DREG.
+</small></pre>
+
+<p><small>The identifier before the &rsquo;=&rsquo; sign is
+the name of the register as used further on in the table.
+The string is the name of the register as far as the
+assembler is concerned. The number is the size of the
+register in bytes. Identifiers following the number but
+within the parentheses are previously defined registernames
+that are contained in the register being defined. The
+identifiers following the closing parenthesis are properties
+of the register. So for example R23 is a register with
+assembler name r2, 4 bytes long, contains the registers R2
+and R3 and has the property REGPAIR.</small></p>
+
+<p><small>It might seem wise to list each and every
+property of a register, so one might give R0 the extra
+property MFPTREG named after the not too well known MFPT
+instruction on newer PDP-11 types, but this is not a good
+idea. Every extra property means the registerset is more
+unorthogonal and <i>cg</i> execution time is influenced by
+that, because it has to take into account a larger set of
+registers that are not equivalent.</small></p>
+
+<p><small>There is a predefined property SCRATCH that is
+dynamic, i.e. a register can have the property SCRATCH one
+time, and loose it the next. A register has the property
+SCRATCH when it has a reference count of one. One needs to
+be able to discriminate between SCRATCH registers and
+others, because it is only allowed to do arithmetic on
+SCRATCH registers.</small></p>
+<a name="3.3. Stack token definition"></a>
+<h2>3.3. Stack token definition</h2>
+
+<p><small>The next part describes all possible tokens that
+can reside on the fakestack during code generation.
+Attributes of a token are described in the form of a C
+struct declaration, this is followed by the size in bytes of
+the token, optionally followed by the cost of the token when
+used as an addressing mode and the format to be used on
+output.</small></p>
+
+<p><small>Tokens should usually be declared for every
+addressing mode of the machine at hand and for every size
+directly usable in a machine instruction. Example for the
+PDP-11 (incomplete):</small></p>
+<pre><small>TOKENS:
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>IREG2 =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>{ REGISTER reg; } 2 &quot;*%[reg]&quot; /*
+indirect register */</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>REGCONST =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>{ REGISTER reg; STRING off; } 2 /* not really
+addressable */</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>REGOFF2 =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>{ REGISTER reg; STRING off; } 2
+&quot;%[off](%[reg])&quot;</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>IREGOFF2 =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>{ REGISTER reg; STRING off; } 2
+&quot;*%[off](%[reg])&quot;</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>CONST =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>{ INT off; } 2 cost=(2,850)
+&quot;$%[off].&quot;</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>EXTERN2 =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>{ STRING off; } 2 &quot;%[off]&quot;</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>IEXTERN2 =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>{ STRING off; } 2 &quot;*%[off]&quot;</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>PAIRSIGNED =</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>{ REGISTER regeven,regodd; } 2
+&quot;%[regeven]&quot;</small></p>
+</td>
+<td width="59%">
+</td>
+</table>
+
+<p><small>Types allowed in the struct are REGISTER, INT and
+STRING. Tokens without a printformat should never be
+output.</small></p>
+
+<p><small>Notice that tokens need not correspond to
+addressing modes, the REGCONST token listed above, meaning
+the sum of the contents of the register and the constant,
+has no corresponding addressing mode on the PDP-11, but is
+included so that a sequence of add constant, load indirect,
+can be handled efficiently. This REGCONST token is needed as
+part of the path</small></p>
+<pre><small>     REGISTER -&gt; REGCONST -&gt; REGOFF
+</small></pre>
+
+<p><small>of which the first and the last &quot;exist&quot;
+and the middle is needed only as an intermediate
+step.</small></p>
+<a name="3.4. Token expressions"></a>
+<h2>3.4. Token expressions</h2>
+
+<p><small>Usually machines have certain collections of
+addressing modes that can be used with certain instructions.
+The stack patterns in the table are lists of these
+collections and since it is cumbersome to write out these
+long lists every time, there is a section here to give names
+to these collections. Please note that it is not forbidden
+to write out a token expression in the remainder of the
+table, but for clarity it is usually better not to. Example
+for the PDP-11 (incomplete):</small></p>
+<pre><small>TOKENEXPRESSIONS:
+SOURCE2 = REG + IREG2 + REGOFF2 + IREGOFF2 + CONST + EXTERN2 +
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>IEXTERN2</small></p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p><small>SREG = REG * SCRATCH</small></p>
+
+<p><small>Permissible in the expressions are all PASCAL set
+operators, i.e.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>+</small></p>
+</td>
+<td width="8%"></td>
+<td width="18%">
+
+<p><small>set union</small></p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="28%">
+
+<p><small>set difference</small></p>
+</td>
+<td width="61%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>*</small></p>
+</td>
+<td width="8%"></td>
+<td width="32%">
+
+<p><small>set intersection</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+
+<p><small>Every tokenidentifier is also a token expression
+identifier denoting the singleton collection of tokens
+containing just itself. Every register property as defined
+above is also a token expression matching all registers with
+that property when on the fakestack. The standard token
+expression identifier ALL denotes the collection of all
+tokens.</small></p>
+<a name="3.5. Expressions"></a>
+<h2>3.5. Expressions</h2>
+
+<p><small>Throughout the rest of the table expressions can
+be used in some places. This section will give the syntax
+and semantics of expressions. There are four types of
+expressions: integer, string, register and undefined. Type
+checking is performed by <i>cgg</i>. An operator with at
+least one undefined operand returns undefined except for the
+defined() function mentioned below. An undefined expression
+is interpreted as FALSE when it is needed as a truth value.
+Basic terms in an expression are</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>number</small></p>
+</td>
+<td width="20%"></td>
+<td width="68%">
+
+<p><small>A number is a constant of type
+integer.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>string</small></p>
+</td>
+<td width="20%"></td>
+<td width="68%">
+
+<p><small>A string within double quotes is a constant of
+type string. All the normal C style escapes may be used
+within the string.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>REGIDENT</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>The name of a register is a constant of type
+register.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>$<i>i</i></small></p>
+</td>
+<td width="28%"></td>
+<td width="68%">
+
+<p><small>A dollarsign followed by a number is the
+representation of the argument of EM instruction . The type
+of the operand is dependent on the instruction, sometimes it
+is integer, sometimes it is string. It is undefined when the
+instruction has no operand.</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="31%"></td>
+<td width="68%">
+<p><small>Although an exhaustive list could be given
+describing all the types the following rule of thumb will
+suffice. If it is unimaginable for the operand of the
+instruction ever to be something different from a plain
+integer, the type is integer, otherwise it is string.<i><br>
+Cg</i> makes all necessary conversions, like adding EM_BSIZE
+to positive arguments of instructions dealing with locals,
+prepending underlines to global names, converting codelabels
+into a unique representation etc. Details about this can be
+found in the section about machine dependent C
+code.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>%[1]</small></p>
+</td>
+<td width="24%"></td>
+<td width="68%">
+
+<p><small>This in general means the token mentioned first
+in the stack pattern. When used inside an expression the
+token must be a simple register. Type of this is
+register.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>%[1.off]</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>This means field &quot;off&quot; of the first
+stack pattern token. Type is the same as that of field
+&quot;off&quot;. To use this expression implies a check that
+all tokens in the token expression used have the same
+attributes.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>%[1.1]</small></p>
+</td>
+<td width="20%"></td>
+<td width="68%">
+
+<p><small>This is the first subregister of the first token.
+Previous comments apply.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>%[b]</small></p>
+</td>
+<td width="24%"></td>
+<td width="60%">
+
+<p><small>The second allocated register.</small></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>%[a.2]</small></p>
+</td>
+<td width="20%"></td>
+<td width="68%">
+
+<p><small>The second subregister of the first allocated
+register.</small></p>
+</td>
+</table>
+
+<p><small>All normal C operators apply to integers, the +
+operator serves for string concatenation and register
+expressions can only be compared to each other. Furthermore
+there are some special &quot;functions&quot;:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>tostring(e)</small></p>
+</td>
+<td width="10%"></td>
+<td width="68%">
+
+<p><small>Converts an integer expression e to a
+string.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>defined(e)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Returns 1 if expression e is defined, 0
+otherwise.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p><small>samesign(e1,e2)</small></p>
+</td>
+<td width="2%"></td>
+<td width="68%">
+
+<p><small>Returns 1 if integer expression e1 and e2 have
+the same sign.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>sfit(e1,e2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="68%">
+
+<p><small>Returns 1 if integer expression e1 fits as a
+signed integer into a field of e2 bits, 0
+otherwise.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>ufit(e1,e2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="68%">
+
+<p><small>Same as above but now for unsigned
+e1.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>rom(a,n)</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Integer expression giving the n&rsquo;th argument
+from the <b>rom</b> descriptor pointed at by the a&rsquo;th
+EM instruction. Undefined if that descriptor does not
+exist.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>loww(a)</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Returns the lower half of the argument of the
+a&rsquo;th EM instruction. This is used to split the
+arguments of a <b>ldc</b> instruction.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>highw(a)</small></p>
+</td>
+<td width="16%"></td>
+<td width="40%">
+
+<p><small>Same for upper half.</small></p>
+</td>
+<td width="27%">
+</td>
+</table>
+<a name="3.6. Code rules"></a>
+<h2>3.6. Code rules</h2>
+
+<p><small>The largest section of the tables consists of the
+code generation rules. They specify EM patterns, stack
+patterns, code to be generated etc. Syntax is</small></p>
+<pre><small>code rule : EM pattern &rsquo;|&rsquo; stack pattern &rsquo;|&rsquo; code &rsquo;|&rsquo;
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>stack replacement &rsquo;|&rsquo; EM replacement
+&rsquo;|&rsquo; cost ;</small></p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p><small>All parts are optional, however there must be at
+least one pattern present. If the empattern is missing the
+rule becomes a rewriting rule or <i>coercion</i> to be used
+when code generation cannot continue because of an invalid
+stack pattern. The code rules are preceded by the
+word</small></p>
+<pre><small>     CODE:
+</small></pre>
+
+<p><small>The next paragraphs describe the various parts in
+detail.</small></p>
+<a name="3.6.1. The EM pattern"></a>
+<h2>3.6.1. The EM pattern</h2>
+
+<p><small>The EM pattern consists of a list of EM mnemonics
+followed by a boolean expression. Examples:</small></p>
+<pre><small><b>     loe
+</b></small></pre>
+
+<p><small>will match a single <b>loe</b>
+instruction,</small></p>
+<pre><small><b>     loc loc cif</b> $1==2 &amp;&amp; $2==8
+</small></pre>
+
+<p><small>is a pattern that will match</small></p>
+<pre><small><b>     loc</b> 2
+<b>     loc</b> 8
+<b>     cif
+</b></small></pre>
+
+<p><small>and</small></p>
+<pre><small><b>     lol inc stl</b> $1==$3
+</small></pre>
+
+<p><small>will match for example</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="6" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small><b>lol</b> 6</small></p>
+<td width="9%"></td>
+<td width="20%">
+
+<p><small><b>lol</b> -2</small></p>
+</td>
+<td width="20%">
+</td>
+<td width="20%">
+
+<p><small><b>lol</b> 4<b><br>
+inc</b></small></p>
+</td>
+<td width="20%"></td>
+<td width="9%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="20%">
+
+<p><small><b>inc</b></small></p>
+</td>
+<td width="20%">
+
+<p><small>but <i>not</i></small></p>
+</td>
+<td width="20%">
+
+<p><small><b>inc<br>
+stl</b> 6</small></p>
+</td>
+<td width="20%"></td>
+<td width="9%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="20%">
+
+<p><small><b>stl</b> -2</small></p>
+</td>
+<td width="20%">
+</td>
+<td width="20%">
+
+<p><small><b>stl</b> -4</small></p>
+</td>
+<td width="20%"></td>
+<td width="9%">
+</td>
+</table>
+
+<p><small>A missing boolean expression evaluates to
+TRUE.</small></p>
+
+<p><small>When the EM pattern is the same as in the
+previous code rule the pattern should be given as
+&lsquo;...&rsquo;. The code generator will match the longest
+EM pattern on every occasion, if two patterns of the same
+length match the first in the table will be chosen, while
+all patterns of length greater than or equal to three are
+considered to be of the same length.</small></p>
+<a name="3.6.2. The stack pattern"></a>
+<h2>3.6.2. The stack pattern</h2>
+
+<p><small>The stack pattern is a list of token expressions,
+usually token expression identifiers for clarity. No boolean
+expression is allowed here. The first expression is the one
+that matches the top of the stack.</small></p>
+
+<p><small>The pattern can be followed by the word STACK in
+which case the pattern only matches if there is nothing else
+on the fakestack. The code generator will stack everything
+not matched at the start of the rule.</small></p>
+
+<p><small>The pattern can be preceded with the
+word</small></p>
+<pre><small>     nocoercions:
+</small></pre>
+
+<p><small>which tells the code generator not to try to
+coerce to the pattern but only to use it when it is already
+there. There are two reasons for this construction,
+correctness and speed. It is needed for correctness when the
+pattern contains a register that is not transparent when
+data is moved through it.</small></p>
+
+<p><small>Example: on the PDP-11 the shortest code
+for</small></p>
+<pre><small><b>     lae</b> a
+<b>     loi</b> 8
+<b>     lae</b> b
+<b>     sti</b> 8
+</small></pre>
+
+<p><small>is</small></p>
+<pre><small>     movf _a,fr0
+     movf fr0,_b
+</small></pre>
+
+<p><small>assuming that the floating point processor is in
+double precision mode and fr0 is free. Unfortunately this is
+not correct since a trap can occur on certain kinds of data.
+This could happen if there was a pattern for <b>sti</b> 8
+that allowed one to move a floating point register not
+preceded by nocoercions: . The code generator would then
+find that moving the 8-byte global _a to a floating point
+register and then storing it to _b was the cheapest,
+assuming that the space/time knob was turned far enough to
+space. It is unfortunate that the type information is no
+longer present, since if _a really is a floating point
+number the move could be made without error.</small></p>
+
+<p><small>The second reason for the nocoercions: construct
+is speed. When the code generator has a long list of
+possible stack patterns for one EM pattern it can waste a
+lot of time trying to find coercions to all of them, while
+the mere presence of such a long list indicates that the
+table writer has given a lot of special cases. In this case
+prepending all the special cases by nocoercions: will stop
+the code generator from trying to find things there
+aren&rsquo;t.</small></p>
+<a name="3.6.3. The code part"></a>
+<h2>3.6.3. The code part</h2>
+
+<p><small>The code part consists of three parts, stack
+cleanup, register allocation and code to generate. All of
+these may be omitted.</small></p>
+<a name="3.6.3.1. Stack cleanup"></a>
+<h2>3.6.3.1. Stack cleanup</h2>
+
+<p><small>The stack cleanup part describes certain
+stacktokens that should neither remain on the fakestack, nor
+remembered as contents of registers. This is usually only
+required with store operations. The entire fakestack, except
+for the part matched in the stack pattern, is searched for
+tokens matching the expression and they are copied to the
+real stack. Every register that contains the stacktoken is
+marked as empty.</small></p>
+
+<p><small>Syntax is</small></p>
+<pre><small>     remove(token expression) <i>or
+</i>     remove(token expression, boolean expression)
+</small></pre>
+
+<p><small>Example:</small></p>
+<pre><small>     remove(REGOFF2,%[reg] != LB || %[off] == $1)
+</small></pre>
+
+<p><small>is part of a remove() call for use in the
+<b>stl</b> code rule. It removes all register offsetted
+tokens where the register is not the localbase plus the
+local wherein the store is done. The necessity for this can
+be seen from the following example:</small></p>
+<pre><small><b>     lol</b> 4
+<b>     inl</b> 4
+<b>     stl</b> 6
+</small></pre>
+
+<p><small>Without a proper remove() call in the rule for
+<b>inl</b> code would be generated as here</small></p>
+<pre><small>     inc 4(r5)
+     mov 4(r5),6(r5)
+</small></pre>
+
+<p><small>so local 6 would be given the new value of local
+4 instead of the old as the EM code prescribed.</small></p>
+
+<p><small>When generating something like a branch
+instruction it might be needed to empty the fakestack
+completely. This can of course be done with</small></p>
+<pre><small>     remove(ALL)
+</small></pre>
+<a name="3.6.3.2. Register allocation"></a>
+<h2>3.6.3.2. Register allocation</h2>
+
+<p><small>The register allocation part describes the kind
+of registers needed. Syntax for allocate() is</small></p>
+<pre><small>     allocate(itemlist)
+</small></pre>
+
+<p><small>where itemlist is a list of three kinds of
+things:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="74%">
+
+<p><small>a tokendescription, for example %[1].</small></p>
+</td>
+<td width="15%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This will instruct the code generator to
+temporarily decrement the reference count of all registers
+contained in the token, so that they are available for
+allocation in this allocate() call if they were only used in
+that token. See example below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>a register property.</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This will allocate a register with that property.
+The register will be marked as empty at this point.
+Lookahead will be performed if necessary.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><small>a register property with
+initialization.</small></p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This will allocate the register as in 2) but will
+also initialize it. This eases the task of the code
+generator because it can find a register already filled with
+the right value if it exists.</small></p>
+</td>
+</table>
+
+<p><small>Examples:</small></p>
+<pre><small>     allocate(OREG)
+</small></pre>
+
+<p><small>will allocate an odd register, while</small></p>
+<pre><small>     allocate(REG={REGOFF2,LB,$1})
+</small></pre>
+
+<p><small>will allocate a register while simultaneously
+filling it with the asked value.<br>
+Inside the coercion from SOURCE2 to REGISTER in the PDP-11
+table the following allocate() can be found.</small></p>
+<pre><small>     allocate(%[1],REG=%[1])
+</small></pre>
+
+<p><small>This tells the code generator that registers
+contained in %[1] can be used again and asks to fill the
+register allocated with %[1]. So if
+%[1]={REGOFF2,R3,&quot;4&quot;} and R3 has a reference count
+of 1 the following code might be generated.</small></p>
+<pre><small>     mov 4(r3),r3
+</small></pre>
+
+<p><small>In the rest of the line the registers allocated
+can be named by %[a] and %[b.1],%[b.2], i.e. with lower case
+letters in order of allocation.</small></p>
+
+<p><small>Warning:</small></p>
+<pre><small>     allocate(R3)
+</small></pre>
+
+<p><small>is not the way to allocate R3. R3 is not a
+register property, so it will be seen as a token description
+and the effect is that R3 will have its reference count
+decremented.</small></p>
+<a name="3.6.3.3. Code"></a>
+<h2>3.6.3.3. Code</h2>
+
+<p><small>Code to be generated is specified as a list of
+items of the following kind:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>a string in double quotes (&quot;This is a
+string&quot;).</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This is copied to the codefile and a newline ( \n
+) is appended. Inside the string all normal C string
+conventions are allowed, and substitutions can be made of
+the following sorts.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p><small>a)</small></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><small>$1, $2 etc. These are the operands of the
+corresponding EM instructions and are printed according to
+their type. To put a real &rsquo;$&rsquo; inside the string
+it must be doubled (&rsquo;$$&rsquo;).</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p><small>b)</small></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><small>%[1], %[2.reg], %[b.1] etc. These have their
+obvious meaning. If they describe a complete token ( %[1] )
+the printformat for the token is used. If they stand for a
+basic term in an expression they will be printed according
+to their type. To put a real &rsquo;%&rsquo; inside the
+string it must be doubled (&rsquo;%%&rsquo;).</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p><small>c)</small></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><small>%( arbitrary expression %). This allows inclusion
+of arbitrary expressions inside strings. Usually not needed
+very often, so that the awkward notation is not too bad.
+Note that %(%[1]%) is equivalent to %[1].</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>a move() call. This has the following
+syntax:</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><small>     move(token description, token description)
+</small></pre>
+<!-- INDENTATION -->
+<p><small>Moves are handled specially since that enables the
+code generator to keep track of register contents.
+Example:</small></p>
+<!-- INDENTATION -->
+<pre><small>     move(R3,{REGOFF2,LB,$1})
+</small></pre>
+<!-- INDENTATION -->
+<p><small>will generate code to move R3 to $1(r5) except
+when R3 already was a copy of $1(r5). Then the code will be
+omitted. The rules describing how to move things to each
+other can be found in the MOVES section described
+below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>an erase() call. This has the following
+syntax:</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><small>     erase(register expression)
+</small></pre>
+<!-- INDENTATION -->
+<p><small>This tells the code generator that the register
+mentioned no longer has any useful value. This is
+<i>necessary</i> after code in the table has changed the
+contents of registers. For example, after an add to a
+register the register must be erased, because the contents
+do no longer match any token.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>For machines that have condition codes, alas most
+of them do, there are provisions to remember condition code
+setting and prevent needless testing. To set the condition
+code to a token put in the code the following
+call:</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><small>     test(token)
+</small></pre>
+<!-- INDENTATION -->
+<p><small>where token can be all of the standard forms that
+can also be used in move(). This will generate a test if the
+condition codes were not already set to that token. It is
+also possible to tell <i>cg</i> that a certain operation,
+like a preceding add has set the condition codes to some
+token with the call</small></p>
+<!-- INDENTATION -->
+<pre><small>     setcc(token)
+</small></pre>
+<!-- INDENTATION -->
+<p><small>So a sequence of a setcc and a test on the same
+token will generate no code. Another allowed call within the
+code is</small></p>
+<!-- INDENTATION -->
+<pre><small>     samecc
+</small></pre>
+<!-- INDENTATION -->
+<p><small>which tells the code generator that condition
+codes were unaffected in this rule. If no setcc or samecc
+has been given the default is</small></p>
+<!-- INDENTATION -->
+<pre><small>     nocc
+</small></pre>
+<!-- INDENTATION -->
+<p><small>when a piece of code contained strings, which
+tells the code generator that the condition codes have no
+useful value any more.</small></p></td>
+</table>
+<a name="3.6.4. Stack replacement"></a>
+<h2>3.6.4. Stack replacement</h2>
+
+<p><small>The stack replacement is a possibly empty list of
+items to be pushed onto the fakestack. Three kinds of items
+are possible:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>An item of the form %[1]. This will push the
+stacktoken mentioned back onto the stack
+unchanged.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>A register expression. This will push the
+register mentioned onto the fakestack.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>An item of the form { REGOFF2,%[1.reg],$1 }. This
+generates a token with tokenidentifier REGOFF2 and
+attributes in order of declaration.</small></p>
+</td>
+</table>
+
+<p><small>All tokens matched by the stack pattern at the
+beginning of the code rule are first removed and their
+registers deallocated. Items are pushed in the order of
+appearance. This means that the last item will be on the top
+of the stack after the push. So if the stack pattern
+contained two token expressions and they must be pushed back
+unchanged, they have to be specified as stack
+replacement</small></p>
+<pre><small>     %[2] %[1]
+</small></pre>
+
+<p><small>and not the other way around.</small></p>
+<a name="3.6.5. EM replacement"></a>
+<h2>3.6.5. EM replacement</h2>
+
+<p><small>In exceptional cases it might be useful to leave
+part of an empattern undone. For example, a <b>sdl</b>
+instruction might be split into two <b>stl</b> instructions
+when there is no 4-byte quantity on the stack. The
+emreplacement part allows one to express this.
+Example:</small></p>
+<pre><small><b>     stl</b> $1 <b>stl</b> $1+2
+</small></pre>
+
+<p><small>The instructions are inserted in the stream so
+that they can match the first part of a pattern in the next
+step. Note that since the code generator traverses the EM
+instructions in a strict linear fashion, it is impossible to
+let the EM replacement match later parts of a pattern. So if
+there is a pattern</small></p>
+<pre><small><b>     loc stl</b> $1==0
+</small></pre>
+
+<p><small>and the input is</small></p>
+<pre><small><b>     loc</b> 0 <b>sdl</b> 4
+</small></pre>
+
+<p><small>the <b>loc</b> 0 will be processed first, then
+the <b>sdl</b> might be split into two <b>stl</b>&rsquo;s
+but the pattern cannot match now.</small></p>
+<a name="3.6.6. Cost"></a>
+<h2>3.6.6. Cost</h2>
+
+<p><small>The cost field can be specified when there is
+more than one code rule with the same empattern. If the code
+generator has a choice between two possibilities to generate
+code it will choose the cheapest according to the cost
+field. The cost for a code generation is the sum of the
+costs of all the coercions needed, plus the cost for freeing
+registers plus the cost of the code rule itself.</small></p>
+
+<p><small>The format of the costfield is</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="6" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>( nbytes, time )</small></p>
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="30%"></td>
+<td width="10%">
+
+<p><small>or</small></p>
+</td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+</table>
+
+<p><small>( nbytes, time ) + %[<i>i</i>]</small></p>
+
+<p><small>with time in the metric desired, like nanoseconds
+or states. See constants section above. The %[<i>i</i>] in
+the second example is used for adding the cost of a certain
+address mode used in the code generated. This can of course
+be repeated if desired. The cost of the address mode must
+then be specified in the token definition
+section.</small></p>
+<a name="3.6.7. Examples"></a>
+<h2>3.6.7. Examples</h2>
+
+<p><small>A list of examples for the PDP-11 is given here.
+Far from being complete it gives examples of most kinds of
+instructions.</small></p>
+<pre><small><b>adi</b> $1==2 | SREG,SOURCE2 |
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>&quot;add %[2],%[1]&quot; erase(%[1])
+setcc(%[1])</small></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>| %[1] | | (2,450) + %[2]</small></p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p><small>... | SOURCE2,SREG |</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;add %[1],%[2]&quot; erase(%[2])
+setcc(%[2])</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>| %[2] | | (2,450) + %[1]</small></p>
+</td>
+</table>
+
+<p><small>is an example of the use of the &lsquo;...&rsquo;
+construct and shows how to place erase() and setcc()
+calls.</small></p>
+<pre><small><b>dvi</b> $1==2 | SOURCE2,SPAIRSIGNED |
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>&quot;div %[1],%[2]&quot; erase(%[2])</small></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>| %[2.regeven] | |</small></p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p><small><b>cmi tgt</b> $1==2 | SOURCE2,SOURCE2 |
+allocate(REG={CONST,0})</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;cmp %[2],%[1];ble 1f;inc %[a];1:&quot;
+erase(%[a])</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>| %[a] | |</small></p>
+</td>
+</table>
+
+<p><small><b>cal</b> | STACK |</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;jsr pc,$1&quot;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>| | |</small></p>
+</td>
+</table>
+
+<p><small><b>lol</b> | | | { REGOFF2, LB, $1 } |
+|</small></p>
+
+<p><small><b>stl</b> | SOURCE2 |</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>remove(REGOFF2,%[off]==$1)</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>move(%[1],{REGOFF2,LB,$1})</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>| | |</small></p>
+</td>
+</table>
+
+<p><small>| SOURCE2 |</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>allocate(%[1],REGPAIR)</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>move(%[1],%[a.2])</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>test(%[a.2])</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;sxt %[a.even]&quot; | { PAIRSIGNED, %[a.1],
+%[a.2] }| |</small></p>
+</td>
+</table>
+
+<p><small>This coercion shows how to use the move and test
+calls. At first one might think that the testcall is
+unnecessary, since the move will have set the condition
+codes, but the move may never have been executed if the
+register already contained the value, in which case it is
+necessary to do the test. If the move was executed the test
+will be omitted.</small></p>
+<pre><small>| SOURCE2 | allocate(%[1],REG=%[1]) | %[a] | |
+
+
+<b>sdl</b> | SOURCE2 | | %[1] | <b>stl</b> $1 <b>stl</b> $1+2 |
+
+
+<b>exg</b> $1==2 | SOURCE2 SOURCE2 | | %[1] %[2] | |
+</small></pre>
+
+<p><small>This last example again shows the difference in
+the order of the stack pattern and the stack
+replacement.</small></p>
+<a name="3.7. Move code rules"></a>
+<h2>3.7. Move code rules</h2>
+
+<p><small>When issuing a move() call as described above or
+a register allocation with initialization, the code
+generator has to know which instruction to use for the move.
+The code will of course only be generated if it cannot be
+omitted. This is listed in the move section of the tables by
+giving a list of tuples:</small></p>
+<pre><small>     ( source, destination, codepart [ , costfield ] )
+</small></pre>
+
+<p><small>where the square brackets mean the costfield is
+optional. Example for the PDP-11</small></p>
+<pre><small>     MOVES:
+     ( CONST %[off]==0 , SOURCE2, &quot;clr %[2]&quot; )
+     ( SOURCE2, SOURCE2, &quot;mov %[1],%[2]&quot; )
+</small></pre>
+
+<p><small>The moves are scanned from top to bottom, so the
+first one that matches will be chosen.</small></p>
+<a name="3.8. Test code rules"></a>
+<h2>3.8. Test code rules</h2>
+
+<p><small>When issuing a test() call as described above,
+the code generator has to know which instruction to use for
+the test. The code will only be generated if the condition
+codes were not already set to the token. This is listed in
+the test section of the tables by giving a list of
+tuples:</small></p>
+<pre><small>     ( source, codepart [ , costfield ] )
+</small></pre>
+
+<p><small>Example for the PDP-11</small></p>
+<pre><small>     TESTS:
+     ( SOURCE2, &quot;tst %[1]&quot;)
+     ( DREG, &quot;tstf %[1]\ncfcc&quot;)
+</small></pre>
+
+<p><small>The tests are scanned from top to bottom, so the
+first one that matches will be chosen.</small></p>
+<a name="3.9. Stacking code rules."></a>
+<h2>3.9. Stacking code rules.</h2>
+
+<p><small>When the code generator has to stack a token it
+must know which code to use. Since it must at all times be
+possible to empty the fakestack even when no registers are
+free, it is mandatory that all tokens used must have a rule
+attached for stacking them without using a scratch register.
+Since however this might be clumsy and a register might in
+practice be available it is also possible to give rules
+which use a register. On the Intel 8086 for example, there
+is no instruction to push a constant without using a
+register, and the code needed to do it without, must use
+global data and as such is very complicated and wasteful of
+memory and time. It can therefore be left to be used in
+extreme cases, while in general the constant is pushed
+through a register. The stacking rules are listed in the
+stack section of the table as a list of tuples:</small></p>
+<pre><small>     (source, [ register property ] , codepart [ , costfield ] )
+</small></pre>
+
+<p><small>Example for the Intel 8086:</small></p>
+<pre><small>     STACKS:
+     (CONST, REG, move(%[1],%[a]) &quot;push %[a]&quot;)
+     (REG ,, &quot;push %[1]&quot;)
+</small></pre>
+<a name="4. The files mach.h and mach.c"></a>
+<h2>4. The files mach.h and mach.c</h2>
+
+<p><small>The table writer must also supply two files
+containing machine dependent declarations and C code. These
+files are mach.h and mach.c.</small></p>
+<a name="4.1. Types in the code generator"></a>
+<h2>4.1. Types in the code generator</h2>
+
+<p><small>Three different types of integer coexist in the
+code generator and their range depends on the machine at
+hand. The type &rsquo;int&rsquo; is used for things like
+labelcounters that won&rsquo;t require more than 16 bits
+precision. The type &rsquo;word&rsquo; is used among others
+to assemble datawords and is of type &rsquo;long&rsquo;. The
+type &rsquo;full&rsquo; is used for addresses and is of type
+&rsquo;long&rsquo; if EM_WSIZE&gt;2 or
+EM_PSIZE&gt;2.</small></p>
+
+<p><small>In macro and function definitions in later
+paragraphs implicit typing will be used for parameters, that
+is parameters starting with an &rsquo;s&rsquo; will be of
+type string, and the letters
+&rsquo;i&rsquo;,&rsquo;w&rsquo;,&rsquo;f&rsquo; will stand
+for int, word and full respectively.</small></p>
+<a name="4.2. Global variables to work with"></a>
+<h2>4.2. Global variables to work with</h2>
+
+<p><small>Some global variables are present in the code
+generator that can be manipulated by the routines in mach.h
+and mach.c.</small></p>
+
+<p><small>The declarations are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>FILE *codefile;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* code is emitted on this stream */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>word part_word;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* words to be output are put together here
+*/</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>int part_size;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* number of bytes already put in part_word
+*/</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>char str[];</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* Last string read in */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>long argval;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* Last int read and kept */</small></p>
+</td>
+</table>
+<a name="4.3. Macros in mach.h"></a>
+<h2>4.3. Macros in mach.h</h2>
+
+<p><small>In the file mach.h a collection of macros is
+defined that have to do with formatting of assembly code for
+the machine at hand. Some of these macros can of course be
+left undefined in which case the macro calls are left in the
+source and will be treated as function calls. These
+functions can then be defined in <i>mach.c</i>.</small></p>
+
+<p><small>The macros to be defined are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>ex_ap(s)</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Must print the magic incantations that will mark
+the symbol to be exported to other modules. This is the
+translation of the EM <b>exa</b> and <b>exp</b>
+instructions.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>in_ap(s)</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Same to import the symbol. Translation of
+<b>ina</b> and <b>inp</b>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>newplb(s)</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>Must print the definition of procedure label
+<i>s</i>. If left undefined the newilb() macro is used
+instead.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>newilb(s)</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>Must print the definition of instruction label
+<i>s</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>newdlb(s)</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>Must print the definition of data label
+<i>s</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p><small>dlbdlb(s1,s2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="68%">
+
+<p><small>Must define data label <i>s1</i> to be equal to
+<i>s2</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p><small>newlbss(s,f)</small></p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p><small>Must declare a piece of memory initialized to
+BSS_INIT(see below) of length <i>f</i> and with label
+<i>s</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>cst_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used when converting constant
+arguments of EM instructions to string. Argument to be
+formatted will be &rsquo;full&rsquo;.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>off_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for integer part of
+label+constant, argument will be
+&rsquo;full&rsquo;.</small></p>
+</td>
+</table>
+
+<p><small>fmt_ilb(ip,il,s)</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="31%"></td>
+<td width="68%">
+<p><small>Must use the numbers <i>ip</i> and <i>il</i> which
+are a procedure number and a label number respectively and
+copy a string to <i>s</i> that must be unique for that
+combination. This procedure is optional, if it is not given
+ilb_fmt must be defined as below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>ilb_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for creation of unique
+instruction labels. Arguments will be a unique procedure
+number (int) and the label number (int).</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>dlb_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for printing numeric data
+labels. Argument will be &rsquo;int&rsquo;.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>hol_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for generation of labels for
+space generated by a <b>hol</b> pseudo. Argument will be
+&rsquo;int&rsquo;.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>hol_off</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for printing of the address of
+an element in <b>hol</b> space. Arguments will be the offset
+in the <b>hol</b> block (word) and the number of the
+<b>hol</b> (int).</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>con_cst(w)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Must generate output that will assemble into one
+machineword.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>con_ilb(s)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Must generate output that will put the address of
+the instruction label into the datastream.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>con_dlb(s)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Must generate output that will put the address of
+the data label into the datastream.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p><small>fmt_id(sf,st)</small></p>
+</td>
+<td width="6%"></td>
+<td width="68%">
+
+<p><small>Must take the string in <i>sf</i> which is a
+nonnumeric global label, and transform it into a copy made
+to <i>st</i> which will not collide with reserved assembler
+words and system labels. This procedure is optional, if it
+is not given the id_first macro is used as defined
+below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>id_first</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Must be a character. This is prepended to all
+nonnumeric global labels if their length is shorter than the
+maximum allowed(currently 8) or if they already start with
+that character. This is to avoid conflicts of user labels
+with system labels.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>BSS_INIT</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Must be a constant. This is the value filled in
+all the words not initialized explicitly. This is loader and
+system dependent. If omitted no initialization is
+assumed.</small></p>
+</td>
+</table>
+<a name="4.3.1. Example mach.h for the PDP-11"></a>
+<h2>4.3.1. Example mach.h for the PDP-11</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define ex_ap(y)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+<p><small>fprintf(codefile,&quot;\t.globl
+%s\n&quot;,y)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define in_ap(y)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+<p><small>/* nothing */</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define newplb(x)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;%s:\n&quot;,x)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define newilb(x)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;%s:\n&quot;,x)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define newdlb(x)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;%s:\n&quot;,x)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define</small></p>
+</td>
+<td width="16%">
+
+<p><small>dlbdlb(x,y)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;%s=%s\n&quot;,x,y)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define newlbss(l,x)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;%s:.=.+%d.\n&quot;,l,x);</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define cst_fmt</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>&quot;$%d.&quot;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define off_fmt</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>&quot;%d.&quot;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define ilb_fmt</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>&quot;I%x_%x&quot;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define dlb_fmt</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>&quot;_%d&quot;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define</small></p>
+</td>
+<td width="16%">
+
+<p><small>hol_fmt</small></p>
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>&quot;hol%d&quot;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define hol_off</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>&quot;%ld.+hol%d&quot;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define con_cst(x)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;%ld.\n&quot;,x)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define con_ilb(x)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+<p><small>fprintf(codefile,&quot;%s\n&quot;,x)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define con_dlb(x)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+<p><small>fprintf(codefile,&quot;%s\n&quot;,x)</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define id_first</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+<p><small>&rsquo;_&rsquo;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>#define BSS_INIT</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%">
+
+<p><small>0</small></p>
+</td>
+<td width="35%">
+</td>
+</table>
+<a name="4.4. Functions in mach.c"></a>
+<h2>4.4. Functions in mach.c</h2>
+
+<p><small>In mach.c some functions must be supplied, mostly
+manipulating data resulting from pseudoinstructions. The
+specifications are given here, implicit typing of parameters
+as above.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="36%">
+
+<p><small>con_part(isz,word)</small></p>
+</td>
+<td width="4%"></td>
+<td width="60%">
+
+<p><small>This function must manipulate the globals
+part_word and part_size to append the isz bytes contained in
+word to the output stream. If part_word is full, i.e.
+part_size==EM_WSIZE the function part_flush() may be called
+to empty the buffer. This is the function that must go
+through the trouble of doing byte order in words
+correct.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%">
+
+<p><small>con_mult(w_size)</small></p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p><small>This function must take the string str[] and
+create an integer from the string of size w_size and
+generate code to assemble global data for that integer. Only
+the sizes for which arithmetic is implemented need be
+handled, so if 200-byte integer division is not implemented,
+200-byte integer global data do not have to be implemented.
+Here one must take care of word order in long
+integers.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>con_float()</small></p>
+</td>
+<td width="18%"></td>
+<td width="60%">
+
+<p><small>This function must generate code to assemble a
+floating point number of which the size is contained in
+argval and the ASCII representation in str[].</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="34%">
+
+<p><small>prolog(f_nlocals)</small></p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><small>This function is called at the start of every
+procedure. Function prolog code must be generated, and room
+made for local variables for a total of f_nlocals
+bytes.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p><small>mes(w_mesno)</small></p>
+</td>
+<td width="16%"></td>
+<td width="60%">
+
+<p><small>This function is called when a <b>mes</b> pseudo
+is seen that is not handled by the machine independent part.
+The example below probably shows all the table writer ever
+has to know about that.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>segname[]</small></p>
+</td>
+<td width="22%"></td>
+<td width="60%">
+
+<p><small>This is not a function, but an array of four
+strings. These strings are put out whenever the code
+generator switches segments. Segments are SEGTXT, SEGCON,
+SEGROM and SEGBSS in that order.</small></p>
+</td>
+</table>
+<a name="4.4.1. Example mach.c for the PDP-11"></a>
+<h2>4.4.1. Example mach.c for the PDP-11</h2>
+
+<p><small>As an example of the sort of code expected, the
+mach.c for the PDP-11 is presented here.</small></p>
+<pre><small>/*
+ * machine dependent back end routines for the PDP-11
+ */
+
+
+con_part(sz,w) register sz; word w; {
+
+
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+
+<p><small>while (part_size % sz)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>part_size++;</small></p>
+</td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+
+<p><small>if (part_size == EM_WSIZE)</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>part_flush();</small></p>
+</td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+
+<p><small>if (sz == 1) {</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>w &amp;= 0xFF;</small></p>
+</td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>if (part_size)</small></p>
+</td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>w &lt;&lt;= 8;</small></p>
+</td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>part_word |= w;</small></p>
+</td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+
+<p><small>} else {</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>assert(sz == 2);</small></p>
+</td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>part_word = w;</small></p>
+</td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+
+<p><small>}</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="16%">
+
+<p><small>part_size += sz;</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="35%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>con_mult(sz) word sz; {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>long l;</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>if (sz != 4)</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>fatal(&quot;bad icon/ucon
+size&quot;);</small></p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>l = atol(str);</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;\t%o;%o\n&quot;,(int)(l&gt;&gt;16),(int)l);</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>con_float() {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>double f;</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>register short *p,i;</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>/*</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>* This code is correct only when the code
+generator is</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>* run on a PDP-11 or VAX-11 since it assumes
+native</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>* floating point format is PDP-11
+format.</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>*/</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>if (argval != 4 &amp;&amp; argval !=
+8)</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>fatal(&quot;bad fcon size&quot;);</small></p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>f = atof(str);</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>p = (short *) &amp;f;</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>i = *p++;</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>if (argval == 8) {</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;\t%o;%o;&quot;,i,*p++);</small></p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>i = *p++;</small></p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>}</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+
+<p><small>fprintf(codefile,&quot;\t%o;%o\n&quot;,i,*p++);</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>prolog(nlocals) full nlocals; {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>fprintf(codefile,&quot;mov r5,-(sp)\nmov
+sp,r5\n&quot;);</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>if (nlocals == 0)</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>return;</small></p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>if (nlocals == 2)</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>fprintf(codefile,&quot;tst
+-(sp)\n&quot;);</small></p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>else</small></p>
+</td>
+<td width="16%"></td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>fprintf(codefile,&quot;sub
+$%d.,sp\n&quot;,nlocals);</small></p>
+</td>
+<td width="51%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>mes(type) word type; {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>int argt ;</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>switch ( (int)type ) {</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>case ms_ext :</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>for (;;) {</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>switch ( argt=getarg(</small></p>
+</td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) )
+{</small></p>
+</td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>case sp_cend :</small></p>
+</td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>return ;</small></p>
+</td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>default:</small></p>
+</td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>strarg(argt) ;</small></p>
+</td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>fprintf(codefile,&quot;.globl %s\n&quot;,argstr)
+;</small></p>
+</td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>break ;</small></p>
+</td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>}</small></p>
+</td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>}</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>default :</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>while ( getarg(any_ptyp) != sp_cend )
+;</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+</td>
+<td width="16%">
+
+<p><small>break ;</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="0%"></td>
+<td width="16%">
+
+<p><small>}</small></p>
+</td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="16%"></td>
+<td width="19%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>char *segname[] = {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+
+<p><small>&quot;.text&quot;, /* SEGTXT */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+
+<p><small>&quot;.data&quot;, /* SEGCON */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+
+<p><small>&quot;.data&quot;, /* SEGROM */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+
+<p><small>&quot;.bss&quot; /* SEGBSS */</small></p>
+</td>
+</table>
+
+<p><small>};</small></p>
+<a name="5. Coercions"></a>
+<h2>5. Coercions</h2>
+
+<p><small>A central part in code generation is taken by the
+<i>coercions</i>. It is the responsibility of the table
+writer to provide all necessary coercions so that code
+generation can continue. The very minimal set of coercions
+are the coercions to unstack every token expression, in
+combination with the rules to stack every token.</small></p>
+
+<p><small>If these are present the code generator can
+always make the necessary transformations by stacking and
+unstacking. Of course for codequality it is usually best to
+provide extra coercions to prevent this stacking to take
+place. <i>Cg</i> discriminates three types of
+coercions:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Unstacking coercions. This category can use the
+allocate() call in its code.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Splitting coercions, these are the coercions that
+split larger tokens into smaller ones.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Transforming coercions, these are the coercions
+that transform a token into another one of the same size.
+This category can use the allocate() call in its
+code.</small></p>
+</td>
+</table>
+
+<p><small>When a stack configuration does not match the
+stack pattern <i>coercions</i> are searched for in the
+following order:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>First tokens are split if necessary to get their
+sizes right.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Then transforming coercions are found that will
+make the pattern match.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Finally if the stack pattern is longer than the
+fakestack contents unstacking coercions will be used to fill
+up the pattern.</small></p>
+</td>
+</table>
+
+<p><small>At any point, when coercions are missing so code
+generation could not continue, the offending tokens are
+stacked.</small></p>
+<a name="6. Internal workings of the code generator."></a>
+<h2>6. Internal workings of the code generator.</h2>
+<a name="6.1. Description of tables.c and tables.h contents"></a>
+<h2>6.1. Description of tables.c and tables.h contents</h2>
+
+<p><small>In this section the intermediate files will be
+described that are produced by <i>cgg</i> and compiled with
+machine independent code to produce a code
+generator.</small></p>
+<a name="6.1.1. Tables.c"></a>
+<h2>6.1.1. Tables.c</h2>
+
+<p><small>Tables.c contains a large number of initialized
+array&rsquo;s of all sorts. Description of each
+follows:</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>byte code rules[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Pseudo code interpreted by the code generator.
+Always starts with some opcode followed by operands
+depending on the opcode. Integers in this table are between
+0 and 32767 and have a one byte encoding if between 0 and
+127.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>char stregclass[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Number of computed static register class per
+register. Two registers are in the same class if they have
+the same properties and don&rsquo;t share a common
+subregister.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>struct reginfo machregs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Info per register. Initialized with representation
+string, size, members of the register and set of registers
+affected when this one is changed. Also contains room for
+runtime information, like contents and reference
+count.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>tkdef_t tokens[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Information per tokentype. Initialized with size,
+cost, type of operands and formatstring.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>node_t enodes[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of triples representing expressions for the
+code generator.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>string code strings[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of strings. All strings are put in a list and
+checked for duplication, so only one copy per string will
+reside here.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>set_t machsets[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of token expression sets. Bit 0 of the set is
+used for the SCRATCH property of registers, bit 1 upto NREG
+are for the corresponding registers and bit NREG+1 upto the
+end are for corresponding tokens.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>inst_t tokeninstances[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of descriptions for building tokens. Contains
+type of rule for building one, plus operands depending on
+the type.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>move_t moves[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of move rules. Contains token expressions for
+source and destination plus cost and index for code
+rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>byte pattern[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>EM patterns. This is structured internally as
+chains of patterns, each chain pointed at by pathash[].
+After each pattern the list of possible code rules is
+given.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>int pathash[256]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Indices into pattern[] for all patterns with a
+certain low order byte of the hashing
+function.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>c1_t c1coercs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of rules to stack tokens. Contains token
+expressions, register needed, cost and code
+rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>c2_t c2coercs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of splitting coercions. Token expressions,
+split factor, replacements and code rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>c3_t c3coercs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of one to one coercions. Token expressions,
+register needed, replacement and code rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>struct reginfo **reglist[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of lists of pointers to register information.
+For every property the list is here to find the registers
+corresponding to it.</small></p></td>
+</table>
+<a name="6.1.2. tables.h"></a>
+<h2>6.1.2. tables.h</h2>
+
+<p><small>In tables.h various derived constants for the
+tables are given. They are then used to determine array
+sizes in the actual code generator, plus loop termination in
+some cases.</small></p>
+<a name="6.2. Other important data structures"></a>
+<h2>6.2. Other important data structures</h2>
+
+<p><small>During code generation some other data structures
+are used and here is a short description of some of the
+important ones.</small></p>
+
+<p><small>Tokens are kept in the code generator as a struct
+consisting of one integer <i>t_token</i> which is -1 if the
+token is a register, and the number of the token otherwise,
+plus an array of <i>TOKENSIZE</i> unions <i>t_att</i> of
+which the first is the register number in case of a
+register.</small></p>
+
+<p><small>The fakestack is an array of these tokens, there
+is a global variable <i>stackheight</i>.</small></p>
+
+<p><small>The results of expressions are kept in a struct
+<i>result</i> with elements <i>e_typ</i>, giving the type of
+the expression: <i>EV_INT</i>, <i>EV_REG</i> or
+<i>EV_STR</i>, and a union <i>e_v</i> which contains the
+real result.</small></p>
+<a name="6.3. A tour through the sources"></a>
+<h2>6.3. A tour through the sources</h2>
+<a name="6.3.1. codegen.c"></a>
+<h2>6.3.1. codegen.c</h2>
+
+<p><small>The file codegen.c contains one large function
+consisting of one giant switch statement. It is the
+interpreter for the code generator pseudo code as contained
+in code rules[]. This function can call itself recursively
+when doing lookahead. Arguments are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>codep</small></p>
+</td>
+<td width="10%"></td>
+<td width="80%">
+
+<p><small>Pointer into code rules, pseudo program
+counter.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>ply</small></p>
+</td>
+<td width="14%"></td>
+<td width="78%">
+
+<p><small>Number of EM pattern lookahead
+allowed.</small></p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>toplevel</small></p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p><small>Boolean telling whether this is the toplevel
+codegen() or a deeper incarnation.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>costlimit</small></p>
+</td>
+<td width="2%"></td>
+<td width="80%">
+
+<p><small>A cutoff value to limit searches. If the cost
+crosses costlimit the incarnation can terminate.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>forced</small></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><small>A register number if nonzero. This is used inside
+coercions to force the allocate() call to allocate a
+register determined by earlier lookahead.</small></p>
+</td>
+</table>
+
+<p><small>The instructions inplemented in the
+switch:</small></p>
+<a name="6.3.1.1. DO_NEXTEM"></a>
+<h2>6.3.1.1. DO_NEXTEM</h2>
+
+<p><small>Matches the next EM pattern and does lookahead if
+necessary to find the best code rule associated with this
+pattern. Heuristics are used to determine best code rule
+when possible. This is done by calling the distance()
+function.</small></p>
+<a name="6.3.1.2. DO_COERC"></a>
+<h2>6.3.1.2. DO_COERC</h2>
+
+<p><small>This sets the code generator in the state to do a
+from stack coercion.</small></p>
+<a name="6.3.1.3. DO_XMATCH"></a>
+<h2>6.3.1.3. DO_XMATCH</h2>
+
+<p><small>This is done when a match no longer has to be
+checked. Used when the nocoercions: trick is used in the
+table.</small></p>
+<a name="6.3.1.4. DO_MATCH"></a>
+<h2>6.3.1.4. DO_MATCH</h2>
+
+<p><small>This is the big one inside this function. It has
+the task to transform the contents of the current fakestack
+to match the pattern given after it.</small></p>
+
+<p><small>Since the code generator does not know combining
+coercions, i.e. there is no way to make a big token out of
+two smaller ones, the first thing done is to stack every
+token that is too small. After that all tokens too big are
+split if possible to the right size.</small></p>
+
+<p><small>Next the coercions are sought that would
+transform tokens in place to the right one, plus the
+coercions that would pop tokens of the stack. Each of those
+might need a register, so a list of registers is generated
+and at the end of looking for coercions the function
+<i>tuples()</i> is called to generate the list of all
+possible <i>n</i>-tuples, where <i>n</i> equals the number
+of registers needed.</small></p>
+
+<p><small>Lookahead is now performed if the number of
+tuples is greater than one. If no possibility is found
+within the costlimit, the fakestack is made smaller by
+pushing the bottom token, and this process is repeated until
+either a way is found or the fakestack is completely empty
+and there is still no way to make the match.</small></p>
+
+<p><small>If there is a way the corresponding coercions are
+executed and the code is finished.</small></p>
+<a name="6.3.1.5. DO_REMOVE"></a>
+<h2>6.3.1.5. DO_REMOVE</h2>
+
+<p><small>Here the remove() call is executed, all tokens
+matched by the token expression plus boolean expression are
+pushed. In the current implementation there is no attempt to
+move those tokens to registers, but that is a possible
+future extension.</small></p>
+<a name="6.3.1.6. DO_DEALLOCATE"></a>
+<h2>6.3.1.6. DO_DEALLOCATE</h2>
+
+<p><small>This one temporarily decrements by one the
+reference count of all registers contained in the token
+given as argument.</small></p>
+<a name="6.3.1.7. DO_REALLOCATE"></a>
+<h2>6.3.1.7. DO_REALLOCATE</h2>
+
+<p><small>Here all temporary deallocates are made
+undone.</small></p>
+<a name="6.3.1.8. DO_ALLOCATE"></a>
+<h2>6.3.1.8. DO_ALLOCATE</h2>
+
+<p><small>This is the part that allocates a register and
+decides which one to use. If the <i>forced</i> argument was
+given its task is simple, otherwise some work must be done.
+First the list of possible registers is scanned, all free
+registers noted and it is noted whether any of those
+registers is already containing the initialization. If no
+registers are available some fakestack token is stacked and
+the process is repeated.</small></p>
+
+<p><small>After that if an exact match was found, the list
+of registers is reduced to one register matching exactly out
+of every register class. Now lookahead is performed if
+necessary and the register chosen. If an initialization was
+given the corresponding move is performed, otherwise the
+register is marked empty.</small></p>
+<a name="6.3.1.9. DO_LOUTPUT"></a>
+<h2>6.3.1.9. DO_LOUTPUT</h2>
+
+<p><small>This prints a string and an expression. Only done
+on toplevel.</small></p>
+<a name="6.3.1.10. DO_ROUTPUT"></a>
+<h2>6.3.1.10. DO_ROUTPUT</h2>
+
+<p><small>Prints a string and a new line. Only on
+toplevel.</small></p>
+<a name="6.3.1.11. DO_MOVE"></a>
+<h2>6.3.1.11. DO_MOVE</h2>
+
+<p><small>Calls the move() function in the code generator
+to implement the move() function in the table.</small></p>
+<a name="6.3.1.12. DO_ERASE"></a>
+<h2>6.3.1.12. DO_ERASE</h2>
+
+<p><small>Marks the register that is its argument as
+empty.</small></p>
+<a name="6.3.1.13. DO_TOKREPLACE"></a>
+<h2>6.3.1.13. DO_TOKREPLACE</h2>
+
+<p><small>This is the token replacement part. It is also
+called if there is no token replacement because it has some
+other functions as well.</small></p>
+
+<p><small>First the tokens that will be pushed on the
+fakestack are computed and stored in a temporary array. Then
+the tokens that were matched in this rule are popped and
+their embedded registers have their reference count
+decremented. After that the replacement tokens are
+pushed.</small></p>
+
+<p><small>Finally all registers allocated in this rule have
+their reference count decremented. If they were not pushed
+on the fakestack they will be available again in the next
+code rule.</small></p>
+<a name="6.3.1.14. DO_EMREPLACE"></a>
+<h2>6.3.1.14. DO_EMREPLACE</h2>
+
+<p><small>Places replacement EM instructions back into the
+instruction stream.</small></p>
+<a name="6.3.1.15. DO_COST"></a>
+<h2>6.3.1.15. DO_COST</h2>
+
+<p><small>Accounts for cost as given in the code
+rule.</small></p>
+<a name="6.3.1.16. DO_RETURN"></a>
+<h2>6.3.1.16. DO_RETURN</h2>
+
+<p><small>Returns from this level of codegen(). Is used at
+the end of coercions, move rules etc..</small></p>
+<a name="6.3.2. compute.c"></a>
+<h2>6.3.2. compute.c</h2>
+
+<p><small>This module computes the various expressions as
+given in the enodes[] array. Nothing very special happens
+here, it is just a recursive function computing leaves of
+expressions and applying the operator.</small></p>
+<a name="6.3.3. equiv.c"></a>
+<h2>6.3.3. equiv.c</h2>
+
+<p><small>In this module the tuples() function is
+implemented. It is given the number of registers needed and
+a list of register lists and it constructs a list of tuples
+where the <i>n</i>&rsquo;th register comes from the
+<i>n</i>&rsquo;th list. Before the list is constructed
+however the dynamic register classes are computed. Two
+registers are in the same dynamic class if they are in the
+same static class and their contents is the
+same.</small></p>
+
+<p><small>After that the permute() recursive function is
+called to generate the list of tuples. After construction a
+generated tuple is added to the list if it is not already
+pairwise in the same class or if the register relations are
+not the same, i.e. if the first and second register share a
+common subregister in one tuple and not in the other they
+are considered different.</small></p>
+<a name="6.3.4. fillem.c"></a>
+<h2>6.3.4. fillem.c</h2>
+
+<p><small>This is the routine that does the reading of EM
+instructions and the handling of pseudos. The mach.c module
+provided by the table writer is included at the end of this
+module. The routine fillemlines() is called by nextem() at
+toplevel to make sure there are enough instruction to match.
+It fills the EM instruction buffer up to 5 places from the
+end to keep room for EM replacement instructions, or up to a
+pseudo.</small></p>
+
+<p><small>The dopseudo() function performs the function of
+the pseudo last encountered. If the pseudo is a <b>rom</b>
+the corresponding label is saved with the contents of the
+<b>rom</b> to be available to the code generator later. The
+rest of the routines are small service routines for either
+input or data output.</small></p>
+<a name="6.3.5. gencode.c"></a>
+<h2>6.3.5. gencode.c</h2>
+
+<p><small>This module contains routines called by codegen()
+to generate the real code to the codefile. The function
+gencode() gets a string as argument and copies it to
+codefile while processing certain embedded control
+characters implementing the $2 and [1.reg] escapes. The
+function genexpr() prints the expression given as argument.
+It is used to implement the %( expr %) escape. The prtoken()
+function interprets the tokenformat as given in the tokens[]
+array.</small></p>
+<a name="6.3.6. glosym.c"></a>
+<h2>6.3.6. glosym.c</h2>
+
+<p><small>This module maintains a list of global symbols
+that have a <b>rom</b> pseudo associated. There are
+functions to enter a symbol and to find a
+symbol.</small></p>
+<a name="6.3.7. main.c"></a>
+<h2>6.3.7. main.c</h2>
+
+<p><small>Main routine of the code generator. Processes
+arguments and flags. Flags available are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>-d</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Sets debug mode if the code generator was not
+compiled with the NDEBUG macro defined. Debug mode gives
+very long output on stderr indicating all steps of the code
+generation process including nesting of the codegen()
+function.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>-p<i>n</i></small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Sets the lookahead depth to <i>n</i>, the
+<i>p</i> stands for ply, a well known word in chess playing
+programs.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>-w<i>n</i></small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Sets the weight percentage for size in the cost
+function to <i>n</i> percent. Uses Euclides algorithm to
+simplify rationals.</small></p>
+</td>
+</table>
+<a name="6.3.8. move.c"></a>
+<h2>6.3.8. move.c</h2>
+
+<p><small>Function to implement the move() pseudo function
+in the tables, register initialization and the setcc and
+test pseudo functions. First tests are made to try to
+prevent the move from really happening. The condition code
+register is treated special here. After that, if there is an
+after that, the move rule is found and the code
+executed.</small></p>
+<a name="6.3.9. nextem.c"></a>
+<h2>6.3.9. nextem.c</h2>
+
+<p><small>The entry point of this module is nextem(). It
+hashes the next three EM instructions, and uses the low
+order byte of the hash as an index into the array pathash[],
+to find a chain of patterns in the array pattern[], that are
+all tried for a match.</small></p>
+
+<p><small>The function trypat() does most of the work
+checking patterns. When a pattern is found to match all
+instructions the operands of the instruction are placed into
+the dollar[] array. Then the boolean expression is tried. If
+it matches the function can return, leaving the operands
+still in the dollar[] array, so later in the code rule they
+can still be used.</small></p>
+<a name="6.3.10. reg.c"></a>
+<h2>6.3.10. reg.c</h2>
+
+<p><small>Collection of routines to handle registers.
+Reference count routines are here, chrefcount() and
+getrefcount(), plus routines to erase a single register or
+all of them, erasereg() and cleanregs().</small></p>
+
+<p><small>If NDEBUG hasn&rsquo;t been defined, here is also
+the routine that checks if the reference count kept with the
+register information is in agreement with the number of
+times it occurs on the fakestack.</small></p>
+<a name="6.3.11. salloc.c"></a>
+<h2>6.3.11. salloc.c</h2>
+
+<p><small>Module for string allocation and garbage
+collection. Contains entry points myalloc(), a routine
+calling malloc() and checking whether room is left,
+myfree(), just free(), popstr() a function called from
+state.c to free all strings made since the last saved
+status. Furthermore there is salloc() which has the size of
+the string as parameter and returns a pointer to the
+allocated space, while keeping a copy of the pointer for
+garbage allocation purposes.</small></p>
+
+<p><small>The function garbage_collect is called from
+codegen() at toplevel every now and then, and checks all
+places where strings may reside to mark strings as being in
+use. Strings not in use are returned to the pool of free
+space.</small></p>
+<a name="6.3.12. state.c"></a>
+<h2>6.3.12. state.c</h2>
+
+<p><small>Set of routines called to save current status,
+restore a previous saved state and to free the room occupied
+by a saved state. A list of structs is kept here to save the
+state. If this is not done, small allocates will take space
+from the holes big enough for state saves, and as a result
+every new state save will need a new struct. The code
+generator runs out of room very rapidly under these
+conditions.</small></p>
+<a name="6.3.13. subr.c"></a>
+<h2>6.3.13. subr.c</h2>
+
+<p><small>Random set of leftover routines.</small></p>
+<a name="6.3.13.1. match"></a>
+<h2>6.3.13.1. match</h2>
+
+<p><small>Computes whether a certain token matches a
+certain token expression. Just computes a bitnumber
+according to the algorithm explained with machsets[], and
+tests the bit and the boolean expression if it is
+there.</small></p>
+<a name="6.3.13.2. instance,cinstance"></a>
+<h2>6.3.13.2. instance,cinstance</h2>
+
+<p><small>These two functions compute a token from a
+description. They differ very slight, cinstance() is used to
+compute the result of a coercion in a certain context and
+therefore has more arguments, which it uses instead of the
+global information instance() works on.</small></p>
+<a name="6.3.13.3. eqtoken"></a>
+<h2>6.3.13.3. eqtoken</h2>
+
+<p><small>eqtoken computes whether two tokens can be
+considered identical. Used to check register contents during
+moves mainly.</small></p>
+<a name="6.3.13.4. distance"></a>
+<h2>6.3.13.4. distance</h2>
+
+<p><small>This is the heuristic function that computes a
+distance from the current fakestack contents to the token
+pattern in the table. It likes exact matches most, then
+matches where at least the sizes are correct and if the
+sizes are not correct it likes too large sizes more than too
+small, since splitting a token is easier than combining
+one.</small></p>
+<a name="6.3.13.5. split"></a>
+<h2>6.3.13.5. split</h2>
+
+<p><small>This function tries to find a splitting coercion
+and executes it immediately when found. The fakestack is
+shuffled thoroughly when this happens, so pieces below the
+token that must be split are saved first.</small></p>
+<a name="6.3.13.6. docoerc"></a>
+<h2>6.3.13.6. docoerc</h2>
+
+<p><small>This function executes a coercion that was found.
+The same shuffling is done, so the top of the stack is again
+saved.</small></p>
+<a name="6.3.13.7. stackupto"></a>
+<h2>6.3.13.7. stackupto</h2>
+
+<p><small>This function gets a pointer into the fakestack
+and must stack every token including the one pointed at up
+to the bottom of the fakestack. The first stacking rule
+possible is used, so rules using registers must come
+first.</small></p>
+<a name="6.3.13.8. findcoerc"></a>
+<h2>6.3.13.8. findcoerc</h2>
+
+<p><small>Looks for a one to one coercion, if found it
+returns a pointer to it and leaves a list of possible
+registers to use in the global variable curreglist. This is
+used by codegen().</small></p>
+<a name="6.3.14. var.c"></a>
+<h2>6.3.14. var.c</h2>
+
+<p><small>Global variables used by more than one module.
+External definitions are in extern.h.</small></p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/cg.pdf b/src/olddocs/cg.pdf
new file mode 100644 (file)
index 0000000..88610a1
Binary files /dev/null and b/src/olddocs/cg.pdf differ
diff --git a/src/olddocs/crefman.html b/src/olddocs/crefman.html
new file mode 100644 (file)
index 0000000..b7996e9
--- /dev/null
@@ -0,0 +1,1410 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:12 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>ACK/CEM Compiler</title>
+</head>
+<body>
+
+<h1 align=center>ACK/CEM Compiler</h1>
+<a href="#1. C Language">1. C Language</a><br>
+<a href="#2.2 Identifiers">2.2 Identifiers</a><br>
+<a href="#2.3 Keywords">2.3 Keywords</a><br>
+<a href="#asm">asm</a><br>
+<a href="#enum">enum</a><br>
+<a href="#entry , fortran">entry , fortran</a><br>
+<a href="#2.4.1 Integer Constants">2.4.1 Integer Constants</a><br>
+<a href="#2.4.3 Character Constants">2.4.3 Character Constants</a><br>
+<a href="#2.4.4 Floating Constants">2.4.4 Floating Constants</a><br>
+<a href="#2.6 Hardware characteristics">2.6 Hardware characteristics</a><br>
+<a href="#4 What&rsquo;s in a name?">4 What&rsquo;s in a name?</a><br>
+<a href="#char">char</a><br>
+<a href="#unsigned">unsigned</a><br>
+<a href="#enum">enum</a><br>
+<a href="#void">void</a><br>
+<a href="#Fundamental types">Fundamental types</a><br>
+<a href="#7 Expressions">7 Expressions</a><br>
+<a href="#7.2 Unary operators">7.2 Unary operators</a><br>
+<a href="#7.13 Conditional operator">7.13 Conditional operator</a><br>
+<a href="#7.14 Assignment operators">7.14 Assignment operators</a><br>
+<a href="#8.2 Type specifiers">8.2 Type specifiers</a><br>
+<a href="#8.5 Structure and union declarations">8.5 Structure and union declarations</a><br>
+<a href="#9.7 Switch statement">9.7 Switch statement</a><br>
+<a href="#10 External definitions">10 External definitions</a><br>
+<a href="#10.1 External function definitions">10.1 External function definitions</a><br>
+<a href="#11.1 Lexical scope">11.1 Lexical scope</a><br>
+<a href="#12 Compiler control lines">12 Compiler control lines</a><br>
+<a href="#12.1 Token replacement">12.1 Token replacement</a><br>
+<a href="#12.2 File inclusion">12.2 File inclusion</a><br>
+<a href="#12.3 Conditional compilation">12.3 Conditional compilation</a><br>
+<a href="#12.4 Line control">12.4 Line control</a><br>
+<a href="#14.2 Functions">14.2 Functions</a><br>
+<a href="#15 Constant expressions">15 Constant expressions</a><br>
+<a href="#2. Compiler flags">2. Compiler flags</a><br>
+<a href="#References">References</a><br>
+<a href="#Appendix A - Enumeration Type">Appendix A - Enumeration Type</a><br>
+<a href="#Appendix B: C grammar in LL(1) form">Appendix B: C grammar in LL(1) form</a><br>
+
+<hr>
+
+<p><b>Reference Manual</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p align=center><i><small>Erik H.
+Baalbergen</small></i><small><br>
+Department of Mathematics and Computer Science<br>
+Vrije Universiteit<br>
+Amsterdam<br>
+The Netherlands</small></p>
+</td>
+</table>
+<a name="1. C Language"></a>
+<h2>1. C Language</h2>
+
+<p><small>This section discusses the extensions to and
+deviations from the C language, as described in [1]. The
+issues are numbered according to the reference
+manual.</small></p>
+<a name="2.2 Identifiers"></a>
+<h2>2.2 Identifiers</h2>
+
+<p><small>Upper and lower case letters are different. The
+number of significant letters is 32 by default, but may be
+set to another value using the <b>&minus;M</b> option. The
+identifier length should be set according to the rest of the
+compilation programs.</small></p>
+<a name="2.3 Keywords"></a>
+<h2>2.3 Keywords</h2>
+<a name="asm"></a>
+<h2>asm</h2>
+
+<p><small>The keyword <tt>asm</tt> is recognized. However,
+the statement</small></p>
+<pre><small>     asm(string);
+</small></pre>
+
+<p><small>is skipped, while a warning is given.</small></p>
+<a name="enum"></a>
+<h2>enum</h2>
+
+<p><small>The <tt>enum</tt> keyword is recognized and
+interpreted.</small></p>
+<a name="entry , fortran"></a>
+<h2>entry , fortran</h2>
+
+<p><small>The words <tt>entry</tt> and <tt>fortran</tt> are
+reserved under the restricted option. The words are not
+interpreted by the compiler.</small></p>
+<a name="2.4.1 Integer Constants"></a>
+<h2>2.4.1 Integer Constants</h2>
+
+<p><small>The type of an integer constant is the first of
+the corresponding list in which its value can be
+represented. Decimal: <tt>int, long, unsigned long</tt>;
+octal or hexadecimal: <tt>int, unsigned, long, unsigned
+long</tt>; suffixed by the letter L or l: <tt>long, unsigned
+long</tt>.</small></p>
+<a name="2.4.3 Character Constants"></a>
+<h2>2.4.3 Character Constants</h2>
+
+<p><small>A character constant is a sequence of 1 up to
+<tt>sizeof(int)</tt> characters enclosed in single quotes.
+The value of a character constant &rsquo;<i>c</i>
+<small><small>1</small></small> <i>c</i>
+<small><small>2</small></small> ...<i>c
+<small><small>n</small></small></i> &rsquo; is <i>d
+<small><small>n</small></small></i> +<i>M</i>&times;<i>d
+<small><small>n</small></small></i><small><small>&minus;1</small></small>
++...+<i>M
+<small><small>n</small></small></i><small><small>&minus;1</small></small>
+&times;<i>d</i> <small><small>2</small></small> +<i>M
+<small><small>n</small></small></i> &times;<i>d</i>
+<small><small>1</small></small> , where M is 1 + maximum
+unsigned number representable in an <tt>unsigned char</tt>,
+and <i>d <small><small>i</small></small></i> is the signed
+value (ASCII) of character <i>c
+<small><small>i</small></small></i> .</small></p>
+<a name="2.4.4 Floating Constants"></a>
+<h2>2.4.4 Floating Constants</h2>
+
+<p><small>The compiler does not support compile-time
+floating point arithmetic.</small></p>
+<a name="2.6 Hardware characteristics"></a>
+<h2>2.6 Hardware characteristics</h2>
+
+<p><small>The compiler is capable of producing EM code for
+machines with the following properties</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="32%">
+
+<p><small>a <tt>char</tt> is 8 bits</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="82%">
+
+<p><small>the size of <tt>int</tt> is equal to the word
+size</small></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>the size of <tt>short</tt> may not exceed the
+size of <tt>int</tt></small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>the size of <tt>int</tt> may not exceed the size
+of <tt>long</tt></small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>the size of pointers is equal to the size of
+either <tt>short</tt>, <tt>int</tt> or
+<tt>long</tt></small></p>
+</td>
+</table>
+<a name="4 What&rsquo;s in a name?"></a>
+<h2>4 What&rsquo;s in a name?</h2>
+<a name="char"></a>
+<h2>char</h2>
+
+<p><small>Objects of type <tt>char</tt> are taken to be
+signed. The combination <tt>unsigned char</tt> is
+legal.</small></p>
+<a name="unsigned"></a>
+<h2>unsigned</h2>
+
+<p><small>The type combinations <tt>unsigned char</tt>,
+<tt>unsigned short</tt> and <tt>unsigned long</tt> are
+supported.</small></p>
+<a name="enum"></a>
+<h2>enum</h2>
+
+<p><small>The data type <tt>enum</tt> is implemented as
+described in <i>Recent Changes to C</i> (see appendix A).
+<i>Cem</i> treats enumeration variables as if they were
+<tt>int</tt>.</small></p>
+<a name="void"></a>
+<h2>void</h2>
+
+<p><small>Type <tt>void</tt> is implemented. The type
+specifies an empty set of values, which takes no storage
+space.</small></p>
+<a name="Fundamental types"></a>
+<h2>Fundamental types</h2>
+
+<p><small>The names of the fundamental types can be
+redefined by the user, using <tt>typedef</tt>.</small></p>
+<a name="7 Expressions"></a>
+<h2>7 Expressions</h2>
+
+<p><small>The order of evaluation of expressions depends on
+the complexity of the subexpressions. In case of commutative
+operations, the most complex subexpression is evaluated
+first. Parameter lists are evaluated from right to
+left.</small></p>
+<a name="7.2 Unary operators"></a>
+<h2>7.2 Unary operators</h2>
+
+<p><small>The type of a <tt>sizeof</tt> expression is
+<tt>unsigned int</tt>.</small></p>
+<a name="7.13 Conditional operator"></a>
+<h2>7.13 Conditional operator</h2>
+
+<p><small>Both the second and the third expression in a
+conditional expression may include assignment operators.
+They may be structs or unions.</small></p>
+<a name="7.14 Assignment operators"></a>
+<h2>7.14 Assignment operators</h2>
+
+<p><small>Structures may be assigned, passed as arguments
+to functions, and returned by functions. The types of
+operands taking part must be the same.</small></p>
+<a name="8.2 Type specifiers"></a>
+<h2>8.2 Type specifiers</h2>
+
+<p><small>The combinations <tt>unsigned char</tt>,
+<tt>unsigned short</tt> and <tt>unsigned long</tt> are
+implemented.</small></p>
+<a name="8.5 Structure and union declarations"></a>
+<h2>8.5 Structure and union declarations</h2>
+
+<p><small>Fields of any integral type, either signed or
+unsigned, are supported, as long as the type fits in a word
+on the target machine.</small></p>
+
+<p><small>Fields are left adjusted by default; the first
+field is put into the left part of a word, the next one on
+the right side of the first one, etc. The <tt>-Vr</tt>
+option in the call of the compiler causes fields to be right
+adjusted within a machine word.</small></p>
+
+<p><small>The tags of structs and unions occupy a different
+name space from that of variables and that of member
+names.</small></p>
+<a name="9.7 Switch statement"></a>
+<h2>9.7 Switch statement</h2>
+
+<p><small>The type of <i>expression</i> in</small></p>
+<pre><small>     switch (<i>expression</i>) <i>statement
+</i></small></pre>
+
+<p><small>must be integral. A warning is given under the
+restricted option if the type is <tt>long</tt>.</small></p>
+<a name="10 External definitions"></a>
+<h2>10 External definitions</h2>
+
+<p><small>See [4] for a discussion on this complicated
+issue.</small></p>
+<a name="10.1 External function definitions"></a>
+<h2>10.1 External function definitions</h2>
+
+<p><small>Structures may be passed as arguments to
+functions, and returned by functions.</small></p>
+<a name="11.1 Lexical scope"></a>
+<h2>11.1 Lexical scope</h2>
+
+<p><small>Typedef names may be redeclared like any other
+variable name; the ice mentioned in &sect;11.1 is walked
+correctly.</small></p>
+<a name="12 Compiler control lines"></a>
+<h2>12 Compiler control lines</h2>
+
+<p><small>Lines which do not occur within comment, and with
+<tt>#</tt> as first character, are interpreted as compiler
+control line. There may be an arbitrary number of spaces,
+tabs and comments (collectively referred as <i>white
+space</i>) following the <tt>#</tt>. Comments may contain
+newline characters. Control lines with only white space
+between the <tt>#</tt> and the line separator are
+skipped.</small></p>
+
+<p><small>The #<tt>include</tt>, #<tt>ifdef</tt>,
+#<tt>ifndef</tt>, #<tt>undef</tt>, #<tt>else</tt> and
+#<tt>endif</tt> control lines and line directives consist of
+a fixed number of arguments. The list of arguments may be
+followed an arbitrary sequence of characters, in which
+comment is interpreted as such. (I.e., the text between
+<tt>/*</tt> and <tt>*/</tt> is skipped, regardless of
+newlines; note that commented-out lines beginning with
+<tt>#</tt> are not considered to be control
+lines.)</small></p>
+<a name="12.1 Token replacement"></a>
+<h2>12.1 Token replacement</h2>
+
+<p><small>The replacement text of macros is taken to be a
+string of characters, in which an identifier may stand for a
+formal parameter, and in which comment is interpreted as
+such. Comments and newline characters, preceeded by a
+backslash, in the replacement text are replaced by a space
+character.</small></p>
+
+<p><small>The actual parameters of a macro are considered
+tokens and are balanced with regard to <tt>()</tt>,
+<tt>{}</tt> and <tt>[]</tt>. This prevents the use of macros
+like</small></p>
+<pre><small>     CTL([)
+</small></pre>
+
+<p><small>Formal parameters of a macro must have unique
+names within the formal-parameter list of that
+macro.</small></p>
+
+<p><small>A message is given at the definition of a macro
+if the macro has already been #<tt>defined</tt>, while the
+number of formal parameters differ or the replacement texts
+are not equal (apart from leading and trailing white
+space).</small></p>
+
+<p><small>Recursive use of macros is detected by the
+compiler.</small></p>
+
+<p><small>Standard #<tt>defined</tt> macros are</small></p>
+<pre><small>     __FILE__  name of current input file as string constant
+     __DATE__  curent date as string constant; e.g. &quot;Tue Wed  2 14:45:23 1986&quot;
+     __LINE__  current line number as an integer
+</small></pre>
+
+<p><small>No message is given if <i>identifier</i> is not
+known in</small></p>
+<pre><small>     #undef <i>identifier
+</i></small></pre>
+<a name="12.2 File inclusion"></a>
+<h2>12.2 File inclusion</h2>
+
+<p><small>A newline character is appended to each file
+which is included.</small></p>
+<a name="12.3 Conditional compilation"></a>
+<h2>12.3 Conditional compilation</h2>
+
+<p><small>The #<tt>if</tt>, #<tt>ifdef</tt> and
+#<tt>ifndef</tt> control lines may be followed by an
+arbitrary number of</small></p>
+<pre><small>     #elif <i>constant-expression
+</i></small></pre>
+
+<p><small>control lines, before the corresponding
+#<tt>else</tt> or #<tt>endif</tt> is encountered. The
+construct</small></p>
+<pre><small>     #elif <i>constant-expression
+</i>     some text
+     #endif /* corresponding to #elif */
+</small></pre>
+
+<p><small>is equivalent to</small></p>
+<pre><small>     #else
+     #if <i>constant-expression
+</i>     some text
+     #endif /* corresponding to #if */
+     #endif /* corresponding to #else */
+</small></pre>
+
+<p><small>The <i>constant-expression</i> in #<tt>if</tt>
+and #<tt>elif</tt> control lines may contain the
+construction</small></p>
+<pre><small>     defined(<i>identifier</i>)
+</small></pre>
+
+<p><small>which is replaced by <tt>1</tt>, if
+<i>identifier</i> has been #<tt>defined</tt>, and by
+<tt>0</tt>, if not.</small></p>
+
+<p><small>Comments in skipped lines are interpreted as
+such.</small></p>
+<a name="12.4 Line control"></a>
+<h2>12.4 Line control</h2>
+
+<p><small>Line directives may occur in the following
+forms:</small></p>
+<pre><small>     #line <i>constant
+</i>     #line <i>constant</i> &quot;<i>filename</i>&quot;
+     #<i>constant
+</i>     #<i>constant</i> &quot;<i>filename</i>&quot;
+</small></pre>
+
+<p><small>Note that <i>filename</i> is enclosed in double
+quotes.</small></p>
+<a name="14.2 Functions"></a>
+<h2>14.2 Functions</h2>
+
+<p><small>If a pointer to a function is called, the
+function the pointer points to is called
+instead.</small></p>
+<a name="15 Constant expressions"></a>
+<h2>15 Constant expressions</h2>
+
+<p><small>The compiler distinguishes the following types of
+integral constant expressions</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="42%">
+
+<p><small>field-width specifier</small></p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p><small>case-entry specifier</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p><small>array-size specifier</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p><small>global variable initialization value</small></p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p><small>enum-value specifier</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>&bull;</small></p>
+</td>
+<td width="8%"></td>
+<td width="62%">
+
+<p><small>truth value in <tt>#if</tt> control
+line</small></p>
+</td>
+<td width="27%">
+</td>
+</table>
+
+<p><small>Constant integral expressions are compile-time
+evaluated while an effort is made to report overflow.
+Constant floating expressions are not compile-time
+evaluated.</small></p>
+<a name="2. Compiler flags"></a>
+<h2>2. Compiler flags</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><b>&minus;C</b></small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Run the preprocessor stand-alone while
+maintaining the comments. Line directives are produced
+whenever needed.</small></p>
+</td>
+</table>
+
+
+<p><small><b>&minus;D</b><i>name</i>=<i>string-of-characters</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Define <i>name</i> as macro with
+<i>string-of-characters</i> as replacement text.</small></p>
+</td>
+</table>
+
+<p><small><b>&minus;D</b><i>name</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Equal to
+<b>&minus;D</b><i>name</i><b>=1</b>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><b>&minus;E</b></small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Run the preprocessor stand alone, i.e., list the
+sequence of input tokens and delete any comments. Line
+directives are produced whenever needed.</small></p>
+</td>
+</table>
+
+<p><small><b>&minus;I</b><i>path</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Prepend <i>path</i> to the list of include
+directories. To put the directories &quot;include&quot;,
+&quot;sys/h&quot; and &quot;util/h&quot; into the include
+directory list in that order, the user has to
+specify</small></p>
+<!-- INDENTATION -->
+<pre><small>     -Iinclude -Isys/h -Iutil/h
+</small></pre>
+<!-- INDENTATION -->
+<p><small>An empty <i>path</i> causes the standard include
+directory (usually <tt>/usr/include</tt>) to be
+forgotten.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small><b>&minus;M</b><i>n</i></small></p>
+</td>
+<td width="93%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Set maximum significant identifier length to
+<i>n</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><b>&minus;n</b></small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Suppress EM register messages. The user-declared
+variables are not stored into registers on the target
+machine.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><b>&minus;p</b></small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Generate the EM <b>fil</b> and <b>lin</b>
+instructions in order to enable an interpreter to keep track
+of the current location in the source code.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><b>&minus;P</b></small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Equivalent with <b>&minus;E</b>, but without line
+directives.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><b>&minus;R</b></small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Interpret the input as restricted C (according to
+the language as described in [1]).</small></p>
+</td>
+</table>
+
+<p><small><b>&minus;T</b><i>path</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Create temporary files, if necessary, in directory
+<i>path</i>.</small></p>
+</td>
+</table>
+
+<p><small><b>&minus;U</b><i>name</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Get rid of the compiler-predefined macro
+<i>name</i>, i.e., consider</small></p>
+<!-- INDENTATION -->
+<pre><small>     #undef <i>name
+</i></small></pre>
+<!-- INDENTATION -->
+<p><small>to appear in the beginning of the
+file.</small></p>
+</td>
+</table>
+
+<p><small><b>&minus;V</b><i>cm</i>.<i>n</i>,
+<b>&minus;V</b><i>cm</i>.<i>ncm</i>.<i>n</i> ...</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Set the size and alignment requirements. The
+letter <i>c</i> indicates the simple type, which is one of
+<b>s</b>(short), <b>i</b>(int), <b>l</b>(long),
+<b>f</b>(float), <b>d</b>(double) or <b>p</b>(pointer). If
+<i>c</i> is <b>S</b> or <b>U</b>, then <i>n</i> is taken to
+be the initial alignment of structs or unions, respectively.
+The effective alignment of a struct or union is the least
+common multiple of the initial struct/union alignment and
+the alignments of its members. The <i>m</i> parameter can be
+used to specify the length of the type (in bytes) and the
+<i>n</i> parameter for the alignment of that type. Absence
+of <i>m</i> or <i>n</i> causes the default value to be
+retained. To specify that the bitfields should be right
+adjusted instead of the default left adjustment, specify
+<b>r</b> as <i>c</i> parameter.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small><b>&minus;w</b></small></p>
+</td>
+<td width="6%"></td>
+<td width="50%">
+
+<p><small>Suppress warning messages</small></p>
+</td>
+<td width="39%">
+</td>
+</table>
+
+
+<p><small><b>&minus;&minus;</b><i>character</i></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Set debug-flag <i>character</i>. This enables some
+special features offered by a debug and develop version of
+the compiler. Some particular flags may be recognized,
+others may have surprising effects.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>d</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><small>Generate a dependency graph, reflecting the
+calling structure of functions. Lines of the
+form</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<pre><small>     DFA: <i>calling-function</i>: <i>called-function
+</i></small></pre>
+<!-- INDENTATION -->
+<p><small>are generated whenever a function call is
+encountered.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>f</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><small>Dump whole identifier table, including macros and
+reserved words.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>h</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="58%">
+
+<p><small>Supply hash-table statistics.</small></p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>i</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p><small>Print names of included files.</small></p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>m</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><small>Supply statistics concerning the memory
+allocation.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>t</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="52%">
+
+<p><small>Dump table of identifiers.</small></p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>u</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><small>Generate extra statistics concerning the
+predefined types and identifiers. Works in combination with
+<b>f</b> or <b>t</b>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p><small><b>x</b></small></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><small>Print expression trees in human-readable
+format.</small></p>
+</td>
+</table>
+<a name="References"></a>
+<h2>References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[1]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Brian W. Kernighan, Dennis M. Ritchie, <i>The C
+Programming Language</i></small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[2]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>L. Rosler, <i>Draft Proposed Standard -
+Programming Language C,</i> ANSI X3J11 Language
+Subcommittee</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[3]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Erik H. Baalbergen, Dick Grune, Maarten Waage,
+<i>The CEM Compiler,</i> Informatica Manual IM-4, Dept. of
+Mathematics and Computer Science, Vrije Universiteit,
+Amsterdam, The Netherlands</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[4]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Erik H. Baalbergen, <i>Modeling global
+declarations in C,</i> internal paper</small></p>
+</td>
+</table>
+<a name="Appendix A - Enumeration Type"></a>
+<h2>Appendix A - Enumeration Type</h2>
+
+<p>The syntax is</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><i>enum-specifier</i>:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><tt>enum</tt> { <i>enum-list</i> }<tt><br>
+enum</tt> <i>identifier</i> { <i>enum-list</i> }<tt><br>
+enum</tt> <i>identifier</i></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><i>enum-list</i> :</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><i>enumerator<br>
+enum-list</i> , <i>enumerator</i></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><i>enumerator</i> :</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><i>identifier<br>
+identifier</i> = <i>constant-expression</i></p>
+</td>
+</table>
+
+<p>The identifier has the same role as the structure tag in
+a struct specification. It names a particular enumeration
+type.</p>
+
+<p>The identifiers in the enum-list are declared as
+constants, and may appear whenever constants are required.
+If no enumerators with <b>=</b> appear, then the values of
+the constants begin at 0 and increase by 1 as the
+declaration is read from left to right. An enumerator with
+<b>=</b> gives the associated identifier the value
+indicated; subsequent identifiers continue the progression
+from the assigned value.</p>
+
+<p>Enumeration tags and constants must all be distinct,
+and, unlike structure tags and members, are drawn from the
+same set as ordinary identifiers.</p>
+
+<p>Objects of a given enumeration type are regarded as
+having a type distinct from objects of all other types.</p>
+<a name="Appendix B: C grammar in LL(1) form"></a>
+<h2>Appendix B: C grammar in LL(1) form</h2>
+
+<p>The <b>bold-faced</b> and <i>italicized</i> tokens
+represent terminal symbols.</p>
+<pre><b>external definitions
+</b>program:  external-definition*
+external-definition:  ext-decl-specifiers [declarator [function  |  non-function]  |  &rsquo;<b>;</b>&rsquo;]  |  asm-statement
+ext-decl-specifiers:  decl-specifiers?
+non-function:  initializer? [&rsquo;<b>,</b>&rsquo; init-declarator]* &rsquo;<b>;</b>&rsquo;
+function:  declaration* compound-statement
+
+<b>declarations
+</b>declaration:  decl-specifiers init-declarator-list? &rsquo;<b>;</b>&rsquo;
+decl-specifiers:  other-specifier+ [single-type-specifier other-specifier*]?  |  single-type-specifier other-specifier*
+other-specifier: <b> auto</b>  | <b> static</b>  | <b> extern</b>  | <b> typedef</b>  | <b> register</b>  | <b> short</b>  | <b> long</b>  | <b> unsigned
+</b>type-specifier:  decl-specifiers
+single-type-specifier: <i> type-identifier</i>  |  struct-or-union-specifier  |  enum-specifier
+init-declarator-list:  init-declarator [&rsquo;<b>,</b>&rsquo; init-declarator]*
+init-declarator:  declarator initializer?
+declarator:  primary-declarator [&rsquo;<b>(</b>&rsquo; formal-list ? &rsquo;<b>)</b>&rsquo;  |  arrayer]*  |  &rsquo;<b>*</b>&rsquo; declarator
+primary-declarator:  identifier  |  &rsquo;<b>(</b>&rsquo; declarator &rsquo;<b>)</b>&rsquo;
+arrayer:  &rsquo;<b>[</b>&rsquo; constant-expression? &rsquo;<b>]</b>&rsquo;
+formal-list:  formal [&rsquo;<b>,</b>&rsquo; formal]*
+formal:  identifier
+enum-specifier: <b> enum</b> [enumerator-pack  |  identifier enumerator-pack?]
+enumerator-pack:  &rsquo;<b>{</b>&rsquo; enumerator [&rsquo;<b>,</b>&rsquo; enumerator]* &rsquo;<b>,</b>&rsquo;? &rsquo;<b>}</b>&rsquo;
+enumerator:  identifier [&rsquo;<b>=</b>&rsquo; constant-expression]?
+struct-or-union-specifier:  [ <b>struct</b>  | <b> union</b>] [ struct-declaration-pack  |  identifier struct-declaration-pack?]
+struct-declaration-pack:  &rsquo;<b>{</b>&rsquo; struct-declaration+ &rsquo;<b>}</b>&rsquo;
+struct-declaration:  type-specifier struct-declarator-list &rsquo;<b>;</b>&rsquo;?
+struct-declarator-list:  struct-declarator [&rsquo;<b>,</b>&rsquo; struct-declarator]*
+struct-declarator:  declarator bit-expression?  |  bit-expression
+bit-expression:  &rsquo;<b>:</b>&rsquo; constant-expression
+initializer:  &rsquo;<b>=</b>&rsquo;? initial-value
+cast:  &rsquo;<b>(</b>&rsquo; type-specifier abstract-declarator &rsquo;<b>)</b>&rsquo;
+abstract-declarator:  primary-abstract-declarator [&rsquo;<b>(</b>&rsquo; &rsquo;<b>)</b>&rsquo;  |  arrayer]*  |  &rsquo;<b>*</b>&rsquo; abstract-declarator
+primary-abstract-declarator:  [&rsquo;<b>(</b>&rsquo; abstract-declarator &rsquo;<b>)</b>&rsquo;]?
+
+<b>statements
+</b>statement:
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>expression-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| label &rsquo;<b>:</b>&rsquo; statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| compound-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| if-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| while-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| do-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| for-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| switch-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| case-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| default-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| break-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| continue-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| return-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| jump</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| &rsquo;<b>;</b>&rsquo;</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>| asm-statement</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>;</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p>expression-statement: expression
+&rsquo;<b>;</b>&rsquo;<br>
+label: identifier<br>
+if-statement: <b>if</b> &rsquo;<b>(</b>&rsquo; expression
+&rsquo;<b>)</b>&rsquo; statement [<b>else</b>
+statement]?<br>
+while-statement: <b>while</b> &rsquo;<b>(</b>&rsquo;
+expression &rsquo;<b>)</b>&rsquo; statement<br>
+do-statement: <b>do</b> statement <b>while</b>
+&rsquo;<b>(</b>&rsquo; expression &rsquo;<b>)</b>&rsquo;
+&rsquo;<b>;</b>&rsquo;<br>
+for-statement: <b>for</b> &rsquo;<b>(</b>&rsquo; expression?
+&rsquo;<b>;</b>&rsquo; expression? &rsquo;<b>;</b>&rsquo;
+expression? &rsquo;<b>)</b>&rsquo; statement<br>
+switch-statement: <b>switch</b> &rsquo;<b>(</b>&rsquo;
+expression &rsquo;<b>)</b>&rsquo; statement<br>
+case-statement: <b>case</b> constant-expression
+&rsquo;<b>:</b>&rsquo; statement<br>
+default-statement: <b>default</b> &rsquo;<b>:</b>&rsquo;
+statement<br>
+break-statement: <b>break</b> &rsquo;<b>;</b>&rsquo;<br>
+continue-statement: <b>continue</b>
+&rsquo;<b>;</b>&rsquo;<br>
+return-statement: <b>return</b> expression?
+&rsquo;<b>;</b>&rsquo;<br>
+jump: <b>goto</b> identifier &rsquo;<b>;</b>&rsquo;<br>
+compound-statement: &rsquo;<b>{</b>&rsquo; declaration*
+statement* &rsquo;<b>}</b>&rsquo;<br>
+asm-statement: <b>asm</b> &rsquo;<b>(</b>&rsquo;
+<i>string</i> &rsquo;<b>)</b>&rsquo;
+&rsquo;<b>;</b>&rsquo;</p>
+
+<p><b>expressions</b><br>
+initial-value: assignment-expression |
+initial-value-pack<br>
+initial-value-pack: &rsquo;<b>{</b>&rsquo;
+initial-value-list &rsquo;<b>}</b>&rsquo;<br>
+initial-value-list: initial-value [&rsquo;<b>,</b>&rsquo;
+initial-value]* &rsquo;<b>,</b>&rsquo;?<br>
+primary: <i>identifier</i> | constant | <i>string</i> |
+&rsquo;<b>(</b>&rsquo; expression &rsquo;<b>)</b>&rsquo;<br>
+secundary: primary [index-pack | parameter-pack |
+selection]*<br>
+index-pack: &rsquo;<b>[</b>&rsquo; expression
+&rsquo;<b>]</b>&rsquo;<br>
+parameter-pack: &rsquo;<b>(</b>&rsquo; parameter-list?
+&rsquo;<b>)</b>&rsquo;<br>
+selection: [&rsquo;<b>.</b>&rsquo; |
+&rsquo;<b>&minus;&gt;</b>&rsquo;] identifier<br>
+parameter-list: assignment-expression
+[&rsquo;<b>,</b>&rsquo; assignment-expression]*<br>
+postfixed: secundary postop?<br>
+unary: cast unary | postfixed | unop unary | size-of<br>
+size-of: <b>sizeof</b> [cast | unary]<br>
+binary-expression: unary [binop binary-expression]*<br>
+conditional-expression: binary-expression
+[&rsquo;<b>?</b>&rsquo; expression &rsquo;<b>:</b>&rsquo;
+assignment-expression]?<br>
+assignment-expression: conditional-expression [asgnop
+assignment-expression]?<br>
+expression: assignment-expression [&rsquo;<b>,</b>&rsquo;
+assignment-expression]*<br>
+unop: &rsquo;<b>*</b>&rsquo; | &rsquo;<b>&amp;</b>&rsquo; |
+&rsquo;<b>&minus;</b>&rsquo; | &rsquo;<b>!</b>&rsquo; |
+&rsquo;<b>~</b> &rsquo; | &rsquo;<b>++</b>&rsquo; |
+&rsquo;<b>&minus;&minus;</b>&rsquo;<br>
+postop: &rsquo;<b>++</b>&rsquo; |
+&rsquo;<b>&minus;&minus;</b>&rsquo;<br>
+multop: &rsquo;<b>*</b>&rsquo; | &rsquo;<b>/</b>&rsquo; |
+&rsquo;<b>%</b>&rsquo;<br>
+addop: &rsquo;<b>+</b>&rsquo; |
+&rsquo;<b>&minus;</b>&rsquo;<br>
+shiftop: &rsquo;<b>&lt;&lt;</b>&rsquo; |
+&rsquo;<b>&gt;&gt;</b>&rsquo;<br>
+relop: &rsquo;<b>&lt;</b>&rsquo; | &rsquo;<b>&gt;</b>&rsquo;
+| &rsquo;<b>&lt;=</b>&rsquo; |
+&rsquo;<b>&gt;=</b>&rsquo;<br>
+eqop: &rsquo;<b>==</b>&rsquo; | &rsquo;<b>!=</b>&rsquo;<br>
+arithop: multop | addop | shiftop |
+&rsquo;<b>&amp;</b>&rsquo; | &rsquo;<b>^</b> &rsquo; |
+&rsquo;<b>|</b>&rsquo;<br>
+binop: arithop | relop | eqop |
+&rsquo;<b>&amp;&amp;</b>&rsquo; |
+&rsquo;<b>||</b>&rsquo;<br>
+asgnop: &rsquo;<b>=</b>&rsquo; | &rsquo;<b>+</b>&rsquo;
+&rsquo;<b>=</b>&rsquo; | &rsquo;<b>&minus;</b>&rsquo;
+&rsquo;<b>=</b>&rsquo; | &rsquo;<b>*</b>&rsquo;
+&rsquo;<b>=</b>&rsquo; | &rsquo;<b>/</b>&rsquo;
+&rsquo;<b>=</b>&rsquo; | &rsquo;<b>%</b>&rsquo;
+&rsquo;<b>=</b>&rsquo;</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p>| &rsquo;<b>&lt;&lt;</b>&rsquo; &rsquo;<b>=</b>&rsquo; |
+&rsquo;<b>&gt;&gt;</b>&rsquo; &rsquo;<b>=</b>&rsquo; |
+&rsquo;<b>&amp;</b>&rsquo; &rsquo;<b>=</b>&rsquo; |
+&rsquo;<b>^</b> &rsquo; &rsquo;<b>=</b>&rsquo; |
+&rsquo;<b>|</b>&rsquo; &rsquo;<b>=</b>&rsquo;</p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p>| &rsquo;<b>+=</b>&rsquo; |
+&rsquo;<b>&minus;=</b>&rsquo; | &rsquo;<b>*=</b>&rsquo; |
+&rsquo;<b>/=</b>&rsquo; | &rsquo;<b>%=</b>&rsquo;</p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p>| &rsquo;<b>&lt;&lt;=</b>&rsquo; |
+&rsquo;<b>&gt;&gt;=</b>&rsquo; | &rsquo;<b>&amp;=</b>&rsquo;
+| &rsquo;<b>^=</b>&rsquo; | &rsquo;<b>|=</b>&rsquo;</p>
+</td>
+</table>
+
+<p>constant: <i>integer</i> | <i>floating</i><br>
+constant-expression: assignment-expression<br>
+identifier: <i>identifier</i> | <i>type-identifier</i></p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/crefman.pdf b/src/olddocs/crefman.pdf
new file mode 100644 (file)
index 0000000..87407d4
Binary files /dev/null and b/src/olddocs/crefman.pdf differ
diff --git a/src/olddocs/ego.html b/src/olddocs/ego.html
new file mode 100644 (file)
index 0000000..4d6353a
--- /dev/null
@@ -0,0 +1,9470 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:28 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The design and implementation of the EM Global Optimizer</title>
+</head>
+<body>
+
+<h1 align=center>The design and implementation of the EM Global Optimizer</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. Overview of the global optimizer">2. Overview of the global optimizer</a><br>
+<a href="#2.1. The ACK compilation process">2.1. The ACK compilation process</a><br>
+<a href="#2.2. The EM code">2.2. The EM code</a><br>
+<a href="#2.3. Requirements on the EM input">2.3. Requirements on the EM input</a><br>
+<a href="#2.4. Structure of the optimizer">2.4. Structure of the optimizer</a><br>
+<a href="#2.5. Structure of this document">2.5. Structure of this document</a><br>
+<a href="#2.6. References">2.6. References</a><br>
+<a href="#3. The Intermediate Code and the IC phase">3. The Intermediate Code and the IC phase</a><br>
+<a href="#3.1. Introduction">3.1. Introduction</a><br>
+<a href="#3.2. Representation of complex data structures in a sequential file">3.2. Representation of complex data structures in a sequential file</a><br>
+<a href="#3.3. Definition of the intermediate code">3.3. Definition of the intermediate code</a><br>
+<a href="#3.3.1. The object table">3.3.1. The object table</a><br>
+<a href="#3.3.2. The procedure table">3.3.2. The procedure table</a><br>
+<a href="#3.3.3. The EM text">3.3.3. The EM text</a><br>
+<a href="#3.3.4. The control flow graphs">3.3.4. The control flow graphs</a><br>
+<a href="#3.3.5. The loop tables">3.3.5. The loop tables</a><br>
+<a href="#3.4. External representation of the intermediate code">3.4. External representation of the intermediate code</a><br>
+<a href="#3.5. The Intermediate Code construction phase">3.5. The Intermediate Code construction phase</a><br>
+<a href="#3.5.1. Implementation">3.5.1. Implementation</a><br>
+<a href="#3.5.2. Source files of IC">3.5.2. Source files of IC</a><br>
+<a href="#4. The Control Flow Phase">4. The Control Flow Phase</a><br>
+<a href="#4.1. Partitioning into basic blocks">4.1. Partitioning into basic blocks</a><br>
+<a href="#4.2. Control Flow">4.2. Control Flow</a><br>
+<a href="#4.3. Immediate dominators">4.3. Immediate dominators</a><br>
+<a href="#4.4. Loop detection">4.4. Loop detection</a><br>
+<a href="#4.5. Interprocedural analysis">4.5. Interprocedural analysis</a><br>
+<a href="#4.6. Source files">4.6. Source files</a><br>
+<a href="#5. Inline substitution">5. Inline substitution</a><br>
+<a href="#5.1. Introduction">5.1. Introduction</a><br>
+<a href="#5.2. Parameters and local variables.">5.2. Parameters and local variables.</a><br>
+<a href="#5.3. Feasibility and desirability analysis">5.3. Feasibility and desirability analysis</a><br>
+<a href="#5.4. Heuristic rules">5.4. Heuristic rules</a><br>
+<a href="#5.5. Implementation">5.5. Implementation</a><br>
+<a href="#5.5.1. Data structures">5.5.1. Data structures</a><br>
+<a href="#5.5.1.1. The procedure table">5.5.1.1. The procedure table</a><br>
+<a href="#5.5.1.2. Call-count information">5.5.1.2. Call-count information</a><br>
+<a href="#5.5.1.3. The call-list">5.5.1.3. The call-list</a><br>
+<a href="#5.5.2. The first subphase: procedure analysis">5.5.2. The first subphase: procedure analysis</a><br>
+<a href="#5.5.3. The second subphase: making decisions">5.5.3. The second subphase: making decisions</a><br>
+<a href="#5.5.4. The third subphase: doing transformations">5.5.4. The third subphase: doing transformations</a><br>
+<a href="#5.6. Source files of IL">5.6. Source files of IL</a><br>
+<a href="#6. Strength reduction">6. Strength reduction</a><br>
+<a href="#6.1. Introduction">6.1. Introduction</a><br>
+<a href="#6.2. The model of strength reduction">6.2. The model of strength reduction</a><br>
+<a href="#6.2.1. Induction variables">6.2.1. Induction variables</a><br>
+<a href="#6.2.2. Recognized expressions">6.2.2. Recognized expressions</a><br>
+<a href="#6.2.3. Transformations">6.2.3. Transformations</a><br>
+<a href="#6.3. Implementation">6.3. Implementation</a><br>
+<a href="#6.3.1. Finding induction variables">6.3.1. Finding induction variables</a><br>
+<a href="#6.3.2. Optimizing expressions">6.3.2. Optimizing expressions</a><br>
+<a href="#6.4. Source files of SR">6.4. Source files of SR</a><br>
+<a href="#7. Common subexpression elimination">7. Common subexpression elimination</a><br>
+<a href="#7.1. Introduction">7.1. Introduction</a><br>
+<a href="#7.2. Specification of the Common Subexpression Elimination phase">7.2. Specification of the Common Subexpression Elimination phase</a><br>
+<a href="#7.2.1. The working window">7.2.1. The working window</a><br>
+<a href="#7.2.2. Recognized expressions.">7.2.2. Recognized expressions.</a><br>
+<a href="#7.2.3. Transformations">7.2.3. Transformations</a><br>
+<a href="#7.3. Implementation">7.3. Implementation</a><br>
+<a href="#7.3.1. The value number method">7.3.1. The value number method</a><br>
+<a href="#7.3.2. Entities">7.3.2. Entities</a><br>
+<a href="#7.3.3. Parsing expressions">7.3.3. Parsing expressions</a><br>
+<a href="#7.3.4. Updating entities">7.3.4. Updating entities</a><br>
+<a href="#7.3.5. Changing the EM text">7.3.5. Changing the EM text</a><br>
+<a href="#7.3.6. Desirability analysis">7.3.6. Desirability analysis</a><br>
+<a href="#7.3.7. The algorithm">7.3.7. The algorithm</a><br>
+<a href="#7.4. Implementation.">7.4. Implementation.</a><br>
+<a href="#7.4.1. Partioning the EM instructions">7.4.1. Partioning the EM instructions</a><br>
+<a href="#7.4.2. Parsing expressions">7.4.2. Parsing expressions</a><br>
+<a href="#7.4.3. Updating entities">7.4.3. Updating entities</a><br>
+<a href="#7.4.4. Additions and replacements.">7.4.4. Additions and replacements.</a><br>
+<a href="#7.4.5. Desirability analysis">7.4.5. Desirability analysis</a><br>
+<a href="#7.4.6. The algorithm">7.4.6. The algorithm</a><br>
+<a href="#7.5. Source files of CS">7.5. Source files of CS</a><br>
+<a href="#8. Stack pollution">8. Stack pollution</a><br>
+<a href="#8.1. Introduction">8.1. Introduction</a><br>
+<a href="#8.2. Implementation">8.2. Implementation</a><br>
+<a href="#9. Cross jumping">9. Cross jumping</a><br>
+<a href="#9.1. Introduction">9.1. Introduction</a><br>
+<a href="#9.2. Implementation">9.2. Implementation</a><br>
+<a href="#10. Branch Optimization">10. Branch Optimization</a><br>
+<a href="#10.1. Introduction">10.1. Introduction</a><br>
+<a href="#10.1.1. Fusion of basic blocks">10.1.1. Fusion of basic blocks</a><br>
+<a href="#10.1.2. While-loop optimization">10.1.2. While-loop optimization</a><br>
+<a href="#10.2. Implementation">10.2. Implementation</a><br>
+<a href="#11. Use-Definition analysis">11. Use-Definition analysis</a><br>
+<a href="#11.1. Introduction">11.1. Introduction</a><br>
+<a href="#11.2. Data flow information">11.2. Data flow information</a><br>
+<a href="#11.2.1. Use-Definition information">11.2.1. Use-Definition information</a><br>
+<a href="#11.2.2. Copy information">11.2.2. Copy information</a><br>
+<a href="#11.3. Pointers and subroutine calls">11.3. Pointers and subroutine calls</a><br>
+<a href="#11.4. Implementation">11.4. Implementation</a><br>
+<a href="#11.5. Source files of UD">11.5. Source files of UD</a><br>
+<a href="#12. Live-Variable analysis">12. Live-Variable analysis</a><br>
+<a href="#12.1. Introduction">12.1. Introduction</a><br>
+<a href="#12.2. Implementation">12.2. Implementation</a><br>
+<a href="#13. Register Allocation">13. Register Allocation</a><br>
+<a href="#13.1. Introduction">13.1. Introduction</a><br>
+<a href="#13.2. Usage of registers in ACK compilers">13.2. Usage of registers in ACK compilers</a><br>
+<a href="#13.2.1. Usage of registers without the intervention of the Global Optimizer">13.2.1. Usage of registers without the intervention of the Global Optimizer</a><br>
+<a href="#13.2.2. The role of the Global Optimizer">13.2.2. The role of the Global Optimizer</a><br>
+<a href="#13.2.3. The interface between the register allocator and the code generator">13.2.3. The interface between the register allocator and the code generator</a><br>
+<a href="#13.3. The register allocation phase">13.3. The register allocation phase</a><br>
+<a href="#13.3.1. Overview">13.3.1. Overview</a><br>
+<a href="#13.3.2. The item recognition subphase">13.3.2. The item recognition subphase</a><br>
+<a href="#13.3.3. The allocation determination subphase">13.3.3. The allocation determination subphase</a><br>
+<a href="#13.3.4. The rivals computation subphase">13.3.4. The rivals computation subphase</a><br>
+<a href="#13.3.5. The profits computation subphase">13.3.5. The profits computation subphase</a><br>
+<a href="#13.3.6. The packing subphase">13.3.6. The packing subphase</a><br>
+<a href="#13.3.7. The transformation subphase">13.3.7. The transformation subphase</a><br>
+<a href="#13.4. Source files of RA">13.4. Source files of RA</a><br>
+<a href="#14. Compact assembly generation">14. Compact assembly generation</a><br>
+<a href="#14.1. Introduction">14.1. Introduction</a><br>
+<a href="#14.2. Implementation">14.2. Implementation</a><br>
+<a href="#Acknowledgements">Acknowledgements</a><br>
+<a href="#References">References</a><br>
+<a href="#References">References</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>H.E. Bal</i><br>
+Vrije Universiteit<br>
+Wiskundig Seminarium, Amsterdam</p>
+
+<p>The EM Global Optimizer is part of the Amsterdam
+Compiler Kit, a toolkit for making retargetable compilers.
+It optimizes the intermediate code common to all compilers
+of the toolkit (EM), so it can be used for all programming
+languages and all processors supported by the kit.</p>
+
+<p>The optimizer is based on well-understood concepts like
+control flow analysis and data flow analysis. It performs
+the following optimizations: Inline Substitution, Strength
+Reduction, Common Subexpression Elimination, Stack
+Pollution, Cross Jumping, Branch Optimization, Copy
+Propagation, Constant Propagation, Dead Code Elimination and
+Register Allocation.</p>
+
+<p>This report describes the design of the optimizer and
+several of its implementation issues.</p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p align=center><img src="grohtml-102721.png"></p>
+
+<p>The EM Global Optimizer is part of a software toolkit
+for making production-quality retargetable compilers. This
+toolkit, called the Amsterdam Compiler Kit [Tane81a,
+Tane83b] runs under the Unix*</p>
+
+<p align=center><img src="grohtml-102722.png"></p>
+
+<p>operating system.<br>
+The main design philosophy of the toolkit is to use a
+language- and machine-independent intermediate code, called
+EM. [Tane83a] The basic compilation process can be split up
+into two parts. A language-specific front end translates the
+source program into EM. A machine-specific back end
+transforms EM to assembly code of the target machine.</p>
+
+<p>The global optimizer is an optional phase of the
+compilation process, and can be used to obtain machine code
+of a higher quality. The optimizer transforms EM-code to
+better EM-code, so it comes between the front end and the
+back end. It can be used with any combination of languages
+and machines, as far as they are supported by the compiler
+kit.</p>
+
+<p>This report describes the design of the global optimizer
+and several of its implementation issues. Measurements can
+be found in. [Bal86a]</p>
+<a name="2. Overview of the global optimizer"></a>
+<h2>2. Overview of the global optimizer</h2>
+<a name="2.1. The ACK compilation process"></a>
+<h2>2.1. The ACK compilation process</h2>
+
+<p>The EM Global Optimizer is one of three optimizers that
+are part of the Amsterdam Compiler Kit (ACK). The phases of
+ACK are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>A Front End translates a source program to EM</p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>The Peephole Optimizer [a] reads EM code and produces
+&rsquo;better&rsquo; EM code. It performs a number of
+optimizations (mostly peephole optimizations) such as
+constant folding, strength reduction and unreachable code
+elimination.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>The Global Optimizer further improves the EM code.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>The Code Generator transforms EM to assembly code of the
+target computer.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>The Target Optimizer improves the assembly code.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>An Assembler/Loader generates an executable file.</p>
+</td>
+</table>
+
+<p>For a more extensive overview of the ACK compilation
+process, we refer to. [Tane81a, Tane83b]</p>
+
+<p>The input of the Global Optimizer may consist of files
+and libraries. Every file or module in the library must
+contain EM code in Compact Assembly Language format.
+[Tane83a, section 11.2] The output consists of one such EM
+file. The input files and libraries together need not
+constitute an entire program, although as much of the
+program as possible should be supplied. The more information
+about the program the optimizer gets, the better its output
+code will be.</p>
+
+<p>The Global Optimizer is language- and
+machine-independent, i.e. it can be used for all languages
+and machines supported by ACK. Yet, it puts some unavoidable
+restrictions on the EM code produced by the Front End (see
+below). It must have some knowledge of the target machine.
+This knowledge is expressed in a machine description table
+which is passed as argument to the optimizer. This table
+does not contain very detailed information about the target
+(such as its instruction set and addressing modes).</p>
+<a name="2.2. The EM code"></a>
+<h2>2.2. The EM code</h2>
+
+<p>The definition of EM, the intermediate code of all ACK
+compilers, is given in a separate document. [Tane83a] We
+will only discuss some features of EM that are most relevant
+to the Global Optimizer.</p>
+
+<p>EM is the assembly code of a virtual <i>stack
+machine</i>. All operations are performed on the top of the
+stack. For example, the statement &quot;A := B + 3&quot; may
+be expressed in EM as:</p>
+
+<p align=center><img src="grohtml-102723.png"></p>
+
+<p>So EM is essentially a <i>postfix</i> code.</p>
+
+<p>EM has a rich instruction set, containing several
+arithmetic and logical operators. It also contains
+special-case instructions (such as INCrement).</p>
+
+<p>EM has <i>global</i> (<i>external</i>) variables,
+accessible by all procedures and <i>local</i> variables,
+accessible by a few (nested) procedures. The local variables
+of a lexically enclosing procedure may be accessed via a
+<i>static link</i>. EM has instructions to follow the static
+chain. There are EM instruction to allow a procedure to
+access its local variables directly (such as LOL and STL
+above). Local variables are referenced via an offset in the
+stack frame of the procedure, rather than by their names
+(e.g. -2 and -4 above). The EM code does not contain the
+(source language) type of the variables.</p>
+
+<p>All structured statements in the source program are
+expressed in low level jump instructions. Besides
+conditional and unconditional branch instructions, there are
+two case instructions (CSA and CSB), to allow efficient
+translation of case statements.</p>
+<a name="2.3. Requirements on the EM input"></a>
+<h2>2.3. Requirements on the EM input</h2>
+
+<p>As the optimizer should be useful for all languages, it
+clearly should not put severe restrictions on the EM code of
+the input. There is, however, one immovable requirement: it
+must be possible to determine the <i>flow of control</i> of
+the input program. As virtually all global optimizations are
+based on control flow information, the optimizer would be
+totally powerless without it. For this reason we restrict
+the usage of the case jump instructions (CSA/CSB) of EM.
+Such an instruction is always called with the address of a
+case descriptor on top the the stack. [Tane83a section 7.4]
+This descriptor contains the labels of all possible
+destinations of the jump. We demand that all case
+descriptors are allocated in a global data fragment of type
+ROM, i.e. the case descriptors may not be modifyable.
+Furthermore, any case instruction should be immediately
+preceded by a LAE (Load Address External) instruction, that
+loads the address of the descriptor, so the descriptor can
+be uniquely identified.</p>
+
+<p>The optimizer will work improperly if the user deceives
+the control flow. We will give two methods to do this.</p>
+
+<p>In &quot;C&quot; the notorious library routines
+&quot;setjmp&quot; and &quot;longjmp&quot; [Kern79a] may be
+used to jump out of a procedure, but can also be used for a
+number of other stuffy purposes, for example, to create an
+extra entry point in a loop.</p>
+<pre>      while (condition) {
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>....<br>
+setjmp(buf);<br>
+...</p>
+</table>
+
+<p>}<br>
+...<br>
+longjmp(buf);</p>
+
+<p>The invocation to longjmp actually is a jump to the
+place of the last call to setjmp with the same argument
+(buf). As the calls to setjmp and longjmp are
+indistinguishable from normal procedure calls, the optimizer
+will not see the danger. No need to say that several loop
+optimizations will behave unexpectedly when presented with
+such pathological input.</p>
+
+<p>Another way to deceive the flow of control is by using
+exception handling routines. Ada*</p>
+
+<p align=center><img src="grohtml-102724.png"></p>
+
+<p>has clearly recognized the dangers of exception
+handling, but other languages (such as PL/I) have not.
+[Ichb79a]</p>
+
+<p>The optimizer will be more effective if the EM input
+contains some extra information about the source program.
+Especially the <i>register message</i> is very important.
+These messages indicate which local variables may never be
+accessed indirectly. Most optimizations benefit
+significantly by this information.</p>
+
+<p>The Inline Substitution technique needs to know how many
+bytes of formal parameters every procedure accesses. Only
+calls to procedures for which the EM code contains this
+information will be substituted in line.</p>
+<a name="2.4. Structure of the optimizer"></a>
+<h2>2.4. Structure of the optimizer</h2>
+
+<p>The Global Optimizer is organized as a number of
+<i>phases</i>, each one performing some task. The main
+structure is as follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>IC</p>
+</td>
+<td width="8%"></td>
+<td width="88%">
+
+<p>the Intermediate Code construction phase transforms EM
+into the intermediate code (ic) of the optimizer</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>CF</p>
+</td>
+<td width="8%"></td>
+<td width="88%">
+
+<p>the Control Flow phase extends the ic with control flow
+information and interprocedural information</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>OPTs</p>
+</td>
+<td width="4%"></td>
+<td width="88%">
+
+<p>zero or more optimization phases, each one performing
+one or more related optimizations</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>CA</p>
+</td>
+<td width="8%"></td>
+<td width="88%">
+
+<p>the Compact Assembly phase generates Compact Assembly
+Language EM code out of ic.</p>
+</td>
+</table>
+
+<p>An important issue in the design of a global optimizer
+is the interaction between optimization techniques. It is
+often advantageous to combine several techniques in one
+algorithm that takes into account all interactions between
+them. Ideally, one single algorithm should be developed that
+does all optimizations simultaneously and deals with all
+possible interactions. In practice, such an algorithm is
+still far out of reach. Instead some rather ad hoc (albeit
+important) combinations are chosen, such as Common
+Subexpression Elimination and Register Allocation. [Prab80a,
+Seth70a]</p>
+
+<p>In the Em Global Optimizer there is one separate
+algorithm for every technique. Note that this does not mean
+that all techniques are independent of each other.</p>
+
+<p>In principle, the optimization phases can be run in any
+order; a phase may even be run more than once. However, the
+following rules should be obeyed:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the Live Variable analysis phase (LV) must be run prior
+to Register Allocation (RA), as RA uses information
+outputted by LV.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>RA should be the last phase; this is a consequence of
+the way the interface between RA and the Code Generator is
+defined.</p>
+</td>
+</table>
+
+<p>The ordering of the phases has significant impact on the
+quality of the produced code. In [Leve79a] two kinds of
+phase ordering problems are distinguished. If two techniques
+A and B both take away opportunities of each other, there is
+a &quot;negative&quot; ordering problem. If, on the other
+hand, both A and B introduce new optimization opportunities
+for each other, the problem is called &quot;positive&quot;.
+In the Global Optimizer the following interactions must be
+taken into account:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Inline Substitution (IL) may create new opportunities
+for most other techniques, so it should be run as early as
+possible</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Use Definition analysis (UD) may introduce opportunities
+for LV.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Strength Reduction may create opportunities for UD</p>
+</td>
+</table>
+
+<p>The optimizer has a default phase ordering, which can be
+changed by the user.</p>
+<a name="2.5. Structure of this document"></a>
+<h2>2.5. Structure of this document</h2>
+
+<p>The remaining chapters of this document each describe
+one phase of the optimizer. For every phase, we describe its
+task, its design, its implementation, and its source files.
+The latter two sections are intended to aid the maintenance
+of the optimizer and can be skipped by the initial
+reader.</p>
+<a name="2.6. References"></a>
+<h2>2.6. References</h2>
+
+<p>There are very few modern textbooks on optimization.
+Chapters 12, 13, and 14 of [Aho78a] are a good introduction
+to the subject. Wulf et. al. [Wulf75a] describe one specific
+optimizing (Bliss) compiler. Anklam et. al. [Ankl82a]
+discuss code generation and optimization in compilers for
+one specific machine (a Vax-11). Kirchgaesner et. al.
+[Kirc83a] present a brief description of many optimizations;
+the report also contains a lengthy (over 60 pages)
+bibliography.</p>
+
+<p>The number of articles on optimization is quite
+impressive. The Lowry and Medlock paper on the Fortran H
+compiler [Lowr69a] is a classical one. Other papers on
+global optimization are. [Faim80a, Perk79a, Harr79a,
+More79a, Mint79a] Freudenberger [Freu83a] describes an
+optimizer for a Very High Level Language (SETL). The
+Production-Quality Compiler-Compiler (PQCC) project uses
+very sophisticated compiler techniques, as described in.
+[Leve80a, Leve79a, Wulf80a]</p>
+
+<p>Several Ph.D. theses are dedicated to optimization.
+Davidson [Davi81a] outlines a machine-independent peephole
+optimizer that improves assembly code. Katkus [Katk73a]
+describes how efficient programs can be obtained at little
+cost by optimizing only a small part of a program.
+Photopoulos [Phot81a] discusses the idea of generating
+interpreted intermediate code as well as assembly code, to
+obtain programs that are both small and fast. Shaffer
+[Shaf78a] describes the theory of automatic subroutine
+generation. Leverett [Leve81a] deals with register
+allocation in the PQCC compilers.</p>
+
+<p>References to articles about specific optimization
+techniques will be given in later chapters.</p>
+<a name="3. The Intermediate Code and the IC phase"></a>
+<h2>3. The Intermediate Code and the IC phase</h2>
+
+<p>In this chapter the intermediate code of the EM global
+optimizer will be defined. The &rsquo;Intermediate Code
+construction&rsquo; phase (IC), which builds the initial
+intermediate code from EM Compact Assembly Language, will be
+described.</p>
+<a name="3.1. Introduction"></a>
+<h2>3.1. Introduction</h2>
+
+<p>The EM global optimizer is a multi pass program, hence
+there is a need for an intermediate code. Usually, programs
+in the Amsterdam Compiler Kit use the Compact Assembly
+Language format [Tane83a, section 11.2] for this purpose.
+Although this code has some convenient features, such as
+being compact, it is quite unsuitable in our case, because
+of a number of reasons. At first, the code lacks global
+information about whole procedures or whole basic blocks.
+Second, it uses identifiers (&rsquo;names&rsquo;) to bind
+defining and applied occurrences of procedures, data labels
+and instruction labels. Although this is usual in high level
+programming languages, it is awkward in an intermediate code
+that must be read many times. Each pass of the optimizer
+would have to incorporate an identifier look-up mechanism to
+associate a defining occurrence with each applied occurrence
+of an identifier. Finally, EM programs are used to declare
+blocks of bytes, rather than variables. A &rsquo;hol
+6&rsquo; instruction may be used to declare three 2-byte
+variables. Clearly, the optimizer wants to deal with
+variables, and not with rows of bytes.</p>
+
+<p>To overcome these problems, we have developed a new
+intermediate code. This code does not merely consist of the
+EM instructions, but also contains global information in the
+form of tables and graphs. Before describing the
+intermediate code we will first leap aside to outline the
+problems one generally encounters when trying to store
+complex data structures such as graphs outside the program,
+i.e. in a file. We trust this will enhance the
+comprehensibility of the intermediate code definition and
+the design and implementation of the IC phase.</p>
+<a name="3.2. Representation of complex data structures in a sequential file"></a>
+<h2>3.2. Representation of complex data structures in a sequential file</h2>
+
+<p>Most programmers are quite used to deal with complex
+data structures, such as arrays, graphs and trees. There are
+some particular problems that occur when storing such a data
+structure in a sequential file. We call data that is kept in
+main memory internal ,as opposed to external data that is
+kept in a file outside the program.</p>
+
+<p>We assume a simple data structure of a scalar type
+(integer, floating point number) has some known external
+representation. An array having elements of a scalar type
+can be represented externally easily, by successively
+representing its elements. The external representation may
+be preceded by a number, giving the length of the array.
+Now, consider a linear, singly linked list, the elements of
+which look like:</p>
+<pre>     record
+             data: scalar_type;
+             next: pointer_type;
+     end;
+</pre>
+
+<p>It is significant to note that the &quot;next&quot;
+fields of the elements only have a meaning within main
+memory. The field contains the address of some location in
+main memory. If a list element is written to a file in some
+program, and read by another program, the element will be
+allocated at a different address in main memory. Hence this
+address value is completely useless outside the program.</p>
+
+<p>One may represent the list by ignoring these
+&quot;next&quot; fields and storing the data items in the
+order they are linked. The &quot;next&quot; fields are
+represented <i>implicitly</i>. When the file is read again,
+the same list can be reconstructed. In order to know where
+the external representation of the list ends, it may be
+useful to put the length of the list in front of it.</p>
+
+<p>Note that arrays and linear lists have the same external
+representation.</p>
+
+<p>A doubly linked, linear list, with elements of the
+type:</p>
+<pre>     record
+             data: scalar_type;
+             next,
+             previous: pointer_type;
+     end
+</pre>
+
+<p>can be represented in precisely the same way. Both the
+&quot;next&quot; and the &quot;previous&quot; fields are
+represented implicitly.</p>
+
+<p>Next, consider a binary tree, the nodes of which have
+type:</p>
+<pre>     record
+             data: scalar_type;
+             left,
+             right: pointer_type;
+     end
+</pre>
+
+<p>Such a tree can be represented sequentially, by storing
+its nodes in some fixed order, e.g. prefix order. A special
+null data item may be used to denote a missing left or right
+son. For example, let the scalar type be integer, and let
+the null item be 0. Then the tree of fig. 3.1(a) can be
+represented as in fig. 3.1(b).</p>
+<pre>                             4
+                           /   \
+                         9      12
+                       /  \    /  \
+                     12    3   4   6
+                          / \  \  /
+                          8  1  5 1
+
+
+     Fig. 3.1(a) A binary tree
+
+
+
+
+     4 9 12 0 0 3 8 0 0 1 0 0 12 4 0 5 0 0 6 1 0 0 0
+
+
+     Fig. 3.1(b) Its sequential representation
+</pre>
+
+<p>We are still able to represent the pointer fields
+(&quot;left&quot; and &quot;right&quot;) implicitly.</p>
+
+<p>Finally, consider a general graph , where each node has
+a &quot;data&quot; field and pointer fields, with no
+restriction on where they may point to. Now we&rsquo;re at
+the end of our tale. There is no way to represent the
+pointers implicitly, like we did with lists and trees. In
+order to represent them explicitly, we use the following
+scheme. Every node gets an extra field, containing some
+unique number that identifies the node. We call this number
+its id. A pointer is represented externally as the id of the
+node it points to. When reading the file we use a table that
+maps an id to the address of its node. In general this table
+will not be completely filled in until we have read the
+entire external representation of the graph and allocated
+internal memory locations for every node. Hence we cannot
+reconstruct the graph in one scan. That is, there may be
+some pointers from node A to B, where B is placed after A in
+the sequential file than A. When we read the node of A we
+cannot map the id of B to the address of node B, as we have
+not yet allocated node B. We can overcome this problem if
+the size of every node is known in advance. In this case we
+can allocate memory for a node on first reference. Else, the
+mapping from id to pointer cannot be done while reading
+nodes. The mapping can be done either in an extra scan or at
+every reference to the node.</p>
+<a name="3.3. Definition of the intermediate code"></a>
+<h2>3.3. Definition of the intermediate code</h2>
+
+<p>The intermediate code of the optimizer consists of
+several components:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="32%">
+
+<p>the object table</p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="38%">
+
+<p>the procedure table</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p>the em code</p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="46%">
+
+<p>the control flow graphs</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="28%">
+
+<p>the loop table</p>
+</td>
+<td width="61%">
+</td>
+</table>
+
+<p>These components are described in the next sections. The
+syntactic structure of every component is described by a set
+of context free syntax rules, with the following
+conventions:</p>
+
+<p align=center><img src="grohtml-102725.png"></p>
+<a name="3.3.1. The object table"></a>
+<h2>3.3.1. The object table</h2>
+
+<p>EM programs declare blocks of bytes rather than (global)
+variables. A typical program may declare &rsquo;HOL
+7780&rsquo; to allocate space for 8 I/O buffers, 2 large
+arrays and 10 scalar variables. The optimizer wants to deal
+with objects like variables, buffers and arrays and
+certainly not with huge numbers of bytes. Therefore the
+intermediate code contains information about which global
+objects are used. This information can be obtained from an
+EM program by just looking at the operands of instruction
+such as LOE, LAE, LDE, STE, SDE, INE, DEE and ZRE.</p>
+
+<p>The object table consists of a list of datablock
+entries. Each such entry represents a declaration like HOL,
+BSS, CON or ROM. There are five kinds of datablock entries.
+The fifth kind, UNKNOWN, denotes a declaration in a
+separately compiled file that is not made available to the
+optimizer. Each datablock entry contains the type of the
+block, its size, and a description of the objects that
+belong to it. If it is a rom, it also contains a list of
+values given as arguments to the rom instruction, provided
+that this list contains only integer numbers. An object has
+an offset (within its datablock) and a size. The size need
+not always be determinable. Both datablock and object
+contain a unique identifying number (see previous section
+for their use).</p>
+<pre>     syntax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+
+<p align=center><img src="grohtml-102726.png"></p>
+
+<p>A data block has only one flag: &quot;external&quot;,
+indicating whether the data label is externally visible. The
+syntax for &quot;argument&quot; will be given later on (see
+em_text).</p>
+<a name="3.3.2. The procedure table"></a>
+<h2>3.3.2. The procedure table</h2>
+
+<p>The procedure table contains global information about
+all procedures that are made available to the optimizer and
+that are needed by the EM program. (Library units may not be
+needed, see section 3.5). The table has one entry for every
+procedure.</p>
+<pre>     syntax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+
+<p align=center><img src="grohtml-102727.png"></p>
+
+<p>The number of bytes of formal parameters accessed by a
+procedure is determined by the front ends and passed via a
+message (parameter message) to the optimizer. If the front
+end is not able to determine this number (e.g. the parameter
+may be an array of dynamic size or the procedure may have a
+variable number of arguments) the attribute contains the
+value &rsquo;UNKNOWN_SIZE&rsquo;.<br>
+A procedure has the following flags:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>external: true if the proc. is externally visible</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>bodyseen: true if its code is available as EM text</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>calunknown: true if it calls a procedure that has its
+bodyseen flag not set</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>environ: true if it uses or changes a (non-global)
+variable in a lexically enclosing procedure</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>lpi: true if is used as operand of an lpi instruction,
+so it may be called indirect</p>
+</td>
+</table>
+
+<p>The change and use attributes both have one flag:
+&quot;indirect&quot;, indicating whether the procedure does
+a &rsquo;use indirect&rsquo; or a &rsquo;store
+indirect&rsquo; (indirect means through a pointer).</p>
+<a name="3.3.3. The EM text"></a>
+<h2>3.3.3. The EM text</h2>
+
+<p>The EM text contains the EM instructions. Every EM
+instruction has an operation code (opcode) and 0 or 1
+operands. EM pseudo instructions can have more than 1
+operand. The opcode is just a small (8 bit) integer.</p>
+
+<p>There are several kinds of operands, which we will refer
+to as types. Many EM instructions can have more than one
+type of operand. The types and their encodings in Compact
+Assembly Language are discussed extensively in. [Tane83a,
+section 11.2] Of special interest is the way numeric values
+are represented. Of prime importance is the machine
+independency of the representation. Ultimately, one could
+store every integer just as a string of the characters
+&rsquo;0&rsquo; to &rsquo;9&rsquo;. As doing arithmetic on
+strings is awkward, Compact Assembly Language allows several
+alternatives. The main idea is to look at the value of the
+integer. Integers that fit in 16, 32 or 64 bits are
+represented as a row of resp. 2, 4 and 8 bytes, preceded by
+an indication of how many bytes are used. Longer integers
+are represented as strings; this is only allowed within
+pseudo instructions, however. This concept works very well
+for target machines with reasonable word sizes. At present,
+most ACK software cannot be used for word sizes higher than
+32 bits, although the handles for using larger word sizes
+are present in the design of the EM code. In the
+intermediate code we essentially use the same ideas. We
+allow three representations of integers.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>integers that fit in a short are represented as a
+short</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>integers that fit in a long but not in a short are
+represented as longs</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>all remaining integers are represented as strings (only
+allowed in pseudos).</p>
+</td>
+</table>
+
+<p>The terms short and long are defined in [Ritc78a,
+section 4] and depend only on the source machine (i.e. the
+machine on which ACK runs), not on the target machines. For
+historical reasons a long will often be called an
+offset.</p>
+
+<p>Operands can also be instruction labels, objects or
+procedures. Instruction labels are denoted by a label
+identifier, which can be distinguished from a normal
+identifier.</p>
+
+<p>The operand of a pseudo instruction can be a list of
+arguments. Arguments can have the same type as operands,
+except for the type short, which is not used for arguments.
+Furthermore, an argument can be a string or a string
+representation of a signed integer, unsigned integer or
+floating point number. If the number of arguments is not
+fully determined by the pseudo instruction (e.g. a ROM
+pseudo can have any number of arguments), then the list is
+terminated by a special argument of type CEND.</p>
+<pre>     syntax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+
+<p align=center><img src="grohtml-102728.png"></p>
+<a name="3.3.4. The control flow graphs"></a>
+<h2>3.3.4. The control flow graphs</h2>
+
+<p>Each procedure can be divided into a number of basic
+blocks. A basic block is a piece of code with no jumps in,
+except at the beginning, and no jumps out, except at the
+end.</p>
+
+<p>Every basic block has a set of successors, which are
+basic blocks that can follow it immediately in the dynamic
+execution sequence. The predecessors are the basic blocks of
+which this one is a successor. The successor and predecessor
+attributes of all basic blocks of a single procedure are
+said to form the control flow graph of that procedure.</p>
+
+<p>Another important attribute is the immediate dominator.
+A basic block B dominates a block C if every path in the
+graph from the procedure entry block to C goes through B.
+The immediate dominator of C is the closest dominator of C
+on any path from the entry block. (Note that the dominator
+relation is transitive, so the immediate dominator is well
+defined.)</p>
+
+<p>A basic block also has an attribute containing the
+identifiers of every loop that the block belongs to (see
+next section for loops).</p>
+<pre>     syntax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+
+<p align=center><img src="grohtml-102729.png"></p>
+
+<p>The flag bits can have the values &rsquo;firm&rsquo; and
+&rsquo;strong&rsquo;, which are explained below.</p>
+<a name="3.3.5. The loop tables"></a>
+<h2>3.3.5. The loop tables</h2>
+
+<p>Every procedure has an associated loop table containing
+information about all the loops in the procedure. Loops can
+be detected by a close inspection of the control flow graph.
+The main idea is to look for two basic blocks, B and C, for
+which the following holds:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="42%">
+
+<p>B is a successor of C</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="42%">
+
+<p>B is a dominator of C</p>
+</td>
+<td width="47%">
+</td>
+</table>
+
+<p>B is called the loop entry and C is called the loop end.
+Intuitively, C contains a jump backwards to the beginning of
+the loop (B).</p>
+
+<p>A loop L1 is said to be nested within loop L2 if all
+basic blocks of L1 are also part of L2. It is important to
+note that loops could originally be written as a well
+structured for -or while loop or as a messy goto loop. Hence
+loops may partly overlap without one being nested inside the
+other. The nesting level of a loop is the number of loops in
+which it is nested (so it is 0 for an outermost loop). The
+details of loop detection will be discussed later.</p>
+
+<p>It is often desirable to know whether a basic block gets
+executed during every iteration of a loop. This leads to the
+following definitions:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A basic block B of a loop L is said to be a <i>firm</i>
+block of L if B is executed on all successive iterations of
+L, with the only possible exception of the last
+iteration.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A basic block B of a loop L is said to be a
+<i>strong</i> block of L if B is executed on all successive
+iterations of L.</p>
+</td>
+</table>
+
+<p>Note that a strong block is also a firm block. If a
+block is part of a conditional statement, it is neither
+strong nor firm, as it may be skipped during some iterations
+(see Fig. 3.2).</p>
+<pre>     loop
+            if cond1 then
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>... -- this code will not</p>
+<td width="19%"></td>
+<td width="10%">
+
+<p>-- result in a firm or strong block</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+
+<p>end if;<br>
+... -- strong (always executed)<br>
+exit when cond2;<br>
+... -- firm (not executed on last iteration).<br>
+end loop;</p>
+
+<p>Fig. 3.2 Example of firm and strong block</p>
+<pre>     syntax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+
+<p align=center><img src="grohtml-1027210.png"></p>
+<a name="3.4. External representation of the intermediate code"></a>
+<h2>3.4. External representation of the intermediate code</h2>
+
+<p>The syntax of the intermediate code was given in the
+previous section. In this section we will make some remarks
+about the representation of the code in sequential
+files.</p>
+
+<p>We use sequential files in order to avoid the
+bookkeeping of complex file indices. As a consequence of
+this decision we can&rsquo;t store all components of the
+intermediate code in one file. If a phase wishes to change
+some attribute of a procedure, or wants to add or delete
+entire procedures (inline substitution may do the latter),
+the procedure table will only be fully updated after the
+entire EM text has been scanned. Yet, the next phase
+undoubtedly wants to read the procedure table before it
+starts working on the EM text. Hence there is an ordering
+problem, which can be solved easily by putting the procedure
+table in a separate file. Similarly, the data block table is
+kept in a file of its own.</p>
+
+<p>The control flow graphs (CFGs) could be mixed with the
+EM text. Rather, we have chosen to put them in a separate
+file too. The control flow graph file should be regarded as
+a file that imposes some structure on the EM-text file, just
+as an overhead sheet containing a picture of a Flow Chart
+may be put on an overhead sheet containing statements. The
+loop tables are also put in the CFG file. A loop imposes an
+extra structure on the CFGs and hence on the EM text. So
+there are four files:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="32%">
+
+<p>the EM-text file</p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="48%">
+
+<p>the procedure table file</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="42%">
+
+<p>the object table file</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p>the CFG and loop tables file</p>
+</td>
+<td width="33%">
+</td>
+</table>
+
+<p>Every table is preceded by its length, in order to tell
+where it ends. The CFG file also contains the number of
+instructions of every basic block, indicating which part of
+the EM text belongs to that block.</p>
+<pre>     syntax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+
+<p align=center><img src="grohtml-1027211.png"></p>
+<a name="3.5. The Intermediate Code construction phase"></a>
+<h2>3.5. The Intermediate Code construction phase</h2>
+
+<p>The first phase of the global optimizer, called IC,
+constructs a major part of the intermediate code. To be
+specific, it produces:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p>the EM text</p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="32%">
+
+<p>the object table</p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="54%">
+
+<p>part of the procedure table</p>
+</td>
+<td width="35%">
+</td>
+</table>
+
+<p>The calling, change and use attributes of a procedure
+and all its flags except the external and bodyseen flags are
+computed by the next phase (Control Flow phase).</p>
+
+<p>As explained before, the intermediate code does not
+contain any names of variables or procedures. The normal
+identifiers are replaced by identifying numbers. Yet, the
+output of the global optimizer must contain normal
+identifiers, as this output is in Compact Assembly Language
+format. We certainly want all externally visible names to be
+the same in the input as in the output, because the
+optimized EM module may be a library unit, used by other
+modules. IC dumps the names of all procedures and data
+labels on two files:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the procedure dump file, containing tuples (P_ID,
+procedure name)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the data dump file, containing tuples (D_ID, data label
+name)</p>
+</td>
+</table>
+
+<p>The names of instruction labels are not dumped, as they
+are not visible outside the procedure in which they are
+defined.</p>
+
+<p>The input to IC consists of one or more files. Each file
+is either an EM module in Compact Assembly Language format,
+or a Unix archive file (library) containing such modules. IC
+only extracts those modules from a library that are needed
+somehow, just as a linker does. It is advisable to present
+as much code of the EM program as possible to the optimizer,
+although it is not required to present the whole program. If
+a procedure is called somewhere in the EM text, but its body
+(text) is not included in the input, its bodyseen flag in
+the procedure table will still be off. Whenever such a
+procedure is called, we assume the worst case for
+everything; it will change and use all variables it has
+access to, it will call every procedure etc.</p>
+
+<p>Similarly, if a data label is used but not defined, the
+PSEUDO attribute in its data block will be set to
+UNKNOWN.</p>
+<a name="3.5.1. Implementation"></a>
+<h2>3.5.1. Implementation</h2>
+
+<p>Part of the code for the EM Peephole Optimizer [b] has
+been used for IC. Especially the routines that read and
+unravel Compact Assembly Language and the identifier lookup
+mechanism have been used. New code was added to recognize
+objects, build the object and procedure tables and to output
+the intermediate code.</p>
+
+<p>IC uses singly linked linear lists for both the
+procedure and object table. Hence there are no limits on the
+size of such a table (except for the trivial fact that it
+must fit in main memory). Both tables are outputted after
+all EM code has been processed. IC reads the EM text of one
+entire procedure at a time, processes it and appends the
+modified code to the EM text file. EM code is represented
+internally as a doubly linked linear list of EM
+instructions.</p>
+
+<p>Objects are recognized by looking at the operands of
+instructions that reference global data. If we come across
+the instructions:</p>
+
+<p align=center><img src="grohtml-1027212.png"></p>
+
+<p>we conclude that the data block preceded by the data
+label X contains an object at offset 6 of size twice the
+word size, and an object at offset 20 of unknown size.</p>
+
+<p>A data block entry of the object table is allocated at
+the first reference to a data label. If this reference is a
+defining occurrence or a INA pseudo instruction, the label
+is not externally visible [Tane83a, section 11.1.4.3] In
+this case, the external flag of the data block is turned
+off. If the first reference is an applied occurrence or a
+EXA pseudo instruction, the flag is set. We record this
+information, because the optimizer may change the order of
+defining and applied occurrences. The INA and EXA pseudos
+are removed from the EM text. They may be regenerated by the
+last phase of the optimizer.</p>
+
+<p>Similar rules hold for the procedure table and the INP
+and EXP pseudos.</p>
+<a name="3.5.2. Source files of IC"></a>
+<h2>3.5.2. Source files of IC</h2>
+
+<p>The source files of IC consist of the files ic.c, ic.h
+and several packages. ic.h contains type definitions, macros
+and variable declarations that may be used by ic.c and by
+every package. ic.c contains the definitions of these
+variables, the procedure main and some high level I/O
+routines used by main.</p>
+
+<p>Every package xxx consists of two files. ic_xxx.h
+contains type definitions, macros, variable declarations and
+procedure declarations that may be used by every .c file
+that includes this .h file. The file ic_xxx.c provides the
+definitions of these variables and the implementation of the
+declared procedures. IC uses the following packages:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>lookup:</p>
+</td>
+<td width="22%"></td>
+<td width="64%">
+
+<p>procedures that loop up procedure, data label and
+instruction label names; procedures to dump the procedure
+and data label names.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>lib:</p>
+</td>
+<td width="28%"></td>
+<td width="64%">
+
+<p>one procedure that gets the next useful input module;
+while scanning archives, it skips unnecessary modules.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>aux:</p>
+</td>
+<td width="28%"></td>
+<td width="54%">
+
+<p>several auxiliary routines.</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>io:</p>
+</td>
+<td width="30%"></td>
+<td width="64%">
+
+<p>low-level I/O routines that unravel the Compact Assembly
+Language.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>put:</p>
+</td>
+<td width="28%"></td>
+<td width="64%">
+
+<p>routines that output the intermediate code</p>
+</td>
+</table>
+<a name="4. The Control Flow Phase"></a>
+<h2>4. The Control Flow Phase</h2>
+
+<p>In the previous chapter we described the intermediate
+code of the global optimizer. We also specified which part
+of this code was constructed by the IC phase of the
+optimizer. The Control Flow Phase (<i>CF</i>) does the
+remainder of the job, i.e. it determines:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="46%">
+
+<p>the control flow graphs</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="30%">
+
+<p>the loop tables</p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the calling, change and use attributes of the procedure
+table entries</p>
+</td>
+</table>
+
+<p>CF operates on one procedure at a time. For every
+procedure it first reads the EM instructions from the
+EM-text file and groups them into basic blocks. For every
+basic block, its successors and predecessors are determined,
+resulting in the control flow graph. Next, the immediate
+dominator of every basic block is computed. Using these
+dominators, any loop in the procedure is detected. Finally,
+interprocedural analysis is done, after which we will know
+the global effects of every procedure call on its
+environment.</p>
+
+<p>CF uses the same internal data structures for the
+procedure table and object table as IC.</p>
+<a name="4.1. Partitioning into basic blocks"></a>
+<h2>4.1. Partitioning into basic blocks</h2>
+
+<p>With regard to flow of control, we distinguish three
+kinds of EM instructions: jump instructions, instruction
+label definitions and normal instructions. Jump instructions
+are all conditional or unconditional branch instructions,
+the case instructions (CSA/CSB) and the RET (return)
+instruction. A procedure call (CAL) is not considered to be
+a jump. A defining occurrence of an instruction label is
+regarded as an EM instruction.</p>
+
+<p>An instruction starts a new basic block, in any of the
+following cases:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>It is the first instruction of a procedure</p>
+</td>
+<td width="5%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>It is the first of a list of instruction label defining
+occurrences</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p>It follows a jump</p>
+</td>
+<td width="55%">
+</td>
+</table>
+
+<p>If there are several consecutive instruction labels
+(which is highly unusual), all of them are put in the same
+basic block. Note that several cases may overlap, e.g. a
+label definition at the beginning of a procedure or a label
+following a jump.</p>
+
+<p>A simple Finite State Machine is used to model the above
+rules. It also recognizes the end of a procedure, marked by
+an END pseudo. The basic blocks are stored internally as a
+doubly linked linear list. The blocks are linked in textual
+order. Every node of this list has the attributes described
+in the previous chapter (see syntax rule for basic_block).
+Furthermore, every node contains a pointer to its EM
+instructions, which are represented internally as a linear,
+doubly linked list, just as in the IC phase. However,
+instead of one list per procedure (as in IC) there is now
+one list per basic block.</p>
+
+<p>On the fly, a table is build that maps every label
+identifier to the label definition instruction. This table
+is used for computing the control flow. The table is stored
+as a dynamically allocated array. The length of the array is
+the number of labels of the current procedure; this value
+can be found in the procedure table, where it was stored by
+IC.</p>
+<a name="4.2. Control Flow"></a>
+<h2>4.2. Control Flow</h2>
+
+<p>A <i>successor</i> of a basic block B is a block C that
+can be executed immediately after B. C is said to be a
+<i>predecessor</i> of B. A block ending with a RET
+instruction has no successors. Such a block is called a
+<i>return block</i>. Any block that has no predecessors
+cannot be executed at all (i.e. it is unreachable), unless
+it is the first block of a procedure, called the
+<i>procedure entry block</i>.</p>
+
+<p>Internally, the successor and predecessor attributes of
+a basic block are stored as <i>sets</i>. Alternatively, one
+may regard all these sets of all basic blocks as a
+conceptual <i>graph</i>, in which there is an edge from B to
+C if C is in the successor set of B. We call this conceptual
+graph the <i>Control Flow Graph</i>.</p>
+
+<p>The only successor of a basic block ending on an
+unconditional branch instruction is the block that contains
+the label definition of the target of the jump. The target
+instruction can be found via the LAB_ID that is the operand
+of the jump instruction, by using the label-map table
+mentioned above. If the last instruction of a block is a
+conditional jump, the successors are the target block and
+the textually next block. The last instruction can also be a
+case jump instruction (CSA or CSB). We then analyze the case
+descriptor, to find all possible target instructions and
+their associated blocks. We require the case descriptor to
+be allocated in a ROM, so it cannot be changed dynamically.
+A case jump via an alterable descriptor could in principle
+go to any label in the program. In the presence of such an
+uncontrolled jump, hardly any optimization can be done. We
+do not expect any front end to generate such a descriptor,
+however, because of the controlled nature of case statements
+in high level languages. If the basic block does not end in
+a jump instruction, its only successor is the textually next
+block.</p>
+<a name="4.3. Immediate dominators"></a>
+<h2>4.3. Immediate dominators</h2>
+
+<p>A basic block B dominates a block C if every path in the
+control flow graph from the procedure entry block to C goes
+through B. The immediate dominator of C is the closest
+dominator of C on any path from the entry block. See also
+[Aho78a, section 13.1.]</p>
+
+<p>There are a number of algorithms to compute the
+immediate dominator relation.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Purdom and Moore give an algorithm that is easy to
+program and easy to describe (although the description they
+give is unreadable; it is given in a very messy Algol60
+program full of gotos). [Purd72a]</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Aho and Ullman present a bitvector algorithm, which is
+also easy to program and to understand. (See [Aho78a,
+section 13.1.]).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>3</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Lengauer and Tarjan introduce a fast algorithm that is
+hard to understand, yet remarkably easy to implement.
+[Leng79a]</p>
+</td>
+</table>
+
+<p>The Purdom-Moore algorithm is very slow if the number of
+basic blocks in the flow graph is large. The Aho-Ullman
+algorithm in fact computes the dominator relation, from
+which the immediate dominator relation can be computed in
+time quadratic to the number of basic blocks, worst case.
+The storage requirement is also quadratic to the number of
+blocks. The running time of the third algorithm is
+proportional to:</p>
+<pre>     (number of edges in the graph) * log(number of blocks).
+</pre>
+
+<p>We have chosen this algorithm because it is fast (as
+shown by experiments done by Lengauer and Tarjan), it is
+easy to program and requires little data space.</p>
+<a name="4.4. Loop detection"></a>
+<h2>4.4. Loop detection</h2>
+
+<p>Loops are detected by using the loop construction
+algorithm of. [Aho78a, section 13.1.] This algorithm uses
+<i>back edges</i>. A back edge is an edge from B to C in the
+CFG, whose head (C) dominates its tail (B). The loop
+associated with this back edge consists of C plus all nodes
+in the CFG that can reach B without going through C.</p>
+
+<p>As an example of how the algorithm works, consider the
+piece of program of Fig. 4.1. First just look at the program
+and try to see what part of the code constitutes the
+loop.</p>
+<pre>     loop
+        if cond then                       1
+           -- lots of simple
+           -- assignment
+           -- statements              2          3
+           exit; -- exit loop
+        else
+           S; -- one statement
+        end if;
+     end loop;
+
+
+     Fig. 4.1 A misleading loop
+</pre>
+
+<p>Although a human being may be easily deceived by the
+brackets &quot;loop&quot; and &quot;end loop&quot;, the loop
+detection algorithm will correctly reply that only the test
+for &quot;cond&quot; and the single statement in the
+false-part of the if statement are part of the loop! The
+statements in the true-part only get executed once, so there
+really is no reason at all to say they&rsquo;re part of the
+loop too. The CFG contains one back edge,
+&quot;3-&gt;1&quot;. As node 3 cannot be reached from node
+2, the latter node is not part of the loop.</p>
+
+<p>A source of problems with the algorithm is the fact that
+different back edges may result in the same loop. Such an
+ill-structured loop is called a <i>messy</i> loop. After a
+loop has been constructed, it is checked if it is really a
+new loop.</p>
+
+<p>Loops can partly overlap, without one being nested
+inside the other. This is the case in the program of Fig.
+4.2.</p>
+<pre>     1:                              1
+        S1;
+     2:
+        S2;                          2
+        if cond then
+           goto 4;
+        S3;                     3         4
+        goto 1;
+     4:
+        S4;
+        goto 1;
+
+
+     Fig. 4.2 Partly overlapping loops
+</pre>
+
+<p>There are two back edges &quot;3-&gt;1&quot; and
+&quot;4-&gt;1&quot;, resulting in the loops {1,2,3} and
+{1,2,4}. With every basic block we associate a set of all
+loops it is part of. It is not sufficient just to record its
+most enclosing loop.</p>
+
+<p>After all loops of a procedure are detected, we
+determine the nesting level of every loop. Finally, we find
+all strong and firm blocks of the loop. If the loop has only
+one back edge (i.e. it is not messy), the set of firm blocks
+consists of the head of this back edge and its dominators in
+the loop (including the loop entry block). A firm block is
+also strong if it is not a successor of a block that may
+exit the loop; a block may exit a loop if it has an
+(immediate) successor that is not part of the loop. For
+messy loops we do not determine the strong and firm blocks.
+These loops are expected to occur very rarely.</p>
+<a name="4.5. Interprocedural analysis"></a>
+<h2>4.5. Interprocedural analysis</h2>
+
+<p>It is often desirable to know the effects a procedure
+call may have. The optimization below is only possible if we
+know for sure that the call to P cannot change A.</p>
+
+<p align=center><img src="grohtml-1027213.png"></p>
+
+<p>Although it is not possible to predict exactly all the
+effects a procedure call has, we may determine a kind of
+upper bound for it. So we compute all variables that may be
+changed by P, although they need not be changed at every
+invocation of P. We can get hold of this set by just looking
+at all assignment (store) instructions in the body of P. EM
+also has a set of <i>indirect</i> assignment instructions,
+i.e. assignment through a pointer variable. In general, it
+is not possible to determine which variable is affected by
+such an assignment. In these cases, we just record the fact
+that P does an indirect assignment. Note that this does not
+mean that all variables are potentially affected, as the
+front ends may generate messages telling that certain
+variables can never be accessed indirectly. We also set a
+flag if P does a use (load) indirect. Note that we only have
+to look at <i>global</i> variables. If P changes or uses any
+of its locals, this has no effect on its environment. Local
+variables of a lexically enclosing procedure can only be
+accessed indirectly.</p>
+
+<p>A procedure P may of course call another procedure. To
+determine the effects of a call to P, we also must know the
+effects of a call to the second procedure. This second one
+may call a third one, and so on. Effectively, we need to
+compute the <i>transitive closure</i> of the effects. To do
+this, we determine for every procedure which other
+procedures it calls. This set is the &quot;calling&quot;
+attribute of a procedure. One may regard all these sets as a
+conceptual graph, in which there is an edge from P to Q if Q
+is in the calling set of P. This graph will be referred to
+as the <i>call graph</i>. (Note the resemblance with the
+control flow graph).</p>
+
+<p>We can detect which procedures are called by P by
+looking at all CAL instructions in its body. Unfortunately,
+a procedure may also be called indirectly, via a CAI
+instruction. Yet, only procedures that are used as operand
+of an LPI instruction can be called indirect, because this
+is the only way to take the address of a procedure. We
+determine for every procedure whether it does a CAI
+instruction. We also build a set of all procedures used as
+operand of an LPI.</p>
+
+<p>After all procedures have been processed (i.e. all CFGs
+are constructed, all loops are detected, all procedures are
+analyzed to see which variables they may change, which
+procedures they call, whether they do a CAI or are used in
+an LPI) the transitive closure of all interprocedural
+information is computed. During the same process, the
+calling set of every procedure that uses a CAI is extended
+with the above mentioned set of all procedures that can be
+called indirect.</p>
+<a name="4.6. Source files"></a>
+<h2>4.6. Source files</h2>
+
+<p>The sources of CF are in the following files and
+packages:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>cf.h:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>declarations of global variables and data structures</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>cf.c:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>the routine main; interprocedural analysis; transitive
+closure</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>succ:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>control flow (successor and predecessor)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>idom:</p>
+</td>
+<td width="18%"></td>
+<td width="40%">
+
+<p>immediate dominators</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>loop:</p>
+</td>
+<td width="18%"></td>
+<td width="28%">
+
+<p>loop detection</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>get:</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>read object and procedure table; read EM text and
+partition it into basic blocks</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>put:</p>
+</td>
+<td width="20%"></td>
+<td width="60%">
+
+<p>write tables, CFGs and EM text</p>
+</td>
+<td width="11%">
+</td>
+</table>
+<a name="5. Inline substitution"></a>
+<h2>5. Inline substitution</h2>
+<a name="5.1. Introduction"></a>
+<h2>5.1. Introduction</h2>
+
+<p>The Inline Substitution technique (IL) tries to decrease
+the overhead associated with procedure calls (invocations).
+During a procedure call, several actions must be undertaken
+to set up the right environment for the called procedure.
+[John81a] On return from the procedure, most of these
+effects must be undone. This entire process introduces
+significant costs in execution time as well as in object
+code size.</p>
+
+<p>The inline substitution technique replaces some of the
+calls by the modified body of the called procedure, hence
+eliminating the overhead. Furthermore, as the calling and
+called procedure are now integrated, they can be optimized
+together, using other techniques of the optimizer. This
+often leads to extra opportunities for optimization
+[Ball79a, Cart77a, Sche77a]</p>
+
+<p>An inline substitution of a call to a procedure P
+increases the size of the program, unless P is very small or
+P is called only once. In the latter case, P can be
+eliminated. In practice, procedures that are called only
+once occur quite frequently, due to the introduction of
+structured programming. (Carter [Cart82a] states that almost
+50% of the Pascal procedures he analyzed were called just
+once).</p>
+
+<p>Scheifler [Sche77a] has a more general view of inline
+substitution. In his model, the program under consideration
+is allowed to grow by a certain amount, i.e. code size is
+sacrificed to speed up the program. The above two cases are
+just special cases of his model, obtained by setting the
+size-change to (approximately) zero. He formulates the
+substitution problem as follows:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>&quot;Given a program, a subset of all invocations, a
+maximum program size, and a maximum procedure size, find a
+sequence of substitutions that minimizes the expected
+execution time.&quot;</p>
+</td>
+</table>
+
+<p>Scheifler shows that this problem is NP-complete
+[Aho74a, chapter 10] by reduction to the Knapsack Problem.
+Heuristics will have to be used to find a near-optimal
+solution.</p>
+
+<p>In the following chapters we will extend
+Scheifler&rsquo;s view and adapt it to the EM Global
+Optimizer. We will first describe the transformations that
+have to be applied to the EM text when a call is substituted
+in line. Next we will examine in which cases inline
+substitution is not possible or desirable. Heuristics will
+be developed for chosing a good sequence of substitutions.
+These heuristics make no demand on the user (such as making
+profiles [Sche77a] or giving pragmats [Ichb83a, section
+6.3.2]), although the model could easily be extended to use
+such information. Finally, we will discuss the
+implementation of the IL phase of the optimizer.</p>
+
+<p>We will often use the term inline expansion as a synonym
+of inline substitution.<br>
+The inverse technique of procedure abstraction (automatic
+subroutine generation) [Shaf78a] will not be discussed in
+this report.</p>
+<a name="5.2. Parameters and local variables."></a>
+<h2>5.2. Parameters and local variables.</h2>
+
+<p>In the EM calling sequence, the calling procedure pushes
+its parameters on the stack before doing the CAL. The called
+routine first saves some status information on the stack and
+then allocates space for its own locals (also on the stack).
+Usually, one special purpose register, the Local Base (LB)
+register, is used to access both the locals and the
+parameters. If memory is highly segmented, the stack frames
+of the caller and the callee may be allocated in different
+fragments; an extra Argument Base (AB) register is used in
+this case to access the actual parameters. See 4.2 of
+[Tane83a] for further details.</p>
+
+<p>If a procedure call is expanded in line, there are two
+problems:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>No stack frame will be allocated for the called
+procedure; we must find another place to put its locals.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>The LB register cannot be used to access the actual
+parameters; as the CAL instruction is deleted, the LB will
+still point to the local base of the <i>calling</i>
+procedure.</p>
+</td>
+</table>
+
+<p>The local variables of the called procedure will be put
+in the stack frame of the calling procedure, just after its
+own locals. The size of the stack frame of the calling
+procedure will be increased during its entire lifetime.
+Therefore our model will allow a limit to be set on the
+number of bytes for locals that the called procedure may
+have (see next section).</p>
+
+<p>There are several alternatives to access the parameters.
+An actual parameter may be any auxiliary expression, which
+we will refer to as the <i>actual parameter expression</i>.
+The value of this expression is stored in a location on the
+stack (see above), the <i>parameter location</i>.<br>
+The alternatives for accessing parameters are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>save the value of the stackpointer at the point of the
+CAL in a temporary variable X; this variable can be used to
+simulate the AB register, i.e. parameter locations are
+accessed via an offset to the value of X.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>create a new temporary local variable T for the
+parameter (in the stack frame of the caller); every access
+to the parameter location must be changed into an access to
+T.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>do not evaluate the actual parameter expression before
+the call; instead, substitute this expression for every use
+of the parameter location.</p>
+</td>
+</table>
+
+<p>The first method may be expensive if X is not put in a
+register. We will not use this method. The time required to
+evaluate and access the parameters when the second method is
+used will not differ much from the normal calling sequence
+(i.e. not in line call). It is not expensive, but there are
+no extra savings either. The third method is essentially the
+&rsquo;by name&rsquo; parameter mechanism of Algol60. If the
+actual parameter is just a numeric constant, it is
+advantageous to use it. Yet, there are several circumstances
+under which it cannot or should not be used. We will deal
+with this in the next section.<br>
+In general we will use the third method, if it is possible
+and desirable. Such parameters will be called <i>in line
+parameters</i>. In all other cases we will use the second
+method.</p>
+<a name="5.3. Feasibility and desirability analysis"></a>
+<h2>5.3. Feasibility and desirability analysis</h2>
+
+<p>Feasibility and desirability analysis of in line
+substitution differ somewhat from most other techniques.
+Usually, much effort is needed to find a feasible
+opportunity for optimization (e.g. a redundant
+subexpression). Desirability analysis then checks if it is
+really advantageous to do the optimization. For IL,
+opportunities are easy to find. To see if an in line
+expansion is desirable will not be hard either. Yet, the
+main problem is to find the most desirable ones. We will
+deal with this problem later and we will first attend
+feasibility and desirability analysis.</p>
+
+<p>There are several reasons why a procedure invocation
+cannot or should not be expanded in line.</p>
+
+<p>A call to a procedure P cannot be expanded in line in
+any of the following cases:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>The body of P is not available as EM text. Clearly,
+there is no way to do the substitution.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P, or any procedure called by P (transitively), follows
+the chain of statically enclosing procedures (via a LXL or
+LXA instruction) or follows the chain of dynamically
+enclosing procedures (via a DCH). If the call were expanded
+in line, one level would be removed from the chains, leading
+to total chaos. This chaos could be solved by patching up
+every LXL, LXA or DCH in all procedures that could be part
+of the chains, but this is hard to implement.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P, or any procedure called by P (transitively), calls a
+procedure whose body is not available as EM text. The
+unknown procedure may use an LXL, LXA or DCH. However, in
+several languages a separately compiled procedure has no
+access to the static or dynamic chain. In this case this
+point does not apply.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P, or any procedure called by P (transitively), uses the
+LPB instruction, which converts a local base to an argument
+base; as the locals and parameters are stored in a
+non-standard way (differing from the normal EM calling
+sequence) this instruction would yield incorrect
+results.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>The total number of bytes of the parameters of P is not
+known. P may be a procedure with a variable number of
+parameters or may have an array of dynamic size as value
+parameter.</p>
+</td>
+</table>
+
+<p>It is undesirable to expand a call to a procedure P in
+line in any of the following cases:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P is large, i.e. the number of EM instructions of P
+exceeds some threshold. The expanded code would be large
+too. Furthermore, several programs in ACK, including the
+global optimizer itself, may run out of memory if they they
+have to run in a small address space and are provided very
+large procedures. The threshold may be set to infinite, in
+which case this point does not apply.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P has many local variables. All these variables would
+have to be allocated in the stack frame of the calling
+procedure.</p>
+</td>
+</table>
+
+<p>If a call may be expanded in line, we have to decide how
+to access its parameters. In the previous section we stated
+that we would use in line parameters whenever possible and
+desirable. There are several reasons why a parameter cannot
+or should not be expanded in line.</p>
+
+<p>No parameter of a procedure P can be expanded in line,
+in any of the following cases:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P, or any procedure called by P (transitively), does a
+store-indirect or a use-indirect (i.e. through a pointer).
+However, if the front-end has generated messages telling
+that certain parameters can not be accessed indirectly,
+those parameters may be expanded in line.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P, or any procedure called by P (transitively), calls a
+procedure whose body is not available as EM text. The
+unknown procedure may do a store-indirect or a use-indirect.
+However, the same remark about front-end messages as for 1.
+holds here.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>The address of a parameter location is taken (via a
+LAL). In the normal calling sequence, all parameters are
+stored sequentially. If the address of one parameter
+location is taken, the address of any other parameter
+location can be computed from it. Hence we must put every
+parameter in a temporary location; furthermore, all these
+locations must be in the same order as for the normal
+calling sequence.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P has overlapping parameters; for example, it uses the
+parameter at offset 10 both as a 2 byte and as a 4 byte
+parameter. Such code may be produced by the front ends if
+the formal parameter is of some record type with
+variants.</p>
+</td>
+</table>
+
+<p>Sometimes a specific parameter must not be expanded in
+line.<br>
+An actual parameter expression cannot be expanded in line in
+any of the following cases:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P stores into the parameter location. Even if the actual
+parameter expression is a simple variable, it is incorrect
+to change the &rsquo;store into formal&rsquo; into a
+&rsquo;store into actual&rsquo;, because of the parameter
+mechanism used. In Pascal, the following expansion is
+incorrect:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<pre>     procedure p (x:integer);
+     begin
+        x := 20;
+     end;
+     ...
+     a := 10;                a := 10;
+     p(a);        ---&gt;       a := 20;
+     write(a);               write(a);
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>P changes any of the operands of the actual parameter
+expression. If the expression is expanded and evaluated
+after the operand has been changed, the wrong value will be
+used.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>The actual parameter expression has side effects. It
+must be evaluated only once, at the place of the call.</p>
+</td>
+</table>
+
+<p>It is undesirable to expand an actual parameter in line
+in the following case:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="2%"></td>
+<td width="94%">
+
+<p>The parameter is used more than once (dynamically) and
+the actual parameter expression is not just a simple
+variable or constant.</p>
+</td>
+</table>
+<a name="5.4. Heuristic rules"></a>
+<h2>5.4. Heuristic rules</h2>
+
+<p>Using the information described in the previous section,
+we can find all calls that can be expanded in line, and for
+which this expansion is desirable. In general, we cannot
+expand all these calls, so we have to choose the
+&rsquo;best&rsquo; ones. With every CAL instruction that may
+be expanded, we associate a <i>pay off</i>, which expresses
+how desirable it is to expand this specific CAL.</p>
+
+<p>Let Tc denote the portion of EM text involved in a
+specific call, i.e. the pushing of the actual parameter
+expressions, the CAL itself, the popping of the parameters
+and the pushing of the result (if any, via an LFR). Let Te
+denote the EM text that would be obtained by expanding the
+call in line. Let Pc be the original program and Pe the
+program with Te substituted for Tc. The pay off of the CAL
+depends on two factors:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p>T = execution_time(Pe) - execution_time(Pc)</p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="66%">
+
+<p>S = code_size(Pe) - code_size(Pc)</p>
+</td>
+<td width="23%">
+</td>
+</table>
+
+<p>The change in execution time (T) depends on:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="88%">
+
+<p>T1 = execution_time(Te) - execution_time(Tc)</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="84%">
+
+<p>N = number of times Te or Tc get executed.</p>
+</td>
+<td width="5%">
+</td>
+</table>
+
+<p>We assume that T1 will be the same every time the code
+gets executed. This is a reasonable assumption. (Note that
+we are talking about one CAL, not about different calls to
+the same procedure). Hence</p>
+<pre>     T = N * T1
+</pre>
+
+<p>T1 can be estimated by a careful analysis of the
+transformations that are performed. Below, we list
+everything that will be different when a call is expanded in
+line:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The CAL instruction is not executed. This saves a
+subroutine jump.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The instructions in the procedure prolog are not
+executed. These instructions, generated from the PRO pseudo,
+save some machine registers (including the old LB), set the
+new LB and allocate space for the locals of the called
+routine. The savings may be less if there are no locals to
+allocate.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>In line parameters are not evaluated before the call and
+are not pushed on the stack.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>All remaining parameters are stored in local variables,
+instead of being pushed on the stack.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>If the number of parameters is nonzero, the ASP
+instruction after the CAL is not executed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Every reference to an in line parameter is substituted
+by the parameter expression.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>RET (return) instructions are replaced by BRA (branch)
+instructions. If the called procedure &rsquo;falls
+through&rsquo; (i.e. it has only one RET, at the end of its
+code), even the BRA is not needed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The LFR (fetch function result) is not executed</p>
+</td>
+</table>
+
+<p>Besides these changes, which are caused directly by IL,
+other changes may occur as IL influences other optimization
+techniques, such as Register Allocation and Constant
+Propagation. Our heuristic rules do not take into account
+the quite inpredictable effects on Register Allocation. It
+does, however, favour calls that have numeric
+<i>constants</i> as parameter; especially the constant
+&quot;0&quot; as an inline parameter gets high scores, as
+further optimizations may often be possible.</p>
+
+<p>It cannot be determined statically how often a CAL
+instruction gets executed. We will use <i>loop nesting</i>
+information here. The nesting level of the loop in which the
+CAL appears (if any) will be used as an indication for the
+number of times it gets executed.</p>
+
+<p>Based on all these facts, the pay off of a call will be
+computed. The following model was developed empirically.
+Assume procedure P calls procedure Q. The call takes place
+in basic block B.</p>
+
+<p align=center><img src="grohtml-1027214.png"></p>
+
+<p>S stands for the size increase of the program, which is
+slightly less than the size of Q. The size of a procedure is
+taken to be its number of (non-pseudo) EM instructions. The
+terms &quot;loop nesting level&quot; and &quot;firm&quot;
+were defined in the chapter on the Intermediate Code
+(section &quot;loop tables&quot;). If a call is not inside a
+loop and the calling procedure is itself never called from a
+loop (transitively), then the call will probably be executed
+at most once. Such a call is never expanded in line (its pay
+off is zero). If the calling procedure doesn&rsquo;t have
+local variables, a penalty (L) is introduced, as it will
+most likely get local variables if the call gets
+expanded.</p>
+<a name="5.5. Implementation"></a>
+<h2>5.5. Implementation</h2>
+
+<p>A major factor in the implementation of Inline
+Substitution is the requirement not to use an excessive
+amount of memory. IL essentially analyzes the entire
+program; it makes decisions based on which procedure calls
+appear in the whole program. Yet, because of the memory
+restriction, it is not feasible to read the entire program
+in main memory. To solve this problem, the IL phase has been
+split up into three subphases that are executed
+sequentially:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>analyze every procedure; see how it accesses its
+parameters; simultaneously collect all calls appearing in
+the whole program an put them in a <i>call-list</i>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>use the call-list and decide which calls will be
+substituted in line.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>take the decisions of subphase 2 and modify the program
+accordingly.</p>
+</td>
+</table>
+
+<p>Subphases 1 and 3 scan the input program; only subphase
+3 modifies it. It is essential that the decisions can be
+made in subphase 2 without using the input program, provided
+that subphase 1 puts enough information in the call-list.
+Subphase 2 keeps the entire call-list in main memory and
+repeatedly scans it, to find the next best candidate for
+expansion.</p>
+
+<p>We will specify the data structures used by IL before
+describing the subphases.</p>
+<a name="5.5.1. Data structures"></a>
+<h2>5.5.1. Data structures</h2>
+<a name="5.5.1.1. The procedure table"></a>
+<h2>5.5.1.1. The procedure table</h2>
+
+<p>In subphase 1 information is gathered about every
+procedure and added to the procedure table. This information
+is used by the heuristic rules. A proctable entry for
+procedure p has the following extra information:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>is it allowed to substitute an invocation of p in
+line?</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>is it allowed to put any parameter of such a call in
+line?</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="82%">
+
+<p>the size of p (number of EM instructions)</p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="44%">
+
+<p>does p &rsquo;fall through&rsquo;?</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>a description of the formal parameters that p accesses;
+this information is obtained by looking at the code of p.
+For every parameter f, we record:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="30%">
+
+<p>the offset of f</p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>the type of f (word, double word, pointer)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>may the corresponding actual parameter be put in
+line?</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p>is f ever accessed indirectly?</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>if f used: never, once or more than once?</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p>the number of times p is called (see below)</p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the file address of its call-count information (see
+below).</p>
+</td>
+</table>
+<a name="5.5.1.2. Call-count information"></a>
+<h2>5.5.1.2. Call-count information</h2>
+
+<p>As a result of Inline Substitution, some procedures may
+become useless, because all their invocations have been
+substituted in line. One of the tasks of IL is to keep track
+which procedures are no longer called. Note that IL is
+especially keen on procedures that are called only once
+(possibly as a result of expanding all other calls to it).
+So we want to know how many times a procedure is called
+<i>during</i> Inline Substitution. It is not good enough to
+compute this information afterwards. The task is rather
+complex, because the number of times a procedure is called
+varies during the entire process:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>If a call to p is substituted in line, the number of
+calls to p gets decremented by 1.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>If a call to p is substituted in line, and p contains n
+calls to q, then the number of calls to q gets incremented
+by n.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>If a procedure p is removed (because it is no longer
+called) and p contains n calls to q, then the number of
+calls to q gets decremented by n.</p>
+</td>
+</table>
+
+<p>(Note that p may be the same as q, if p is
+recursive).<br>
+So we actually want to have the following information:</p>
+<pre>     NRCALL(p,q) = number of call to q appearing in p,
+
+
+     for all procedures p and q that may be put in line.
+</pre>
+
+<p>This information, called <i>call-count information</i>
+is computed by the first subphase. It is stored in a file.
+It is represented as a number of lists, rather than as a
+(very sparse) matrix. Every procedure has a list of
+(proc,count) pairs, telling which procedures it calls, and
+how many times. The file address of its call-count list is
+stored in its proctable entry. Whenever this information is
+needed, it is fetched from the file, using direct access.
+The proctable entry also contains the number of times a
+procedure is called, at any moment.</p>
+<a name="5.5.1.3. The call-list"></a>
+<h2>5.5.1.3. The call-list</h2>
+
+<p>The call-list is the major data structure use by IL.
+Every item of the list describes one procedure call. It
+contains the following attributes:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p>the calling procedure (caller)</p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="58%">
+
+<p>the called procedure (callee)</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>identification of the CAL instruction (sequence
+number)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the loop nesting level; our heuristic rules appreciate
+calls inside a loop (or even inside a loop nested inside
+another loop, etc.) more than other calls</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the actual parameter expressions involved in the call;
+for every actual, we record:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="58%">
+
+<p>the EM code of the expression</p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>the number of bytes of its result (size)</p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>an indication if the actual may be put in line</p>
+</td>
+</table>
+
+<p>The structure of the call-list is rather complex.
+Whenever a call is expanded in line, new calls will suddenly
+appear in the program, that were not contained in the
+original body of the calling subroutine. These calls are
+inherited from the called procedure. We will refer to these
+invocations as <i>nested calls</i> (see Fig. 5.1).</p>
+
+<p align=center><img src="grohtml-1027215.png"></p>
+
+<p align=center><img src="grohtml-1027216.png"></p>
+
+<p>Fig. 5.1 Example of nested procedure calls</p>
+
+<p>Nested calls may subsequently be put in line too
+(probably resulting in a yet deeper nesting level, etc.). So
+the call-list does not always reflect the source program,
+but changes dynamically, as decisions are made. If a call to
+p is expanded, all calls appearing in p will be added to the
+call-list.<br>
+A convenient and elegant way to represent the call-list is
+to use a LISP-like list. [Poel72a] Calls that appear at the
+same level are linked in the CDR direction. If a call C to a
+procedure p is expanded, all calls appearing in p are put in
+a sub-list of C, i.e. in its CAR. In the example above,
+before the decision to expand the call to p is made, the
+call-list of procedure r looks like:</p>
+<pre>     (call-to-x, call-to-p, call-to-y)
+</pre>
+
+<p>After the decision, it looks like:</p>
+<pre>     (call-to-x, (call-to-p*, call-to-a, call-to-b), call-to-y)
+</pre>
+
+<p>The call to p is marked, because it has been
+substituted. Whenever IL wants to traverse the call-list of
+some procedure, it uses the well-known LISP technique of
+recursion in the CAR direction and iteration in the CDR
+direction (see page 1.19-2 of [Poel72a] ). All list
+traversals look like:</p>
+<pre>     traverse(list)
+     {
+         for (c = first(list); c != 0; c = CDR(c)) {
+             if (c is marked) {
+                 traverse(CAR(c));
+             } else {
+                 do something with c
+             }
+         }
+     }
+</pre>
+
+<p>The entire call-list consists of a number of LISP-like
+lists, one for every procedure. The proctable entry of a
+procedure contains a pointer to the beginning of the
+list.</p>
+<a name="5.5.2. The first subphase: procedure analysis"></a>
+<h2>5.5.2. The first subphase: procedure analysis</h2>
+
+<p>The tasks of the first subphase are to determine several
+attributes of every procedure and to construct the basic
+call-list, i.e. without nested calls. The size of a
+procedure is determined by simply counting its EM
+instructions. Pseudo instructions are skipped. A procedure
+does not &rsquo;fall through&rsquo; if its CFG contains a
+basic block that is not the last block of the CFG and that
+ends on a RET instruction. The formal parameters of a
+procedure are determined by inspection of its code.</p>
+
+<p>The call-list in constructed by looking at all CAL
+instructions appearing in the program. The call-list should
+only contain calls to procedures that may be put in line.
+This fact is only known if the procedure was analyzed
+earlier. If a call to a procedure p appears in the program
+before the body of p, the call will always be put in the
+call-list. If p is later found to be unsuitable, the call
+will be removed from the list by the second subphase.</p>
+
+<p>An important issue is the recognition of the actual
+parameter expressions of the call. The front ends produces
+messages telling how many bytes of formal parameters every
+procedure accesses. (If there is no such message for a
+procedure, it cannot be put in line). The actual parameters
+together must account for the same number of bytes.A
+recursive descent parser is used to parse side-effect free
+EM expressions. It uses a table and some auxiliary routines
+to determine how many bytes every EM instruction pops from
+the stack and how many bytes it pushes onto the stack. These
+numbers depend on the EM instruction, its argument, and the
+wordsize and pointersize of the target machine. Initially,
+the parser has to recognize the number of bytes specified in
+the formals-message, say N. Assume the first instruction
+before the CAL pops S bytes and pushes R bytes. If R &gt; N,
+too many bytes are recognized and the parser fails. Else, it
+calls itself recursively to recognize the S bytes used as
+operand of the instruction. If it succeeds in doing so, it
+continues with the next instruction, i.e. the first
+instruction before the code recognized by the recursive
+call, to recognize N-R more bytes. The result is a number of
+EM instructions that collectively push N bytes. If an
+instruction is come across that has side-effects (e.g. a
+store or a procedure call) or of which R and S cannot be
+computed statically (e.g. a LOS), it fails.<br>
+Note that the parser traverses the code backwards. As EM
+code is essentially postfix code, the parser works top
+down.</p>
+
+<p>If the parser fails to recognize the parameters, the
+call will not be substituted in line. If the parameters can
+be determined, they still have to match the formal
+parameters of the called procedure. This check is performed
+by the second subphase; it cannot be done here, because it
+is possible that the called procedure has not been analyzed
+yet.</p>
+
+<p>The entire call-list is written to a file, to be
+processed by the second subphase.</p>
+<a name="5.5.3. The second subphase: making decisions"></a>
+<h2>5.5.3. The second subphase: making decisions</h2>
+
+<p>The task of the second subphase is quite easy to
+understand. It reads the call-list file, builds an incore
+call-list and deletes every call that may not be expanded in
+line (either because the called procedure may not be put in
+line, or because the actual parameters of the call do not
+match the formal parameters of the called procedure). It
+assigns a <i>pay-off</i> to every call, indicating how
+desirable it is to expand it.</p>
+
+<p>The subphase repeatedly scans the call-list and takes
+the call with the highest ratio. The chosen one gets marked,
+and the call-list is extended with the nested calls, as
+described above. These nested calls are also assigned a
+ratio, and will be considered too during the next scans.<br>
+After every decision the number of times every procedure is
+called is updated, using the call-count information.
+Meanwhile, the subphase keeps track of the amount of space
+left available. If all space is used, or if there are no
+more calls left to be expanded, it exits this loop. Finally,
+calls to procedures that are called only once are also
+chosen.</p>
+
+<p>The actual parameters of a call are only needed by this
+subphase to assign a ratio to a call. To save some space,
+these actuals are not kept in main memory. They are removed
+after the call has been read and a ratio has been assigned
+to it. So this subphase works with <i>abstracts</i> of
+calls. After all work has been done, the actual parameters
+of the chosen calls are retrieved from a file, as they are
+needed by the transformation subphase.</p>
+<a name="5.5.4. The third subphase: doing transformations"></a>
+<h2>5.5.4. The third subphase: doing transformations</h2>
+
+<p>The third subphase makes the actual modifications to the
+EM text. It is directed by the decisions made in the
+previous subphase, as expressed via the call-list. The
+call-list read by this subphase contains only calls that
+were selected for expansion. The list is ordered in the same
+way as the EM text, i.e. if a call C1 appears before a call
+C2 in the call-list, C1 also appears before C2 in the EM
+text. So the EM text is traversed linearly, the calls that
+have to be substituted are determined and the modifications
+are made. If a procedure is come across that is no longer
+needed, it is simply not written to the output EM file. The
+substitution of a call takes place in distinct steps:</p>
+
+<p>change the calling sequence</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The actual parameter expressions are changed. Parameters
+that are put in line are removed. All remaining ones must
+store their result in a temporary local variable, rather
+than push it on the stack. The CAL instruction and any ASP
+(to pop actual parameters) or LFR (to fetch the result of a
+function) are deleted.</p>
+</td>
+</table>
+
+<p>fetch the text of the called procedure</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>Direct disk access is used to to read the text of the
+called procedure. The file offset is obtained from the
+proctable entry.</p>
+</td>
+</table>
+
+<p>allocate bytes for locals and temporaries</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The local variables of the called procedure will be put
+in the stack frame of the calling procedure. The same
+applies to any temporary variables that hold the result of
+parameters that were not put in line. The proctable entry of
+the caller is updated.</p>
+</td>
+</table>
+
+<p>put a label after the CAL</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>If the called procedure contains a RET (return)
+instruction somewhere in the middle of its text (i.e. it
+does not fall through), the RET must be changed into a BRA
+(branch), to jump over the remainder of the text. This label
+is not needed if the called procedure falls through.</p>
+</td>
+</table>
+
+<p>copy the text of the called procedure and modify it</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>References to local variables of the called routine and
+to parameters that are not put in line are changed to refer
+to the new local of the caller. References to in line
+parameters are replaced by the actual parameter expression.
+Returns (RETs) are either deleted or replaced by a BRA.
+Messages containing information about local variables or
+parameters are changed. Global data declarations and the PRO
+and END pseudos are removed. Instruction labels and
+references to them are changed to make sure they do not have
+the same identifying number as labels in the calling
+procedure.</p>
+</td>
+</table>
+
+<p>insert the modified text</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The pseudos of the called procedure are put after the
+pseudos of the calling procedure. The real text of the
+callee is put at the place where the CAL was.</p>
+</td>
+</table>
+
+<p>take care of nested substitutions</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The expanded procedure may contain calls that have to be
+expanded too (nested calls). If the descriptor of this call
+contains actual parameter expressions, the code of the
+expressions has to be changed the same way as the code of
+the callee was changed. Next, the entire process of finding
+CALs and doing the substitutions is repeated
+recursively.</p>
+</td>
+</table>
+<a name="5.6. Source files of IL"></a>
+<h2>5.6. Source files of IL</h2>
+
+<p>The sources of IL are in the following files and
+packages (the prefixes 1_, 2_ and 3_ refer to the three
+subphases):</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>il.h:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>declarations of global variables and data structures</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>il.c:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>the routine main; the driving routines of the three
+subphases</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>1_anal:</p>
+</td>
+<td width="14%"></td>
+<td width="72%">
+
+<p>contains a subroutine that analyzes a procedure</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>1_cal:</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>contains a subroutine that analyzes a call</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>1_aux:</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>implements auxiliary procedures used by subphase 1</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>2_aux:</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>implements auxiliary procedures used by subphase 2</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>3_subst:</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>the driving routine for doing the substitution</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>3_change:</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>lower level routines that do certain modifications</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>3_aux:</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>implements auxiliary procedures used by subphase 3</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>aux:</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>implements auxiliary procedures used by several
+subphases.</p>
+</td>
+</table>
+<a name="6. Strength reduction"></a>
+<h2>6. Strength reduction</h2>
+<a name="6.1. Introduction"></a>
+<h2>6.1. Introduction</h2>
+
+<p>The Strength Reduction optimization technique (SR) tries
+to replace expensive operators by cheaper ones, in order to
+decrease the execution time of the program. A classical
+example is replacing a &rsquo;multiplication by 2&rsquo; by
+an addition or a shift instruction. These kinds of local
+transformations are already done by the EM Peephole
+Optimizer. Strength reduction can also be applied more
+generally to operators used in a loop.</p>
+
+<p align=center><img src="grohtml-1027217.png"></p>
+
+<p>Fig. 6.1 An example of Strenght Reduction</p>
+
+<p>In Fig. 6.1, a multiplication inside a loop is replaced
+by an addition inside the loop and a multiplication outside
+the loop. Clearly, this is a global optimization; it cannot
+be done by a peephole optimizer.</p>
+
+<p>In some cases a related technique, <i>test
+replacement</i>, can be used to eliminate the loop variable
+i. This technique will not be discussed in this report.<br>
+In the example above, the resulting code can be further
+optimized by using constant propagation. Obviously, this is
+not the task of the Strength Reduction phase.</p>
+<a name="6.2. The model of strength reduction"></a>
+<h2>6.2. The model of strength reduction</h2>
+
+<p>In this section we will describe the transformations
+performed by Strength Reduction (SR). Before doing so, we
+will introduce the central notion of an induction
+variable.</p>
+<a name="6.2.1. Induction variables"></a>
+<h2>6.2.1. Induction variables</h2>
+
+<p>SR looks for variables whose values form an arithmetic
+progression at the beginning of a loop. These variables are
+called induction variables. The most frequently occurring
+example of such a variable is a loop-variable in a
+high-order programming language. Several quite sophisticated
+models of strength reduction can be found in the literature.
+[Cock77a, Alle81a, Lowr69a, Aho78a] In these models the
+notion of an induction variable is far more general than the
+intuitive notion of a loop-variable. The definition of an
+induction variable we present here is more restricted,
+yielding a simpler model and simpler transformations. We
+think the principle source for strength reduction lies in
+expressions using a loop-variable, i.e. a variable that is
+incremented or decremented by the same amount after every
+loop iteration, and that cannot be changed in any other
+way.</p>
+
+<p>Of course, the EM code does not contain high level
+constructs such as for-statements. We will define an
+induction variable in terms of the Intermediate Code of the
+optimizer. Note that the notions of a loop in the EM text
+and of a firm basic block were defined in section 3.3.5.</p>
+
+<p>definition<br>
+An induction variable i of a loop L is a local variable that
+is never accessed indirectly, whose size is the word size of
+the target machine, and that is assigned exactly once within
+L, the assignment:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>being of the form i := i + c or i := c +i, c is a
+constant called the <i>step value</i> of i.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="62%">
+
+<p>occurring in a firm block of L.</p>
+</td>
+<td width="27%">
+</td>
+</table>
+
+<p>(Note that the first restriction on the assignment is
+not described in terms of the Intermediate Code; we will
+give such a description later; the current definition is
+easier to understand however).</p>
+<a name="6.2.2. Recognized expressions"></a>
+<h2>6.2.2. Recognized expressions</h2>
+
+<p>SR recognizes certain expressions using an induction
+variable and replaces them by cheaper ones. Two kinds of
+expensive operations are recognized: multiplication and
+array address computations. The expressions that are
+simplified must use an induction variable as an operand of a
+multiplication or as index in an array expression.</p>
+
+<p>Often a linear function of an induction variable is
+used, rather than the variable itself. In these cases
+optimization is still possible. We call such expressions
+<i>iv-expressions</i>.</p>
+
+<p>definition:<br>
+An iv-expression of an induction variable i of a loop L is
+an expression that:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>uses only the operators + and - (unary as well as
+binary)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p>uses i as operand exactly once</p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>uses (besides i) only constants or variables that are
+never changed in L as operands.</p>
+</td>
+</table>
+
+<p>The expressions recognized by SR are of the following
+forms:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(1)</p>
+</td>
+<td width="4%"></td>
+<td width="48%">
+
+<p>iv_expression * constant</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(2)</p>
+</td>
+<td width="4%"></td>
+<td width="48%">
+
+<p>constant * iv_expression</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(3)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>A[iv-expression] := (assign to array element)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(4)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>A[iv-expression] (use array element)</p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(5)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>&amp; A[iv-expression] (take address of array
+element)</p>
+</td>
+</table>
+
+<p>(Note that EM has different instructions to use an array
+element, store into one, or take the address of one, resp.
+LAR, SAR, and AAR).<br>
+The size of the elements of A must be known statically. In
+cases (3) and (4) this size must equal the word size of the
+target machine.</p>
+<a name="6.2.3. Transformations"></a>
+<h2>6.2.3. Transformations</h2>
+
+<p>With every recognized expression we associate a new
+temporary local variable TMP, allocated in the stack frame
+of the procedure containing the expression. At any program
+point within the loop, TMP will contain the following
+value:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p>multiplication:</p>
+</td>
+<td width="6%"></td>
+<td width="64%">
+
+<p>the current value of iv-expression * constant</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>arrays:</p>
+</td>
+<td width="22%"></td>
+<td width="64%">
+
+<p>the current value of &amp;A[iv-expression].</p>
+</td>
+</table>
+
+<p>In the second case, TMP essentially is a pointer
+variable, pointing to the element of A that is currently in
+use.<br>
+If the same expression occurs several times in the loop, the
+same temporary local is used each time.</p>
+
+<p>Three transformations are applied to the EM text:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(1)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>TMP is initialized with the right value. This
+initialization takes place just before the loop.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(2)</p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p>The recognized expression is simplified.</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(3)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>TMP is incremented; this takes place just after the
+induction variable is incremented.</p>
+</td>
+</table>
+
+<p>For multiplication, the initial value of TMP is the
+value of the recognized expression at the program point
+immediately before the loop. For arrays, TMP is initialized
+with the address of the first array element that is
+accessed. So the initialization code is:</p>
+<pre>     TMP := iv-expression * constant;  or
+     TMP := &amp;A[iv-expression]
+</pre>
+
+<p>At the point immediately before the loop, the induction
+variable will already have been initialized, so the value
+used in the code above will be the value it has during the
+first iteration.</p>
+
+<p>For multiplication, the recognized expression can simply
+be replaced by TMP. For array optimizations, the replacement
+depends on the form:</p>
+
+<p align=center><img src="grohtml-1027218.png"></p>
+
+<p>The &rsquo;*&rsquo; denotes the indirect operator. (Note
+that EM has different instructions to do an assign-indirect
+and a use-indirect). As the size of the array elements is
+restricted to be the word size in case (3) and (4), only one
+EM instruction needs to be generated in all cases.</p>
+
+<p>The amount by which TMP is incremented is:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p>multiplication:</p>
+</td>
+<td width="6%"></td>
+<td width="42%">
+
+<p>step value * constant</p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>arrays:</p>
+</td>
+<td width="22%"></td>
+<td width="50%">
+
+<p>step value * element size</p>
+</td>
+<td width="13%">
+</td>
+</table>
+
+<p>Note that the step value (see definition of induction
+variable above), the constant, and the element size (see
+previous section) can all be determined statically. If the
+sign of the induction variable in the iv-expression is
+negative, the amount must be negated.</p>
+
+<p>The transformations are demonstrated by an example.</p>
+
+<p align=center><img src="grohtml-1027219.png"></p>
+
+<p>Fig. 6.2 Example of complex Strength Reduction
+transformations</p>
+
+<p>The expression &rsquo;(6-i)*5&rsquo; is recognized
+twice. The constant is 5. The step value is -3. The sign of
+i in the recognized expression is &rsquo;-&rsquo;. So the
+increment value of TMP is -(-3*5) = +15.</p>
+<a name="6.3. Implementation"></a>
+<h2>6.3. Implementation</h2>
+
+<p>Like most phases, SR deals with one procedure at a time.
+Within a procedure, SR works on one loop at a time. Loops
+are processed in textual order. If loops are nested inside
+each other, SR starts with the outermost loop and proceeds
+in the inwards direction. This order is chosen, because it
+enables the optimization of multi-dimensional array address
+computations, if the elements are accessed in the usual way
+(i.e. row after row, rather than column after column). For
+every loop, SR first detects all induction variables and
+then tries to recognize expressions that can be
+optimized.</p>
+<a name="6.3.1. Finding induction variables"></a>
+<h2>6.3.1. Finding induction variables</h2>
+
+<p>The process of finding induction variables can
+conveniently be split up into two parts. First, the EM text
+of the loop is scanned to find all <i>candidate</i>
+induction variables, which are word-sized local variables
+that are assigned precisely once in the loop, within a firm
+block. Second, for every candidate, the single assignment is
+inspected, to see if it has the form required by the
+definition of an induction variable.</p>
+
+<p>Candidates are found by scanning the EM code of the
+loop. During this scan, two sets are maintained. The set
+&quot;cand&quot; contains all variables that were assigned
+exactly once so far, within a firm block. The set
+&quot;dismiss&quot; contains all variables that should not
+be made a candidate. Initially, both sets are empty. If a
+variable is assigned to, it is put in the cand set, if three
+conditions are met:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>the variable was not in cand or dismiss already</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>the assignment takes place in a firm block</p>
+</td>
+<td width="5%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>the assignment is not a ZRL instruction (assignment by
+zero) or a SDL instruction (store double local).</p>
+</td>
+</table>
+
+<p>If any condition fails, the variable is dismissed from
+cand (if it was there already) and put in dismiss (if it was
+not there already).<br>
+All variables for which no register message was generated
+(i.e. those variables that may be accessed indirectly) are
+assumed to be changed in the loop.<br>
+All variables that remain in cand are candidate induction
+variables.</p>
+
+<p>From the set of candidates, the induction variables can
+be determined, by inspecting the single assignment. The
+assignment must match one of the EM patterns below.
+(&rsquo;x&rsquo; is the candidate. &rsquo;ws&rsquo; is the
+word size of the target machine.</p>
+
+<p align=center><img src="grohtml-1027220.png"></p>
+
+<p>From the patterns the step size of the induction
+variable can also be determined. These step sizes are
+displayed on the right hand side.</p>
+
+<p>For every induction variable we maintain the following
+information:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the offset of the variable in the stackframe of its
+procedure</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>a pointer to the EM text of the assignment statement</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="28%">
+
+<p>the step value</p>
+</td>
+<td width="61%">
+</td>
+</table>
+<a name="6.3.2. Optimizing expressions"></a>
+<h2>6.3.2. Optimizing expressions</h2>
+
+<p>If any induction variables of the loop were found, the
+EM text of the loop is scanned again, to detect expressions
+that can be optimized. SR scans for multiplication and array
+instructions. Whenever it finds such an instruction, it
+analyses the code in front of it. If an expression is to be
+optimized, it must be generated by the following syntax
+rules.</p>
+
+<p align=center><img src="grohtml-1027221.png"></p>
+
+<p>An &rsquo;address&rsquo; is an EM instruction that loads
+an address on the stack. An instruction like LOL may be an
+&rsquo;address&rsquo;, if the size of an address (pointer
+size, =ps) is the same as the word size. If the pointer size
+is twice the word size, instructions like LDL are an
+&rsquo;address&rsquo;. (The addresses in the third grammar
+rule denote resp. the array address and the array descriptor
+address).</p>
+
+<p align=center><img src="grohtml-1027222.png"></p>
+
+<p>The notion of an iv-expression was introduced
+earlier.</p>
+
+<p align=center><img src="grohtml-1027223.png"></p>
+
+<p>An iv_expression must satisfy one additional constraint:
+it must use exactly one operand that is an induction
+variable. A simple, hand written, top-down parser is used to
+recognize an iv-expression. It scans the EM code from right
+to left (recall that EM is essentially postfix). It uses
+semantic attributes (inherited as well as derived) to check
+the additional constraint.</p>
+
+<p>All information assembled during the recognition process
+is put in a &rsquo;code_info&rsquo; structure. This
+structure contains the following information:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="54%">
+
+<p>the optimizable code itself</p>
+</td>
+<td width="35%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="88%">
+
+<p>the loop and basic block the code is part of</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="44%">
+
+<p>the induction variable</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="34%">
+
+<p>the iv-expression</p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the sign of the induction variable in the
+iv-expression</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the offset and size of the temporary local variable</p>
+</td>
+</table>
+
+<p>-</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>the expensive operator (MLI, LAR etc.)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the instruction that loads the constant (for
+multiplication) or the array descriptor (for arrays).</p>
+</td>
+</table>
+
+<p>The entire transformation process is driven by this
+information. As the EM text is represented internally as a
+list, this process consists mainly of straightforward list
+manipulations.<br>
+The initialization code must be put immediately before the
+loop entry. For this purpose a <i>header block</i> is
+created that has the loop entry block as its only successor
+and that dominates the entry block. The CFG and all
+relations (SUCC,PRED, IDOM, LOOPS etc.) are updated.<br>
+An EM instruction that will replace the optimizable code is
+created and put at the place of the old code. The list
+representing the old optimizable code is used to create a
+list for the initializing code, as they are similar. Only
+two modifications are required:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>if the expensive operator is a LAR or SAR, it must be
+replaced by an AAR, as the initial value of TMP is the
+<i>address</i> of the first array element that is
+accessed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>code must be appended to store the result of the
+expression in TMP.</p>
+</td>
+</table>
+
+<p>Finally, code to increment TMP is created and put after
+the code of the single assignment to the induction variable.
+The generated code uses either an integer addition (ADI) or
+an integer-to-pointer addition (ADS) to do the
+increment.</p>
+
+<p>SR maintains a set of all expressions that have already
+been recognized in the present loop. Such expressions are
+said to be <i>available</i>. If an expression is recognized
+that is already available, no new temporary local variable
+is allocated for it, and the code to initialize and
+increment the local is not generated.</p>
+<a name="6.4. Source files of SR"></a>
+<h2>6.4. Source files of SR</h2>
+
+<p>The sources of SR are in the following files and
+packages:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>sr.h:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>declarations of global variables and data structures</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>sr.c:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>the routine main; a driving routine to process (possibly
+nested) loops in the right order</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>iv</p>
+</td>
+<td width="24%"></td>
+<td width="72%">
+
+<p>implements a procedure that finds the induction
+variables of a loop</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>reduce</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>implements a procedure that finds optimizable
+expressions and that does the transformations</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>cand</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>implements a procedure that finds the candidate
+induction variables; used to implement iv</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>xform</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>implements several useful routines that transform lists
+of EM text or a CFG; used to implement reduce</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>expr</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>implements a procedure that parses iv-expressions</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>aux</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>implements several auxiliary procedures.</p>
+</td>
+</table>
+<a name="7. Common subexpression elimination"></a>
+<h2>7. Common subexpression elimination</h2>
+<a name="7.1. Introduction"></a>
+<h2>7.1. Introduction</h2>
+
+<p>The Common Subexpression Elimination optimization
+technique (CS) tries to eliminate multiple computations of
+EM expressions that yield the same result. It places the
+result of one such computation in a temporary variable, and
+replaces the other computations by a reference to this
+temporary variable. The primary goal of this technique is to
+decrease the execution time of the program, but in general
+it will save space too.</p>
+
+<p>As an example of the application of Common Subexpression
+Elimination, consider the piece of program in Fig.
+7.1(a).</p>
+
+<p align=center><img src="grohtml-1027224.png"></p>
+
+<p>Fig. 7.1 Examples of Common Subexpression
+Elimination</p>
+
+<p>If neither a nor b is changed in CODE, the instructions
+can be replaced by those of Fig. 7.1(b), which saves one
+multiplication, but costs an extra store instruction. If the
+value of x is not changed in CODE either, the instructions
+can be replaced by those of Fig. 7.1(c). In this case the
+extra store is not needed.</p>
+
+<p>In the following sections we will describe which
+transformations are done by CS and how this phase was
+implemented.</p>
+<a name="7.2. Specification of the Common Subexpression Elimination phase"></a>
+<h2>7.2. Specification of the Common Subexpression Elimination phase</h2>
+
+<p>In this section we will describe the window through
+which CS examines the code, the expressions recognized by
+CS, and finally the changes made to the code.</p>
+<a name="7.2.1. The working window"></a>
+<h2>7.2.1. The working window</h2>
+
+<p>The CS algorithm is applied to the largest sequence of
+textually adjacent basic blocks B1,..,Bn, for which</p>
+<pre>     PRED(Bj) = {Bj-1},  j = 2,..,n.
+</pre>
+
+<p>Intuitively, this window consists of straight line code,
+with only one entry point (at the beginning); it may contain
+jumps, which should all have their targets outside the
+window. This is illustrated in Fig. 7.2.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="6" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>x := a * b;</p>
+<td width="9%"></td>
+<td width="10%">
+
+<p>(1)<br>
+if x &lt; 10 then</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>(2)<br>
+y := a * b;</p>
+</td>
+<td width="20%"></td>
+<td width="10%">
+
+<p>(3)</p>
+</td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+</table>
+
+<p>Fig. 7.2 The working window of CS</p>
+
+<p>Line (2) can only be executed after line (1). Likewise,
+line (3) can only be executed after line (2). Both a and b
+have the same values at line (1) and at line (3).</p>
+
+<p>Larger windows were avoided. In Fig. 7.3, the value of a
+at line (4) may have been obtained at more than one
+point.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>x := a * b;</p>
+<td width="9%"></td>
+<td width="10%">
+
+<p>(1)<br>
+if x &lt; 10 then</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>(2)<br>
+a := 100;</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>(3)<br>
+y := a * b;</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>(4)</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+
+<p>Fig. 7.3 Several working windows</p>
+<a name="7.2.2. Recognized expressions."></a>
+<h2>7.2.2. Recognized expressions.</h2>
+
+<p>The computations eliminated by CS need not be normal
+expressions (like &quot;a * b&quot;), but can even consist
+of a single operand that is expensive to access, such as an
+array element or a record field. If an array element is
+used, its address is computed implicitly. CS is able to
+eliminate either the element itself or its address,
+whichever one is most profitable. A variable of a textually
+enclosing procedure may also be expensive to access,
+depending on the lexical level difference.</p>
+<a name="7.2.3. Transformations"></a>
+<h2>7.2.3. Transformations</h2>
+
+<p>CS creates a new temporary local variable (TMP) for
+every eliminated expression, unless it is able to use an
+existing local variable. It emits code to initialize this
+variable with the result of the expression. Most recurrences
+of the expression can simply be replaced by a reference to
+TMP. If the address of an array element is recognized as a
+common subexpression, references to the element itself are
+replaced by indirect references through TMP (see Fig.
+7.4).</p>
+
+<p align=center><img src="grohtml-1027225.png"></p>
+
+<p>Fig. 7.4 Elimination of an array address computation</p>
+
+<p>Here, &rsquo;&amp;&rsquo; is the &rsquo;address
+of&rsquo; operator, and unary &rsquo;*&rsquo; is the
+indirection operator. (Note that EM actually has different
+instructions to do a use-indirect or an
+assign-indirect.)</p>
+<a name="7.3. Implementation"></a>
+<h2>7.3. Implementation</h2>
+<a name="7.3.1. The value number method"></a>
+<h2>7.3.1. The value number method</h2>
+
+<p>To determine whether two expressions have the same
+result, there must be some way to determine whether their
+operands have the same values. We use a system of <i>value
+numbers</i> [Kenn81a] in which each distinct value of
+whatever type, created or used within the working window,
+receives a unique identifying number, its value number. Two
+items have the same value number if and only if, based only
+upon information from the instructions in the window, their
+values are provably identical. For example, after processing
+the statement</p>
+<pre>     a := 4;
+</pre>
+
+<p>the variable a and the constant 4 have the same value
+number.</p>
+
+<p>The value number of the result of an expression depends
+only on the kind of operator and the value number(s) of the
+operand(s). The expressions need not be textually equal, as
+shown in Fig. 7.5.</p>
+
+<p align=center><img src="grohtml-1027226.png"></p>
+
+<p>Fig. 7.5 Different expressions with the same value
+number</p>
+
+<p>At line (1) a receives the same value number as c. At
+line (2) d receives the same value number as b. At line (4)
+the expression &quot;c * d&quot; receives the same value
+number as the expression &quot;a * b&quot; at line (2),
+because the value numbers of their left and right operands
+are the same, and the operator (*) is the same.</p>
+
+<p>As another example of the value number method, consider
+Fig. 7.6.</p>
+
+<p align=center><img src="grohtml-1027227.png"></p>
+
+<p>Fig. 7.6 Identical expressions with the different value
+numbers</p>
+
+<p>Although textually the expressions &quot;a * b&quot; in
+line 1 and line 3 are equal, a will have different value
+numbers at line 3 and line 1. The two expressions will not
+mistakenly be recognized as equivalent.</p>
+<a name="7.3.2. Entities"></a>
+<h2>7.3.2. Entities</h2>
+
+<p>The Value Number Method distinguishes between operators
+and operands. The value numbers of operands are stored in a
+table, called the <i>symbol table</i>. The value number of a
+subexpression depends on the (root) operator of the
+expression and on the value numbers of its operands. A table
+of &quot;available expressions&quot; is used to do this
+mapping.</p>
+
+<p>CS recognizes the following kinds of EM operands, called
+<i>entities</i>:</p>
+<pre>     - constant
+     - local variable
+     - external variable
+     - indirectly accessed entity
+     - offsetted entity
+     - address of local variable
+     - address of external variable
+     - address of offsetted entity
+     - address of local base
+     - address of argument base
+     - array element
+     - procedure identifier
+     - floating zero
+     - local base
+     - heap pointer
+     - ignore mask
+</pre>
+
+<p>Whenever a new entity is encountered in the working
+window, it is entered in the symbol table and given a brand
+new value number. Most entities have attributes (e.g. the
+offset in the current stackframe for local variables), which
+are also stored in the symbol table.</p>
+
+<p>An entity is called static if its value cannot be
+changed (e.g. a constant or an address).</p>
+<a name="7.3.3. Parsing expressions"></a>
+<h2>7.3.3. Parsing expressions</h2>
+
+<p>Common subexpressions are recognized by simulating the
+behaviour of the EM machine. The EM code is parsed from left
+to right; as EM is postfix code, this is a bottom up parse.
+At any point the current state of the EM runtime stack is
+reflected by a simulated &quot;fake stack&quot;, containing
+descriptions of the parsed operands and expressions. A
+descriptor consists of:</p>
+<pre>     (1) the value number of the operand or expression
+     (2) the size of the operand or expression
+     (3) a pointer to the first line of EM-code
+         that constitutes the operand or expression
+</pre>
+
+<p>Note that operands may consist of several EM
+instructions. Whenever an operator is encountered, the
+descriptors of its operands are on top of the fake stack.
+The operator and the value numbers of the operands are used
+as indices in the table of available expressions, to
+determine the value number of the expression.</p>
+
+<p>During the parsing process, we keep track of the first
+line of each expression; we need this information when we
+decide to eliminate the expression.</p>
+<a name="7.3.4. Updating entities"></a>
+<h2>7.3.4. Updating entities</h2>
+
+<p>An entity is assigned a value number when it is used for
+the first time in the working window. If the entity is used
+as left hand side of an assignment, it gets the value number
+of the right hand side. Sometimes the effects of an
+instruction on an entity cannot be determined exactly; the
+current value and value number of the entity may become
+inconsistent. Hence the current value number must be
+forgotten. This is achieved by giving the entity a new value
+number that was not used before. The entity is said to be
+<i>killed</i>.</p>
+
+<p>As information is lost when an entity is killed, CS
+tries to save as many entities as possible. In case of an
+indirect assignment through a pointer, some analysis is done
+to see which variables cannot be altered. For a procedure
+call, the interprocedural information contained in the
+procedure table is used to restrict the set of entities that
+may be changed by the call. Local variables for which the
+front end generated a register message can never be changed
+by an indirect assignment or a procedure call.</p>
+<a name="7.3.5. Changing the EM text"></a>
+<h2>7.3.5. Changing the EM text</h2>
+
+<p>When a new expression comes available, it is checked
+whether its result is saved in a local that may go in a
+register. The last line of the expression must be followed
+by a STL or SDL instruction (depending on the size of the
+result) and a register message must be present for this
+local. If there is such a local, it is recorded in the
+available expressions table. Each time a new occurrence of
+this expression is found, the value number of the local is
+compared against the value number of the result. If they are
+different the local cannot be used and is forgotten.</p>
+
+<p>The available expressions are linked in a list. New
+expressions are linked at the head of the list. In this way
+expressions that are contained within other expressions
+appear later in the list, because EM-expressions are
+postfix. The elimination process walks through the list,
+starting at the head, to find the largest expressions first.
+If an expression is eliminated, any expression later on in
+the list, contained in the former expression, is removed
+from the list, as expressions can only be eliminated
+once.</p>
+
+<p>A STL or SDL is emitted after the first occurrence of
+the expression, unless there was an existing local variable
+that could hold the result.</p>
+<a name="7.3.6. Desirability analysis"></a>
+<h2>7.3.6. Desirability analysis</h2>
+
+<p>Although the global optimizer works on EM code, the goal
+is to improve the quality of the object code. Therefore some
+machine-dependent information is needed to decide whether it
+is desirable to eliminate a given expression. Because it is
+impossible for the CS phase to know exactly what code will
+be generated, some heuristics are used. CS essentially looks
+for some special cases that should not be eliminated. These
+special cases can be turned on or off for a given machine,
+as indicated in a machine descriptor file.</p>
+
+<p>Some operators can sometimes be translated into an
+addressing mode for the machine at hand. Such an operator is
+only eliminated if its operand is itself expensive, i.e. it
+is not just a simple load. The machine descriptor file
+contains a set of such operators.</p>
+
+<p>Eliminating the loading of the Local Base or the
+Argument Base by the LXL resp. LXA instruction is only
+beneficial if the difference in lexical levels exceeds a
+certain threshold. The machine descriptor file contains this
+threshold.</p>
+
+<p>Replacing a SAR or a LAR by an AAR followed by a LOI may
+possibly increase the size of the object code. We assume
+that this is only possible when the size of the array
+element is greater than some limit.</p>
+
+<p>There are back ends that can very efficiently translate
+the index computing instruction sequence LOC SLI ADS. If
+this is the case, the SLI instruction between a LOC and an
+ADS is not eliminated.</p>
+
+<p>To handle unforseen cases, the descriptor file may also
+contain a set of operators that should never be
+eliminated.</p>
+<a name="7.3.7. The algorithm"></a>
+<h2>7.3.7. The algorithm</h2>
+
+<p>After these preparatory explanations, the algorithm
+itself is easy to understand. For each instruction within
+the current window, the following steps are performed in the
+given order :</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Check if this instruction defines an entity. If so, the
+set of entities is updated accordingly.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Kill all entities that might be affected by this
+instruction.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Simulate the instruction on the fake-stack. If this
+instruction is an operator, update the list of available
+expressions accordingly.</p>
+</td>
+</table>
+
+<p>The result of this process is a list of available
+expressions plus the information needed to eliminate them.
+Expressions that are desirable to eliminate are eliminated.
+Next, the window is shifted and the process is repeated.</p>
+<a name="7.4. Implementation."></a>
+<h2>7.4. Implementation.</h2>
+
+<p>In this section we will discuss the implementation of
+the CS phase. We will first describe the basic actions that
+are undertaken by the algorithm, than the algorithm
+itself.</p>
+<a name="7.4.1. Partioning the EM instructions"></a>
+<h2>7.4.1. Partioning the EM instructions</h2>
+
+<p>There are over 100 EM instructions. For our purpose we
+partition this huge set into groups of instructions which
+can be more or less conveniently handled together.</p>
+
+<p>There are groups for all sorts of load instructions:
+simple loads, expensive loads, loads of an array element. A
+load is considered <i>expensive</i> when more than one EM
+instructions are involved in loading it. The load of a
+lexical entity is also considered expensive. For instance:
+LOF is expensive, LAL is not. LAR forms a group on its own,
+because it is not only an expensive load, but also
+implicitly includes the ternary operator AAR, which computes
+the address of the array element.</p>
+
+<p>There are groups for all sorts of operators: unary,
+binary, and ternary. The groups of operators are further
+partitioned according to the size of their operand(s) and
+result.</p>
+
+<p>There are groups for all sorts of stores: direct,
+indirect, array element. The SAR forms a group on its own
+for the same reason as appeared with LAR.</p>
+
+<p>The effect of the remaining instructions is less clear.
+They do not help very much in parsing expressions or in
+constructing our pseudo symboltable. They are partitioned
+according to the following criteria:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>They change the value of an entity without using the
+stack (e.g. ZRL, DEE).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="74%">
+
+<p>They are subroutine calls (CAI, CAL).</p>
+</td>
+<td width="5%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>They change the stack in some irreproduceable way (e.g.
+ASP, LFR, DUP).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>They have no effect whatever on the stack or on the
+entities. This does not mean they can be deleted, but they
+can be ignored for the moment (e.g. MES, LIN, NOP).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>Their effect is too complicate too compute, so we just
+assume worst case behaviour. Hopefully, they do not occur
+very often. (e.g. MON, STR, BLM).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>They signal the end of the basic block (e.g. BLT, RET,
+TRP).</p>
+</td>
+</table>
+<a name="7.4.2. Parsing expressions"></a>
+<h2>7.4.2. Parsing expressions</h2>
+
+<p>To recognize expressions, we simulate the behaviour of
+the EM machine, by means of a fake-stack. When we scan the
+instructions in sequential order, we first encounter the
+instructions that load the operands on the stack, and then
+the instruction that indicates the operator, because EM
+expressions are postfix. When we find an instruction to load
+an operand, we load on the fake-stack a struct with the
+following information:</p>
+
+<p align=center><img src="grohtml-1027228.png"></p>
+
+<p>In most cases, (3) will point to the line that loaded
+the operand (e.g. LOL, LOC), i.e. there is only one line
+that refers to this operand, but sometimes some information
+must be popped to load the operand (e.g. LOI, LAR). This
+information must have been pushed before, so we also pop a
+pointer to the first line that pushed the information. This
+line is now the first line that defines the operand.</p>
+
+<p>When we find the operator instruction, we pop its
+operand(s) from the fake-stack. The first line that defines
+the first operand is now the first line of the expression.
+We now have all information to determine whether the just
+parsed expression has occurred before. We also know the
+first and last line of the expression; we need this when we
+decide to eliminate it. Associated with each available
+expression is a set of which the elements contains the first
+and last line of a recurrence of this expression.</p>
+
+<p>Not only will the operand(s) be popped from the
+fake-stack, but the following will be pushed:</p>
+
+<p align=center><img src="grohtml-1027229.png"></p>
+
+<p>In this way an item on the fake-stack always contains
+the necessary information. EM expressions are parsed bottum
+up.</p>
+<a name="7.4.3. Updating entities"></a>
+<h2>7.4.3. Updating entities</h2>
+
+<p>As said before, we build our private
+&quot;symboltable&quot;, while scanning the EM-instructions.
+The behaviour of the EM-machine is not only reflected in the
+fake-stack, but also in the entities. When an entity is
+created, we do not yet know its value, so we assign a brand
+new value number to it. Each time a store-instruction is
+encountered, we change the value number of the target entity
+of this store to the value number of the token that was
+popped from the fake-stack. Because entities may overlap, we
+must also &quot;forget&quot; the value numbers of entities
+that might be affected by this store. Each such entity will
+be <i>killed</i>, i.e. assigned a brand new valuenumber.</p>
+
+<p>Because we lose information when we forget the value
+number of an entity, we try to save as much entities as
+possible. When we store into an external, we don&rsquo;t
+have to kill locals and vice versa. Furthermore, we can see
+whether two locals or two externals overlap, because we know
+the offset from the local base, resp. the offset within the
+data block, and the size. The situation becomes more
+complicated when we have to consider indirection. The worst
+case is that we store through an unknown pointer. In that
+case we kill all entities except those locals for which a
+so-called <i>register message</i> has been generated; this
+register message indicates that this local can never be
+accessed indirectly. If we know this pointer we can be more
+careful. If it points to a local then the entity that is
+accessed through this pointer can never overlap with an
+external. If it points to an external this entity can never
+overlap with a local. Furthermore, in the latter case, we
+can find the data block this entity belongs to. Since
+pointer arithmetic is only defined within a data block, this
+entity can never overlap with entities that are known to
+belong to another data block.</p>
+
+<p>Not only after a store-instruction but also after a
+subroutine-call it may be necessary to kill entities; the
+subroutine may affect global variables or store through a
+pointer. If a subroutine is called that is not available as
+EM-text, we assume worst case behaviour, i.e. we kill all
+entities without register message.</p>
+<a name="7.4.4. Additions and replacements."></a>
+<h2>7.4.4. Additions and replacements.</h2>
+
+<p>When a new expression comes available, we check whether
+the result is saved in a local that may go in a register.
+The last line of the expression must be followed by a STL or
+SDL instruction, depending on the size of the result (resp.
+WS and 2*WS), and a register message must be present for
+this local. If we have found such a local, we store a
+pointer to it with the available expression. Each time a new
+occurrence of this expression is found, we compare the value
+number of the local against the value number of the result.
+When they are different we remove the pointer to it, because
+we cannot use it.</p>
+
+<p>The available expressions are singly linked in a list.
+When a new expression comes available, we link it at the
+head of the list. In this way expressions that are contained
+within other expressions appear later in the list, because
+EM-expressions are postfix. When we are going to eliminate
+expressions, we walk through the list, starting at the head,
+to find the largest expressions first. When we decide to
+eliminate an expression, we look at the expressions in the
+tail of the list, starting from where we are now, to delete
+expressions that are contained within the chosen one because
+we cannot eliminate an expression more than once.</p>
+
+<p>When we are going to eliminate expressions, and we do
+not have a local that holds the result, we emit a STL or SDL
+after the line where the expression was first found. The
+other occurrences are simply removed, unless they contain
+instructions that not only have effect on the stack; e.g.
+messages, stores, calls. Before each instruction that needs
+the result on the stack, we emit a LOL or LDL. When the
+expression was an AAR, but the instruction was a LAR or a
+SAR, we append a LOI resp. a STI of the number of bytes in
+an array-element after each LOL/LDL.</p>
+<a name="7.4.5. Desirability analysis"></a>
+<h2>7.4.5. Desirability analysis</h2>
+
+<p>Although the global optimizer works on EM code, the goal
+is to improve the quality of the object code. Therefore we
+need some machine dependent information to decide whether it
+is desirable to eliminate a given expression. Because it is
+impossible for the CS phase to know exactly what code will
+be generated, we use some heuristics. In most cases it will
+save time when we eliminate an operator, so we just do it.
+We only look for some special cases.</p>
+
+<p>Some operators can in some cases be translated into an
+addressing mode for the machine at hand. We only eliminate
+such an operator, when its operand is itself
+&quot;expensive&quot;, i.e. not just a simple load. The user
+of the CS phase has to supply a set of such operators.</p>
+
+<p>Eliminating the loading of the Local Base or the
+Argument Base by the LXL resp. LXA instruction is only
+beneficial when the number of lexical levels we have to go
+back exceeds a certain threshold. This threshold will be
+different when registers are saved by the back end. The user
+must supply this threshold.</p>
+
+<p>Replacing a SAR or a LAR by an AAR followed by a LOI may
+possibly increase the size of the object code. We assume
+that this is only possible when the size of the array
+element is greater than some (user-supplied) limit.</p>
+
+<p>There are back ends that can very efficiently translate
+the index computing instruction sequence LOC SLI ADS. If
+this is the case, we do not eliminate the SLI instruction
+between a LOC and an ADS.</p>
+
+<p>To handle unforeseen cases, the user may also supply a
+set of operators that should never be eliminated.</p>
+<a name="7.4.6. The algorithm"></a>
+<h2>7.4.6. The algorithm</h2>
+
+<p>After these preparatory explanations, we can be short
+about the algorithm itself. For each instruction within our
+window, the following steps are performed in the order
+given:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>We check if this instructin defines an entity. If this
+is the case the set of entities is updated accordingly.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>We kill all entities that might be affected by this
+instruction.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>The instruction is simulated on the fake-stack. Copy
+propagation is done. If this instruction is an operator, we
+update the list of available expressions accordingly.</p>
+</td>
+</table>
+
+<p>When we have processed all instructions this way, we
+have built a list of available expressions plus the
+information we need to eliminate them. Those expressions of
+which desirability analysis tells us so, we eliminate. The
+we shift our window and continue.</p>
+<a name="7.5. Source files of CS"></a>
+<h2>7.5. Source files of CS</h2>
+
+<p>The sources of CS are in the following files and
+packages:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>cs.h</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>declarations of global variables and data structures</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>cs.c</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>the routine main; a driving routine to process the basic
+blocks in the right order</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>vnm</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>implements a procedure that performs the value numbering
+on one basic block</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>eliminate</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>implements a procedure that does the transformations, if
+desirable</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>avail</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>implements a procedure that manipulates the list of
+available expressions</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>entity</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>implements a procedure that manipulates the set of
+entities</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>getentity</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>implements a procedure that extracts the pseudo
+symboltable information from EM-instructions; uses a small
+table</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>kill</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>implements several routines that find the entities that
+might be changed by EM-instructions and kill them</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>partition</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>implements several routines that partition the huge set
+of EM-instructions into more or less manageable, more or
+less logical chunks</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>profit</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>implements a procedure that decides whether it is
+advantageous to eliminate an expression; also removes
+expressions with side-effects</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>stack</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>implements the fake-stack and operations on it</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>alloc</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>implements several allocation routines</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>aux</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>implements several auxiliary routines</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>debug</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>implements several routines to provide debugging and
+verbose output</p>
+</td>
+</table>
+<a name="8. Stack pollution"></a>
+<h2>8. Stack pollution</h2>
+<a name="8.1. Introduction"></a>
+<h2>8.1. Introduction</h2>
+
+<p>The &quot;Stack Pollution&quot; optimization technique
+(SP) decreases the costs (time as well as space) of
+procedure calls. In the EM calling sequence, the actual
+parameters are popped from the stack by the <i>calling</i>
+procedure. The ASP (Adjust Stack Pointer) instruction is
+used for this purpose. A call in EM is shown in Fig. 8.1</p>
+
+<p align=center><img src="grohtml-1027230.png"></p>
+
+<p>Fig. 8.1 An example procedure call in Pascal and EM</p>
+
+<p>As procedure calls occur often in most programs, the ASP
+is one of the most frequently used EM instructions.</p>
+
+<p>The main intention of removing the actual parameters
+after a procedure call is to avoid the stack size to
+increase rapidly. Yet, in some cases, it is possible to
+<i>delay</i> or even <i>avoid</i> the removal of the
+parameters without letting the stack grow significantly. In
+this way, considerable savings in code size and execution
+time may be achieved, at the cost of a slightly increased
+stack size.</p>
+
+<p>A stack adjustment may be delayed if there is some other
+stack adjustment later on in the same basic block. The two
+ASPs can be combined into one.</p>
+
+<p align=center><img src="grohtml-1027231.png"></p>
+
+<p>Fig. 8.2 An example of local Stack Pollution</p>
+
+<p>The stacksize will be increased only temporarily. If the
+basic block contains another ASP, the ASP 10 may
+subsequently be combined with that next ASP, and so on.</p>
+
+<p>For some back ends, a stack adjustment also takes place
+at the point of a procedure return. There is no need to
+specify the number of bytes to be popped at a return. This
+provides an opportunity to remove ASPs more globally. If all
+ASPs outside any loop are removed, the increase of the stack
+size will still only be small, as no such ASP is executed
+more than once without an intervening return from the
+procedure it is part of.</p>
+
+<p>This second approach is not generally applicable to all
+target machines, as some back ends require the stack to be
+cleaned up at the point of a procedure return.</p>
+<a name="8.2. Implementation"></a>
+<h2>8.2. Implementation</h2>
+
+<p>There is one main problem the implementation has to
+solve. In EM, the stack is not only used for passing
+parameters, but also for evaluating expressions. Hence, ASP
+instructions can only be combined or removed if certain
+conditions are satisfied.</p>
+
+<p>Two consecutive ASPs of one basic block can only be
+combined (as described above) if:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>On no point of text in between the two ASPs, any item is
+popped from the stack that was pushed onto it before the
+first ASP.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>The number of bytes popped from the stack by the second
+ASP must equal the number of bytes pushed since the first
+ASP.</p>
+</td>
+</table>
+
+<p>Condition 1. is not satisfied in Fig. 8.3.</p>
+
+<p align=center><img src="grohtml-1027232.png"></p>
+
+<p>Fig. 8.3 An illegal transformation</p>
+
+<p>If the first ASP were removed (delayed), the first ADI
+would add 10 and f(10), instead of 5 and f(10).</p>
+
+<p>Condition 2. is not satisfied in Fig. 8.4.</p>
+
+<p align=center><img src="grohtml-1027233.png"></p>
+
+<p>Fig. 8.4 A second illegal transformation</p>
+
+<p>If the two ASPs were combined into one &rsquo;ASP
+4&rsquo;, the constant 5 would have been popped, rather than
+the parameter 10 (so &rsquo;10 + f(10)*g(30)&rsquo; would
+have been computed).</p>
+
+<p>The second approach to deleting ASPs (i.e. let the
+procedure return do the stack clean-up) is only applied to
+the last ASP of every basic block. Any preceding ASPs are
+dealt with by the first approach. The last ASP of a basic
+block B will only be removed if:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>on no path in the control flow graph from B to any block
+containing a RET (return) there is a basic block that, at
+some point of its text, pops items from the stack that it
+has not itself pushed earlier.</p>
+</td>
+</table>
+
+<p>Clearly, if this condition is satisfied, no harm can be
+done; no other basic block will ever access items that were
+pushed on the stack before the ASP.</p>
+
+<p>The number of bytes pushed onto or popped from the stack
+can be easily encoded in a so called &quot;pop-push
+table&quot;. The numbers in general depend on the target
+machine word- and pointer size and on the argument given to
+the instruction. For example, an ADS instruction is
+described by:</p>
+<pre>        -a-p+p
+</pre>
+
+<p>which means: an &rsquo;ADS n&rsquo; first pops an n-byte
+value (n being the argument), next pops a pointer-size value
+and finally pushes a pointer-size value. For some
+infrequently used EM instructions the pop-push numbers
+cannot be computed statically.</p>
+
+<p>The stack pollution algorithm first performs a depth
+first search over the control flow graph and marks all
+blocks that do not satisfy the global condition. Next it
+visits all basic blocks in turn. For every pair of adjacent
+ASPs, it checks conditions 1. and 2. and combines the ASPs
+if they are satisfied. The new ASP may be used as first ASP
+in the next pair. If a condition fails, it simply continues
+with the next ASP. Finally, the last ASP is removed if:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>nothing has been popped from the stack after the last
+ASP that was pushed before it</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the block was not marked by the depth first search</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="52%">
+
+<p>the block is not in a loop</p>
+</td>
+<td width="37%">
+</td>
+</table>
+<a name="9. Cross jumping"></a>
+<h2>9. Cross jumping</h2>
+<a name="9.1. Introduction"></a>
+<h2>9.1. Introduction</h2>
+
+<p>The &quot;Cross Jumping&quot; optimization technique
+(CJ) [Wulf75a] is basically a space optimization technique.
+It looks for pairs of basic blocks (B1,B2), for which:</p>
+<pre>     SUCC(B1) = SUCC(B2) = {S}
+</pre>
+
+<p>(So B1 and B2 both have one and the same successor). If
+the last few non-branch instructions are the same for B1 and
+B2, one such sequence can be eliminated.</p>
+<pre>     Pascal:
+
+
+     if cond then
+         S1
+         S3
+     else
+         S2
+         S3
+
+
+     (pseudo) EM:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+
+<p align=center><img src="grohtml-1027234.png"></p>
+
+<p>Fig. 9.1 An example of Cross Jumping</p>
+
+<p>As the basic blocks have the same successor, at least
+one of them ends in an unconditional branch instruction
+(BRA). Hence no extra branch instruction is ever needed,
+just the target of an existing branch needs to be changed;
+neither the program size nor the execution time will ever
+increase. In general, the execution time will remain the
+same, unless further optimizations can be applied because of
+this optimization.</p>
+
+<p>This optimization is particularly effective, because it
+cannot always be done by the programmer at the source level,
+as demonstrated by the Fig. 8.2.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>Pascal:</p>
+</table>
+
+<p>if cond then<br>
+x := f(4)<br>
+else<br>
+x := g(5)</p>
+
+<p>EM:</p>
+
+<p align=center><img src="grohtml-1027235.png"></p>
+
+<p>Fig. 9.2 Effectiveness of Cross Jumping</p>
+
+<p>At the source level there is no common tail, but at the
+EM level there is a common tail.</p>
+<a name="9.2. Implementation"></a>
+<h2>9.2. Implementation</h2>
+
+<p>The implementation of cross jumping is rather
+straightforward. The technique is applied to one procedure
+at a time. The control flow graph of the procedure is
+scanned for pairs of basic blocks with the same (single)
+successor and with common tails. Note that there may be more
+than two such blocks (e.g. as the result of a case
+statement). This is dealt with by repeating the entire
+process until no further optimizations can de done for the
+current procedure.</p>
+
+<p>If a suitable pair of basic blocks has been found, the
+control flow graph must be altered. One of the basic blocks
+must be split into two. The control flow graphs before and
+after the optimization are shown in Fig. 9.3 and Fig.
+9.4.</p>
+<pre>             --------                                --------
+             |      |                                |      |
+             | S1   |                                | S2   |
+             | S3   |                                | S3   |
+             |      |                                |      |
+             --------                                --------
+                |                                       |
+                |------------------|--------------------|
+                                   |
+                                   v
+
+
+     Fig. 9.3 CFG before optimization
+</pre>
+<pre>             --------                                --------
+             |      |                                |      |
+             | S1   |                                | S2   |
+             |      |                                |      |
+             --------                                --------
+                |                                       |
+                |--------------------&lt;------------------|
+                v
+             --------
+             |      |
+             | S3   |
+             |      |
+             --------
+                |
+                v
+
+
+     Fig. 9.4 CFG after optimization
+</pre>
+
+<p>Some attributes of the three resulting blocks (such as
+immediate dominator) are updated.</p>
+
+<p>In some cases, cross jumping might split the computation
+of an expression into two, by inserting a branch somewhere
+in the middle. Most code generators will generate very poor
+assembly code when presented with such EM code. Therefor,
+cross jumping is not performed in these cases.</p>
+<a name="10. Branch Optimization"></a>
+<h2>10. Branch Optimization</h2>
+<a name="10.1. Introduction"></a>
+<h2>10.1. Introduction</h2>
+
+<p>The Branch Optimization phase (BO) performs two related
+(branch) optimizations.</p>
+<a name="10.1.1. Fusion of basic blocks"></a>
+<h2>10.1.1. Fusion of basic blocks</h2>
+
+<p>If two basic blocks B1 and B2 have the following
+properties:</p>
+<pre>     SUCC(B1) = {B2}
+     PRED(B2) = {B1}
+</pre>
+
+<p>then B1 and B2 can be combined into one basic block. If
+B1 ends in an unconditional jump to the beginning of B2,
+this jump can be eliminated, hence saving a little execution
+time and object code size. This technique can be used to
+eliminate some deficiencies introduced by the front ends
+(for example, the &quot;C&quot; front end translates switch
+statements inefficiently due to its one pass nature).</p>
+<a name="10.1.2. While-loop optimization"></a>
+<h2>10.1.2. While-loop optimization</h2>
+
+<p>The straightforward way to translate a while loop is to
+put the test for loop termination at the beginning of the
+loop.</p>
+<pre>     while cond loop                       LAB1: Test cond
+        body of the loop     ---&gt;                Branch On False To LAB2
+     end loop                                    code for body of loop
+                                                 Branch To LAB1
+                                           LAB2:
+
+
+     Fig. 10.1 Example of Branch Optimization
+</pre>
+
+<p>If the condition fails at the Nth iteration, the
+following code gets executed (dynamically):</p>
+
+<p align=center><img src="grohtml-1027236.png"></p>
+
+<p>An alternative translation is:</p>
+<pre>          Branch To LAB2
+     LAB1:
+          code for body of loop
+     LAB2:
+          Test cond
+          Branch On True To LAB1
+</pre>
+
+<p>This translation results in the following profile:</p>
+
+<p align=center><img src="grohtml-1027237.png"></p>
+
+<p>So the second translation will be significantly faster
+if N &gt;&gt; 2. If N=2, execution time will be slightly
+increased. On the average, the program will be speeded up.
+Note that the code sizes of the two translations will be the
+same.</p>
+<a name="10.2. Implementation"></a>
+<h2>10.2. Implementation</h2>
+
+<p>The basic block fusion technique is implemented by
+traversing the control flow graph of a procedure, looking
+for basic blocks B with only one successor (S). If one is
+found, it is checked if S has only one predecessor (which
+has to be B). If so, the two basic blocks can in principle
+be combined. However, as one basic block will have to be
+moved, the textual order of the basic blocks will be
+altered. This reordering causes severe problems in the
+presence of conditional jumps. For example, if S ends in a
+conditional branch, the basic block that comes textually
+next to S must stay in that position. So the transformation
+in Fig. 10.2 is illegal.</p>
+
+<p align=center><img src="grohtml-1027238.png"></p>
+
+<p>Fig. 10.2 An illegal transformation of Branch
+Optimization</p>
+
+<p>If B is moved towards S the same problem occurs if the
+block before B ends in a conditional jump. The problem could
+be solved by adding one extra branch, but this would reduce
+the gains of the optimization to zero. Hence the
+optimization will only be done if the block that follows S
+(in the textual order) is not a successor of S. This
+condition assures that S does not end in a conditional
+branch. The condition always holds for the code generated by
+the &quot;C&quot; front end for a switch statement.</p>
+
+<p>After the transformation has been performed, some
+attributes of the basic blocks involved (such as successor
+and predecessor sets and immediate dominator) must be
+recomputed.</p>
+
+<p>The while-loop technique is applied to one loop at a
+time. The list of basic blocks of the loop is traversed to
+find a block B that satisfies the following conditions:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>the textually next block to B is not part of the
+loop</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>the last instruction of B is an unconditional branch;
+hence B has only one successor, say S</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>the textually next block of B is a successor of S</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>the last instruction of S is a conditional branch</p>
+</td>
+</table>
+
+<p>If such a block B is found, the control flow graph is
+changed as depicted in Fig. 10.3.</p>
+<pre>            |                                    |
+            |                                    v
+            v                                    |
+            |-----&lt;------|                       -----&gt;-----|
+        ____|____        |                                  |
+        |       |        |               |-------|          |
+        |  S1   |        |               |       v          |
+        |  Bcc  |        |               |     ....         |
+     |--|       |        |               |                  |
+     |  ---------        |               |   ----|----      |
+     |                   |               |   |       |      |
+     |     ....          ^               |   |  S2   |      |
+     |                   |               |   |       |      |
+     |   ---------       |               |   |       |      |
+     v   |       |       |               ^   ---------      |
+     |   |  S2   |       |               |       |          |
+     |   | BRA   |       |               |       |-----&lt;-----
+     |   |       |       |               |       v
+     |   ---------       |               |   ____|____
+     |       |           |               |   |       |
+     |       ------&gt;------               |   |  S1   |
+     |                                   |   |  Bnn  |
+     |-------|                           |   |       |
+             |                           |   ----|----
+             v                           |       |
+                                         |----&lt;--|
+                                                 |
+                                                 v
+
+
+     Fig. 10.3 Transformation of the CFG by Branch Optimization
+</pre>
+<a name="11. Use-Definition analysis"></a>
+<h2>11. Use-Definition analysis</h2>
+<a name="11.1. Introduction"></a>
+<h2>11.1. Introduction</h2>
+
+<p>The &quot;Use-Definition analysis&quot; phase (UD)
+consists of two related optimization techniques that both
+depend on &quot;Use-Definition&quot; information. The
+techniques are Copy Propagation and Constant Propagation.
+They are best explained via an example (see Figs. 11.1 and
+11.2).</p>
+<pre>        (1)  A := B                  A := B
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>... --&gt; ...</p>
+</table>
+
+<p>(2) use(A) use(B)</p>
+
+<p>Fig. 11.1 An example of Copy Propagation</p>
+<pre>        (1)  A := 12                  A := 12
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>... --&gt; ...</p>
+</table>
+
+<p>(2) use(A) use(12)</p>
+
+<p>Fig. 11.2 An example of Constant Propagation</p>
+
+<p>Both optimizations have to check that the value of A at
+line (2) can only be obtained at line (1). Copy Propagation
+also has to assure that the value of B is the same at line
+(1) as at line (2).</p>
+
+<p>One purpose of both transformations is to introduce
+opportunities for the Dead Code Elimination optimization. If
+the variable A is used nowhere else, the assignment A := B
+becomes useless and can be eliminated.<br>
+If B is less expensive to access than A (e.g. this is
+sometimes the case if A is a local variable and B is a
+global variable), Copy Propagation directly improves the
+code itself. If A is cheaper to access the transformation
+will not be performed. Likewise, a constant as operand may
+be cheeper than a variable. Having a constant as operand may
+also facilitate other optimizations.</p>
+
+<p>The design of UD is based on the theory described in
+section 14.1 and 14.3 of. [Aho78a] As a main departure from
+that theory, we do not demand the statement A := B to become
+redundant after Copy Propagation. If B is cheaper to access
+than A, the optimization is always performed; if B is more
+expensive than A, we never do the transformation. If A and B
+are equally expensive UD uses the heuristic rule to replace
+infrequently used variables by frequently used ones. This
+rule increases the chances of the assignment to become
+useless.</p>
+
+<p>In the next section we will give a brief outline of the
+data flow theory used for the implementation of UD.</p>
+<a name="11.2. Data flow information"></a>
+<h2>11.2. Data flow information</h2>
+<a name="11.2.1. Use-Definition information"></a>
+<h2>11.2.1. Use-Definition information</h2>
+
+<p>A <i>definition</i> of a variable A is an assignment to
+A. A definition is said to <i>reach</i> a point p if there
+is a path in the control flow graph from the definition to
+p, such that A is not redefined on that path.</p>
+
+<p>For every basic block B, we define the following
+sets:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>GEN[b]</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>the set of definitions in b that reach the end of b.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>KILL[b]</p>
+</td>
+<td width="4%"></td>
+<td width="82%">
+
+<p>the set of definitions outside b that define a variable
+that is changed in b.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>IN[b]</p>
+</td>
+<td width="8%"></td>
+<td width="82%">
+
+<p>the set of all definitions reaching the beginning of
+b.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>OUT[b]</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>the set of all definitions reaching the end of b.</p>
+</td>
+</table>
+
+<p>GEN and KILL can be determined by inspecting the code of
+the procedure. IN and OUT are computed by solving the
+following data flow equations:</p>
+<pre>     (1)    OUT[b] = IN[b] - KILL[b] + GEN[b]
+     (2)    IN[b]  = OUT[p1] + ... + OUT[pn],
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>where PRED(b) = {p1, ... , pn}</p>
+</table>
+<a name="11.2.2. Copy information"></a>
+<h2>11.2.2. Copy information</h2>
+
+<p>A <i>copy</i> is a definition of the form &quot;A :=
+B&quot;. A copy is said to be <i>generated</i> in a basic
+block n if it occurs in n and there is no subsequent
+assignment to B in n. A copy is said to be <i>killed</i> in
+n if:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>it occurs in n and there is a subsequent assignment to B
+within n, or</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="2%"></td>
+<td width="90%">
+
+<p>it occurs outside n, the definition A := B reaches the
+beginning of n and B is changed in n (note that a copy also
+is a definition).</p>
+</td>
+</table>
+
+<p>A copy <i>reaches</i> a point p, if there are no
+assignments to B on any path in the control flow graph from
+the copy to p.</p>
+
+<p>We define the following sets:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>C_GEN[b]</p>
+</td>
+<td width="6%"></td>
+<td width="78%">
+
+<p>the set of all copies in b generated in b.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>C_KILL[b]</p>
+</td>
+<td width="4%"></td>
+<td width="68%">
+
+<p>the set of all copies killed in b.</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>C_IN[b]</p>
+</td>
+<td width="8%"></td>
+<td width="78%">
+
+<p>the set of all copies reaching the beginning of b.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>C_OUT[b]</p>
+</td>
+<td width="6%"></td>
+<td width="78%">
+
+<p>the set of all copies reaching the end of b.</p>
+</td>
+</table>
+
+<p>C_IN and C_OUT are computed by solving the following
+equations: (root is the entry node of the current procedure;
+&rsquo;*&rsquo; denotes set intersection)</p>
+<pre>     (1)    C_OUT[b] = C_IN[b] - C_KILL[b] + C_GEN[b]
+     (2)    C_IN[b]  = C_OUT[p1] * ... * C_OUT[pn],
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>where PRED(b) = {p1, ... , pn} and b /= root</p>
+</table>
+
+<p>C_IN[root] = {all copies}</p>
+<a name="11.3. Pointers and subroutine calls"></a>
+<h2>11.3. Pointers and subroutine calls</h2>
+
+<p>The theory outlined above assumes that variables can
+only be changed by a direct assignment. This condition does
+not hold for EM. In case of an assignment through a pointer
+variable, it is in general impossible to see which variable
+is affected by the assignment. Similar problems occur in the
+presence of procedure calls. Therefore we distinguish two
+kinds of definitions:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>an <i>explicit</i> definition is a direct assignment to
+one specific variable</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>an <i>implicit</i> definition is the potential
+alteration of a variable as a result of a procedure call or
+an indirect assignment.</p>
+</td>
+</table>
+
+<p>An indirect assignment causes implicit definitions to
+all variables that may be accessed indirectly, i.e. all
+local variables for which no register message was generated
+and all global variables. If a procedure contains an
+indirect assignment it may change the same set of variables,
+else it may change some global variables directly. The KILL,
+GEN, IN and OUT sets contain explicit as well as implicit
+definitions.</p>
+<a name="11.4. Implementation"></a>
+<h2>11.4. Implementation</h2>
+
+<p>UD first builds a number of tables:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>locals:</p>
+</td>
+<td width="4%"></td>
+<td width="82%">
+
+<p>contains information about the local variables of the
+current procedure (offset,size,whether a register message
+was found for it and, if so, the score field of that
+message)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>defs:</p>
+</td>
+<td width="8%"></td>
+<td width="82%">
+
+<p>a table of all explicit definitions appearing in the
+current procedure.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>copies:</p>
+</td>
+<td width="4%"></td>
+<td width="82%">
+
+<p>a table of all copies appearing in the current
+procedure.</p>
+</td>
+</table>
+
+<p>Every variable (local as well as global), definition and
+copy is identified by a unique number, which is the index in
+the table. All tables are constructed by traversing the EM
+code. A fourth table, &quot;vardefs&quot; is used, indexed
+by a &rsquo;variable number&rsquo;, which contains for every
+variable the set of explicit definitions of it. Also, for
+each basic block b, the set CHGVARS containing all variables
+changed by it is computed.</p>
+
+<p>The GEN sets are obtained in one scan over the EM text,
+by analyzing every EM instruction. The KILL set of a basic
+block b is computed by looking at the set of variables
+changed by b (i.e. CHGVARS[b]). For every such variable v,
+all explicit definitions to v (i.e. vardefs[v]) that are not
+in GEN[b] are added to KILL[b]. Also, the implicit
+defininition of v is added to KILL[b]. Next, the data flow
+equations for use-definition information are solved, using a
+straight forward, iterative algorithm. All sets are
+represented as bitvectors, so the operations on sets (union,
+difference) can be implemented efficiently.</p>
+
+<p>The C_GEN and C_KILL sets are computed simultaneously in
+one scan over the EM text. For every copy A := B appearing
+in basic block b we do the following:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>for every basic block n /= b that changes B, see if the
+definition A := B reaches the beginning of n (i.e. check if
+the index number of A := B in the &quot;defs&quot; table is
+an element of IN[n]); if so, add the copy to C_KILL[n]</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>if B is redefined later on in b, add the copy to
+C_KILL[b], else add it to C_GEN[b]</p>
+</td>
+</table>
+
+<p>C_IN and C_OUT are computed from C_GEN and C_KILL via
+the second set of data flow equations.</p>
+
+<p>Finally, in one last scan all opportunities for
+optimization are detected. For every use u of a variable A,
+we check if there is a unique explicit definition d reaching
+u.</p>
+
+<p>If the definition is a copy A := B and B has the same
+value at d as at u, then the use of A at u may be changed
+into B. The latter condition can be verified as follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>if u and d are in the same basic block, see if there is
+any assignment to B in between d and u</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>if u and d are in different basic blocks, the condition
+is satisfied if there is no assignment to B in the block of
+u prior to u and d is in C_IN[b].</p>
+</td>
+</table>
+
+<p>Before the transformation is actually done, UD first
+makes sure the alteration is really desirable, as described
+before. The information needed for this purpose (access
+costs of local and global variables) is read from a machine
+descriptor file.</p>
+
+<p>If the only definition reaching u has the form &quot;A
+:= constant&quot;, the use of A at u is replaced by the
+constant.</p>
+<a name="11.5. Source files of UD"></a>
+<h2>11.5. Source files of UD</h2>
+
+<p>The sources of UD are in the following files and
+packages:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>ud.h:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>declarations of global variables and data structures</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>ud.c:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>the routine main; initialization of target machine
+dependent tables</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>defs:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>routines to compute the GEN and KILL sets and routines
+to analyse EM instructions</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>const:</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>routines involved in constant propagation</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>copy:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>routines involved in copy propagation</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>aux:</p>
+</td>
+<td width="20%"></td>
+<td width="54%">
+
+<p>contains auxiliary routines</p>
+</td>
+<td width="17%">
+</td>
+</table>
+<a name="12. Live-Variable analysis"></a>
+<h2>12. Live-Variable analysis</h2>
+<a name="12.1. Introduction"></a>
+<h2>12.1. Introduction</h2>
+
+<p>The &quot;Live-Variable analysis&quot; optimization
+technique (LV) performs some code improvements and computes
+information that may be used by subsequent optimizations.
+The main task of this phase is the computation of
+<i>live-variable information</i>. [Aho78a section 14.4] A
+variable A is said to be <i>dead</i> at some point p of the
+program text, if on no path in the control flow graph from p
+to a RET (return), A can be used before being changed; else
+A is said to be <i>live</i>.</p>
+
+<p>A statement of the form</p>
+<pre>     VARIABLE := EXPRESSION
+</pre>
+
+<p>is said to be dead if the left hand side variable is
+dead just after the statement and the right hand side
+expression has no side effects (i.e. it doesn&rsquo;t change
+any variable). Such a statement can be eliminated entirely.
+Dead code will seldom be present in the original program,
+but it may be the result of earlier optimizations, such as
+copy propagation.</p>
+
+<p>Live-variable information is passed to other phases via
+messages in the EM code. Live/dead messages are generated at
+points in the EM text where variables become dead or live.
+This information is especially useful for the Register
+Allocation phase.</p>
+<a name="12.2. Implementation"></a>
+<h2>12.2. Implementation</h2>
+
+<p>The implementation uses algorithm 14.6 of. [Aho78a]
+First two sets DEF and USE are computed for every basic
+block b:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>DEF(b)</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>the set of all variables that are assigned a value in b
+before being used</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>USE(b)</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>the set of all variables that may be used in b before
+being changed.</p>
+</td>
+</table>
+
+<p>(So variables that may, but need not, be used resp.
+changed via a procedure call or through a pointer are
+included in USE but not in DEF). The next step is to compute
+the sets IN and OUT :</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>IN[b]</p>
+</td>
+<td width="8%"></td>
+<td width="82%">
+
+<p>the set of all variables that are live at the beginning
+of b</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>OUT[b]</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>the set of all variables that are live at the end of
+b</p>
+</td>
+</table>
+
+<p>IN and OUT can be computed for all blocks simultaneously
+by solving the data flow equations:</p>
+<pre>     (1)   IN[b] = OUT[b] - DEF[b] + USE[b]
+     [2]   OUT[b] = IN[s1] + ... + IN[sn] ;
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>where SUCC[b] = {s1, ... , sn}</p>
+</table>
+
+<p>The equations are solved by a similar algorithm as for
+the Use Definition equations (see previous chapter).</p>
+
+<p>Finally, each basic block is visited in turn to remove
+its dead code and to emit the live/dead messages. Every
+basic block b is traversed from its last instruction
+backwards to the beginning of b. Initially, all variables
+that are dead at the end of b are marked dead. All others
+are marked live. If we come across an assignment to a
+variable X that was marked live, a live-message is put after
+the assignment and X is marked dead; if X was marked dead,
+the assignment may be removed, provided that the right hand
+side expression contains no side effects. If we come across
+a use of a variable X that was marked dead, a dead-message
+is put after the use and X is marked live. So at any point,
+the mark of X tells whether X is live or dead immediately
+before that point. A message is also generated at the start
+of a basic block for every variable that was live at the end
+of the (textually) previous block, but dead at the entry of
+this block, or v.v.</p>
+
+<p>Only local variables are considered. This significantly
+reduces the memory needed by this phase, eases the
+implementation and is hardly less efficient than considering
+all variables. (Note that it is very hard to prove that an
+assignment to a global variable is dead).</p>
+<a name="13. Register Allocation"></a>
+<h2>13. Register Allocation</h2>
+<a name="13.1. Introduction"></a>
+<h2>13.1. Introduction</h2>
+
+<p>The efficient usage of the general purpose registers of
+the target machine plays a key role in any optimizing
+compiler. This subject, often referred to as <i>Register
+Allocation</i>, has great impact on both the code generator
+and the optimizing part of such a compiler. The code
+generator needs registers for at least the evaluation of
+arithmetic expressions; the optimizer uses the registers to
+decrease the access costs of frequently used entities (such
+as variables). The design of an optimizing compiler must pay
+great attention to the cooperation of optimization, register
+allocation and code generation.</p>
+
+<p>Register allocation has received much attention in
+literature (see [Leve81a, Chai81a, Frei74a] and
+[Site79a]).</p>
+<a name="13.2. Usage of registers in ACK compilers"></a>
+<h2>13.2. Usage of registers in ACK compilers</h2>
+
+<p>We will first describe the major design decisions of the
+Amsterdam Compiler Kit, as far as they concern register
+allocation. Subsequently we will outline the role of the
+Global Optimizer in the register allocation process and the
+interface between the code generator and the optimizer.</p>
+<a name="13.2.1. Usage of registers without the intervention of the Global Optimizer"></a>
+<h2>13.2.1. Usage of registers without the intervention of the Global Optimizer</h2>
+
+<p>Registers are used for two purposes:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="88%">
+
+<p>for the evaluation of arithmetic expressions</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>to hold local variables, for the duration of the
+procedure they are local to.</p>
+</td>
+</table>
+
+<p>It is essential to note that no translation part of the
+compilers, except for the code generator, knows anything at
+all about the register set of the target computer. Hence all
+decisions about registers are ultimately made by the code
+generator. Earlier phases of a compiler can only
+<i>advise</i> the code generator.</p>
+
+<p>The code generator splits the register set into two: a
+fixed part for the evaluation of expressions (called
+<i>scratch</i> registers) and a fixed part to store local
+variables. This partitioning, which depends only on the
+target computer, significantly reduces the complexity of
+register allocation, at the penalty of some loss of code
+quality.</p>
+
+<p>The code generator has some (machine-dependent)
+knowledge of the access costs of memory locations and
+registers and of the costs of saving and restoring
+registers. (Registers are always saved by the <i>called</i>
+procedure). This knowledge is expressed in a set of
+procedures for each target machine. The code generator also
+knows how many registers there are and of which type they
+are. A register can be of type <i>pointer</i>, <i>floating
+point</i> or <i>general</i>.</p>
+
+<p>The front ends of the compilers determine which local
+variables may be put in a register; such a variable may
+never be accessed indirectly (i.e. through a pointer). The
+front end also determines the types and sizes of these
+variables. The type can be any of the register types or the
+type <i>loop variable</i>, which denotes a general-typed
+variable that is used as loop variable in a for-statement.
+All this information is collected in a <i>register
+message</i> in the EM code. Such a message is a pseudo EM
+instruction. This message also contains a <i>score</i>
+field, indicating how desirable it is to put this variable
+in a register. A front end may assign a high score to a
+variable if it was declared as a register variable (which is
+only possible in some languages, such as &quot;C&quot;). Any
+compiler phase before the code generator may change this
+score field, if it has reason to do so. The code generator
+bases its decisions on the information contained in the
+register message, most notably on the score.</p>
+
+<p>If the global optimizer is not used, the score fields
+are set by the Peephole Optimizer. This optimizer simply
+counts the number of occurrences of every local (register)
+variable and adds this count to the score provided by the
+front end. In this way a simple, yet quite effective
+register allocation scheme is achieved.</p>
+<a name="13.2.2. The role of the Global Optimizer"></a>
+<h2>13.2.2. The role of the Global Optimizer</h2>
+
+<p>The Global Optimizer essentially tries to improve the
+scheme outlined above. It uses the following principles for
+this purpose:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Entities are not always assigned a register for the
+duration of an entire procedure; smaller regions of the
+program text may be considered too.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>several variables may be put in the same register
+simultaneously, provided at most one of them is live at any
+point.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>besides local variables, other entities (such as
+constants and addresses of variables and procedures) may be
+put in a register.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="76%">
+
+<p>more accurate cost estimates are used.</p>
+</td>
+<td width="13%">
+</td>
+</table>
+
+<p>To perform its task, the optimizer must have some
+knowledge of the target machine.</p>
+<a name="13.2.3. The interface between the register allocator and the code generator"></a>
+<h2>13.2.3. The interface between the register allocator and the code generator</h2>
+
+<p>The RA phase of the optimizer must somehow be able to
+express its decisions. Such decisions may look like:
+&rsquo;put constant 1283 in a register from line 12 to line
+40&rsquo;. To be precise, RA must be able to tell the code
+generator to:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="74%">
+
+<p>initialize a register with some value</p>
+</td>
+<td width="15%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="64%">
+
+<p>update an entity from a register</p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>replace all occurrences of an entity in a certain region
+of text by a reference to the register.</p>
+</td>
+</table>
+
+<p>At least three problems occur here: the code generator
+is only used to put local variables in registers, it only
+assigns a register to a variable for the duration of an
+entire procedure and it is not used to have some earlier
+compiler phase make all the decisions.</p>
+
+<p>All problems are solved by one mechanism, that involves
+no changes to the code generator. With every (non-scratch)
+register R that will be used in a procedure P, we associate
+a new variable T, local to P. The size of T is the same as
+the size of R. A register message is generated for T with an
+exceptionally high score. The scores of all original
+register messages are set to zero. Consequently, the code
+generator will always assign precisely those new variables
+to a register. If the optimizer wants to put some entity,
+say the constant 1283, in a register, it emits the code
+&quot;T := 1283&quot; and replaces all occurrences of
+&rsquo;1283&rsquo; by T. Similarly, it can put the address
+of a procedure in T and replace all calls to that procedure
+by indirect calls. Furthermore, it can put several different
+entities in T (and thus in R) during the lifetime of P.</p>
+
+<p>In principle, the code generated by the optimizer in
+this way would always be valid EM code, even if the
+optimizer would be presented a totally wrong description of
+the target computer register set. In practice, it would be a
+waste of data as well as text space to allocate memory for
+these new variables, as they will always be assigned a
+register (in the correct order of events). Hence, no memory
+locations are allocated for them. For this reason they are
+called pseudo local variables.</p>
+<a name="13.3. The register allocation phase"></a>
+<h2>13.3. The register allocation phase</h2>
+<a name="13.3.1. Overview"></a>
+<h2>13.3.1. Overview</h2>
+
+<p>The RA phase deals with one procedure at a time. For
+every procedure, it first determines which entities may be
+put in a register. Such an entity is called an <i>item</i>.
+For every item it decides during which parts of the
+procedure it might be assigned a register. Such a region is
+called a <i>timespan</i>. For any item, several (possibly
+overlapping) timespans may be considered. A pair
+(item,timespan) is called an <i>allocation</i>. If the items
+of two allocations are both live at some point of time in
+the intersections of their timespans, these allocations are
+said to be <i>rivals</i> of each other, as they cannot be
+assigned the same register. The rivals-set of every
+allocation is computed. Next, the gains of assigning a
+register to an allocation are estimated, for every
+allocation. With all this information, decisions are made
+which allocations to store in which registers
+(<i>packing</i>). Finally, the EM text is transformed to
+reflect these decisions.</p>
+<a name="13.3.2. The item recognition subphase"></a>
+<h2>13.3.2. The item recognition subphase</h2>
+
+<p>RA tries to put the following entities in a
+register:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>a local variable for which a register message was
+found</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the address of a local variable for which no register
+message was found</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="64%">
+
+<p>the address of a global variable</p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="52%">
+
+<p>the address of a procedure</p>
+</td>
+<td width="37%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="38%">
+
+<p>a numeric constant.</p>
+</td>
+<td width="51%">
+</td>
+</table>
+
+<p>Only the <i>address</i> of a global variable may be put
+in a register, not the variable itself. This approach avoids
+the very complex problems that would be caused by procedure
+calls and indirect pointer references (see [Aho78a sections
+14.7 and 14.8] and [Spil71a]). Still, on most machines
+accessing a global variable using indirect addressing
+through a register is much cheaper than accessing it via its
+address. Similarly, if the address of a procedure is put in
+a register, the procedure can be called via an indirect
+call.</p>
+
+<p>With every item we associate a register type. This type
+is</p>
+<pre>     for local variables: the type contained in the register message
+     for addresses of variables and procedures: the pointer type
+     for constants: the general type
+</pre>
+
+<p>An entity other than a local variable is not taken to be
+an item if it is used only once within the current
+procedure.</p>
+
+<p>An item is said to be <i>live</i> at some point of the
+program text if its value may be used before it is changed.
+As addresses and constants are never changed, all items but
+local variables are always live. The region of text during
+which a local variable is live is determined via the
+live/dead messages generated by the Live Variable analysis
+phase of the Global Optimizer.</p>
+<a name="13.3.3. The allocation determination subphase"></a>
+<h2>13.3.3. The allocation determination subphase</h2>
+
+<p>If a procedure has more items than registers, it may be
+advantageous to put an item in a register only during those
+parts of the procedure where it is most heavily used. Such a
+part will be called a timespan. With every item we may
+associate a set of timespans. If two timespans of an item
+overlap, at most one of them may be granted a register, as
+there is no use in putting the same item in two registers
+simultaneously. If two timespans of an item are distinct,
+both may be chosen; the item will possibly be put in two
+different registers during different parts of the procedure.
+The timespan may also consist of the whole procedure.</p>
+
+<p>A list of (item,timespan) pairs (allocations) is build,
+which will be the input to the decision making subphase of
+RA (packing subphase). This allocation list is the main data
+structure of RA. The description of the remainder of RA will
+be in terms of allocations rather than items. The phrase
+&quot;to assign a register to an allocation&quot; means
+&quot;to assign a register to the item of the allocation for
+the duration of the timespan of the allocation&quot;.
+Subsequent subphases will add more information to this
+list.</p>
+
+<p>Several factors must be taken into account when a
+timespan for an item is constructed:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>At any <i>entry point</i> of the timespan where the item
+is live, the register must be initialized with the item</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>At any exit point of the timespan where the item is
+live, the item must be updated.</p>
+</td>
+</table>
+
+<p>In order to decrease these costs, we will only consider
+timespans with one entry point and no live exit points.</p>
+<a name="13.3.4. The rivals computation subphase"></a>
+<h2>13.3.4. The rivals computation subphase</h2>
+
+<p>As stated before, several different items may be put in
+the same register, provided they are not live
+simultaneously. For every allocation we determine the
+intersection of its timespan and the lifetime of its item
+(i.e. the part of the procedure during which the item is
+live). The allocation is said to be busy during this
+intersection. If two allocations are ever busy
+simultaneously they are said to be rivals of each other. The
+rivals information is added to the allocation list.</p>
+<a name="13.3.5. The profits computation subphase"></a>
+<h2>13.3.5. The profits computation subphase</h2>
+
+<p>To make good decisions, the packing subphase needs to
+know which allocations can be assigned the same register
+(rivals information) and how much is gained by granting an
+allocation a register.</p>
+
+<p>Besides the gains of using a register instead of an
+item, two kinds of overhead costs must be taken into
+account:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the register must be initialized with the item</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the register must be saved at procedure entry and
+restored at procedure exit.</p>
+</td>
+</table>
+
+<p>The latter costs should not be due to a single
+allocation, as several allocations can be assigned the same
+register. These costs are dealt with after packing has been
+done. They do not influence the decisions of the packing
+algorithm, they may only undo them.</p>
+
+<p>The actual profits consist of improvements of execution
+time and code size. As the former is far more difficult to
+estimate , we will discuss code size improvements first.</p>
+
+<p>The gains of putting a certain item in a register
+depends on how the item is used. Suppose the item is a
+pointer variable. On machines that do not have a
+double-indirect addressing mode, two instructions are needed
+to dereference the variable if it is not in a register, but
+only one if it is put in a register. If the variable is not
+dereferenced, but simply copied, one instruction may be
+sufficient in both cases. So the gains of putting a pointer
+variable in a register are higher if the variable is
+dereferenced often.</p>
+
+<p>To make accurate estimates, detailed knowledge of the
+target machine and of the code generator would be needed.
+Therefore, a simplification has been made that substantially
+limits the amount of target machine information that is
+needed. The estimation of the number of bytes saved does not
+take into account how an item is used. Rather, an average
+number is used. So these gains are computed as follows:</p>
+<pre>     #bytes_saved = #occurrences * gains_per_occurrence
+</pre>
+
+<p>The number of occurrences is derived from the EM code.
+Note that this is not exact either, as there is no
+one-to-one correspondence between occurrences in the EM code
+and in the assembler code.</p>
+
+<p>The gains of one occurrence depend on:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p>the type of the item</p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p>the size of the item</p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="48%">
+
+<p>the type of the register</p>
+</td>
+<td width="41%">
+</td>
+</table>
+
+<p>and for local variables and addresses of local
+variables:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p>the type of the local variable</p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="6%"></td>
+<td width="88%">
+
+<p>the offset of the variable in the stackframe</p>
+</td>
+<td width="1%">
+</td>
+</table>
+
+<p>For every allocation we try two types of registers: the
+register type of the item and the general register type.
+Only the type with the highest profits will subsequently be
+used. This type is added to the allocation information.</p>
+
+<p>To compute the gains, RA uses a machine-dependent table
+that is read from a machine descriptor file. By means of
+this table the number of bytes saved can be computed as a
+function of the five properties.</p>
+
+<p>The costs of initializing a register with an item is
+determined in a similar way. The cost of one initialization
+is also obtained from the descriptor file. Note that there
+can be at most one initialization for any allocation.</p>
+
+<p>To summarize, the number of bytes a certain allocation
+would save is computed as follows:</p>
+
+<p align=center><img src="grohtml-1027239.png"></p>
+
+<p>It is inherently more difficult to estimate the
+execution time saved by putting an item in a register,
+because it is impossible to predict how many times an item
+will be used dynamically. If an occurrence is part of a
+loop, it may be executed many times. If it is part of a
+conditional statement, it may never be executed at all. In
+the latter case, the speed of the program may even get worse
+if an initialization is needed. As a clear example, consider
+the piece of &quot;C&quot; code in Fig. 13.1.</p>
+<pre>     switch(expr) {
+           case 1:  p(); break;
+           case 2:  p(); p(); break;
+           case 3:  p(); break;
+           default: break;
+     }
+
+
+     Fig. 13.1 A &quot;C&quot; switch statement
+</pre>
+
+<p>Lots of bytes may be saved by putting the address of
+procedure p in a register, as p is called four times
+(statically). Dynamically, p will be called zero, one or two
+times, depending on the value of the expression.</p>
+
+<p>The optimizer uses the following strategy for optimizing
+execution time:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>try to put items in registers during <i>loops</i>
+first</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>always keep the initializing code outside the loop</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>if an item is not used in a loop, do not put it in a
+register if the initialization costs may be higher than the
+gains</p>
+</td>
+</table>
+
+<p>The latter condition can be checked by determining the
+minimal number of usages (dynamically) of the item during
+the procedure, via a shortest path algorithm. In the example
+above, this minimal number is zero, so the address of p is
+not put in a register.</p>
+
+<p>The costs of one occurrence is estimated as described
+above for the code size. The number of dynamic occurrences
+is guessed by looking at the loop nesting level of every
+occurrence. If the item is never used in a loop, the minimal
+number of occurrences is used. From these facts, the
+execution time improvement is assessed for every
+allocation.</p>
+<a name="13.3.6. The packing subphase"></a>
+<h2>13.3.6. The packing subphase</h2>
+
+<p>The packing subphase takes as input the allocation list
+and outputs a description of which allocations should be put
+in which registers. So it is essentially the decision making
+part of RA.</p>
+
+<p>The packing system tries to assign a register to
+allocations one at a time, in some yet to be defined order.
+For every allocation A, it first checks if there is a
+register (of the right type) that is already assigned to one
+or more allocations, none of which are rivals of A. In this
+case A is assigned the same register. Else, A is assigned a
+new register, if one exists. A table containing the number
+of free registers for every type is maintained. It is
+initialized with the number of non-scratch registers of the
+target computer and updated whenever a new register is
+handed out. The packing algorithm stops when no more
+allocations can or need be assigned a register.</p>
+
+<p>After an allocation A has been packed, all allocations
+with non-disjunct timespans (including A itself) are removed
+from the allocation list.</p>
+
+<p>In case the number of items exceeds the number of
+registers, it is important to choose the most profitable
+allocations. Due to the possibility of having several
+allocations occupying the same register, this problem is
+quite complex. Our packing algorithm uses simple heuristic
+rules and avoids any combinatorial search. It has distinct
+rules for different costs measures.</p>
+
+<p>If object code size is the most important factor, the
+algorithm is greedy and chooses allocations in decreasing
+order of their profits attribute. It does not take into
+account the fact that other allocations may be passed over
+because of this decision.</p>
+
+<p>If execution time is at prime stake, the algorithm first
+considers allocations whose timespans consist of loops.
+After all these have been packed, it considers the remaining
+allocations. Within the two subclasses, it considers
+allocations with the highest profits first. When assigning a
+register to an allocation with a loop as timespan, the
+algorithm checks if the item has already been put in a
+register during another loop. If so, it tries to use the
+same register for the new allocation. After all packing has
+been done, it checks if the item has always been assigned
+the same register (although not necessarily during all
+loops). If so, it tries to put the item in that register
+during the entire procedure. This is possible if the
+allocation (item,whole_procedure) is not a rival of any
+allocation with a different item that has been assigned to
+the same register. Note that this approach is essentially
+&rsquo;bottom up&rsquo;, as registers are first assigned
+over small regions of text which are later collapsed into
+larger regions. The advantage of this approach is the fact
+that the decisions for one loop can be made independently of
+all other loops.</p>
+
+<p>After the entire packing process has been completed, we
+compute for each register how much is gained in using this
+register, by simply adding the net profits of all
+allocations assigned to it. This total yield should outweigh
+the costs of saving/restoring the register at procedure
+entry/exit. As most modern processors (e.g. 68000, Vax) have
+special instructions to save/restore several registers, the
+differential costs of saving one extra register are by no
+means constant. The costs are read from the machine
+descriptor file and compared to the total yields of the
+registers. As a consequence of this analysis, some
+allocations may have their registers taken away.</p>
+<a name="13.3.7. The transformation subphase"></a>
+<h2>13.3.7. The transformation subphase</h2>
+
+<p>The final subphase of RA transforms the EM text
+according to the decisions made by the packing system. It
+traverses the text of the currently optimized procedure and
+changes all occurrences of items at points where they are
+assigned a register. It also clears the score field of the
+register messages for normal local variables and emits
+register messages with a very high score for the pseudo
+locals. At points where registers have to be initialized
+with items, it generates EM code to do so. Finally it tries
+to decrease the size of the stackframe of the procedure by
+looking at which local variables need not be given memory
+locations.</p>
+<a name="13.4. Source files of RA"></a>
+<h2>13.4. Source files of RA</h2>
+
+<p>The sources of RA are in the following files and
+packages:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>ra.h:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>declarations of global variables and data structures</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>ra.c:</p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>the routine main; initialization of target
+machine-dependent tables</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>items:</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>a routine to build the list of items of one procedure;
+routines to manipulate items</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>lifetime:</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>contains a subroutine that determines when items are
+live/dead</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>alloclist:</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>contains subroutines that build the initial allocations
+list and that compute the rivals sets.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>profits:</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>contains a subroutine that computes the profits of the
+allocations and a routine that determines the costs of
+saving/restoring registers</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>pack:</p>
+</td>
+<td width="18%"></td>
+<td width="58%">
+
+<p>contains the packing subphase</p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>xform:</p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>contains the transformation subphase</p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>interval:</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>contains routines to manipulate intervals of time</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>aux:</p>
+</td>
+<td width="20%"></td>
+<td width="54%">
+
+<p>contains auxiliary routines</p>
+</td>
+<td width="17%">
+</td>
+</table>
+<a name="14. Compact assembly generation"></a>
+<h2>14. Compact assembly generation</h2>
+<a name="14.1. Introduction"></a>
+<h2>14.1. Introduction</h2>
+
+<p>The &quot;Compact Assembly generation phase&quot; (CA)
+transforms the intermediate code of the optimizer into EM
+code in Compact Assembly Language (CAL) format. In the
+intermediate code, all program entities (such as procedures,
+labels, global variables) are denoted by a unique
+identifying number (see 3.5). In the CAL output of the
+optimizer these numbers have to be replaced by normal
+identifiers (strings). The original identifiers of the input
+program are used whenever possible. Recall that the IC phase
+generates two files that can be used to map unique
+identifying numbers to procedure names and global variable
+names. For instruction labels CA always generates new names.
+The reasons for doing so are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>instruction labels are only visible inside one
+procedure, so they can not be referenced in other
+modules</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the names are not very suggestive anyway, as they must
+be integer numbers</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the optimizer considerably changes the control structure
+of the program, so there is really no one to one mapping of
+instruction labels in the input and the output program.</p>
+</td>
+</table>
+
+<p>As the optimizer combines all input modules into one
+module, visibility problems may occur. Two modules M1 and M2
+can both define an identifier X (provided that X is not
+externally visible in any of these modules). If M1 and M2
+are combined into one module M, two distinct entities with
+the same name would exist in M, which is not allowed.
+[Tane83a, section 11.1.4.3] In these cases, CA invents a new
+unique name for one of the entities.</p>
+<a name="14.2. Implementation"></a>
+<h2>14.2. Implementation</h2>
+
+<p>CA first reads the files containing the procedure and
+global variable names and stores the names in two tables. It
+scans these tables to make sure that all names are
+different. Subsequently it reads the EM text, one procedure
+at a time, and outputs it in CAL format. The major part of
+the code that does the latter transformation is adapted from
+the EM Peephole Optimizer.</p>
+
+<p>The main problem of the implementation of CA is to
+assure that the visibility rules are obeyed. If an
+identifier must be externally visible (i.e. it was
+externally visible in the input program) and the identifier
+is defined (in the output program) before being referenced,
+an EXA or EXP pseudo must be generated for it. (Note that
+the optimizer may change the order of definitions and
+references, so some pseudos may be needed that were not
+present in the input program). On the other hand, an
+identifier may be only internally visible. If such an
+identifier is referenced before being defined, an INA or INP
+pseudo must be emitted prior to its first reference.</p>
+<a name="Acknowledgements"></a>
+<h2>Acknowledgements</h2>
+
+<p>The author would like to thank Andy Tanenbaum for his
+guidance, Duk Bekema for implementing the Common
+Subexpression Elimination phase and writing the initial
+documentation of that phase, Dick Grune for reading the
+manuscript of this report and Ceriel Jacobs, Ed Keizer,
+Martin Kersten, Hans van Staveren and the members of the
+S.T.W. user&rsquo;s group for their interest and
+assistance.</p>
+<a name="References"></a>
+<h2>References</h2>
+<a name="References"></a>
+<h2>References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>a.</p>
+</td>
+<td width="95%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>b.</p>
+</td>
+<td width="95%">
+</td>
+</table>
+
+<p>Aho74a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.V. Aho, J.E. Hopcroft, and J.D. Ullman, <i>The Design
+and Analysis of Computer Algorithms,</i> Addison-Wesley,
+Reading, Massachusetts (1974).</p>
+</td>
+</table>
+
+<p>Aho78a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.V. Aho and J.D. Ullman, <i>Principles of compiler
+design,</i> Addison-Wesley, Reading, Massachusetts
+(1978).</p>
+</td>
+</table>
+
+<p>Alle81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>F.E. Allen, J. Cocke, and K. Kennedy, &ldquo;Reduction of
+Operator Strength&rdquo; in <i>Program Flow Analysis,</i>
+ed. S.S. Muchnick and D. Jones, Prentice-Hall, Englewood
+Cliffs, N.J. (1981).</p>
+</td>
+</table>
+
+<p>Ankl82a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>P. Anklam, D. Cutler, R. Heinen, and M. MacLaren,
+<i>Engineering a compiler: Vax-11 code generation and
+optimization,</i> Digital Equipment Corporation (1982).</p>
+</td>
+</table>
+
+<p>Bal86a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>H.E. Bal and A.S. Tanenbaum, &ldquo;Language- and
+Machine-independent Global Optimization on Intermediate
+Code,&rdquo; <i>Computer Languages,</i> 11, 2, pp. 105-121
+(April 1986).</p>
+</td>
+</table>
+
+<p>Ball79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>J.E. Ball, &ldquo;Predicting the Effects of Optimization
+on a Procedure Body,&rdquo; <i>SIGPLAN Notices,</i> 14, 8,
+pp. 214-220 (August 1979).</p>
+</td>
+</table>
+
+<p>Cart77a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>J.L. Carter, &ldquo;A Case Study of a New Code Generation
+Technique for Compilers,&rdquo; <i>CACM,</i> 20, 12, pp.
+914-920 (December 1977).</p>
+</td>
+</table>
+
+<p>Cart82a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>L.R. Carter, <i>An analysis of Pascal Programs,</i> UMI
+Research Press, Ann Arbor, Michigan (1982).</p>
+</td>
+</table>
+
+<p>Chai81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>G.J. Chaitin, M.A. Auslander, A.K. Chandra, J. Cocke,
+M.E. Hopkins, and P.W. Markstein, &ldquo;Register Allocation
+via Coloring,&rdquo; <i>Computer Languages,</i> 6, 1, pp.
+47-57 (January 1981).</p>
+</td>
+</table>
+
+<p>Cock77a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>J. Cocke and K. Kennedy, &ldquo;An algorithm for
+Reduction of Operator Strength,&rdquo; <i>CACM,</i> 20, 11,
+pp. 850-856 (November 1977).</p>
+</td>
+</table>
+
+<p>Davi81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>J.W. Davidson, &ldquo;Simplifying Code Generation Through
+Peephole Optimization,&rdquo; Ph.D. thesis, Dept. of
+Computer Science, Univ. of Arizona (December 1981).</p>
+</td>
+</table>
+
+<p>Faim80a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>R.N. Faiman and A.A. Kortesoja, &ldquo;An Optimizing
+Pascal Compiler,&rdquo; <i>IEEE Trans. on Softw. Eng.,</i>
+6, 6, pp. 512-518 (November 1980).</p>
+</td>
+</table>
+
+<p>Frei74a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>R.A. Freiburghouse, &ldquo;Register Allocation Via Usage
+Counts,&rdquo; <i>CACM,</i> 17, 11, pp. 638-642 (November
+1974).</p>
+</td>
+</table>
+
+<p>Freu83a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>S.M. Freudenberger and J.T. Schwartz, &ldquo;Experience
+with the SETL Optimizer,&rdquo; <i>TOPLAS,</i> 5, 1, pp.
+26-45 (Januari 1983).</p>
+</td>
+</table>
+
+<p>Harr79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>W.H. Harrison, &ldquo;A New Strategy for Code Generation
+- the General-Purpose Optimizing Compiler,&rdquo; <i>IEEE
+Trans. on Softw. Eng.,</i> 5, 4, pp. 367-373 (July
+1979).</p>
+</td>
+</table>
+
+<p>Ichb83a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>J.D. Ichbiah, &ldquo;Ada Programming Language - MILITARY
+STANDARD,&rdquo; ANSI/MIL-STD-1815A, U.S. Department of
+Defense (22 January 1983).</p>
+</td>
+</table>
+
+<p>Ichb79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>J.D. Ichbiah, &ldquo;Rationale for the Design of the Ada
+Programming Language,&rdquo; <i>SIGPLAN Notices,</i> 14, 6
+(June 1979).</p>
+</td>
+</table>
+
+<p>John81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>S.C. Johnson and D.M. Ritchie, <i>The C Language Calling
+Sequence,</i> Bell Laboratories, Murray Hill, New Jersey
+(September 1981).</p>
+</td>
+</table>
+
+<p>Katk73a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>G.R. Katkus, &ldquo;A study of selective optimization
+techniques,&rdquo; Ph.D. Thesis, University of Southern
+California (1973).</p>
+</td>
+</table>
+
+<p>Kenn81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>K. Kennedy, &ldquo;A Survey of Data Flow Analysis
+Techniques&rdquo; in <i>Program Flow Analysis,</i> ed. S.S.
+Muchnick and D. Jones, Prentice-Hall, Englewood Cliffs
+(1981).</p>
+</td>
+</table>
+
+<p>Kern79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>B.W. Kernighan and M.D. McIlroy, <i>Unix
+programmer&rsquo;s manual, Seventh Edition,</i> 1, Bell
+Laboratories, Murray Hill, New Jersey (January 1979).</p>
+</td>
+</table>
+
+<p>Kirc83a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>W. Kirchgaesner, J. Uhl, G. Winterstein, G. Goos, M.
+Dausmann, and S. Drossopoulou, <i>An Optimizing Ada
+Compiler,</i> Institut fur Informatik II, Universitat
+Karlsruhe (February 1983).</p>
+</td>
+</table>
+
+<p>Leng79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>T. Lengauer and R.E. Tarjan, &ldquo;A Fast Algorithm for
+Finding Dominators in a Flowgraph,&rdquo; <i>TOPLAS,</i> 1,
+1, pp. 121-141 (July 1979).</p>
+</td>
+</table>
+
+<p>Leve81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>B.W. Leverett, &ldquo;Register Allocation in Optimizing
+Compilers,&rdquo; Ph.D. Thesis, CMU-CS-81-103,
+Carnegie-Mellon University, Pittsburgh (February 1981).</p>
+</td>
+</table>
+
+<p>Leve79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>B.W. Leverett, R.G.G Cattell, S.O. Hobbs, J.M. Newcomer,
+A.H. Reiner, B.R. Schatz, and W.A. Wulf, &ldquo;An Overview
+of the Production-Quality Compiler-Compiler Project,&rdquo;
+CMU-CS-79-105, Carnegie-Mellon University, Pittsburgh
+(1979).</p>
+</td>
+</table>
+
+<p>Leve80a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>B.W. Leverett, R.G.G Cattell, S.O. Hobbs, J.M. Newcomer,
+A.H. Reiner, B.R. Schatz, and W.A. Wulf, &ldquo;An Overview
+of the Production-Quality Compiler-Compiler Project,&rdquo;
+<i>IEEE Computer,</i> 13, 8, pp. 38-49 (August 1980).</p>
+</td>
+</table>
+
+<p>Lowr69a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>E.S. Lowry and C.W. Medlock, &ldquo;Object Code
+Optimization,&rdquo; <i>CACM,</i> 12, 1, pp. 13-22 (Januari
+1969).</p>
+</td>
+</table>
+
+<p>Mint79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>R.J. Mintz, G.A. Fisher, and M. Sharir, &ldquo;The design
+of a global optimizer,&rdquo; <i>SIGPLAN Notices,</i> 14, 9,
+pp. 226-234 (September 1979).</p>
+</td>
+</table>
+
+<p>More79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>E. Morel and C. Renvoise, &ldquo;Global Optimization by
+Suppression of Partial Redundancies,&rdquo; <i>CACM,</i> 22,
+2, pp. 96-103 (February 1979).</p>
+</td>
+</table>
+
+<p>Perk79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>D.R. Perkins and R.L. Sites, &ldquo;Machine-independent
+Pascal code optimization,&rdquo; <i>SIGPLAN Notices,</i> 14,
+8, pp. 201-207 (August 1979).</p>
+</td>
+</table>
+
+<p>Phot81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>D.S. Photopoulos, &ldquo;Optimal mixed code generation
+for microcomputers,&rdquo; Ph.D. Thesis, Northeastern
+University (1981).</p>
+</td>
+</table>
+
+<p>Poel72a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>W.L. van der Poel, <i>The Programming Languages LISP and
+TRAC,</i> Technische Hogeschool Delft, Delft (1972).</p>
+</td>
+</table>
+
+<p>Prab80a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>B. Prabhala and R. Sethi, &ldquo;Efficient Computation of
+Expressions with Common Subexpressions,&rdquo; <i>JACM,</i>
+27, 1, pp. 146-163 (Januari 1980).</p>
+</td>
+</table>
+
+<p>Purd72a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>P.W. Purdom and E.F. Moore, &ldquo;Immediate
+Predominators in a Directed Graph,&rdquo; <i>CACM,</i> 15,
+8, pp. 777-778 (August 1972).</p>
+</td>
+</table>
+
+<p>Ritc78a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>D.M. Ritchie, <i>The C Programming Language - Reference
+Manual,</i> Bell Laboratories, Murray Hill, New Jersey
+(1978).</p>
+</td>
+</table>
+
+<p>Sche77a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>R.W. Scheifler, &ldquo;An Analysis of Inline Substitution
+for a Structured Programming Language,&rdquo; <i>CACM,</i>
+20, 9, pp. 647-654 (September 1977).</p>
+</td>
+</table>
+
+<p>Seth70a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>R. Sethi and J.D. Ullman, &ldquo;The Generation of
+Optimal Code for Arithmetic Expressions,&rdquo; <i>JACM,</i>
+17, 4, pp. 715-728 (October 1970).</p>
+</td>
+</table>
+
+<p>Shaf78a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>J.B. Shaffer, &ldquo;Automatic subroutine generation in
+an optimizing compiler,&rdquo; Ph.D. Thesis, University of
+Maryland (1978).</p>
+</td>
+</table>
+
+<p>Site79a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>R.L. Sites, &ldquo;Machine-independent register
+allocation,&rdquo; <i>SIGPLAN Notices,</i> 14, 8, pp.
+221-225 (August 1979).</p>
+</td>
+</table>
+
+<p>Spil71a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>T.C. Spillman, &ldquo;Exposing side-effects in a PL/I
+optimizing compiler&rdquo; in <i>Information Processing
+1971,</i> pp. 376-381, North-Holland Publishing Company,
+Amsterdam (1971).</p>
+</td>
+</table>
+
+<p>Tane83a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, H. van Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;Description of a machine architecture for
+use with block structured languages,&rdquo; Rapport nr
+IR-81, Vrije Universiteit, Amsterdam (August 1983).</p>
+</td>
+</table>
+
+<p>Tane81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, H. van Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;A Practical Toolkit for Making Portable
+Compilers,&rdquo; Rapport nr IR-74, Vrije Universiteit,
+Amsterdam (October 1981).</p>
+</td>
+</table>
+
+<p>Tane83b.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, H. van Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;A Practical Toolkit for Making Portable
+Compilers,&rdquo; <i>CACM,</i> 26, 9, pp. 654-660 (September
+1983).</p>
+</td>
+</table>
+
+<p>Wulf75a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>W.A. Wulf, R.K. Johnsson, C.B. Weinstock, S.O. Hobbs, and
+C.M. Geschke, <i>The Design of an Optimizing Compiler,</i>
+American Elsevier Publishing Company, New York (1975).</p>
+</td>
+</table>
+
+<p>Wulf80a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>W.M. Wulf, &ldquo;PQCC: A Machine-Relative Compiler
+Technology,&rdquo; CMU-CS-80-144, Carnegie-Mellon
+University, Pittsburgh (25 september 1980).</p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/ego.pdf b/src/olddocs/ego.pdf
new file mode 100644 (file)
index 0000000..e69f36d
Binary files /dev/null and b/src/olddocs/ego.pdf differ
diff --git a/src/olddocs/em.html b/src/olddocs/em.html
new file mode 100644 (file)
index 0000000..826c002
--- /dev/null
@@ -0,0 +1,12846 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:05 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title></title>
+</head>
+<body>
+
+<hr>
+
+<p align=center>DESCRIPTION OF A MACHINE<br>
+ARCHITECTURE FOR USE WITH<br>
+BLOCK STRUCTURED LANGUAGES</p>
+
+<p align=center>Andrew S. Tanenbaum<br>
+Hans van Staveren<br>
+Ed G. Keizer<br>
+Johan W. Stevenson*</p>
+
+<p align=center>August 1983</p>
+
+<p align=center>Informatica Rapport IR-81</p>
+
+<p align=center>Abstract</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>EM is a family of intermediate languages designed for
+producing portable compilers. A program called <b>front
+end</b> translates source programs to EM. Another program,
+<b>back end</b>, translates EM to the assembly language of
+the target machine. Alternatively, the EM program can be
+assembled to a highly efficient binary format for
+interpretation. This document describes the EM languages in
+detail.</p>
+<!-- INDENTATION -->
+<p>* Present affiliation: NV Philips, Eindhoven</p></td>
+</table>
+
+<p>1</p>
+
+<p><b>1. INTRODUCTION</b></p>
+
+<p>EM is a family of intermediate languages designed for
+producing portable compilers. The general strategy is for a
+program called <b>front end</b> to translate the source
+program to EM. Another program, <b>back end</b>, translates
+EM to target assembly language. Alternatively, the EM code
+can be assembled to a binary form and interpreted. These
+considerations led to the following goals:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>1</p>
+</td>
+<td width="8%"></td>
+<td width="28%">
+
+<p>The design should allow translation to, or
+interpretation on, a wide range of existing machines. Design
+decisions should be delayed as far as possible and the
+implications of these decisions should be localized as much
+as possible.</p>
+</td>
+<td width="61%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The current microcomputer technology offers 8, 16 and 32
+bit machines with various sizes of address space. EM should
+be flexible enough to be useful on most of these machines.
+The differences between the members of the EM family should
+only concern the wordsize and address space size.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>2</p>
+</td>
+<td width="8%"></td>
+<td width="30%">
+
+<p>The architecture should ease the task of code generation
+for high level languages such as Pascal, C, Ada, Algol 68,
+BCPL.</p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>3</p>
+</td>
+<td width="8%"></td>
+<td width="30%">
+
+<p>The instruction set used by the interpreter should be
+compact, to reduce the amount of memory needed for program
+storage, and to reduce the time needed to transmit programs
+over communication lines.</p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>3</p>
+</td>
+<td width="8%"></td>
+<td width="30%">
+
+<p>It should be designed with microprogrammed
+implementations in mind; in particular, the use of many
+short fields within instruction opcodes should be avoided,
+because their extraction by the microprogram or conversion
+to other instruction formats is inefficient.</p>
+</td>
+<td width="59%">
+</td>
+</table>
+
+<p>The basic architecture is based on the concept of a
+stack. The stack is used for procedure return addresses,
+actual parameters, local variables, and arithmetic
+operations. There are several built-in object types, for
+example, signed and unsigned integers, floating point
+numbers, pointers and sets of bits. There are instructions
+to push and pop objects to and from the stack. The push and
+pop instructions are not typed. They only care about the
+size of the objects. For each built-in type there are
+reverse Polish type instructions that pop one or more
+objects from the top of the stack, perform an operation, and
+push the result back onto the stack. For all types except
+pointers, these instructions have the object size as
+argument.</p>
+
+<p>There are no visible general registers used for
+arithmetic operands etc. This is in contrast to most third
+generation computers, which usually have 8 or 16 general
+registers. The decision not to have a group of general
+registers was fully intentional, and follows W.L. Van der
+Poel&rsquo;s dictum that a machine should have 0, 1, or an
+infinite number of any feature. General registers have two
+primary uses: to hold intermediate results of complicated
+expressions, e.g.</p>
+<pre>     ((a*b + c*d)/e + f*g/h) * i
+</pre>
+
+<p>and to hold local variables.</p>
+
+<p>Various studies have shown that the average expression
+has fewer than two operands, making the former use of
+registers of doubtful value. The present trend toward
+structured programs consisting of many small procedures
+greatly reduces the value of registers to hold local
+variables because the large number of procedure calls
+implies a large overhead in saving and restoring the
+registers at every call.</p>
+
+<p>Although there are no general purpose registers, there
+are a few internal registers with specific functions as
+follows:</p>
+
+<p align=center><img src="grohtml-97441.png"></p>
+
+<p>Furthermore, reverse Polish code is much easier to
+generate than multi-register machine code, especially if
+highly efficient code is desired. When translating to
+assembly language the back end can make good use of the
+target machine&rsquo;s registers. An EM machine can achieve
+high performance by keeping part of the stack in high speed
+storage (a cache or microprogram scratchpad memory) rather
+than in primary memory.</p>
+
+<p>Again according to van der Poel&rsquo;s dictum, all EM
+instructions have zero or one argument. We believe that
+instructions needing two arguments can be split into two
+simpler ones. The simpler ones can probably be used in other
+circumstances as well. Moreover, these two instructions
+together often have a shorter encoding than the single
+instruction before.</p>
+
+<p>This document describes EM at three different levels:
+the abstract level, the assembly language level and the
+machine language level.<br>
+The most important level is that of the abstract EM
+architecture. This level deals with the basic design issues.
+Only the functional capabilities of instructions are
+relevant, not their format or encoding. Most chapters of
+this document refer to the abstract level and it is
+explicitly stated whenever another level is described.<br>
+The assembly language is intended for the compiler writer.
+It presents a more or less orthogonal instruction set and
+provides symbolic names for data. Moreover, it facilitates
+the linking of separately compiled &rsquo;modules&rsquo;
+into a single program by providing several
+pseudoinstructions.<br>
+The machine language is designed for interpretation with a
+compact program text and easy decoding. The binary
+representation of the machine language instruction set is
+far from orthogonal. Frequent instructions have a short
+opcode. The encoding is fully byte oriented. These bytes do
+not contain small bit fields, because bit fields would slow
+down decoding considerably.</p>
+
+<p>A common use for EM is for producing portable (cross)
+compilers. When used this way, the compilers produce EM
+assembly language as their output. To run the compiled
+program on the target machine, the back end, translates the
+EM assembly language to the target machine&rsquo;s assembly
+language. When this approach is used, the format of the EM
+machine language instructions is irrelevant. On the other
+hand, when writing an interpreter for EM machine language
+programs, the interpreter must deal with the machine
+language and not with the symbolic assembly language.</p>
+
+<p>As mentioned above, the current microcomputer technology
+offers 8, 16 and 32 bit machines with address spaces ranging
+from 2 <small>16</small> to 2 <small>32</small> bytes.
+Having one size of pointers and integers restricts the
+usefulness of the language. We decided to have a different
+language for each combination of word and pointer size. All
+languages offer the same instruction set and differ only in
+memory alignment restrictions and the implicit size assumed
+in several instructions. The languages differ slightly for
+the different size combinations. For example: the size of
+any object on the stack and alignment restrictions. The
+wordsize is restricted to powers of 2 and the pointer size
+must be a multiple of the wordsize. Almost all programs
+handling EM will be parametrized with word and pointer
+size.</p>
+
+<p>2</p>
+
+<p><b>2. MEMORY</b></p>
+
+<p>The EM machine has two distinct address spaces, one for
+instructions and one for data. The data space is divided up
+into 8-bit bytes. The smallest addressable unit is a byte.
+Bytes are numbered consecutively from 0 to some maximum. All
+sizes in EM are expressed in bytes.</p>
+
+<p>Some EM instructions can transfer objects containing
+several bytes to and/or from memory. The size of all objects
+larger than a word must be a multiple of the wordsize. The
+size of all objects smaller than a word must be a divisor of
+the wordsize. For example: if the wordsize is 2 bytes,
+objects of the sizes 1, 2, 4, 6,... are allowed. The address
+of such an object is the lowest address of all bytes it
+contains. For objects smaller than the wordsize, the address
+must be a multiple of the object size. For all other objects
+the address must be a multiple of the wordsize. For example,
+if an instruction transfers a 4-byte object to memory at
+location <i>m</i> and the wordsize is 2, <i>m</i> must be a
+multiple of 2 and the bytes at locations <i>m</i>,
+<i>m</i>+1,<i>m</i>+2 and <i>m</i>+3 are overwritten.</p>
+
+<p>The size of almost all objects in EM is an integral
+number of words. Only two operations are allowed on objects
+whose size is a divisor of the wordsize: push it onto the
+stack and pop it from the stack. The addressing of these
+objects in memory is always indirect. If such a small object
+is pushed onto the stack it is assumed to be a small integer
+and stored in the least significant part of a word. The rest
+of the word is cleared to zero, although EM provides a way
+to sign-extend a small integer. Popping a small object from
+the stack removes a word from the stack, stores the least
+significant byte(s) of this word in memory and discards the
+rest of the word.</p>
+
+<p>The format of pointers into both address spaces is
+explicitly undefined. The size of a pointer, however, is
+fixed for a member of EM, so that the compiler writer knows
+how much storage to allocate for a pointer.</p>
+
+<p>A minor problem is raised by the undefined pointer
+format. Some languages, notably Pascal, require a special,
+otherwise illegal, pointer value to represent the nil
+pointer. The current Pascal-VU compiler uses the integer
+value 0 as nil pointer. This value is also used by many C
+programs as a normally impossible address. A better solution
+would be to have a special instruction loading an illegal
+pointer value, but it is hard to imagine an implementation
+for which the current solution is inadequate, especially
+because the first word in the EM data space is special and
+probably not the target of any pointer.</p>
+
+<p>The next two chapters describe the EM memory in more
+detail. One describes the instruction address space, the
+other the data address space.</p>
+
+<p>A design goal of EM has been to allow its implementation
+on a wide range of existing machines, as well as allowing a
+new one to be built in hardware. To this extent we have
+tried to minimize the demands of EM on the memory structure
+of the target machine. Therefore, apart from the logical
+partitioning, EM memory is divided into
+&rsquo;fragments&rsquo;. A fragment consists of consecutive
+machine words and has a base address and a size. Pointer
+arithmetic is only defined within a fragment. The only
+exception to this rule is comparison with the null pointer.
+All fragments must be word aligned.</p>
+
+<p>3</p>
+
+<p><b>3. INSTRUCTION ADDRESS SPACE</b></p>
+
+<p>The instruction space of the EM machine contains the
+code for procedures. Tables necessary for the execution of
+this code, for example, procedure descriptor tables, may
+also be present. The instruction space does not change
+during the execution of a program, so that it may be
+protected. No further restrictions to the instruction
+address space are necessary for the abstract and assembly
+language level.</p>
+
+<p>Each procedure has a single entry point: the first
+instruction. A special type of pointer identifies a
+procedure. Pointers into the instruction address space have
+the same size as pointers into data space and can, for
+example, contain the address of the first instruction or an
+index in a procedure descriptor table.</p>
+
+<p>There is a single EM program counter, PC, pointing to
+the next instruction to be executed. The procedure pointed
+to by PC is called the &rsquo;current&rsquo; procedure. A
+procedure may call another procedure using the CAL or CAI
+instruction. The calling procedure remains
+&rsquo;active&rsquo; and is resumed whenever the called
+procedure returns. Note that a procedure has several
+&rsquo;active&rsquo; invocations when called
+recursively.</p>
+
+<p>Each procedure must return properly. It is not allowed
+to fall through to the code of the next procedure. There are
+several ways to exit from a procedure:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="24%">
+
+<p>the RET instruction, which returns to the calling
+procedure.</p>
+</td>
+<td width="65%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="24%">
+
+<p>the RTT instruction, which exits a trap handling routine
+and resumes the trapping instruction (see next chapter).</p>
+</td>
+<td width="65%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="24%">
+
+<p>the GTO instruction, which is used for non-local
+goto&rsquo;s. It can remove several frames from the stack
+and transfer control to an active procedure. (see also MES
+11 in paragraph 11.1.4.4)</p>
+</td>
+<td width="65%">
+</td>
+</table>
+
+<p>All branch instructions can transfer control to any
+label within the same procedure. Branch instructions can
+never jump out of a procedure.</p>
+
+<p>Several language implementations use a so called
+procedure instance identifier, a combination of a procedure
+identifier and the LB of a stack frame, also called static
+link.</p>
+
+<p>The program text for each procedure, as well as any
+tables, are fragments and can be allocated anywhere in the
+instruction address space.</p>
+
+<p>4</p>
+
+<p><b>4. DATA ADDRESS SPACE</b></p>
+
+<p>The data address space is divided into three parts,
+called &rsquo;areas&rsquo;, each with its own addressing
+method: global data area, local data area (including the
+stack), and heap data area. These data areas must be part of
+the same address space because all data is accessed by the
+same type of pointers.</p>
+
+<p>Space for global data is reserved using several
+pseudoinstructions in the assembly language, as described in
+the next paragraph and chapter 11. The size of the global
+data area is fixed per program.</p>
+
+<p>Global data is addressed absolutely in the machine
+language. Many instructions are available to address global
+data. They all have an absolute address as argument.
+Examples are LOE, LAE and STE.</p>
+
+<p>Part of the global data area is initialized by the
+compiler, the rest is not initialized at all or is
+initialized with a value, typically &minus;32768 or 0. Part
+of the initialized global data may be made read-only if the
+implementation supports protection.</p>
+
+<p>The local data area is used as a stack, which grows from
+high to low addresses and contains some data for each active
+procedure invocation, called a &rsquo;frame&rsquo;. The size
+of the local data area varies dynamically during execution.
+Below the current procedure frame resides the operand stack.
+The stack pointer SP always points to the bottom of the
+local data area. Local data is addressed by offsetting from
+the local base pointer LB. LB always points to the frame of
+the current procedure. Only the words of the current frame
+and the parameters can be addressed directly. Variables in
+other active procedures are addressed by following the chain
+of statically enclosing procedures using the LXL or LXA
+instruction. The variables in dynamically enclosing
+procedures can be addressed with the use of the DCH
+instruction.</p>
+
+<p>Many instructions have offsets to LB as argument, for
+instance LOL, LAL and STL. The arguments of these
+instructions range from &minus;1 to some (negative) minimum
+for the access of local storage and from 0 to some
+(positive) maximum for parameter access.</p>
+
+<p>The procedure call instructions CAL and CAI each create
+a new frame on the stack. Each procedure has an
+assembly-time parameter specifying the number of bytes
+needed for local storage. This storage is allocated each
+time the procedure is called and must be a multiple of the
+wordsize. Each procedure, therefore, starts with a stack
+with the local variables already allocated. The return
+instructions RET and RTT remove a frame. The actual
+parameters must be removed by the calling procedure.</p>
+
+<p>RET may copy some words from the stack of the returning
+procedure to an unnamed &rsquo;function return area&rsquo;.
+This area is available for &rsquo;READ-ONCE&rsquo; access
+using the LFR instruction. The result of a LFR is only
+defined if the size used to fetch is identical to the size
+used in the last return. The instruction ASP, used to remove
+the parameters from the stack, the branch instruction BRA
+and the non-local goto instruction GTO are the only ones
+that leave the contents of the &rsquo;function return
+area&rsquo; intact. All other instructions are allowed to
+destroy the function return area. Thus parameters can be
+popped before fetching the function result. The maximum size
+of all function return areas is implementation dependent,
+but should allow procedure instance identifiers and all
+implemented objects of type integer, unsigned, float and
+pointer to be returned. In most implementations the maximum
+size of the function return area is twice the pointer size,
+because we want to be able to handle &rsquo;procedure
+instance identifiers&rsquo; which consist of a procedure
+identifier and the LB of a frame belonging to that
+procedure.</p>
+
+<p>The heap data area grows upwards, to higher numbered
+addresses. It is initially empty. The initial value of the
+heap pointer HP marks the low end. The heap pointer may be
+manipulated by the LOR and STR instructions. The heap can
+only be addressed indirectly, by pointers derived from
+previous values of HP.</p>
+
+<p><b>4.1 Global data area</b></p>
+
+<p>The initial size of the global data area is determined
+at assembly time. Global data is allocated by several
+pseudoinstructions in the EM assembly language. Each
+pseudoinstruction allocates one or more bytes. The bytes
+allocated for a single pseudo form a &rsquo;block&rsquo;. A
+block differs from a fragment, because, under certain
+conditions, several blocks are allocated in a single
+fragment. This guarantees that the bytes of these blocks are
+consecutive.</p>
+
+<p>Global data is addressed absolutely in binary machine
+language. Most compilers, however, cannot assign absolute
+addresses to their global variables, especially not if the
+language allows programs to be composed of several
+separately compiled modules. The assembly language therefore
+allows the compiler to name the first address of a global
+data block with an alphanumeric label. Moreover, the only
+way to address such a named global data block in the
+assembly language is by using its name. It is the task of
+the assembler/loader to translate these labels into absolute
+addresses. These labels may also be used in CON and ROM
+pseudoinstructions to initialize pointers.</p>
+
+<p>The pseudoinstruction CON allocates initialized data.
+ROM acts like CON but indicates that the initialized data
+will not change during execution of the program. The
+pseudoinstruction BSS allocates a block of uninitialized or
+identically initialized data. The pseudoinstruction HOL is
+similar to BSS, but it alters the meaning of subsequent
+absolute addressing in the assembly language.</p>
+
+<p>Another type of global data is a small block, called the
+ABS block, with an implementation defined size. Storage in
+this type of block can only be addressed absolutely in
+assembly language. The first word has address 0 and is used
+to maintain the source line number. Special instructions LIN
+and LNI are provided to update this counter. A pointer at
+location 4 points to a string containing the current source
+file name. The instruction FIL can be used to update the
+pointer.</p>
+
+<p>All numeric arguments of the instructions that address
+the global data area refer to locations in the ABS block
+unless they are preceded by at least one HOL pseudo in the
+same module, in which case they refer to the storage area
+allocated by the last HOL pseudoinstruction. Thus LOE 0
+loads the zeroth word of the most recent HOL, unless no HOL
+has appeared in the current file so far, in which case it
+loads the zeroth word of the ABS fragment.</p>
+
+<p>The global data area is highly fragmented. The ABS block
+and each HOL and BSS block are separate fragments. The way
+fragments are formed from CON and ROM blocks is more
+complex. The assemblers group several blocks into a single
+fragment. A fragment only contains blocks of the same type:
+CON or ROM. It is guaranteed that the bytes allocated for
+two consecutive CON pseudos are allocated consecutively in a
+single fragment, unless these CON pseudos are separated in
+the assembly language program by a data label definition or
+one or more of the following pseudos:</p>
+<pre>     ROM, BSS, HOL and END
+</pre>
+
+<p>An analogous rule holds for ROM pseudos.</p>
+
+<p><b>4.2 Local data area</b></p>
+
+<p>The local data area consists of a sequence of frames,
+one for each active procedure. Below the frame of the
+current procedure resides the expression stack. Frames are
+generated by procedure calls and are removed by procedure
+returns. A procedure frame consists of six
+&rsquo;zones&rsquo;:</p>
+<pre>     1.  The return status block
+     2.  The local variables and compiler temporaries
+     3.  The register save block
+     4.  The dynamic local generators
+     5.  The operand stack.
+     6.  The parameters of a procedure one level deeper
+</pre>
+
+<p>A sample frame is shown in Figure 1.</p>
+
+<p>Before a procedure call is performed the actual
+parameters are pushed onto the stack of the calling
+procedure. The exact details are compiler dependent. EM
+allows procedures to be called with a variable number of
+parameters. The implementation of the C-language almost
+forces its runtime system to push the parameters in reverse
+order, that is, the first positional parameter last. Most
+compilers use the C calling convention to be compatible. The
+parameters of a procedure belong to the frame of the calling
+procedure. Note that the evaluation of the actual parameters
+may imply the calling of procedures. The parameters can be
+accessed with certain instructions using offsets of 0 and
+greater. The first byte of the last parameter pushed has
+offset 0. Note that the parameter at offset 0 has a special
+use in the instructions following the static chain (LXL and
+LXA). These instructions assume that this parameter contains
+the LB of the statically enclosing procedure. Procedures
+that do not have a dynamically enclosing procedure do not
+need a static link at offset 0.</p>
+
+<p>Two instructions are available to perform procedure
+calls, CAL and CAI. Several tasks are performed by these
+call instructions.</p>
+
+<p>First, a part of the status of the calling procedure is
+saved on the stack in the return status block. This block
+should contain the return address of the calling procedure,
+its LB and other implementation dependent data. The size of
+this block is fixed for any given implementation because the
+lexical instructions LPB, LXL and LXA must be able to obtain
+the base addresses of the procedure parameters <b>and</b>
+local variables. An alternative solution can be used on
+machines with a highly segmented address space. The stack
+frames need not be contiguous then and the first status save
+area can contain the parameter base AB, which has the value
+of SP just after the last parameter has been pushed.</p>
+
+<p>Second, the LB is changed to point to the first word
+above the local variables. The new LB is a copy of the SP
+after the return status block has been pushed.</p>
+
+<p>Third, the amount of local storage needed by the
+procedure is reserved. The parameters and local storage are
+accessed by the same instructions. Negative offsets are used
+for access to local variables. The highest byte, that is the
+byte nearest to LB, has to be accessed with offset &minus;1.
+The pseudoinstruction specifying the entry point of a
+procedure, has an argument that specifies the amount of
+local storage needed. The local variables allocated by the
+CAI or CAL instructions are the only ones that can be
+accessed with a fixed negative offset. The initial value of
+the allocated words is not defined, but implementations that
+check for undefined values will probably initialize them
+with a special &rsquo;undefined&rsquo; pattern, typically
+&minus;32768.</p>
+
+<p>Fourth, any EM implementation is allowed to reserve a
+variable size block beneath the local variables. This block
+could, for example, be used to save a variable number of
+registers.</p>
+
+<p>Finally, the address of the entry point of the called
+procedure is loaded into the Program Counter.</p>
+
+<p>The ASP instruction can be used to allocate further
+(dynamic) local storage. The base address of such storage
+must be obtained with a LOR SP instruction. This same
+instruction ASP may also be used to remove some words from
+the stack.</p>
+
+<p>There is a version of ASP, called ASS, which fetches the
+number of bytes to allocate from the stack. It can be used
+to allocate space for local objects whose size is unknown at
+compile time, so called &rsquo;dynamic local
+generators&rsquo;.</p>
+
+<p>Control is returned to the calling procedure with a RET
+instruction. Any return value is then copied to the
+&rsquo;function return area&rsquo;. The frame created by the
+call is deallocated and the status of the calling procedure
+is restored. The value of SP just after the return value has
+been popped must be the same as the value of SP just before
+executing the first instruction of this invocation. This
+means that when a RET is executed the operand stack can only
+contain the return value and all dynamically generated
+locals must be deallocated. Violating this restriction might
+result in hard to detect errors. The calling procedure has
+to remove the parameters from the stack. This can be done
+with the aforementioned ASP instruction.</p>
+
+<p>Each procedure frame is a separate fragment. Because any
+fragment may be placed anywhere in memory, procedure frames
+need not be contiguous.</p>
+
+<p><tt>|===============================| | actual parameter
+n-1 | |-------------------------------| | . | | . | | . |
+|-------------------------------| | actual parameter 0 | (
+&lt;&minus; AB ) |===============================|</tt></p>
+
+<p><tt>|===============================|
+|///////////////////////////////| |///// return status block
+/////| |///////////////////////////////| &lt;&minus; LB
+|===============================| | | | local variables | |
+| |-------------------------------| | | | compiler
+temporaries | | | |===============================|
+|///////////////////////////////| |///// register save block
+/////| |///////////////////////////////|
+|===============================| | | | dynamic local
+generators | | | |===============================| | operand
+| |-------------------------------| | operand |
+|===============================| | parameter m-1 |
+|-------------------------------| | . | | . | | . |
+|-------------------------------| | parameter 0 |
+&lt;&minus; SP |===============================|</tt></p>
+
+<p align=center>Figure 1. A sample procedure frame and
+parameters.</p>
+
+<p><b>4.3 Heap data area</b></p>
+
+<p>The heap area starts empty, with HP pointing to the low
+end of it. HP always contains a word address. A copy of HP
+can always be obtained with the LOR instruction. A new value
+may be stored in the heap pointer using the STR instruction.
+If the new value is greater than the old one, then the heap
+grows. If it is smaller, then the heap shrinks. HP may never
+point below its original value. All words between the
+current HP and the original HP are allocated to the heap.
+The heap may not grow into a part of memory that is already
+allocated. When this is attempted, the STR instruction will
+cause a trap to occur. In this case, HP retains its old
+value.</p>
+
+<p>The only way to address the heap is indirectly. Whenever
+an object is allocated by increasing HP, then the old HP
+value must be saved and can be used later to address the
+allocated object. If, in the meantime, HP is decreased so
+that the object is no longer part of the heap, then an
+attempt to access the object is not allowed. Furthermore, if
+the heap pointer is increased again to above the object
+address, then access to the old object gives undefined
+results.</p>
+
+<p>The heap is a single fragment. All bytes have
+consecutive addresses. No limits are imposed on the size of
+the heap as long as it fits in the available data address
+space.</p>
+
+<p>5</p>
+
+<p><b>5. MAPPING OF EM DATA MEMORY ONTO TARGET MACHINE
+MEMORY</b></p>
+
+<p>The EM architecture is designed to be implemented on
+many existing and future machines. EM memory is highly
+fragmented to make adaptation to various memory
+architectures possible. Format and encoding of pointers is
+explicitly undefined.</p>
+
+<p>This chapter gives solutions to some of the anticipated
+problems. First, we describe a possible memory layout for
+machines with 64K bytes of address space. Here we use a
+member of the EM family with 2-byte word and pointer size.
+The most straightforward layout is shown in figure 2.</p>
+
+<p><tt>65534 &minus;&gt; |-------------------------------|
+|///////////////////////////////| |//// unimplemented memory
+/////| |///////////////////////////////| ML &minus;&gt;
+|-------------------------------| | | | | &lt;&minus; LB |
+stack and local area | | | |-------------------------------|
+&lt;&minus; SP |///////////////////////////////| |////////
+inaccessible /////////| |///////////////////////////////|
+|-------------------------------| &lt;&minus; HP | | | heap
+area | | | | | HB &minus;&gt;
+|-------------------------------| | | | global data area | |
+| EB &minus;&gt; |-------------------------------| | | |
+program text | &lt;&minus; PC | | | ( and tables ) | | | | |
+PB &minus;&gt; |-------------------------------|
+|///////////////////////////////| |////////// undefined
+//////////| |///////////////////////////////| 0 &minus;&gt;
+|-------------------------------|</tt></p>
+
+<p align=center>Figure 2. Memory layout showing typical
+register<br>
+positions during execution of an EM program.</p>
+
+<p>The base registers for the various memory pieces can be
+stored in target machine registers or memory.</p>
+
+<p align=center><img src="grohtml-97442.png"></p>
+
+<p>The stack grows from high EM addresses to low EM
+addresses, and the heap the other way. The memory between SP
+and HP is not accessible, but may be allocated later to the
+stack or the heap if needed. The local data area is
+allocated starting at the high end of memory.</p>
+
+<p>Because EM address 0 is not mapped onto target address
+0, a problem arises when pointers are used. If a program
+pushed a constant, say 6, onto the stack, and then tried to
+indirect through it, the wrong word would be fetched,
+because EM address 6 is mapped onto target address EB+6 and
+not target address 6 itself. This particular problem is
+solved by explicitly declaring the format of a pointer to be
+undefined, so that using a constant as a pointer is
+completely illegal. However, the general problem of mapping
+pointers still exists.</p>
+
+<p>There are two possible solutions. In the first solution,
+EM pointers are represented in the target machine as true EM
+addresses, for example, a pointer to EM address 6 really is
+stored as a 6 in the target machine. This solution implies
+that every time a pointer is fetched EB must be added before
+referencing the target machine&rsquo;s memory. If the target
+machine has powerful indexing facilities, EB can be kept in
+a target machine register, and the relocation can indeed be
+done on every reference to the data address space at a
+modest cost in speed.</p>
+
+<p>The other solution consists of having EM pointers refer
+to the true target machine address. Thus the instruction LAE
+6 (Load Address of External 6) would push the value of EB+6
+onto the stack. When this approach is chosen, back ends must
+know how to offset from EB, to translate all instructions
+that manipulate EM addresses. However, the problem is not
+completely solved, because a front end may have to
+initialize a pointer in CON or ROM data to point to a global
+address. This pointer must also be relocated by the back end
+or the interpreter.</p>
+
+<p>Although the EM stack grows from high to low EM
+addresses, some machines have hardware PUSH and POP
+instructions that require the stack to grow upwards. If
+reasons of efficiency demand the use of these instructions,
+then EM can be implemented with the memory layout upside
+down, as shown in figure 3. This is possible because the
+pointer format is explicitly undefined. The first element of
+a word array will have a lower physical address than the
+second element.</p>
+
+<p><tt>| | | | | EB=60 | | ^ | | | | | |
+|-----------------| |-----------------| 105 | 45 | 44 | 104
+214 | 41 | 40 | 215 |-----------------| |-----------------|
+103 | 43 | 42 | 102 212 | 43 | 42 | 213 |-----------------|
+|-----------------| 101 | 41 | 40 | 100 210 | 45 | 44 | 211
+|-----------------| |-----------------| | | | | | | v | |
+EB=255 | | | | |</tt></p>
+
+<p><tt>Type A Type B</tt></p>
+
+<p align=center>Figure 3. Two possible memory
+implementations.<br>
+Numbers within the boxes are EM addresses.<br>
+The other numbers are physical addresses.</p>
+
+<p>So, we have two different EM memory implementations:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>A &minus;</p>
+</td>
+<td width="4%"></td>
+<td width="18%">
+
+<p>stack downwards</p>
+</td>
+<td width="71%">
+</td>
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>B &minus;</p>
+</td>
+<td width="4%"></td>
+<td width="18%">
+
+<p>stack upwards</p>
+</td>
+<td width="71%">
+</td>
+</table>
+
+<p>For each of these two possibilities we give the
+translation of the EM instructions to push the third byte of
+a global data block starting at EM address 40 onto the stack
+and to load the word at address 40. All translations assume
+a word and pointer size of two bytes. The target machine
+used is a PDP-11 augmented with push and pop instructions.
+Registers &rsquo;r0&rsquo; and &rsquo;r1&rsquo; are used and
+suffer from sign extension for byte transfers. Push $40
+means push the constant 40, not word 40.</p>
+
+<p>The translation of the EM instructions depends on the
+pointer representation used. For each of the two solutions
+explained above the translation is given.</p>
+
+<p>First, the translation for the two implementations using
+EM addresses as pointer representation:</p>
+
+<p align=center><img src="grohtml-97443.png"></p>
+
+<p>The translation for the two implementations, if the
+target machine address is used as pointer representation,
+is:</p>
+
+<p align=center><img src="grohtml-97444.png"></p>
+
+<p>The translation presented above is not intended to be
+optimal. Most machines can handle these simple cases in one
+or two instructions. It demonstrates, however, the
+flexibility of the EM design.</p>
+
+<p>There are several possibilities to implement EM on
+machines with address spaces larger than 64k bytes. For EM
+with two byte pointers one could allocate instruction and
+data space each in a separate 64k piece of memory. EM
+pointers still have to fit in two bytes, but the base
+registers PB and EB may be loaded in hardware registers
+wider than 16 bits, if available. EM implementations can
+also make efficient use of a machine with separate
+instruction and data space.</p>
+
+<p>EM with 32 bit pointers allows one to make use of
+machines with large address spaces. In a virtual, segmented
+memory system one could use a separate segment for each
+fragment.</p>
+
+<p>6</p>
+
+<p><b>6. TYPE REPRESENTATIONS</b></p>
+
+<p>The representations used for typed objects are not
+precisely specified by EM. Sometimes we only specify that a
+typed object occupies a certain amount of space and state no
+further restrictions. If one wants to have a different
+representation of the value of an object on the stack one
+has to use a convert instruction in most cases. We do
+specify some relations between the representations of types.
+This allows some intermixed use of operators for different
+types on the same object(s). For example, the instruction
+ZER pushes signed and unsigned integers with the value zero
+and empty sets. ZER has as only argument the size of the
+object.</p>
+
+<p>The representation of floating point numbers is a good
+example, it allows widely varying implementations. The only
+ways to create floating point numbers are via initialization
+and via conversions from integer numbers. Only by using
+conversions to integers and comparing two floating point
+numbers with each other, can these numbers be converted to
+human readable output. Implementations may use base 10, base
+2 or any other base for exponents, and have freedom in
+choosing the range of exponent and mantissa.</p>
+
+<p>Other types are more precisely described. In the
+following paragraphs a description will be given of the
+restrictions imposed on the representation of the types
+used. A number <b>n</b> used in these paragraphs indicates
+the size of the object in <i>bits</i>.</p>
+
+<p><b>6.1 Unsigned integers</b></p>
+
+<p>The range of unsigned integers is 0.. 2
+<b><small>n</small></b> -1. A binary representation is
+assumed. The order of the bits within an object is knowingly
+left unspecified. Discussing bit order within each 8-bit
+byte is academic, so the only real freedom of this
+specification lies in the byte order. We really do not care
+whether an implementation of a 4-byte integer has its bytes
+in a particular order of significance. This of course means
+that some sequences of instructions have unpredictable
+effects. For example:</p>
+<pre>     LOC 258 ; STL 0 ; LAL 0 ; LOI 1      ( wordsize &gt;=2 )
+</pre>
+
+<p>The value on the stack after executing this sequence can
+be anything, but will most likely be 1 or 2.</p>
+
+<p>Conversion between unsigned integers of different sizes
+have to be done with explicit convert instructions. One
+cannot simply pad an unsigned integer with zero&rsquo;s at
+either end and expect a correct result.</p>
+
+<p>We assume existence of at least single word unsigned
+arithmetic in any implementation.</p>
+
+<p><b>6.2 Signed Integers</b></p>
+
+<p>The range of signed integers is &minus;2
+<b><small>n</small></b><small>&minus;1</small> .. 2
+<b><small>n</small></b><small>&minus;1</small> &minus;1, in
+other words the range of signed integers of <b>n</b> bits
+using two&rsquo;s complement arithmetic. The representation
+is the same as for unsigned integers except the range 2
+<b><small>n</small></b><small>&minus;1</small> .. 2
+<b><small>n</small></b> &minus;1 is mapped on the range
+&minus;2 <b><small>n</small></b><small>&minus;1</small> ..
+&minus;1. In other words, the most significant bit is used
+as sign bit. The convert instructions between signed and
+unsigned integers of the same size can be used to catch
+errors.</p>
+
+<p>The value &minus;2
+<b><small>n</small></b><small>&minus;1</small> is used for
+undefined signed integers. EM implementations should trap
+when this value is used in an operation on signed integers.
+The instruction mask, accessed with SIM and LIM &minus; see
+chapter 9 &minus;, can be used to disable such traps.</p>
+
+<p>We assume existence of at least single word signed
+arithmetic in any implementation.</p>
+
+<p><b>6.3 Floating point values</b></p>
+
+<p>Floating point values must have a signed mantissa and a
+signed exponent. Although no base is specified, base 2 is
+the normal choice, because the FEF instruction pushes the
+exponent in base 2.</p>
+
+<p>The implementation of floating point arithmetic is
+optional. The compilers currently in use have runtime
+parameters for the size of the floating point values they
+should use. Common choices are 4 and/or 8 bytes.</p>
+
+<p><b>6.4 Pointers</b></p>
+
+<p>EM has two kinds of pointers: for instruction and for
+data space. Each kind can only be used for its own space,
+conversion between these two subtypes is impossible. We
+assume that pointers have a range from 0 upwards. Any
+implementation may have holes in the pointer range between
+fragments. One can of course not expect to be able to
+address two megabyte of memory using a 2-byte pointer.
+Normally, a 2-byte pointer allows up to 65536 bytes of
+addressable memory.</p>
+
+<p>Pointer representation has one restriction. The pointer
+with the same representation as the integer zero of the same
+size should be invalid. Some languages and/or runtime
+systems represent the nil pointer as zero.</p>
+
+<p><b>6.5 Bit sets</b></p>
+
+<p>All bit sets of size <b>n</b> are subsets of the set { i
+| i&gt;=0, i&lt;<b>n</b> }. A bit set contains a bit for
+each element showing its presence or absence. Bit sets are
+subdivided into words. The word with the lowest EM address
+governs the subset { i | i&gt;=0, i&lt;<b>m</b> }, where
+<b>m</b> is the number of bits in a word. The next higher
+words each govern the next higher <b>m</b> set elements. The
+relation between a set with size of a word and an unsigned
+integer word is that the value of the unsigned integer is
+the summation of the 2i where i is in the set.</p>
+
+<p>Example: a 2-word bit set (wordsize 2) containing the
+elements 1, 6, 8, 15, 18, 21, 27 and 28 is composed of two
+integers, e.g. at addresses 40 and 42. The word at 40
+contains the value 33090 (or &minus;32446), the word at 42
+contains the value 6180.</p>
+
+<p>7</p>
+
+<p><b>7. DESCRIPTORS</b></p>
+
+<p>Several instructions use descriptors, notably the range
+check instruction, the array instructions, the goto
+instruction and the case jump instructions. Descriptors
+reside in data space. They may be constructed at run time,
+but more often they are fixed and allocated in ROM data.</p>
+
+<p>All instructions using descriptors, except GTO, have as
+argument the size of the integers in the descriptor. All
+implementations have to allow integers of the size of a word
+in descriptors. All integers popped from the stack and used
+for indexing or comparing must have the same size as the
+integers in the descriptor.</p>
+
+<p><b>7.1 Range check descriptors</b></p>
+
+<p>Range check descriptors consist of two integers:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>1.</p>
+</td>
+<td width="10%">
+
+<p>lower bound</p>
+</td>
+<td width="79%">
+
+<p>signed</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>2.</p>
+</td>
+<td width="10%">
+
+<p>upper bound</p>
+</td>
+<td width="79%">
+
+<p>signed</p>
+</td>
+</table>
+
+<p>The range check instruction checks an integer on the
+stack against these bounds and causes a trap if the value is
+outside the interval. The value itself is neither changed
+nor removed from the stack.</p>
+
+<p><b>7.2 Array descriptors</b></p>
+
+<p>Each array descriptor describes a single dimension. For
+multi-dimensional arrays, several array instructions are
+needed to access a single element. Array descriptors contain
+the following three integers:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>1.</p>
+</td>
+<td width="10%">
+
+<p>lower bound</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="79%">
+
+<p>signed</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>2.</p>
+</td>
+<td width="10%">
+
+<p>upper bound &minus; lower bound</p>
+</td>
+<td width="79%">
+
+<p>unsigned</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>3.</p>
+</td>
+<td width="14%">
+
+<p>number of bytes per element</p>
+</td>
+<td width="75%">
+
+<p>unsigned</p>
+</td>
+</table>
+
+<p>The array instructions LAR, SAR and AAR have the pointer
+to the start of the descriptor as operand on the stack.</p>
+
+<p>The element A[I] is fetched as follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>Stack the address of A (e.g., using LAE or LAL)</p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>Stack the value of I (n-byte integer)</p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>Stack the pointer to the descriptor (e.g., using
+LAE)</p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>LAR n (n is the size of the integers in the descriptor
+and I)</p>
+</td>
+<td width="69%">
+</td>
+</table>
+
+<p>All array instructions first pop the address of the
+descriptor and the index. If the index is not within the
+bounds specified, a trap occurs. If ok, (I &minus; lower
+bound) is multiplied by the number of bytes per element (the
+third word). The result is added to the address of A and
+replaces A on the stack.</p>
+
+<p>At this point LAR, SAR and AAR diverge. AAR is finished.
+LAR pops the address and fetches the data item, the size
+being specified by the descriptor. The usual restrictions
+for memory access must be obeyed. SAR pops the address and
+stores the data item now exposed.</p>
+
+<p><b>7.3 Non-local goto descriptors</b></p>
+
+<p>The GTO instruction provides a way of returning directly
+to any active procedure invocation. The argument of the
+instruction is the address of a descriptor containing three
+pointers:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="10%">
+
+<p>value of PC after the jump</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="10%">
+
+<p>value of SP after the jump</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="10%">
+
+<p>value of LB after the jump</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p>GTO replaces the loads PC, SP and LB from the
+descriptor, thereby jumping to a procedure and removing zero
+or more frames from the stack. The LB, SP and PC in the
+descriptor must belong to a dynamically enclosing procedure,
+because some EM implementations will need to backtrack
+through the dynamic chain and use the implementation
+dependent data in frames to restore registers etc.</p>
+
+<p><b>7.4 Case descriptors</b></p>
+
+<p>The case jump instructions CSA and CSB both provide
+multiway branches selected by a case index. Both fetch two
+operands from the stack: first a pointer to the low address
+of the case descriptor and then the case index. CSA uses the
+case index as index in the descriptor table, but CSB
+searches the table for an occurrence of the case index.
+Therefore, the descriptors for CSA and CSB, as shown in
+figure 4, are different. All pointers in the table must be
+addresses of instructions in the procedure executing the
+case instruction.</p>
+
+<p>CSA selects the new PC by indexing. If the index, a
+signed integer, is greater than or equal to the lower bound
+and less than or equal to the upper bound, then fetch the
+new PC from the list of instruction pointers by indexing
+with index-lower. The table does not contain the value of
+the upper bound, but the value of upper-lower as an unsigned
+integer. The default instruction pointer is used when the
+index is out of bounds. If the resulting PC is 0, then
+trap.</p>
+
+<p>CSB selects the new PC by searching. The table is
+searched for an entry with index value equal to the case
+index. That entry or, if none is found, the default entry
+contains the new PC. When the resulting PC is 0, a trap is
+performed.</p>
+
+<p>The choice of which case instruction to use for each
+source language case statement is up to the front end. If
+the range of the index value is dense, i.e</p>
+<pre>     (highest value &minus; lowest value) / number of cases
+</pre>
+
+<p>is less than some threshold, then CSA is the obvious
+choice. If the range is sparse, CSB is better.</p>
+
+<p><tt>|--------------------| |--------------------| high
+address | pointer for upb | | pointer n-1 |
+|--------------------| |- - - - - - - | | . | | index n-1 |
+| . | |--------------------| | . | | . | | . | | . | | . | |
+. | | . | |--------------------| | . | | pointer 1 |
+|--------------------| |- - - - - - - | | pointer for lwb+1
+| | index 1 | |--------------------| |--------------------|
+| pointer for lwb | | pointer 0 | |--------------------| |-
+- - - - - - | | upper - lower | | index 0 |
+|--------------------| |--------------------| | lower bound
+| | number of entries | |--------------------|
+|--------------------| | default pointer | | default pointer
+| low address |--------------------|
+|--------------------|</tt></p>
+
+<p><tt>CSA descriptor CSB descriptor</tt></p>
+
+<p align=center>Figure 4. Descriptor layout for CSA and
+CSB</p>
+
+<p>8</p>
+
+<p><b>8. ENVIRONMENT INTERACTIONS</b></p>
+
+<p>EM programs can interact with their environment in three
+ways. Two, starting/stopping and monitor calls, are dealt
+with in this chapter. The remaining way to interact,
+interrupts, will be treated together with traps in chapter
+9.</p>
+
+<p><b>8.1 Program starting and stopping</b></p>
+
+<p>EM user programs start with a call to a procedure called
+_m_a_i_n. The assembler and backends look for the definition
+of a procedure with this name in their input. The call
+passes three parameters to the procedure. The parameters are
+similar to the parameters supplied by the
+<small>UNIX</small> &reg; operating system to C programs.
+These parameters are often called <b>argc</b>, <b>argv</b>
+and <b>envp</b>. Argc is the parameter nearest to LB and is
+a wordsized integer. The other two are pointers to the first
+element of an array of string pointers. The <b>argv</b>
+array contains <b>argc</b> strings, the first of which
+contains the program call name. The other strings in the
+<b>argv</b> array are the program parameters.</p>
+
+<p>The <b>envp</b> array contains strings in the form
+&quot;name=string&quot;, where &rsquo;name&rsquo; is the
+name of an environment variable and string its value. The
+<b>envp</b> is terminated by a zero pointer.</p>
+
+<p>An EM user program stops if the program returns from the
+first invocation of _m_a_i_n. The contents of the function
+return area are used to procure a wordsized program return
+code. EM programs also stop when traps and interrupts occur
+that are not caught and when the exit monitor call is
+executed.</p>
+
+<p><b>8.2 Input/Output and other monitor calls</b></p>
+
+<p>EM differs from most conventional machines in that it
+has high level i/o instructions. Typical instructions are
+OPEN FILE and READ FROM FILE instead of low level
+instructions such as setting and clearing bits in device
+registers. By providing such high level i/o primitives, the
+task of implementing EM on various non EM machines is made
+considerably easier.</p>
+
+<p>I/O is initiated by the MON instruction, which expects
+an iocode on top of the stack. Often there are also
+parameters which are pushed on the stack in reverse order,
+that is: last parameter first. Some i/o functions also
+provide results, which are returned on the stack. In the
+list of monitor calls we use several types of parameters and
+results, these types consist of integers and unsigneds of
+varying sizes, but never smaller than the wordsize, and the
+two pointer types.</p>
+
+<p>The names of the types used are:</p>
+
+<p align=center><img src="grohtml-97445.png"></p>
+
+<p>The table below lists the i/o codes with their results
+and parameters. This list is similar to the system calls of
+the UNIX Version 7 operating system.</p>
+
+<p>To execute a monitor call, proceed as follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>a)</p>
+</td>
+<td width="6%"></td>
+<td width="24%">
+
+<p>Stack the parameters, in reverse order, last parameter
+first.</p>
+</td>
+<td width="65%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>b)</p>
+</td>
+<td width="6%"></td>
+<td width="24%">
+
+<p>Push the monitor call number (iocode) onto the
+stack.</p>
+</td>
+<td width="65%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>c)</p>
+</td>
+<td width="6%"></td>
+<td width="24%">
+
+<p>Execute the MON instruction.</p>
+</td>
+<td width="65%">
+</td>
+</table>
+
+<p>An error code is present on the top of the stack after
+execution of most monitor calls. If this error code is zero,
+the call performed the action requested and the results are
+available on top of the stack. Non-zero error codes indicate
+a failure, in this case no results are available and the
+error code has been pushed twice. This construction enables
+programs to test for failure with a single instruction ( TEQ
+or TNE ) and still find out the cause of the failure. The
+result name &rsquo;e&rsquo; is reserved for the error
+code.</p>
+
+<p>List of monitor calls.</p>
+<pre>nr  name     parameters      results                function
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>1</p>
+</td>
+<td width="92%">
+
+<p>Exit</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>status:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Terminate this process</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>2</p>
+</td>
+<td width="92%">
+
+<p>Fork</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e,flag,pid:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Spawn new process</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>3</p>
+</td>
+<td width="92%">
+
+<p>Read</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>fildes:int;buf:ptr;nbytes:unsp</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int;rbytes:unsp</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Read from file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>4</p>
+</td>
+<td width="92%">
+
+<p>Write</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>fildes:int;buf:ptr;nbytes:unsp</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int;wbytes:unsp</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Write on a file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>5</p>
+</td>
+<td width="92%">
+
+<p>Open</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr;flag:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e,fildes:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Open file for read and/or write</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>6</p>
+</td>
+<td width="92%">
+
+<p>Close</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>fildes:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Close a file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>7</p>
+</td>
+<td width="92%">
+
+<p>Wait</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int;status,pid:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Wait for child</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>8</p>
+</td>
+<td width="92%">
+
+<p>Creat</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr;mode:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e,fildes:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Create a new file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>9</p>
+</td>
+<td width="92%">
+
+<p>Link</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string1,string2:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Link to a file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>10</p>
+</td>
+<td width="92%">
+
+<p>Unlink</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Remove directory entry</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>12</p>
+</td>
+<td width="92%">
+
+<p>Chdir</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Change default directory</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>14</p>
+</td>
+<td width="92%">
+
+<p>Mknod</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr;mode,addr:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Make a special file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>15</p>
+</td>
+<td width="92%">
+
+<p>Chmod</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr;mode:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Change mode of file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>16</p>
+</td>
+<td width="92%">
+
+<p>Chown</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr;owner,group:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Change owner/group of a file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>18</p>
+</td>
+<td width="92%">
+
+<p>Stat</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string,statbuf:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Get file status</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>19</p>
+</td>
+<td width="92%">
+
+<p>Lseek</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>fildes:int;off:int4;whence:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int;oldoff:int4</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Move read/write pointer</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>20</p>
+</td>
+<td width="92%">
+
+<p>Getpid</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>pid:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Get process identification</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>21</p>
+</td>
+<td width="92%">
+
+<p>Mount</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>special,string:ptr;rwflag:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Mount file system</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>22</p>
+</td>
+<td width="92%">
+
+<p>Umount</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>special:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Unmount file system</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>23</p>
+</td>
+<td width="92%">
+
+<p>Setuid</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>userid:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Set user ID</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>24</p>
+</td>
+<td width="92%">
+
+<p>Getuid</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e_uid,r_uid:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Get user ID</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>25</p>
+</td>
+<td width="92%">
+
+<p>Stime</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>time:int4</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Set time and date</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>26</p>
+</td>
+<td width="92%">
+
+<p>Ptrace</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>request:int;pid:int2;addr:ptr;data:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e,value:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Process trace</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>27</p>
+</td>
+<td width="92%">
+
+<p>Alarm</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>seconds:uns2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>previous:uns2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Schedule signal</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>28</p>
+</td>
+<td width="92%">
+
+<p>Fstat</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>fildes:int;statbuf:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Get file status</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>29</p>
+</td>
+<td width="92%">
+
+<p>Pause</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Stop until signal</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>30</p>
+</td>
+<td width="92%">
+
+<p>Utime</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string,timep:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Set file times</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>33</p>
+</td>
+<td width="92%">
+
+<p>Access</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr;mode:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Determine file accessibility</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>34</p>
+</td>
+<td width="92%">
+
+<p>Nice</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>incr:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Set program priority</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>35</p>
+</td>
+<td width="92%">
+
+<p>Ftime</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>bufp:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Get date and time</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>36</p>
+</td>
+<td width="92%">
+
+<p>Sync</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Update filesystem</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>37</p>
+</td>
+<td width="92%">
+
+<p>Kill</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>pid:int2;sig:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Send signal to a process</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>41</p>
+</td>
+<td width="92%">
+
+<p>Dup</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>fildes,newfildes:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e,fildes:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Duplicate a file descriptor</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>42</p>
+</td>
+<td width="92%">
+
+<p>Pipe</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e,w_des,r_des:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Create a pipe</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>43</p>
+</td>
+<td width="92%">
+
+<p>Times</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>buffer:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Get process times</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>44</p>
+</td>
+<td width="92%">
+
+<p>Profil</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>buff:ptr;bufsiz,offset,scale:intp</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Execution time profile</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>46</p>
+</td>
+<td width="92%">
+
+<p>Setgid</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>gid:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Set group ID</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>47</p>
+</td>
+<td width="92%">
+
+<p>Getgid</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e_gid,r_gid:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Get group ID</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>48</p>
+</td>
+<td width="92%">
+
+<p>Sigtrp</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>trapno,signo:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e,prevtrap:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>See below</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>51</p>
+</td>
+<td width="92%">
+
+<p>Acct</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>file:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Turn accounting on or off</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>53</p>
+</td>
+<td width="92%">
+
+<p>Lock</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>flag:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Lock a process</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>54</p>
+</td>
+<td width="92%">
+
+<p>Ioctl</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>fildes,request:int;argp:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Control device</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>56</p>
+</td>
+<td width="92%">
+
+<p>Mpxcall</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>cmd:int;vec:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Multiplexed file handling</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>59</p>
+</td>
+<td width="92%">
+
+<p>Exece</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>name,argv,envp:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Execute a file</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>60</p>
+</td>
+<td width="92%">
+
+<p>Umask</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>mask:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>oldmask:int2</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Set file creation mode mask</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>61</p>
+</td>
+<td width="92%">
+
+<p>Chroot</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>string:ptr</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>e:int</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>Change root directory</p>
+</td>
+</table>
+
+<p>Codes 0, 11, 13, 17, 31, 32, 38, 39, 40, 45, 49, 50, 52,
+55, 57, 58, 62, and 63 are not used.</p>
+
+<p>All monitor calls, except fork and sigtrp are the same
+as the UNIX version 7 system calls.</p>
+
+<p>The sigtrp entry maps UNIX signals onto EM interrupts.
+Normally, trapno is in the range 0 to 252. In that case it
+requests that signal signo will cause trap trapno to occur.
+When given trap number &minus;2, default signal handling is
+reset, and when given trap number &minus;3, the signal is
+ignored.</p>
+
+<p>The flag returned by fork is 1 in the child process and
+0 in the parent. The pid returned is the process-id of the
+other process.</p>
+
+<p>9</p>
+
+<p><b>9. TRAPS AND INTERRUPTS</b></p>
+
+<p>EM provides a means for the user program to catch all
+traps generated by the program itself, the hardware, or
+external conditions. This mechanism uses five instructions:
+LIM, SIM, SIG, TRP and RTT. This section of the manual may
+be omitted on the first reading since it presupposes
+knowledge of the EM instruction set.</p>
+
+<p>The action taken when a trap occurs is determined by the
+value of an internal EM trap register. This register
+contains a pointer to a procedure. Initially the pointer
+used is zero and all traps halt the program with, hopefully,
+a useful message to the outside world. The SIG instruction
+can be used to alter the trap register, it pops a procedure
+pointer from the stack into the trap register. When a trap
+occurs after storing a nonzero value in the trap register,
+the procedure pointed to by the trap register is called with
+the trap number as the only parameter (see below). SIG
+returns the previous value of the trap register on the
+stack. Two consecutive SIGs are a no-op. When a trap occurs,
+the trap register is reset to its initial condition, to
+prevent recursive traps from hanging the machine up, e.g.
+stack overflow in the stack overflow handling procedure.</p>
+
+<p>The runtime systems for some languages need to ignore
+some EM traps. EM offers a feature called the ignore mask.
+It contains one bit for each of the lowest 16 trap numbers.
+The bits are numbered 0 to 15, with the least significant
+bit having number 0. If a certain bit is 1 the corresponding
+trap never occurs and processing simply continues. The
+actions performed by the offending instruction are described
+by the Pascal program in appendix A.<br>
+If the bit is 0, traps are not ignored. The instructions LIM
+and SIM allow copying and replacement of the ignore
+mask.</p>
+
+<p>The TRP instruction generates a trap, the trap number
+being found on the stack. This is, among other things,
+useful for library procedures and runtime systems. It can
+also be used by a low level trap procedure to pass the trap
+to a higher level one (see example below).</p>
+
+<p>The RTT instruction returns from the trap procedure and
+continues after the trap. In the list below all traps marked
+with an asterisk (&rsquo;*&rsquo;) are considered to be
+fatal and it is explicitly undefined what happens when
+restarting after the trap.</p>
+
+<p>The way a trap procedure is called is completely
+compatible with normal calling conventions. The only way a
+trap procedure differs from normal procedures is the return.
+It has to use RTT instead of RET. This is necessary because
+the complete runtime status is saved on the stack before
+calling the procedure and all this status has to be
+reloaded. Error numbers are in the range 0 to 252. The trap
+numbers are divided into three categories:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="10%">
+
+<p>0&minus; 63</p>
+</td>
+<td width="10%"></td>
+<td width="24%">
+
+<p>EM machine errors, e.g. illegal instruction.</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>0&minus;15</p>
+<td width="39%"></td>
+<td width="16%">
+
+<p>maskable</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="32%">
+
+<p>16&minus;63</p>
+</td>
+<td width="6%"></td>
+<td width="16%">
+
+<p>not maskable</p>
+</td>
+<td width="43%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="32%">
+
+<p>64&minus;127</p>
+</td>
+<td width="6%"></td>
+<td width="16%"></td>
+<td width="43%">
+</td>
+</table>
+
+<p>Reserved for use by compilers, run time systems,
+etc.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>128&minus;252</p>
+</td>
+<td width="10%"></td>
+<td width="18%">
+
+<p>Available for user programs.</p>
+</td>
+<td width="57%">
+</td>
+</table>
+
+<p>EM machine errors are numbered as follows:</p>
+
+<p align=center><img src="grohtml-97446.png"></p>
+
+<p>As an example, suppose a subprocedure has to be written
+to do a numeric calculation. When an overflow occurs the
+computation has to be stopped and the higher level procedure
+must be resumed. This can be programmed as follows using the
+mechanism described above:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>mes 2,2,2</p>
+</td>
+<td width="52%">
+
+<p>; set sizes</p>
+</td>
+</table>
+
+<p>ersave</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>bss 2,0,0</p>
+</td>
+<td width="52%">
+
+<p>; Room to save previous value of trap procedure</p>
+</td>
+</table>
+
+<p>msave</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>bss 2,0,0</p>
+</td>
+<td width="52%">
+
+<p>; Room to save previous value of trap mask</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>pro $calcule,0</p>
+</td>
+<td width="52%">
+
+<p>; entry point</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lxl 0</p>
+</td>
+<td width="52%">
+
+<p>; fill in non-local goto descriptor with LB</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>ste jmpbuf+4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lor 1</p>
+</td>
+<td width="52%">
+
+<p>; and SP</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>ste jmpbuf+2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lim</p>
+</td>
+<td width="52%">
+
+<p>; get current ignore mask</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>ste msave</p>
+</td>
+<td width="52%">
+
+<p>; save it</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>lim</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>loc 16</p>
+</td>
+<td width="52%">
+
+<p>; bit for EFOVFL</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>ior 2</p>
+</td>
+<td width="52%">
+
+<p>; set in mask</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>sim</p>
+</td>
+<td width="52%">
+
+<p>; ignore EFOVFL from now on</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lpi $catch</p>
+</td>
+<td width="52%">
+
+<p>; load procedure identifier</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>sig</p>
+</td>
+<td width="52%">
+
+<p>; catch wil get all traps now</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>ste ersave</p>
+</td>
+<td width="52%">
+
+<p>; save previous trap procedure identifier</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+</td>
+<td width="52%">
+
+<p>; perform calculation now, possibly generating
+overflow</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>1</p>
+</td>
+<td width="46%"></td>
+<td width="52%">
+
+<p>; label jumped to by catch procedure</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>loe ersave</p>
+</td>
+<td width="52%">
+
+<p>; get old trap procedure</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>sig</p>
+</td>
+<td width="52%">
+
+<p>; refer all following trap to old procedure</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>asp 2</p>
+</td>
+<td width="52%">
+
+<p>; remove result of sig</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>loe msave</p>
+</td>
+<td width="52%">
+
+<p>; restore previous mask</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>sim</p>
+</td>
+<td width="52%">
+
+<p>; done now</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+</td>
+<td width="52%">
+
+<p>; load result of calculation</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>ret 2</p>
+</td>
+<td width="52%">
+
+<p>; return result</p>
+</td>
+</table>
+
+<p>jmpbuf</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="98%">
+
+<p>con *1,0,0</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="98%">
+
+<p>end</p>
+</td>
+</table>
+
+<p>Example of catch procedure</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>pro $catch,0</p>
+</td>
+<td width="52%">
+
+<p>; Local procedure that must catch the overflow trap</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lol 2</p>
+</td>
+<td width="52%">
+
+<p>; Load trap number</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>loc 4</p>
+</td>
+<td width="52%">
+
+<p>; check for overflow</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>bne *1</p>
+</td>
+<td width="52%">
+
+<p>; if other trap, call higher trap procedure</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>gto jmpbuf</p>
+</td>
+<td width="52%">
+
+<p>; return to procedure calcule</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>1</p>
+</td>
+<td width="46%"></td>
+<td width="52%">
+
+<p>; other trap has occurred</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>loe ersave</p>
+</td>
+<td width="52%">
+
+<p>; previous trap procedure</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>sig</p>
+</td>
+<td width="52%">
+
+<p>; other procedure will get the traps now</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>asp 2</p>
+</td>
+<td width="52%">
+
+<p>; remove the result of sig</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lol 2</p>
+</td>
+<td width="52%">
+
+<p>; stack trap number</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>trp</p>
+</td>
+<td width="52%">
+
+<p>; call other trap procedure</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>rtt</p>
+</td>
+<td width="52%">
+
+<p>; if other procedure returns, do the same</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>end</p>
+</td>
+<td width="52%">
+</td>
+</table>
+
+<p>10</p>
+
+<p><b>10. EM MACHINE LANGUAGE</b></p>
+
+<p>The EM machine language is designed to make program text
+compact and to make decoding easy. Compact program text has
+many advantages: programs execute faster, programs occupy
+less primary and secondary storage and loading programs into
+satellite processors is faster. The decoding of EM machine
+language is so simple, that it is feasible to use
+interpreters as long as EM hardware machines are not
+available. This chapter is irrelevant when back ends are
+used to produce executable target machine code.</p>
+
+<p><b>10.1 Instruction encoding</b></p>
+
+<p>A design goal of EM is to make the program text as
+compact as possible. Decoding must be easy, however. The
+encoding is fully byte oriented, without any small bit
+fields. There are 256 primary opcodes, two of which are an
+escape to two groups of 256 secondary opcodes each.</p>
+
+<p>EM instructions without arguments have a single opcode
+assigned, possibly escaped:</p>
+
+<p><tt>|--------------| | opcode |
+|--------------|</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="47%"></td>
+<td width="-24%"></td>
+<td width="76%">
+
+<p>or</p>
+</td>
+</table>
+
+<p><tt>|--------------|--------------| | escape | opcode |
+|--------------|--------------|</tt></p>
+
+<p>The encoding for instructions with an argument is more
+complex. Several instructions have an address from the
+global data area as argument. Other instructions have
+different opcodes for positive and negative arguments.</p>
+
+<p>There is always an opcode that takes the next two bytes
+as argument, high byte first:</p>
+
+<p><tt>|--------------|--------------|--------------| |
+opcode | hibyte | lobyte |
+|--------------|--------------|--------------|</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="-10%"></td>
+<td width="90%">
+
+<p>or</p>
+</td>
+</table>
+
+
+<p><tt>|--------------|--------------|--------------|--------------|
+| escape | opcode | hibyte | lobyte |
+|--------------|--------------|--------------|--------------|</tt></p>
+
+<p>An extra escape is provided for instructions with four
+or eight byte arguments.</p>
+
+<p><tt>|--------------|--------------|--------------|
+|--------------| | ESCAPE | opcode | hibyte |...| lobyte |
+|--------------|--------------|--------------|
+|--------------|</tt></p>
+
+<p>For most instructions some argument values predominate.
+The most frequent combinations of instruction and argument
+will be encoded in a single byte, called a mini:</p>
+
+<p><tt>|---------------| |opcode+argument| (mini)
+|---------------|</tt></p>
+
+<p>The number of minis is restricted, because only 254
+primary opcodes are available. Many instructions have the
+bulk of their arguments fall in the range 0 to 255.
+Instructions that address global data have their arguments
+distributed over a wider range, but small values of the high
+byte are common. For all these cases there is another
+encoding that combines the instruction and the high byte of
+the argument into a single opcode. These opcodes are called
+shorties. Shorties may be escaped.</p>
+
+<p><tt>|--------------|--------------| | opcode+high |
+lobyte | (shortie) |--------------|--------------|</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="-10%"></td>
+<td width="90%">
+
+<p>or</p>
+</td>
+</table>
+
+<p><tt>|--------------|--------------|--------------| |
+escape | opcode+high | lobyte |
+|--------------|--------------|--------------|</tt></p>
+
+<p>Escaped shorties are useless if the normal encoding has
+a primary opcode. Note that for some instruction-argument
+combinations several different encodings are available. It
+is the task of the assembler to select the shortest of
+these. The savings by these mini and shortie opcodes are
+considerable, about 55%.</p>
+
+<p>Further improvements are possible: the arguments of many
+instructions are a multiple of the wordsize. Some do also
+not allow zero as an argument. If these arguments are
+divided by the wordsize and, when zero is not allowed, then
+decremented by 1, more of them can be encoded as shortie or
+mini. The arguments of some other instructions rarely or
+never assume the value 0, but start at 1. The value 1 is
+then encoded as 0, 2 as 1 and so on.</p>
+
+<p>Assigning opcodes to instructions by the assembler is
+completely table driven. For details see appendix B.</p>
+
+<p><b>10.2 Procedure descriptors</b></p>
+
+<p>The procedure identifiers used in the interpreter are
+indices into a table of procedure descriptors. Each
+descriptor contains:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>the number of bytes to be reserved for locals at each
+invocation.</p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This is a pointer-sized integer.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="18%">
+
+<p>the start address of the procedure</p>
+</td>
+<td width="71%">
+</td>
+</table>
+
+<p><b>10.3 Load format</b></p>
+
+<p>The EM machine language load format defines the
+interface between the EM assembler/loader and the EM machine
+itself. A load file consists of a header, the program text
+to be executed, a description of the global data area and
+the procedure descriptor table, in this order. All integers
+in the load file are presented with the least significant
+byte first.</p>
+
+<p>The header has two parts: the first half (eight 16-bit
+integers) aids in selecting the correct EM machine or
+interpreter. Some EM machines, for instance, may have
+hardware floating point instructions. The header entries are
+as follows (bit 0 is rightmost):</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="6%"></td>
+<td width="18%">
+
+<p>magic number (07255)</p>
+</td>
+<td width="71%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="6%"></td>
+<td width="18%">
+
+<p>flag bits with the following meaning:</p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>bit 0</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>TEST; test for integer overflow etc.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>bit 1</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>PROFILE; for each source line: count the number of memory
+cycles executed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>bit 2</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>FLOW; for each source line: set a bit in a bit map table
+if instructions on that line are executed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>bit 3</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>COUNT; for each source line: increment a counter if that
+line is entered.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>bit 4</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>REALS; set if a program uses floating point
+instructions.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>bit 5</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>EXTRA; more tests during compiler debugging.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3:</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>number of unresolved references.</p>
+</td>
+<td width="67%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4:</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>version number; used to detect obsolete EM load
+files.</p>
+</td>
+<td width="67%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5:</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>wordsize ; the number of bytes in each machine word.</p>
+</td>
+<td width="67%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6:</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>pointer size ; the number of bytes available for
+addressing.</p>
+</td>
+<td width="67%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7:</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>unused</p>
+</td>
+<td width="67%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>8:</p>
+</td>
+<td width="6%"></td>
+<td width="22%">
+
+<p>unused</p>
+</td>
+<td width="67%">
+</td>
+</table>
+
+<p>The second part of the header (eight entries, of pointer
+size bytes each) describes the load file itself:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>NTEXT; the program text size in bytes.</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>NDATA; the number of load-file descriptors (see
+below).</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>NPROC; the number of entries in the procedure descriptor
+table.</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>ENTRY; procedure number of the procedure to start
+with.</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>NLINE; the maximum source line number.</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>SZDATA; the address of the lowest uninitialized data
+byte.</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>unused</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>8:</p>
+</td>
+<td width="6%"></td>
+<td width="26%">
+
+<p>unused</p>
+</td>
+<td width="63%">
+</td>
+</table>
+
+<p>The program text consists of NTEXT bytes. NTEXT is
+always a multiple of the wordsize. The first byte of the
+program text is the first byte of the instruction address
+space, i.e. it has address 0. Pointers into the program text
+are found in the procedure descriptor table where relocation
+is simple and in the global data area. The initialization of
+the global data area allows easy relocation of pointers into
+both address spaces.</p>
+
+<p>The global data area is described by the NDATA
+descriptors. Each descriptor describes a number of
+consecutive words (of wordsize) and consists of a sequence
+of bytes. While reading the descriptors from the load file,
+one can initialize the global data area from low to high
+addresses. The size of the initialized data area is given by
+SZDATA, this number can be used to check the
+initialization.<br>
+The header of each descriptor consists of a byte, describing
+the type, and a count. The number of bytes used for this
+(unsigned) count depends on the type of the descriptor and
+is either a pointer-sized integer or one byte. The meaning
+of the count depends on the descriptor type. At load time an
+interpreter can perform any conversion deemed necessary,
+such as reordering bytes in integers and pointers and adding
+base addresses to pointers.</p>
+
+<p>In the following pictures we show a graphical notation
+of the initializers. The leftmost rectangle represents the
+leading byte.</p>
+
+<p>Fields marked with</p>
+
+<p align=center><img src="grohtml-97447.png"></p>
+
+<p><tt>------------------- | 0 | n | repeat last
+initialization n times -------------------</tt></p>
+
+<p><tt>--------- | 1 | m | m uninitialized words
+---------</tt></p>
+
+<p><tt>____________ / bytes \ ----------------- ----- | 2 |
+m | b | b |...| b | m initialized bytes -----------------
+-----</tt></p>
+
+<p><tt>_________ / word \ ----------------------- | 3 | m |
+w |... m initialized wordsized integers
+-----------------------</tt></p>
+
+<p><tt>_________ / pointer \ ----------------------- | 4 |
+m | p |... m initialized data pointers
+-----------------------</tt></p>
+
+<p><tt>_________ / pointer \ ----------------------- | 5 |
+m | p |... m initialized instruction pointers
+-----------------------</tt></p>
+
+<p><tt>____________ / bytes \ ------------------------- | 6
+| m | b | b |...| b | initialized integer of size m
+-------------------------</tt></p>
+
+<p><tt>____________ / bytes \ ------------------------- | 7
+| m | b | b |...| b | initialized unsigned of size m
+-------------------------</tt></p>
+
+<p><tt>____________ / string \ ------------------------- |
+8 | m | s | initialized float of size m
+-------------------------</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 0:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>If the last initialization initialized k bytes starting
+at address <i>a</i>, do the same initialization again n
+times, starting at <i>a</i>+k, <i>a</i>+2*k, ....
+<i>a</i>+n*k. This is the only descriptor whose starting
+byte is followed by an integer with the size of a pointer,
+in all other descriptors the first byte is followed by a
+one-byte count. This descriptor must be preceded by a
+descriptor of another type.</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 1:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>Reserve m words, not explicitly initialized (BSS and
+HOL).</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 2:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>The m bytes following the descriptor header are
+initializers for the next m bytes of the global data area. m
+is divisible by the wordsize.</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 3:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>The m words following the header are initializers for
+the next m words of the global data area.</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 4:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>The m data address space pointers following the header
+are initializers for the next m data pointers in the global
+data area. Interpreters that represent EM pointers by target
+machine addresses must relocate all data pointers.</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 5:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>The m instruction address space pointers following the
+header are initializers for the next m instruction pointers
+in the global data area. Interpreters that represent EM
+instruction pointers by target machine addresses must
+relocate these pointers.</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 6:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>The m bytes following the header form a signed integer
+number with a size of m bytes, which is an initializer for
+the next m bytes of the global data area. m is governed by
+the same restrictions as for transfer of objects to/from
+memory.</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 7:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>The m bytes following the header form an unsigned
+integer number with a size of m bytes, which is an
+initializer for the next m bytes of the global data area. m
+is governed by the same restrictions as for transfer of
+objects to/from memory.</p>
+</td>
+<td width="51%">
+</td>
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>type 8:</p>
+</td>
+<td width="6%"></td>
+<td width="28%">
+
+<p>The header is followed by an ASCII string, null
+terminated, to initialize, in global data, a floating point
+number with a size of m bytes. m is governed by the same
+restrictions as for transfer of objects to/from memory. The
+ASCII string contains the notation of a real as used in the
+Pascal language.</p>
+</td>
+<td width="51%">
+</td>
+</table>
+
+<p>The NPROC procedure descriptors on the load file consist
+of an instruction space address (of pointer size) and an
+integer (of pointer size) specifying the number of bytes for
+locals.</p>
+
+<p>11</p>
+
+<p><b>11. EM ASSEMBLY LANGUAGE</b></p>
+
+<p>We use two representations for assembly language
+programs, one is in ASCII and the other is the compact
+assembly language. The latter needs less space than the
+first for the same program and therefore allows faster
+processing. Our only program accepting ASCII assembly
+language converts it to the compact form. All other programs
+expect compact assembly input. The first part of the chapter
+describes the ASCII assembly language and its semantics. The
+second part describes the syntax of the compact assembly
+language. The last part lists the EM instructions with the
+type of arguments allowed and an indication of the function.
+Appendix A gives a detailed description of the effect of all
+instructions in the form of a Pascal program.</p>
+
+<p><b>11.1 ASCII assembly language</b></p>
+
+<p>An assembly language program consists of a series of
+lines, each line may be blank, contain one
+(pseudo)instruction or contain one label. Input to the
+assembler is in lower case. Upper case is used in this
+document merely to distinguish keywords from the surrounding
+prose. Comment is allowed at the end of each line and starts
+with a semicolon &quot;;&quot;. This kind of comment does
+not exist in the compact form.</p>
+
+<p>Labels must be placed all by themselves on a line and
+start in column 1. There are two kinds of labels,
+instruction and data labels. Instruction labels are unsigned
+positive integers. The scope of an instruction label is its
+procedure.</p>
+
+<p>The pseudoinstructions CON, ROM and BSS may be preceded
+by a line containing a 1&minus;8 character data label, the
+first character of which is a letter, period or underscore.
+The period may only be followed by digits, the others may be
+followed by letters, digits and underscores. The use of the
+character &quot;.&quot; followed by a constant, which must
+be in the range 1 to 32767 (e.g. &quot;.40&quot;) is
+recommended for compiler generated programs. These labels
+are considered as a special case and handled more
+efficiently in compact assembly language (see below). Note
+that a data label on its own or two consecutive labels are
+not allowed.</p>
+
+<p>Each statement may contain an instruction mnemonic or
+pseudoinstruction. These must begin in column 2 or later
+(not column 1) and must be followed by a space, tab,
+semicolon or LF. Everything on the line following a
+semicolon is taken as a comment.</p>
+
+<p>Each input file contains one module. A module may
+contain many procedures, which may be nested. A procedure
+consists of a PRO statement, a (possibly empty) collection
+of instructions and pseudoinstructions and finally an END
+statement. Pseudoinstructions are also allowed between
+procedures. They do not belong to a specific procedure.</p>
+
+<p>All constants in EM are interpreted in the decimal base.
+The ASCII assembly language accepts constant expressions
+wherever constants are allowed. The operators recognized
+are: +, &minus;, *, % and / with the usual precedence order.
+Use of the parentheses ( and ) to alter the precedence order
+is allowed.</p>
+
+<p><i>11.1.1 Instruction arguments</i></p>
+
+<p>Unlike many other assembly languages, the EM assembly
+language requires all arguments of normal and
+pseudoinstructions to be either a constant or an identifier,
+but not a combination of these two. There is one exception
+to this rule: when a data label is used for initialization
+or as an instruction argument, expressions of the form
+&rsquo;label+constant&rsquo; and
+&rsquo;label-constant&rsquo; are allowed. This makes it
+possible to address, for example, the third word of a ten
+word BSS block directly. Thus LOE LABEL+4 is permitted and
+so is CON LABEL+3. The resulting address is must be in the
+same fragment as the label. It is not allowed to add or
+subtract from instruction labels or procedure identifiers,
+which certainly is not a severe restriction and greatly aids
+optimization.</p>
+
+<p>Instruction arguments can be constants, data labels,
+data labels offsetted by a constant, instruction labels and
+procedure identifiers. The range of integers allowed depends
+on the instruction. Most instructions allow only integers
+(signed or unsigned) that fit in a word. Arguments used as
+offsets to pointers should fit in a pointer-sized integer.
+Finally, arguments to LDC should fit in a double-word
+integer.</p>
+
+<p>Several instructions have two possible forms: with an
+explicit argument and with an implicit argument on top of
+the stack. The size of the implicit argument is the
+wordsize. The implicit argument is always popped before all
+other operands. For example: &rsquo;CMI 4&rsquo; specifies
+that two four-byte signed integers on top of the stack are
+to be compared. &rsquo;CMI&rsquo; without an argument
+expects a wordsized integer on top of the stack that
+specifies the size of the integers to be compared. Thus the
+following two sequences are equivalent:</p>
+
+<p align=center><img src="grohtml-97448.png"></p>
+
+<p>Section 11.1.6 shows the arguments allowed for each
+instruction.</p>
+
+<p><i>11.1.2 Pseudoinstruction arguments</i></p>
+
+<p>Pseudoinstruction arguments can be divided in two
+classes: Initializers and others. The following initializers
+are allowed: signed integer constants, unsigned integer
+constants, floating-point constants, strings, data labels,
+data labels offsetted by a constant, instruction labels and
+procedure identifiers.</p>
+
+<p>Constant initializers in BSS, HOL, CON and ROM
+pseudoinstructions can be followed by a letter I, U or F.
+This indicator specifies the type of the initializer:
+Integer, Unsigned or Float. If no indicator is present I is
+assumed. The size of the initializer is the wordsize unless
+the indicator is followed by an integer specifying the
+initializer&rsquo;s size. This integer is governed by the
+same restrictions as for transfer of objects to/from memory.
+As in instruction arguments, initializers include
+expressions of the form: &quot;LABEL+offset&quot; and
+&quot;LABEL&minus;offset&quot;. The offset must be an
+unsigned decimal constant. The &rsquo;IUF&rsquo; indicators
+cannot be used in the offsets.</p>
+
+<p>Data labels are referred to by their name.</p>
+
+<p>Strings are surrounded by double quotes (&quot;).
+Semicolon&rsquo;s in string do not indicate the start of
+comment. In the ASCII representation the escape character \
+(backslash) alters the meaning of subsequent character(s).
+This feature allows inclusion of zeroes, graphic characters
+and the double quote in the string. The following escape
+sequences exist:</p>
+
+<p align=center><img src="grohtml-97449.png"></p>
+
+<p>The escape <b>\ddd</b> consists of the backslash
+followed by 1, 2, or 3 octal digits specifying the value of
+the desired character. If the character following a
+backslash is not one of those specified, the backslash is
+ignored. Example: CON &quot;hello\012\0&quot;. Each string
+element initializes a single byte. The ASCII character set
+is used to map characters onto values.</p>
+
+<p>Instruction labels are referred to as *1, *2, etc. in
+both branch instructions and as initializers.</p>
+
+<p>The notation $procname means the identifier for the
+procedure with the specified name. This identifier has the
+size of a pointer.</p>
+
+<p><i>11.1.3 Notation</i></p>
+
+<p>First, the notation used for the arguments, classes of
+instructions and pseudoinstructions.</p>
+
+<p align=center><img src="grohtml-974410.png"></p>
+
+<p><i>11.1.4 Pseudoinstructions</i></p>
+
+<p><i>11.1.4.1 Storage declaration</i></p>
+
+<p>Initialized global data is allocated by the
+pseudoinstruction CON, which needs at least one argument.
+Each argument is used to allocate and initialize a number of
+consecutive bytes in data memory. The number of bytes to be
+allocated and the alignment depend on the type of the
+argument. For each argument, an integral number of words,
+determined by the argument type, is allocated and
+initialized.</p>
+
+<p>The pseudoinstruction ROM is the same as CON, except
+that it guarantees that the initialized words will not
+change during the execution of the program. This information
+allows optimizers to do certain calculations such as array
+indexing and subrange checking at compile time instead of at
+run time.</p>
+
+<p>The pseudoinstruction BSS allocates uninitialized global
+data or large blocks of data initialized by the same value.
+The first argument to this pseudo is the number of bytes
+required, which must be a multiple of the wordsize. The
+other arguments specify the value used for initialization
+and whether the initialization is only for convenience or a
+strict necessity. The pseudoinstruction HOL is similar to
+BSS in that it requests an (un)initialized global data
+block. Addressing of a HOL block, however, is quasi
+absolute. The first byte is addressed by 0, the second byte
+by 1 etc. in assembly language. The assembler/loader adds
+the base address of the HOL block to these numbers to obtain
+the absolute address in the machine language.</p>
+
+<p>The scope of a HOL block starts at the HOL pseudo and
+ends at the next HOL pseudo or at the end of a module
+whatever comes first. Each instruction falls in the scope of
+at most one HOL block, the current HOL block. It is not
+allowed to have more than one HOL block per procedure.</p>
+
+<p>The alignment restrictions are enforced by the
+pseudoinstructions. All initializers are aligned on a
+multiple of their size or the wordsize whichever is smaller.
+Strings form an exception, they are to be seen as a sequence
+of initializers each for one byte, i.e. strings are not
+padded with zero bytes. Switching to another type of
+fragment or placing a label forces word-alignment. There are
+three types of fragments in global data space: CON, ROM and
+BSS/HOL.</p>
+
+<p>BSS &lt;cst1&gt;,&lt;val&gt;,&lt;cst2&gt;</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Reserve &lt;cst1&gt; bytes. &lt;val&gt; is the value used
+to initialize the area. &lt;cst1&gt; must be a multiple of
+the size of &lt;val&gt;. &lt;cst2&gt; is 0 if the
+initialization is not strictly necessary, 1 if it is.</p>
+</td>
+</table>
+
+<p>HOL &lt;cst1&gt;,&lt;val&gt;,&lt;cst2&gt;</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Idem, but all following absolute global data references
+will refer to this block. Only one HOL is allowed per
+procedure, it has to be placed before the first
+instruction.</p>
+</td>
+</table>
+
+<p>CON &lt;val&gt;+</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Assemble global data words initialized with the
+&lt;val&gt; constants.</p>
+</td>
+</table>
+
+<p>ROM &lt;val&gt;+</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Idem, but the initialized data will never be changed by
+the program.</p>
+</td>
+</table>
+
+<p><i>11.1.4.2 Partitioning</i></p>
+
+<p>Two pseudoinstructions partition the input into
+procedures:</p>
+
+<p>PRO &lt;pro&gt;[,&lt;cst&gt;]</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Start of procedure. &lt;pro&gt; is the procedure name.
+&lt;cst&gt; is the number of bytes for locals. The number of
+bytes for locals must be specified in the PRO or END
+pseudoinstruction. When specified in both, they must be
+identical.</p>
+</td>
+</table>
+
+<p>END [&lt;cst&gt;]</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>End of Procedure. &lt;cst&gt; is the number of bytes for
+locals. The number of bytes for locals must be specified in
+either the PRO or END pseudoinstruction or both.</p>
+</td>
+</table>
+
+<p><i>11.1.4.3 Visibility</i></p>
+
+<p>Names of data and procedures in an EM module can either
+be internal or external. External names are known outside
+the module and are used to link several pieces of a program.
+Internal names are not known outside the modules they are
+used in. Other modules will not &rsquo;see&rsquo; an
+internal name.</p>
+
+<p>To reduce the number of passes needed, it must be known
+at the first occurrence whether a name is internal or
+external. If the first occurrence of a name is in a
+definition, the name is considered to be internal. If the
+first occurrence of a name is a reference, the name is
+considered to be external. If the first occurrence is in one
+of the following pseudoinstructions, the effect of the
+pseudo has precedence.</p>
+
+<p>EXA &lt;dlb&gt;</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>External name. &lt;dlb&gt; is known, possibly defined,
+outside this module. Note that &lt;dlb&gt; may be defined in
+the same module.</p>
+</td>
+</table>
+
+<p>EXP &lt;pro&gt;</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>External procedure identifier. Note that &lt;pro&gt; may
+be defined in the same module.</p>
+</td>
+</table>
+
+<p>INA &lt;dlb&gt;</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Internal name. &lt;dlb&gt; is internal to this module and
+must be defined in this module.</p>
+</td>
+</table>
+
+<p>INP &lt;pro&gt;</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Internal procedure. &lt;pro&gt; is internal to this
+module and must be defined in this module.</p>
+</td>
+</table>
+
+<p><i>11.1.4.4 Miscellaneous</i></p>
+
+<p>Two other pseudoinstructions provide miscellaneous
+features:</p>
+
+<p>EXC &lt;cst1&gt;,&lt;cst2&gt;</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Two blocks of instructions preceding this one are
+interchanged before being processed. &lt;cst1&gt; gives the
+number of lines of the first block. &lt;cst2&gt; gives the
+number of lines of the second one. Blank and pure comment
+lines do not count. This instruction is obsolete. Its use is
+strongly discouraged.</p>
+</td>
+</table>
+
+<p>MES &lt;cst&gt;[,&lt;par&gt;]*</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A special type of comment. Used by compilers to
+communicate with the optimizer, assembler, etc. as
+follows:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 0</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>An error has occurred, stop further processing.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 1</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Suppress optimization.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 2,&lt;cst1&gt;,&lt;cst2&gt;</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Use wordsize &lt;cst1&gt; and pointer size
+&lt;cst2&gt;.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES
+3,&lt;cst1&gt;,&lt;cst2&gt;,&lt;cst3&gt;,&lt;cst4&gt;</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Indicates that a local variable is never referenced
+indirectly. Used to indicate that a register may be used for
+a specific variable. &lt;cst1&gt; is offset in bytes from AB
+if positive and offset from LB if negative. &lt;cst2&gt;
+gives the size of the variable. &lt;cst3&gt; indicates the
+class of the variable. The following values are currently
+recognized:<br>
+0 The variable can be used for anything.<br>
+1 The variable is used as a loopindex.<br>
+2 The variable is used as a pointer.<br>
+3 The variable is used as a floating point number.<br>
+&lt;cst4&gt; gives the priority of the variable, higher
+numbers indicate better candidates.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 4,&lt;cst&gt;,&lt;str&gt;</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Number of source lines in file &lt;str&gt; (for
+profiler).</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 5</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Floating point used.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 6,&lt;val&gt;*</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Comment. Used to provide comments in compact assembly
+language.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 7,.....</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Reserved.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 8,&lt;pro&gt;[,&lt;dlb&gt;]...</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Library module. Indicates that the module may only be
+loaded if it is useful, that is, if it can satisfy any
+unresolved references during the loading process. May not be
+preceded by any other pseudo, except MES&rsquo;s.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 9,&lt;cst&gt;</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Guarantees that no more than &lt;cst&gt; bytes of
+parameters are accessed, either directly or indirectly.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 10,&lt;cst&gt;[,&lt;par&gt;]*</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>This message number is reserved for the global optimizer.
+It inserts these messages in its output as hints to
+backends. &lt;cst&gt; indicates the type of hint.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>MES 11</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Procedures containing this message are possible
+destinations of non-local goto&rsquo;s with the GTO
+instruction. Some backends keep locals in registers, the
+locals in this procedure should not be kept in registers and
+all registers containing locals of other procedures should
+be saved upon entry to this procedure.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Each backend is free to skip irrelevant MES pseudos.</p>
+</td>
+</table>
+
+<p><b>11.2 The Compact Assembly Language</b></p>
+
+<p>The assembler accepts input in a highly encoded form.
+This form is intended to reduce the amount of file transport
+between the front ends, optimizers and back ends, and also
+reduces the amount of storage required for storing
+libraries. Libraries are stored as archived compact assembly
+language, not machine language.</p>
+
+<p>When beginning to read the input, the assembler is in
+neutral state, and expects either a label or an instruction
+(including the pseudoinstructions). The meaning of the next
+byte(s) when in neutral state is as follows, where b1, b2
+etc. represent the succeeding bytes.</p>
+
+<p align=center><img src="grohtml-974411.png"></p>
+
+<p>After a label, the assembler is back in neutral state;
+it can immediately accept another label or an instruction in
+the next byte. No linefeeds are used to separate lines.</p>
+
+<p>If an opcode expects no arguments, the assembler is back
+in neutral state after reading the one byte containing the
+instruction number. If it has one or more arguments (only
+pseudos have more than 1), the arguments follow directly,
+encoded as follows:</p>
+
+<p align=center><img src="grohtml-974412.png"></p>
+
+<p>Absence of an optional argument is indicated by a
+special byte.</p>
+
+<p align=center><img src="grohtml-974413.png"></p>
+
+<p>The bytes specifying the value of a 16, 32 or 64 bit
+constant are presented in two&rsquo;s complement notation,
+with the least significant byte first. For example: the
+value of a 32 bit constant is ((s4*256+b3)*256+b2)*256+b1,
+where s4 is b4&minus;256 if b4 is greater than 128 else s4
+takes the value of b4. A &lt;string&gt; consists of a
+&lt;cst&gt; immediately followed by a sequence of bytes with
+length &lt;cst&gt;.</p>
+
+<p>The pseudoinstructions fall into several categories,
+depending on their arguments:</p>
+<pre>     Group 1 &minus; EXC, BSS, HOL have a known number of arguments
+     Group 2 &minus; EXA, EXP, INA, INP have a string as argument
+     Group 3 &minus; CON, MES, ROM have a variable number of various things
+     Group 4 &minus; END, PRO have a trailing optional argument.
+</pre>
+
+<p>Groups 1 and 2 use the encoding described above. Group 3
+also uses the encoding listed above, with an &lt;end&gt;
+byte after the last argument to indicate the end of the
+list. Group 4 uses an &lt;end&gt; byte if the trailing
+argument is not present.</p>
+
+<p align=center><img src="grohtml-974414.png"></p>
+
+<p><b>11.3 Assembly language instruction list</b></p>
+
+<p>For each instruction in the list the range of argument
+values in the assembly language is given. The column headed
+<i>assem</i> contains the mnemonics defined in 11.1.3. The
+following column specifies restrictions of the argument
+value. Addresses have to obey the restrictions mentioned in
+chapter 2. The classes of arguments are indicated by
+letters:</p>
+
+<p align=center><img src="grohtml-974415.png"></p>
+
+<p>The * at the rationale for <b>w</b> indicates that the
+argument can either be given as argument or on top of the
+stack. If the argument is omitted, the argument is fetched
+from the stack; it is assumed to be a wordsized unsigned
+integer. Instructions that check for undefined integer or
+floating-point values and underflow or overflow are
+indicated below by (*).</p>
+<pre>     GROUP 1 &minus; LOAD
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>LOC <b>c</b> :</p>
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load constant (i.e. push one word onto the stack)<br>
+LDC <b>d</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load double constant ( push two words )<br>
+LOL <b>l</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load word at <b>l</b>-th local (<b>l</b>&lt;0) or
+parameter (<b>l</b>&gt;=0)<br>
+LOE <b>g</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load external word <b>g</b><br>
+LIL <b>l</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load word pointed to by <b>l</b>-th local or
+parameter<br>
+LOF <b>f</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load offsetted (top of stack + <b>f</b> yield
+address)<br>
+LAL <b>l</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load address of local or parameter<br>
+LAE <b>g</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load address of external<br>
+LXL <b>n</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load lexical (address of LB <b>n</b> static levels
+back)<br>
+LXA <b>n</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load lexical (address of AB <b>n</b> static levels
+back)<br>
+LOI <b>o</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load indirect <b>o</b> bytes (address is popped from the
+stack)<br>
+LOS <b>w</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load indirect, <b>w</b>-byte integer on top of stack
+gives object size<br>
+LDL <b>l</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load double local or parameter (two consecutive words
+are stacked)<br>
+LDE <b>g</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load double external (two consecutive externals are
+stacked)<br>
+LDF <b>f</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load double offsetted (top of stack + <b>f</b> yield
+address)<br>
+LPI <b>p</b> :</p>
+</td>
+<td width="66%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="20%">
+
+<p>Load procedure identifier</p>
+</td>
+<td width="66%">
+</td>
+</table>
+<pre>     GROUP 2 &minus; STORE
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>STL <b>l</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store local or parameter<br>
+STE <b>g</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store external<br>
+SIL <b>l</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store into word pointed to by <b>l</b>-th local or
+parameter<br>
+STF <b>f</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store offsetted<br>
+STI <b>o</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store indirect <b>o</b> bytes (pop address, then
+data)<br>
+STS <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store indirect, <b>w</b>-byte integer on top of stack
+gives object size<br>
+SDL <b>l</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store double local or parameter<br>
+SDE <b>g</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store double external<br>
+SDF <b>f</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store double offsetted</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 3 &minus; INTEGER ARITHMETIC
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>ADI <b>w</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Addition (*)<br>
+SBI <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Subtraction (*)<br>
+MLI <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Multiplication (*)<br>
+DVI <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Division (*)<br>
+RMI <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Remainder (*)<br>
+NGI <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Negate (two&rsquo;s complement) (*)<br>
+SLI <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Shift left (*)<br>
+SRI <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Shift right (*)</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 4 &minus; UNSIGNED ARITHMETIC
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>ADU <b>w</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Addition<br>
+SBU <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Subtraction<br>
+MLU <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Multiplication<br>
+DVU <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Division<br>
+RMU <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Remainder<br>
+SLU <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Shift left<br>
+SRU <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Shift right</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 5 &minus; FLOATING POINT ARITHMETIC
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>ADF <b>w</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Floating add (*)<br>
+SBF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Floating subtract (*)<br>
+MLF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Floating multiply (*)<br>
+DVF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Floating divide (*)<br>
+NGF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Floating negate (*)<br>
+FIF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Floating multiply and split integer and fraction part
+(*)<br>
+FEF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Split floating number in exponent and fraction part
+(*)</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 6 &minus; POINTER ARITHMETIC
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>ADP <b>f</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Add <b>f</b> to pointer on top of stack<br>
+ADS <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Add <b>w</b>-byte value and pointer<br>
+SBS <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Subtract pointers in same fragment and push diff as size
+<b>w</b> integer</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 7 &minus; INCREMENT/DECREMENT/ZERO
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>INC <b>&minus;</b> :</p>
+<td width="9%"></td>
+<td width="10%">
+
+<p>Increment word on top of stack by 1 (*)<br>
+INL <b>l</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Increment local or parameter (*)<br>
+INE <b>g</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Increment external (*)<br>
+DEC <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Decrement word on top of stack by 1 (*)<br>
+DEL <b>l</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Decrement local or parameter (*)<br>
+DEE <b>g</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Decrement external (*)<br>
+ZRL <b>l</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Zero local or parameter<br>
+ZRE <b>g</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Zero external<br>
+ZRF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Load a floating zero of size <b>w</b><br>
+ZER <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>Load <b>w</b> zero bytes</p>
+<pre>     GROUP 8 &minus; CONVERT    (stack:</td>
+<td width="79%">
+  source, source size, dest. size (top))
+
+
+       CII <b>&minus;</b> :</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert integer to integer (*)
+       CUI <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert unsigned to integer (*)
+       CFI <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert floating to integer (*)
+       CIF <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert integer to floating (*)
+       CUF <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert unsigned to floating (*)
+       CFF <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert floating to floating (*)
+       CIU <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert integer to unsigned
+       CUU <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert unsigned to unsigned
+       CFU <b>&minus;</b> :</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+ Convert floating to unsigned</td>
+<td width="79%">
+</td>
+</table>
+
+</pre>
+<pre>     GROUP 9 &minus; LOGICAL
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>AND <b>w</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Boolean and on two groups of <b>w</b> bytes<br>
+IOR <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Boolean inclusive or on two groups of <b>w</b> bytes<br>
+XOR <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Boolean exclusive or on two groups of <b>w</b> bytes<br>
+COM <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Complement (one&rsquo;s complement of top <b>w</b>
+bytes)<br>
+ROL <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Rotate left a group of <b>w</b> bytes<br>
+ROR <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Rotate right a group of <b>w</b> bytes</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 10 &minus; SETS
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>INN <b>w</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Bit test on <b>w</b> byte set (bit number on top of
+stack)<br>
+SET <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Create singleton <b>w</b> byte set with bit n on (n is
+top of stack)</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 11 &minus; ARRAY
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>LAR <b>w</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Load array element, descriptor contains integers of size
+<b>w</b><br>
+SAR <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store array element<br>
+AAR <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Load address of array element</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 12 &minus; COMPARE
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>CMI <b>w</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Compare <b>w</b> byte integers, Push negative, zero,
+positive for &lt;, = or &gt;<br>
+CMF <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Compare <b>w</b> byte reals<br>
+CMU <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Compare <b>w</b> byte unsigneds<br>
+CMS <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Compare <b>w</b> byte values, can only be used for bit
+for bit equality test<br>
+CMP <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Compare pointers</p>
+
+<p>TLT <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>True if less, i.e. iff top of stack &lt; 0<br>
+TLE <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>True if less or equal, i.e. iff top of stack &lt;= 0<br>
+TEQ <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>True if equal, i.e. iff top of stack = 0<br>
+TNE <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>True if not equal, i.e. iff top of stack non zero<br>
+TGE <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>True if greater or equal, i.e. iff top of stack &gt;=
+0<br>
+TGT <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>True if greater, i.e. iff top of stack &gt; 0</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 13 &minus; BRANCH
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>BRA <b>b</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch unconditionally to label <b>b</b></p>
+
+<p>BLT <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch less (pop 2 words, branch if top &gt; second)<br>
+BLE <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch less or equal<br>
+BEQ <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch equal<br>
+BNE <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch not equal<br>
+BGE <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch greater or equal<br>
+BGT <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch greater</p>
+
+<p>ZLT <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch less than zero (pop 1 word, branch negative)<br>
+ZLE <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch less or equal to zero<br>
+ZEQ <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch equal zero<br>
+ZNE <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch not zero<br>
+ZGE <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch greater or equal zero<br>
+ZGT <b>b</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Branch greater than zero</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 14 &minus; PROCEDURE CALL
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>CAI <b>&minus;</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Call procedure (procedure identifier on stack)<br>
+CAL <b>p</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Call procedure (with identifier <b>p</b>)<br>
+LFR <b>s</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Load function result<br>
+RET <b>z</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Return (function result consists of top <b>z</b>
+bytes)</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<pre>     GROUP 15 &minus; MISCELLANEOUS
+
+
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>ASP <b>f</b> :</p>
+<td width="13%"></td>
+<td width="6%">
+
+<p>Adjust the stack pointer by <b>f</b><br>
+ASS <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Adjust the stack pointer by <b>w</b>-byte integer<br>
+BLM <b>z</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Block move <b>z</b> bytes; first pop destination addr,
+then source addr<br>
+BLS <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Block move, size is in <b>w</b>-byte integer on top of
+stack<br>
+CSA <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Case jump; address of jump table at top of stack<br>
+CSB <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Table lookup jump; address of jump table at top of
+stack<br>
+DCH <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Follow dynamic chain, convert LB to LB of caller<br>
+DUP <b>s</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Duplicate top <b>s</b> bytes<br>
+DUS <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Duplicate top <b>w</b> bytes<br>
+EXG <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Exchange top <b>w</b> bytes<br>
+FIL <b>g</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>File name (external 4 := <b>g</b>)<br>
+GTO <b>g</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Non-local goto, descriptor at <b>g</b><br>
+LIM <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Load 16 bit ignore mask<br>
+LIN <b>n</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Line number (external 0 := <b>n</b>)<br>
+LNI <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Line number increment<br>
+LOR <b>r</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Load register (0=LB, 1=SP, 2=HP)<br>
+LPB <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Convert local base to argument base<br>
+MON <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Monitor call<br>
+NOP <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>No operation<br>
+RCK <b>w</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Range check; trap on error<br>
+RTT <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Return from trap<br>
+SIG <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Trap errors to proc identifier on top of stack, &minus;2
+resets default<br>
+SIM <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store 16 bit ignore mask<br>
+STR <b>r</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Store register (0=LB, 1=SP, 2=HP)<br>
+TRP <b>&minus;</b> :</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="6%">
+
+<p>Cause trap to occur (Error number on stack)</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p>12</p>
+
+<p><b>A. EM INTERPRETER</b></p>
+<pre>{ This  is an interpreter for EM.  It serves as  the official machine
+  definition.  This interpreter must run on a machine which supports
+  arithmetic with words and memory offsets.
+
+ Certain aspects of the definition are over specified.  In particular:
+
+   1. The representation of  an  address on the stack  need not be the
+       numerical value of the memory location.
+
+   2. The state of  the stack is not defined  after a trap has aborted
+       an instruction in the middle.  For example, it is officially un-
+       defined  whether the second  operand of an  ADD  instruction has
+       been popped  or  not  if the  first one is undefined ( -32768 or
+       unsigned 32768).
+
+   3. The memory layout is implementation dependent. Only the most
+       basic checks are performed whenever memory is accessed.
+
+   4. The representation of an integer or set on the stack is not fixed
+       in bit order.
+
+   5. The format and existence of the procedure descriptors depends on
+       the implementation.
+
+   6. The result of the compare operators  CMI etc.  are -1, 0  and  1
+       here, but other negative  and  positive values will do  and they
+       need not be the same each time.
+
+   7. The shift count for SHL, SHR, ROL and ROR must be in the range 0
+       to object size in bits - 1.  The effect of a  count  not in this
+       range is undefined.
+}
+</pre>
+
+<p>13</p>
+
+<p><tt>{$i256} {$d+} program
+em(tables,prog,input,output);</tt></p>
+
+<p><tt>label 8888,9999;</tt></p>
+
+<p><tt>const t15 = 32768; { 2**15 } t15m1 = 32767; { 2**15
+-1 } t16 = 65536; { 2**16 } t16m1 = 65535; { 2**16 -1 }
+t31m1 = 2147483647; { 2**31 -1 }</tt></p>
+
+<p><tt>wsize = 2; { number of bytes in a word } asize = 2;
+{ number of bytes in an address } fsize = 4; { number of
+bytes in a floating point number } maxret =4; { number of
+words in the return value area }</tt></p>
+
+<p><tt>signbit = t15; { the power of two indicating the
+sign bit } negoff = t16; { the next power of two } maxsint =
+t15m1; { the maximum signed integer } maxuint = t16m1; { the
+maximum unsigned integer } maxdbl = t31m1; { the maximum
+double signed integer } maxadr = t16m1; { the maximum
+address } maxoffs = t15m1; { the maximum offset from an
+address } maxbitnr= 15; { the number of the highest bit
+}</tt></p>
+
+<p><tt>lineadr = 0; { address of the line number } fileadr
+= 4; { address of the file name } maxcode = 8191; { highest
+byte in code address space } maxdata = 8191; { highest byte
+in data address space }</tt></p>
+
+<p><tt>{ format of status save area } statd = 4; { how far
+is static link from lb } dynd = 2; { how far is dynamic link
+from lb } reta = 0; { how far is the return address from lb
+} savsize = 4; { size of save area in bytes }</tt></p>
+
+<p><tt>{ procedure descriptor format } pdlocs = 0; { offset
+for size of local variables in bytes } pdbase = asize; {
+offset for the procedure base } pdsize = 4; { size of
+procedure descriptor in bytes = 2*asize }</tt></p>
+
+<p><tt>{ header words } NTEXT = 1; NDATA = 2; NPROC = 3;
+ENTRY = 4; NLINE = 5; SZDATA = 6;</tt></p>
+
+<p><tt>escape1 = 254; { escape to secondary opcodes }
+escape2 = 255; { escape to tertiary opcodes } undef =
+signbit; { the range of integers is -32767 to +32767
+}</tt></p>
+
+<p><tt>{ error codes } EARRAY = 0; ERANGE = 1; ESET = 2;
+EIOVFL = 3; EFOVFL = 4; EFUNFL = 5; EIDIVZ = 6; EFDIVZ = 7;
+EIUND = 8; EFUND = 9; ECONV = 10; ESTACK = 16; EHEAP = 17;
+EILLINS = 18; EODDZ = 19; ECASE = 20; EMEMFLT = 21; EBADPTR
+= 22; EBADPC = 23; EBADLAE = 24; EBADMON = 25; EBADLIN = 26;
+EBADGTO = 27;</tt></p>
+
+<p>14</p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Declarations }
+{---------------------------------------------------------------------------}</tt></p>
+
+<p><tt>type bitval= 0..1; { one bit } bitnr= 0..maxbitnr; {
+bits in machine words are numbered 0 to 15 } byte= 0..255; {
+memory is an array of bytes } adr= {0..maxadr} long; { the
+range of addresses } word= {0..maxuint} long;{ the range of
+unsigned integers } offs= -maxoffs..maxoffs; { the range of
+signed offsets from addresses } size= 0..maxoffs; { the
+range of sizes is the positive offsets } sword=
+{-signbit..maxsint} long; { the range of signed integers }
+full= {-maxuint..maxuint} long; { intermediate results need
+this range } double={-maxdbl..maxdbl} long; { double
+precision range } bftype= (andf,iorf,xorf); { tells which
+boolean operator needed } insclass=(prim,second,tert); {
+tells which opcode table is in use }
+instype=(implic,explic); { does opcode have implicit or
+explicit operand } iflags= (mini,short,sbit,wbit,zbit,ibit);
+ifset= set of iflags;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><tt>mnem = ( NON,</tt></p>
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>AAR, ADF, ADI, ADP, ADS, ADU,XAND, ASP, ASS,
+BEQ,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>BGE, BGT, BLE, BLM, BLS, BLT, BNE, BRA, CAI,
+CAL,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>CFF, CFI, CFU, CIF, CII, CIU, CMF, CMI, CMP,
+CMS,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>CMU, COM, CSA, CSB, CUF, CUI, CUU, DCH, DEC,
+DEE,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>DEL, DUP, DUS, DVF, DVI, DVU, EXG, FEF, FIF,
+FIL,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>GTO, INC, INE, INL, INN, IOR, LAE, LAL, LAR,
+LDC,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>LDE, LDF, LDL, LFR, LIL, LIM, LIN, LNI, LOC,
+LOE,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>LOF, LOI, LOL, LOR, LOS, LPB, LPI, LXA, LXL,
+MLF,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>MLI, MLU, MON, NGF, NGI, NOP, RCK, RET, RMI,
+RMU,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>ROL, ROR, RTT, SAR, SBF, SBI, SBS, SBU, SDE,
+SDF,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>SDL,XSET, SIG, SIL, SIM, SLI, SLU, SRI, SRU,
+STE,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>STF, STI, STL, STR, STS, TEQ, TGE, TGT, TLE,
+TLT,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>TNE, TRP, XOR, ZEQ, ZER, ZGE, ZGT, ZLE, ZLT,
+ZNE,</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>ZRE, ZRF, ZRL);</tt></p>
+
+<p><tt>dispatch = record</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>iflag: ifset;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>instr: mnem;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>case instype of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>implic: (implicit:sword);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>explic: (ilength:byte);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+</table>
+
+<p><tt>var code: packed array[0..maxcode] of byte; { code
+space } data: packed array[0..maxdata] of byte; { data space
+} retarea: array[1..maxret ] of word; { return area }
+pc,lb,sp,hp,pd: adr; { internal machine registers } i:
+integer; { integer scratch variable } s,t :word; { scratch
+variables } sz:size; { scratch variables } ss,st: sword; {
+scratch variables } k :double; { scratch variables } j:size;
+{ scratch variable used as index } a,b:adr; { scratch
+variable used for addresses } dt,ds:double; { scratch
+variables for double precision } rt,rs,x,y:real; { scratch
+variables for real } found:boolean; { scratch } opcode:
+byte; { holds the opcode during execution } iclass:
+insclass; { true for escaped opcodes } dispat:
+array[insclass,byte] of dispatch; retsize:size; { holds size
+of last LFR } insr: mnem; { holds the instruction number }
+halted: boolean; { normally false } exitstatus:word; {
+parameter of MON 1 } ignmask:word; { ignore mask for traps }
+uerrorproc:adr; { number of user defined error procedure }
+intrap:boolean; { Set when executing trap(), to catch
+recursive calls} trapval:byte; { Set to number of last trap
+} header: array[1..8] of adr;</tt></p>
+
+<p><tt>tables: text; { description of EM instructions }
+prog: file of byte; { program and initialized data
+}</tt></p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Various check routines }
+{---------------------------------------------------------------------------}</tt></p>
+
+<p><tt>{ Only the most basic checks are performed. These
+routines are inherently implementation dependent. }</tt></p>
+
+<p><tt>procedure trap(n:byte); forward;</tt></p>
+
+<p><tt>procedure memadr(a:adr); begin if (a&gt;maxdata) or
+((a&lt;sp) and (a&gt;=hp)) then trap(EMEMFLT) end;</tt></p>
+
+<p><tt>procedure wordadr(a:adr); begin memadr(a); if (a mod
+wsize&lt;&gt;0) then trap(EBADPTR) end;</tt></p>
+
+<p><tt>procedure chkadr(a:adr; s:size); begin memadr(a);
+memadr(a+s-1); { assumption: size is ok } if s&lt;wsize then
+begin if a mod s&lt;&gt;0 then trap(EBADPTR) end else if a
+mod wsize&lt;&gt;0 then trap(EBADPTR) end;</tt></p>
+
+<p><tt>procedure newpc(a:double); begin if (a&lt;0) or
+(a&gt;maxcode) then trap(EBADPC); pc:=a end;</tt></p>
+
+<p><tt>procedure newsp(a:adr); begin if (a&gt;lb) or
+(a&lt;hp) or (a mod wsize&lt;&gt;0) then trap(ESTACK); sp:=a
+end;</tt></p>
+
+<p><tt>procedure newlb(a:adr); begin if (a&lt;sp) or (a mod
+wsize&lt;&gt;0) then trap(ESTACK); lb:=a end;</tt></p>
+
+<p><tt>procedure newhp(a:adr); begin if (a&gt;sp) or
+(a&gt;maxdata+1) or (a mod wsize&lt;&gt;0) then trap(EHEAP)
+else hp:=a end;</tt></p>
+
+<p><tt>function argc(a:double):sword; begin if
+(a&lt;-signbit) or (a&gt;maxsint) then trap(EILLINS);
+argc:=a end;</tt></p>
+
+<p><tt>function argd(a:double):double; begin if
+(a&lt;-maxdbl) or (a&gt;maxdbl) then trap(EILLINS); argd:=a
+end;</tt></p>
+
+<p><tt>function argl(a:double):offs; begin if
+(a&lt;-maxoffs) or (a&gt;maxoffs) then trap(EILLINS);
+argl:=a end;</tt></p>
+
+<p><tt>function argg(k:double):adr; begin if (k&lt;0) or
+(k&gt;maxadr) then trap(EILLINS); argg:=k end;</tt></p>
+
+<p><tt>function argf(a:double):offs; begin if
+(a&lt;-maxoffs) or (a&gt;maxoffs) then trap(EILLINS);
+argf:=a end;</tt></p>
+
+<p><tt>function argn(a:double):word; begin if (a&lt;0) or
+(a&gt;maxuint) then trap(EILLINS); argn:=a end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>function args(a:double):size; begin if (a&lt;=0) or
+(a&gt;maxoffs)</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>then trap(EODDZ)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else if (a mod wsize)&lt;&gt;0 then trap(EODDZ);
+args:=a ; end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>function argz(a:double):size; begin if (a&lt;0) or
+(a&gt;maxoffs)</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>then trap(EODDZ)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else if (a mod wsize)&lt;&gt;0 then trap(EODDZ);
+argz:=a ; end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>function argo(a:double):size; begin if (a&lt;=0) or
+(a&gt;maxoffs)</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>then trap(EODDZ)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else if (a mod wsize&lt;&gt;0) and (wsize mod
+a&lt;&gt;0) then trap(EODDZ); argo:=a ; end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>function argw(a:double):size; begin if (a&lt;=0) or
+(a&gt;maxoffs) or (a&gt;maxuint)</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>then trap(EODDZ)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else if (a mod wsize)&lt;&gt;0 then trap(EODDZ);
+argw:=a ; end;</tt></p>
+</td>
+</table>
+
+<p><tt>function argp(a:double):size; begin if (a&lt;0) or
+(a&gt;=header[NPROC]) then trap(EILLINS); argp:=a
+end;</tt></p>
+
+<p><tt>function argr(a:double):word; begin if (a&lt;0) or
+(a&gt;2) then trap(EILLINS); argr:=a end;</tt></p>
+
+<p><tt>procedure argwf(s:double); begin if
+argw(s)&lt;&gt;fsize then trap(EILLINS) end;</tt></p>
+
+<p><tt>function szindex(s:double):integer; begin
+s:=argw(s); if (s mod wsize &lt;&gt; 0) or (s&gt;2*wsize)
+then trap(EILLINS); szindex:=s div wsize end;</tt></p>
+
+<p><tt>function locadr(l:double):adr; begin l:=argl(l); if
+l&lt;0 then locadr:=lb+l else locadr:=lb+l+savsize
+end;</tt></p>
+
+<p><tt>function signwd(w:word):sword; begin if w = undef
+then trap(EIUND); if w &gt;= signbit then signwd:=w-negoff
+else signwd:=w end;</tt></p>
+
+<p><tt>function dosign(w:word):sword; begin if w &gt;=
+signbit then dosign:=w-negoff else dosign:=w end;</tt></p>
+
+<p><tt>function unsign(w:sword):word; begin if w&lt;0 then
+unsign:=w+negoff else unsign:=w end;</tt></p>
+
+<p><tt>function chopw(dw:double):word; begin chopw:=dw mod
+negoff end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>function fitsw(w:full;trapno:byte):word; { checks
+whether value fits in signed word, returns unsigned
+representation} begin if (w&gt;maxsint) or (w&lt;-signbit)
+then begin trap(trapno); if w&lt;0 then fitsw:=negoff-
+(-w)mod negoff</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>else fitsw:=w mod negoff; end else fitsw:=unsign(w)
+end;</tt></p>
+</td>
+</table>
+
+<p><tt>function fitd(w:full):double; begin if abs(w) &gt;
+maxdbl then trap(ECONV); fitd:=w end;</tt></p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Memory access routines }
+{---------------------------------------------------------------------------}</tt></p>
+
+<p><tt>{ memw returns a machine word as an unsigned integer
+memb returns a single byte as a positive integer: 0 &lt;=
+memb &lt;= 255 mems(a,s) fetches an object smaller than a
+word and returns a word store(a,v) stores the word v at
+machine address a storea(a,v) stores the address v at
+machine address a storeb(a,b) stores the byte b at machine
+address a stores(a,s,v) stores the s least significant bytes
+of a word at address a memi returns an offset from the
+instruction space Note that the procedure descriptors are
+part of instruction space. nextpc returns the next byte
+addressed by pc, incrementing pc</tt></p>
+
+<p><tt>lino changes the line number word. filna changes the
+pointer to the file name.</tt></p>
+
+<p><tt>All routines check to make sure the address is
+within range and valid for the size of the object. If an
+addressing error is found, a trap occurs. }</tt></p>
+
+<p><tt>function memw(a:adr):word; var b:word; i:integer;
+begin wordadr(a); b:=0; for i:=wsize-1 downto 0 do b:=256*b
++ data[a+i] ; memw:=b end;</tt></p>
+
+<p><tt>function memd(a:adr):double; { Always signed } var
+b:double; i:integer; begin wordadr(a); b:=data[a+2*wsize-1];
+if b&gt;=128 then b:=b-256; for i:=2*wsize-2 downto 0 do
+b:=256*b + data[a+i] ; memd:=b end;</tt></p>
+
+<p><tt>function mema(a:adr):adr; var b:adr; i:integer;
+begin wordadr(a); b:=0; for i:=asize-1 downto 0 do b:=256*b
++ data[a+i] ; mema:=b end;</tt></p>
+
+<p><tt>function mems(a:adr;s:size):word; var i:integer;
+b:word; begin chkadr(a,s); b:=0; for i:=1 to s do
+b:=b*256+data[a+s-i]; mems:=b end;</tt></p>
+
+<p><tt>function memb(a:adr):byte; begin memadr(a);
+memb:=data[a] end;</tt></p>
+
+<p><tt>procedure store(a:adr; x:word); var i:integer; begin
+wordadr(a); for i:=0 to wsize-1 do begin data[a+i]:=x mod
+256; x:=x div 256 end end;</tt></p>
+
+<p><tt>procedure storea(a:adr; x:adr); var i:integer; begin
+wordadr(a); for i:=0 to asize-1 do begin data[a+i]:=x mod
+256; x:=x div 256 end end;</tt></p>
+
+<p><tt>procedure stores(a:adr;s:size;v:word); var
+i:integer; begin chkadr(a,s); for i:=0 to s-1 do begin
+data[a+i]:=v mod 256; v:=v div 256 end; end;</tt></p>
+
+<p><tt>procedure storeb(a:adr; b:byte); begin memadr(a);
+data[a]:=b end;</tt></p>
+
+<p><tt>function memi(a:adr):adr; var b:adr; i:integer;
+begin if (a mod wsize&lt;&gt;0) or (a+asize-1&gt;maxcode)
+then trap(EBADPTR); b:=0; for i:=asize-1 downto 0 do
+b:=256*b + code[a+i] ; memi:=b end;</tt></p>
+
+<p><tt>function nextpc:byte; begin if pc&gt;=pd then
+trap(EBADPC); nextpc:=code[pc]; newpc(pc+1) end;</tt></p>
+
+<p><tt>procedure lino(w:word); begin store(lineadr,w)
+end;</tt></p>
+
+<p><tt>procedure filna(a:adr); begin storea(fileadr,a)
+end;</tt></p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Stack Manipulation Routines }
+{---------------------------------------------------------------------------}</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>{ push puts a word on the stack pushsw takes a
+signed one word integer and pushes it on the stack pop
+removes a machine word from the stack and delivers it as a
+word popsw removes a machine word from the stack and
+delivers a signed integer pusha pushes an address on the
+stack popa removes a machine word from the stack and
+delivers it as an address pushd pushes a double precision
+number on the stack popd removes two machine words and
+returns a double precision integer pushr pushes a float
+(floating point) number on the stack popr removes several
+machine words and returns a float number pushx puts an
+object of arbitrary size on the stack popx removes an object
+of arbitrary size</tt></p>
+</td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>}</tt></p>
+</td>
+</table>
+
+<p><tt>procedure push(x:word); begin newsp(sp-wsize);
+store(sp,x) end;</tt></p>
+
+<p><tt>procedure pushsw(x:sword); begin newsp(sp-wsize);
+store(sp,unsign(x)) end;</tt></p>
+
+<p><tt>function pop:word; begin pop:=memw(sp);
+newsp(sp+wsize) end;</tt></p>
+
+<p><tt>function popsw:sword; begin popsw:=signwd(pop)
+end;</tt></p>
+
+<p><tt>procedure pusha(x:adr); begin newsp(sp-asize);
+storea(sp,x) end;</tt></p>
+
+<p><tt>function popa:adr; begin popa:=mema(sp);
+newsp(sp+asize) end;</tt></p>
+
+<p><tt>procedure pushd(y:double); begin { push double
+integer onto the stack } newsp(sp-2*wsize) end;</tt></p>
+
+<p><tt>function popd:double; begin { pop double integer
+from the stack } newsp(sp+2*wsize); popd:=0 end;</tt></p>
+
+<p><tt>procedure pushr(z:real); begin { Push a float onto
+the stack } newsp(sp-fsize) end;</tt></p>
+
+<p><tt>function popr:real; begin { pop float from the stack
+} newsp(sp+fsize); popr:=0.0 end;</tt></p>
+
+<p><tt>procedure pushx(objsize:size; a:adr); var i:integer;
+begin if objsize&lt;wsize then push(mems(a,objsize)) else
+for i:=1 to objsize div wsize do
+push(memw(a+objsize-wsize*i)) end;</tt></p>
+
+<p><tt>procedure popx(objsize:size; a:adr); var i:integer;
+begin if objsize&lt;wsize then stores(a,objsize,pop) else
+for i:=1 to objsize div wsize do store(a-wsize+wsize*i,pop)
+end;</tt></p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Bit manipulation routines (extract, shift, rotate) }
+{---------------------------------------------------------------------------}</tt></p>
+
+<p><tt>procedure sleft(var w:sword); { 1 bit left shift }
+begin w:= dosign(fitsw(2*w,EIOVFL)) end;</tt></p>
+
+<p><tt>procedure suleft(var w:word); { 1 bit left shift }
+begin w := chopw(2*w) end;</tt></p>
+
+<p><tt>procedure sdleft(var d:double); { 1 bit left shift }
+begin { shift two word signed integer } end;</tt></p>
+
+<p><tt>procedure sright(var w:sword); { 1 bit right shift
+with sign extension } begin if w &gt;= 0 then w := w div 2
+else w := (w-1) div 2 end;</tt></p>
+
+<p><tt>procedure suright(var w:word); { 1 bit right shift
+without sign extension } begin w := w div 2 end;</tt></p>
+
+<p><tt>procedure sdright(var d:double); { 1 bit right shift
+} begin { shift two word signed integer } end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure rleft(var w:word); { 1 bit left rotate }
+begin if w &gt;= t15</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>then w:=(w-t15)*2 + 1</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else w:=w*2 end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure rright(var w:word); { 1 bit right rotate }
+begin if w mod 2 = 1</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>then w:=w div 2 + t15</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else w:=w div 2 end;</tt></p>
+</td>
+</table>
+
+<p><tt>function sextend(w:word;s:size):word; var i:size;
+begin for i:=1 to (wsize-s)*8 do rleft(w); for i:=1 to
+(wsize-s)*8 do sright(w); sextend:=w; end;</tt></p>
+
+<p><tt>function bit(b:bitnr; w:word):bitval; { return bit b
+of the word w } var i:bitnr; begin for i:= 1 to b do
+rright(w); bit:= w mod 2 end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>function bf(ty:bftype; w1,w2:word):word; { return
+boolean fcn of 2 words } var i:bitnr; j:word; begin j:=0;
+for i:= maxbitnr downto 0 do</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>begin j := 2*j;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case ty of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>andf: if bit(i,w1)+bit(i,w2) = 2 then
+j:=j+1;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>iorf: if bit(i,w1)+bit(i,w2) &gt; 0 then
+j:=j+1;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>xorf: if bit(i,w1)+bit(i,w2) = 1 then
+j:=j+1</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; bf:=j end;</tt></p>
+</td>
+</table>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Array indexing }
+{---------------------------------------------------------------------------}</tt></p>
+
+<p><tt>function arraycalc(c:adr):adr; { subscript
+calculation } var j:full; objsize:size; a:adr; begin j:=
+popsw - signwd(memw(c)); if (j&lt;0) or (j&gt;memw(c+wsize))
+then trap(EARRAY); objsize := argo(memw(c+wsize+wsize)); a
+:= j*objsize+popa; chkadr(a,objsize); arraycalc:=a
+end;</tt></p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Double and Real Arithmetic }
+{---------------------------------------------------------------------------}</tt></p>
+
+<p><tt>{ All routines for doubles and floats are dummy
+routines, since the format of doubles and floats is not
+defined in EM. }</tt></p>
+
+<p><tt>function doadi(ds,dt:double):double; begin { add two
+doubles } doadi:=0 end;</tt></p>
+
+<p><tt>function dosbi(ds,dt:double):double; begin {
+subtract two doubles } dosbi:=0 end;</tt></p>
+
+<p><tt>function domli(ds,dt:double):double; begin {
+multiply two doubles } domli:=0 end;</tt></p>
+
+<p><tt>function dodvi(ds,dt:double):double; begin { divide
+two doubles } dodvi:=0 end;</tt></p>
+
+<p><tt>function dormi(ds,dt:double):double; begin { modulo
+of two doubles } dormi:=0 end;</tt></p>
+
+<p><tt>function dongi(ds:double):double; begin { negative
+of a double } dongi:=0 end;</tt></p>
+
+<p><tt>function doadf(x,y:real):real; begin { add two
+floats } doadf:=0.0 end;</tt></p>
+
+<p><tt>function dosbf(x,y:real):real; begin { subtract two
+floats } dosbf:=0.0 end;</tt></p>
+
+<p><tt>function domlf(x,y:real):real; begin { multiply two
+floats } domlf:=0.0 end;</tt></p>
+
+<p><tt>function dodvf(x,y:real):real; begin { divide two
+floats } dodvf:=0.0 end;</tt></p>
+
+<p><tt>function dongf(x:real):real; begin { negate a float
+} dongf:=0.0 end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure dofif(x,y:real;var intpart,fraction:real);
+begin { dismember x*y into integer and fractional parts }
+intpart:=0.0; { integer part of x*y, same sign as x*y }
+fraction:=0.0;</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>{ fractional part of x*y, 0&lt;=abs(fraction)&lt;1
+and same sign as x*y } end;</tt></p>
+</td>
+</table>
+
+<p><tt>procedure dofef(x:real;var mantissa:real;var
+exponent:sword); begin { dismember x into mantissa and
+exponent parts } mantissa:=0.0; { mantissa of x , &gt;= 1/2
+and &lt;1 } exponent:=0; { base 2 exponent of x }
+end;</tt></p>
+
+<p>15</p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Trap and Call }
+{---------------------------------------------------------------------------}</tt></p>
+
+<p><tt>procedure call(p:adr); { Perform the call } begin
+pusha(lb);pusha(pc); newlb(sp);newsp(sp - memi(pd + pdsize*p
++ pdlocs)); newpc(memi(pd + pdsize*p+ pdbase)) end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure dotrap(n:byte); var i:size; begin if
+(uerrorproc=0) or intrap then begin if intrap then</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>writeln(&rsquo;Recursive trap, first trap number was
+&rsquo;, trapval:1); writeln(&rsquo;Error &rsquo;, n:1);
+writeln(&rsquo;With&rsquo;,ord(insr):4,&rsquo; arg
+&rsquo;,k:1); goto 9999 end; { Deposit all interpreter
+variables that need to be saved on the stack. This includes
+all scratch variables that can be in use at the moment and (
+not possible in this interpreter ) the internal address of
+the interpreter where the error occurred. This would make it
+possible to execute an RTT instruction totally transparent
+to the user program. It can, for example, occur within an
+ADD instruction that both operands are undefined and that
+the result overflows. Although this will generate 3 error
+traps it must be possible to ignore them all. }
+intrap:=true; trapval:=n; for i:=retsize div wsize downto 1
+do push(retarea[i]); push(retsize); { saved return area }
+pusha(mema(fileadr)); { saved current file name pointer }
+push(memw(lineadr)); { saved line number } push(n); { push
+error number } a:=argp(uerrorproc); uerrorproc:=0; { reset
+signal } call(a); { call the routine } intrap:=false; {
+Don&rsquo;t catch recursive traps anymore } goto 8888; {
+reenter main loop } end;</tt></p>
+</td>
+</table>
+
+<p><tt>procedure trap; { This routine is invoked for
+overflow, and other run time errors. For non-fatal errors,
+trap returns to the calling routine } begin if n&gt;=16 then
+dotrap(n) else if bit(n,ignmask)=0 then dotrap(n);
+end;</tt></p>
+
+<p><tt>procedure dortt; { The restoration of file address
+and line number is not essential. The restoration of the
+return save area is. } var i:size; n:word; begin newsp(lb);
+lb:=maxdata+1 ; { to circumvent ESTACK for the popa + pop }
+newpc(popa); newlb(popa); { So far a plain RET 0 } n:=pop;
+if (n&gt;=16) and (n&lt;64) then goto 9999 ; lino(pop);
+filna(popa); retsize:=pop; for i:=1 to retsize div wsize do
+retarea[i]:=pop ; end;</tt></p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ monitor calls }
+{---------------------------------------------------------------------------}</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure domon(entry:word); var index:
+1..63;</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>dummy: double;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>count,rwptr: adr;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>token: byte;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>i: integer; begin if (entry&lt;=0) or (entry&gt;63)
+then entry:=63 ; index:=entry; case index of 1: begin { exit
+} exitstatus:=pop; halted:=true end; 3: begin { read }
+dummy:=pop; { All input is from stdin }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>rwptr:=popa; count:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>i:=0 ;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>while (not eof(input)) and (i&lt;count) do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if eoln(input) then begin storeb(rwptr,10) ;
+count:=i end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else storeb(rwptr,ord(input^)) ;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>get(input); rwptr:=rwptr+1 ; i:=i+1 ;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>pusha(i); push(0) end; 4: begin { write }
+dummy:=pop; { All output is to stdout }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>rwptr:=popa; count:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:=1 to count do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin token:=memb(rwptr); rwptr:=rwptr+1 ;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if token=10 then writeln else
+write(chr(token))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end ;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>pusha(count);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>push(0) end; 54: begin { ioctl, faked }
+dummy:=popa;dummy:=popa;dummy:=pop;push(0) end ; 2, 5, 6, 7,
+8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+53, 55, 56, 57, 58, 59, 60, 61, 62: begin push(22); push(22)
+end; 63: { exists only for the trap } trap(EBADMON) end
+end;</tt></p>
+</td>
+</table>
+
+<p>16</p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Initialization and debugging }
+{---------------------------------------------------------------------------}</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure doident; { print line number and file name
+} var a:adr; i,c:integer; found:boolean; begin
+write(&rsquo;at line &rsquo;,memw(lineadr):1,&rsquo;
+&rsquo;); a:=mema(fileadr); if a&lt;&gt;0 then begin i:=20;
+found:=false; while (i&lt;&gt;0) and not found do begin
+c:=memb(a); a:=a+1; found:=true; i:=i-1; if (c&gt;=48) and
+(c&lt;=57) then</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>begin found:=false;
+write(chr(ord(&rsquo;0&rsquo;)+c-48)) end; if (c&gt;=65) and
+(c&lt;=90) then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin found:=false;
+write(chr(ord(&rsquo;A&rsquo;)+c-65)) end; if (c&gt;=97) and
+(c&lt;=122) then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin found:=false;
+write(chr(ord(&rsquo;a&rsquo;)+c-97)) end; end; end;
+writeln; end;</tt></p>
+</td>
+</table>
+
+<p><tt>procedure initialize; { start the ball rolling } {
+This is not part of the machine definition } var cset:set of
+char; f:ifset; iclass:insclass; insno:byte; nops:integer;
+opcode:byte; i,j,n:integer; wtemp:sword; count:integer;
+repc:adr; nexta,firsta:adr; elem:byte; amount,ofst:size;
+c:char;</tt></p>
+
+<p><tt>function readb(n:integer):double; var b:byte; begin
+read(prog,b); if n&gt;1 then readb:=readb(n-1)*256+b else
+readb:=b end;</tt></p>
+
+<p><tt>function readbyte:byte; begin readbyte:=readb(1)
+end;</tt></p>
+
+<p><tt>function readword:word; begin readword:=readb(wsize)
+end;</tt></p>
+
+<p><tt>function readadr:adr; begin readadr:=readb(asize)
+end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><tt>function ifind(ordinal:byte):mnem; var
+loopvar:mnem;</tt></p>
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>found:boolean; begin ifind:=NON; loopvar:=insr;
+found:=false; repeat</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>if ordinal=ord(loopvar) then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>begin found:=true; ifind:=loopvar end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>if loopvar&lt;&gt;ZRL then loopvar:=succ(loopvar)
+else loopvar:=NON; until found or (loopvar=insr) ;
+end;</tt></p>
+
+<p><tt>procedure readhdr; type hdrw=0..32767 ; { 16 bit
+header words } var hdr: hdrw;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>i: integer; begin for i:=0 to 7 do begin
+hdr:=readb(2);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>case i of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>0: if hdr&lt;&gt;3757 then { 07255 }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>begin writeln(&rsquo;Not an em load file&rsquo;);
+halt end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>2: if hdr&lt;&gt;0 then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>begin writeln(&rsquo;Unsolved references&rsquo;);
+halt end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>3: if hdr&lt;&gt;3 then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>begin writeln(&rsquo;Incorrect load file
+version&rsquo;); halt end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>4: if hdr&lt;&gt;wsize then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>begin writeln(&rsquo;Incorrect word size&rsquo;);
+halt end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>5: if hdr&lt;&gt;asize then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>begin writeln(&rsquo;Incorrect pointer size&rsquo;);
+halt end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>1,6,7:;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+</table>
+
+<p><tt>procedure noinit; begin writeln(&rsquo;Illegal
+initialization&rsquo;); halt end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><tt>procedure readint(a:adr;s:size); var i:size; begin {
+construct integer out of byte sequence } for i:=1 to s do {
+construct the value and initialize at a }</tt></p>
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>begin storeb(a,readbyte); a:=a+1 end end;</tt></p>
+</td>
+</table>
+
+<p><tt>procedure readuns(a:adr;s:size); begin { construct
+unsigned out of byte sequence } readint(a,s) { identical to
+readint } end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><tt>procedure readfloat(a:adr;s:size); var i:size;
+b:byte; begin { construct float out of string} if
+(s&lt;&gt;4) and (s&lt;&gt;8) then noinit; i:=0; repeat {
+eat the bytes, construct the value and intialize at a
+}</tt></p>
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>b:=readbyte; i:=i+1; until b=0 ; end;</tt></p>
+</td>
+</table>
+
+<p><tt>begin halted:=false; exitstatus:=undef;
+uerrorproc:=0; intrap:=false;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><tt>{ initialize tables } for i:=0 to maxcode do
+code[i]:=0; for i:=0 to maxdata do data[i]:=0; for
+iclass:=prim to tert do for i:=0 to 255 do with
+dispat[iclass][i] do</tt></p>
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin instr:=NON; iflag:=[zbit] end;</tt></p>
+
+<p><tt>{ read instruction table file. see appendix B } {
+The table read here is a simple transformation of the table
+on page xx } { - instruction names were transformed to
+numbers } { - the &rsquo;-&rsquo; flag was transformed to an
+&rsquo;i&rsquo; flag for &rsquo;w&rsquo; type instructions }
+{ - the &rsquo;S&rsquo; flag was added for instructions
+having signed operands } reset(tables); insr:=NON; repeat
+read(tables,insno) ; cset:=[]; f:=[]; insr:=ifind(insno); if
+insr=NON then begin writeln(&rsquo;Incorrect table&rsquo;);
+halt end; repeat read(tables,c) until c&lt;&gt;&rsquo;
+&rsquo; ; repeat cset:=cset+[c]; read(tables,c) until
+c=&rsquo; &rsquo; ; if &rsquo;m&rsquo; in cset then
+f:=f+[mini]; if &rsquo;s&rsquo; in cset then f:=f+[short];
+if &rsquo;-&rsquo; in cset then f:=f+[zbit]; if
+&rsquo;i&rsquo; in cset then f:=f+[ibit]; if &rsquo;S&rsquo;
+in cset then f:=f+[sbit]; if &rsquo;w&rsquo; in cset then
+f:=f+[wbit]; if (mini in f) or (short in f) then
+read(tables,nops) else nops:=1 ; readln(tables,opcode); if
+(&rsquo;4&rsquo; in cset) or (&rsquo;8&rsquo; in cset) then
+begin iclass:=tert end else if &rsquo;e&rsquo; in cset then
+begin iclass:=second end else iclass:=prim; for i:=0 to
+nops-1 do begin with dispat[iclass,opcode+i] do
+begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>iflag:=f; instr:=insr;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>if &rsquo;2&rsquo; in cset then ilength:=2</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>else if &rsquo;u&rsquo; in cset then
+ilength:=2</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>else if &rsquo;4&rsquo; in cset then
+ilength:=4</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>else if &rsquo;8&rsquo; in cset then
+ilength:=8</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>else if (mini in f) or (short in f) then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>if &rsquo;N&rsquo; in cset then wtemp:=-1-i else
+wtemp:=i ;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>if &rsquo;o&rsquo; in cset then wtemp:=wtemp+1
+;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>if short in f then wtemp:=wtemp*256 ;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>implicit:=wtemp</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>end end end until eof(tables);</tt></p>
+
+<p><tt>{ read in program text, data and procedure
+descriptors } reset(prog); readhdr; { verify first header }
+for i:=1 to 8 do header[i]:=readadr; { read second header }
+hp:=maxdata+1; sp:=maxdata+1; lino(0); { read program text }
+if header[NTEXT]+header[NPROC]*pdsize&gt;maxcode then begin
+writeln(&rsquo;Text size too large&rsquo;); halt end; if
+header[SZDATA]&gt;maxdata then begin writeln(&rsquo;Data
+size too large&rsquo;); halt end; for i:=0 to
+header[NTEXT]-1 do code[i]:=readbyte; { read data blocks }
+nexta:=0; for i:=1 to header[NDATA] do begin n:=readbyte; if
+n&lt;&gt;0 then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>elem:=readbyte; firsta:=nexta;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>case n of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>1: { uninitialized words }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>for j:=1 to elem do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin store(nexta,undef); nexta:=nexta+wsize
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>2: { initialized bytes }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>for j:=1 to elem do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin storeb(nexta,readbyte); nexta:=nexta+1
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>3: { initialized words }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>for j:=1 to elem do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin store(nexta,readword); nexta:=nexta+wsize
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>4,5: { instruction and data pointers }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>for j:=1 to elem do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin storea(nexta,readadr); nexta:=nexta+asize
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>6: { signed integers }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin readint(nexta,elem); nexta:=nexta+elem
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>7: { unsigned integers }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin readuns(nexta,elem); nexta:=nexta+elem
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>8: { floating point numbers }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin readfloat(nexta,elem); nexta:=nexta+elem
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>end else</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>repc:=readadr; amount:=nexta-firsta;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>for count:=1 to repc do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>for ofst:=0 to amount-1 do
+data[nexta+ofst]:=data[firsta+ofst];</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>nexta:=nexta+amount;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>end end; if header[SZDATA]&lt;&gt;nexta then
+writeln(&rsquo;Data initialization error&rsquo;); hp:=nexta;
+{ read descriptor table } pd:=header[NTEXT]; for i:=1 to
+header[NPROC]*pdsize do code[pd+i-1]:=readbyte; { call the
+entry point routine } ignmask:=0;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>{ catch all traps, higher numbered traps cannot be
+ignored} retsize:=0; lb:=maxdata; { illegal dynamic link }
+pc:=maxcode; { illegal return address } push(0); a:=sp; { No
+environment } push(0); b:=sp; { No args } pusha(a); { envp }
+pusha(b); { argv } push(0); { argc }
+call(argp(header[ENTRY])); end;</tt></p>
+</td>
+</table>
+
+<p>17</p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ MAIN LOOP OF THE INTERPRETER }
+{---------------------------------------------------------------------------}
+{ It should be noted that the interpreter (microprogram) for
+an EM machine can be written in two fundamentally different
+ways: (1) the instruction operands are fetched in the main
+loop, or (2) the in- struction operands are fetched after
+the 256 way branch, by the exe- cution routines themselves.
+In this interpreter, method (1) is used to simplify the
+description of execution routines. The dispatch table dispat
+is used to determine how the operand is encoded. There are 4
+possibilities:</tt></p>
+
+<p><tt>0. There is no operand 1. The operand and
+instruction are together in 1 byte (mini) 2. The operand is
+one byte long and follows the opcode byte(s) 3. The operand
+is two bytes long and follows the opcode byte(s) 4. The
+operand is four bytes long and follows the opcode
+byte(s)</tt></p>
+
+<p><tt>In this interpreter, the main loop determines the
+operand type, fetches it, and leaves it in the global
+variable k for the execution routines to use. Consequently,
+instructions such as LOL, which use three different formats,
+need only be described once in the body of the interpreter.
+However, for a production interpreter, or a hardware EM
+machine, it is probably better to use method (2), i.e. to
+let the execution routines themselves fetch their own
+operands. The reason for this is that each opcode uniquely
+determines the operand format, so no table lookup in the
+dispatch table is needed. The whole table is not needed.
+Method (2) therefore executes much faster. However, separate
+execution routines will be needed for LOL with a one byte
+offset, and LOL with a two byte offset. It is to avoid this
+additional clutter that method (1) is used here. In a
+produc- tion interpreter, it is envisioned that the main
+loop will fetch the next instruction byte, and use it as an
+index into a 256 word table to find the address of the
+interpreter routine to jump to. The routine jumped to will
+begin by fetching its operand, if any, without any table
+lookup, since it knows which format to expect. After doing
+the work, it returns to the main loop by jumping in-
+directly to a register that contains the address of the main
+loop. A slight variation on this idea is to have the
+register contain the address of the branch table, rather
+than the address of the main loop. Another issue is whether
+the execution routines for LOL 0, LOL 2, LOL 4, etc. should
+all be have distinct execution routines. Doing so provides
+for the maximum speed, since the operand is implicit in the
+routine itself. The disadvantage is that many nearly
+identical execution routines will then be needed. Another
+way of doing it is to keep the instruction byte fetched from
+memory (LOL 0, LOL 2, LOL 4, etc.) in some register, and
+have all the LOL mini format instruc- tions branch to a
+common routine. This routine can then determine the operand
+by subtracting the code for LOL 0 from the register, leaving
+the true operand in the register (as a word quantity of
+course). This method makes the interpreter smaller, but is a
+bit slower.</tt></p>
+
+<p>18</p>
+
+<p><tt>To make this important point a little clearer,
+consider how a production interpreter for the PDP-11 might
+appear. Let us assume the following opcodes have been
+assigned:</tt></p>
+
+<p><tt>31: LOL -2 (2 bytes, i.e. next word) 32: LOL -4 33:
+LOL -6 34: LOL b (format with a one byte offset) 35: LOL w
+(format with a one word, i.e. two byte offset)</tt></p>
+
+<p><tt>Further assume that each of the 5 opcodes will have
+its own execution routine, i.e. we are making a tradeoff in
+favor of fast execution and a slightly larger interpreter.
+Register r5 is the em program counter. Register r4 is the em
+LB register Register r3 is the em SP register (the stack
+grows toward low core) Register r2 contains the interpreter
+address of the main loop</tt></p>
+
+<p><tt>The main loop looks like this:</tt></p>
+
+<p><tt>movb (r5)+,r0 /fetch the opcode into r0 and
+increment r5 asl r0 /shift r0 left 1 bit. Now:
+-256&lt;=r0&lt;=+254 jmp *table(r0) /jump to execution
+routine</tt></p>
+
+<p><tt>Notice that no operand fetching has been done. The
+execution routines for the 5 sample instructions given above
+might be as follows:</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><tt>lol2: mov -2(r4),-(sp) /push local -2 onto
+stack</tt></p>
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>jmp (r2) /go back to main loop lol4: mov
+-4(r4),-(sp) /push local -4 onto stack</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>jmp (r2) /go back to main loop lol6: mov
+-6(r4),-(sp) /push local -6 onto stack</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>jmp (r2) /go back to main loop lolb: mov $177400,r0
+/prepare to fetch the 1 byte operand</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>bisb (r5)+,r0 /operand is now in r0</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>asl r0 /r0 is now offset from LB in bytes, not
+words</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>add r4,r0 /r0 is now address of the needed
+local</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>mov (r0),-(sp) /push the local onto the
+stack</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>jmp (r2) lolw: clr r0 /prepare to fetch the 2 byte
+operand</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>bisb (r5)+,r0 /fetch high order byte first
+!!!</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>swab r0 /insert high order byte in place</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>bisb (r5)+,r0 /insert low order byte in
+place</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>asl r0 /convert offset to bytes, from words</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>add r4,r0 /r0 is now address of needed
+local</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>mov (r0),-(sp) /stack the local</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="6%"></td>
+<td width="89%">
+
+<p><tt>jmp (r2) /done</tt></p>
+</td>
+</table>
+
+<p><tt>The important thing to notice is where and how the
+operand fetch occurred: lol2, lol4, and lol6, (the
+mini&rsquo;s) have implicit operands lolb knew it had to
+fetch one byte, and did so without any table lookup lolw
+knew it had to fetch a word, and did so, high order byte
+first }</tt></p>
+
+<p>19</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Routines for the individual instructions }
+{---------------------------------------------------------------------------}
+procedure loadops; var j:integer; begin case insr of { LOAD
+GROUP } LDC: pushd(argd(k)); LOC: pushsw(argc(k)); LOL:
+push(memw(locadr(k))); LOE: push(memw(argg(k))); LIL:
+push(memw(mema(locadr(k)))); LOF: push(memw(popa+argf(k)));
+LAL: pusha(locadr(k)); LAE: pusha(argg(k)); LXL: begin
+a:=lb; for j:=1 to argn(k) do a:=mema(a+savsize); pusha(a)
+end; LXA: begin a:=lb;</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>for j:=1 to argn(k) do a:= mema(a+savsize);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>pusha(a+savsize)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; LOI: pushx(argo(k),popa); LOS: begin
+k:=argw(k); if k&lt;&gt;wsize then trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>k:=pop; pushx(argo(k),popa)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; LDL: begin a:=locadr(k); push(memw(a+wsize));
+push(memw(a)) end; LDE: begin k:=argg(k);
+push(memw(k+wsize)); push(memw(k)) end; LDF: begin
+k:=argf(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>a:=popa; push(memw(a+k+wsize));
+push(memw(a+k))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; LPI: push(argp(k)) end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure storeops; begin case insr of { STORE GROUP
+} STL: store(locadr(k),pop); STE: store(argg(k),pop); SIL:
+store(mema(locadr(k)),pop); STF: begin a:=popa;
+store(a+argf(k),pop) end; STI: popx(argo(k),popa); STS:
+begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS);</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>k:=popa; popx(argo(k),popa)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; SDL: begin a:=locadr(k); store(a,pop);
+store(a+wsize,pop) end; SDE: begin k:=argg(k); store(k,pop);
+store(k+wsize,pop) end; SDF: begin k:=argf(k); a:=popa;
+store(a+k,pop); store(a+k+wsize,pop) end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure intarith; var i:integer; begin case insr
+of { SIGNED INTEGER ARITHMETIC } ADI: case szindex(argw(k))
+of</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>1: begin st:=popsw; ss:=popsw;
+push(fitsw(ss+st,EIOVFL)) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin dt:=popd; ds:=popd; pushd(doadi(ds,dt))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end ; SBI: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin st:=popsw; ss:= popsw;
+push(fitsw(ss-st,EIOVFL)) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin dt:=popd; ds:=popd; pushd(dosbi(ds,dt))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end ; MLI: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin st:=popsw; ss:= popsw;
+push(fitsw(ss*st,EIOVFL)) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin dt:=popd; ds:=popd; pushd(domli(ds,dt))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end ; DVI: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin st:= popsw; ss:= popsw;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if st=0 then trap(EIDIVZ) else pushsw(ss div
+st)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin dt:=popd; ds:=popd; pushd(dodvi(ds,dt))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; RMI: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin st:= popsw; ss:=popsw;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if st=0 then trap(EIDIVZ) else pushsw(ss - (ss div
+st)*st)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin dt:=popd; ds:=popd; pushd(dormi(ds,dt))
+end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; NGI: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin st:=popsw; pushsw(-st) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin ds:=popd; pushd(dongi(ds)) end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; SLI: begin t:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin ss:=popsw;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:= 1 to t do sleft(ss); pushsw(ss)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; SRI: begin t:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin ss:=popsw;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:= 1 to t do sright(ss); pushsw(ss)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin ds:=popd;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:= 1 to t do sdright(ss); pushd(ss)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure unsarith; var i:integer; begin case insr
+of { UNSIGNED INTEGER ARITHMETIC } ADU: case
+szindex(argw(k)) of</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>1: begin t:=pop; s:= pop; push(chopw(s+t))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end ; SBU: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin t:=pop; s:= pop; push(chopw(s-t))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end ; MLU: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin t:=pop; s:= pop; push(chopw(s*t))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end ; DVU: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin t:= pop; s:= pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if t=0 then trap(EIDIVZ) else push(s div t)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; RMU: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin t:= pop; s:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if t=0 then trap(EIDIVZ) else push(s - (s div
+t)*t)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; SLU: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin t:=pop; s:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:= 1 to t do suleft(s); push(s)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; SRU: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin t:=pop; s:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:= 1 to t do suright(s); push(s)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure fltarith; begin case insr of { FLOATING
+POINT ARITHMETIC } ADF: begin argwf(k); rt:=popr; rs:=popr;
+pushr(doadf(rs,rt)) end; SBF: begin argwf(k); rt:=popr;
+rs:=popr; pushr(dosbf(rs,rt)) end; MLF: begin argwf(k);
+rt:=popr; rs:=popr; pushr(domlf(rs,rt)) end; DVF: begin
+argwf(k); rt:=popr; rs:=popr; pushr(dodvf(rs,rt)) end; NGF:
+begin argwf(k); rt:=popr; pushr(dongf(rt)) end; FIF: begin
+argwf(k); rt:=popr; rs:=popr;</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>dofif(rt,rs,x,y); pushr(y); pushr(x)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; FEF: begin argwf(k); rt:=popr; dofef(rt,x,ss);
+pushr(x); pushsw(ss) end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure ptrarith; begin case insr of { POINTER
+ARITHMETIC } ADP: pusha(popa+argf(k)); ADS: case
+szindex(argw(k)) of</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>1: begin st:=popsw; pusha(popa+st) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin dt:=popd; pusha(popa+dt) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; SBS: begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>a:=popa; b:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: push(fitsw(b-a,EIOVFL));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: pushd(b-a)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+</table>
+
+<p><tt>procedure incops; var j:integer; begin case insr of
+{ INCREMENT/DECREMENT/ZERO } INC:
+push(fitsw(popsw+1,EIOVFL)); INL: begin a:=locadr(k);
+store(a,fitsw(signwd(memw(a))+1,EIOVFL)) end; INE: begin
+a:=argg(k); store(a,fitsw(signwd(memw(a))+1,EIOVFL)) end;
+DEC: push(fitsw(popsw-1,EIOVFL)); DEL: begin a:=locadr(k);
+store(a,fitsw(signwd(memw(a))-1,EIOVFL)) end; DEE: begin
+a:=argg(k); store(a,fitsw(signwd(memw(a))-1,EIOVFL)) end;
+ZRL: store(locadr(k),0); ZRE: store(argg(k),0); ZER: for
+j:=1 to argw(k) div wsize do push(0); ZRF: pushr(0); end
+end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure convops; begin case insr of { CONVERT
+GROUP } CII: begin s:=pop; t:=pop;</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>if t&lt;wsize then begin push(sextend(pop,t));
+t:=wsize end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(argw(t)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: if szindex(argw(s))=2 then pushd(popsw);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: if szindex(argw(s))=1 then
+push(fitsw(popd,ECONV))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CIU: case szindex(argw(pop)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: if szindex(argw(pop))=2 then push(unsign(popd mod
+negoff));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CIF: begin argwf(pop);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(argw(pop)) of 1:pushr(popsw);
+2:pushr(popd) end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CUI: case szindex(argw(pop)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: case szindex(argw(pop)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin s:=pop; if s&gt;maxsint then trap(ECONV);
+push(s) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: case szindex(argw(pop)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: pushd(pop);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CUU: case szindex(argw(pop)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: if szindex(argw(pop))=2 then
+trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CUF: begin argwf(pop);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if szindex(argw(pop))=1 then pushr(pop) else
+trap(EILLINS)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CFI: begin sz:=argw(pop); argwf(pop);
+rt:=popr;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(sz) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: push(fitsw(trunc(rt),ECONV));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: pushd(fitd(trunc(rt)));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CFU: begin sz:=argw(pop); argwf(pop);
+rt:=popr;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(sz) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: push( chopw(trunc(abs(rt)-0.5)) );</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CFF: begin argwf(pop); argwf(pop) end end
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure logops; var i,j:integer; begin case insr
+of { LOGICAL GROUP } XAND:</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for j:= 1 to k div wsize do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin a:=sp+k; t:=pop; store(a,bf(andf,memw(a),t))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; IOR:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for j:= 1 to k div wsize do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin a:=sp+k; t:=pop; store(a,bf(iorf,memw(a),t))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; XOR:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for j:= 1 to k div wsize do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin a:=sp+k; t:=pop; store(a,bf(xorf,memw(a),t))
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; COM:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for j:= 1 to k div wsize do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>store(sp+k-wsize*j, bf(xorf,memw(sp+k-wsize*j),
+negoff-1))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; ROL: begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>t:=pop; s:=pop; for i:= 1 to t do rleft(s);
+push(s)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; ROR: begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>t:=pop; s:=pop; for i:= 1 to t do rright(s);
+push(s)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure setops; var i,j:integer; begin case insr
+of { SET GROUP } INN:</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>t:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>i:= t mod 8; t:= t div 8;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if t&gt;=k then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin trap(ESET); s:=0 end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin s:=memb(sp+t) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>newsp(sp+k); push(bit(i,s));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; XSET:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>t:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>i:= t mod 8; t:= t div 8;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for j:= 1 to k div wsize do push(0);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if t&gt;=k then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>trap(ESET)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin s:=1; for j:= 1 to i do rleft(s);
+storeb(sp+t,s) end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure arrops; begin case insr of { ARRAY GROUP }
+LAR:</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS); a:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>pushx(argo(memw(a+2*k)),arraycalc(a))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; SAR:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS); a:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>popx(argo(memw(a+2*k)),arraycalc(a))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; AAR:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS); a:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>push(arraycalc(a))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure cmpops; begin case insr of { COMPARE GROUP
+} CMI: case szindex(argw(k)) of</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>1: begin st:=popsw; ss:=popsw;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if ss&lt;st then pushsw(-1) else if ss=st then
+push(0) else push(1)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: begin dt:=popd; ds:=popd;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if ds&lt;dt then pushsw(-1) else if ds=dt then
+push(0) else push(1)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CMU: case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: begin t:=pop; s:=pop;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if s&lt;t then pushsw(-1) else if s=t then push(0)
+else push(1)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CMP: begin a:=popa; b:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if b&lt;a then pushsw(-1) else if b=a then push(0)
+else push(1)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CMF: begin argwf(k); rt:=popr;
+rs:=popr;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if rs&lt;rt then pushsw(-1) else if rs=rt then
+push(0) else push(1)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CMS: begin k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>t:= 0; j:= 0;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>while (j &lt; k) and (t=0) do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin if memw(sp+j) &lt;&gt; memw(sp+k+j) then
+t:=1;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>j:=j+wsize</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>newsp(sp+wsize*k); push(t);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+</table>
+
+<p><tt>TLT: if popsw &lt; 0 then push(1) else push(0); TLE:
+if popsw &lt;= 0 then push(1) else push(0); TEQ: if pop = 0
+then push(1) else push(0); TNE: if pop &lt;&gt; 0 then
+push(1) else push(0); TGE: if popsw &gt;= 0 then push(1)
+else push(0); TGT: if popsw &gt; 0 then push(1) else
+push(0); end end;</tt></p>
+
+<p><tt>procedure branchops; begin case insr of { BRANCH
+GROUP } BRA: newpc(pc+k);</tt></p>
+
+<p><tt>BLT: begin st:=popsw; if popsw &lt; st then
+newpc(pc+k) end; BLE: begin st:=popsw; if popsw &lt;= st
+then newpc(pc+k) end; BEQ: begin t :=pop ; if pop = t then
+newpc(pc+k) end; BNE: begin t :=pop ; if pop &lt;&gt; t then
+newpc(pc+k) end; BGE: begin st:=popsw; if popsw &gt;= st
+then newpc(pc+k) end; BGT: begin st:=popsw; if popsw &gt; st
+then newpc(pc+k) end;</tt></p>
+
+<p><tt>ZLT: if popsw &lt; 0 then newpc(pc+k); ZLE: if popsw
+&lt;= 0 then newpc(pc+k); ZEQ: if pop = 0 then newpc(pc+k);
+ZNE: if pop &lt;&gt; 0 then newpc(pc+k); ZGE: if popsw &gt;=
+0 then newpc(pc+k); ZGT: if popsw &gt; 0 then newpc(pc+k)
+end end;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure callops; var j:integer; begin case insr of
+{ PROCEDURE CALL GROUP } CAL: call(argp(k)); CAI: begin
+call(argp(popa)) end; RET: begin k:=argz(k); if k div
+wsize&gt;maxret then trap(EILLINS);</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>for j:= 1 to k div wsize do retarea[j]:=pop;
+retsize:=k;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>newsp(lb); lb:=maxdata+1; { To circumvent stack
+overflow error }</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>newpc(popa);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if pc=maxcode then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>halted:=true;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if retsize=wsize then
+exitstatus:=retarea[1]</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else exitstatus:=undef</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>newlb(popa);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; LFR: begin k:=args(k); if k&lt;&gt;retsize then
+trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for j:=k div wsize downto 1 do
+push(retarea[j]);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>procedure miscops; var i,j:integer; begin case insr
+of { MISCELLANEOUS GROUP } ASP,ASS:</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>begin if insr=ASS then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS); k:=popsw end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>k:=argf(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if k&lt;0</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>then for j:= 1 to -k div wsize do
+push(undef)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>else newsp(sp+k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; BLM,BLS:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin if insr=BLS then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS); k:=pop end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>k:=argz(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>b:=popa; a:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for j := 1 to k div wsize do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+
+<p><tt>store(b-wsize+wsize*j,memw(a-wsize+wsize*j))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CSA: begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>a:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>st:= popsw - signwd(memw(a+asize));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if (st&gt;=0) and (st&lt;=memw(a+wsize+asize))
+then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>b:=mema(a+2*wsize+asize+asize*st) else
+b:=mema(a);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if b=0 then trap(ECASE) else newpc(b)</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; CSB: begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS); a:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>t:=pop; i:=1; found:=false;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>while (i&lt;=memw(a+asize)) and not found
+do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if t=memw(a+(asize+wsize)*i) then found:=true else
+i:=i+1;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if found then b:=memw(a+(asize+wsize)*i+wsize) else
+b:=memw(a);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if b=0 then trap(ECASE) else newpc(b);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; DCH: begin pusha(mema(popa+dynd)) end;
+DUP,DUS:</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin if insr=DUS then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=argw(k); if k&lt;&gt;wsize then
+trap(EILLINS); k:=pop end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>k:=args(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:=1 to k div wsize do
+push(memw(sp+k-wsize));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; EXG: begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>k:=argw(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:=1 to k div wsize do
+push(memw(sp+k-wsize));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:=0 to k div wsize - 1 do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>store(sp+k+i*wsize,memw(sp+k+k+i*wsize));</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:=1 to k div wsize do</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin t:=pop ; store(sp+k+k-wsize,t) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; FIL: filna(argg(k)); GTO: begin
+k:=argg(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>newlb(mema(k+2*asize)); newsp(mema(k+asize));
+newpc(mema(k))</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; LIM: push(ignmask); LIN: lino(argn(k)); LNI:
+lino(memw(0)+1); LOR: begin i:=argr(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case i of 0:pusha(lb); 1:pusha(sp); 2:pusha(hp)
+end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; LPB: pusha(popa+statd); MON: domon(pop); NOP:
+writeln(&rsquo;NOP at line &rsquo;,memw(0):5) ; RCK: begin
+a:=popa;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case szindex(argw(k)) of</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>1: if (signwd(memw(sp))&lt;signwd(memw(a)))
+or</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>(signwd(memw(sp))&gt;signwd(memw(a+wsize))) then
+trap(ERANGE);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>2: if (memd(sp)&lt;memd(a)) or</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>(memd(sp)&gt;memd(a+2*wsize)) then
+trap(ERANGE);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; RTT: dortt; SIG: begin a:=popa;
+pusha(uerrorproc); uerrorproc:=a end; SIM: ignmask:=pop;
+STR: begin i:=argr(k);</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>case i of 0: newlb(popa); 1: newsp(popa); 2:
+newhp(popa) end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end; TRP: trap(pop) end end;</tt></p>
+</td>
+</table>
+
+<p>20</p>
+
+
+<p><tt>{---------------------------------------------------------------------------}
+{ Main Loop }
+{---------------------------------------------------------------------------}</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><tt>begin initialize; 8888: repeat opcode := nextpc; {
+fetch the first byte of the instruction } if opcode=escape1
+then iclass:=second else if opcode=escape2 then iclass:=tert
+else iclass:=prim; if iclass&lt;&gt;prim then opcode :=
+nextpc; with dispat[iclass][opcode] do begin
+insr:=instr;</tt></p>
+</td>
+<td width="89%">
+
+<p><tt>if not (zbit in iflag) then</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if ibit in iflag then k:=pop else</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if mini in iflag then k:=implicit else</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if short in iflag then k:=implicit+nextpc
+else</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>begin k:=nextpc;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if (sbit in iflag) and (k&gt;=128) then
+k:=k-256;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>for i:=2 to ilength do k:=256*k + nextpc</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>if wbit in iflag then k:=k*wsize;</tt></p>
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="89%">
+
+<p><tt>end end; case insr of</tt></p>
+</td>
+</table>
+
+<p><tt>NON: trap(EILLINS);</tt></p>
+
+<p><tt>{ LOAD GROUP }
+LDC,LOC,LOL,LOE,LIL,LOF,LAL,LAE,LXL,LXA,LOI,LOS,LDL,LDE,LDF,LPI:
+loadops;</tt></p>
+
+<p><tt>{ STORE GROUP } STL,STE,SIL,STF,STI,STS,SDL,SDE,SDF:
+storeops;</tt></p>
+
+<p><tt>{ SIGNED INTEGER ARITHMETIC }
+ADI,SBI,MLI,DVI,RMI,NGI,SLI,SRI: intarith;</tt></p>
+
+<p><tt>{ UNSIGNED INTEGER ARITHMETIC }
+ADU,SBU,MLU,DVU,RMU,SLU,SRU: unsarith;</tt></p>
+
+<p><tt>{ FLOATING POINT ARITHMETIC }
+ADF,SBF,MLF,DVF,NGF,FIF,FEF: fltarith;</tt></p>
+
+<p><tt>{ POINTER ARITHMETIC } ADP,ADS,SBS:
+ptrarith;</tt></p>
+
+<p><tt>{ INCREMENT/DECREMENT/ZERO }
+INC,INL,INE,DEC,DEL,DEE,ZRL,ZRE,ZER,ZRF: incops;</tt></p>
+
+<p><tt>{ CONVERT GROUP }
+CII,CIU,CIF,CUI,CUU,CUF,CFI,CFU,CFF: convops;</tt></p>
+
+<p><tt>{ LOGICAL GROUP } XAND,IOR,XOR,COM,ROL,ROR:
+logops;</tt></p>
+
+<p><tt>{ SET GROUP } INN,XSET: setops;</tt></p>
+
+<p><tt>{ ARRAY GROUP } LAR,SAR,AAR: arrops;</tt></p>
+
+<p><tt>{ COMPARE GROUP } CMI,CMU,CMP,CMF,CMS,
+TLT,TLE,TEQ,TNE,TGE,TGT: cmpops;</tt></p>
+
+<p><tt>{ BRANCH GROUP } BRA, BLT,BLE,BEQ,BNE,BGE,BGT,
+ZLT,ZLE,ZEQ,ZNE,ZGE,ZGT: branchops;</tt></p>
+
+<p><tt>{ PROCEDURE CALL GROUP } CAL,CAI,RET,LFR:
+callops;</tt></p>
+
+<p><tt>{ MISCELLANEOUS GROUP }
+ASP,ASS,BLM,BLS,CSA,CSB,DCH,DUP,DUS,EXG,FIL,GTO,LIM,
+LIN,LNI,LOR,LPB,MON,NOP,RCK,RTT,SIG,SIM,STR,TRP:
+miscops;</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><tt>end; { end of case statement } if not ( (insr=RET)
+or (insr=ASP) or (insr=BRA) or (insr=GTO) ) then</tt></p>
+<td width="7%"></td>
+<td width="2%"></td>
+<td width="89%">
+
+<p><tt>retsize:=0 ; until halted; 9999: writeln(&rsquo;halt
+with exit status: &rsquo;,exitstatus:1); doident;
+end.</tt></p>
+</td>
+</table>
+
+<p>21</p>
+
+<p><b>B. EM CODE TABLES</b></p>
+
+<p>The following table is used by the assembler for EM
+machine language. It specifies the opcodes used for each
+instruction and how arguments are mapped to machine language
+arguments. The table is presented in three columns, each
+line in each column contains three or four fields. Each line
+describes a range of interpreter opcodes by specifying for
+which instruction the range is used, the type of the opcodes
+(mini, shortie, etc..) and range for the instruction
+argument.</p>
+
+<p>The first field on each line gives the EM instruction
+mnemonic, the second field gives some flags. If the opcodes
+are minis or shorties the third field specifies how many
+minis/shorties are used. The last field gives the number of
+the (first) interpreter opcode.</p>
+
+<p>Flags :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Opcode type, only one of the following may be
+specified.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="16%">
+
+<p>opcode without argument</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>m</p>
+</td>
+<td width="8%"></td>
+<td width="16%">
+
+<p>mini</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>s</p>
+</td>
+<td width="8%"></td>
+<td width="16%">
+
+<p>shortie</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>2</p>
+</td>
+<td width="8%"></td>
+<td width="16%">
+
+<p>opcode with 2-byte signed argument</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>4</p>
+</td>
+<td width="8%"></td>
+<td width="16%">
+
+<p>opcode with 4-byte signed argument</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>8</p>
+</td>
+<td width="8%"></td>
+<td width="16%">
+
+<p>opcode with 8-byte signed argument</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>u</p>
+</td>
+<td width="8%"></td>
+<td width="16%">
+
+<p>opcode with 2-byte unsigned argument</p>
+</td>
+<td width="63%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Secondary (escaped) opcodes.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>e</p>
+</td>
+<td width="8%"></td>
+<td width="18%">
+
+<p>The opcode thus marked is in the secondary opcode group
+instead of the primary</p>
+</td>
+<td width="61%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>restrictions on arguments</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>N</p>
+</td>
+<td width="8%"></td>
+<td width="18%">
+
+<p>Negative arguments only</p>
+</td>
+<td width="61%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>P</p>
+</td>
+<td width="8%"></td>
+<td width="18%">
+
+<p>Positive and zero arguments only</p>
+</td>
+<td width="61%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>mapping of arguments</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>w</p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p>argument must be divisible by the wordsize and is
+divided by the wordsize before use as opcode argument.</p>
+</td>
+<td width="57%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>o</p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p>argument ( possibly after division ) must be &gt;= 1 and
+is decremented before use as opcode argument</p>
+</td>
+<td width="57%">
+</td>
+</table>
+
+<p>If the opcode type is 2,4 or 8 the resulting argument is
+used as opcode argument (least significant byte first). If
+the opcode type is mini, the argument is added to the first
+opcode &minus; if in range &minus; . If the argument is
+negative, the absolute value minus one is used in the
+algorithm above.<br>
+For shorties with positive arguments the first opcode is
+used for arguments in the range 0..255, the second for the
+range 256..511, etc.. For shorties with negative arguments
+the first opcode is used for arguments in the range
+&minus;1..&minus;256, the second for the range
+&minus;257..&minus;512, etc.. The byte following the opcode
+contains the least significant byte of the argument. First
+some examples of these specifications.</p>
+
+<p>aar mwPo 1 34</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Indicates that opcode 34 is used as a mini for Positive
+instruction arguments only. The w and o indicate division
+and decrementing of the instruction argument. Because the
+resulting argument must be zero ( only opcode 34 may be
+used), this mini can only be used for instruction argument
+2. Conclusion: opcode 34 is for &quot;AAR 2&quot;.</p>
+</td>
+</table>
+
+<p>adp sP 1 41</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Opcode 41 is used as shortie for ADP with arguments in
+the range 0..255.</p>
+</td>
+</table>
+
+<p>bra sN 2 60</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Opcode 60 is used as shortie for BRA with arguments
+&minus;1..&minus;256, 61 is used for arguments
+&minus;257..&minus;512.</p>
+</td>
+</table>
+
+<p>zer e&minus; 145</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Escaped opcode 145 is used for ZER.</p>
+</td>
+</table>
+
+<p>The interpreter opcode table:</p>
+
+<p align=center><img src="grohtml-974416.png"></p>
+
+<p>The table above results in the following dispatch
+tables. Dispatch tables are used by interpreters to jump to
+the routines implementing the EM instructions, indexed by
+the next opcode. Each line of the dispatch tables gives the
+routine names of eight consecutive opcodes, preceded by the
+first opcode number on that line. Routine names consist of
+an EM mnemonic followed by a suffix. The suffices show the
+encoding used for each opcode.</p>
+
+<p>The following suffices exist:</p>
+
+<p>&lt;num&gt; is a possibly negative integer.</p>
+
+<p>The dispatch table for the 256 primary opcodes:</p>
+
+<p align=center><img src="grohtml-974418.png"></p>
+
+<p>The list of secondary opcodes (escape1):</p>
+
+<p align=center><img src="grohtml-974419.png"></p>
+
+<p>Finally, the list of opcodes with four byte arguments
+(escape2).</p>
+
+<p align=center><img src="grohtml-974420.png"></p>
+
+<p>22</p>
+
+<p><b>C. AN EXAMPLE PROGRAM</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>1</p>
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>program example(output);<br>
+2</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>{This program just demonstrates typical EM code.}<br>
+3</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>type rec = record r1: integer; r2:real; r3: boolean
+end;<br>
+4</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>var mi: integer; mx:real; r:rec;</p>
+</td>
+</table>
+
+<p>5</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>6</p>
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>function sum(a,b:integer):integer;<br>
+7</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>begin<br>
+8</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>sum := a + b<br>
+9</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="6%"></td>
+<td width="92%">
+
+<p>end;</p>
+</td>
+</table>
+
+<p>10</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>11</p>
+</td>
+<td width="92%">
+
+<p>procedure test(var r: rec);</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>12</p>
+</td>
+<td width="92%">
+
+<p>label 1;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>13</p>
+</td>
+<td width="92%">
+
+<p>var i,j: integer;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>14</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>x,y: real;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>15</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>b: boolean;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>16</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>c: char;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>17</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>a: array[1..100] of integer;</p>
+</td>
+</table>
+
+<p>18</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>19</p>
+</td>
+<td width="92%">
+
+<p>begin</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>20</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>j := 1;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>21</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>i := 3 * j + 6;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>22</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>x := 4.8;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>23</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>y := x/0.5;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>24</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>b := true;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>25</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>c := &rsquo;z&rsquo;;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>26</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>for i:= 1 to 100 do a[i] := i * i;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>27</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>r.r1 := j+27;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>28</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>r.r3 := b;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>29</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>r.r2 := x+y;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>30</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>i := sum(r.r1, a[j]);</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>31</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>while i &gt; 0 do begin j := j + r.r1; i := i - 1
+end;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>32</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>with r do begin r3 := b; r2 := x+y; r1 := 0 end;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>33</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>goto 1;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>34</p>
+</td>
+<td width="92%">
+
+<p>1:</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>writeln(j, i:6, x:9:3, b)</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>35</p>
+</td>
+<td width="92%">
+
+<p>end; {test}</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>36</p>
+</td>
+<td width="92%">
+
+<p>begin {main program}</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>37</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>mx := 15.96;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>38</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>mi := 99;</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>39</p>
+</td>
+<td width="92%">
+</td>
+<tr valign="top" align="left">
+<td width="8%"></td>
+<td width="92%">
+
+<p>test(r)</p>
+</td>
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>40</p>
+</td>
+<td width="92%">
+
+<p>end.</p>
+</td>
+</table>
+
+<p>23</p>
+
+<p>The EM code as produced by the Pascal-VU compiler is
+given below. Comments have been added manually. Note that
+this code has already been optimized.</p>
+<!-- TABS -->
+
+<p>mes 2,2,2 ; wordsize 2, pointersize 2<br>
+.1</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>rom &rsquo;t.p\000&rsquo;</p>
+</td>
+<td width="52%">
+
+<p>; the name of the source file</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>hol 552,&minus;32768,0</p>
+</td>
+<td width="52%">
+
+<p>; externals and buf occupy 552 bytes</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>exp $sum</p>
+</td>
+<td width="52%">
+
+<p>; sum can be called from other modules</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>pro $sum,2</p>
+</td>
+<td width="52%">
+
+<p>; procedure sum; 2 bytes local storage</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>lin 8</p>
+</td>
+<td width="52%">
+
+<p>; code from source line 8</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>ldl 0</p>
+</td>
+<td width="52%">
+
+<p>; load two locals ( a and b )</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>adi 2</p>
+</td>
+<td width="52%">
+
+<p>; add them</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>ret 2</p>
+</td>
+<td width="52%">
+
+<p>; return the result</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>end 2</p>
+</td>
+<td width="52%">
+
+<p>; end of procedure ( still two bytes local storage )</p>
+</td>
+</table>
+
+<p>.2</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>rom 1,99,2</p>
+</td>
+<td width="52%">
+
+<p>; descriptor of array a[]</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>exp $test</p>
+</td>
+<td width="52%">
+
+<p>; the compiler exports all level 0 procedures</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>pro $test,226</p>
+</td>
+<td width="52%">
+
+<p>; procedure test, 226 bytes local storage</p>
+</td>
+</table>
+
+<p>.3</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>rom 4.8F8</p>
+</td>
+<td width="52%">
+
+<p>; assemble Floating point 4.8 (8 bytes) in</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>.4</p>
+</td>
+<td width="46%"></td>
+<td width="52%">
+
+<p>; global storage</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>rom 0.5F8</p>
+</td>
+<td width="52%">
+
+<p>; same for 0.5</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>mes 3,&minus;226,2,2</p>
+</td>
+<td width="52%">
+
+<p>; compiler temporary not referenced by address</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>mes 3,&minus;24,2,0</p>
+</td>
+<td width="52%">
+
+<p>; the same is true for i, j, b and c in test</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>mes 3,&minus;22,2,0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>mes 3,&minus;4,2,0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>mes 3,&minus;2,2,0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>mes 3,&minus;20,8,0</p>
+</td>
+<td width="52%">
+
+<p>; and for x and y</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>mes 3,&minus;12,8,0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lin 20</p>
+</td>
+<td width="52%">
+
+<p>; maintain source line number</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loc 1</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>stl &minus;4</p>
+</td>
+<td width="52%">
+
+<p>; j := 1</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 21 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>lol &minus;4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loc 3</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>mli 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loc 6</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>adi 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>stl &minus;2</p>
+</td>
+<td width="52%">
+
+<p>; i := 3 * j + 6</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 22 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>lae .3</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loi 8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>lal &minus;12</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>sti 8</p>
+</td>
+<td width="52%">
+
+<p>; x := 4.8</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 23 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>lal &minus;12</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loi 8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>lae .4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loi 8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>dvf 8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>lal &minus;20</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>sti 8</p>
+</td>
+<td width="52%">
+
+<p>; y := x / 0.5</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 24 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loc 1</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>stl &minus;22</p>
+</td>
+<td width="52%">
+
+<p>; b := true</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 25 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loc 122</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>stl &minus;24</p>
+</td>
+<td width="52%">
+
+<p>; c := &rsquo;z&rsquo;</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 26 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="2%"></td>
+<td width="46%">
+
+<p>loc 1</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="2%">
+</td>
+<td width="46%">
+
+<p>stl &minus;2</p>
+</td>
+<td width="52%">
+
+<p>; for i:= 1</p>
+</td>
+</table>
+
+<p>2</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>dup 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>mli 2</p>
+</td>
+<td width="52%">
+
+<p>; i*i</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lal &minus;224</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae .2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>sar 2</p>
+</td>
+<td width="52%">
+
+<p>; a[i] :=</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 100</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>beq *3</p>
+</td>
+<td width="52%">
+
+<p>; to 100 do</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>inl &minus;2</p>
+</td>
+<td width="52%">
+
+<p>; increment i and loop</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>bra *2</p>
+</td>
+<td width="52%">
+</td>
+</table>
+
+<p>3</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lin 27</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 27</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>adi 2</p>
+</td>
+<td width="52%">
+
+<p>; j + 27</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>sil 0</p>
+</td>
+<td width="52%">
+
+<p>; r.r1 :=</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 28 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;22</p>
+</td>
+<td width="52%">
+
+<p>; b</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol 0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>stf 10</p>
+</td>
+<td width="52%">
+
+<p>; r.r3 :=</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 29 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lal &minus;20</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loi 16</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>adf 8</p>
+</td>
+<td width="52%">
+
+<p>; x + y</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol 0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>adp 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>sti 8</p>
+</td>
+<td width="52%">
+
+<p>; r.r2 :=</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 30 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lal &minus;224</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae .2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lar 2</p>
+</td>
+<td width="52%">
+
+<p>; a[j]</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lil 0</p>
+</td>
+<td width="52%">
+
+<p>; r.r1</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $sum</p>
+</td>
+<td width="52%">
+
+<p>; call now</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 4</p>
+</td>
+<td width="52%">
+
+<p>; remove parameters from stack</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lfr 2</p>
+</td>
+<td width="52%">
+
+<p>; get function result</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>stl &minus;2</p>
+</td>
+<td width="52%">
+
+<p>; i :=</p>
+</td>
+</table>
+
+<p>4</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lin 31</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>zle *5</p>
+</td>
+<td width="52%">
+
+<p>; while i &gt; 0 do</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lil 0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>adi 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>stl &minus;4</p>
+</td>
+<td width="52%">
+
+<p>; j := j + r.r1</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>del &minus;2</p>
+</td>
+<td width="52%">
+
+<p>; i := i - 1</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>bra *4</p>
+</td>
+<td width="52%">
+
+<p>; loop</p>
+</td>
+</table>
+
+<p>5</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lin 32</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol 0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>stl &minus;226</p>
+</td>
+<td width="52%">
+
+<p>; make copy of address of r</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;22</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;226</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>stf 10</p>
+</td>
+<td width="52%">
+
+<p>; r3 := b</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lal &minus;20</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loi 16</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>adf 8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;226</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>adp 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>sti 8</p>
+</td>
+<td width="52%">
+
+<p>; r2 := x + y</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>sil &minus;226</p>
+</td>
+<td width="52%">
+
+<p>; r1 := 0</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lin 34</p>
+</td>
+<td width="52%">
+
+<p>; note the absence of the unnecessary jump</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 22</p>
+</td>
+<td width="52%">
+
+<p>; address of output structure</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $_wri</p>
+</td>
+<td width="52%">
+
+<p>; write integer with default width</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 4</p>
+</td>
+<td width="52%">
+
+<p>; pop parameters</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 22</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 6</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $_wsi</p>
+</td>
+<td width="52%">
+
+<p>; write integer width 6</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 6</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 22</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lal &minus;12</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loi 8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 9</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 3</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $_wrf</p>
+</td>
+<td width="52%">
+
+<p>; write fixed format real, width 9, precision 3</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 14</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 22</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lol &minus;22</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $_wrb</p>
+</td>
+<td width="52%">
+
+<p>; write boolean, default width</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 22</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $_wln</p>
+</td>
+<td width="52%">
+
+<p>; writeln</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>ret 0</p>
+</td>
+<td width="52%">
+
+<p>; return, no result</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>end 226</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>exp $_main</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>pro $_main,0</p>
+</td>
+<td width="52%">
+
+<p>; main program</p>
+</td>
+</table>
+
+<p>.6</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="46%">
+
+<p>con 2,&minus;1,22</p>
+</td>
+<td width="52%">
+
+<p>; description of external files</p>
+</td>
+</table>
+
+<p>.5</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>rom 15.96F8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>fil .1</p>
+</td>
+<td width="52%">
+
+<p>; maintain source file name</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae .6</p>
+</td>
+<td width="52%">
+
+<p>; description of external files</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 0</p>
+</td>
+<td width="52%">
+
+<p>; base of hol area to relocate buffer addresses</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $_ini</p>
+</td>
+<td width="52%">
+
+<p>; initialize files, etc...</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 4</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lin 37</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae .5</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loi 8</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>sti 8</p>
+</td>
+<td width="52%">
+
+<p>; mx := 15.96</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 38 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 99</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>ste 0</p>
+</td>
+<td width="52%">
+
+<p>; mi := 99</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lni</p>
+</td>
+<td width="52%">
+
+<p>; lin 39 prior to optimization</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>lae 10</p>
+</td>
+<td width="52%">
+
+<p>; address of r</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $test</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>loc 0</p>
+</td>
+<td width="52%">
+
+<p>; normal exit</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>cal $_hlt</p>
+</td>
+<td width="52%">
+
+<p>; cleanup and finish</p>
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>asp 2</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>end 0</p>
+</td>
+<td width="52%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="0%"></td>
+<td width="46%">
+
+<p>mes 5</p>
+</td>
+<td width="52%">
+
+<p>; reals were used</p>
+</td>
+</table>
+
+<p>The compact code corresponding to the above program is
+listed below. Read it horizontally, line by line, not column
+by column. Each number represents a byte of compact code,
+printed in decimal. The first two bytes form the magic
+word.</p>
+
+<p><tt>173 0 159 122 122 122 255 242 1 161 250 124 116 46
+112 0 255 156 245 40 2 245 0 128 120 155 249 123 115 117 109
+160 249 123 115 117 109 122 67 128 63 120 3 122 88 122 152
+122 242 2 161 121 219 122 255 155 249 124 116 101 115 116
+160 249 124 116 101 115 116 245 226 0 242 3 161 253 128 123
+52 46 56 255 242 4 161 253 128 123 48 46 53 255 159 123 245
+30 255 122 122 255 159 123 96 122 120 255 159 123 98 122 120
+255 159 123 116 122 120 255 159 123 118 122 120 255 159 123
+100 128 120 255 159 123 108 128 120 255 67 140 69 121 113
+116 68 73 116 69 123 81 122 69 126 3 122 113 118 68 57 242 3
+72 128 58 108 112 128 68 58 108 72 128 57 242 4 72 128 44
+128 58 100 112 128 68 69 121 113 98 68 69 245 122 0 113 96
+68 69 121 113 118 182 73 118 42 122 81 122 58 245 32 255 73
+118 57 242 2 94 122 73 118 69 220 10 123 54 118 18 122 183
+67 147 73 116 69 147 3 122 104 120 68 73 98 73 120 111 130
+68 58 100 72 136 2 128 73 120 4 122 112 128 68 58 245 32 255
+73 116 57 242 2 59 122 65 120 20 249 123 115 117 109 8 124
+64 122 113 118 184 67 151 73 118 128 125 73 116 65 120 3 122
+113 116 41 118 18 124 185 67 152 73 120 113 245 30 255 73 98
+73 245 30 255 111 130 58 100 72 136 2 128 73 245 30 255 4
+122 112 128 69 120 104 245 30 255 67 154 57 142 73 116 20
+249 124 95 119 114 105 8 124 57 142 73 118 69 126 20 249 124
+95 119 115 105 8 126 57 142 58 108 72 128 69 129 69 123 20
+249 124 95 119 114 102 8 134 57 142 73 98 20 249 124 95 119
+114 98 8 124 57 142 20 249 124 95 119 108 110 8 122 88 120
+152 245 226 0 155 249 125 95 109 97 105 110 160 249 125 95
+109 97 105 110 120 242 6 151 122 119 142 255 242 5 161 253
+128 125 49 53 46 57 54 255 50 242 1 57 242 6 57 120 20 249
+124 95 105 110 105 8 124 67 157 57 242 5 72 128 57 122 112
+128 68 69 219 110 120 68 57 130 20 249 124 116 101 115 116 8
+122 69 120 20 249 124 95 104 108 116 8 122 152 120 159 124
+160 255 159 125 255</tt></p>
+
+<p>1. INTRODUCTION ............. 1</p>
+
+<p>2. MEMORY ....... 2</p>
+
+<p>3. INSTRUCTION ADDRESS SPACE ........................
+3</p>
+
+<p>4. DATA ADDRESS SPACE ................. 4<br>
+__4.1 Global data area .................. 4<br>
+__4.2 Local data area ................. 4<br>
+__4.3 Heap data area ................ 4</p>
+
+<p>5. MAPPING OF EM DATA MEMORY ONTO TARGET MACHINE MEMORY
+............................................. 5</p>
+
+<p>6. TYPE REPRESENTATIONS .................... 6<br>
+__6.1 Unsigned integers .................... 6<br>
+__6.2 Signed Integers .................. 6<br>
+__6.3 Floating point values ....................... 6<br>
+__6.4 Pointers ............ 6<br>
+__6.5 Bit sets ........... 6</p>
+
+<p>7. DESCRIPTORS ............ 7<br>
+__7.1 Range check descriptors .........................
+7<br>
+__7.2 Array descriptors .................... 7<br>
+__7.3 Non-local goto descriptors
+............................ 7<br>
+__7.4 Case descriptors ................... 7</p>
+
+<p>8. ENVIRONMENT INTERACTIONS ........................
+8<br>
+__8.1 Program starting and stopping
+.............................. 8<br>
+__8.2 Input/Output and other monitor calls
+.................................... 8</p>
+
+<p>9. TRAPS AND INTERRUPTS ................... 9</p>
+
+<p>10. EM MACHINE LANGUAGE .................... 10<br>
+__10.1 Instruction encoding ......................... 10<br>
+__10.2 Procedure descriptors ..........................
+10<br>
+__10.3 Load format ................ 10</p>
+
+<p>11. EM ASSEMBLY LANGUAGE ..................... 11<br>
+__11.1 ASCII assembly language ...........................
+11<br>
+____11.1.1 Instruction arguments
+.............................. 11<br>
+____11.1.2 Pseudoinstruction arguments
+.................................... 11<br>
+____11.1.3 Notation .................. 11<br>
+____11.1.4 Pseudoinstructions ............................
+11<br>
+______11.1.4.1 Storage declaration
+................................ 11<br>
+______11.1.4.2 Partitioning ..........................
+11<br>
+______11.1.4.3 Visibility ........................ 11<br>
+______11.1.4.4 Miscellaneous ...........................
+11<br>
+__11.2 The Compact Assembly Language
+................................ 11<br>
+__11.3 Assembly language instruction list
+..................................... 11</p>
+
+<p>A. EM INTERPRETER ............... 12</p>
+
+<p>B. EM CODE TABLES .............. 21</p>
+
+<p>C. AN EXAMPLE PROGRAM .................. 22</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/em.pdf b/src/olddocs/em.pdf
new file mode 100644 (file)
index 0000000..45d0e78
Binary files /dev/null and b/src/olddocs/em.pdf differ
diff --git a/src/olddocs/grohtml-100191.png b/src/olddocs/grohtml-100191.png
new file mode 100644 (file)
index 0000000..ad2f031
Binary files /dev/null and b/src/olddocs/grohtml-100191.png differ
diff --git a/src/olddocs/grohtml-100601.png b/src/olddocs/grohtml-100601.png
new file mode 100644 (file)
index 0000000..38e4683
Binary files /dev/null and b/src/olddocs/grohtml-100601.png differ
diff --git a/src/olddocs/grohtml-100602.png b/src/olddocs/grohtml-100602.png
new file mode 100644 (file)
index 0000000..ea24351
Binary files /dev/null and b/src/olddocs/grohtml-100602.png differ
diff --git a/src/olddocs/grohtml-101091.png b/src/olddocs/grohtml-101091.png
new file mode 100644 (file)
index 0000000..8890306
Binary files /dev/null and b/src/olddocs/grohtml-101091.png differ
diff --git a/src/olddocs/grohtml-101092.png b/src/olddocs/grohtml-101092.png
new file mode 100644 (file)
index 0000000..1974778
Binary files /dev/null and b/src/olddocs/grohtml-101092.png differ
diff --git a/src/olddocs/grohtml-101093.png b/src/olddocs/grohtml-101093.png
new file mode 100644 (file)
index 0000000..819befc
Binary files /dev/null and b/src/olddocs/grohtml-101093.png differ
diff --git a/src/olddocs/grohtml-101094.png b/src/olddocs/grohtml-101094.png
new file mode 100644 (file)
index 0000000..af163c1
Binary files /dev/null and b/src/olddocs/grohtml-101094.png differ
diff --git a/src/olddocs/grohtml-101481.png b/src/olddocs/grohtml-101481.png
new file mode 100644 (file)
index 0000000..5e571b5
Binary files /dev/null and b/src/olddocs/grohtml-101481.png differ
diff --git a/src/olddocs/grohtml-101482.png b/src/olddocs/grohtml-101482.png
new file mode 100644 (file)
index 0000000..57ec951
Binary files /dev/null and b/src/olddocs/grohtml-101482.png differ
diff --git a/src/olddocs/grohtml-101483.png b/src/olddocs/grohtml-101483.png
new file mode 100644 (file)
index 0000000..9efcf47
Binary files /dev/null and b/src/olddocs/grohtml-101483.png differ
diff --git a/src/olddocs/grohtml-101484.png b/src/olddocs/grohtml-101484.png
new file mode 100644 (file)
index 0000000..1043710
Binary files /dev/null and b/src/olddocs/grohtml-101484.png differ
diff --git a/src/olddocs/grohtml-101485.png b/src/olddocs/grohtml-101485.png
new file mode 100644 (file)
index 0000000..b896524
Binary files /dev/null and b/src/olddocs/grohtml-101485.png differ
diff --git a/src/olddocs/grohtml-101486.png b/src/olddocs/grohtml-101486.png
new file mode 100644 (file)
index 0000000..9c5510b
Binary files /dev/null and b/src/olddocs/grohtml-101486.png differ
diff --git a/src/olddocs/grohtml-101487.png b/src/olddocs/grohtml-101487.png
new file mode 100644 (file)
index 0000000..0d356ff
Binary files /dev/null and b/src/olddocs/grohtml-101487.png differ
diff --git a/src/olddocs/grohtml-101488.png b/src/olddocs/grohtml-101488.png
new file mode 100644 (file)
index 0000000..8d62461
Binary files /dev/null and b/src/olddocs/grohtml-101488.png differ
diff --git a/src/olddocs/grohtml-101489.png b/src/olddocs/grohtml-101489.png
new file mode 100644 (file)
index 0000000..85e4abe
Binary files /dev/null and b/src/olddocs/grohtml-101489.png differ
diff --git a/src/olddocs/grohtml-102111.png b/src/olddocs/grohtml-102111.png
new file mode 100644 (file)
index 0000000..a88cfe8
Binary files /dev/null and b/src/olddocs/grohtml-102111.png differ
diff --git a/src/olddocs/grohtml-102411.png b/src/olddocs/grohtml-102411.png
new file mode 100644 (file)
index 0000000..b3c889f
Binary files /dev/null and b/src/olddocs/grohtml-102411.png differ
diff --git a/src/olddocs/grohtml-102412.png b/src/olddocs/grohtml-102412.png
new file mode 100644 (file)
index 0000000..de9fb31
Binary files /dev/null and b/src/olddocs/grohtml-102412.png differ
diff --git a/src/olddocs/grohtml-102413.png b/src/olddocs/grohtml-102413.png
new file mode 100644 (file)
index 0000000..29f4afc
Binary files /dev/null and b/src/olddocs/grohtml-102413.png differ
diff --git a/src/olddocs/grohtml-102721.png b/src/olddocs/grohtml-102721.png
new file mode 100644 (file)
index 0000000..47c7da9
Binary files /dev/null and b/src/olddocs/grohtml-102721.png differ
diff --git a/src/olddocs/grohtml-1027210.png b/src/olddocs/grohtml-1027210.png
new file mode 100644 (file)
index 0000000..3228123
Binary files /dev/null and b/src/olddocs/grohtml-1027210.png differ
diff --git a/src/olddocs/grohtml-1027211.png b/src/olddocs/grohtml-1027211.png
new file mode 100644 (file)
index 0000000..efee400
Binary files /dev/null and b/src/olddocs/grohtml-1027211.png differ
diff --git a/src/olddocs/grohtml-1027212.png b/src/olddocs/grohtml-1027212.png
new file mode 100644 (file)
index 0000000..6c694f6
Binary files /dev/null and b/src/olddocs/grohtml-1027212.png differ
diff --git a/src/olddocs/grohtml-1027213.png b/src/olddocs/grohtml-1027213.png
new file mode 100644 (file)
index 0000000..f357ee8
Binary files /dev/null and b/src/olddocs/grohtml-1027213.png differ
diff --git a/src/olddocs/grohtml-1027214.png b/src/olddocs/grohtml-1027214.png
new file mode 100644 (file)
index 0000000..a7a0693
Binary files /dev/null and b/src/olddocs/grohtml-1027214.png differ
diff --git a/src/olddocs/grohtml-1027215.png b/src/olddocs/grohtml-1027215.png
new file mode 100644 (file)
index 0000000..4b43183
Binary files /dev/null and b/src/olddocs/grohtml-1027215.png differ
diff --git a/src/olddocs/grohtml-1027216.png b/src/olddocs/grohtml-1027216.png
new file mode 100644 (file)
index 0000000..30e8772
Binary files /dev/null and b/src/olddocs/grohtml-1027216.png differ
diff --git a/src/olddocs/grohtml-1027217.png b/src/olddocs/grohtml-1027217.png
new file mode 100644 (file)
index 0000000..4c65d68
Binary files /dev/null and b/src/olddocs/grohtml-1027217.png differ
diff --git a/src/olddocs/grohtml-1027218.png b/src/olddocs/grohtml-1027218.png
new file mode 100644 (file)
index 0000000..8e518eb
Binary files /dev/null and b/src/olddocs/grohtml-1027218.png differ
diff --git a/src/olddocs/grohtml-1027219.png b/src/olddocs/grohtml-1027219.png
new file mode 100644 (file)
index 0000000..5f00257
Binary files /dev/null and b/src/olddocs/grohtml-1027219.png differ
diff --git a/src/olddocs/grohtml-102722.png b/src/olddocs/grohtml-102722.png
new file mode 100644 (file)
index 0000000..18f0e21
Binary files /dev/null and b/src/olddocs/grohtml-102722.png differ
diff --git a/src/olddocs/grohtml-1027220.png b/src/olddocs/grohtml-1027220.png
new file mode 100644 (file)
index 0000000..7bf86f3
Binary files /dev/null and b/src/olddocs/grohtml-1027220.png differ
diff --git a/src/olddocs/grohtml-1027221.png b/src/olddocs/grohtml-1027221.png
new file mode 100644 (file)
index 0000000..998a0b5
Binary files /dev/null and b/src/olddocs/grohtml-1027221.png differ
diff --git a/src/olddocs/grohtml-1027222.png b/src/olddocs/grohtml-1027222.png
new file mode 100644 (file)
index 0000000..bf57847
Binary files /dev/null and b/src/olddocs/grohtml-1027222.png differ
diff --git a/src/olddocs/grohtml-1027223.png b/src/olddocs/grohtml-1027223.png
new file mode 100644 (file)
index 0000000..a63c789
Binary files /dev/null and b/src/olddocs/grohtml-1027223.png differ
diff --git a/src/olddocs/grohtml-1027224.png b/src/olddocs/grohtml-1027224.png
new file mode 100644 (file)
index 0000000..d27a857
Binary files /dev/null and b/src/olddocs/grohtml-1027224.png differ
diff --git a/src/olddocs/grohtml-1027225.png b/src/olddocs/grohtml-1027225.png
new file mode 100644 (file)
index 0000000..d28a241
Binary files /dev/null and b/src/olddocs/grohtml-1027225.png differ
diff --git a/src/olddocs/grohtml-1027226.png b/src/olddocs/grohtml-1027226.png
new file mode 100644 (file)
index 0000000..f2643a7
Binary files /dev/null and b/src/olddocs/grohtml-1027226.png differ
diff --git a/src/olddocs/grohtml-1027227.png b/src/olddocs/grohtml-1027227.png
new file mode 100644 (file)
index 0000000..fcf2400
Binary files /dev/null and b/src/olddocs/grohtml-1027227.png differ
diff --git a/src/olddocs/grohtml-1027228.png b/src/olddocs/grohtml-1027228.png
new file mode 100644 (file)
index 0000000..18ad40c
Binary files /dev/null and b/src/olddocs/grohtml-1027228.png differ
diff --git a/src/olddocs/grohtml-1027229.png b/src/olddocs/grohtml-1027229.png
new file mode 100644 (file)
index 0000000..149bab4
Binary files /dev/null and b/src/olddocs/grohtml-1027229.png differ
diff --git a/src/olddocs/grohtml-102723.png b/src/olddocs/grohtml-102723.png
new file mode 100644 (file)
index 0000000..e33f7ca
Binary files /dev/null and b/src/olddocs/grohtml-102723.png differ
diff --git a/src/olddocs/grohtml-1027230.png b/src/olddocs/grohtml-1027230.png
new file mode 100644 (file)
index 0000000..b505ccf
Binary files /dev/null and b/src/olddocs/grohtml-1027230.png differ
diff --git a/src/olddocs/grohtml-1027231.png b/src/olddocs/grohtml-1027231.png
new file mode 100644 (file)
index 0000000..353396a
Binary files /dev/null and b/src/olddocs/grohtml-1027231.png differ
diff --git a/src/olddocs/grohtml-1027232.png b/src/olddocs/grohtml-1027232.png
new file mode 100644 (file)
index 0000000..7511176
Binary files /dev/null and b/src/olddocs/grohtml-1027232.png differ
diff --git a/src/olddocs/grohtml-1027233.png b/src/olddocs/grohtml-1027233.png
new file mode 100644 (file)
index 0000000..62f10d9
Binary files /dev/null and b/src/olddocs/grohtml-1027233.png differ
diff --git a/src/olddocs/grohtml-1027234.png b/src/olddocs/grohtml-1027234.png
new file mode 100644 (file)
index 0000000..d6011a7
Binary files /dev/null and b/src/olddocs/grohtml-1027234.png differ
diff --git a/src/olddocs/grohtml-1027235.png b/src/olddocs/grohtml-1027235.png
new file mode 100644 (file)
index 0000000..3fd8338
Binary files /dev/null and b/src/olddocs/grohtml-1027235.png differ
diff --git a/src/olddocs/grohtml-1027236.png b/src/olddocs/grohtml-1027236.png
new file mode 100644 (file)
index 0000000..00e53e4
Binary files /dev/null and b/src/olddocs/grohtml-1027236.png differ
diff --git a/src/olddocs/grohtml-1027237.png b/src/olddocs/grohtml-1027237.png
new file mode 100644 (file)
index 0000000..2cceea2
Binary files /dev/null and b/src/olddocs/grohtml-1027237.png differ
diff --git a/src/olddocs/grohtml-1027238.png b/src/olddocs/grohtml-1027238.png
new file mode 100644 (file)
index 0000000..586d48a
Binary files /dev/null and b/src/olddocs/grohtml-1027238.png differ
diff --git a/src/olddocs/grohtml-1027239.png b/src/olddocs/grohtml-1027239.png
new file mode 100644 (file)
index 0000000..4287bbd
Binary files /dev/null and b/src/olddocs/grohtml-1027239.png differ
diff --git a/src/olddocs/grohtml-102724.png b/src/olddocs/grohtml-102724.png
new file mode 100644 (file)
index 0000000..af20645
Binary files /dev/null and b/src/olddocs/grohtml-102724.png differ
diff --git a/src/olddocs/grohtml-102725.png b/src/olddocs/grohtml-102725.png
new file mode 100644 (file)
index 0000000..43c856c
Binary files /dev/null and b/src/olddocs/grohtml-102725.png differ
diff --git a/src/olddocs/grohtml-102726.png b/src/olddocs/grohtml-102726.png
new file mode 100644 (file)
index 0000000..31ae765
Binary files /dev/null and b/src/olddocs/grohtml-102726.png differ
diff --git a/src/olddocs/grohtml-102727.png b/src/olddocs/grohtml-102727.png
new file mode 100644 (file)
index 0000000..d6b437b
Binary files /dev/null and b/src/olddocs/grohtml-102727.png differ
diff --git a/src/olddocs/grohtml-102728.png b/src/olddocs/grohtml-102728.png
new file mode 100644 (file)
index 0000000..9c0caee
Binary files /dev/null and b/src/olddocs/grohtml-102728.png differ
diff --git a/src/olddocs/grohtml-102729.png b/src/olddocs/grohtml-102729.png
new file mode 100644 (file)
index 0000000..fca6b38
Binary files /dev/null and b/src/olddocs/grohtml-102729.png differ
diff --git a/src/olddocs/grohtml-105631.png b/src/olddocs/grohtml-105631.png
new file mode 100644 (file)
index 0000000..829c2b4
Binary files /dev/null and b/src/olddocs/grohtml-105631.png differ
diff --git a/src/olddocs/grohtml-105632.png b/src/olddocs/grohtml-105632.png
new file mode 100644 (file)
index 0000000..791f7a4
Binary files /dev/null and b/src/olddocs/grohtml-105632.png differ
diff --git a/src/olddocs/grohtml-105633.png b/src/olddocs/grohtml-105633.png
new file mode 100644 (file)
index 0000000..1015348
Binary files /dev/null and b/src/olddocs/grohtml-105633.png differ
diff --git a/src/olddocs/grohtml-105634.png b/src/olddocs/grohtml-105634.png
new file mode 100644 (file)
index 0000000..0b9604d
Binary files /dev/null and b/src/olddocs/grohtml-105634.png differ
diff --git a/src/olddocs/grohtml-106061.png b/src/olddocs/grohtml-106061.png
new file mode 100644 (file)
index 0000000..c1484b4
Binary files /dev/null and b/src/olddocs/grohtml-106061.png differ
diff --git a/src/olddocs/grohtml-106062.png b/src/olddocs/grohtml-106062.png
new file mode 100644 (file)
index 0000000..08803d6
Binary files /dev/null and b/src/olddocs/grohtml-106062.png differ
diff --git a/src/olddocs/grohtml-106063.png b/src/olddocs/grohtml-106063.png
new file mode 100644 (file)
index 0000000..e137fa4
Binary files /dev/null and b/src/olddocs/grohtml-106063.png differ
diff --git a/src/olddocs/grohtml-106064.png b/src/olddocs/grohtml-106064.png
new file mode 100644 (file)
index 0000000..a6c0da7
Binary files /dev/null and b/src/olddocs/grohtml-106064.png differ
diff --git a/src/olddocs/grohtml-106561.png b/src/olddocs/grohtml-106561.png
new file mode 100644 (file)
index 0000000..df12c85
Binary files /dev/null and b/src/olddocs/grohtml-106561.png differ
diff --git a/src/olddocs/grohtml-1065610.png b/src/olddocs/grohtml-1065610.png
new file mode 100644 (file)
index 0000000..f35948c
Binary files /dev/null and b/src/olddocs/grohtml-1065610.png differ
diff --git a/src/olddocs/grohtml-1065611.png b/src/olddocs/grohtml-1065611.png
new file mode 100644 (file)
index 0000000..99dcee8
Binary files /dev/null and b/src/olddocs/grohtml-1065611.png differ
diff --git a/src/olddocs/grohtml-1065612.png b/src/olddocs/grohtml-1065612.png
new file mode 100644 (file)
index 0000000..1f7773f
Binary files /dev/null and b/src/olddocs/grohtml-1065612.png differ
diff --git a/src/olddocs/grohtml-1065613.png b/src/olddocs/grohtml-1065613.png
new file mode 100644 (file)
index 0000000..45bdc5a
Binary files /dev/null and b/src/olddocs/grohtml-1065613.png differ
diff --git a/src/olddocs/grohtml-1065614.png b/src/olddocs/grohtml-1065614.png
new file mode 100644 (file)
index 0000000..b0901b8
Binary files /dev/null and b/src/olddocs/grohtml-1065614.png differ
diff --git a/src/olddocs/grohtml-106562.png b/src/olddocs/grohtml-106562.png
new file mode 100644 (file)
index 0000000..27f984f
Binary files /dev/null and b/src/olddocs/grohtml-106562.png differ
diff --git a/src/olddocs/grohtml-106563.png b/src/olddocs/grohtml-106563.png
new file mode 100644 (file)
index 0000000..d429787
Binary files /dev/null and b/src/olddocs/grohtml-106563.png differ
diff --git a/src/olddocs/grohtml-106565.png b/src/olddocs/grohtml-106565.png
new file mode 100644 (file)
index 0000000..ef2e545
Binary files /dev/null and b/src/olddocs/grohtml-106565.png differ
diff --git a/src/olddocs/grohtml-106566.png b/src/olddocs/grohtml-106566.png
new file mode 100644 (file)
index 0000000..b5e976e
Binary files /dev/null and b/src/olddocs/grohtml-106566.png differ
diff --git a/src/olddocs/grohtml-106567.png b/src/olddocs/grohtml-106567.png
new file mode 100644 (file)
index 0000000..72b7516
Binary files /dev/null and b/src/olddocs/grohtml-106567.png differ
diff --git a/src/olddocs/grohtml-106568.png b/src/olddocs/grohtml-106568.png
new file mode 100644 (file)
index 0000000..4682a8a
Binary files /dev/null and b/src/olddocs/grohtml-106568.png differ
diff --git a/src/olddocs/grohtml-106569.png b/src/olddocs/grohtml-106569.png
new file mode 100644 (file)
index 0000000..e4ccdbe
Binary files /dev/null and b/src/olddocs/grohtml-106569.png differ
diff --git a/src/olddocs/grohtml-107771.png b/src/olddocs/grohtml-107771.png
new file mode 100644 (file)
index 0000000..6b17ec9
Binary files /dev/null and b/src/olddocs/grohtml-107771.png differ
diff --git a/src/olddocs/grohtml-107772.png b/src/olddocs/grohtml-107772.png
new file mode 100644 (file)
index 0000000..d30d541
Binary files /dev/null and b/src/olddocs/grohtml-107772.png differ
diff --git a/src/olddocs/grohtml-107773.png b/src/olddocs/grohtml-107773.png
new file mode 100644 (file)
index 0000000..723648f
Binary files /dev/null and b/src/olddocs/grohtml-107773.png differ
diff --git a/src/olddocs/grohtml-96851.png b/src/olddocs/grohtml-96851.png
new file mode 100644 (file)
index 0000000..09e6997
Binary files /dev/null and b/src/olddocs/grohtml-96851.png differ
diff --git a/src/olddocs/grohtml-96852.png b/src/olddocs/grohtml-96852.png
new file mode 100644 (file)
index 0000000..ef01349
Binary files /dev/null and b/src/olddocs/grohtml-96852.png differ
diff --git a/src/olddocs/grohtml-96853.png b/src/olddocs/grohtml-96853.png
new file mode 100644 (file)
index 0000000..ceebd2b
Binary files /dev/null and b/src/olddocs/grohtml-96853.png differ
diff --git a/src/olddocs/grohtml-96854.png b/src/olddocs/grohtml-96854.png
new file mode 100644 (file)
index 0000000..c53a6c6
Binary files /dev/null and b/src/olddocs/grohtml-96854.png differ
diff --git a/src/olddocs/grohtml-96855.png b/src/olddocs/grohtml-96855.png
new file mode 100644 (file)
index 0000000..1e8bffd
Binary files /dev/null and b/src/olddocs/grohtml-96855.png differ
diff --git a/src/olddocs/grohtml-96856.png b/src/olddocs/grohtml-96856.png
new file mode 100644 (file)
index 0000000..ca04a79
Binary files /dev/null and b/src/olddocs/grohtml-96856.png differ
diff --git a/src/olddocs/grohtml-96857.png b/src/olddocs/grohtml-96857.png
new file mode 100644 (file)
index 0000000..5cbe89a
Binary files /dev/null and b/src/olddocs/grohtml-96857.png differ
diff --git a/src/olddocs/grohtml-97441.png b/src/olddocs/grohtml-97441.png
new file mode 100644 (file)
index 0000000..4348fd4
Binary files /dev/null and b/src/olddocs/grohtml-97441.png differ
diff --git a/src/olddocs/grohtml-974410.png b/src/olddocs/grohtml-974410.png
new file mode 100644 (file)
index 0000000..ee45994
Binary files /dev/null and b/src/olddocs/grohtml-974410.png differ
diff --git a/src/olddocs/grohtml-974411.png b/src/olddocs/grohtml-974411.png
new file mode 100644 (file)
index 0000000..47d8c91
Binary files /dev/null and b/src/olddocs/grohtml-974411.png differ
diff --git a/src/olddocs/grohtml-974412.png b/src/olddocs/grohtml-974412.png
new file mode 100644 (file)
index 0000000..67f9773
Binary files /dev/null and b/src/olddocs/grohtml-974412.png differ
diff --git a/src/olddocs/grohtml-974413.png b/src/olddocs/grohtml-974413.png
new file mode 100644 (file)
index 0000000..a4efff5
Binary files /dev/null and b/src/olddocs/grohtml-974413.png differ
diff --git a/src/olddocs/grohtml-974414.png b/src/olddocs/grohtml-974414.png
new file mode 100644 (file)
index 0000000..2a7f742
Binary files /dev/null and b/src/olddocs/grohtml-974414.png differ
diff --git a/src/olddocs/grohtml-974415.png b/src/olddocs/grohtml-974415.png
new file mode 100644 (file)
index 0000000..0b8bfe4
Binary files /dev/null and b/src/olddocs/grohtml-974415.png differ
diff --git a/src/olddocs/grohtml-974416.png b/src/olddocs/grohtml-974416.png
new file mode 100644 (file)
index 0000000..520c1da
Binary files /dev/null and b/src/olddocs/grohtml-974416.png differ
diff --git a/src/olddocs/grohtml-974418.png b/src/olddocs/grohtml-974418.png
new file mode 100644 (file)
index 0000000..2659ec8
Binary files /dev/null and b/src/olddocs/grohtml-974418.png differ
diff --git a/src/olddocs/grohtml-974419.png b/src/olddocs/grohtml-974419.png
new file mode 100644 (file)
index 0000000..3abe23d
Binary files /dev/null and b/src/olddocs/grohtml-974419.png differ
diff --git a/src/olddocs/grohtml-97442.png b/src/olddocs/grohtml-97442.png
new file mode 100644 (file)
index 0000000..70e02f6
Binary files /dev/null and b/src/olddocs/grohtml-97442.png differ
diff --git a/src/olddocs/grohtml-974420.png b/src/olddocs/grohtml-974420.png
new file mode 100644 (file)
index 0000000..523b39e
Binary files /dev/null and b/src/olddocs/grohtml-974420.png differ
diff --git a/src/olddocs/grohtml-97443.png b/src/olddocs/grohtml-97443.png
new file mode 100644 (file)
index 0000000..157dcee
Binary files /dev/null and b/src/olddocs/grohtml-97443.png differ
diff --git a/src/olddocs/grohtml-97444.png b/src/olddocs/grohtml-97444.png
new file mode 100644 (file)
index 0000000..7c71b25
Binary files /dev/null and b/src/olddocs/grohtml-97444.png differ
diff --git a/src/olddocs/grohtml-97445.png b/src/olddocs/grohtml-97445.png
new file mode 100644 (file)
index 0000000..ce6791a
Binary files /dev/null and b/src/olddocs/grohtml-97445.png differ
diff --git a/src/olddocs/grohtml-97446.png b/src/olddocs/grohtml-97446.png
new file mode 100644 (file)
index 0000000..345f51d
Binary files /dev/null and b/src/olddocs/grohtml-97446.png differ
diff --git a/src/olddocs/grohtml-97447.png b/src/olddocs/grohtml-97447.png
new file mode 100644 (file)
index 0000000..0445942
Binary files /dev/null and b/src/olddocs/grohtml-97447.png differ
diff --git a/src/olddocs/grohtml-97448.png b/src/olddocs/grohtml-97448.png
new file mode 100644 (file)
index 0000000..cd98a0d
Binary files /dev/null and b/src/olddocs/grohtml-97448.png differ
diff --git a/src/olddocs/grohtml-97449.png b/src/olddocs/grohtml-97449.png
new file mode 100644 (file)
index 0000000..bf6457e
Binary files /dev/null and b/src/olddocs/grohtml-97449.png differ
diff --git a/src/olddocs/grohtml-99071.png b/src/olddocs/grohtml-99071.png
new file mode 100644 (file)
index 0000000..5f26193
Binary files /dev/null and b/src/olddocs/grohtml-99071.png differ
diff --git a/src/olddocs/grohtml-99261.png b/src/olddocs/grohtml-99261.png
new file mode 100644 (file)
index 0000000..f1c853f
Binary files /dev/null and b/src/olddocs/grohtml-99261.png differ
diff --git a/src/olddocs/grohtml-99451.png b/src/olddocs/grohtml-99451.png
new file mode 100644 (file)
index 0000000..bce93cc
Binary files /dev/null and b/src/olddocs/grohtml-99451.png differ
diff --git a/src/olddocs/grohtml-99452.png b/src/olddocs/grohtml-99452.png
new file mode 100644 (file)
index 0000000..6ecce63
Binary files /dev/null and b/src/olddocs/grohtml-99452.png differ
diff --git a/src/olddocs/grohtml-99453.png b/src/olddocs/grohtml-99453.png
new file mode 100644 (file)
index 0000000..3f28bf6
Binary files /dev/null and b/src/olddocs/grohtml-99453.png differ
diff --git a/src/olddocs/grohtml-99454.png b/src/olddocs/grohtml-99454.png
new file mode 100644 (file)
index 0000000..b9ff1dd
Binary files /dev/null and b/src/olddocs/grohtml-99454.png differ
diff --git a/src/olddocs/grohtml-99455.png b/src/olddocs/grohtml-99455.png
new file mode 100644 (file)
index 0000000..32144ff
Binary files /dev/null and b/src/olddocs/grohtml-99455.png differ
diff --git a/src/olddocs/grohtml-99456.png b/src/olddocs/grohtml-99456.png
new file mode 100644 (file)
index 0000000..3da0187
Binary files /dev/null and b/src/olddocs/grohtml-99456.png differ
diff --git a/src/olddocs/grohtml-99457.png b/src/olddocs/grohtml-99457.png
new file mode 100644 (file)
index 0000000..b426a55
Binary files /dev/null and b/src/olddocs/grohtml-99457.png differ
diff --git a/src/olddocs/i80.html b/src/olddocs/i80.html
new file mode 100644 (file)
index 0000000..3a01053
--- /dev/null
@@ -0,0 +1,1391 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:17 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>Back end table for the Intel 8080 micro-processor</title>
+</head>
+<body>
+
+<h1 align=center>Back end table for the Intel 8080 micro-processor</h1>
+<a href="#1. THE 8080 MICRO PROCESSOR">1. THE 8080 MICRO PROCESSOR</a><br>
+<a href="#1.1. Registers">1.1. Registers</a><br>
+<a href="#1.2. Flip-flops">1.2. Flip-flops</a><br>
+<a href="#1.3. Addressing modes">1.3. Addressing modes</a><br>
+<a href="#1.3.1. Implied addressing">1.3.1. Implied addressing</a><br>
+<a href="#1.3.2. Register addressing">1.3.2. Register addressing</a><br>
+<a href="#1.3.3. Register indirect addressing">1.3.3. Register indirect addressing</a><br>
+<a href="#1.3.4. Immediate addressing">1.3.4. Immediate addressing</a><br>
+<a href="#1.3.5. Direct addressing">1.3.5. Direct addressing</a><br>
+<a href="#2. THE 8080 BACK END TABLE">2. THE 8080 BACK END TABLE</a><br>
+<a href="#2.1. Constant definitions">2.1. Constant definitions</a><br>
+<a href="#2.2. Registers and their properties">2.2. Registers and their properties</a><br>
+<a href="#2.3. Tokens">2.3. Tokens</a><br>
+<a href="#2.4. Sets">2.4. Sets</a><br>
+<a href="#2.5. Instructions">2.5. Instructions</a><br>
+<a href="#2.6. Moves">2.6. Moves</a><br>
+<a href="#2.7. Tests">2.7. Tests</a><br>
+<a href="#2.8. Stacking rules">2.8. Stacking rules</a><br>
+<a href="#2.9. Coercions">2.9. Coercions</a><br>
+<a href="#2.10. Patterns">2.10. Patterns</a><br>
+<a href="#2.10.1. Group 1: Load instructions">2.10.1. Group 1: Load instructions</a><br>
+<a href="#2.10.2. Group 2: Store instructions">2.10.2. Group 2: Store instructions</a><br>
+<a href="#2.10.3. Groups 3 and 4: Signed and unsigned integer arithmetic">2.10.3. Groups 3 and 4: Signed and unsigned integer arithmetic</a><br>
+<a href="#2.10.4. Group 5: Floating point arithmetic">2.10.4. Group 5: Floating point arithmetic</a><br>
+<a href="#2.10.5. Group 12: Compare instructions">2.10.5. Group 12: Compare instructions</a><br>
+<a href="#2.10.6. Group 9: Logical instructions">2.10.6. Group 9: Logical instructions</a><br>
+<a href="#2.10.7. Group 14: Procedure call instructions">2.10.7. Group 14: Procedure call instructions</a><br>
+<a href="#3. LIBRARY ROUTINES">3. LIBRARY ROUTINES</a><br>
+<a href="#4. TRAPS">4. TRAPS</a><br>
+<a href="#5. IMPLEMENTATION">5. IMPLEMENTATION</a><br>
+<a href="#6. INTEL 8080 VERSUS ZILOG Z80 AND INTEL 8086">6. INTEL 8080 VERSUS ZILOG Z80 AND INTEL 8086</a><br>
+<a href="#6.1. Introduction">6.1. Introduction</a><br>
+<a href="#6.2. Differences between the 8080 and z80 processors">6.2. Differences between the 8080 and z80 processors</a><br>
+<a href="#6.3. Consequences for the 8080 and z80 back end">6.3. Consequences for the 8080 and z80 back end</a><br>
+<a href="#6.4. What did I do?">6.4. What did I do?</a><br>
+<a href="#6.5. The results">6.5. The results</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Gerard Buskermolen</i></p>
+
+<p>A back end is a part of the Amsterdam Compiler Kit
+(ACK). It translates EM, a family of intermediate languages,
+into the assembly language of some target machine, here the
+Intel 8080 and Intel 8085 microprocessors. INTRODUCTION</p>
+
+<p>To simplify the task of producing portable (cross)
+compilers and interpreters, the Vrije Universiteit designed
+an integrated collection of programs, the Amsterdam Compiler
+Kit (ACK). It is based on the old UNCOL-idea ([4]) which
+attempts to solve the problem of making a compiler for each
+of <b>N</b> languages on <b>M</b> different machines without
+having to write <b>N * M</b> programs.</p>
+
+<p>The UNCOL approach is to write <b>N</b> &quot;front
+ends&quot;, each of which translates one source language
+into a common intermediate language, UNCOL (UNiversal
+Computer Oriented Language), and <b>M</b> &quot;back
+ends&quot;, each of which translates programs in UNCOL into
+a specific machine language. Under these conditions, only
+<b>N + M</b> programs should be written to provide all
+<b>N</b> languages on all <b>M</b> machines, instead of <b>N
+* M</b> programs.</p>
+
+<p>The intermediate language for the Amsterdam Compiler Kit
+is the machine language for a simple stack machine called EM
+(Encoding Machine). So a back end for the Intel 8080 micro
+translates EM code into 8080 assembly language.</p>
+
+<p>The back end is a single program that is driven by a
+machine dependent driving table. This driving table, or back
+end table, defines the mapping from EM code to the
+machine&rsquo;s assembly language.</p>
+<a name="1. THE 8080 MICRO PROCESSOR"></a>
+<h2>1. THE 8080 MICRO PROCESSOR</h2>
+
+<p>This back end table can be used without modification for
+the Intel 8085 processor. Except for two additional
+instructions, the 8085 instruction set is identical and
+fully compatible with the 8080 instruction set. So
+everywhere in this document &rsquo;8080&rsquo; can be read
+as &rsquo;8080 and 8085&rsquo;.</p>
+<a name="1.1. Registers"></a>
+<h2>1.1. Registers</h2>
+
+<p>The 8080 processor has an 8 bit accumulator, six general
+purpose 8-bit registers, a 16 bit programcounter and a 16
+bit stackpointer. Assembler programs can refer the
+accumulator by A and the general purpose registers by B, C,
+D, E, H and L. (*)</p>
+
+<p align=center><img src="grohtml-102111.png"></p>
+
+<p>Several instructions address registers in groups of two,
+thus creating 16 bit registers:</p>
+<pre>     Registers referenced:   Symbolic reference:
+           B and C                   B
+           D and E                   D
+           H and L                   H
+</pre>
+
+<p>The first named register, contains the high order byte
+(H and L stand for High and Low).<br>
+The instruction determines how the processor interprets the
+reference. For example, ADD B is an 8 bit operation, adding
+the contents of register B to accumulator A. By contrast
+PUSH B is a 16 bit operation pushing B and C onto the
+stack.</p>
+
+<p>There are no index registers.</p>
+<a name="1.2. Flip-flops"></a>
+<h2>1.2. Flip-flops</h2>
+
+<p>The 8080 microprocessor provides five flip-flops used as
+condition flags (S, Z, P, C, AC) and one interrupt enable
+flip-flop IE.<br>
+The sign bit S is set (cleared) by certain instructions when
+the most significant bit of the result of an operation
+equals one (zero). The zero bit Z is set (cleared) by
+certain operations when the 8-bit result of an operation
+equals (does not equal) zero. The parity bit P is set
+(cleared) if the 8-bit result of an operation includes an
+even (odd) number of ones. C is the normal carry bit. AC is
+an auxiliary carry that indicates whether there has been a
+carry out of bit 3 of the accumulator. This auxiliary carry
+is used only by the DAA instruction, which adjusts the 8-bit
+value in the accumulator to form two 4-bit binary coded
+decimal digits. Needless to say this instruction is not used
+in the back-end.</p>
+
+<p>The interrupt enable flip-flop IE is set and cleared
+under program control using the instructions EI (Enable
+Interrupt) and DI (Disable Interrupt). It is automatically
+cleared when the CPU is reset and when an interrupt occurs,
+disabling further interrupts until IE = 1 again.</p>
+<a name="1.3. Addressing modes"></a>
+<h2>1.3. Addressing modes</h2>
+<a name="1.3.1. Implied addressing"></a>
+<h2>1.3.1. Implied addressing</h2>
+
+<p>The addressing mode of some instructions is implied by
+the instruction itself. For example, the RAL (rotate
+accumulator left) instruction deals only with the
+accumulator, and PCHL loads the programcounter with the
+contents of register-pair HL.</p>
+<a name="1.3.2. Register addressing"></a>
+<h2>1.3.2. Register addressing</h2>
+
+<p>With each instruction using register addressing, only
+one register is specified (except for the MOV instruction),
+although in many of them the accumulator is implied as
+second operand. Examples are CMP E, which compares register
+E with the accumulator, and DCR B, which decrements register
+B. A few instructions deal with 16 bit register-pairs:
+examples are DCX B, which decrements register-pair BC and
+the PUSH and POP instructions.</p>
+<a name="1.3.3. Register indirect addressing"></a>
+<h2>1.3.3. Register indirect addressing</h2>
+
+<p>Each instruction that may refer to an 8 bit register,
+may refer also to a memory location. In this case the letter
+M (for Memory) has to be used instead of a register. It
+indicates the memory location pointed to by H and L, so ADD
+M adds the contents of the memory location specified by H
+and L to the contents of the accumulator.<br>
+The register-pairs BC and DE can also be used for indirect
+addressing, but only to load or store the accumulator. For
+example, STAX B stores the contents of the accumulator into
+the memory location addressed by register-pair BC.</p>
+<a name="1.3.4. Immediate addressing"></a>
+<h2>1.3.4. Immediate addressing</h2>
+
+<p>The immediate value can be an 8 bit value, as in ADI 10
+which adds 10 to the accumulator, or a 16 bit value, as in
+LXI H,1000, which loads 1000 in the register-pair HL.</p>
+<a name="1.3.5. Direct addressing"></a>
+<h2>1.3.5. Direct addressing</h2>
+
+<p>Jump instructions include a 16 bit address as part of
+the instruction.<br>
+The instruction SHLD 1234 stores the contents of register
+pair HL on memory locations 1234 and 1235. The high order
+byte is stored at the highest address.</p>
+<a name="2. THE 8080 BACK END TABLE"></a>
+<h2>2. THE 8080 BACK END TABLE</h2>
+
+<p>The back end table is designed as described in [5]. For
+an overall design of a back end table I refer to this
+document.<br>
+This section deals with problems encountered in writing the
+8080 back-end table. Some remarks are made about particular
+parts of the table that might not seem clear at first
+sight.</p>
+<a name="2.1. Constant definitions"></a>
+<h2>2.1. Constant definitions</h2>
+
+<p>Word size (EM_WSIZE) and pointer size (EM_PSIZE) are
+both defined as two bytes. The hole between AB and LB
+(EM_BSIZE) is four bytes: only the return address and the
+local base are saved.</p>
+<a name="2.2. Registers and their properties"></a>
+<h2>2.2. Registers and their properties</h2>
+
+<p>All properties have the default size of two bytes,
+because one-byte registers also cover two bytes when put on
+the real stack.</p>
+
+<p>The next considerations led to the choice of
+register-pair BC as local base. Though saving the local base
+in memory would leave one more register-pair available as
+scratch register, it would slow down instructions as
+&rsquo;lol&rsquo; and &rsquo;stl&rsquo; too much. So a
+register-pair should be sacrificed as local base. Because a
+back-end without a free register-pair HL is completely
+broken-winged, the only reasonable choices are BC and DE.
+Though the choice between them might seem arbitrary at first
+sight, there is a difference between register-pairs BC and
+DE: the instruction XCHG exchanges the contents of
+register-pairs DE and HL. When DE and HL are both heavily
+used on the fake-stack, this instruction is very useful.
+Since it won&rsquo;t be useful too often to exchange HL with
+the local base and since an instruction exchanging BC and HL
+does not exist, BC is chosen as local base.</p>
+
+<p>Many of the register properties are never mentioned in
+the PATTERNS part of the table. They are only needed to
+define the INSTRUCTIONS correctly.</p>
+
+<p>The properties really used in the PATTERNS part are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>areg:</p>
+</td>
+<td width="38%"></td>
+<td width="40%">
+
+<p>the accumulator only</p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>reg:</p>
+</td>
+<td width="40%"></td>
+<td width="52%">
+
+<p>any of the registers A, D, E, H or L. Of course the
+registers B and C which are used as local base don&rsquo;t
+possess this property. When there is a single register on
+the fake-stack, its value is always considered
+non-negative.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>dereg:</p>
+</td>
+<td width="36%"></td>
+<td width="42%">
+
+<p>register-pair DE only</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>hlreg:</p>
+</td>
+<td width="36%"></td>
+<td width="42%">
+
+<p>register-pair HL only</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>hl_or_de:</p>
+</td>
+<td width="30%"></td>
+<td width="52%">
+
+<p>register-pairs HL and DE both have this property</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>local</p>
+</td>
+<td width="38%"></td>
+<td width="52%">
+
+<p>used only once (i.e. in the EM-instruction &rsquo;str
+0&rsquo;)</p>
+</td>
+</table>
+
+<p>The stackpointer SP and the processor status word PSW
+have to be defined explicitly because they are needed in
+some instructions (i.e. SP in LXI, DCX and INX and PSW in
+PUSH and POP).<br>
+It doesn&rsquo;t matter that the processor status word is
+not just register A but includes the condition flags.</p>
+<a name="2.3. Tokens"></a>
+<h2>2.3. Tokens</h2>
+
+<p>The tokens &rsquo;m&rsquo; and &rsquo;const1&rsquo; are
+used in the INSTRUCTIONS- and MOVES parts only. They will
+never be on the fake-stack.</p>
+
+<p>The token &rsquo;label&rsquo; reflects addresses known
+at assembly time. It is used to take full profit of the
+instructions LHLD (Load HL Direct) and SHLD (Store HL
+Direct).</p>
+
+<p>Compared with many other back-end tables, there are only
+a small number of different tokens (four). Reasons are the
+limited addressing modes of the 8080 microprocessor, no
+index registers etc. For example to translate the
+EM-instruction</p>
+<pre>     lol 10
+</pre>
+
+<p>the next 8080 instructions are generated:</p>
+<pre>LXI H,10        /* load registers pair HL with value 10 */
+DAD B           /* add local base (BC) to HL            */
+MOV E,M         /* load E with byte pointed to by HL    */
+INX H           /* increment HL                         */
+MOV D,M         /* load D with next byte                */
+</pre>
+
+<p>Of course, instead of emitting code immediately, it
+could be postponed by placing something like a {LOCAL,10} on
+the fake-stack, but some day the above mentioned code will
+have to be generated, so a LOCAL-token is hardly useful. See
+also the comment on the load instructions.</p>
+<a name="2.4. Sets"></a>
+<h2>2.4. Sets</h2>
+
+<p>Only &rsquo;src1or2&rsquo; is used in the PATTERNS.</p>
+<a name="2.5. Instructions"></a>
+<h2>2.5. Instructions</h2>
+
+<p>Each instruction indicates whether or not the condition
+flags are affected, but this information will never have any
+influence because there are no tests in the PATTERNS part of
+the table.</p>
+
+<p>For each instruction a cost vector indicates the number
+of bytes the instruction occupies and the number of time
+periods it takes to execute the instruction. The length of a
+time period depends on the clock frequency and may range
+from 480 nanoseconds to 2 microseconds on a 8080 system and
+from 320 nanoseconds to 2 microseconds on a 8085 system.</p>
+
+<p>In the TOKENS-part the cost of token &rsquo;m&rsquo; is
+defined as (0,3). In fact it usually takes 3 extra time
+periods when this register indirect mode is used instead of
+register mode, but since the costs are not completely
+orthogonal this results in small deficiencies for the DCR,
+INR and MOV instructions. Although it is not particularly
+useful these deficiencies are corrected in the INSTRUCTIONS
+part, by treating the register indirect mode separately.</p>
+
+<p>The costs of the conditional call and return
+instructions really depend on whether or not the call resp.
+return is actually made. However, this is not important to
+the behaviour of the back end.</p>
+
+<p>Instructions not used in this table have been commented
+out. Of course many of them are used in the library
+routines.</p>
+<a name="2.6. Moves"></a>
+<h2>2.6. Moves</h2>
+
+<p>This section is supposed to be straight-forward.</p>
+<a name="2.7. Tests"></a>
+<h2>2.7. Tests</h2>
+
+<p>The TESTS section is only included to refrain <b>cgg</b>
+from complaining.</p>
+<a name="2.8. Stacking rules"></a>
+<h2>2.8. Stacking rules</h2>
+
+<p>When, for example, the token {const2,10} has to be
+stacked while no free register-pair is available, the next
+code is generated:</p>
+<pre>     PUSH H
+     LXI H,10
+     XTHL
+</pre>
+
+<p>The last instruction exchanges the contents of HL with
+the value on top of the stack, giving HL its original value
+again.</p>
+<a name="2.9. Coercions"></a>
+<h2>2.9. Coercions</h2>
+
+<p>The coercion to unstack register A, is somewhat tricky,
+but unfortunately just popping PSW leaves the high-order
+byte in the accumulator.</p>
+
+<p>The cheapest way to coerce HL to DE (or DE to HL) is by
+using the XCHG instruction, but it is not possible to
+explain <b>cgg</b> this instruction in fact exchanges the
+contents of these register-pairs. Before the coercion is
+carried out other appearances of DE and HL on the fake-stack
+will be moved to the real stack, because in the
+INSTRUCTION-part is told that XCHG destroys the contents of
+both DE and HL. The coercion transposing one register-pair
+to another one by emitting two MOV-instructions, will be
+used only if one of the register-pairs is the local
+base.</p>
+<a name="2.10. Patterns"></a>
+<h2>2.10. Patterns</h2>
+
+<p>As a general habit I have allocated (uses ...) all
+registers that should be free to generate the code, although
+it is not always necessary. For example in the code rule</p>
+<pre>     pat loe
+     uses hlreg
+     gen lhld {label,$1}                   yields hl
+</pre>
+
+<p>the &rsquo;uses&rsquo;-clause could have been omitted
+because <b>cgg</b> knows that LHLD destroys register-pair
+HL.</p>
+
+<p>Since there is only one register with property
+&rsquo;hlreg&rsquo;, there is no difference between
+&rsquo;uses hlreg&rsquo; (allocate a register with property
+&rsquo;hlreg&rsquo;) and &rsquo;kills hlreg&rsquo; (remove
+all registers with property &rsquo;hlreg&rsquo; from the
+fake-stack). The same applies for the property
+&rsquo;dereg&rsquo;.<br>
+Consequently &rsquo;kills&rsquo; is rarely used in this
+back-end table.</p>
+<a name="2.10.1. Group 1: Load instructions"></a>
+<h2>2.10.1. Group 1: Load instructions</h2>
+
+<p>When a local variable must be squared, there will
+probably be EM-code like:</p>
+<pre>     lol 10
+     lol 10
+     mli 2
+</pre>
+
+<p>When the code for the first &rsquo;lol 10&rsquo; has
+been executed, DE contains the wanted value. To refrain
+<b>cgg</b> from emitting the code for &rsquo;lol 10&rsquo;
+again, an extra pattern is included in the table for cases
+like this. The same applies for two consecutive
+&rsquo;loe&rsquo;-s or &rsquo;lil&rsquo;-s.</p>
+
+<p>A bit tricky is &rsquo;lof&rsquo;. It expects either DE
+or HL on the fake-stack, moves {const2,$1} into the other
+one, and eventually adds them. The &rsquo;kills&rsquo; part
+is necessary here because if DE was on the fake-stack,
+<b>cgg</b> doesn&rsquo;t see that the contents of DE is
+destroyed by the code (in fact &rsquo;kills dereg&rsquo;
+would have been sufficient: because of the DAD instruction
+<b>cgg</b> knows that HL is destroyed).</p>
+
+<p>By lookahead, <b>cgg</b> can make a clever choice
+between the first and second code rule of &rsquo;loi
+4&rsquo;. The same applies for several other
+instructions.</p>
+<a name="2.10.2. Group 2: Store instructions"></a>
+<h2>2.10.2. Group 2: Store instructions</h2>
+
+<p>A similar idea as with the two consecutive identical
+load instructions in Group 1, applies for a store
+instruction followed by a corresponding load
+instruction.</p>
+<a name="2.10.3. Groups 3 and 4: Signed and unsigned integer arithmetic"></a>
+<h2>2.10.3. Groups 3 and 4: Signed and unsigned integer arithmetic</h2>
+
+<p>Since the 8080 instruction set doesn&rsquo;t provide
+multiply and divide instructions, special routines are made
+to accomplish these tasks.</p>
+
+<p>Instead of providing four slightly differing routines
+for 16 bit signed or unsigned division, yielding the
+quotient or the remainder, the routines are merged. This
+saves space and assembly time when several variants are used
+in a particular program, at the cost of a little speed. When
+the routine is called, bit 7 of register A indicates whether
+the operands should be considered as signed or as unsigned
+integers, and bit 0 of register A indicates whether the
+quotient or the remainder has to be delivered.<br>
+The same applies for 32 bit division.</p>
+
+<p>The routine doing the 16 bit unsigned multiplication
+could have been used for 16 bit signed multiplication too.
+Nevertheless a special 16 bit signed multiplication routine
+is provided, because this one will usually be much
+faster.</p>
+<a name="2.10.4. Group 5: Floating point arithmetic"></a>
+<h2>2.10.4. Group 5: Floating point arithmetic</h2>
+
+<p>Floating point is not implemented. Whenever an
+EM-instruction involving floating points is offered to the
+code-generator, it calls the corresponding library routine
+with the proper parameters. Each floating point library
+routine calls &rsquo;eunimpl&rsquo;, trapping with trap
+number 63. Some of the Pascal and C library routines output
+floating point EM-instructions, so code has to be generated
+for them. Of course this does not imply the code will ever
+be executed.</p>
+<a name="2.10.5. Group 12: Compare instructions"></a>
+<h2>2.10.5. Group 12: Compare instructions</h2>
+
+<p>The code for &rsquo;cmu 2&rsquo;, with its 4 labels, is
+terrible. But it is the best I could find.</p>
+<a name="2.10.6. Group 9: Logical instructions"></a>
+<h2>2.10.6. Group 9: Logical instructions</h2>
+
+<p>I have tried to merge both variants of the instructions
+&rsquo;and 2&rsquo;, &rsquo;ior 2&rsquo; and &rsquo;xor
+2&rsquo;, as in</p>
+<pre>     pat and $1==2
+     with hl_or_de hl_or_de
+     uses reusing %1, reusing %2, hl_or_de, areg
+     gen mov a,%1.2
+         ana %2.2
+         mov %a.2,a
+         mov a,%1.1
+         ana %2.1
+         mov %a.1,a                     yields %a
+</pre>
+
+<p>but the current version of <b>cgg</b> doesn&rsquo;t
+approve this. In any case <b>cgg</b> chooses either DE or HL
+to store the result, using lookahead.</p>
+<a name="2.10.7. Group 14: Procedure call instructions"></a>
+<h2>2.10.7. Group 14: Procedure call instructions</h2>
+
+<p>There is an 8 bytes function return area, called
+&rsquo;.fra&rsquo;. If only 2 bytes have to be returned,
+register-pair DE is used.</p>
+<a name="3. LIBRARY ROUTINES"></a>
+<h2>3. LIBRARY ROUTINES</h2>
+
+<p>Most of the library routines start with saving the
+return address and the local base, so that the parameters
+are on the top of the stack and the registers B and C are
+available as scratch registers. Since register-pair HL is
+needed to accomplish these tasks, and also to restore
+everything just before the routine returns, it is not
+possible to transfer data between the routines and the
+surrounding world through register H or L. Only registers A,
+D and E can be used for this.</p>
+
+<p>When a routine returns 2 bytes, they are usually
+returned in registers-pair DE. When it returns more than 2
+bytes they are pushed onto the stack.<br>
+It would have been possible to let the 32 bit arithmetic
+routines return 2 bytes in DE and the remaining 2 bytes on
+the stack (this often would have saved some space and
+execution time), but I don&rsquo;t consider that as
+well-structured programming.</p>
+<a name="4. TRAPS"></a>
+<h2>4. TRAPS</h2>
+
+<p>Whenever a trap, for example trying to divide by zero,
+occurs in a program that originally was written in C or
+Pascal, a special trap handler is called. This trap handler
+wants to write an appropriate error message on the monitor.
+It tries to read the message from a file (e.g.
+etc/pc_rt_errors in the EM home directory for Pascal
+programs), but since the 8080 back-end doesn&rsquo;t know
+about files, we are in trouble. This problem is solved, as
+far as possible, by including the &rsquo;open&rsquo;-monitor
+call in the mon-routine. It returns with file descriptor -1.
+The trap handler reacts by generating another trap, with the
+original trap number. But this time, instead of calling the
+C- or Pascal trap handler again, the next message is printed
+on the monitor:</p>
+<pre>        trap number &lt;TN&gt;
+        line &lt;LN&gt; of file &lt;FN&gt;
+
+
+where   &lt;TN&gt; is the trap number (decimal)
+        &lt;LN&gt; is the line number (decimal)
+        &lt;FN&gt; is the filename of the original program
+</pre>
+
+<p>Trap numbers are subdivided as follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>1-27:</p>
+</td>
+<td width="30%"></td>
+<td width="60%">
+
+<p>EM-machine error, as described in [3]</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>63:</p>
+</td>
+<td width="34%"></td>
+<td width="60%">
+
+<p>an unimplemented EM-instruction is used</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>64-127:</p>
+</td>
+<td width="26%"></td>
+<td width="60%">
+
+<p>generated by compilers, runtime systems, etc.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>128-252:</p>
+</td>
+<td width="24%"></td>
+<td width="52%">
+
+<p>generated by user programs</p>
+</td>
+<td width="7%">
+</td>
+</table>
+<a name="5. IMPLEMENTATION"></a>
+<h2>5. IMPLEMENTATION</h2>
+
+<p>It will not be possible to run the entire Amsterdam
+Compiler Kit on a 8080-based computer system. One has to
+write a program on another system, a system where the
+compiler kit runs on. This program may be a mixture of
+high-level languages, such as C or Pascal, EM and 8080
+assembly code. The program should be compiled using the
+compiler kit, producing 8080 machine code. This code should
+come available to the 8080 machine for example by
+downloading or by storing it in ROM (Read Only Memory).</p>
+
+<p>Depending on the characteristics of the particular 8080
+based system, some adaptations have to be made:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>In &rsquo;head_em&rsquo;: the base address, which is the
+address where the first 8080 instruction will be stored, and
+the initial value of the stackpointer are set to 0x1000 and
+0x8000 respectively.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Other systems require other values.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>In &rsquo;head_em&rsquo;: before calling
+&quot;__m_a_i_n&quot;, the environment pointer, argument
+vector and argument count will have to be pushed onto the
+stack. Since this back-end is tested on a system without any
+knowledge of these things, dummies are pushed now.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3)</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>In &rsquo;tail_em&rsquo;: proper routines
+&quot;putchar&quot; and &quot;getchar&quot; should be
+provided. They should write resp. read a character on/from
+the monitor. Maybe some conversions will have to be
+made.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4)</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>In &rsquo;head_em&rsquo;: an application program returns
+control to the monitor by jumping to address 0xFB52. This
+may have to be changed for different systems.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5)</p>
+</td>
+<td width="16%"></td>
+<td width="80%">
+
+<p>In &rsquo;tail_em&rsquo;: the current version of the
+8080 back-end has very limited I/O capabilities, because it
+was tested on a system that had no knowledge of files. So
+the implementation of the EM-instruction &rsquo;mon&rsquo;
+is very simple; it can only do the following things:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="30%">
+
+<p>Monitor call 1:</p>
+</td>
+<td width="50%"></td>
+<td width="0%">
+
+<p>exit</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="30%">
+
+<p>Monitor call 3:</p>
+</td>
+<td width="50%"></td>
+<td width="0%">
+
+<p>read, always reads from the monitor.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="99%"></td>
+<td width="0%">
+<p>echos the read character.<br>
+ignores file descriptor.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="30%">
+
+<p>Monitor call 4:</p>
+</td>
+<td width="50%"></td>
+<td width="0%">
+
+<p>write, always writes on the monitor.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="99%"></td>
+<td width="0%">
+<p>ignores file descriptor.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="30%">
+
+<p>Monitor call 5:</p>
+</td>
+<td width="50%"></td>
+<td width="0%">
+
+<p>open file, returns file descriptor -1.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="99%"></td>
+<td width="0%">
+<p>(compare chapter about TRAPS)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="30%">
+
+<p>Monitor call 6:</p>
+</td>
+<td width="50%"></td>
+<td width="0%">
+
+<p>close file, returns error code = 0.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="32%">
+
+<p>Monitor call 54:</p>
+</td>
+<td width="48%"></td>
+<td width="0%">
+
+<p>io-control, returns error code = 0.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>If the system should do file-handling the routine
+&quot;.mon&quot; should be extended thoroughly.</p></td>
+</table>
+<a name="6. INTEL 8080 VERSUS ZILOG Z80 AND INTEL 8086"></a>
+<h2>6. INTEL 8080 VERSUS ZILOG Z80 AND INTEL 8086</h2>
+<a name="6.1. Introduction"></a>
+<h2>6.1. Introduction</h2>
+
+<p>At about the same time I developed the back end for the
+Intel 8080 and Intel 8085, Frans van Haarlem did the same
+job for the Zilog z80 microprocessor. Since the z80
+processor is an extension of the 8080, any machine code
+offered to a 8080 processor can be offered to a z80 too. The
+assembly languages are quite different however.<br>
+During the developments of the back ends we have used two
+micro-computers, both equipped with a z80 microprocessor. Of
+course the output of the 8080 back end is assembled by an
+8080 assembler. This should assure I have never used any of
+the features that are potentially available in the z80
+processor, but are not part of a true 8080 processor.</p>
+
+<p>As a final job, I have investigated the differences
+between the 8080 and z80 processors and their influence on
+the back ends. I have tried to measure this influence by
+examining the length of the generated code. I have also
+involved the 8086 micro-processor in this measurements.</p>
+<a name="6.2. Differences between the 8080 and z80 processors"></a>
+<h2>6.2. Differences between the 8080 and z80 processors</h2>
+
+<p>Except for some features that are less important
+concerning back ends, there are two points where the z80
+improves upon the 8080:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>First,</p>
+</td>
+<td width="24%"></td>
+<td width="64%">
+
+<p>the z80 has two additional index registers, IX and IY.
+They are used as in</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="64%">
+<pre>              LD B,(IX+10)
+</pre>
+<!-- INDENTATION -->
+<p>The offset, here 10, should fit in one byte.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>Second,</p>
+</td>
+<td width="22%"></td>
+<td width="64%">
+
+<p>the z80 has several additional instructions. The most
+important ones are:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="12%"></td>
+<td width="48%">
+
+<p>The 8080 can only load or store register-pair HL direct
+(using LHLD or SHLD). The z80 can handle BC, DE and SP
+too.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="12%"></td>
+<td width="48%">
+
+<p>Instructions are included to ease block movements.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="4%">
+
+<p>3)</p>
+</td>
+<td width="12%"></td>
+<td width="48%">
+
+<p>There is a 16 bit subtract instruction.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="4%">
+
+<p>4)</p>
+</td>
+<td width="12%"></td>
+<td width="48%">
+
+<p>While the 8080 can only rotate the accumulator, the z80
+can rotate and shift each 8 bit register.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="4%">
+
+<p>5)</p>
+</td>
+<td width="12%"></td>
+<td width="48%">
+
+<p>Special routines are included to jump to near locations,
+saving 1 byte.</p>
+</td>
+</table>
+<a name="6.3. Consequences for the 8080 and z80 back end"></a>
+<h2>6.3. Consequences for the 8080 and z80 back end</h2>
+
+<p>The most striking difference between the 8080 and z80
+back ends is the choice of the local base. The writer of the
+z80 back end chose index register IY as local base, because
+this results in the cheapest coding of EM-instructions like
+&rsquo;lol&rsquo; and &rsquo;stl&rsquo;. The z80
+instructions that load local 10, for example</p>
+<pre>     LD E,(IY+10)
+     LD D,(IY+11)
+</pre>
+
+<p>occupy 6 bytes and take 38 time periods to execute. The
+five corresponding 8080 instructions loading a local occupy
+7 bytes and take 41 time periods. Although the profit of the
+z80 might be not world-shocking, it should be noted that as
+a side effect it may save some pushing and popping since
+register pair HL is not used.</p>
+
+<p>The choice of IY as local base has its drawbacks too.
+The root of the problem is that it is not possible to add IY
+to HL. For the EM-instruction</p>
+<pre>     lal 20
+</pre>
+
+<p>the z80 back end generates code like</p>
+<pre>     LD BC,20
+     PUSH IY
+     POP HL
+     ADD HL,BC
+</pre>
+
+<p>leaving the wanted address in HL.<br>
+This annoying push and pop instructions are also needed in
+some other instructions, for instance in &rsquo;lol&rsquo;
+when the offset doesn&rsquo;t fit in one byte.</p>
+
+<p>Beside the choice of the local base, I think there is no
+fundamental difference between the 8080 and z80 back ends,
+except of course that the z80 back end has register pair BC
+and, less important, index register IX available as scratch
+registers.</p>
+
+<p>Most of the PATTERNS in the 8080 and z80 tables are more
+or less a direct translation of each other.</p>
+<a name="6.4. What did I do?"></a>
+<h2>6.4. What did I do?</h2>
+
+<p>To get an idea of the quality of the code generated by
+the 8080, z80 and 8086 back ends I have gathered some C
+programs and some Pascal programs. Then I produced 8080, z80
+and 8086 code for them. Investigating the assembler listing
+I found the lengths of the different parts of the generated
+code. I have checked two areas:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="12%"></td>
+<td width="40%">
+
+<p>the entire text part</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="12%"></td>
+<td width="84%">
+
+<p>the text part without any library routine, so only the
+plain user program</p>
+</td>
+</table>
+
+<p>I have to admit that neither one of them is really
+honest. When the entire text part is checked, the result is
+disturbed because not always the same library routines are
+loaded. And when only the user program itself is considered,
+the result is disturbed too. For example the 8086 has a
+multiply instruction, so the EM-instruction &rsquo;mli
+2&rsquo; is translated in the main program, but the 8080 and
+z80 call a library routine that is not counted. Also the
+8080 uses library routines at some places where the z80 does
+not.</p>
+
+<p>But nevertheless I think the measurements will give an
+idea about the code produced by the three back ends.</p>
+<a name="6.5. The results"></a>
+<h2>6.5. The results</h2>
+
+<p>The table below should be read as follows. For all
+programs I have computed the ratio of the code-lengths of
+the 8080, z80 and 8086. The averages of all Pascal/C
+programs are listed in the table, standardized to
+&rsquo;100&rsquo; for the 8080. So the listed
+&rsquo;107&rsquo; indicates that the lengths of the text
+parts of the z80 programs that originally were Pascal
+programs, averaged 7 percent larger than in the
+corresponding 8080 programs.</p>
+
+
+<p align=center>--------------------------------------------------<br>
+| | 8080 | z80 | 8086 |<br>
+--------------------------------------------------<br>
+| C, text part | 100 | 103 | 65 |<br>
+| Pascal, text part | 100 | 107 | 55 |<br>
+| C, user program | 100 | 110 | 71 |<br>
+| Pascal, user program | 100 | 118 | 67 |<br>
+--------------------------------------------------</p>
+
+<p>The most striking thing in this table is that the z80
+back end appears to produce larger code than the 8080 back
+end. The reason is that the current z80 back end table is
+not very sophisticated yet. For instance it doesn&rsquo;t
+look for any EM-pattern longer than one. So the table shows
+that the preparations in the 8080 back end table to produce
+faster code (like recognizing special EM-patterns and
+permitting one byte registers on the fake-stack) was not
+just for fun, but really improved the generated code
+significantly.</p>
+
+<p>The table shows that the 8080 table is relatively better
+when only the plain user program is considered instead of
+the entire text part. This is not very surprising since the
+8080 back end sometimes uses library routines where the z80
+and especially the 8086 don&rsquo;t.</p>
+
+<p>The difference between the 8080 and z80 on the one hand
+and the 8086 on the other is very big. But of course it was
+not equal game: the 8086 is a 16 bit processor that is much
+more advanced than the 8080 or z80 and the 8086 back end is
+known to produce very good code.</p>
+
+<p><b>REFERENCES</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[1]</p>
+</td>
+<td width="14%"></td>
+<td width="80%">
+
+<p>8080/8085 Assembly Language Programming Manual,</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Intel Corporation (1977,1978)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[2]</p>
+</td>
+<td width="14%"></td>
+<td width="80%">
+
+<p>Andrew S. Tanenbaum, Hans van Staveren, E.G. Keizer and
+Johan W. Stevenson,</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>A practical tool kit for making portable compilers,<br>
+Informatica report 74, Vrije Universiteit, Amsterdam,
+1983.</p>
+<!-- INDENTATION -->
+<p>An overview on the Amsterdam Compiler Kit.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[3]</p>
+</td>
+<td width="14%"></td>
+<td width="80%">
+
+<p>Tanenbaum, A.S., Stevenson, J.W., Keizer, E.G., and van
+Staveren, H.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Description of an experimental machine architecture for
+use with block structured languages,<br>
+Informatica report 81, Vrije Universiteit, Amsterdam,
+1983.</p>
+<!-- INDENTATION -->
+<p>The defining document for EM.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[4]</p>
+</td>
+<td width="14%"></td>
+<td width="32%">
+
+<p>Steel, T.B., Jr.</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>UNCOL: The myth and the Fact. in Ann. Rev. Auto.
+Prog.<br>
+Goodman, R. (ed.), vol. 2, (1960), p325-344.</p>
+<!-- INDENTATION -->
+<p>An introduction to the UNCOL idea by its originator.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[5]</p>
+</td>
+<td width="14%"></td>
+<td width="36%">
+
+<p>van Staveren, Hans</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>The table driven code generator from the Amsterdam
+Compiler Kit (Second Revised Edition),<br>
+Vrije Universiteit, Amsterdam.</p>
+<!-- INDENTATION -->
+<p>The defining document for writing a back end table.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[6]</p>
+</td>
+<td width="14%"></td>
+<td width="20%">
+
+<p>Voors, Jan</p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>A back end for the Zilog z8000 micro,<br>
+Vrije Universiteit, Amsterdam.</p>
+<!-- INDENTATION -->
+<p>A document like this one, but for the z8000.</p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/i80.pdf b/src/olddocs/i80.pdf
new file mode 100644 (file)
index 0000000..13c6484
Binary files /dev/null and b/src/olddocs/i80.pdf differ
diff --git a/src/olddocs/install.html b/src/olddocs/install.html
new file mode 100644 (file)
index 0000000..d7e4fd5
--- /dev/null
@@ -0,0 +1,2645 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:16:57 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>Amsterdam Compiler Kit Installation Guide</title>
+</head>
+<body>
+
+<h1 align=center>Amsterdam Compiler Kit Installation Guide</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The ACK installation process">2. The ACK installation process</a><br>
+<a href="#3. Restoring the ACK tree">3. Restoring the ACK tree</a><br>
+<a href="#4. Adapting ACK to the local system">4. Adapting ACK to the local system</a><br>
+<a href="#5. Compiling the Kit">5. Compiling the Kit</a><br>
+<a href="#5.1. Problems">5.1. Problems</a><br>
+<a href="#5.1.1. on Unisoft m68000 systems.">5.1.1. on Unisoft m68000 systems.</a><br>
+<a href="#5.1.2. with backends">5.1.2. with backends</a><br>
+<a href="#5.2. An example output of TakeAction.">5.2. An example output of TakeAction.</a><br>
+<a href="#6. Commands">6. Commands</a><br>
+<a href="#7. Machines">7. Machines</a><br>
+<a href="#8. Compilation on a different machine.">8. Compilation on a different machine.</a><br>
+<a href="#8.1. Backend">8.1. Backend</a><br>
+<a href="#8.2. Universal assembler/loader, link editor">8.2. Universal assembler/loader, link editor</a><br>
+<a href="#9. Options">9. Options</a><br>
+<a href="#9.1. Default machine">9.1. Default machine</a><br>
+<a href="#9.2. Pathnames">9.2. Pathnames</a><br>
+<a href="#10. Makefiles">10. Makefiles</a><br>
+<a href="#11. Testing">11. Testing</a><br>
+<a href="#12. Documentation">12. Documentation</a><br>
+
+<hr>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>This document describes the process of installing the
+Amsterdam Compiler Kit (ACK). It depends on the combination
+of hard- and software how hard it will be to install the
+Kit. This description is intended for a Sun-3 or SPARC
+workstation. Installation on VAXen running Berkeley
+<small>UNIX</small> &reg; or Ultrix, Sun-2 systems and most
+System V <small>UNIX</small> systems should be easy. As of
+this distribution, installation on PDP-11&rsquo;s or other
+systems with a small address space is no longer supported.
+See section 8 for installation on other systems.</p>
+<a name="2. The ACK installation process"></a>
+<h2>2. The ACK installation process</h2>
+
+<p>In the ACK installation process, three directory trees
+are used:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the ACK source tree. This is the tree on the ACK
+distribution medium. For the rest of this document, we will
+refer to this directory as $SRC_HOME;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>a configuration tree. This tree is built by the
+installation process and is used to do compilations in. Its
+structure reflects that of the source tree, but this tree
+will mostly contain Makefiles and relocatable objects. For
+the rest of this document, we will refer to this directory
+as $CONFIG;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>an ACK users tree. This tree is also built by the
+installation process. For the rest of this document, we will
+refer to this directory as $TARGET_HOME;</p>
+</td>
+</table>
+
+<p>After installation, the directories in $TARGET_HOME
+contain the following information:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>bin</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>the few utilities that knot things together. See the
+section about &quot;Commands&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>lib</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>root of a tree containing almost all libraries used by
+commands. Files specific to a certain machine are collected
+in one subtree per machine. E.g. &quot;lib/pdp&quot;,
+&quot;lib/z8000&quot;. The names used here are the same
+names as used for subtrees of
+&quot;$SRC_HOME/mach&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>lib/descr</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>command descriptor files used by the program ack.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>lib/LLgen</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>files used by the LL(1) parser generator.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>lib/flex</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>files used by the lexical analyzer generator Flex.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>lib/m2</p>
+</td>
+<td width="16%"></td>
+<td width="64%">
+
+<p>definition modules for Modula-2.</p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>lib.bin</p>
+</td>
+<td width="14%"></td>
+<td width="72%">
+
+<p>root of a tree containing almost all binaries used by
+commands. All programs specific to a certain machine are
+collected in one subtree per machine. E.g.
+&quot;lib.bin/pdp&quot;, &quot;lib.bin/z8000&quot;. The
+names used here are the same names as used for subtrees of
+&quot;$SRC_HOME/mach&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>lib.bin/ego</p>
+</td>
+<td width="6%"></td>
+<td width="70%">
+
+<p>files used by the global optimizer.</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>lib.bin/lint</p>
+</td>
+<td width="4%"></td>
+<td width="72%">
+
+<p>binaries for the lint passes and lint libraries.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>lib.bin/ceg</p>
+</td>
+<td width="6%"></td>
+<td width="72%">
+
+<p>files used by the code-expander-generator.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>etc</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>contains the file &quot;ip_spec.t&quot; needed for EM
+interpreters and EM documentation.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>config</p>
+</td>
+<td width="16%"></td>
+<td width="54%">
+
+<p>contains two include files:</p>
+</td>
+<td width="17%">
+</td>
+</table>
+
+<p align=center><img src="grohtml-96851.png"></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>These include files are specific for the current machine,
+so they are in a separate directory.</p>
+</td>
+</table>
+
+<p>include/_tail_cc</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>include files needed by modules in the C library from
+lang/cem/libcc.</p>
+</td>
+</table>
+
+<p>include/tail_ac</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>include files for ANSI C.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p>include/occam</p>
+</td>
+<td width="2%"></td>
+<td width="48%">
+
+<p>include files for occam.</p>
+</td>
+<td width="23%">
+</td>
+</table>
+
+<p>include/_tail_mon</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>more or less system independent include files needed by
+modules in the library lang/cem/libcc/mon.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>h</p>
+</td>
+<td width="26%"></td>
+<td width="46%">
+
+<p>the #include files for:</p>
+</td>
+<td width="25%">
+</td>
+</table>
+
+<p align=center><img src="grohtml-96852.png"></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>modules</p>
+</td>
+<td width="14%"></td>
+<td width="72%">
+
+<p>root of a tree containing modules for compiler
+writers.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>modules/man</p>
+</td>
+<td width="6%"></td>
+<td width="58%">
+
+<p>manual pages for all modules.</p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>modules/lib</p>
+</td>
+<td width="6%"></td>
+<td width="48%">
+
+<p>contains module objects.</p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>modules/h</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>include files for some of the modules.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>modules/pkg</p>
+</td>
+<td width="6%"></td>
+<td width="72%">
+
+<p>include files for some of the modules.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>doc</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>this directory contains the unformatted documents for
+the Kit. A list of the available documents can be found in
+the last section. These documents must be processed by
+[nt]roff.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>man</p>
+</td>
+<td width="22%"></td>
+<td width="64%">
+
+<p>man files for various utilities.</p>
+</td>
+<td width="7%">
+</td>
+</table>
+
+<p>When installing ACK on several types of machines with a
+shared file system, it may be useful to know that the
+&quot;doc&quot;, &quot;etc&quot;, &quot;h&quot;,
+&quot;include&quot;, &quot;lib&quot; and &quot;man&quot;
+sub-directories do not depend on this particular
+installation. They do not contain binaries or path-dependent
+information. These directories can therefore be shared
+between the ACK installations. This can be accomplished by
+creating the tree and suitable symbolic links before
+starting the installation process.</p>
+
+<p>For instance, let us say there is a file-system that is
+accessible from the different machines as
+&quot;/usr/share/local&quot;, and the ACK binary tree must
+be installed in &quot;/usr/local/ack&quot;. In this case,
+proceed as follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>create a directory &quot;/usr/share/local/ack&quot;,
+with subdirectories &quot;doc&quot;, &quot;etc&quot;,
+&quot;h&quot;, &quot;include&quot;, &quot;lib&quot; and
+&quot;man&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>create a directory &quot;/usr/local/ack&quot; and then
+create symbolic links &quot;doc&quot; to
+&quot;/usr/share/local/ack/doc&quot;, etc.</p>
+</td>
+</table>
+
+<p>If this is done on all machines on which ACK will be
+installed, the machine-independent part only has to be
+installed once, preferably on the fastest processor (it
+takes a long time to install all libraries).</p>
+
+<p>The directories in the source tree contain the following
+information:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>bin</p>
+</td>
+<td width="22%"></td>
+<td width="58%">
+
+<p>source of some shell-scripts.</p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>lib</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>mostly description files for the &quot;ack&quot;
+program.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>etc</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>the main description of EM sits here. Files (e.g.
+em_table) describing the opcodes and pseudos in use, the
+operands allowed, effect in stack etc. etc.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>mach</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>just there to group the directories with all sources for
+each machine. The section about &quot;Machines&quot; of this
+manual indicates which subdirectories are used for which
+systems.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>These directories have subdirectories named:</p></td>
+</table>
+
+<p align=center><img src="grohtml-96853.png"></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>Actually, some of these directories will only appear in
+the configuration tree.<br>
+The directory proto contains files used by most machines,
+like machine-independent sources and Makefiles.</p></td>
+</table>
+
+<p align=center><img src="grohtml-96854.png"></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>emtest</p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p>contains prototype of em test set.</p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>lang</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>just there to group the directories for all
+front-ends.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>lang/pc</p>
+</td>
+<td width="14%"></td>
+<td width="42%">
+
+<p>the Pascal front-end.</p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p>lang/pc/libpc</p>
+</td>
+<td width="73%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>source of Pascal run-time system (in EM or C).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>lang/pc/test</p>
+</td>
+<td width="4%"></td>
+<td width="72%">
+
+<p>some test programs written in Pascal.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>lang/pc/comp</p>
+</td>
+<td width="4%"></td>
+<td width="54%">
+
+<p>the Pascal compiler proper.</p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>lang/cem</p>
+</td>
+<td width="12%"></td>
+<td width="32%">
+
+<p>the C front-end.</p>
+</td>
+<td width="39%">
+</td>
+</table>
+
+<p>lang/cem/libcc</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>directories with sources of C runtime system, libraries
+(in EM or C).</p>
+</td>
+</table>
+
+<p>lang/cem/libcc/gen</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>sources for routines in chapter III of
+<small>UNIX</small> programmers manual, excluding stdio.</p>
+</td>
+</table>
+
+<p>lang/cem/libcc/stdio</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>stdio sources.</p>
+</td>
+</table>
+
+<p>lang/cem/libcc/math</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>sources for mathematical routines, normally available
+with the <b>-lm</b> option to <i>cc</i>.</p>
+</td>
+</table>
+
+<p>lang/cem/libcc/mon</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>sources for routines in chapter II, mostly written in
+EM.</p>
+</td>
+</table>
+
+<p>lang/cem/cemcom</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the compiler proper.</p>
+</td>
+</table>
+
+<p>lang/cem/cemcom.ansi</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the ANSI C compiler proper.</p>
+</td>
+</table>
+
+<p>lang/cem/cpp.ansi</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the ANSI C preprocessor.</p>
+</td>
+</table>
+
+<p>lang/cem/libcc.ansi</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the ANSI C library sources.</p>
+</td>
+</table>
+
+<p>lang/cem/ctest</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the C test set.</p>
+</td>
+</table>
+
+<p>lang/cem/ctest/cterr</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>programs developed for pinpointing previous errors.</p>
+</td>
+</table>
+
+<p>lang/cem/ctest/ct*</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the test programs.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p>lang/cem/lint</p>
+</td>
+<td width="2%"></td>
+<td width="40%">
+
+<p>a C program checker.</p>
+</td>
+<td width="31%">
+</td>
+</table>
+
+<p>lang/cem/lint/lpass1</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the first pass of lint.</p>
+</td>
+</table>
+
+<p>lang/cem/lint/lpass1.ansi</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the first pass of lint, this time for ANSI C.</p>
+</td>
+</table>
+
+<p>lang/cem/lint/lpass2</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the second pass of lint, shared between ANSI C and
+&quot;old-fashioned&quot; C.</p>
+</td>
+</table>
+
+<p>lang/cem/lint/llib</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>programs for producing lint libraries.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>lang/basic</p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p>the Basic front-end.</p>
+</td>
+<td width="31%">
+</td>
+</table>
+
+<p>lang/basic/src</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the compiler proper.</p>
+</td>
+</table>
+
+<p>lang/basic/lib</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the Basic run-time library source.</p>
+</td>
+</table>
+
+<p>lang/basic/test</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>various Basic programs.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>lang/occam</p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p>the occam front-end.</p>
+</td>
+<td width="31%">
+</td>
+</table>
+
+<p>lang/occam/comp</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the compiler proper.</p>
+</td>
+</table>
+
+<p>lang/occam/lib</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>source of occam run-time system (in EM or C).</p>
+</td>
+</table>
+
+<p>lang/occam/test</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>some occam programs.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>lang/m2</p>
+</td>
+<td width="14%"></td>
+<td width="46%">
+
+<p>the Modula-2 front-end.</p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>lang/m2/comp</p>
+</td>
+<td width="4%"></td>
+<td width="40%">
+
+<p>the compiler proper.</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p>lang/m2/libm2</p>
+</td>
+<td width="2%"></td>
+<td width="72%">
+
+<p>source of Modula-2 run-time system (in EM, C and
+Modula-2).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>lang/m2/m2mm</p>
+</td>
+<td width="4%"></td>
+<td width="64%">
+
+<p>the Modula-2 makefile generator.</p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>lang/m2/test</p>
+</td>
+<td width="4%"></td>
+<td width="62%">
+
+<p>some Modula-2 example programs.</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>lang/fortran</p>
+</td>
+<td width="4%"></td>
+<td width="72%">
+
+<p>the Fortran front-end (translates Fortran into C). This
+compiler is not a part of ACK, but is included because it
+adds another language. The Fortran system carries the
+following copyright notice:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<pre>/**************************************************************
+Copyright 1990, 1991 by AT&amp;T Bell Laboratories and Bellcore.
+
+Permission to use, copy, modify, and distribute this software
+and its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the names of AT&amp;T Bell Laboratories or
+Bellcore or any of their entities not be used in advertising or
+publicity pertaining to distribution of the software without
+specific, written prior permission.
+
+AT&amp;T and Bellcore disclaim all warranties with regard to this
+software, including all implied warranties of merchantability
+and fitness.  In no event shall AT&amp;T or Bellcore be liable for
+any special, indirect or consequential damages or any damages
+whatsoever resulting from loss of use, data or profits, whether
+in an action of contract, negligence or other tortious action,
+arising out of or in connection with the use or performance of
+this software.
+**************************************************************/
+</pre>
+</td>
+</table>
+
+<p>lang/fortran/comp</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the compiler proper.</p>
+</td>
+</table>
+
+<p>lang/fortran/lib</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>source of Fortran runtime system and libraries.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>fast</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>contains sub-directories for installing the fast ACK
+compatible compilers.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>fast/driver</p>
+</td>
+<td width="77%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>contains the sources of the fast ACK compatible compiler
+drivers.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>fcc</p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>contains the fast cc-compatible C compiler for SUN-3 and
+VAX.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>util</p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>contains directories with sources for various
+utilities.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/ack</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>the program used for translation with the Kit.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/opt</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>the EM peephole optimizer (*.k =&gt; *.m).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/ego</p>
+</td>
+<td width="12%"></td>
+<td width="42%">
+
+<p>the global optimizer.</p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>util/topgen</p>
+</td>
+<td width="6%"></td>
+<td width="62%">
+
+<p>the target optimizer generator.</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>util/misc</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>decode (*.[km] =&gt; *.e) + encode (*.e =&gt; *.k).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>util/data</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>the C-code for $TARGET_HOME/lib.bin/em_data.a. These
+sources are created by the Makefile in
+&lsquo;etc&lsquo;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/ass</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>the EM assembler (*.[km] + libraries =&gt; e.out).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>util/arch</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>the archivers to be used for all EM utilities.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/cgg</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>a program needed for compiling backends.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>util/ncgg</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>a program needed for compiling the newest backends.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/cpp</p>
+</td>
+<td width="12%"></td>
+<td width="38%">
+
+<p>the C preprocessor.</p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/shf</p>
+</td>
+<td width="12%"></td>
+<td width="40%">
+
+<p>various shell files.</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>util/LLgen</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>the extended LL(1) parser generator.</p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>util/amisc</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>contains some programs handling ACK a.out format, such
+as anm, asize.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>util/cmisc</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>contains some programs to help in resolving name
+conflicts, and a dependency generator for makefiles.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/led</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>the ACK link-editor, reading ACK relocatable a.out
+format, and writing ACK a.out format.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/int</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>an EM interpreter, written in C. Very useful for
+checking out software, but slow.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>util/ceg</p>
+</td>
+<td width="12%"></td>
+<td width="48%">
+
+<p>code expander generator.</p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>util/grind</p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p>a symbolic debugger.</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>util/byacc</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>this is Berkeley yacc, in the public domain.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>util/flex</p>
+</td>
+<td width="10%"></td>
+<td width="72%">
+
+<p>this is a replacement for lex. It carries the following
+copyright notice:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<pre>Copyright (c) 1990 The Regents of the University of California.
+All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Vern Paxson.
+
+The United States Government has rights in this work pursuant
+to contract no. DE-AC03-76SF00098 between the United States
+Department of Energy and the University of California.
+
+Redistribution and use in source and binary forms are permitted
+provided that: (1) source distributions retain this entire
+copyright notice and comment, and (2) distributions including
+binaries display the following acknowledgement:  &lsquo;&lsquo;This product
+includes software developed by the University of California,
+Berkeley and its contributors&rsquo;&rsquo; in the documentation or other
+materials provided with the distribution and in all advertising
+materials mentioning features or use of this software.  Neither the
+name of the University nor the names of its contributors may be
+used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED &lsquo;&lsquo;AS IS&rsquo;&rsquo; AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.
+</pre>
+</td>
+</table>
+
+<p>All path names mentioned in the text of this document
+are relative to $SRC_HOME, unless they start with
+&rsquo;/&rsquo; or one of $SRC_HOME, $TARGET_HOME or
+$CONFIG.</p>
+<a name="3. Restoring the ACK tree"></a>
+<h2>3. Restoring the ACK tree</h2>
+
+<p>The process of installing the Amsterdam Compiler Kit is
+quite simple. The first step is to restore the Amsterdam
+Compiler Kit distribution tree structure. Proceed as
+follows</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="14%"></td>
+<td width="80%">
+
+<p>Create a directory, for example
+/usr/share/local/src/ack, on a device with at least 15
+Megabytes left. This directory will be $SRC_HOME.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p>Change to that directory (cd ...).</p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="14%"></td>
+<td width="80%">
+
+<p>Extract all files from the distribution medium, for
+instance magtape: <b>tar x</b>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="12%"></td>
+<td width="80%">
+
+<p>Keep a copy of the original distribution to be able to
+repeat the process of installation in case of disasters.
+This copy is also useful as a reference point for
+diff-listings.</p>
+</td>
+</table>
+<a name="4. Adapting ACK to the local system"></a>
+<h2>4. Adapting ACK to the local system</h2>
+
+<p>Before compiling the sources in the Kit some
+installation dependent actions have to be taken. Most of
+these are performed by an interactive shell script in the
+file <i>$SRC_HOME/first/first.</i> Calling this script
+should be done from another directory, for instance an empty
+directory which will later become $CONFIG.</p>
+
+<p>The actions of the <i>first</i> script are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Asking for the path names of the ACK source directory
+($SRC_HOME), the configuration directory ($CONFIG), and the
+ACK users directory ($TARGET_HOME). About 5M are needed for
+the configuration tree. The disk space needed for the ACK
+users tree depends on which front-ends and back-ends are to
+be installed. For instance, on our SPARC systems we have
+installed all languages and 6 back-ends, including the
+system-independent part. This amounts to about 16M. On our
+SUN-3 systems, we have installed all front-ends and 5
+back-ends, but only the machine-dependent part. The
+machine-independent directories are symbolic links to the
+SPARC ACK users tree. We also have the fast ACK compilers
+installed on the SUN-3&rsquo;s. The total amount of
+disk-space used is less than 8M.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Asking for what type of system the binary tree must be
+produced for and creating the shell script
+&quot;ack_sys&quot; in the Kit&rsquo;s bin directory.
+Several utilities make use of &quot;ack_sys&quot; to
+determine the type of system. The current choice is
+between:</p>
+</td>
+</table>
+
+<p align=center><img src="grohtml-96855.png"></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>For some of these, the installation procedure has not
+been tested, as we don&rsquo;t have them. For others, the
+installation procedure has only been tested with earlier
+distributions, as we don&rsquo;t have those systems anymore.
+However, the sun3 and sparc systems are known to behave
+reasonably. The sparc_solaris system has only been tested
+with the GNU C compiler, because we don&rsquo;t have the SUN
+C compiler (it is unbundled in Solaris 2). The Sun systems
+should run SunOs Release 3.0 or newer. The i386 choice may
+also be used for Intel 80386 or 80486 systems running
+<small>UNIX</small> System V Release 4. These systems are
+also able to run Xenix System V binaries. If the target
+system is not on this list, choose one that comes close. If
+none of them come close, use the &quot;ANY&quot; choice. For
+ANY, any name can be used, but the Kit will not be able to
+compile programs for the target system. See the section
+about &quot;compilation on a different machine&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Setting the default machine for which code is produced
+to the local type of system according to the table above.
+This in done in the file
+&quot;$TARGET_HOME/config/local.h&quot;. See also section
+9.1.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Asking for things that don&rsquo;t have to be
+installed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Producing a shell script called &quot;INSTALL&quot; that
+will take care of the ACK installation process.</p>
+</td>
+</table>
+<a name="5. Compiling the Kit"></a>
+<h2>5. Compiling the Kit</h2>
+
+<p>The next step in the installation process is to run the
+&quot;INSTALL&quot; shell-script. When using a Bourne-shell,
+type:</p>
+<pre>     sh INSTALL &gt; INSTALL.out 2&gt;&amp;1 &amp;
+</pre>
+
+<p>When using a C-shell, type:</p>
+<pre>     sh INSTALL &gt;&amp; INSTALL.out &amp;
+</pre>
+
+<p>This shell-script performs the following steps:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Produce a configuration tree ($CONFIG), reflecting the
+structure of the source tree.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Produce Makefiles in $CONFIG. As mentioned before,
+compilations will be done in the configuration tree, not in
+the source tree. Most configuration directories will have
+Makefiles used to compile and install the programs in that
+directory. All programs needed for compilation and/or cross
+compilation with the Kit are installed in $TARGET_HOME by
+these Makefiles. These Makefiles are produced from
+corresponding files called &quot;proto.make&quot; in the
+source tree. In fact, the &quot;proto.make&quot; files are
+almost complete Makefiles, except for some macro definitions
+that are collected by the <i>first</i> script. The Makefiles
+adhere to a standard which is described in the section
+9.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Copy &quot;Action&quot; files to the configuration tree
+and editing them to reflect the choices concerning the parts
+of ACK that have to be installed. &quot;Action&quot; files
+are described below.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Copy part of the source tree to the ACK users tree
+(include files, manual pages, documentation, et cetera).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Calling the &quot;TakeAction&quot; script. All these
+Makefiles do not have to be called separately. We wrote a
+shell script calling the make&rsquo;s needed to install the
+whole Kit. This script consists of the file
+$SRC_HOME/TakeAction and a few files called Action in some
+configuration directories. The Action files describe in a
+very simple form which actions have to be performed in which
+directories. The default action is to start &quot;make
+install &amp;&amp; make clean&quot;. The output of each make
+is diverted to a file called &quot;Out&quot; in the same
+directory as the make was started in. If the make was
+successful (return code 0) the Out file is removed and the
+script TakeAction produces a small message indicating that
+it succeeded in fulfilling its goal. If the make was not
+successful (any other return code) the Out file is left
+alone for further examination and the script TakeAction
+produces a small message indicating that it failed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>For some programs the scripts already know they
+can&rsquo;t be installed on the local type of system. In
+that case they produce a message &quot;Sorry, .....&quot;
+and happily proceed with further installation commands.</p>
+</td>
+</table>
+
+<p>Installation of the Kit might take anything from a few
+hours to more than a day, depending on the speed of the
+local machine and what must be installed.</p>
+
+<p>If the installation succeeded, the Kit is ready to be
+used. Read section 6 and the manuals provided with the Kit
+(in the $TARGET_HOME/man directory) on how to use it.</p>
+<a name="5.1. Problems"></a>
+<h2>5.1. Problems</h2>
+<a name="5.1.1. on Unisoft m68000 systems."></a>
+<h2>5.1.1. on Unisoft m68000 systems.</h2>
+
+<p>The Unisoft C compiler has a bug which impedes the
+correct translation of the peephole optimizer. For a more
+detailed description of this phenomenon see the file
+&quot;$SRC_HOME/mach/m68k2/Unisoft_bug&quot;. (This
+observation was made in 1985 or so, so it is probably no
+longer true).</p>
+<a name="5.1.2. with backends"></a>
+<h2>5.1.2. with backends</h2>
+
+<p>The backends for the PDP11, VAX, Motorola 68000 and
+68020, SPARC, Intel 8086, and Intel 80386 have been heavily
+used by ourselves and are well tested. The backends for the
+other machines are known to run our own test programs, but
+might reveal errors when more heavily used.</p>
+<a name="5.2. An example output of TakeAction."></a>
+<h2>5.2. An example output of TakeAction.</h2>
+<pre>    System definition -- done
+    EM definition library -- done
+    C utilities -- done
+    Flex lexical analyzer generator -- done
+    Yacc parser generator -- done
+    system-call interface module -- done
+        .
+        .
+        .
+    EM Global optimizer -- done
+    ACK archiver -- done
+    Program &rsquo;ack&rsquo; -- done
+    Bootstrap for backend tables -- done
+    Bootstrap for newest form of backend tables -- done
+        .
+        .
+        .
+    C frontend -- done
+    ANSI-C frontend -- done
+    ANSI-C preprocessor -- done
+    ANSI-C header files -- done
+    Failed for LINT C program checker, see lang/cem/lint/Out
+    Pascal frontend -- done
+    Basic frontend -- done
+        .
+        .
+        .
+    Vax 4-4 assembler -- done
+    Vax 4-4 backend -- done
+    Vax target optimizer -- done
+    ACK a.out to VAX a.out conversion program -- done
+    Sorry, Vax code expander library can only be made on vax* systems
+    Vax 4-4 EM library -- done
+    Vax 4-4 debugger support library -- done
+    Vax 4-4 etext,edata,end library -- done
+    Vax 4-4 systemcall interface -- done
+        .
+        .
+        .
+
+</pre>
+
+<p>The lines starting with &quot;Sorry, &quot; indicate
+that certain programs cannot be translated on the local
+machine. The lines starting with &quot;Failed for&quot;
+indicate that certain programs/libraries were expected to,
+but did not compile. In this example, the installation of
+LINT failed. To repeat a certain part of the installation,
+look in the Action file, which resides in the root of the
+configuration tree, for the directory in which that part is
+to be found. If that directory contains an Action file issue
+the command &quot;sh $CONFIG/bin/TakeAction&quot;, otherwise
+type &quot;make install&quot;.</p>
+<a name="6. Commands"></a>
+<h2>6. Commands</h2>
+
+<p>The following commands are available in the
+$TARGET_HOME/bin directory after compilation of the Kit:</p>
+
+<p><i>ack</i>, <i>acc</i>, <i>abc</i>, <i>apc</i>,
+<i>ocm</i>, <i>m2</i>, <i>f2c</i> and their links</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>the names mentioned here can be used to compile Pascal,
+C, etc... programs. Most of the links can be used to
+generate code for a particular machine. See also the section
+about &quot;Machines&quot;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><i>arch</i></p>
+</td>
+<td width="20%"></td>
+<td width="72%">
+
+<p>the archiver used for the EM- and universal
+assembler/loader.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><i>aal</i></p>
+</td>
+<td width="22%"></td>
+<td width="68%">
+
+<p>the archiver used for ACK objects.</p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><i>em</i></p>
+</td>
+<td width="24%"></td>
+<td width="72%">
+
+<p>this program selects a interpreter to execute an e.out
+file. Interpreters exist for PDP-11 and Motorola 68000
+systems.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><i>eminform</i></p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>the program to unravel the post-mortem information of
+the EM interpretator for the PDP-11.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><i>LLgen</i></p>
+</td>
+<td width="18%"></td>
+<td width="54%">
+
+<p>the LL(1) parser generator.</p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><i>ack_sys</i></p>
+</td>
+<td width="14%"></td>
+<td width="72%">
+
+<p>a shell script producing an identification of the target
+system. Used by some utilities to determine what is, and
+what is not feasible on the target system.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><i>march</i></p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>a shell script used while compiling libraries.</p>
+</td>
+</table>
+
+<p><i>asize</i>, <i>anm</i>, <i>astrip</i></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>do the same as <i>size</i>, <i>nm</i> and <i>strip</i>,
+but for ACK object format.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><i>mkdep</i></p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>a dependency generator for makefiles.</p>
+</td>
+</table>
+
+<p><i>cid</i>, <i>prid</i>, <i>cclash</i></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>some utilities for handling name clashes in C programs.
+Some systems have C-compilers with only 7 or 8 characters
+significant in identifiers.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><i>tabgen</i></p>
+</td>
+<td width="16%"></td>
+<td width="72%">
+
+<p>a utility for generating character tables for
+C-programs.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><i>int</i></p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>an EM interpreter. This one is written in C, and is very
+useful for checking out programs.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><i>grind</i></p>
+</td>
+<td width="18%"></td>
+<td width="72%">
+
+<p>a source level debugger for C, ANSI-C, Modula-2 and
+Pascal.</p>
+</td>
+</table>
+
+<p><i>afcc</i>, <i>afm2</i>, <i>afpc</i></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>these are ACK-compatible fast C, Modula-2 and Pascal
+compilers, available for M68020, VAX and Intel 80386
+systems. They compile very fast, but produce slow code.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><i>fcc</i></p>
+</td>
+<td width="22%"></td>
+<td width="72%">
+
+<p>this is a cc-compatible fast C compiler, available on
+SUN-3 and VAX systems. It compiles very fast, but produces
+slow code.</p>
+</td>
+</table>
+
+<p>We currently make the Kit available to our users by
+telling them that they should include the $TARGET_HOME/bin
+directory in their PATH shell variable. The programs will
+still work when moved to a different directory or linked to.
+Copying should preferably be done with tar, since links are
+heavily used. Renaming of the programs linked to <i>ack</i>
+will not always produce the desired result. This program
+uses its call name as an argument. Any call name not being
+<i>cc</i>, <i>acc</i>, <i>abc</i>, <i>pc</i>, <i>f2c</i>,
+<i>ocm</i>, <i>m2</i>, or <i>apc</i> will be interpreted as
+the name of a &rsquo;machine description&rsquo; and the
+program will try to find a description file with that name.
+The installation process will only touch the utilities in
+the $TARGET_HOME/bin directory, not copies of these
+utilities.</p>
+<a name="7. Machines"></a>
+<h2>7. Machines</h2>
+
+<p>Below is a table with entries for all commands in the
+bin directory used to (cross)compile for a particular
+machine. The name in the first column gives the name in the
+bin directory. The column headed dir indicates which
+subdirectories of $TARGET_HOME/lib and/or
+$TARGET_HOME/lib.bin are needed for compilation. The column
+head i/p contains the integer and pointer size used in units
+of bytes. The subdirectories with the same name in mach
+contain the sources. A * in the column headed
+&rsquo;fp&rsquo; indicates that floating point can be used
+for that particular machine. A + in that column indicates
+that floating point is available under the &rsquo;-fp&rsquo;
+option. In this case, software floating point emulation is
+used.</p>
+
+<p align=center><img src="grohtml-96856.png"></p>
+
+<p>The commands <b>em22</b>, <b>em24</b> and <b>em44</b>
+produce e.out files with EM machine code which must be
+interpreted. The Kit contains three interpreters: one
+running under PDP 11/V7 UNIX, one for the M68000, running
+under the PMDS system, Sun systems, the Mantra system, etc,
+and a portable one, written in C. The first one can only
+interpret 2/2 e.out files, the second takes 2/4 and 4/4
+files, and the last one takes 2/2, 2/4 and 4/4. The PDP 11
+interpreter executes floating point instructions.</p>
+
+<p>The program <b>$TARGET_HOME/bin/em</b> calls the
+appropriate interpreter. The interpreters are looked for in
+the em22, em24 and em44 subdirectories of
+$TARGET_HOME/lib.bin. The third interpreter is available as
+the program <b>$TARGET_HOME/bin/int</b> in the bin
+directory.</p>
+<a name="8. Compilation on a different machine."></a>
+<h2>8. Compilation on a different machine.</h2>
+
+<p>The installation mechanism of the Kit is supposed to be
+portable across <small>UNIX</small> machines, so the Kit can
+be installed and used as a cross-compiler for the languages
+it supports on any <small>UNIX</small> machine. The presence
+of most <small>UNIX</small> utilities is essential for
+compilation. A few of the programs certainly needed are: sh,
+C-compiler, sed, ed, make, and awk.</p>
+<a name="8.1. Backend"></a>
+<h2>8.1. Backend</h2>
+
+<p>The existence of a backend with a system call library
+for the target system is essential for producing executable
+files for that system. Rewriting the system call library if
+the one supplied does not work on the target system is
+fairly straightforward. If no backend exists for the target
+CPU type, a new backend has to be written which is a major
+undertaking.</p>
+<a name="8.2. Universal assembler/loader, link editor"></a>
+<h2>8.2. Universal assembler/loader, link editor</h2>
+
+<p>For most machines, the description files in
+$TARGET_HOME/lib/*/descr use our universal assembler and our
+link editor. The load file produced is not directly usable
+in any system known to us, but has to be converted before it
+can be put to use. The <i>cv</i> programs convert our a.out
+format into executable files. The <i>dl</i> programs present
+for some machines unravel our a.out files and transmit
+commands to load memory to a microprocessor over a serial
+line. The file $TARGET_HOME/man/man5/ack.out.5 contains a
+description of the format of the universal assembler load
+file. It might be useful to those who wish or need to write
+their own conversion programs. Also, a module is included to
+read and write our a.out format. See
+$TARGET_HOME/man/man3/object.3.</p>
+<a name="9. Options"></a>
+<h2>9. Options</h2>
+<a name="9.1. Default machine"></a>
+<h2>9.1. Default machine</h2>
+
+<p>There is one important option in
+$TARGET_HOME/config/local.h. The utility <i>ack</i> uses a
+default machine name when called as <i>acc</i>, <i>cc</i>,
+<i>abc</i>, <i>apc</i>, <i>pc</i>, <i>ocm</i>, <i>m2</i>,
+<i>f2c</i>, or <i>ack</i>. The machine name used by default
+is determined by the definition of ACKM in
+$TARGET_HOME/config/local.h. The Kit is distributed with
+&quot;sun3&quot; as the default machine, but the shell
+script &quot;first&quot; in the directory &quot;first&quot;
+alters this to suit the target system. There is nothing
+against using the Kit as a cross-compiler and by default
+produce code that can&rsquo;t run on the local system.</p>
+<a name="9.2. Pathnames"></a>
+<h2>9.2. Pathnames</h2>
+
+<p>Absolute path names are concentrated in
+&quot;$TARGET_HOME/config/em_path.h&quot;. Only the
+utilities <i>ack</i>, <i>flex</i>, and <i>LLgen</i> use
+absolute path names to access files in the Kit. The tree is
+distributed with /usr/em as the working directory. The
+definition of EM_DIR in em_path.h should be altered to
+specify the root directory for the Compiler Kit binaries on
+the local system ($TARGET_HOME). This is done automatically
+by the shell script &quot;first&quot; in the directory
+&quot;first&quot;. Em_path.h also specifies which directory
+should be used for temporary files. Most programs from the
+Kit do indeed use that directory although some remain
+stubborn and use /tmp.</p>
+
+<p>The shape of the tree should not be altered lightly
+because most Makefiles and the utility <i>ack</i> know the
+shape of the ACK tree. The knowledge of the utility
+<i>ack</i> about the shape of the tree is concentrated in
+the files in the directory $TARGET_HOME/lib/*/descr and
+$TARGET_HOME/lib/descr/*.</p>
+<a name="10. Makefiles"></a>
+<h2>10. Makefiles</h2>
+
+<p>Most directories contain a &quot;proto.make&quot;, from
+which a Makefile is derived. Apart from commands applying to
+that specific directory these files all recognize a few
+special commands. When called with one of these they will
+apply the command to their own directory. The special
+commands are:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>install</p>
+</td>
+<td width="26%"></td>
+<td width="60%">
+
+<p>recompile and install all binaries and libraries.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="39%"></td>
+<td width="60%">
+<p>Some Makefiles allow errors to occur in the programs they
+call. They ignore such errors and notify the user with the
+message &quot;~....... error code n: ignored&quot;. Whenever
+such a message appears in the output it can be ignored.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>cmp</p>
+</td>
+<td width="34%"></td>
+<td width="60%">
+
+<p>recompile all binaries and libraries and compare them to
+the ones already installed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>pr</p>
+</td>
+<td width="36%"></td>
+<td width="60%">
+
+<p>print the sources and documentation on the standard
+output.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>opr</p>
+</td>
+<td width="34%"></td>
+<td width="26%">
+
+<p>make pr | opr</p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="39%"></td>
+<td width="60%">
+<p>Opr should be an off-line printer daemon. On some systems
+it exists under another name e.g. lpr. The easiest way to
+call such a spooler is using a shell script with the name
+opr that calls lpr. This script should be placed in /usr/bin
+or $TARGET_HOME/bin or one of the directories in the PATH
+environment variable.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>clean</p>
+</td>
+<td width="30%"></td>
+<td width="60%">
+
+<p>remove all files not needed for day-to-day use, that is
+binaries not in $TARGET_HOME/bin or $TARGET_HOME/lib.bin,
+object files etc.</p>
+</td>
+</table>
+
+<p>Example:</p>
+<pre>     make install
+</pre>
+
+<p>given as command in a configuration directory will cause
+compilation of all programs in the directory and copying of
+the results to the $TARGET_HOME/bin and $TARGET_HOME/lib.bin
+directories.</p>
+<a name="11. Testing"></a>
+<h2>11. Testing</h2>
+
+<p>Test sets are available in Pascal, C, Basic and EM
+assembly:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>EM</p>
+</td>
+<td width="12%"></td>
+<td width="84%">
+
+<p>the directory $SRC_HOME/emtest contains a few EM test
+programs. The EM assembly files in these tests must be
+transformed into load files. These tests use the LIN and NOP
+instructions to mark the passing of each test. The NOP
+instruction prints the current line number during the test
+phase. Each test notifies its correctness by calling LIN
+with a unique number followed by a NOP which prints this
+line number. The test finishes normally with 0 as the last
+number printed In all other cases a bug showed its
+existence.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>Pascal</p>
+</td>
+<td width="4%"></td>
+<td width="84%">
+
+<p>the directory $SRC_HOME/lang/pc/test contains a few
+Pascal test programs. All these programs print the number of
+errors found and a identification of these errors.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="23%"></td>
+<td width="76%">
+<p>We also tested Pascal with the Validation Suite. The
+Validation Suite is a collection of more than 200 Pascal
+programs, designed by Brian Wichmann and Arthur Sale to test
+Pascal compilers. We are not allowed to distribute it, but a
+copy may be requested from</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<pre>     Richard J. Cichelli
+     A.N.P.A.
+     1350 Sullivan Trail
+     P.O. Box 598
+     Easton, Pennsylvania 18042
+     USA
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>C</p>
+</td>
+<td width="14%"></td>
+<td width="84%">
+
+<p>the sub-directories in $SRC_HOME/lang/cem/ctest contain
+C test programs. The idea behind these tests is: if there is
+a program called xx.c, compile it into xx.cem. Run it with
+standard output to xx.cem.r, compare this file to xx.cem.g,
+a file containing the &rsquo;ideal&rsquo; output. Any
+differences will point to implementation differences or
+bugs. Giving the command &quot;run gen&quot; or plain
+&quot;run&quot; starts this process. The differences will be
+presented on standard output. The contents of the result
+files depend on the word size, the xx.cem.g files on the
+distribution are intended for a 32-bit machine.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>Basic</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>the directory $SRC_HOME/lang/basic/test contains some
+forty Basic programs. Not all of these programs are correct,
+some have syntactic errors, some simply don&rsquo;t work.
+The Makefile in that directory attempts to compile and run
+these tests. If it compiles its output is compared to a file
+with suffix .g which contains the output to be expected. The
+make should be started with its standard input diverted to
+/dev/null. An example of the output of a make is present in
+the file Out.std.</p>
+</td>
+</table>
+<a name="12. Documentation"></a>
+<h2>12. Documentation</h2>
+
+<p>After installation, the manual pages for Amsterdam
+Compiler Kit can be found in the $TARGET_HOME/man directory.
+Also, the following documents are provided in the
+$TARGET_HOME/doc directory:</p>
+
+<p align=center><img src="grohtml-96857.png"></p>
+
+<p>Use the Makefile to get readable copies.</p>
+
+<p>Good luck.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/install.pdf b/src/olddocs/install.pdf
new file mode 100644 (file)
index 0000000..618817d
Binary files /dev/null and b/src/olddocs/install.pdf differ
diff --git a/src/olddocs/int.html b/src/olddocs/int.html
new file mode 100644 (file)
index 0000000..39552c6
--- /dev/null
@@ -0,0 +1,3910 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:37 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The EM Interpreter</title>
+</head>
+<body>
+
+<h1 align=center>The EM Interpreter</h1>
+<a href="#1. INTRODUCTION.">1. INTRODUCTION.</a><br>
+<a href="#1.1. The virtual EM machine.">1.1. The virtual EM machine.</a><br>
+<a href="#1.1.1. Instruction Space">1.1.1. Instruction Space</a><br>
+<a href="#1.1.2. The Procedure Table">1.1.2. The Procedure Table</a><br>
+<a href="#1.1.3. The Data Space">1.1.3. The Data Space</a><br>
+<a href="#1.2. Physical lay-out">1.2. Physical lay-out</a><br>
+<a href="#1.3. Speed.">1.3. Speed.</a><br>
+<a href="#2. IMPLEMENTATION DETAILS.">2. IMPLEMENTATION DETAILS.</a><br>
+<a href="#2.1. Stack manipulation and start-up">2.1. Stack manipulation and start-up</a><br>
+<a href="#2.1.1. The anomalous value of the ML register">2.1.1. The anomalous value of the ML register</a><br>
+<a href="#2.1.2. The absence of an initial Return Status Block">2.1.2. The absence of an initial Return Status Block</a><br>
+<a href="#2.2. Floating point numbers.">2.2. Floating point numbers.</a><br>
+<a href="#2.3. Pointers.">2.3. Pointers.</a><br>
+<a href="#2.3.1. Pointer arithmetic.">2.3.1. Pointer arithmetic.</a><br>
+<a href="#2.3.2. Null pointer.">2.3.2. Null pointer.</a><br>
+<a href="#2.4. Function Return Area (FRA).">2.4. Function Return Area (FRA).</a><br>
+<a href="#2.5. Environment interaction.">2.5. Environment interaction.</a><br>
+<a href="#2.5.1. Traps and interrupts.">2.5.1. Traps and interrupts.</a><br>
+<a href="#2.5.2. Monitor calls.">2.5.2. Monitor calls.</a><br>
+<a href="#2.6. Internal arithmetic.">2.6. Internal arithmetic.</a><br>
+<a href="#2.7. Shadow bytes implementation.">2.7. Shadow bytes implementation.</a><br>
+<a href="#2.8. Return Status Block (RSB)">2.8. Return Status Block (RSB)</a><br>
+<a href="#2.9. Operand access.">2.9. Operand access.</a><br>
+<a href="#2.9.1. The Dispatch Table, Method 1.">2.9.1. The Dispatch Table, Method 1.</a><br>
+<a href="#2.9.2. Intelligent Routines, Method 2.">2.9.2. Intelligent Routines, Method 2.</a><br>
+<a href="#2.9.3. Intelligent Calls, Method 3.">2.9.3. Intelligent Calls, Method 3.</a><br>
+<a href="#2.9.4. Static Evaluation.">2.9.4. Static Evaluation.</a><br>
+<a href="#2.10. Disassembly.">2.10. Disassembly.</a><br>
+<a href="#3. THE LOGGING MACHINE.">3. THE LOGGING MACHINE.</a><br>
+<a href="#3.1. Implementation.">3.1. Implementation.</a><br>
+<a href="#3.2. Controlling the Logging machine.">3.2. Controlling the Logging machine.</a><br>
+<a href="#3.3. Dumps.">3.3. Dumps.</a><br>
+<a href="#3.4. Forking.">3.4. Forking.</a><br>
+<a href="#List of Warnings.">List of Warnings.</a><br>
+<a href="#How to use the interpreter">How to use the interpreter</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Eddo de Groot<br>
+Leo van den Berge<br>
+Dick Grune</i><br>
+Faculteit Wiskunde en Informatica<br>
+Vrije Universiteit, Amsterdam</p>
+
+<p>This document describes the implementation and usage of
+a new interpreter for the EM machine language. This
+interpreter implements the full EM machine and can be
+helpful to people writing new front-ends. Moreover, it can
+be used as a thorough testing and debugging tool by anyone
+familiar with the EM language.</p>
+
+<p>A list of all warnings is given in appendix A; appendix
+B is a simple tutorial.</p>
+<a name="1. INTRODUCTION."></a>
+<h2>1. INTRODUCTION.</h2>
+
+<p>This document describes an EM interpreter which does
+extensive checking. The interpreter exists in two versions:
+the normal version with full checking and debugging
+facilities, and a fast stripped version that does
+interpretation only. This document assumes that the full
+version is used.</p>
+
+<p>First the virtual EM machine embodied by the interpreter
+(called <b>int</b>) is described, followed by some remarks
+on performance. The second section gives some specific
+implementation decisions. Section three explains the usage
+of the built-in debugging tool.</p>
+
+<p>Appendix A gives an overview of the various warnings
+<b>int</b> gives, with possible causes and solutions.
+Appendix B is a simple tutorial on the use of <b>int</b>. A
+separate manual page exists.</p>
+
+<p>The document assumes a good understanding of what EM is
+and what the assembly code looks like [1]. Notions like
+&rsquo;procedure descriptor&rsquo;, &rsquo;mini&rsquo;,
+&rsquo;shortie&rsquo; etc. are not explained. In the sequel,
+any word in <i>this font</i> refers to the name of a
+variable, constant, function or whatever, used in the source
+code under the same name.</p>
+
+<p>To avoid confusion: <b>int</b> interprets EM machine
+language (e.out files), <i>not</i> the assembly language (.e
+files) and <i>not</i> the compact code (.k files).</p>
+<a name="1.1. The virtual EM machine."></a>
+<h2>1.1. The virtual EM machine.</h2>
+
+<p>The memory layout of the virtual EM machine represented
+by the interpreter differs in details from the description
+in [1]. Virtual memory is split up into two separate spaces:
+one space containing the instructions, the other all the
+data, including stack and heap (D-space). The procedure
+descriptors are preprocessed and stored in a separate array,
+<i>proctab[]</i>. Both spaces start off at address 0. This
+is possible because pointers in the two different spaces are
+distinguishable by context (and shadow-bytes: see 2.6).</p>
+<a name="1.1.1. Instruction Space"></a>
+<h2>1.1.1. Instruction Space</h2>
+
+<p>Figure 1 shows the I-space, together with the position
+of some important EM registers.</p>
+<pre>                      NEXT --&gt;  |________________|  &lt;-- DB    \
+                                |                |            |
+                                |                |            |  T
+                                |                |  &lt;-- PC    |
+                                |     Program    |            |  e
+                                |                |            |
+                                |      Text      |            |  x
+                                |                |            |
+                                |                |            |  t
+                         0 --&gt;  |________________|  &lt;--(PB)   /
+
+</pre>
+
+<p align=center><i>Fig 1. Virtual instruction space
+(I-space).</i></p>
+
+<p>The I-space is just big enough to contain all the
+instructions. The size needed for the program text
+(<i>NTEXT</i>) is found from the header-bytes of the
+loadfile. Legal values for the program counter (<i>PC</i>)
+consist of all addresses in the range from 0 through
+<i>NTEXT</i> &minus; 1. If the <i>PC</i> is made to point to
+an illegal address, a trap will occur.</p>
+<a name="1.1.2. The Procedure Table"></a>
+<h2>1.1.2. The Procedure Table</h2>
+
+<p>The <i>NProc</i> constant indicates how many procedure
+descriptors there are in the proctab array. Elements of this
+array contain for each procedure: the number of locals, the
+entry point and the entry point of the textually following
+procedure. This is used in testing the restriction that the
+program counter may not wander from procedure to
+procedure.</p>
+<a name="1.1.3. The Data Space"></a>
+<h2>1.1.3. The Data Space</h2>
+
+<p>Figure 2 shows the layout of the data space, which
+closely conforms to the EM Manual.</p>
+<pre>                                __________________
+            maxaddr(psize) --&gt;  |                |  &lt;-- ML    \
+                                |                |            |  S
+                                |     Locals     |            |  t
+                                |       &amp;        |            |  a
+                                |      RSBs      |            |  c
+                                |                |            |  k
+                                |________________|  &lt;-- SP    /
+                                .                .
+                                .                .
+                                .     Unused     .
+                                .                .
+                                .                .
+                                .                .
+                                .                .
+                                .                .
+                                .     Unused     .
+                                .                .
+                                .                .
+                                |________________|  &lt;-- HP
+                                |                |            \
+                                |      Heap      |            |
+                                |________________|  &lt;-- HB    |
+                                |                |            |  D
+                                |    Arguments   |            |
+                                |     Environ    |            |  a
+                                |  _   _   _   _ |            |
+                                |                |            |  t
+                                |                |            |
+                                |                |            |  a
+                                |   Global data  |            |
+                                |                |            |
+                                |                |            |
+                         0 --&gt;  |________________|  &lt;--(EB)   /
+
+</pre>
+
+<p align=center><i>Fig 2. Virtual dataspace
+(D-space).</i></p>
+
+<p>D-space begins at address 0, and ends at the largest
+address representable by the pointer size (<i>psize</i>)
+being used; for a 2-byte pointer size this maximum address
+is</p>
+<pre>     ((2 ^ 16 &minus; 1) / word size * word size) &minus; 1
+</pre>
+
+<p>for a 4-byte pointer size it is</p>
+<pre>     ((2 ^ 31 &minus; 1) / word size * word size) &minus; 1
+</pre>
+
+<p>(not 2 ^ 32, to allow illegal pointers to be implemented
+in the future). The funny rounding construction is required
+to make ML+1 expressible as the initialisation value of LB
+and SP.</p>
+
+<p>D-space is split into two partitions: Data and Stack
+(indicated by the brackets). The Data partition holds the
+global data area (GDA) and the heap. Its initial size is
+given by the loadfile constant SZDATA. Some space is added
+to it, because arguments and environment are stored here
+also. This total size is static while interpreting. However,
+as the heap may grow during execution (e.g. caused by
+dynamic allocation) this results in a variable size for the
+Data partition. Initially, the size for the Data partition
+is the sum of the space needed by the GDA (including the
+space needed for arguments and environment) and the initial
+heapspace. The lowest legal Data address is 0; the highest
+<i>HP</i> &minus; 1.</p>
+
+<p>The Stack partition holds the stack. It begins at the
+highest available D-space address, and grows towards the low
+addresses, so the Stack partition is of variable size too.
+The lowest legal Stack address is the stackpointer
+(<i>SP</i>), the highest is the memory limit
+(<i>ML</i>).</p>
+<a name="1.2. Physical lay-out"></a>
+<h2>1.2. Physical lay-out</h2>
+
+<p>Each partition is mapped onto a piece of physical memory
+with the same name: <i>text</i> (fig. 1), <i>stack</i> and
+<i>data</i> (fig. 2). These are the storage structures which
+<b>int</b> uses to physically store the contents of the
+virtual EM spaces. Figure 2 thus shows the mapping of
+D-space onto two different physical parts: <i>stack</i> and
+<i>data</i>. The I-space is represented by one physical
+part: <i>text</i>.</p>
+
+<p>Each time more space is needed, the actual partition is
+reallocated, with the new size being computed with the
+formula:</p>
+<pre><i>     new size</i> = 1.5 &times; (<i>old size</i> + <i>extra</i>)
+</pre>
+
+<p><i>extra</i> is the number of bytes exceeding the <i>old
+size</i>. One can prove that using this method, there is a
+linear relationship between allocation time and needed
+partition size.</p>
+
+<p>A virtual D-space starting at address 0 is in
+correspondence with the definition in [1], p. 3&minus;6. The
+main reason for having D-space start at address 0, is that
+it induces a one-one correspondence between the heap &minus;
+and GDA addresses on the virtual machine (and hence the
+definition) on one hand, and the offset within the
+<i>data</i> partition on the other. This implies that no
+extra calculation is needed to perform load and storage
+operations.</p>
+
+<p>Some calculation however cannot be avoided, because the
+stack part of the D-space grows downwards by EM definition.
+The first address of the virtual stack (<i>ML</i>, the
+maximum address for the given <i>psize</i>) is mapped onto
+the beginning of the <i>stack</i> partition. When the stack
+grows (i.e. EM addresses get lower), the offset within the
+<i>stack</i> partition gets higher. By taking offset <i>ML
+&minus; A</i> in the stack partition, one obtains the
+physical address corresponding to some virtual EM (stack)
+address <i>A</i>.</p>
+<a name="1.3. Speed."></a>
+<h2>1.3. Speed.</h2>
+
+<p>From several test results with both versions of the
+interpreter, the following may be concluded. The speed of
+the interpreter depends strongly on the type of program
+being interpreted. If plain CPU arithmetic is performed, the
+interpreter is relatively slow (1000 &times; the cc
+version). When stack manipulation is at hand, the
+interpreter is quite fast (100 &times; the cc version).</p>
+
+<p>Most programs however will not be this extreme, so an
+interpretation time of somewhere between 300 and 500 times
+direct execution for a normal program is to be expected.</p>
+
+<p>The fast version runs in about 60% of the time of the
+full version, at the expense of a considerably lower
+functionality. Tallying costs about 10%.</p>
+<a name="2. IMPLEMENTATION DETAILS."></a>
+<h2>2. IMPLEMENTATION DETAILS.</h2>
+
+<p>The pertinent issues are addressed below, in arbitrary
+order.</p>
+<a name="2.1. Stack manipulation and start-up"></a>
+<h2>2.1. Stack manipulation and start-up</h2>
+
+<p>It is not at all easy to start the EM machine with the
+stack in a reasonable and consistent state. One reason is
+the anomalous value of the ML register and another is the
+absence of a proper RSB. It may be argued that the initial
+stack does not have to be in a consistent state, since the
+first instruction proper is only executed after <i>argc</i>,
+<i>argv</i> and <i>environ</i> have been stacked (which
+takes care of the empty stack) and the initial procedure has
+been called (which creates a RSB). We would, however, like
+to preform the stacking of these values and the calling of
+the initial procedure using the normal stack and call
+routines, which again require the stack to be in an
+acceptable state.</p>
+<a name="2.1.1. The anomalous value of the ML register"></a>
+<h2>2.1.1. The anomalous value of the ML register</h2>
+
+<p>All registers in the EM machine point to word
+boundaries, and all of them, except ML, address the
+even-numbered byte at the boundary. The exception has a good
+reason: the even numbered byte at the ML boundary does not
+exist. This problem is not particular to EM but is inherent
+in the number system: the number of N-digit numbers can
+itself not be expressed in an N-digit number, and the number
+of addresses in an N-bit machine will itself not fit in an
+N-bit address. The problem is solved in the interpreter by
+having ML point to the highest word boundary that has bytes
+on either side; this makes ML+1 expressible.</p>
+<a name="2.1.2. The absence of an initial Return Status Block"></a>
+<h2>2.1.2. The absence of an initial Return Status Block</h2>
+
+<p>When the stack is empty, there is no legal value for AB,
+since there are no actuals; LB can be set naturally to ML+1.
+This is all right when the interpreter starts with a call of
+the initial routine which stores the value of LB in the
+first RSB, but causes problems when finally this call
+returns. We want this call to return completely before
+stopping the interpreter, to check the integrity of the last
+RSB; restoring information from it will, however, cause
+illegal values to be stored in LB and AB (ML+1 and
+ML+1+rsbsize, resp.). On top of this, the initial (illegal)
+Procedure Identifier of the running procedure will be
+restored; then, upon restoring the likewise illegal PC will
+cause a check to see if it still is inside the running
+procedure. After a few attempts at writing special cases, we
+have decided that it is possible, but not worth the effort;
+the final (= initial) RSB will not be unstacked.</p>
+<a name="2.2. Floating point numbers."></a>
+<h2>2.2. Floating point numbers.</h2>
+
+<p>The interpreter is capable of working with 4- and 8-byte
+floating point (FP) numbers. In C-terms, this corresponds to
+objects of type float and double respectively. Both types
+fit in a C-double so the obvious way to manipulate these
+entities internally is in doubles. Pushing a 8-byte FP, all
+bytes of the C-double are pushed. Pushing a 4-byte FP causes
+the 4 bytes representing the smallest fraction to be
+discarded.</p>
+
+<p>In EM, floats can be obtained in two different ways: via
+conversion of another type, or via initialization in the
+loadfile. Initialized floats are represented in the loadfile
+by an ASCII string in the syntax of a Pascal real (signed
+UnsignedReal). I.e. a float looks like:</p>
+<pre>     [ <i>Sign</i> ] <i>Digit</i>+ [ . <i>Digit</i>+ ] [ <i>Exp</i> [ <i>Sign</i> ] <i>Digit</i>+ ]                                (G1)
+</pre>
+
+<p>followed by a null byte. Here <i>Sign</i> = {+,
+&minus;}; <i>Digit</i> = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+<i>Exp</i> = {e, E}; [ <i>Anything</i> ] means that
+<i>Anything</i> is optional; and a + means one or more
+times. To accommodate some loose code generators, the actual
+grammar accepted is:</p>
+<pre>     [ <i>Sign</i> ] <i>Digit</i>&lowast; [ . <i>Digit</i>&lowast; ] [ <i>Exp</i> [ <i>Sign</i> ] <i>Digit</i>+ ]                                (G2)
+</pre>
+
+<p>followed by a null byte. Here &lowast; means zero or
+more times. A floating denotation which is in G2 but not in
+G1 draws a warning, one that is not even in G2 causes a
+fatal error.</p>
+
+<p>A string, representing a float which does not fit in a
+double causes a warning to be given. In that case, the
+returned value will be the double 0.0.</p>
+
+<p>Floating point arithmetic is handled by some simple
+routines, checking for over/underflow, and returning
+appropriate values in case of an ignored error.</p>
+
+<p>Since not all C compilers provide floating point
+operations, there is a compile time flag NOFLOAT, which, if
+defined, suppresses the use of all fp operations in the
+interpreter. The resulting interpreter will still load EM
+files with floats in the global data area (and ignore them)
+but will give a fatal error upon attempt to execute a
+floating point instruction; consequently code involving
+floating point operations can be run as long as the actual
+instructions are avoided.</p>
+<a name="2.3. Pointers."></a>
+<h2>2.3. Pointers.</h2>
+
+<p>The following sub-sections both deal with problems
+concerning pointers. First, something is said about pointer
+arithmetic in general. Then, the null-pointer problem is
+dealt with.</p>
+<a name="2.3.1. Pointer arithmetic."></a>
+<h2>2.3.1. Pointer arithmetic.</h2>
+
+<p>Strictly speaking, pointer arithmetic is defined only
+within a <b>fragment</b>. From the explanation of the term
+fragment however (as given in [1], page 3), it is not quite
+clear what a fragment should look like from an
+interpreter&rsquo;s point of view. For this reason we
+introduced the term <b>segment</b>, bordering the various
+areas within which pointer arithmetic is allowed. Every
+stack-frame is a segment, and so are the global data area
+(GDA) and the heap area. Thus, the number of segments varies
+over time, and at some point in time is given by the number
+of currently active stack-frames (#CAL + #CAI &minus; #RET
+&minus; #RTT) plus 2 (gda, heap). Pointers in the area
+between heap and stack (which is inaccessible by
+definition), are assumed to be in the heap segment.</p>
+
+<p>The interpreter, while building a new stack-frame (i.e.
+segment), stores the value of the last ActualBase in a
+pointer-array (<i>AB_list[ ]</i>). When a pointer (say
+<i>P</i>) is available for arithmetic, the number of the
+segment where it points (say <i>S <small>P</small></i> ), is
+determined first. Next, the arithmetic is performed,
+followed by a check on the number of the segment where the
+resulting pointer <i>R</i> points (say <i>S
+<small>R</small></i> ). Now, if <i>S <small>P</small> != S
+<small>R</small></i> , a warning is given: <b>Pointer
+arithmetic yields pointer to bad segment</b>.<br>
+It may also be clear now, why the illegal area between heap
+and stack was joined with the heap segment. When calculating
+a new heap pointer (<i>HP</i>), one will obtain intermediate
+results being pointers in this area just before it is made
+legal. We do not want error messages all of the time, just
+because someone is allocating space in the heap.</p>
+
+<p>A similar treatment is given to the pointers in the SBS
+instruction; they have to point into the same fragment for
+subtraction to be meaningful.</p>
+
+<p>The length of the <i>AB_list[ ]</i> is initially 100,
+and it is reallocated in the same way the dynamically
+growing partitions are (see 1.1).</p>
+<a name="2.3.2. Null pointer."></a>
+<h2>2.3.2. Null pointer.</h2>
+
+<p>Because the EM language lacks an instruction for loading
+a null pointer, most programs solve this problem by loading
+a pointer-sized integer of value zero, and using this as a
+null pointer (this is also proposed in [1]). <b>Int</b>
+allows this, and will not complain. A warning is given
+however, when an attempt is made to add something to a null
+pointer (i.e. the pointer-sized integer zero).</p>
+
+<p>Since many programming languages use a pointer to
+location 0 as an illegal value, it is desirable to detect
+its use. The big problem is though that 0 is a perfectly
+legal EM address; address 0 holds the current line number in
+the source file. It may be freely read but is written only
+by means of the LIN instruction. This allows us to declare
+the area consisting of the line number and the file name
+pointer to be read-only memory. Thus a store will be caught
+(and result in a warning) but a read will succeed (and yield
+the EM information stored there).</p>
+<a name="2.4. Function Return Area (FRA)."></a>
+<h2>2.4. Function Return Area (FRA).</h2>
+
+<p>The Function Return Area (<i>FRA[ ]</i>) has a default
+size of 8 bytes; this default can be overridden through the
+use of the <b>&minus;r</b>-option, but cannot be made
+smaller than the size of two pointers, in accordance with
+the remark on page 5 of [1]. The global variable
+<i>FRASize</i> keeps track of how many bytes were stored in
+the FRA, the last time a RET instruction was executed. The
+LFR instruction only works when its argument is equal to
+this size. If not, the FRA contents are loaded anyhow, but
+one of the following warnings is given: <b>Returned function
+result too large</b> (<i>FRASize</i> &gt; LFR size) or
+<b>Returned function result too small</b> (<i>FRASize</i>
+&lt; LFR size).</p>
+
+<p>Note that a C-program, falling through the end of its
+code without doing a proper <i>return</i> or <i>exit()</i>,
+will generate this warning.</p>
+
+<p>The only instructions that do not disturb the contents
+of the FRA are GTO, BRA, ASP and RET. This is expressed in
+the program by setting <i>FRA_def</i> to
+&quot;undefined&quot; in any instruction except these four.
+We realize this is a useless action most of the time, but a
+more efficient solution does not seem to be at hand. If a
+result is loaded when <i>FRA_def</i> is
+&quot;undefined&quot;, the warning: <b>Returned function
+result may be garbled</b> is generated.</p>
+
+<p>Note that the FRA needs a shadow-FRA in order to store
+the shadow information when performing a LFR
+instruction.</p>
+<a name="2.5. Environment interaction."></a>
+<h2>2.5. Environment interaction.</h2>
+
+<p>The EM machine represented by <b>int</b> can communicate
+with the environment in three different ways. A first
+possibility is by means of (UNIX) interrupts; the second by
+executing (relatively) high level system calls (called
+monitor calls). A third means of interaction, especially
+interesting for the debugging programmer, is via internal
+variables set on the command line. The former two
+techniques, and the way they are implemented will be
+described in this section. The latter has been allotted a
+separate section (3).</p>
+<a name="2.5.1. Traps and interrupts."></a>
+<h2>2.5.1. Traps and interrupts.</h2>
+
+<p>Simple user programs will generally not mess around with
+UNIX-signals. In interpreting these programs, the default
+actions will be taken when a signal is received by the
+program: it gives a message and stops running.</p>
+
+<p>There are programs however, which try to handle certain
+signals themselves. In C, this is achieved by the system
+call <i>signal( sig_no, catch )</i>, which calls the
+handling routine <i>catch()</i>, as soon as signal
+<b>sig_no</b> occurs. EM does not provide this call;
+instead, the <i>sigtrp()</i> monitor call is available for
+mapping UNIX signals onto EM traps. This implies that a
+<i>signal()</i> call in a C-program must be translated by
+the EM library routine to a <i>sigtrp()</i> call in EM.</p>
+
+<p>The interpreter keeps an administration of the mapping
+of UNIX-signals onto EM traps in the array
+<i>sig_map[NSIG]</i>. Initially, the signals all have their
+default values. Now assume a <i>sigtrp()</i> occurs, telling
+to map signal <b>sig_no</b> onto trap <b>trap_no</b>. This
+results in:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>setting the relevant array element
+<i>sig_map[sig_no]</i> to <b>trap_no</b> (after saving the
+old value),</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>catching the next to come <b>sig_no</b> signal with the
+handling routine <i>HndlEMSig</i> (by a plain UNIX
+<i>signal()</i> of course), and</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>returning the saved map-value on the stack so the user
+can know the previous trap value onto which <b>sig_no</b>
+was mapped.</p>
+</td>
+</table>
+
+<p>On an incoming signal, the handling routine for signal
+<b>sig_no</b> arms the correct EM trap by calling the
+routine <i>arm_trap()</i> with argument
+<i>sig_map[sig_no]</i>. At the end of the EM instruction the
+proper call of <i>trap()</i> is done. <i>Trap()</i> on its
+turn examines the value of the <i>HaltOnTrap</i> variable;
+if it is set, the interpreter will stop with a message. In
+the normal case of controlled trap handling this bit is not
+on and the interpreter examines the value of the
+<i>TrapPI</i> variable, which contains the procedure
+identifier of the EM trap handling routine. It then
+initiates a call to this routine and performs a
+<i>longjmp()</i> to the main loop to bypass all further
+processing of the instruction that caused the trap.
+<i>TrapPI</i> should be set properly by the library
+routines, through the SIG instruction.</p>
+
+<p>In short:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>A UNIX interrupt is caught by the interpreter.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>A handling routine is called which generates the
+corresponding EM trap (according to the mapping).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>The trap handler calls the corresponding EM routine
+which emulates a UNIX interrupt for the benefit of the
+interpreted program.</p>
+</td>
+</table>
+
+<p>When considering UNIX signals, it is important to notice
+that some of them are real signals, i.e., messages coming
+from outside the program, like DEL and QUIT, but some are
+actually program-caused synchronous traps, like Illegal
+Instruction. The latter, if they happen, are incurred by the
+interpreter itself and consequently are of no concern to the
+interpreted program: it cannot catch them. The present code
+assumes that the UNIX signals between SIGILL (4) and SIGSYS
+(12) are really traps; <i>do_sigtrp()</i> will fail on
+them.</p>
+
+<p>To avoid losing the last line(s) of output files, the
+interpreter should always do a proper close-down, even in
+the presence of signals. To this end, all non-ignored
+genuine signals are initially caught by the interpreter,
+through the routine <i>HndlIntSig</i>, which gives a message
+and preforms a proper close-down. Synchronous trap can only
+be caused by the interpreter itself; they are never caught,
+and consequently the UNIX default action prevails. Generally
+they cause a core dump. Signals requested by the interpreted
+program are caught by the routine <i>HndlEMSig</i>, as
+explained above.</p>
+<a name="2.5.2. Monitor calls."></a>
+<h2>2.5.2. Monitor calls.</h2>
+
+<p>For the convenience of the programmer, as many monitor
+calls as possible have been implemented. The list of monitor
+calls given in [1] pages 20/21, has been implemented
+completely, except for <i>ptrace()</i>, <i>profil()</i> and
+<i>mpxcall()</i>. The semantics of <i>ptrace()</i> and
+<i>profil()</i> from an interpreted program is unclear; the
+data structure passed to <i>mpxcall()</i> is non-trivial and
+the system call has low portability and applicability. For
+these calls, on invocation a warning is generated, and the
+arguments which were meant for the call are popped properly,
+so the program can continue without the stack being messed
+up. The errorcode 5 (IOERROR) is pushed onto the stack
+(twice), in order to fake an unsuccessful monitor call. No
+other &minus; more meaningful &minus; errorcode is available
+in the errno-list.</p>
+
+<p>Now for the implemented monitor calls. The returned
+value is zero for a successful call. When something goes
+wrong, the value of the external <i>errno</i> variable is
+pushed, thus enabling the user to find out what the reason
+of failure was. The implementation of the majority of the
+monitor calls is straightforward. Those working with a
+special format buffer, (e.g. <i>ioctl()</i>, <i>time()</i>
+and <i>stat()</i> variants), need some extra attention. This
+is due to the fact that working with varying word/pointer
+size combinations may cause alignment problems.</p>
+
+<p>The data structure returned by the UNIX system call
+results from C code that has been translated with the
+regular C compiler, which, on the VAX, happens to be a 4-4
+compiler. The data structure expected by the interpreted
+program conforms to the translation by <b>ack</b> of the
+pertinent include file. Depending on the exact call of
+<b>ack</b>, sizes and alignment may differ.</p>
+
+<p>An example is in order. The EM MON 18 instruction in the
+interpreted program leads to a UNIX <i>stat()</i> system
+call by the interpreter. This call fills the given struct
+with stat information, the contents and alignments of which
+are determined by the version of UNIX and the used C
+compiler, resp. The interpreter, like any program wishing to
+do system calls that fill structs, has to be translated by a
+C compiler that uses the appropriate struct definition and
+alignments, so that it can use, e.g., <i>stab.st_mtime</i>
+and expect to obtain the right field. This struct cannot be
+copied directly to the EM memory to fulfill the MON
+instruction. First, the struct may contain extraneous,
+system-dependent fields, pertaining, e.g., to symbolic
+links, sockets, etc. Second, it may contain holes, due to
+alignment requirements. The EM program runs on an EM
+machine, knows nothing about these requirements and expects
+UNIX Version 7 fields, with offsets as determined by the
+em22, em24 or em44 compiler, resp. To do the conversion, the
+interpreter has a built-in table of the offsets of all the
+fields in the structs that are filled by the MON
+instruction. The appropriate fields from the result of the
+UNIX <i>stat()</i> are copied one by one to the appropriate
+positions in the EM memory to be filled by MON 18.</p>
+
+<p>The <i>ioctl()</i> call (MON 54) poses additional
+problems. Not only does it have a second argument which is a
+pointer to a struct, the type of which is dynamically
+determined, but its first argument is an opcode that varies
+considerably between the versions of UNIX. To solve the
+first problem, the interpreter examines the opcode (request)
+and treats the second argument accordingly. The second
+problem can be solved by translating the UNIX Version 7
+<i>ioctl()</i> request codes to their proper values on the
+various systems. This is, however, not always useful, since
+some EM run-time systems use the local request codes. There
+is a compile-time flag, V7IOCTL, which, if defined, will
+restrict the <i>ioctl()</i> call to the version 7 request
+codes and emulate them on the local system; otherwise the
+request codes of the local system will be used (as far as
+implemented).</p>
+
+<p>Minor problems also showed up with the implementation of
+<i>execve()</i> and <i>fork()</i>. <i>Execve()</i> expects
+three pointers on the stack. The first points to the name of
+the program to be executed, the second and third are the
+beginnings of the <b>argv</b> and <b>envp</b> pointer arrays
+respectively. We cannot pass these pointers to the system
+call however, because the EM addresses to which they point
+do not correspond with UNIX addresses. Moreover, (it is not
+very likely to happen but) what if someone constructs a
+program holding the contents for one of these pointers in
+the stack? The stack is implemented upside down, so passing
+the pointer to <i>execve()</i> causes trouble for this
+reason too. The only solution was to copy the pointer
+contents completely to fresh UNIX memory, constructing
+vectors which can be passed to the system call. Any
+impending memory fault while making these copies results in
+failure of the system call, with <i>errno</i> set to
+EFAULT.</p>
+
+<p>The implementation of the <i>fork()</i> call faced us
+with problems concerning IO-channels. Checking messages (as
+well as logging) must be divided over different files.
+Otherwise, these messages will coincide. This problem was
+solved by post-fixing the default message file
+<b>int.mess</b> (as well as the logging file <b>int.log</b>)
+with an automatically leveled number for every new forked
+process. Children of the original process do their
+diagnostics in files with postfix 1,2,3 etc. Second
+generation processes are assigned files numbered 11, 12, 21
+etc. When 6 generations of processes exist at one moment,
+the seventh will get the same message file as the sixth, for
+the length of the filename will become too long.</p>
+
+<p>Some of the monitor calls receive pointers (addresses)
+from to program, to be passed to the kernel; examples are
+the struct stat for <i>stat()</i>, the area to be filled for
+<i>read()</i>, etc. If the address is wrong, the kernel does
+not generate a trap, but rather the system call returns with
+failure, while <i>errno</i> is set to EFAULT. This is
+implemented by consistent checking of all pointers in the
+MON instruction.</p>
+<a name="2.6. Internal arithmetic."></a>
+<h2>2.6. Internal arithmetic.</h2>
+
+<p>Doing arithmetic on signed integers, the smallest
+negative integer (<i>minsint</i>) is considered a legal
+value. This is in contradiction with the EM Manual [1], page
+14, which proposes using <i>minsint</i> for uninitialized
+integers. The shadow bytes already check for uninitialized
+integers however, so we do not need this special illegal
+value. Although the EM Manual provides two traps, for
+undefined integers and floats, undefined objects occur so
+frequently (e.g. in block copying partially initialized
+areas) that the interpreter just gives a warning.</p>
+
+<p>Except for arithmetic on unsigneds, all arithmetic
+checks for overflow. The value that is pushed on the stack
+after an overflow occurs depends on the UNIX behavior with
+regard to that particular calculation. If UNIX would not
+accept the calculation (e.g. division by zero), a zero is
+pushed as a convention. Illegal computations which UNIX does
+accept in silence (e.g. one&rsquo;s complement of
+<i>minsint</i>), simply push the UNIX-result after giving a
+trap message.</p>
+<a name="2.7. Shadow bytes implementation."></a>
+<h2>2.7. Shadow bytes implementation.</h2>
+
+<p>A great deal of run-time checking is performed by the
+interpreter (except if used in the fast version). This
+section gives all details about the shadow bytes. In order
+to keep track of information about the contents of D-space
+(stack and global data area), there is one shadow-byte for
+each byte in these spaces. Each bit in a shadow-byte
+represents some piece of information about the contents of
+its corresponding &rsquo;sun-byte&rsquo;. All bits off
+indicates an undefined sun-byte. One or more bits on always
+guarantees a well-defined sun-byte. The bits have the
+following meaning:</p>
+
+<p>&bull; bit 0:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p>indicates that the sun-byte is (a part of) an
+integer.</p>
+</td>
+</table>
+
+<p>&bull; bit 1:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p>the sun-byte is a part of a floating point number.</p>
+</td>
+</table>
+
+<p>&bull; bit 2:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p>the sun-byte is a part of a pointer in dataspace.</p>
+</td>
+</table>
+
+<p>&bull; bit 3:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p>the sun-byte is a part of a pointer in the instruction
+space. According to [1] (paragraph 6.4), there are two types
+pointers which must be distinguishable. Conversion between
+these two types is impossible. The shadow-bytes make the
+distinction here.</p>
+</td>
+</table>
+
+<p>&bull; bit 4:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p>protection bit. Indicates that the sun-byte is part of a
+protected piece of memory. There is a protected area in the
+stack, the Return Status Block. The EM machine language has
+no possibility to declare protected memory, as is possible
+in EM assembly (the ROM instruction). The protection bit is,
+however, set for the line number and filename pointer area
+near location 0, to aid in catching references to location
+0.</p>
+</td>
+</table>
+
+<p>&bull; bit 5/6/7:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p>free for later use.</p>
+</td>
+</table>
+
+<p>The shadow bytes are managed by the routines declared in
+<i>shadow.h</i>. The warnings originating from checking
+these shadow-bytes during run-time are various. A list of
+them is given in appendix A, together with suggestions
+(primarily for the C-programmer) where to look for the
+trouble maker(s).</p>
+
+<p>A point to notice is, that once a warning is generated,
+it may be repeated thousands of times. Since repetitive
+warnings carry little information, but consume much file
+space, the interpreter keeps track of the number of times a
+given warning has been produced from a given line in a given
+file. The warning message will be printed only if the
+corresponding counter is a power of four (starting at 1). In
+this way, a logarithmic back-off in warning generation is
+established.</p>
+
+<p>It might be argued that the counter should be kept for
+each (warning, PC value) pair rather than for each (warning,
+file position) pair. Suppose, however, that two instruction
+in a given line would cause the same message regularly; this
+would produce two intertwined streams of identical messages,
+with their counters jumping up and down. This does not seem
+desirable.</p>
+<a name="2.8. Return Status Block (RSB)"></a>
+<h2>2.8. Return Status Block (RSB)</h2>
+
+<p>According to the description in [1], at least the return
+address and the base address of the previous RSB have to be
+pushed when performing a call. Besides these two pointers,
+other information can be stored in the RSB also. The
+interpreter pushes the following items:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p>a pointer to the current filename,</p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="88%">
+
+<p>the current line number (always four bytes),</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="30%">
+
+<p>the Local Base,</p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="74%">
+
+<p>the return address (Program Counter),</p>
+</td>
+<td width="15%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="64%">
+
+<p>the current procedure identifier</p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the RSB code, which distinguishes between initial
+start-up, normal call, returnable trap and non-returnable
+trap (a word-size integer).</p>
+</td>
+</table>
+
+<p>Consequently, the size of the RSB varies, depending on
+word size and pointer size; its value is available as
+<i>rsbsize</i>. When the RSB is removed from the stack (by a
+RET or RTT) the RSB code is under the Stack Pointer for
+immediate checking. It is not clear what should be done if
+RSB code and return instruction do not match; at present we
+give a message and continue, for what it is worth.</p>
+
+<p>The reason for pushing filename and line number is that
+some front-ends tend to forget the LIN and FIL instructions
+after returning from a function. This may result in error
+messages in wrong source files and/or line numbers.</p>
+
+<p>The procedure identifier is kept and restored to check
+that the PC will not move out of the running procedure. The
+PI is an index in the proctab, which tells the limits in the
+text segment of the running procedure.</p>
+
+<p>If the Return Status Block is generated as a result of a
+trap, more is stacked. Before stacking the normal RSB, the
+trap function pushes the following items:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the contents of the entire Function Return Area,</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the number of bytes significant in the above (a
+word-size integer),</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>a word-size flag indicating if the contents of the FRA
+are valid,</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="76%">
+
+<p>the trap number (a word-size integer).</p>
+</td>
+<td width="13%">
+</td>
+</table>
+
+<p>The latter is followed directly by the RSB, and
+consequently acts as the only parameter to the trap
+handler.</p>
+<a name="2.9. Operand access."></a>
+<h2>2.9. Operand access.</h2>
+
+<p>The EM Manual mentions two ways to access the operands
+of an instruction. It should be noticed that the operand in
+EM is often not the direct operand of the operation; the
+operand of the ADI instruction, e.g., is the width of the
+integers to be added, not one of the integers themselves.
+The various operand types are described in [1]. Each opcode
+in the text segment identifies an instruction with a
+particular operand type; these relations are described in
+computer-readable format in a file in the EM tree,
+<i>ip_spec.t</i>.</p>
+
+<p>The interpreter uses the third method. Several other
+approaches can be designed, with increasing efficiency and
+equally increasing complexity. They are briefly treated
+below.</p>
+<a name="2.9.1. The Dispatch Table, Method 1."></a>
+<h2>2.9.1. The Dispatch Table, Method 1.</h2>
+
+<p>When the interpreter starts, it reads the ip_spec.t file
+and constructs from it a dispatch table. This table (of
+which there are actually three, for primary, secondary and
+tertiary opcodes) has 256 entries, each describing an
+instruction with indications on how to decode the operand.
+For each instruction executed, the interpreter finds the
+entry in the dispatch table, finds information there on how
+to access the operand, constructs the operand and calls the
+appropriate routine with the operand as calculated. There is
+one routine for each instruction, which is called with the
+ready-made operand. Method 1 is easy to program but requires
+constant interpretation of the dispatch table.</p>
+<a name="2.9.2. Intelligent Routines, Method 2."></a>
+<h2>2.9.2. Intelligent Routines, Method 2.</h2>
+
+<p>For each opcode there is a separate routine, and since
+an opcode uniquely defines the instruction and the operand
+format, the routine knows how to get the operand; this
+knowledge is built into the routine. Preferably the heading
+of the routine is generated automatically from the ip_spec.t
+file. Operand decoding is immediate, and no dispatch table
+is needed. Generation of the 469 required routines is,
+however, far from simple. Either a generated array of
+routine names or a generated switch statement is used to map
+the opcode onto the correct routine. The switch approach has
+the advantage that parameters can be passed to the
+routines.</p>
+<a name="2.9.3. Intelligent Calls, Method 3."></a>
+<h2>2.9.3. Intelligent Calls, Method 3.</h2>
+
+<p>The call in the switch statement does full operand
+construction, and the resulting operand is passed to the
+routine. This reduces the number of routines to 133, the
+number of EM instructions. Generation of the switch
+statement from ip_spec.t is more complicated, but the
+routine space is much cleaner. This does not give any
+speed-up since the same actions are still required; they are
+just performed in a different place.</p>
+<a name="2.9.4. Static Evaluation."></a>
+<h2>2.9.4. Static Evaluation.</h2>
+
+<p>It can be observed that the evaluation of the operand of
+a given instruction in the text segment will always give the
+same result. It is therefore possible to preprocess the text
+segment, decomposing the instructions into structs which
+contain the address, the instruction code and the operand.
+No operand decoding will be necessary at run-time: all
+operands have been precalculated. This will probably give a
+considerable speed-up. Jumps, especially GTO jumps, will,
+however, require more attention.</p>
+<a name="2.10. Disassembly."></a>
+<h2>2.10. Disassembly.</h2>
+
+<p>A disassembly facility is available, which gives a
+readable but not letter-perfect disassembly of the EM
+object. The procedure structure is indicated by placing the
+indication <b>P[n]</b> at the entry point of each procedure,
+where <b>n</b> is the procedure identifier. The number of
+locals is given in a comment.</p>
+
+<p>The disassembler was generated by the software in the
+directory <i>switch</i> and then further processed by
+hand.</p>
+<a name="3. THE LOGGING MACHINE."></a>
+<h2>3. THE LOGGING MACHINE.</h2>
+
+<p>Since messages and warnings provided by <b>int</b>
+include source code file names and line numbers, they alone
+often suffice to identify the error. If, however, the
+necessity arises, much more extensive debugging information
+can be obtained by activating the the Logging Machine. This
+Logging Machine, which monitors all actions of the EM
+machine, is the subject of this chapter.</p>
+<a name="3.1. Implementation."></a>
+<h2>3.1. Implementation.</h2>
+
+<p>When inspecting the source code of <b>int</b>, many
+lines in the following format will show up:</p>
+<pre>     LOG((&quot;@&lt;<i>letter</i>&gt;&lt;<i>digit</i>&gt; message&quot;, args));
+</pre>
+
+<p>or</p>
+<pre>     LOG((&quot; &lt;<i>letter</i>&gt;&lt;<i>digit</i>&gt; message&quot;, args));
+</pre>
+
+<p>The double parentheses are needed, because <i>LOG()</i>
+is declared as a define, and has a printf-like argument
+structure.</p>
+
+<p>The &lt;<i>letter</i>&gt; classifies the log message and
+corresponds to an entry in the <i>logmask</i>, which holds a
+threshold for each class of messages. The following classes
+exist:</p>
+
+<p align=center><img src="grohtml-107771.png"></p>
+
+<p>When the interpreter reaches a LOG(()) statement it
+scans its first argument; if <i>letter</i> occurs in the
+logmask, and if <i>digit</i> is lower or equal to the
+threshold in the logmask, the message is given. Depending on
+the first character, the message will be preceded by a
+position indication (with the @) or will be printed as is
+(with the space). The <i>letter</i> is determines the
+message class and the <i>digit</i> is used to distinguish
+various levels of logging, with a lower digit indicating a
+more important message. We will call the
+&lt;<i>letter</i>&gt;&lt;<i>digit</i>&gt; combination the
+<b>id</b> of the logging.</p>
+
+<p>In general, the lower the <i>digit</i> following the
+<i>letter</i>, the more important the message. E.g. m5
+reports about unsuccessful monitor calls only, m9 also
+reports about successful monitors (which are obviously less
+interesting). New logging messages can be added to the
+source code on relevant places.</p>
+
+<p>Reasonable settings for the logmask are:</p>
+
+<p align=center><img src="grohtml-107772.png"></p>
+
+<p>An EM interpreter without a Logging Machine can be
+obtained by undefining the macro <i>CHECKING</i> in the file
+<i>checking.h</i>.</p>
+<a name="3.2. Controlling the Logging machine."></a>
+<h2>3.2. Controlling the Logging machine.</h2>
+
+<p>The actions of the Logging Machine are controlled by a
+set of internal variables (one of which is the log mask).
+These variables can be set through assignments on the
+command line, as explained int the manual page <i>int.1</i>,
+q.v. Since there are a great many logging statements in the
+program, of which only a few will be executed in any call of
+the interpreter, it is important to be able to decide
+quickly if a given <i>id</i> has to be checked at all. To
+this end all logging statements are guarded (in the #define)
+by a test for the boolean variable <i>logging</i>. This
+variable will only be set if the command line assignments
+show the potential need for logging (<i>must_log</i>) and
+the instruction count (<i>inr</i>) is at least equal to
+<i>log_start</i> (which derives from the parameter
+<b>LOG</b>).</p>
+
+<p>The log mask can be set by the assignment</p>
+<pre>     &quot;LOGMASK=<i>logstring</i>&quot;
+</pre>
+
+<p>which sets the current logmask to <i>logstring</i>. A
+logstring has the following form:</p>
+<pre>     [ [ <i>letter</i> | <i>letter</i> &minus; <i>letter</i> ]+ <i>digit</i> ]+
+</pre>
+
+<p>E.g. LOGMASK=A&minus;D8x9R7c0hi4 will print all messages
+belonging to loggings with <b>id</b>s:
+<i>A0..A8,B0..B8,C0..C8,D0..D8,x0..x9,R0..R7,c0,h0..h4,i0..i4</i>.</p>
+
+<p>The logging variable STOP can be used to prevent
+run-away logging past the point where the user expects an
+error to occur. STOP=<i>nr</i> will stop the interpreter
+after instruction number <i>nr</i>.</p>
+
+<p>To simplify the use of the logging machine, a number of
+abbreviations have been defined. E.g., AT=<i>nr</i> can be
+thought of as an abbreviation of LOG=<i>nr&minus;1</i>
+STOP=<i>nr+1</i>; this causes three stack dumps, one before
+the suspect instruction, one on it and one after it; then
+the interpreter stops.</p>
+
+<p>Logging results will appear in a special logging file
+(default: <i>int.log</i>).</p>
+<a name="3.3. Dumps."></a>
+<h2>3.3. Dumps.</h2>
+
+<p>There are three routines available to examine the memory
+contents:</p>
+
+<p align=center><img src="grohtml-107773.png"></p>
+
+<p>These routines can be used everywhere in the program to
+examine the contents of memory. The internal variables allow
+the gda and heap to be dumped only once (according to the
+corresponding internal variable). The stack is dumped after
+each instruction if the log mask contains d1 or d2; d2 gives
+a full formatted dump, d1 produces a listing of the Return
+Status Blocks only. An attempt is made to format the stack
+correctly, based on the shadow bytes, which identify the
+Return Status Block.</p>
+
+<p>Remember to set the correct <b>id</b> in the LOGMASK,
+and to give LOG the correct value. If dumping is needed
+before the first instruction, then LOG must be set to 0.</p>
+
+<p>The dumps of the global data area and the heap are
+controlled internally by the id-s +1 and *1 resp.; the
+corresponding logmask entries are set automatically by
+setting the GDA and HEAP variables.</p>
+<a name="3.4. Forking."></a>
+<h2>3.4. Forking.</h2>
+
+<p>As mentioned earlier, a call to <i>fork()</i>, causes an
+image of the current program to start running. To prevent a
+messy logfile, the child process gets its own logfile (and
+message file, tally file, etc.). These logfiles are
+distinguished from the parent logfile by the a postfix,
+e.g., <i>logfile_1</i> for the first child, <i>logfile_2</i>
+for the second child, <i>logfile_1_2</i> for the second
+child of the first child, etc.<i><br>
+Note</i>: the implementation of this feature is shaky; it
+works for the log file but should also work for other files
+and for the names of the logging variables.</p>
+
+<p align=center>APPENDIX A</p>
+<a name="List of Warnings."></a>
+<h2>List of Warnings.</h2>
+
+<p>The shadow-byte administration makes it possible to
+check for a wide range of errors during run-time. We have
+tried to make the diagnostics self-explanatory and
+especially useful for the C-programmer. The warnings are
+printed in the message file, together with source file and
+line number. The complete list of warnings is presented
+here, followed by an explanation of what might be wrong.
+Often, these explanations implicitly assume that the program
+being interpreted, was originally written in C (and not
+Pascal, Basic etc.).</p>
+
+<p><i>Reading the load file</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="10%"></td>
+<td width="86%">
+
+<p><b>Floating point instructions flag in header
+ignored</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="10%"></td>
+<td width="78%">
+
+<p><b>No float initialisation in this version</b></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The interpreter was compiled with the NOFLOAT option;
+code involving floating point operations can be run as long
+as the actual instructions are avoided.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="10%"></td>
+<td width="66%">
+
+<p><b>Extra-test flag in header ignored</b></p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The interpreter already tests anything conceivable.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="10%"></td>
+<td width="70%">
+
+<p><b>Maximum line number in header was 0</b></p>
+</td>
+<td width="15%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>This number could be used to allocate tables for
+tallying; these tables are, however, expanded as needed, so
+the number is immaterial.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7.</p>
+</td>
+<td width="10%"></td>
+<td width="48%">
+
+<p><b>Bad float initialisation</b></p>
+</td>
+<td width="37%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The loadfile contains a floating point denotation which
+does not satisfy the syntax (see 2.6). Examining the
+loadfile (with <b>od &minus;c</b>) might show the syntax
+error. Probably there is a bug in the front-end, creating
+floats with a bad syntax.</p>
+</td>
+</table>
+
+<p><i>System calls</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>11.</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p><b>IOCTL &minus; bad or unimplemented request</b></p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The second parameter to the ioctl() request (the
+operation code) is invalid or not implemented; since there
+are many different opcodes on the various UNIX systems, it
+is difficult to tell which. The system call fails.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>14.</p>
+</td>
+<td width="8%"></td>
+<td width="62%">
+
+<p><b>MPXCALL &minus; not (yet) implemented</b></p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>15.</p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p><b>PROFIL &minus; not (yet) implemented</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>16.</p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p><b>PTRACE &minus; not (yet) implemented</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The monitor calls <i>mpxcall()</i>, <i>profil()</i> and
+<i>ptrace()</i> have not been implemented. The monitor call
+fails.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>21.</p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p><b>Inaccessible memory in system call</b></p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>Bad pointers passed to system calls do not cause a memory
+fault (which in UNIX would happen to the kernel), but cause
+the system call to fail with the UNIX variable errno set to
+14 (EFAULT). It seems likely that the program is at fault,
+but there is also a good possibility that a library routine
+made unwarranted assumptions about word size and pointer
+size.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>23.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>READ &minus; buffer resides in unallocated
+memory</b></p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>24.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>READ &minus; buffer across global data area and
+heap</b></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>When the buffer passed to the read() system call is
+situated (completely or partially) in unallocated memory
+(beyond <i>HP</i>) or begins in the global data area and
+ends in the heap, the appropriate warning is given. The
+buffer is not written.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>25.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>WRITE &minus; buffer resides in unallocated
+memory</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>26.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>WRITE &minus; buffer across global data area and
+heap</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>27.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>WRITE &minus; (part of) global buffer is
+undefined</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>28.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>WRITE &minus; (part of) local buffer is
+undefined</b></p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The first two are equivalent to the READ-errors above.
+Writing out a buffer usually makes no sense when the
+contents are undefined, so one of the latter two warnings
+will be generated in this case. A global buffer resides in
+the data partition; a local buffer resides in the stack
+partition. This corresponds to global and local variables in
+a C-program. In the first two cases the WRITE is not
+performed, in the latter two cases it is.</p>
+</td>
+</table>
+
+<p><i>Traps and signals</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>31.</p>
+</td>
+<td width="8%"></td>
+<td width="54%">
+
+<p><b>SIGTRP &minus; bad signo argument</b></p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The <i>sigtrp()</i> monitor call allows <i>sig_no</i>
+arguments in the range [1..17] (UNIX Version 7 signals); the
+actual argument is out of range.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>32.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>SIGTRP &minus; signo argument is a synchronous
+trap</b></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The signal is one that can only be caused synchronously
+by the running program on UNIX; it cannot occur to an
+interpreted program.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>33.</p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p><b>SIGTRP &minus; bad trapno argument</b></p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The <i>sigtrp()</i> monitor call allows <i>trap_no</i>
+arguments between 0 and 252, and the special values &minus;2
+and &minus;3; the actual argument is not one of these.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>36.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>Heap overflow due to command line limitation</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>37.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>Stack overflow due to command line limitation</b></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The maximum sizes of the heap and the stack can be
+limited by options on the command line. If overflow occurs
+due to such limitations, the corresponding trap is taken,
+preceded by one of the above warnings. If the memory of the
+interpreter itself is exhausted, a fatal error follows.</p>
+</td>
+</table>
+
+<p><i>Run-time type checking</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>41.</p>
+</td>
+<td width="8%"></td>
+<td width="48%">
+
+<p><b>Local character expected</b></p>
+</td>
+<td width="37%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>42.</p>
+</td>
+<td width="8%"></td>
+<td width="50%">
+
+<p><b>Global character expected</b></p>
+</td>
+<td width="35%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>43.</p>
+</td>
+<td width="8%"></td>
+<td width="44%">
+
+<p><b>Local integer expected</b></p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>44.</p>
+</td>
+<td width="8%"></td>
+<td width="46%">
+
+<p><b>Global integer expected</b></p>
+</td>
+<td width="39%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>45.</p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p><b>Local float expected</b></p>
+</td>
+<td width="45%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>46.</p>
+</td>
+<td width="8%"></td>
+<td width="42%">
+
+<p><b>Global float expected</b></p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>47.</p>
+</td>
+<td width="8%"></td>
+<td width="54%">
+
+<p><b>Local data pointer expected</b></p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>48.</p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p><b>Global data pointer expected</b></p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>49.</p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p><b>Local instruction pointer expected</b></p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>50.</p>
+</td>
+<td width="8%"></td>
+<td width="70%">
+
+<p><b>Global instruction pointer expected</b></p>
+</td>
+<td width="15%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>In general, a type violation has taken place when one of
+these warnings is given. The <b>float</b>- and
+<b>instruction pointer</b> warnings are rare and will
+usually be easy traceable. <b>Integer/character expected</b>
+will normally occur when unsigned arithmetic is performed on
+datapointers or when memory containing objects other than
+integers is copied bytewise. Often, this warning is followed
+by a warning <b>datapointer expected</b>. This is due to our
+decision of transforming pointers to (unsigned) integers
+after doing unsigned arithmetic on them. When such a
+transformed integer is dereferenced (as if it were a
+pointer) or, in general, when it is treated as a pointer,
+this results in a warning. The present library
+implementation of malloc() causes such a sequence of
+errors.</p>
+</td>
+</table>
+
+<p>These messages are always followed by a tentative
+description of what is found in memory at the offending
+place.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>61.</p>
+</td>
+<td width="8%"></td>
+<td width="52%">
+
+<p><b>Actual memory is undefined</b></p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>62.</p>
+</td>
+<td width="8%"></td>
+<td width="66%">
+
+<p><b>Actual memory contains an integer</b></p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>63.</p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p><b>Actual memory contains a float</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>64.</p>
+</td>
+<td width="8%"></td>
+<td width="74%">
+
+<p><b>Actual memory contains a data pointer</b></p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>65.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>Actual memory contains an instruction pointer</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>66.</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><b>Actual memory contains mixed information</b></p>
+</td>
+<td width="5%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>If the contents of the area was undefined, check the
+source code for an uninitialized variable of the mentioned
+type. Officially, the use of an undefined value should
+result in a EIUND or EFUND trap but the occurrence is so
+common that a warning is more appropriate. The contents of
+memory are described as mixed if the data consists of pieces
+of different types. This happens, e.g., when caller and
+callee do not agree on the types and lengths of the
+parameters.</p>
+</td>
+</table>
+
+<p><i>Protection</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>71.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>Destroying contents of ROM (at or near loc 0)</b></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The program stores a value in Read-Only Memory; the only
+ROM in the present implementation is the area near location
+0. The warning probably results from storing under a NULL
+pointer. This is only a warning, the store operation is
+executed normally. Reads from location 0 are not
+detected.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>72.</p>
+</td>
+<td width="8%"></td>
+<td width="84%">
+
+<p><b>Destroying contents of Return Status Block</b></p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The Return Status Block is the stack area containing the
+return address, the dynamic link, etc. This may or may not
+be an error. The current implementation of
+<i>setjmp()</i>/<i>longjmp()</i> may be responsible for it.
+If the program does not use setjmp(), there <i>is</i>
+something very wrong (e.g. argument for ASP too large). Note
+that there are some library routines (such as
+<i>alarm()</i>) which use <i>setjmp()</i>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>81.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>Logical operation using undefined operand(s)</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>82.</p>
+</td>
+<td width="8%"></td>
+<td width="60%">
+
+<p><b>Comparing undefined operand(s)</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The logical operations AND, XOR, IOR, COM and the compare
+operation CMS do their jobs bytewise. If one of the bytes is
+found to be undefined, the corresponding warning is given,
+and the operation is stopped immediately. The stack is
+adjusted so interpretation may continue.<br>
+It is hard to say what went wrong. Possibly, the argument of
+the instruction at hand (which indicates the size of the
+objects to be compared), was too large.</p>
+</td>
+</table>
+
+<p><i>Bad operands</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>91.</p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p><b>Shift over negative distance</b></p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>92.</p>
+</td>
+<td width="8%"></td>
+<td width="58%">
+
+<p><b>Shift over too large distance</b></p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>Shift instructions yield undefined results if the shift
+distance is negative or larger than the object size.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>93.</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><b>Pointer arithmetic yields pointer to bad
+segment</b></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>When doing pointer arithmetic (ADP, ADS), the operand and
+result pointer must be in the same <i>segment</i> (see sec.
+4). E.g. loading the address of the first local and adding
+20 to it will certainly give this warning.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>94.</p>
+</td>
+<td width="8%"></td>
+<td width="84%">
+
+<p><b>Subtracting pointers to different segments</b></p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>Pointers may be subtracted only if they point into the
+same segment.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>96.</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p><b>Pointer arithmetic with NULL pointer</b></p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>By definition it is illegal to do arithmetic with null
+pointers. Integers with the size of a pointer and the value
+zero are recognized as NULL pointers. A well-known C-trick
+to compute the offset of some field in a struct is
+converting the null-pointer to the type of the struct and
+simply taking the address of the field. This trick will
+&minus;when translated and interpreted&minus; generate this
+warning because it results in arithmetic with the NULL
+pointer.</p>
+</td>
+</table>
+
+<p><i>Return area</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>101.</p>
+</td>
+<td width="6%"></td>
+<td width="68%">
+
+<p><b>Returned function result too large</b></p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>102.</p>
+</td>
+<td width="6%"></td>
+<td width="68%">
+
+<p><b>Returned function result too small</b></p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>This warning is generated when the size of the expected
+return value is not equal to the size actually returned.<br>
+An interpreted program may have fallen through the end of
+the code without explicitly doing an <i>exit()</i> or
+<i>return()</i>. The start-up routine (<i>crt0()</i>)
+however always expects to get some value returned by the
+program proper.<br>
+Another (less probable) possibility of course is that the
+code contains a subroutine or function call that does not
+return properly (e.g. it returns a short instead of a
+long).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>103.</p>
+</td>
+<td width="6%"></td>
+<td width="78%">
+
+<p><b>Returned function result may be garbled</b></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>This warning will be generated, when the contents of the
+FRA are fetched after some instruction is executed which can
+mess up the area. Compiler-generated loadfiles should not
+generate this message.</p>
+</td>
+</table>
+
+<p><i>Return Status Block</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>111.</p>
+</td>
+<td width="6%"></td>
+<td width="76%">
+
+<p><b>RET did not find a Return Status Block</b></p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>112.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><b>Used RET to return from a trap</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The RET instruction found a garbled Return Status Block,
+or on that resulted from a trap.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>115.</p>
+</td>
+<td width="6%"></td>
+<td width="76%">
+
+<p><b>RTT did not find a Return Status Block</b></p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>116.</p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p><b>RTT on empty stack</b></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>117.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><b>Used RTT to return from a call</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>118.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Used RTT to return from a non-returnable trap</b></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>The RTT (Return from Trap) instruction found a Return
+Status block that was not created properly by a trap.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>121.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><b>Stack Pointer too large in RET</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>122.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><b>Stack Pointer too small in RET</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>125.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><b>Stack Pointer too large in RTT</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>126.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><b>Stack Pointer too small in RTT</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<p>According to the EM Manual (4.2), &quot;the value of SP
+just after the return value has been popped must be the same
+as the value of SP just before executing the first
+instruction of the invocation.&quot; If the Stack Pointer is
+too large, some dynamically allocated item or some temporary
+result may have been left behind on the stack. If the Stack
+Pointer is too small, some locals have been unstacked. Since
+the interpreter has enough information in the Return Status
+Block, it recovers correctly from these errors.</p>
+</td>
+</table>
+
+<p><i>Traps</i></p>
+
+<p>Some traps have ambiguous or non-obvious causes. As far
+as possible, these are preceded by a warning, explaining the
+circumstances of the trap.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>131.</p>
+</td>
+<td width="6%"></td>
+<td width="52%">
+
+<p><b>Trap ESTACK: DCH on bad LB</b></p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>132.</p>
+</td>
+<td width="6%"></td>
+<td width="52%">
+
+<p><b>Trap ESTACK: LPB on bad LB</b></p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>133.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap ESTACK: SP retracted over Return Status
+Block</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>134.</p>
+</td>
+<td width="6%"></td>
+<td width="72%">
+
+<p><b>Trap ESTACK: SP moved into data area</b></p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>135.</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><b>Trap ESTACK: SP set to non-word-boundary</b></p>
+</td>
+<td width="5%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>136.</p>
+</td>
+<td width="6%"></td>
+<td width="64%">
+
+<p><b>Trap ESTACK: LB set out of stack</b></p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>137.</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><b>Trap ESTACK: LB set to non-word-boundary</b></p>
+</td>
+<td width="5%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>138.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap ESTACK: LB set to position where there is no
+RSB</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>141.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EHEAP: HP retracted into Global Data
+Area</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>142.</p>
+</td>
+<td width="6%"></td>
+<td width="64%">
+
+<p><b>Trap EHEAP: HP pushed into stack</b></p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>143.</p>
+</td>
+<td width="6%"></td>
+<td width="78%">
+
+<p><b>Trap EHEAP: HP set to non-word-boundary</b></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>151.</p>
+</td>
+<td width="6%"></td>
+<td width="56%">
+
+<p><b>Trap EILLINS: unknown opcode</b></p>
+</td>
+<td width="29%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>152.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EILLINS: conversion with unacceptable size for
+this machine</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>153.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EILLINS: FIL with non-existing address</b></p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>154.</p>
+</td>
+<td width="6%"></td>
+<td width="74%">
+
+<p><b>Trap EILLINS: LFR with too large size</b></p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>155.</p>
+</td>
+<td width="6%"></td>
+<td width="74%">
+
+<p><b>Trap EILLINS: RET with too large size</b></p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>156.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EILLINS: instruction argument of class c does
+not fit a word</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>157.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EILLINS: instruction on double word on machine
+with word size 4</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>158.</p>
+</td>
+<td width="6%"></td>
+<td width="72%">
+
+<p><b>Trap EILLINS: local offset too large</b></p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>159.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EILLINS: instruction argument of class g not in
+GDA</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>160.</p>
+</td>
+<td width="6%"></td>
+<td width="78%">
+
+<p><b>Trap EILLINS: fragment offset too large</b></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>161.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EILLINS: counter in lexical instruction out of
+range</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>162.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EILLINS: non-existent procedure
+identifier</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>163.</p>
+</td>
+<td width="6%"></td>
+<td width="74%">
+
+<p><b>Trap EILLINS: illegal register number</b></p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>172.</p>
+</td>
+<td width="6%"></td>
+<td width="74%">
+
+<p><b>Trap EBADPC: jump out of text segment</b></p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>173.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EBADPC: jump out of procedure fragment</b></p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>181.</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><b>Trap EBADGTO: GTO does not restore an existing
+RSB</b></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>182.</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p><b>Trap EBADGTO: GTO descriptor on the stack</b></p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>191.</p>
+</td>
+<td width="6%"></td>
+<td width="60%">
+
+<p><b>Trap caused by TRP instruction</b></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="13%"></td>
+<td width="86%">
+<pre>     APPENDIX B
+</pre>
+</td>
+</table>
+<a name="How to use the interpreter"></a>
+<h2>How to use the interpreter</h2>
+
+<p>The interpreter is not normally used for the debugging
+of programs under construction. Its primary application is
+as a verification tool for almost completed programs.
+Although the proper operation of the interpreter is
+obviously a black art, this chapter tries to provide some
+guidelines.</p>
+
+<p>For the sake of the argument, the source language is
+assumed to be C, but most hints apply equally well to other
+languages supported by ACK.</p>
+
+<p><i>Initial measures</i></p>
+
+<p>Start with a test case of trivial size; to be on the
+safe side, reckon with a time dilatation factor of about
+500, i.e., a second grows into 10 minutes. (The interpreter
+takes 0.5 msec to do one EM instruction on a Sun 3/50).
+Fortunately many trivial test cases are much shorter than
+one second.</p>
+
+<p>Compile the program into an <i>e.out</i>, the EM machine
+version of a <i>a.out</i>, by calling <i>em22</i> (for
+2-byte integers and 2-byte pointers), <i>em24</i> (for 2 and
+4) or <i>em44</i> (for 4 and 4) as seems appropriate; if in
+doubt, use <i>em44</i>. These compilers can be found in the
+ACK <i>bin</i> directory, and should be used instead of
+<i>acc</i> (or normal <small>UNIX</small> &reg; <i>cc</i>).
+Alternatively, <i>acc &minus;memNN</i> can be used instead
+of <i>emNN</i>.</p>
+
+<p>If a C program consists of more than one file, as it
+usually does, there is a small problem. The <i>acc</i> and
+<i>cc</i> compilers generate .o files, whereas the
+<i>emNN</i> compilers generate .m files as object files. A
+simple technique to avoid the problem is to call</p>
+<pre>     em44 *.c
+</pre>
+
+<p>if possible. If not, the following hack on the
+<i>Makefile</i> generally works.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Make sure the <i>Makefile</i> is reasonably clean and
+complete: all calls to the compiler are through
+<i>$(CC)</i>, <i>CFLAGS</i> is used properly and all
+dependencies are specified.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Add the following lines to the <i>Makefile</i> (possibly
+permanently):</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>.SUFFIXES:</p>
+<td width="19%"></td>
+<td width="10%">
+
+<p>.o</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>.c.o:</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>$(CC) &minus;c $(CFLAGS) $&lt;</p>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Set CC to <i>em44 &minus;.c</i> (for example). Make sure
+CFLAGS includes the &minus;O option; this yields a speed-up
+of about 15 %.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Change all .o to .m (or .k if the &minus;O option is not
+used).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>If necessary, change <i>a.out</i> to <i>e.out</i>.</p>
+</td>
+<td width="17%">
+</td>
+</table>
+
+<p>With these changes, <i>make</i> will produce an EM
+object; <i>esize</i> can be used to verify that it is indeed
+an EM object and obtain some statistics. Then call the
+interpreter:</p>
+<pre>     int &lt;EM-object-file&gt; [ parameters ]
+</pre>
+
+<p>where the parameters are the normal parameters of the
+program. This should work exactly like the original program,
+though slower. It reads from the terminal if the original
+does, it opens and closes files like the original and it
+accepts interrupts.</p>
+
+<p><i>Interpreting the results</i></p>
+
+<p>Now there are several possibilities.</p>
+
+<p>It does all this. Great! This means the program does not
+do very uncouth things. Now read the file <i>int.mess</i> to
+see if any messages were generated. If there are none, the
+program did not really run (perhaps the original cc
+<i>a.out</i> got called instead?) Normally there is at least
+a termination message like</p>
+<pre>     (Message): program exits with status 0 at &quot;awa.p&quot;, line 64, INR = 4124
+</pre>
+
+<p>This says that the program terminated through an exit(0)
+on line 64 of the file <i>awa.p</i> after 4124 EM
+instructions. If this is the only message it is time to move
+to a bigger test case.</p>
+
+<p>On the other hand, the program may come to a grinding
+halt with an error message. All messages (errors and
+warnings) have a format in which the sequence</p>
+<pre>     &quot;&lt;file name&gt;&quot;, line &lt;ln#&gt;
+</pre>
+
+<p>occurs, which is the same sequence many compilers
+produce for their error messages. Consequently, the
+<i>int.mess</i> file can be processed as any compiler
+message output.</p>
+
+<p>One such message can be</p>
+<pre>     (Fatal error) a.em: trap &quot;Addressing non existent memory&quot; not caught at &quot;a.c&quot;, line 2, INR = 16
+</pre>
+
+<p>produced by the abysmal program</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>main()</p>
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>{</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>*(int*)200000 = 1;</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+
+<p>}</p>
+
+<p>Often the effects are more subtle, however. The
+program</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>main()</p>
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>{</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>int *a, b = 777;</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>b = *a;</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+
+<p>}</p>
+
+<p>produces the following five warnings (in far less than a
+second):</p>
+<pre>     (Warning 47, #1): Local data pointer expected at &quot;t.c&quot;, line 4, INR = 17
+     (Warning 61, cont.): Actual memory is undefined at &quot;t.c&quot;, line 4, INR = 17
+     (Warning 102, #1): Returned function result too small at &quot;&lt;unknown&gt;&quot;, line 0, INR = 21
+     (Warning 43, #1): Local integer expected at &quot;exit.c&quot;, line 11, INR = 34
+     (Warning 61, cont.): Actual memory is undefined at &quot;exit.c&quot;, line 11, INR = 34
+</pre>
+
+<p>The one about the function result looks the most
+frightening, but is the most easily solved: <i>main</i> is a
+function returning an int, so the start-up routine expects a
+(four-byte) integer but gets an empty (zero-byte) return
+area.</p>
+
+<p><i>Note</i>: The experts are divided about this. The
+traditional school holds that <i>main</i> is an int function
+and its result is the return code; this leaves them with two
+ways of supplying a return code: one as the parameter of
+<i>exit()</i> and one as the result of <i>main</i>. The
+modern school (Berkeley 4.2 etc.) claims that return codes
+are supplied exclusively by <i>exit()</i>, and they have an
+<i>exit(0)</i> in the start-up routine, just after the call
+to <i>main()</i>; leaving <i>main()</i> through the bottom
+implies successful termination.</p>
+
+<p>We shall satisfy both groups by</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>main()</p>
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p>{</p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>int *a, b = 777;</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>b = *a;</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>exit(0);</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+
+<p>}</p>
+
+<p>This results in</p>
+<pre>     (Warning 47, #1): Local data pointer expected at &quot;t.c&quot;, line 4, INR = 17
+     (Warning 61, cont.): Actual memory is undefined at &quot;t.c&quot;, line 4, INR = 17
+     (Message): program exits with status 0 at &quot;exit.c&quot;, line 11, INR = 33
+</pre>
+
+<p>which is pretty clear as it stands.</p>
+
+<p><i>Using stack dumps</i></p>
+
+<p>Let&rsquo;s, for the sake of argument and to avoid the
+fierce realism of 10000-line programs, assume that the above
+still does not give enough information. Since the error
+occurred in EM instruction number 17, we should like to see
+more information around that moment. Call the interpreter
+again, now with the shell variable AT set at 17:</p>
+<pre>     int AT=17 t.em
+</pre>
+
+<p>(The interpreter has a number of internal variables that
+can be set by assignments on the command line, like with
+<i>make</i>.) This gives a file called <i>int.log</i>
+containing the stack dump of 150 lines presented at the end
+of this chapter.</p>
+
+<p>Since dumping is a subfacility of logging in the
+interpreter, the formats of the lines are the same. If a
+line starts with an @, it will contain a
+file-name/line-number indication; the next two characters
+are the subject and the log level. Then comes the
+information, preceded by a space. The text contains three
+stack dumps, one before the offending instruction, one at
+it, and one after it; then the interpreter stops. All kinds
+of other dumps can be obtained, but this is default.</p>
+
+<p>For each instruction we have, in order:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>an @x9 line, giving the position in the program,</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>the messages, warnings and errors from the instruction
+as it is being executed,</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="44%">
+
+<p>dump(s), as requested.</p>
+</td>
+<td width="45%">
+</td>
+</table>
+
+<p>The first two lines mean that at line 4 in file
+<i>t.c</i> the interpreter performed its 16-th instruction,
+with the Program Counter at 30 pointing at opcode 180 in the
+text segment; the instruction was an LOL (LOad Local) with
+the operand &minus;4 derived from the opcode. It copies the
+local at offset &minus;4 to the top of the stack. The effect
+can be seen from the subsequent stack dump, where the
+undefined word at addresses 2147483568 to ...571 (the
+variable <i>a</i>) has been copied to the top of the stack
+at 2147483560 (copying undefined values does not generate a
+warning). Since we used the <i>em44</i> compiler, all
+pointers and ints in our dump are 4 bytes long. So a
+variable at address X in reality extends from address X to
+X+3.<br>
+Note that this is not the offending instruction; this stack
+dump represents the situation just before the error.</p>
+
+<p>The stack consists of a sequence of frames, each
+containing data followed by a Return Status Block resulting
+from a call; the last frame ends in top-of-stack. The first
+frame represents the stack when the program starts, through
+a call to the start-up routine. This routine prepares the
+second stack frame with the actual parameters to
+<i>main()</i>: <i>argc</i> at 2147483596, <i>argv</i> at
+2147483600 and <i>environ</i> at 2147483604.</p>
+
+<p>The RSB line shows that the call to <i>main()</i> was
+made from procedure 0 which has 0 locals, with PC at 16, an
+LB of 2147483608 and file name and line number still
+unknown. The <i>code</i> in the RSB tells how this RSB was
+made; possible values are STP (start-up), CAL, RTT
+(returnable trap) and NRT (non-returnable trap).</p>
+
+<p>The next frame shows the local variable(s) of
+<i>main()</i>; there are two of them, the pointer <i>a</i>
+at 2147483568, which is undefined, and variable <i>b</i> at
+2147483564, which has the value 777. Then comes a copy of
+<i>a</i>, just made by the LOL instruction, at 2147483560.
+The following line shows that the Function Return Area
+(which does not reside at the end of the stack, but just
+happens to be printed here) has size 0 and is presently
+undefined. The stack dump ends by showing that the Actuals
+Base is at 2147483596 (pointing at <i>argc</i>), the Locals
+Base at 2147483572 (pointing just above the local <i>a</i>),
+the Stack Pointer at 2147483560 (pointing at the undefined
+pointer), the line count is 4 and the file name is
+&quot;t.c&quot;.</p>
+
+<p>(Notice that there is one more stack frame than one
+would probably expect, the one above the start-up
+routine.)</p>
+
+<p>The Function Return Area could have a size larger than 0
+and still be undefined, for example when an instruction that
+does not preserve the contents of the FRA has just been
+executed; likewise the FRA could have size 0 and be defined
+nevertheless, for example just after a RET 0
+instruction.</p>
+
+<p>All this has set the scene for the distaster which is
+about to strike in the next instruction. This is indeed a
+LOI (LOad Indirect) of size 4, opcode 169; it causes the
+message</p>
+<pre>     warning: Local data pointer expected [stack.c: 242]
+</pre>
+
+<p>and its continuation</p>
+<pre>     warning cont.: Actual memory is undefined
+</pre>
+
+<p>(detected in the interpreter file <i>stack.c</i> at line
+242; this can be useful for sorting out dubious semantics).
+We see that the effect, as shown in the third frame of this
+stack dump (at instruction number 17) is somewhat
+unexpected: the LOI has fetched the value 4 and stacked it.
+The reason is that, unfortunately, undefinedness is not
+transitive in the interpreter. When an undefined value is
+used in an operation (other than copying) a warning is
+given, but thereafter the value is treated as if it were
+zero. So, after the warning a normal null pointer remains,
+which is then used to pick up the value at location 0. This
+is the place where the EM machine stores its current line
+number, which is presently 4.</p>
+
+<p>The third stack dump shows the final effect: the value 4
+has been unstacked and copied to variable <i>b</i> at
+2147483564 through an STL (STore Local) instruction.</p>
+
+<p>Since this form of logging dumps the stack only, the log
+file is relatively small as dumps go. Nevertheless, a useful
+excerpt can be obtained with the command</p>
+<pre>     grep &rsquo;d1&rsquo; int.log
+</pre>
+
+<p>This extracts the Return Status Block lines from the
+log, thus producing three traces of calls, one for each
+instruction in the log:</p>
+<pre>      d1 &gt;&gt; RSB: code = STP, PI = uninit, PC = 0, LB = 2147483644, LIN = 0, FIL = NULL
+      d1 &gt;&gt; RSB: code = CAL, PI = (0,0), PC = 16, LB = 2147483608, LIN = 0, FIL = NULL
+      d1 &gt;&gt; AB = 2147483596, LB = 2147483572, SP = 2147483560, HP = 848, LIN = 4, FIL = &quot;t.c&quot;
+      d1 &gt;&gt; RSB: code = STP, PI = uninit, PC = 0, LB = 2147483644, LIN = 0, FIL = NULL
+      d1 &gt;&gt; RSB: code = CAL, PI = (0,0), PC = 16, LB = 2147483608, LIN = 0, FIL = NULL
+      d1 &gt;&gt; AB = 2147483596, LB = 2147483572, SP = 2147483560, HP = 848, LIN = 4, FIL = &quot;t.c&quot;
+      d1 &gt;&gt; RSB: code = STP, PI = uninit, PC = 0, LB = 2147483644, LIN = 0, FIL = NULL
+      d1 &gt;&gt; RSB: code = CAL, PI = (0,0), PC = 16, LB = 2147483608, LIN = 0, FIL = NULL
+      d1 &gt;&gt; AB = 2147483596, LB = 2147483572, SP = 2147483564, HP = 848, LIN = 4, FIL = &quot;t.c&quot;
+</pre>
+
+<p>Theoretically, the pertinent trace is the middle one,
+but in practice all three are equal. In the present case
+there isn&rsquo;t much to trace, but in real programs the
+trace can be useful.</p>
+
+<p><i>Errors in libraries</i></p>
+
+<p>Since libraries are generally compiled with suppression
+of line number and file name information, the line number
+and file name in the interpreter will not be updated when it
+enters a library routine. Consequently, all messages
+generated by interpreting library routines will seem to
+originate from the line of the call. This is especially true
+for the routine malloc(), which, from the nature of its
+business, often contains dubitable code.</p>
+
+<p>A usual message is:</p>
+<pre>     (Warning 43, #1): Local integer expected at &quot;buff.c&quot;, line 18, INR = 266
+     (Warning 64, cont.): Actual memory contains a data pointer at &quot;buff.c&quot;, line 18, INR = 266
+</pre>
+
+<p>and indeed at line 18 of the file buff.c we find:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>buff = malloc(buff_size = BFSIZE);</p>
+</table>
+
+<p>This problem can be avoided by using a specially
+compiled version of the library that contains the correct
+LIN and FIL instructions, or, less elegantly, by including
+the source code of the library routines in the program; in
+the latter case, one has to be sure to have them all.</p>
+
+<p><i>Unavoidable messages</i><br>
+Some messages produced by the logging are almost
+unavoidable; sometimes the writer of a library routine is
+forced to take liberties with the semantics of EM.</p>
+
+<p>Examples from C include the memory allocation routines.
+For efficiency reasons, one bit of an pointer in the
+administration is used as a flag; setting, clearing and
+reading this bit requires bitwise operations on pointers,
+which gives the above messages. Realloc causes a problem in
+that it may have to copy the originally allocated area to a
+different place; this area may contain uninitialised
+bytes.</p>
+<pre>     @x9 &quot;t.c&quot;, line 4, INR = 16, PC = 30 OPCODE = 180
+     @L6 &quot;t.c&quot;, line 4, INR = 16, DoLOLm(-4)
+      d2
+      d2 . . STACK_DUMP[4/4] . . INR = 16 . . STACK_DUMP . .
+      d2 ----------------------------------------------------------------
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483643        0                  (Dp)
+      d2    2147483642        0                  (Dp)
+      d2    2147483641        0                  (Dp)
+      d2    2147483640       40    [        40]  (Dp)
+      d2    2147483639        0                  (Dp)
+      d2    2147483638        0                  (Dp)
+      d2    2147483637        3                  (Dp)
+      d2    2147483636       64    [       832]  (Dp)
+      d2    2147483635        0                  (In)
+      d2    2147483634        0                  (In)
+      d2    2147483633        0                  (In)
+      d2    2147483632        1    [         1]  (In)
+      d1 &gt;&gt; RSB: code = STP, PI = uninit, PC = 0, LB = 2147483644, LIN = 0, FIL = NULL
+      d2
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483607        0                  (Dp)
+      d2    2147483606        0                  (Dp)
+      d2    2147483605        0                  (Dp)
+      d2    2147483604       40    [        40]  (Dp)
+      d2    2147483603        0                  (Dp)
+      d2    2147483602        0                  (Dp)
+      d2    2147483601        3                  (Dp)
+      d2    2147483600       64    [       832]  (Dp)
+      d2    2147483599        0                  (In)
+      d2    2147483598        0                  (In)
+      d2    2147483597        0                  (In)
+      d2    2147483596        1    [         1]  (In)
+      d1 &gt;&gt; RSB: code = CAL, PI = (0,0), PC = 16, LB = 2147483608, LIN = 0, FIL = NULL
+      d2
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483571    undef
+      d2         | | |    | | |
+      d2    2147483568    undef (1 word)
+      d2    2147483567        0                  (In)
+      d2    2147483566        0                  (In)
+      d2    2147483565        3                  (In)
+      d2    2147483564        9    [       777]  (In)
+      d2    2147483563    undef
+      d2         | | |    | | |
+      d2    2147483560    undef (1 word)
+      d2        FRA: size = 0, undefined
+      d1 &gt;&gt; AB = 2147483596, LB = 2147483572, SP = 2147483560, HP = 848, \
+                                        LIN = 4, FIL = &quot;t.c&quot;
+      d2 ----------------------------------------------------------------
+      d2
+     @x9 &quot;t.c&quot;, line 4, INR = 17, PC = 31 OPCODE = 169
+     @w1 &quot;t.c&quot;, line 4, INR = 17, warning: Local data pointer expected [stack.c: 242]
+     @w1 &quot;t.c&quot;, line 4, INR = 17, warning cont.: Actual memory is undefined
+     @L6 &quot;t.c&quot;, line 4, INR = 17, DoLOIm(4)
+      d2
+      d2 . . STACK_DUMP[4/4] . . INR = 17 . . STACK_DUMP . .
+      d2 ----------------------------------------------------------------
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483643        0                  (Dp)
+      d2    2147483642        0                  (Dp)
+      d2    2147483641        0                  (Dp)
+      d2    2147483640       40    [        40]  (Dp)
+      d2    2147483639        0                  (Dp)
+      d2    2147483638        0                  (Dp)
+      d2    2147483637        3                  (Dp)
+      d2    2147483636       64    [       832]  (Dp)
+      d2    2147483635        0                  (In)
+      d2    2147483634        0                  (In)
+      d2    2147483633        0                  (In)
+      d2    2147483632        1    [         1]  (In)
+      d1 &gt;&gt; RSB: code = STP, PI = uninit, PC = 0, LB = 2147483644, LIN = 0, FIL = NULL
+      d2
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483607        0                  (Dp)
+      d2    2147483606        0                  (Dp)
+      d2    2147483605        0                  (Dp)
+      d2    2147483604       40    [        40]  (Dp)
+      d2    2147483603        0                  (Dp)
+      d2    2147483602        0                  (Dp)
+      d2    2147483601        3                  (Dp)
+      d2    2147483600       64    [       832]  (Dp)
+      d2    2147483599        0                  (In)
+      d2    2147483598        0                  (In)
+      d2    2147483597        0                  (In)
+      d2    2147483596        1    [         1]  (In)
+      d1 &gt;&gt; RSB: code = CAL, PI = (0,0), PC = 16, LB = 2147483608, LIN = 0, FIL = NULL
+      d2
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483571    undef
+      d2         | | |    | | |
+      d2    2147483568    undef (1 word)
+      d2    2147483567        0                  (In)
+      d2    2147483566        0                  (In)
+      d2    2147483565        3                  (In)
+      d2    2147483564        9    [       777]  (In)
+      d2    2147483563        0                  (In)
+      d2    2147483562        0                  (In)
+      d2    2147483561        0                  (In)
+      d2    2147483560        4    [         4]  (In)
+      d2        FRA: size = 0, undefined
+      d1 &gt;&gt; AB = 2147483596, LB = 2147483572, SP = 2147483560, HP = 848, \
+                                        LIN = 4, FIL = &quot;t.c&quot;
+      d2 ----------------------------------------------------------------
+      d2
+     @x9 &quot;t.c&quot;, line 4, INR = 18, PC = 32 OPCODE = 229
+     @S6 &quot;t.c&quot;, line 4, INR = 18, DoSTLm(-8)
+      d2
+      d2 . . STACK_DUMP[4/4] . . INR = 18 . . STACK_DUMP . .
+      d2 ----------------------------------------------------------------
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483643        0                  (Dp)
+      d2    2147483642        0                  (Dp)
+      d2    2147483641        0                  (Dp)
+      d2    2147483640       40    [        40]  (Dp)
+      d2    2147483639        0                  (Dp)
+      d2    2147483638        0                  (Dp)
+      d2    2147483637        3                  (Dp)
+      d2    2147483636       64    [       832]  (Dp)
+      d2    2147483635        0                  (In)
+      d2    2147483634        0                  (In)
+      d2    2147483633        0                  (In)
+      d2    2147483632        1    [         1]  (In)
+      d1 &gt;&gt; RSB: code = STP, PI = uninit, PC = 0, LB = 2147483644, LIN = 0, FIL = NULL
+      d2
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483607        0                  (Dp)
+      d2    2147483606        0                  (Dp)
+      d2    2147483605        0                  (Dp)
+      d2    2147483604       40    [        40]  (Dp)
+      d2    2147483603        0                  (Dp)
+      d2    2147483602        0                  (Dp)
+      d2    2147483601        3                  (Dp)
+      d2    2147483600       64    [       832]  (Dp)
+      d2    2147483599        0                  (In)
+      d2    2147483598        0                  (In)
+      d2    2147483597        0                  (In)
+      d2    2147483596        1    [         1]  (In)
+      d1 &gt;&gt; RSB: code = CAL, PI = (0,0), PC = 16, LB = 2147483608, LIN = 0, FIL = NULL
+      d2
+      d2       ADDRESS     BYTE     ITEM VALUE   SHADOW
+      d2    2147483571    undef
+      d2         | | |    | | |
+      d2    2147483568    undef (1 word)
+      d2    2147483567        0                  (In)
+      d2    2147483566        0                  (In)
+      d2    2147483565        0                  (In)
+      d2    2147483564        4    [         4]  (In)
+      d2        FRA: size = 0, undefined
+      d1 &gt;&gt; AB = 2147483596, LB = 2147483572, SP = 2147483564, HP = 848, \
+                                        LIN = 4, FIL = &quot;t.c&quot;
+      d2 ----------------------------------------------------------------
+      d2
+</pre>
+
+<p align=center>BIBLIOGRAPHY</p>
+
+<p>[1] A.S. Tanenbaum, H. van Staveren, E.G. Keizer and
+J.W. Stevenson. <i>Description of a Machine Architecture for
+use with Block Structured Languages</i>. VU Informatica
+Rapport IR-81, august 1983.</p>
+
+<p>[2] E.G. Keizer. <i>Ack description file reference
+manual.</i></p>
+
+<p>[3] K. Jensen and N. Wirth. <i>PASCAL, User Manual and
+Report</i>. Springer Verlag.</p>
+
+<p>[4] B.W. Kernighan and D.M. Ritchie. <i>The C
+Programming Language</i>. Prentice-Hall, 1978.</p>
+
+<p>[5] D.M. Ritchie. <i>C Reference Manual</i>.</p>
+
+<p>[6] <i>Amsterdam Compiler Kit, reference manual.</i></p>
+
+<p>[7] <i>Unix Programmer&rsquo;s Manual, 4.1BSD</i>. UCB,
+August 1983.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/int.pdf b/src/olddocs/int.pdf
new file mode 100644 (file)
index 0000000..f330d8d
Binary files /dev/null and b/src/olddocs/int.pdf differ
diff --git a/src/olddocs/lint.html b/src/olddocs/lint.html
new file mode 100644 (file)
index 0000000..b195de0
--- /dev/null
@@ -0,0 +1,3054 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:38 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>Lint, a C Program Checker</title>
+</head>
+<body>
+
+<h1 align=center>Lint, a C Program Checker</h1>
+<a href="#Contents">Contents</a><br>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. Outline of the program">2. Outline of the program</a><br>
+<a href="#3. What lint checks">3. What lint checks</a><br>
+<a href="#3.1. Set, used and unused variables">3.1. Set, used and unused variables</a><br>
+<a href="#3.2. Flow of control">3.2. Flow of control</a><br>
+<a href="#3.3. Functions">3.3. Functions</a><br>
+<a href="#3.4. Undefined evaluation order">3.4. Undefined evaluation order</a><br>
+<a href="#3.5. Pointer alignment problems">3.5. Pointer alignment problems</a><br>
+<a href="#3.6. Libraries">3.6. Libraries</a><br>
+<a href="#4. How lint checks">4. How lint checks</a><br>
+<a href="#4.1. The first pass first pass data structure">4.1. The first pass first pass data structure</a><br>
+<a href="#4.1.1. The changes">4.1.1. The changes</a><br>
+<a href="#4.1.1.1. Idf descriptor">4.1.1.1. Idf descriptor</a><br>
+<a href="#4.1.1.2. Def descriptor">4.1.1.2. Def descriptor</a><br>
+<a href="#4.1.2. The additions">4.1.2. The additions</a><br>
+<a href="#4.1.2.1. Lint_stack_entry descriptor">4.1.2.1. Lint_stack_entry descriptor</a><br>
+<a href="#4.1.2.2. State descriptor">4.1.2.2. State descriptor</a><br>
+<a href="#4.1.2.3. Auto_def descriptor">4.1.2.3. Auto_def descriptor</a><br>
+<a href="#4.1.2.4. Expr_state descriptor">4.1.2.4. Expr_state descriptor</a><br>
+<a href="#4.1.2.5. Outdef descriptor">4.1.2.5. Outdef descriptor</a><br>
+<a href="#4.2. The first pass checking mechanism">4.2. The first pass checking mechanism</a><br>
+<a href="#4.2.1. Used and/or set variables">4.2.1. Used and/or set variables</a><br>
+<a href="#4.2.2. Undefined evaluation orders">4.2.2. Undefined evaluation orders</a><br>
+<a href="#4.2.3. Useless statements">4.2.3. Useless statements</a><br>
+<a href="#4.2.4. Not-reachable statements">4.2.4. Not-reachable statements</a><br>
+<a href="#4.2.5. Functions returning expressions and just returning">4.2.5. Functions returning expressions and just returning</a><br>
+<a href="#4.2.6. Output definitions for the second pass">4.2.6. Output definitions for the second pass</a><br>
+<a href="#4.2.7. Generating libraries">4.2.7. Generating libraries</a><br>
+<a href="#4.2.8. Interpreting the pseudocomments">4.2.8. Interpreting the pseudocomments</a><br>
+<a href="#4.3. The second pass data structure">4.3. The second pass data structure</a><br>
+<a href="#4.3.1. Inp_def descriptor">4.3.1. Inp_def descriptor</a><br>
+<a href="#4.4. The second pass checking mechanism">4.4. The second pass checking mechanism</a><br>
+<a href="#4.4.1. Read_defs()">4.4.1. Read_defs()</a><br>
+<a href="#4.4.2. Check()">4.4.2. Check()</a><br>
+<a href="#4.4.3. Check_usage()">4.4.3. Check_usage()</a><br>
+<a href="#5. How to make lint shut up">5. How to make lint shut up</a><br>
+<a href="#6. User options">6. User options</a><br>
+<a href="#7. Ideas for further development">7. Ideas for further development</a><br>
+<a href="#8. Testing the program">8. Testing the program</a><br>
+<a href="#9. References">9. References</a><br>
+<a href="#Appendix A">Appendix A</a><br>
+<a href="#The warnings">The warnings</a><br>
+<a href="#Pass one warnings">Pass one warnings</a><br>
+<a href="#Pass two warnings">Pass two warnings</a><br>
+<a href="#Appendix B">Appendix B</a><br>
+
+<hr>
+
+<p><b>Lint, a C Program Checker</b></p>
+
+<p align=center><small>Afstudeer verslag</small></p>
+
+<p align=center><small>18 mei 1988</small></p>
+
+<p align=center><small><i>Frans Kunst</i></small></p>
+
+<p align=center><small>Vrije Universiteit<br>
+Amsterdam<br>
+This document describes an implementation of a program
+which<br>
+does an extensive consistency and plausibility check on a
+set<br>
+of C program files.<br>
+This may lead to warnings which help the programmer to
+debug<br>
+the program, to remove useless code and to improve his
+style.<br>
+The program has been used to test itself and has found<br>
+bugs in sources of some heavily used code.</small></p>
+<a name="Contents"></a>
+<h2>Contents</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="24%">
+
+<p>Introduction</p>
+</td>
+<td width="65%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="44%">
+
+<p>Outline of the program</p>
+</td>
+<td width="45%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="32%">
+
+<p>What lint checks</p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>3.1</p>
+</td>
+<td width="4%"></td>
+<td width="60%">
+
+<p>Set, used and unused variables</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>3.2</p>
+</td>
+<td width="4%"></td>
+<td width="30%">
+
+<p>Flow of control</p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>3.3</p>
+</td>
+<td width="4%"></td>
+<td width="18%">
+
+<p>Functions</p>
+</td>
+<td width="61%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>3.4</p>
+</td>
+<td width="4%"></td>
+<td width="52%">
+
+<p>Undefined evaluation order</p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>3.5</p>
+</td>
+<td width="4%"></td>
+<td width="52%">
+
+<p>Pointer alignment problems</p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>3.6</p>
+</td>
+<td width="4%"></td>
+<td width="18%">
+
+<p>Libraries</p>
+</td>
+<td width="61%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4.</p>
+</td>
+<td width="6%"></td>
+<td width="30%">
+
+<p>How lint checks</p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>4.1</p>
+</td>
+<td width="4%"></td>
+<td width="58%">
+
+<p>The first pass data structure</p>
+</td>
+<td width="21%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>4.2</p>
+</td>
+<td width="4%"></td>
+<td width="66%">
+
+<p>The first pass checking mechanism</p>
+</td>
+<td width="13%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>4.3</p>
+</td>
+<td width="4%"></td>
+<td width="60%">
+
+<p>The second pass data structure</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="6%">
+
+<p>4.4</p>
+</td>
+<td width="4%"></td>
+<td width="68%">
+
+<p>The second pass checking mechanism</p>
+</td>
+<td width="11%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5.</p>
+</td>
+<td width="6%"></td>
+<td width="48%">
+
+<p>How to make lint shut up</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>6.</p>
+</td>
+<td width="6%"></td>
+<td width="24%">
+
+<p>User options</p>
+</td>
+<td width="65%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>7.</p>
+</td>
+<td width="6%"></td>
+<td width="58%">
+
+<p>Ideas for further development</p>
+</td>
+<td width="31%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>8.</p>
+</td>
+<td width="6%"></td>
+<td width="38%">
+
+<p>Testing the program</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>9.</p>
+</td>
+<td width="6%"></td>
+<td width="20%">
+
+<p>References</p>
+</td>
+<td width="69%">
+</td>
+</table>
+
+<p>Appendix A &minus; The warnings<br>
+Appendix B &minus; The Ten Commandments for C
+programmers</p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>C [1][2] is a dangerous programming language. The
+programmer is allowed to do almost anything, as long as the
+syntax of the program is correct. This has a reason. In this
+way it is possible to make a fast compiler which produces
+fast code. The compiler will be fast because it
+doesn&rsquo;t do much checking at compile time. The code is
+fast because the compiler doesn&rsquo;t generate run time
+checks. The programmer should protect himself against
+producing error prone code. One way to do that is to obey
+the <i>Ten Commandments for C programmers</i> [appendix B].
+This document describes an implementation of the <i>lint</i>
+program, as referred to in Commandment 1. It is a common
+error to run <i>lint</i> only after a few hours of debugging
+and some bug can&rsquo;t be found. <i>Lint</i> should be run
+when large pieces of new code are accepted by the compiler
+and as soon as bugs arise. Even for working programs it is
+useful to run <i>lint,</i> because it can find constructions
+that may lead to problems in the future.</p>
+<a name="2. Outline of the program"></a>
+<h2>2. Outline of the program</h2>
+
+<p>The program can be divided into three parts. A first
+pass, which parses C program files and outputs definitions,
+a second pass which processes the definitions and a driver,
+which feeds the set of files to the first pass and directs
+its output to the second pass. Both passes produce the
+warnings on standard error output, which are redirected to
+standard output by the driver.</p>
+
+<p>The first pass is based on an existing C front end,
+called <i>cem</i> [3]. <i>Cem</i> is part of the Amsterdam
+Compiler Kit (ACK), as described in [4].</p>
+
+<p>Most of the code of <i>cem</i> is left unchanged. This
+has several reasons. A lot of work, which is done by
+<i>cem</i> , must also be done by <i>lint.</i> E.g. the
+lexical analysis, the macro expansions, the parsing part and
+the semantical analysis. Only the code generation part is
+turned off. An advantage of this approach is, that a person
+who understands <i>cem</i> will not have to spend to much
+time in understanding <i>lint.</i></p>
+
+<p>All changes and extensions to <i>cem</i> can be turned
+off by not defining the compiler directive <tt>LINT.</tt>
+Compiling should then result in the original C compiler.</p>
+
+<p>The second pass is a much less complex program. It reads
+simple definitions generated by the first pass and checks
+their consistency. This second pass gives warnings about
+wrong usage of function arguments, their results and about
+external variables, which are used and defined in more than
+one file.</p>
+
+<p>The driver is a shell program, to be executed by the
+<small>UNIX</small> &reg; shell <i>sh.</i> It executes the
+two passes and let them communicate through a filter (sort).
+Actually it is simplex communication: the first pass only
+talks to the second pass through the filter.</p>
+<a name="3. What lint checks"></a>
+<h2>3. What lint checks</h2>
+<a name="3.1. Set, used and unused variables"></a>
+<h2>3.1. Set, used and unused variables</h2>
+
+<p>We make a distinction between two classes of variables:
+the class of automatic variables (including register
+variables) and the other variables. The other variables,
+global variables, static variables, formal parameters et
+cetera, are assumed to have a defined value. Global
+variables e.g., are initialized by the compiled code at
+zeros; formal parameters have a value which is equal to the
+value of the corresponding actual parameter. These variables
+can be used without explicitly initializing them. The
+initial value of automatic variables is undefined (if they
+are not initialized at declaration). These variables should
+be set before they are used. A variable is set by</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>an assignment (including an initialization)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p>taking the address</p>
+</td>
+<td width="43%">
+</td>
+</table>
+
+<p>The first case is clear. The second case is plausible.
+It would take to much effort (if at all possible) to check
+if a variable is set through one of its aliases. Because
+<i>lint</i> should not warn about correct constructs, it
+does this conservative approach. Structures (and unions) can
+also be set by setting at least one member. Again a
+conservative approach. An array can be set by using its name
+(e.g. as actual parameter of a function call). <i>Lint</i>
+warns for usage as <i>rvalue</i> of automatic variables
+which are not set.</p>
+
+<p>A variable is used if</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="44%">
+
+<p>it is used as a <i>rvalue</i></p>
+</td>
+<td width="35%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>2</p>
+</td>
+<td width="8%"></td>
+<td width="40%">
+
+<p>its address is taken</p>
+</td>
+<td width="39%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>Arrays and structures (and unions) are also used if one
+entry or one member respectively is used.</p>
+</td>
+</table>
+
+<p>When a variable is never used in the part of the program
+where it is visible, a warning is given. For variables
+declared at the beginning of a compound statement, a check
+is made at the end of this statement. For formal parameters
+a check is made at the end of the function definition. At
+the end of a file this is done for global static
+definitions. For external variables a warning can be given
+when all the files are parsed.</p>
+<a name="3.2. Flow of control"></a>
+<h2>3.2. Flow of control</h2>
+
+<p>The way <i>lint</i> keeps track of the flow of control
+is best explained by means of an example. See the program of
+figure 1.</p>
+<pre>   if (cond)
+        /* a statement which is executed if cond is true,
+         * the if-part
+         */
+   else
+        /* the else-part */
+
+
+</pre>
+
+<p align=center><i>figure 1.</i></p>
+
+<p>After evaluation of <tt>cond</tt>, two things can
+happen. The if-part is executed or the else-part is executed
+(but not both). Variables which are set in the if-part but
+not in the else-part, need not be set after the if
+statement, and vice versa. <i>Lint</i> detects this and
+assumes these variables after the if statement to be
+<i>maybe set</i>. (See figure 2.)</p>
+<pre>  int cond;
+
+
+  main()
+  {
+          int i, j;
+
+
+          if (cond) {
+                  i = 0;
+                  j = 0;
+          }
+          else
+                  use(i);  /* i may be used before set */
+          use(j);          /* maybe j used before set  */
+  }
+
+
+</pre>
+
+<p align=center><i>figure 2.</i></p>
+
+<p>If both the if-part and the else-part are never left
+(i.e. they contain an endless loop or a return statement),
+<i>lint</i> knows that the if statement is never left too.
+Besides the if statement, <i>lint</i> knows the possible
+flows of control in while, do, for and switch statements. It
+also detects some endless loops like <tt>while(1)</tt>,
+<tt>do ... while (1)</tt>, <tt>for (;;)</tt>.</p>
+<a name="3.3. Functions"></a>
+<h2>3.3. Functions</h2>
+
+<p>Most C compilers will not complain if a function is
+called with actual parameters of a different type than the
+function expects. Using a function in one file as a function
+of type <i>A</i> while defining it in another file as a
+function of type <i>B</i> is also allowed by most compilers.
+It needs no explanation that this can lead to serious
+trouble.</p>
+
+<p><i>Lint</i> checks if functions are called with the
+correct number of arguments, if the types of the actual
+parameters correspond with the types of the formal
+parameters and if function values are used in a way
+consistently with their declaration. When the result of a
+function is used, a check is made to see if the function
+returns a value. When a function returns a value,
+<i>lint</i> checks if the values of all calls of this
+function are used.</p>
+<a name="3.4. Undefined evaluation order"></a>
+<h2>3.4. Undefined evaluation order</h2>
+
+<p>The semantics of C do not define evaluation orders for
+some constructs, which, at first sight, seem well defined.
+The evaluation order of the expression <tt>a[i] = i++;</tt>
+e.g., is undefined. It can be translated to something with
+the semantics of <tt>a[i] = i; i++;</tt> which is what
+probably was meant, or <tt>a[i+1] = i; i++;.</tt> An easier
+example to explain why, is <tt>j = a[i] + i++;.</tt>
+&lsquo;<tt>+</tt>&rsquo; Is a so called <i>commutative</i>
+operator (with respect to the evaluation order) , as is
+&lsquo;<tt>=</tt>&rsquo;. This allows the compiler to choose
+which term to evaluate first. It is easy to see, that it
+makes a difference for the value of <tt>j,</tt> which order
+is chosen. The expression <tt>i++</tt> is said to have
+<i>side effects.</i> It affects the value of <tt>i.</tt>
+Because this value is used in the other term, this gives a
+conflict.</p>
+
+<p>A function call with reference to a variable as argument
+can have side effects to. Therefor, the evaluation order of
+<tt>i</tt> in the expression <tt>f(&amp;i) + i</tt> is
+undefined. When a function is called with an array as
+argument, this array can be affected by the function,
+because only the address of the array is passed to the
+function. (In Pascal a copy of the array is passed to the
+function if the formal parameter is not declared
+<i>var</i>.) So the evaluation order of <tt>a</tt> in the
+expression <tt>f(a) + a[0]</tt> is undefined. This one is
+not yet detected by <i>lint.</i></p>
+
+<p>Global variables can still cause trouble. If function
+<tt>f</tt> affects the global variable <tt>i,</tt> the value
+of the expression <tt>f() + i</tt> is undefined, because the
+evaluation order of <tt>i</tt> is undefined.</p>
+
+<p>The evaluation order of the arguments of a function is
+not defined, so the expression <tt>f(i, i++)</tt> gives a
+warning <tt>i evaluation order undefined.</tt></p>
+<a name="3.5. Pointer alignment problems"></a>
+<h2>3.5. Pointer alignment problems</h2>
+
+<p>For pointers to objects of different types there are
+different alignment restrictions. On some machines pointers
+to type char can have both odd and even values, whereas
+pointers to type int should contain an even address.
+<i>Lint</i> could warn for all pointer conversions. This is
+not what <i>lint</i> does. <i>Lint</i> assumes that some
+pointers are more restricted than others, and that pointers
+of some types can safely be converted to a pointer of a less
+restrictive type. The order of restriction is as follows
+(&lsquo;&le;&rsquo; means &lsquo;is not more restricted
+than&rsquo;) :</p>
+
+<p align=center>char &le; short &le; int &le; long</p>
+
+<p align=center>float &le; double</p>
+<a name="3.6. Libraries"></a>
+<h2>3.6. Libraries</h2>
+
+<p>C is a small language. As a matter of fact it has no i/o
+routines. To make it a useful language, C is supported by
+libraries. These libraries contain functions and variables
+that can be used by any C program. <i>Lint</i> knows some
+libraries too. At this moment it knows the
+&lsquo;-<i>lc</i>&rsquo;, &lsquo;-<i>lm</i>&rsquo; and
+&lsquo;-<i>lcurses</i>&rsquo; libraries. The
+&lsquo;-<i>lc</i>&rsquo; library, containing definitions for
+functions from chapter two and three of the
+<small>UNIX</small> programmers manual, is default.
+<i>Lint</i> warns for definitions of functions or global
+variables with the same name as a function definition in a
+library.</p>
+<a name="4. How lint checks"></a>
+<h2>4. How lint checks</h2>
+<a name="4.1. The first pass first pass data structure"></a>
+<h2>4.1. The first pass first pass data structure</h2>
+
+<p>The data structure of <i>cem</i> is changed a little and
+some structures have been added.</p>
+<a name="4.1.1. The changes"></a>
+<h2>4.1.1. The changes</h2>
+<a name="4.1.1.1. Idf descriptor"></a>
+<h2>4.1.1.1. Idf descriptor</h2>
+
+<p>A member <tt>id_line</tt> is added to the <i>idf</i>
+selector. This line number is used for some warnings.</p>
+<a name="4.1.1.2. Def descriptor"></a>
+<h2>4.1.1.2. Def descriptor</h2>
+
+<p>The <i>def</i> selector is extended with the members
+<tt>df_set</tt> df_line. The <tt>df_used</tt> member did
+exist already, but was only used for code generation. This
+usage is eliminated so it can be used by <i>lint.</i> The
+meaning of these members should be clear.</p>
+<a name="4.1.2. The additions"></a>
+<h2>4.1.2. The additions</h2>
+<a name="4.1.2.1. Lint_stack_entry descriptor"></a>
+<h2>4.1.2.1. Lint_stack_entry descriptor</h2>
+<pre>     struct lint_stack_entry {
+             struct lint_stack_entry *next;
+             struct lint_stack_entry *previous;
+             short ls_class;
+             int ls_level;
+             struct state *ls_current;
+             union {
+                     struct state *S_if;
+                     struct state *S_end;
+                     struct switch_states switch_state;
+             } ls_states;
+     };
+</pre>
+
+<p>Structure to simulate a stacking mechanism.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><tt>next</tt></p>
+</td>
+<td width="22%"></td>
+<td width="70%">
+
+<p>Pointer to the entry on top of this one.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><tt>previous</tt></p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>Pointer to the entry beneath this one.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><tt>ls_class</tt></p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>The class of statement this entry belongs to. Possible
+classes are <tt>IF</tt>, <tt>WHILE</tt>, <tt>DO</tt>,
+<tt>FOR</tt>, <tt>SWITCH</tt> and <tt>CASE</tt>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><tt>ls_level</tt></p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>The level the corresponding statement is nested.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><tt>ls_current</tt></p>
+</td>
+<td width="10%"></td>
+<td width="70%">
+
+<p>A pointer to the state descriptor which describes the
+state of the function (the state of the automatic variables,
+if the next statement can be reached, et cetera) if control
+passes the flow of control to the part of the program
+currently parsed. The initialization of this state is as
+follows</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="39%"></td>
+<td width="60%">
+<p>If <tt>ls_class</tt> in [<tt>IF</tt>, <tt>SWITCH</tt>]
+the state after parsing the conditional expression.</p>
+<!-- INDENTATION -->
+<p>If <tt>ls_class</tt> in [<tt>WHILE</tt>, <tt>FOR</tt>]
+the state after parsing the code between the brackets.</p>
+<!-- INDENTATION -->
+<p>If <tt>ls_class</tt> in [<tt>DO</tt>, <tt>CASE</tt>] the
+state at entrance of the statement after the <tt>DO</tt> or
+<tt>CASE</tt> token.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><tt>ls_states</tt></p>
+</td>
+<td width="12%"></td>
+<td width="70%">
+
+<p>Union of pointers to state descriptors containing
+different information for different values of
+<tt>ls_class</tt>.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="39%"></td>
+<td width="60%">
+<p>If <tt>ls_class</tt> is <tt>IF</tt> and in case of
+parsing an else part, <tt>ls_states.S_if</tt> points to the
+state that is reached after the if part.</p>
+<!-- INDENTATION -->
+<p>If <tt>ls_class</tt> in [<tt>WHILE</tt>, <tt>FOR</tt>,
+<tt>DO</tt>] then <tt>ls_states.S_end</tt> contains a
+conservative description of the state of the program after
+&lsquo;jumping&rsquo; to the end of the statement after the
+<tt>WHILE</tt>, <tt>DO</tt> or <tt>FOR</tt> token. I.e. the
+state at reaching a break (not inside a switch) or continue
+statement.</p>
+<!-- INDENTATION -->
+<p>If ls_class is <tt>SWITCH</tt>, <tt>ls_states</tt> is
+used as a structure</p>
+<!-- INDENTATION -->
+<pre>     struct switch_states {
+             struct state S_case;
+             struct state S_break;
+     };
+</pre>
+<!-- INDENTATION -->
+<p>containing two pointers to state descriptors.
+<tt>ls_states.switch_state.S_case</tt> contains a
+conservative description of the state of the program after
+<tt>case ... case</tt> parts are parsed.
+<tt>ls_states.switch_state.S_break</tt> the state after
+parsing all the <tt>case ... break</tt> parts. The reason
+for <tt>ls_states.switch_state.default_met</tt> should be
+self-explanatory.</p>
+<!-- INDENTATION -->
+<p>In case <tt>ls_class</tt> is <tt>CASE</tt>,
+<tt>ls_states</tt> is not used.</p>
+</td>
+</table>
+<a name="4.1.2.2. State descriptor"></a>
+<h2>4.1.2.2. State descriptor</h2>
+<pre>           struct state {
+                   struct state *next;
+                   struct auto_def *st_auto_list;
+                   int st_nrchd;
+                   int st_warned;
+           };
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p>st_auto_list</p>
+</td>
+<td width="6%"></td>
+<td width="70%">
+
+<p>Pointer to a list of definitions of the automatic
+variables whose scope contain the current position in the
+program.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><tt>st_nrchd</tt></p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>True if the next statement can&rsquo;t be reached.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><tt>st_warned</tt></p>
+</td>
+<td width="12%"></td>
+<td width="70%">
+
+<p>True if a warning has already been given.</p>
+</td>
+</table>
+<a name="4.1.2.3. Auto_def descriptor"></a>
+<h2>4.1.2.3. Auto_def descriptor</h2>
+<pre>               struct auto_def {
+                       struct auto_def *next;
+                       struct idf *ad_idf;
+                       struct def *ad_def;
+                       int ad_used;
+                       int ad_set;
+                       int ad_maybe_set;
+               };
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>next</p>
+</td>
+<td width="22%"></td>
+<td width="70%">
+
+<p>Points to the next auto_definition of the list.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><tt>ad_idf</tt></p>
+</td>
+<td width="18%"></td>
+<td width="70%">
+
+<p>Pointer to the idf descriptor associated with this
+auto_definition.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><tt>ad_def</tt></p>
+</td>
+<td width="18%"></td>
+<td width="50%">
+
+<p>Ditto for def descriptor.</p>
+</td>
+<td width="19%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><tt>ad_used</tt></p>
+</td>
+<td width="16%"></td>
+<td width="70%">
+
+<p>Indicates the state of this automatic variable. Ditto
+for <tt>ad_set</tt> and <tt>ad_maybe_set</tt>. Only one of
+<tt>ad_set</tt> and <tt>ad_maybe_set</tt> may be true.</p>
+</td>
+</table>
+<a name="4.1.2.4. Expr_state descriptor"></a>
+<h2>4.1.2.4. Expr_state descriptor</h2>
+<pre>              struct expr_state {
+                      struct expr_state *next;
+                      struct idf *es_idf;
+                      arith es_offset;
+                      int es_used;
+                      int es_set;
+              };
+</pre>
+
+<p>This structure is introduced to keep track of which
+variables, array entries and structure members (union
+members) are set and/or used in evaluating an
+expression.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><tt>next</tt></p>
+</td>
+<td width="22%"></td>
+<td width="70%">
+
+<p>Pointer to the next descriptor of this list.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><tt>es_idf</tt></p>
+</td>
+<td width="18%"></td>
+<td width="70%">
+
+<p>Pointer to the idf descriptor this descriptor belongs
+to.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><tt>es_offset</tt></p>
+</td>
+<td width="12%"></td>
+<td width="70%">
+
+<p>In case of an array, a structure or union, this member
+contains the offset the compiler would generate for locating
+the array entry or structure/union member.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><tt>es_used</tt></p>
+</td>
+<td width="16%"></td>
+<td width="70%">
+
+<p>True if the indicated memory location is used in
+evaluating the expression.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><tt>es_set</tt></p>
+</td>
+<td width="18%"></td>
+<td width="28%">
+
+<p>Ditto for set.</p>
+</td>
+<td width="41%">
+</td>
+</table>
+<a name="4.1.2.5. Outdef descriptor"></a>
+<h2>4.1.2.5. Outdef descriptor</h2>
+<pre>             struct outdef {
+                     int od_class;
+                     char *od_name;
+                     char *od_file;
+                     unsigned int od_line;
+                     int od_nrargs;
+                     struct tp_entry *od_entry;
+                     int od_returns;
+                     struct type *od_type;
+             };
+</pre>
+
+<p>As structures of this type are not allocated dynamically
+by a storage allocator, it contains no next member. An
+outdef can be given to to <tt>output_def()</tt> to be passed
+to the second pass. Basically this forms the interface with
+the second pass.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><tt>od_class</tt></p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>Indicates what kind of definition it is. Possible
+classes are <tt>EFDF</tt>, <tt>EVDF</tt>, <tt>SFDF</tt>,
+<tt>SVDF</tt>, <tt>LFDF</tt>, <tt>LVDF</tt>, <tt>EFDC</tt>,
+<tt>EVDC</tt>, <tt>IFDC</tt>, <tt>FC</tt>, <tt>VU</tt>.
+([<tt>E</tt>xternal, <tt>S</tt>tatic, <tt>L</tt>ibrary,
+<tt>I</tt>mplicit] [<tt>F</tt>unction, <tt>V</tt>ariable]
+[<tt>D</tt>e<tt>F</tt>inition,
+<tt>D</tt>e<tt>C</tt>laration, <tt>C</tt>all,
+<tt>U</tt>sage])</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><tt>od_name</tt></p>
+</td>
+<td width="16%"></td>
+<td width="70%">
+
+<p>The name of the function or variable.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><tt>od_file</tt></p>
+</td>
+<td width="16%"></td>
+<td width="70%">
+
+<p>The file this definition comes from.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><tt>od_nrargs</tt></p>
+</td>
+<td width="12%"></td>
+<td width="70%">
+
+<p>If <tt>od_class</tt> is one of <tt>EFDF</tt>,
+<tt>SFDF</tt> or <tt>LFDF</tt>, this member contains the
+number of arguments this function has. If the function was
+preceded by the pseudocomment <tt>/* VARARGS */</tt>,
+<tt>od_nrargs</tt> gets the value <tt>-1-n</tt>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><tt>od_entry</tt></p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>A pointer to a list of <tt>od_nrargs</tt> cells, each
+containing a pointer to the type descriptor of an argument.
+(<tt>-1-od_nrargs</tt> cells if <tt>od_nrargs &lt; 0</tt>.)
+<tt>Tp_entry</tt> is defined as</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="70%">
+<pre>struct tp_entry {
+        struct tp_entry *next; /* pointer to next cell */
+        struct type *te_type;  /* an argument type     */
+};
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>od_returns</p>
+</td>
+<td width="10%"></td>
+<td width="70%">
+
+<p>For classes <tt>EFDF</tt>, <tt>SFDF</tt> and
+<tt>LFDF</tt> this member tells if the function returns an
+expression or not. In case <tt>od_class</tt> is <tt>FC</tt>
+it is true if the value of the function is used, false
+otherwise. For other classes this member is not used.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><tt>od_type</tt></p>
+</td>
+<td width="16%"></td>
+<td width="70%">
+
+<p>A pointer to the type of the function or variable
+defined or declared. Not used for classes <tt>FC</tt> and
+<tt>VU</tt>.</p>
+</td>
+</table>
+<a name="4.2. The first pass checking mechanism"></a>
+<h2>4.2. The first pass checking mechanism</h2>
+
+<p>In the description of the implementation of the pass one
+warnings, it is assumed that the reader is familiar with the
+<i>LLgen</i> parser generator, as described in [6].</p>
+<a name="4.2.1. Used and/or set variables"></a>
+<h2>4.2.1. Used and/or set variables</h2>
+
+<p>To be able to give warnings like <tt>%s used before
+set</tt> and <tt>%s set but not used in function %s</tt> ,
+there needs to be a way to keep track of the state of a
+variable. A first approach to do this was by adding two
+fields to the <i>def</i> selector: <tt>df_set</tt> and
+<tt>df_used.</tt> While parsing the program, each time an
+expression was met this expression was analyzed and the
+fields of each <i>def</i> selector were possibly set during
+this analysis. This analysis was done by passing each
+expression to a function <tt>lint_expr</tt> , which walks
+the expression tree in a way similar to the function
+<tt>EVAL</tt> in the file <i>eval.c</i> of the original
+<i>cem</i> compiler. This approach has one big disadvantage:
+it is impossible to keep track of the flow of control of the
+program. No warning will be given for the program fragment
+of figure 3.</p>
+<pre>  func()
+  {
+          int i;
+
+
+          if (cond)
+                  i = 0;
+          else
+                  use(i);  /* i may be used before set */
+  }
+
+
+</pre>
+
+<p align=center>figure 3.</p>
+
+<p>It is clear that it would be nice having <i>lint</i>
+warn for this construction.</p>
+
+<p>This was done in the second approach. When there was a
+choice between two statements, each statement was parsed
+with its own copy of the state at entrance of the
+<i>choosing statement.</i> A state consisted of the state of
+the automatic variables (including register variables). In
+addition to the possibilities of being used and set, a
+variable could be <i>maybe set</i>. These states were passed
+between the statement parsing routines using the
+<i>LLgen</i> parameter mechanism. At the end of a choosing
+statement, the two states were merged into one state, which
+became the state after this statement. The construction of
+figure 4 was now detected, but switch statements still gave
+problems and continue and break statements were not
+understood. The main problem of a switch statement is, that
+the closing bracket (&lsquo;<tt>)</tt>&rsquo;) has to be
+followed by a <i>statement</i>. The syntax shows no choice
+of statements, as is the case with if, while, do and for
+statements. Using the <i>LLgen</i> parameter mechanism, it
+is not a trivial task to parse the different case parts of a
+switch statement with the same initial state and to merge
+the results into one state. This observation led to the
+third and final approach, as described next.</p>
+
+<p>Instead of passing the state of the program through the
+statements parsing routines using the <i>LLgen</i>
+parameters, a special stack is introduced, the
+<i>lint_stack.</i> When a choosing statement is parsed, an
+entry is pushed on the stack containing the information that
+is needed to keep track of the state of the program. Each
+entry contains a description of the <i>current</i> state of
+the program and a field that indicates what part of the
+program the parser is currently parsing. For all the
+possible choosing statements I describe the actions to be
+taken.</p>
+
+<p>At entrance of an if statement, an entry is pushed on
+the stack with the current state being a copy of the current
+state of the stack element one below. The class of this
+entry is <tt>IF</tt>. At reaching the else part, the current
+state is moved to another place in this stack entry (to
+<tt>S_IF</tt>), and a new copy of the current state at
+entrance of this if statement is made. At the end of the
+else part, the two states are merged into one state, the new
+current state, and the <tt>IF</tt> entry is popped from the
+stack. If there is no else part, then the state that is
+reached after parsing the if part is merged with the current
+state at entrance of the if statement into the new current
+state.</p>
+
+<p>At entrance of a while statement a <tt>WHILE</tt> entry
+is pushed on the stack containing a copy of the current
+state. If a continue or break statement is met in the while
+statement, the state at reaching this continue or break
+statement is merged with a special state in the
+<tt>WHILE</tt> entry, called <tt>S_END</tt>. (If
+<tt>S_END</tt> did not yet contain a state, the state is
+copied to <tt>S_END</tt>.) At the end of the while statement
+this <tt>S_END</tt> is merged with the current state, which
+result is merged with the state at entrance of the while
+statement into the new current state.</p>
+
+<p>A for statement is treated similarly. A do statement is
+treated the same way too, except that <tt>S_END</tt>
+isn&rsquo;t merged with the state at entrance of the do
+statement, but becomes the new current state.</p>
+
+<p>For switch statements a <tt>SWITCH</tt> entry is pushed
+on the stack. Apart from the current state, this entry
+contains two other states, <tt>S_BREAK</tt> and
+<tt>S_CASE</tt>. <tt>S_BREAK</tt> initially contains no
+state, <tt>S_CASE</tt> initially contains a copy of the
+current state at entrance of the switch statement. After
+parsing a case label, a <tt>CASE</tt> entry is pushed on the
+stack, containing a copy of the current state. If, after
+zero or more statements, we meet another case label, the
+state at reaching this case label is merged with
+<tt>S_CASE</tt> of the <tt>SWITCH</tt> entry below and a new
+copy of the state at entrance of the switch statement is put
+in the <tt>CASE</tt> entry. If we meet a break statement, we
+merge the current state with <tt>S_BREAK</tt> of the
+<tt>SWITCH</tt> entry below and pop the <tt>CASE</tt> entry.
+In addition to this, the occurrence of a default statement
+inside the switch statement is recorded in the
+<tt>SWITCH</tt> entry. At the end of the switch statement we
+check if we have met a default statement. If not,
+<tt>S_BREAK</tt> is merged with the current state at
+entrance of the switch statement. (Because it is possible
+that no case label will be chosen.) Next the <tt>S_CASE</tt>
+is &lsquo;special_merged&rsquo; with <tt>S_BREAK</tt> into
+the new current state. For more details about these merge
+functions see the sources.</p>
+
+<p>With the approach described above, <i>lint</i> is aware
+of the flow of control in the program. There still are some
+doubtful constructions <i>lint</i> will not detect and there
+are some constructions (although rare) for which <i>lint</i>
+gives an incorrect warning (see figure 4).</p>
+<pre>       {
+               int i;
+
+
+               for (;;) {
+                       if (cond) {
+                               i = 0;
+                               break;
+                       }
+               }
+               use(i);
+               /* lint warns: maybe i used before set
+                * although  the  fragment  is correct
+                */
+       }
+
+
+</pre>
+
+<p align=center><i>figure 4.</i></p>
+
+<p>A nice advantage of the method is, that the parser stays
+clear, i.e. it isn&rsquo;t extended with extra parameters
+which must pass the states. In this way the parser still is
+very readable and we have a nice interface with <i>lint</i>
+using function calls.</p>
+<a name="4.2.2. Undefined evaluation orders"></a>
+<h2>4.2.2. Undefined evaluation orders</h2>
+
+<p>In expressions the values of some variables are used and
+some variables are set. Of course, the same holds for
+subexpressions. The compiler is allowed to choose the order
+of evaluation of subexpressions involving a commutative and
+associative operator (<tt>*</tt>, <tt>+</tt>,
+<tt>&amp;</tt>, <tt>|</tt>, <tt>^</tt>), the comma in a
+parameter list or an assignment operator. In section 3.4 it
+is made clear that this will lead to statements with
+ambiguous semantics.</p>
+
+<p>The way these constructs are detected is rather straight
+forward. The function which parses an expression
+(<tt>lint_expr</tt>) returns a linked list containing
+information telling which variables are set and which
+variables are used. A variable is indicated by its
+<i>idf</i> descriptor and an <i>offset.</i> This offset is
+needed for discriminating entries of the same array and
+members of the same structure or union, so it is possible to
+warn about the statement <tt>a[b[0]] = b[0]++;.</tt> When
+<tt>lint_expr</tt> meets a commutative operator (with
+respect to the evaluation order), it calls itself
+recursively with the operands of the operator as expression.
+The returned results are checked for undefined evaluation
+orders and are put together. This is done by the function
+<tt>check_and_merge</tt>.</p>
+<a name="4.2.3. Useless statements"></a>
+<h2>4.2.3. Useless statements</h2>
+
+<p>Statements which compute a value that is not used, are
+said to have a <i>null effect</i>. Examples are <tt>x = 2,
+3;</tt>, <tt>f() + g();</tt> and <tt>*p++;</tt>. (<tt>*</tt>
+and <tt>++</tt> have the same precedence and associate from
+right to left.)</p>
+
+<p>A conditional expression computes a value too. If this
+value isn&rsquo;t used, it is better to use an if-else
+statement. So, if <i>lint</i> sees</p>
+<pre>                       b ? f() : g();
+</pre>
+
+<p>it warns <tt>use if-else construction</tt>.</p>
+<a name="4.2.4. Not-reachable statements"></a>
+<h2>4.2.4. Not-reachable statements</h2>
+
+<p>The algorithm to detect not-reachable statements
+(including not reachable initializations) is as follows.
+Statements after a label and a case statement and the
+compound statement of a function are always reachable. Other
+statements are not-reachable after:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>a goto statement</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>a return statement</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>a break statement</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>a continue statement</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>a switch statement</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>an endless loop (a while, do or for loop with a
+conditional which always evaluates to true and without a
+break statement)</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>an if-else statement of which both if part and else part
+end up in a not-reachable state</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>a switch statement of which all <tt>case ... break</tt>
+parts (including a <tt>default ... break</tt> part) end up
+in a not-reachable state</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>the pseudocomment <tt>/* NOTREACHED */</tt></p>
+</td>
+</table>
+
+<p>The algorithm is easily implemented using the
+<tt>st_nrchd</tt> selector in the <i>state</i> descriptor.
+The <tt>st_warned</tt> selector is used to prevent
+superfluous warnings. To detect an endless loop, after a
+while (&lt;true&gt;), for (..;&lt;true&gt;;..) and do part
+the current state of the stack entry beneath the top one is
+set to not reached. If, in the statement following, a break
+statement is met, this same state is set to reached. If the
+while (&lt;cond&gt;) part of the do statement is met, this
+state is set to reached if &lt;cond&gt; doesn&rsquo;t
+evaluates to true. The detection of not-reachable statements
+after a switch statement is done in a similar way. In
+addition it is checked if a default statement isn&rsquo;t
+met, in which case the statement after the switch statement
+can be reached. The warning <tt>statement not reached</tt>
+is not given for compound statements. If <i>lint</i> did, it
+would warn for the compound statement in a switch statement,
+which would be incorrect.</p>
+
+<p>Not-reachable statements are still interpreted by
+<i>lint.</i> I.e. when <i>lint</i> warns that some statement
+can&rsquo;t be reached, it assumes this is not what the
+programmer really wants and it ignores this fact. In this
+way a lot of useless warnings are prevented in the case of a
+not-reachable statement. See figure 5.</p>
+<pre> {
+         int i;
+
+
+         for (;;) {
+                 /* A loop in which the programmer
+                  * forgot to introduce a conditional
+                  * break statement.
+                  * Suppose i is not used in this part.
+                  */
+         }
+         /* some more code in which i is used */
+ }
+ /* The warning &quot;statement not reached&quot; highlights the bug.
+  * An additional warning &quot;i unused in function %s&quot; is
+  * formally correct, but doesn&rsquo;t provide the programmer
+  * with useful information.
+  */
+
+
+</pre>
+
+<p align=center><i>figure 5.</i></p>
+<a name="4.2.5. Functions returning expressions and just returning"></a>
+<h2>4.2.5. Functions returning expressions and just returning</h2>
+
+<p>Each time a return statement is met, <i>lint</i> checks
+if an expression is returned or not. If a function has a
+return with expression and a return without expression,
+<i>lint</i> warns <tt>function %s has return(e); and
+return;.</tt> If the flow of control can <i>fall through</i>
+the end of the compound statement of a function, this
+indicates an implicit return statement without an
+expression. If the end of the compound statement of the
+function can be reached, <i>lint</i> introduces this
+implicit return statement without expression.</p>
+
+<p>Sometimes the programmer knows for sure that all case
+parts inside a switch statement include all possible cases,
+so he doesn&rsquo;t introduce a default statement. This can
+lead to an incorrect warning. Figure 6 shows how to prevent
+this warning.</p>
+<pre>            func()
+            {
+                    switch (cond) {
+                    case 0: return(e0);
+                    case 1: return(e1);
+                    }
+                    /* NOTREACHED */
+            }
+/* no warning: &quot;function func has return(e); and return; */
+
+
+</pre>
+
+<p align=center><i>figure 6.</i></p>
+
+<p>The pseudocomment <tt>/* NOTREACHED */</tt> can also be
+used to tell <i>lint</i> that some function doesn&rsquo;t
+return. See figure 7.</p>
+<pre>  func()
+  {
+          switch (cond) {
+          case 0: return(e0);
+          case 1: return(e1);
+          default: error();   /* calls exit or abort */
+                   /* NOTREACHED */
+          }
+  }
+/* no warning: &quot;function func has return(e); and return;&quot; */
+
+
+</pre>
+
+<p align=center>figure 7.</p>
+<a name="4.2.6. Output definitions for the second pass"></a>
+<h2>4.2.6. Output definitions for the second pass</h2>
+
+<p>The first pass can only process one program file. To be
+able to process a program that spreads over more than one
+file, the first pass outputs definitions that are processed
+by a second pass. The format of such a definition is
+different for different classes:</p>
+
+<p>For class in {EFDF, SFDF, LFDF}</p>
+
+
+<p align=center>&lt;name&gt;:&lt;class&gt;:&lt;file&gt;:&lt;line&gt;:&lt;nr
+of args&gt;:&lt;type of args&gt;:&lt;returns
+value&gt;:&lt;type&gt;</p>
+
+<p>A negative <i>nr of args</i> indicates that the function
+can be called with a varying number of arguments.</p>
+
+<p>For class = FC</p>
+
+
+<p align=center>&lt;name&gt;:&lt;class&gt;:&lt;file&gt;:&lt;line&gt;:&lt;value
+is used&gt;:&lt;type&gt;</p>
+
+<p>The <i>value is used</i> part can have three meanings:
+the value of the function is ignored; the value of the
+function is used; the value of the function is cast to type
+<i>void</i>.</p>
+
+<p>For other classes</p>
+
+
+<p align=center>&lt;name&gt;:&lt;class&gt;:&lt;file&gt;:&lt;line&gt;:&lt;type&gt;</p>
+
+<p>Definitions of class VU (Variable Usage) are only output
+for <i>used</i> global variables.</p>
+
+<p>Structure and union types that are output to the
+intermediate file are simplified. (The following occurrences
+of <i>structure</i> should be read as <i>structure or
+union</i> and <i>struct</i> as <i>struct or union</i>.)
+Structures that are identified by a <i>structure tag</i> are
+output to the intermediate file as <tt>struct
+&lt;tag&gt;</tt>. Structures without a structure tag are
+output as <tt>struct {&lt;mems&gt;}</tt> with
+<tt>&lt;mems&gt;</tt> a semicolon-separated list of types of
+the members of this structure. An alternative way would be
+to output the complete structure definition. However, this
+gives practical problems. It is allowed to define some
+object of a structure type with a structure tag, without
+this structure being defined at that place. The first
+approach leaves errors, such as in figure 8, undetected.</p>
+<pre>       &quot;a.c&quot;                           &quot;b.c&quot;
+
+
+   struct str {                    struct str {
+           float f;                        int i;
+   } s;                            };
+
+
+   main()                          func(s)
+   {                                       struct str s;
+           func(s);                {}
+   }
+
+
+</pre>
+
+<p align=center>figure 8.</p>
+
+<p>To be able to detect these errors, the first pass should
+also output definitions of structure tags. The example of
+figure 8 would then get a warning like <tt>structure str
+defined inconsistently</tt></p>
+
+<p>More information on these definitions in section 4.3 and
+4.4.</p>
+<a name="4.2.7. Generating libraries"></a>
+<h2>4.2.7. Generating libraries</h2>
+
+<p><i>Lint</i> knows the library &lsquo;-lc&rsquo;,
+&lsquo;-lm&rsquo; and &lsquo;-lcurses&rsquo;. If a program
+uses some other library, it is possible to generate a
+corresponding <i>lint library</i>. To do this, precede all
+the C source files of this library by the pseudocomment
+<tt>/* LINTLIBRARY */</tt>. Then feed these files one by one
+to the first pass of <i>lint</i> collecting the standard
+output in a file and ignoring the warnings. The resulting
+file contains library definitions of the functions and
+external variables defined in the library sources, and not
+more than that. If this file is called
+&lsquo;llib-l<i>name</i>.ln <i>lint</i> can be told to
+search the library by passing it as argument in the command
+line &lsquo;-llib-l<i>name</i>.ln. The implementation of
+this feature is simple.</p>
+
+<p>As soon as the pseudocomment <tt>/* LINTLIBRARY */</tt>
+is met, only function and variable definitions are output
+with class LFDF and LVDF respectively. Other definitions,
+which otherwise would have been output, are discarded.</p>
+
+<p>Instead of generating a special lint library file, one
+can make a file containing the library definitions and
+starting with <tt>/* LINTLIBRARY */</tt>. This file can then
+be passed to <i>lint</i> just by its name. This method
+isn&rsquo;t as efficient as the first one.</p>
+<a name="4.2.8. Interpreting the pseudocomments"></a>
+<h2>4.2.8. Interpreting the pseudocomments</h2>
+
+<p>The interpretation of the pseudocomments is done by the
+lexical analyzer, because this part of the program already
+took care of the comments. At first sight this seems very
+easy: as soon as some pseudocomment is met, raise the
+corresponding flag. Unfortunately this doesn&rsquo;t work.
+The lexical analyzer is a <i>one token look ahead
+scanner</i>. This causes the above procedure to raise the
+flags one token too soon. A solution to get the right effect
+is to reserve two flags per pseudocomment. The first is set
+as soon as the corresponding pseudocomment is scanned. At
+the returning of each token this flag is moved to the second
+flag. The delay in this way achieved makes the
+pseudocomments have effect at the correct place.</p>
+<a name="4.3. The second pass data structure"></a>
+<h2>4.3. The second pass data structure</h2>
+<a name="4.3.1. Inp_def descriptor"></a>
+<h2>4.3.1. Inp_def descriptor</h2>
+<pre>             struct inp_def {
+                     struct inp_def *next;
+                     int id_class;
+                     char id_name[NAMESIZE];
+                     char id_file[FNAMESIZE];
+                     unsigned int id_line;
+                     int id_nrargs;
+                     char argtps[ARGSTPSSIZE];
+                     int id_returns;
+                     char id_type[TYPESIZE];
+                     int id_called;
+                     int id_used;
+                     int id_ignored;
+                     int id_voided;
+             };
+</pre>
+
+<p>This description is almost similar to the <i>outdef</i>
+descriptor as described in 4.1.2.5. There are some
+differences too.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><tt>next</tt></p>
+</td>
+<td width="22%"></td>
+<td width="70%">
+
+<p>As structures of this type are allocated dynamically,
+this field is added so the same memory allocator as used in
+the first pass can be used.</p>
+</td>
+</table>
+
+<p><tt>id_called<br>
+id_used<br>
+id_ignored</tt></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><tt>id_voided</tt></p>
+</td>
+<td width="12%"></td>
+<td width="70%">
+
+<p>Some additional fields only used for function
+definitions.Their meaning should be clear.</p>
+</td>
+</table>
+
+<p>The other fields have the same meaning as the
+corresponding fields in the <i>outdef</i> descriptor. Some
+attention should be paid to <tt>id_argtps</tt> and
+<tt>id_type</tt>. These members have type <tt>array of
+char</tt>, in contrast to their counterparts in the
+<i>outdef</i> descriptor. The only operation performed on
+types is a check on equality. Types are output by the first
+pass as a string describing the type. The type of <tt>i</tt>
+in <tt>int *i();</tt> e.g. is output as <tt>int *()</tt>.
+Such a string is best put in an <tt>array of char</tt> to be
+compared easily.</p>
+<a name="4.4. The second pass checking mechanism"></a>
+<h2>4.4. The second pass checking mechanism</h2>
+
+<p>After all the definitions that are output by the first
+pass are sorted by name, the definitions belonging to one
+name are ordered as follows.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>external definitions</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>static definitions</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>library definitions</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>declarations</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>function calls</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>-</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="21%"></td>
+<td width="78%">
+<p>variable usages</p>
+</td>
+</table>
+
+<p>The main program of the second pass is easily explained.
+For all different names, do the following. First read the
+definitions. If there is more than one definition, check for
+conflicts. Then read the declarations, function calls and
+variable usages and check them against the definitions.
+After having processed all the declarations, function calls
+and variable usages, check the definitions to see if they
+are used correctly. The next three paragraphs will explain
+the three most important functions of the program.</p>
+<a name="4.4.1. Read_defs()"></a>
+<h2>4.4.1. Read_defs()</h2>
+
+<p>This function reads all definitions belonging to the
+same name. Only one external definition is allowed, so if
+there are more, a warning is given. In different files it is
+allowed to define static functions or variables with the
+same name. So if a static function is read,
+<tt>read_defs</tt> checks if there isn&rsquo;t already an
+external definition, and if not it puts the static
+definition in the list of static definitions, to be used
+later. If no external or static definitions are met, a
+library definition is taken as definition. If a function or
+a variable is defined with the same name as a function or a
+variable in a library (which is allowed) <i>lint</i> gives a
+warning. Of course it is also possible that there is no
+definition at all. In that case <tt>check</tt> will
+warn.</p>
+<a name="4.4.2. Check()"></a>
+<h2>4.4.2. Check()</h2>
+
+<p><tt>Check</tt> verifies declarations, function calls and
+variable usages against the definitions. For each of these
+entries the corresponding definition is looked up. As there
+may be more than one static definition, first a static
+definition from the same file as the entry is searched. If
+not present, the external definition (which may be a library
+definition) is taken as definition. If no definition can be
+found and the current entry is an external declaration,
+<i>lint</i> warns. However in the case of an implicit
+function declaration <i>lint</i> will not warn, because we
+will get a warning <tt>%s used but not defined</tt> later
+on. Next a check is done if the declarations are consistent
+with their definitions. After the declarations, the function
+calls and variable usages are verified against their
+corresponding definitions. If no definition exists,
+<i>lint</i> warns. Else the field <tt>id_called</tt> is set
+to 1. (For variable definitions this should be interpreted
+as <i>used</i>.) For variable usages this will be all. If we
+are processing a function call we also check the number and
+types of the arguments and we warn for function values which
+are used from functions that don&rsquo;t return a value. For
+each function call we administrate if a function value is
+used, ignored or voided.</p>
+<a name="4.4.3. Check_usage()"></a>
+<h2>4.4.3. Check_usage()</h2>
+
+<p>Checks if the external definition and static definitions
+are used correctly. If a function or variable is defined but
+never used, <i>lint</i> warns, except for library
+definitions. Functions, which return a value but whose value
+is always or sometimes ignored, get a warning. (A function
+value which is voided (cast to void) is not ignored, but it
+isn&rsquo;t used either.)</p>
+<a name="5. How to make lint shut up"></a>
+<h2>5. How to make lint shut up</h2>
+
+<p>It can be very annoying having <i>lint</i> warn about
+questionable constructs of which the programmer already is
+aware. There should be a mechanism to give <i>lint</i> some
+extra information in the source code. This could be done by
+introducing some special keywords, which would have a
+special meaning to <i>lint.</i> This is a bad solution,
+because these keywords would cause existing C compilers not
+to work on these programs. A neater solution is to invent
+some comments having a special meaning to <i>lint.</i> We
+call these comments <i>pseudocomments.</i> The
+pseudocomments have no meaning to existing C compilers, so
+compilers will not have to be rewritten for C programs
+containing the previously proposed special keywords. The
+following pseudocomments are recognized by <i>lint.</i></p>
+
+<p><tt>/* VARARGS</tt><i>n</i> <tt>*/</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The next function can be called with a variable number of
+arguments. Only check the first <i>n</i> arguments. The
+<i>n</i> must follow the word <tt>VARARGS</tt> immediately.
+This pseudocomment is useful for functions like e.g. printf.
+(The definition of the function printf should be preceded by
+<tt>/* VARARGS1 */</tt>.)</p></td>
+</table>
+
+<p><tt>/* VARARGS */</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Means the same as <tt>/* VARARGS0 */</tt>.</p></td>
+</table>
+
+<p><tt>/* ARGSUSED */</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Don&rsquo;t complain about unused arguments in the next
+function. When we are developing a program we sometimes
+write functions of which we do not yet use the arguments.
+Because we do want to use <i>lint</i> on these programs, it
+is nice to have this pseudocomment.</p></td>
+</table>
+
+<p><tt>/* NOTREACHED */</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><i>Lint</i> makes no attempt to discover functions which
+never return, although it <i>is</i> possible to find
+functions that don&rsquo;t return. This would require a
+transitive closure with respect to the already known
+<i>not-returning</i> functions; an inacceptable time
+consuming process. To make <i>lint</i> aware of a function
+that doesn&rsquo;t return, a call of this function should be
+followed by the pseudocomment <tt>/* NOTREACHED */</tt>.
+This pseudocomment can also be used to indicate that some
+case part inside a switch (especially a default part)
+can&rsquo;t be reached. The above mentioned cases of use of
+this pseudocomment are examples. The comment can be used
+just to indicate that some part of the program can&rsquo;t
+be reached. It sometimes is necessary to introduce an extra
+compound statement to get the right effect. See figure
+9.</p>
+</td>
+</table>
+<pre>         if (cond)
+                 /* if part */ ;
+         else {
+                 error();  /* doesn&rsquo;t return */
+                 /* NOTREACHED */
+         }
+ /* Without  the compound  else  part, lint  would  assume
+  * the statement after the if statement to be NOTREACHED,
+  * instead of the end of the else part.
+  */
+
+
+</pre>
+
+<p align=center>figure 9.</p>
+
+<p><tt>/* LINTLIBRARY */</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>All definitions following this comment are assumed to be
+library definitions. It shuts off complaints about unused
+functions and variables. See also section 4.2.7 for how to
+use this comment for generating lint libraries.</p></td>
+</table>
+<a name="6. User options"></a>
+<h2>6. User options</h2>
+
+<p><i>Lint</i> recognizes the following command line flags.
+Some of them are identical to the flags of <i>cem. Lint</i>
+warns for flags it doesn&rsquo;t know.</p>
+
+<p><tt>-D&lt;name&gt;<br>
+-D&lt;name&gt;=&lt;text&gt;</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Causes <tt>&lt;name&gt;</tt> to be defined as a macro.
+The first form is equivalent to
+&lsquo;<tt>-D&lt;name&gt;=1</tt>&rsquo;. The second form is
+equivalent to putting &lsquo;<tt>#define &lt;name&gt;
+&lt;text&gt;</tt>&rsquo; in front of all the source
+files.</p></td>
+</table>
+
+<p><tt>-U&lt;name&gt;</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Acts as if the line &lsquo;<tt>#undef
+&lt;name&gt;</tt>&rsquo; is put in front of all the source
+files.</p></td>
+</table>
+
+<p><tt>-I&lt;directory&gt;</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This puts <tt>&lt;directory&gt;</tt> in the include
+directory list.</p></td>
+</table>
+
+<p><tt>-R</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Turn off the &lsquo;strict&rsquo; option. Default
+<i>lint</i> checks the program according to the Reference
+Manual, because this gives a definition of the language with
+which there is a better chance of writing portable programs.
+With this flag on, some constructs, otherwise not allowed,
+are accepted.</p></td>
+</table>
+
+<p><tt>-l&lt;name&gt;<br>
+-llib-l&lt;name&gt;.ln<br>
+-l</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>&lsquo;<tt>-l&lt;name&gt;</tt>&rsquo; tells <i>lint</i>
+to search the lint library <tt>llib-l&lt;name&gt;.ln</tt>
+for missing definitions of functions and variables. The
+option &lsquo;<tt>-llib-l&lt;name&gt;.ln</tt>&rsquo; makes
+<i>lint</i> search the lint library file
+<tt>llib-l&lt;name&gt;.ln</tt> in the current directory for
+missing definitions. Default is &lsquo;<tt>-lc</tt>&rsquo;;
+this default can be suppressed by
+&lsquo;<tt>-l</tt>&rsquo;.</p></td>
+</table>
+
+<p><tt>-a</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Warn for conversions from integer to long and vice
+versa.</p></td>
+</table>
+
+<p><tt>-b</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Don&rsquo;t report not-reachable break statements. This
+flag is useful for running <i>lint</i> on a <i>lex</i>- or
+<i>yacc</i>-generated source file.</p></td>
+</table>
+
+<p><tt>-h</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Check for useless statements and possible pointer
+alignment problems.</p></td>
+</table>
+
+<p><tt>-n</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Don&rsquo;t complain about unused and undefined functions
+and variables.</p></td>
+</table>
+
+<p><tt>-v</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Don&rsquo;t warn about unused arguments of
+functions.</p></td>
+</table>
+
+<p><tt>-x</tt></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Complain about unused external variables.</p></td>
+</table>
+<a name="7. Ideas for further development"></a>
+<h2>7. Ideas for further development</h2>
+
+<p>Although the program in its current state is a useful
+program, there are still a lot of features that should be
+implemented in following versions. I&rsquo;ll summarize them
+in this section.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Actually the program consists of three passes. The
+filter <i>sort</i> is a complete pass, just as the first and
+the second pass. I think we speed up the program by removing
+the filter and making the second pass accept an unsorted
+file. The sorting process can be done in parallel to the
+first pass if both processes communicate through a pipe. In
+addition to this sorting, the second pass can generate
+already some warnings. (Warnings like <tt>%s defined but
+never used</tt> can only be generated after having processed
+all the input.) These warnings generated in parallel to the
+warnings of the first pass, should be sent to an
+intermediate file, otherwise the warnings would get messed
+up. Such an improvement will have best effect on a multi
+processing machine, but even on single processing machines
+this will give a better performance. (On a single processing
+machine the pipe should be replaced by an intermediate
+file.)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Expressions could be classified so <i>lint</i> can warn
+for some classes of expressions in strange contexts. Suppose
+as class &lt;boolean&gt;. <tt>b</tt> Will be of class
+&lt;boolean&gt; if e.g. <tt>b</tt> is assigned to the
+expression <tt>&lt;ex1&gt; || &lt;ex2&gt;</tt>. The
+following expression should then give a warning</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>           b + i;    /* weird expression */
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A mechanism to check printf like routines. This
+mechanism should verify the format string against the
+following arguments. There is a public domain program that
+can be used to do this job. It is called printfck and should
+be used as a filter between the source files and
+<i>lint.</i></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Raise warnings for incomplete initializer lists like</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>          int a[10] = {0, 1, 2};
+          /* initializer list not complete */
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="56%">
+
+<p>Warnings for constructs like</p>
+</td>
+<td width="33%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>     for (i = 0; i &lt; 10; i++) {
+             . . . .
+             i--;
+             /* loop control variable affected */
+             . . . .
+     }
+</pre>
+<!-- INDENTATION -->
+<p>and</p>
+<!-- INDENTATION -->
+<pre>       while (var) {
+               /* statements in which the value
+                * of var is never changed
+                */
+       }
+       /* loop control variable not updated */
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A warning <tt>bad layout</tt> for program fragments
+like</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>             if (cond1)
+                     if (cond2)
+                             statement();
+             else  /* bad layout */
+                     statement();
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A warning <tt>assignment in conditional context</tt> in
+case of</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>                      if (a = b)
+</pre>
+<!-- INDENTATION -->
+<p>The programmer probably meant <tt>if (a == b)</tt>. No
+warning should be given for <tt>if ((a = b) != c)</tt>, nor
+for <tt>if ((a = b))</tt>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Warnings for empty statements in strange contexts,
+like</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>               if (cond);  /* mistake */
+                       statement();
+</pre>
+<!-- INDENTATION -->
+<p>(This mistake would also be detected by a warning <tt>bad
+layout</tt>.)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>A mechanism to prevent the warning <tt>possible pointer
+alignment problem</tt> for functions of which the programmer
+already knows that no problem will arise. E.g. for functions
+like malloc and family.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&bull;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>The current version of <i>lint</i> warns for conversions
+from long to int (if -a flag is on). It even warns if the
+programmer used the proper cast, as e.g.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>                     int i;
+                     long l = 0L;
+
+
+                     i = (int)l;
+</pre>
+<!-- INDENTATION -->
+<p>In this case I think <i>lint</i> need not warn. The
+explicit cast indicates that the programmer knows what he is
+doing. This feature is not implemented because the
+expression tree doesn&rsquo;t show if the cast was implicit
+or explicit.</p>
+</td>
+</table>
+<a name="8. Testing the program"></a>
+<h2>8. Testing the program</h2>
+
+<p>There is no test-suite for testing <i>lint.</i> I have
+written a lot of small files that each test one particular
+property of the program. At this moment there are about 220
+test programs.</p>
+
+<p>It would take a lot of time and effort to run these
+tests by hand. To ease this work I wrote a program that runs
+these tests automatically. The test program (the program
+that runs the tests) needs, associated with each .c file, a
+.w file, containing from each expected warning a substring.
+E.g. when the following warnings should be given by
+<i>lint:</i></p>
+<pre>        file t.c, line 3, i evaluation order undefined
+        file t.c, line 6, a set but not used in function main
+</pre>
+
+<p>it is sufficient to write a file <tt>t.w</tt>
+containing</p>
+<pre>                a set but not used in function main
+                i evaluation order undefined
+</pre>
+
+<p>The test program is called with all the .c files to be
+tested as arguments.</p>
+
+<p>Sometimes it is necessary to test <i>lint</i> on two
+files. The test program runs <i>lint</i> on two files when
+two consecutive arguments are of the form <i>name</i>a.c and
+<i>name</i>b.c. It then compares the output of <i>lint</i>
+with the file <i>name</i>.w.</p>
+
+<p><i>Lint</i> is also tested by running it on existing
+programs. <i>Lint</i> has been run on some
+<small>UNIX</small> utility programs in /usr/src/cmd, on
+Unipress Emacs (consisting of more than 30,000 lines of
+code) and the program itself. Bugs have been found in e.g.
+/usr/src/cmd/cat.c and /usr/src/cmd/ld.c. To test the
+robustness of the program, it was run on the password file
+/etc/passwd and on &lsquo;mixed&rsquo; C program files.
+These mixed C program files are C program files that were
+broken in chunks and then put together in a different
+order.</p>
+<a name="9. References"></a>
+<h2>9. References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[1]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>Dennis M. Ritchie, <i>C Reference Manual,</i> Bell
+Laboratories, Murray Hill, New Jersey, 1978.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[2]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>B.W. Kernighan and D.M. Ritchie, <i>The C Programming
+Language,</i> Prentice Hall, 1978.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[3]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>Eric H. Baalbergen, Dick Grune, Maarten Waage, <i>The
+CEM Compiler,</i> Manual IM-4, Vrije Universiteit,
+Amsterdam, 1985.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[4]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>Andrew S. Tanenbaum et al., <i>A practical tool kit for
+making portable compilers,</i> Comm. ACM, Sep. 1983.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[5]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>S. C. Johnson, <i>Lint, a C program verifier,</i> Bell
+Laboratories, Murray Hill, New Jersey, 1978.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[6]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>Dick Grune, Ceriel J. H. Jacobs, <i>A
+Programmer-friendly LL(1) Parser Generator,</i> IR 127,
+Vrije Universiteit, Amsterdam, 1987.</p>
+</td>
+</table>
+<a name="Appendix A"></a>
+<h2>Appendix A</h2>
+<a name="The warnings"></a>
+<h2>The warnings</h2>
+<a name="Pass one warnings"></a>
+<h2>Pass one warnings</h2>
+<pre>     %s may be used before set
+     maybe %s used before set
+     %s unused in function %s
+     %s set but not used in function %s
+     argument %s unused in function %s
+     static [variable, function] %s unused
+     %s declared extern but never used
+
+
+     long conversion may lose accuracy
+     comparison of unsigned with negative constant
+     unsigned comparison with 0?
+     degenerate unsigned comparison
+     nonportable character comparison
+     possible pointer alignment problem
+
+
+     %s evaluation order undefined
+
+
+     null effect
+     constant in conditional context
+     use if-else construction
+     while (0) ?
+     do ... while (0) ?
+     [case, default] statement in strange context
+
+
+     function %s has return(e); and return;
+     statement not reached
+     function %s declared %s but no value returned
+</pre>
+<a name="Pass two warnings"></a>
+<h2>Pass two warnings</h2>
+<pre>     %s variable # of args
+     %s arg %d used inconsistently
+     %s multiply defined
+     %s value declared inconsistently
+     %s used but not defined
+     %s defined (%s(%d)) but never used
+     %s declared but never defined
+     %s value is used but none is returned
+     %s returns value which is [sometimes, always] ignored
+     %s also defined in library
+</pre>
+<a name="Appendix B"></a>
+<h2>Appendix B</h2>
+
+<p align=center><b><big>The Ten Commandments for C
+Programmers</big></b></p>
+
+<p align=center><i>Henry Spencer</i></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>1</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Thou shalt run <i>lint</i> frequently and study its
+pronouncements with care, for verily its perception and
+judgement oft exceed thine.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>2</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Thou shalt not follow the NULL pointer, for chaos and
+madness await thee at its end.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>3</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Thou shalt cast all function arguments to the expected
+type if they are not of that type already, even when thou
+art convinced that this is unnecessary, lest they take cruel
+vengeance upon thee when thou least expect it.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>4</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>If thy header files fail to declare the return types of
+thy library functions, thou shalt declare them thyself with
+the most meticulous care, lest grievous harm befall thy
+program.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>5</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Thou shalt check the array bounds of all strings
+(indeed, all arrays), for surely where thou typest
+&lsquo;&lsquo;foo&rsquo;&rsquo; someone someday shall type
+&lsquo;&lsquo;supercalifragilisticexpialidocious&rsquo;&rsquo;.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>6</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>If a function be advertised to return an error code in
+the event of difficulties, thou shalt check for that code,
+yea, even though the checks triple the size of thy code and
+produce aches in thy typing fingers, for if thou thinkest
+&lsquo;&lsquo;it cannot happen to me&rsquo;&rsquo;, the gods
+shall surely punish thee for thy arrogance.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>7</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Thou shalt study thy libraries and strive not to
+re-invent them without cause, that thy code may be short and
+readable and thy days pleasant and productive.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>8</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Thou shalt make thy program&rsquo;s purpose and
+structure clear to thy fellow man by using the One True
+Brace Style, even if thou likest it not, for thy creativity
+is better used in solving problems than in creating
+beautiful new impediments to understanding.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>9</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>Thy external identifiers shall be unique in the first
+six characters, though this harsh discipline be irksome and
+the years of its necessity stretch before thee seemingly
+without end, lest thou tear thy hair out and go mad on that
+fateful day when thou desirest to make thy program run on an
+old system.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>10</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>Thou shalt foreswear, renounce, and abjure the vile
+heresy which claimeth that &lsquo;&lsquo;All the
+world&rsquo;s a VAX&rsquo;&rsquo;, and have no commerce with
+the benighted heathens who cling to this barbarous belief,
+that the days of thy program may be long even though the
+days of thy current machine be short.</p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/lint.pdf b/src/olddocs/lint.pdf
new file mode 100644 (file)
index 0000000..342b0f6
Binary files /dev/null and b/src/olddocs/lint.pdf differ
diff --git a/src/olddocs/m2ref.html b/src/olddocs/m2ref.html
new file mode 100644 (file)
index 0000000..f81f52e
--- /dev/null
@@ -0,0 +1,831 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:32 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The ACK Modula-2 Compiler</title>
+</head>
+<body>
+
+<h1 align=center>The ACK Modula-2 Compiler</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The language implemented">2. The language implemented</a><br>
+<a href="#2.1. Syntax (section 2)">2.1. Syntax (section 2)</a><br>
+<a href="#2.2. Vocabulary and Representation (section 3)">2.2. Vocabulary and Representation (section 3)</a><br>
+<a href="#2.3. Declarations and scope rules (section 4)">2.3. Declarations and scope rules (section 4)</a><br>
+<a href="#2.4. Constant expressions (section 5)">2.4. Constant expressions (section 5)</a><br>
+<a href="#2.5. Type declarations (section 6)">2.5. Type declarations (section 6)</a><br>
+<a href="#2.5.1. Basic types (section 6.1)">2.5.1. Basic types (section 6.1)</a><br>
+<a href="#2.5.2. Enumerations (section 6.2)">2.5.2. Enumerations (section 6.2)</a><br>
+<a href="#2.5.3. Record types (section 6.5)">2.5.3. Record types (section 6.5)</a><br>
+<a href="#2.5.4. Set types (section 6.6)">2.5.4. Set types (section 6.6)</a><br>
+<a href="#2.6. Expressions (section 8)">2.6. Expressions (section 8)</a><br>
+<a href="#2.6.1. Operators (section 8.2)">2.6.1. Operators (section 8.2)</a><br>
+<a href="#2.6.1.1. Arithmetic operators (section 8.2.1)">2.6.1.1. Arithmetic operators (section 8.2.1)</a><br>
+<a href="#2.7. Statements (section 9)">2.7. Statements (section 9)</a><br>
+<a href="#2.7.1. Assignments (section 9.1)">2.7.1. Assignments (section 9.1)</a><br>
+<a href="#2.7.2. Case statements (section 9.5)">2.7.2. Case statements (section 9.5)</a><br>
+<a href="#2.7.3. For statements (section 9.8)">2.7.3. For statements (section 9.8)</a><br>
+<a href="#2.7.4. Return and exit statements (section 9.11)">2.7.4. Return and exit statements (section 9.11)</a><br>
+<a href="#2.8. Procedure declarations (section 10)">2.8. Procedure declarations (section 10)</a><br>
+<a href="#2.8.1. Standard procedures (section 10.2)">2.8.1. Standard procedures (section 10.2)</a><br>
+<a href="#2.9. System-dependent facilities (section 12)">2.9. System-dependent facilities (section 12)</a><br>
+<a href="#3. Backwards compatibility">3. Backwards compatibility</a><br>
+<a href="#4. Compile time errors">4. Compile time errors</a><br>
+<a href="#5. Runtime errors">5. Runtime errors</a><br>
+<a href="#6. Calling the compiler">6. Calling the compiler</a><br>
+<a href="#7. The procedure call interface">7. The procedure call interface</a><br>
+<a href="#8. References">8. References</a><br>
+
+<hr>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p align=center><i>Ceriel J.H. Jacobs</i><br>
+Department of Mathematics and Computer Science<br>
+Vrije Universiteit<br>
+Amsterdam<br>
+The Netherlands</p>
+</td>
+</table>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>This document describes the implementation-specific
+features of the ACK Modula-2 compiler. It is not intended to
+teach Modula-2 programming. For a description of the
+Modula-2 language, the reader is referred to [1].</p>
+
+<p>The ACK Modula-2 compiler is currently available for use
+with the VAX, Motorola MC68020, Motorola MC68000, PDP-11,
+and Intel 8086 code-generators. For the 8086, MC68000, and
+MC68020, floating point emulation is used. This is made
+available with the <i>-fp</i> option, which must be passed
+to <i>ack</i>[4,5].</p>
+<a name="2. The language implemented"></a>
+<h2>2. The language implemented</h2>
+
+<p>This section discusses the deviations from the Modula-2
+language as described in the &quot;Report on The Programming
+Language Modula-2&quot;, as it appeared in [1], from now on
+referred to as &quot;the Report&quot;. Also, the Report
+sometimes leaves room for interpretation. The section
+numbers mentioned are the section numbers of the Report.</p>
+<a name="2.1. Syntax (section 2)"></a>
+<h2>2.1. Syntax (section 2)</h2>
+
+<p>The syntax recognized is that of the Report, with some
+extensions to also recognize the syntax of an earlier
+definition, given in [2]. Only one compilation unit per file
+is accepted.</p>
+<a name="2.2. Vocabulary and Representation (section 3)"></a>
+<h2>2.2. Vocabulary and Representation (section 3)</h2>
+
+<p>The input &quot;<tt>10..</tt>&quot; is parsed as two
+tokens: &quot;<tt>10</tt>&quot; and
+&quot;<tt>..</tt>&quot;.</p>
+
+<p>The empty string <tt>&quot;&quot;</tt> has type</p>
+<pre>     ARRAY [0 .. 0] OF CHAR
+</pre>
+
+<p>and contains one character: <tt>0C</tt>.</p>
+
+<p>When the text of a comment starts with a
+&rsquo;<tt>$</tt>&rsquo;, it may be a pragma. Currently, the
+following pragmas exist:</p>
+<pre>     (*$F      (F stands for Foreign) *)
+     (*$R[+|-] (Runtime checks, on or off, default on) *)
+     (*$A[+|-] (Array bound checks, on or off, default off) *)
+     (*$U      (Allow for underscores within identifiers) *)
+</pre>
+
+<p>The Foreign pragma is only meaningful in a
+<tt>DEFINITION MODULE</tt>, and indicates that this
+<tt>DEFINITION MODULE</tt> describes an interface to a
+module written in another language (for instance C, Pascal,
+or EM). Runtime checks that can be disabled are: range
+checks, <tt>CARDINAL</tt> overflow checks, checks when
+assigning a <tt>CARDINAL</tt> to an <tt>INTEGER</tt> and
+vice versa, and checks that <tt>FOR</tt>-loop
+control-variables are not changed in the body of the loop.
+Array bound checks can be enabled, because many EM
+implementations do not implement the array bound checking of
+the EM array instructions. When enabled, the compiler
+generates a check before generating an EM array instruction.
+Even when underscores are enabled, they still may not start
+an identifier.</p>
+
+<p>Constants of type <tt>LONGINT</tt> are integers with a
+suffix letter <tt>D</tt> (for instance <tt>1987D</tt>).
+Constants of type <tt>LONGREAL</tt> have suffix <tt>D</tt>
+if a scale factor is missing, or have <tt>D</tt> in place of
+<tt>E</tt> in the scale factor (f.i. <tt>1.0D</tt>,
+<tt>0.314D1</tt>). This addition was made, because there was
+no way to indicate long constants, and also because the
+addition was made in Wirth&rsquo;s newest Modula-2
+compiler.</p>
+<a name="2.3. Declarations and scope rules (section 4)"></a>
+<h2>2.3. Declarations and scope rules (section 4)</h2>
+
+<p>Standard identifiers are considered to be predeclared,
+and valid in all parts of a program. They are called
+<i>pervasive</i>. Unfortunately, the Report does not state
+how this pervasiveness is accomplished. However, page 87 of
+[1] states: &quot;Standard identifiers are automatically
+imported into all modules&quot;. Our implementation
+therefore allows redeclarations of standard identifiers
+within procedures, but not within modules.</p>
+<a name="2.4. Constant expressions (section 5)"></a>
+<h2>2.4. Constant expressions (section 5)</h2>
+
+<p>Each operand of a constant expression must be a
+constant: a string, a number, a set, an enumeration literal,
+a qualifier denoting a constant expression, a type transfer
+with a constant argument, or one of the standard procedures
+<tt>ABS</tt>, <tt>CAP</tt>, <tt>CHR</tt>, <tt>LONG</tt>,
+<tt>MAX</tt>, <tt>MIN</tt>, <tt>ODD</tt>, <tt>ORD</tt>,
+<tt>SIZE</tt>, <tt>SHORT</tt>, <tt>TSIZE</tt>, or
+<tt>VAL</tt>, with constant argument(s); <tt>TSIZE</tt> and
+<tt>SIZE</tt> may also have a variable as argument.</p>
+
+<p>Floating point expressions are never evaluated compile
+time, because the compiler basically functions as a
+cross-compiler, and thus cannot use the floating point
+instructions of the machine on which it runs. Also,
+<tt>MAX(REAL)</tt> and <tt>MIN(REAL)</tt> are not
+allowed.</p>
+<a name="2.5. Type declarations (section 6)"></a>
+<h2>2.5. Type declarations (section 6)</h2>
+<a name="2.5.1. Basic types (section 6.1)"></a>
+<h2>2.5.1. Basic types (section 6.1)</h2>
+
+<p>The type <tt>CHAR</tt> includes the ASCII character set
+as a subset. Values range from <tt>0C</tt> to <tt>377C</tt>,
+not from <tt>0C</tt> to <tt>177C</tt>.</p>
+<a name="2.5.2. Enumerations (section 6.2)"></a>
+<h2>2.5.2. Enumerations (section 6.2)</h2>
+
+<p>The maximum number of enumeration literals in any one
+enumeration type is <tt>MAX(INTEGER)</tt>.</p>
+<a name="2.5.3. Record types (section 6.5)"></a>
+<h2>2.5.3. Record types (section 6.5)</h2>
+
+<p>The syntax of variant sections in [1] is different from
+the one in [2]. Our implementation recognizes both, giving a
+warning for the older one. However, see section 3.</p>
+<a name="2.5.4. Set types (section 6.6)"></a>
+<h2>2.5.4. Set types (section 6.6)</h2>
+
+<p>The only limitation imposed by the compiler is that the
+base type of the set must be a subrange type, an enumeration
+type, <tt>CHAR</tt>, or <tt>BOOLEAN</tt>. So, the lower
+bound may be negative. However, if a negative lower bound is
+used, the compiler gives a warning of the <i>restricted</i>
+class (see the manual page of the compiler).</p>
+
+<p>The standard type <tt>BITSET</tt> is defined as</p>
+<pre>     TYPE BITSET = SET OF [0 .. 8*SIZE(INTEGER)-1];
+</pre>
+<a name="2.6. Expressions (section 8)"></a>
+<h2>2.6. Expressions (section 8)</h2>
+<a name="2.6.1. Operators (section 8.2)"></a>
+<h2>2.6.1. Operators (section 8.2)</h2>
+
+<a name="2.6.1.1. Arithmetic operators (section 8.2.1)"></a>
+<h2>2.6.1.1. Arithmetic operators (section 8.2.1)</h2>
+
+<p>The Report does not specify the priority of the unary
+operators <tt>+</tt> or <tt>-</tt>: It does not specify
+whether</p>
+<pre>     - 1 + 1
+</pre>
+
+<p>means</p>
+<pre>     - (1 + 1)
+</pre>
+
+<p>or</p>
+<pre>     (-1) + 1
+</pre>
+
+<p>I have seen some compilers that implement the first
+alternative, and others that implement the second. Our
+compiler implements the second, which is suggested by the
+fact that their priority is not specified, which might
+indicate that it is the same as that of their binary
+counterparts. And then the rule about left to right decides
+for the second. On the other hand one might argue that,
+since the grammar only allows for one unary operator in a
+simple expression, it must apply to the whole simple
+expression, not just the first term.</p>
+<a name="2.7. Statements (section 9)"></a>
+<h2>2.7. Statements (section 9)</h2>
+<a name="2.7.1. Assignments (section 9.1)"></a>
+<h2>2.7.1. Assignments (section 9.1)</h2>
+
+<p>The Report does not define the evaluation order in an
+assignment. Our compiler certainly chooses an evaluation
+order, but it is explicitly left undefined. Therefore,
+programs that depend on it may cease to work later.</p>
+
+<p>The types <tt>INTEGER</tt> and <tt>CARDINAL</tt> are
+assignment-compatible with <tt>LONGINT</tt>, and
+<tt>REAL</tt> is assignment-compatible with
+<tt>LONGREAL</tt>.</p>
+<a name="2.7.2. Case statements (section 9.5)"></a>
+<h2>2.7.2. Case statements (section 9.5)</h2>
+
+<p>The size of the type of the case-expression must be less
+than or equal to the word-size.</p>
+
+<p>The Report does not specify what happens if the value of
+the case-expression does not occur as a label of any case,
+and there is no <tt>ELSE</tt>-part. In our implementation,
+this results in a runtime error.</p>
+<a name="2.7.3. For statements (section 9.8)"></a>
+<h2>2.7.3. For statements (section 9.8)</h2>
+
+<p>The Report does not specify the legal types for a
+control variable. Our implementation allows the basic types
+(except <tt>REAL</tt>), enumeration types, and subranges. A
+runtime warning is generated when the value of the control
+variable is changed by the statement sequence that forms the
+body of the loop, unless runtime checking is disabled.</p>
+<a name="2.7.4. Return and exit statements (section 9.11)"></a>
+<h2>2.7.4. Return and exit statements (section 9.11)</h2>
+
+<p>The Report does not specify which result-types are
+legal. Our implementation allows any result type.</p>
+<a name="2.8. Procedure declarations (section 10)"></a>
+<h2>2.8. Procedure declarations (section 10)</h2>
+
+<p>Function procedures must exit through a RETURN
+statement, or a runtime error occurs.</p>
+<a name="2.8.1. Standard procedures (section 10.2)"></a>
+<h2>2.8.1. Standard procedures (section 10.2)</h2>
+
+<p>Our implementation supports <tt>NEW</tt> and
+<tt>DISPOSE</tt> for backwards compatibility, but issues
+warnings for their use. However, see section 3.</p>
+
+<p>Also, some new standard procedures were added, similar
+to the new standard procedures in Wirth&rsquo;s newest
+compiler:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><tt>LONG</tt> converts an argument of type
+<tt>INTEGER</tt> or <tt>REAL</tt> to the types
+<tt>LONGINT</tt> or <tt>LONGREAL</tt>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><tt>SHORT</tt> performs the inverse transformation,
+without range checks.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><tt>FLOATD</tt> is analogous to <tt>FLOAT</tt>, but
+yields a result of type <tt>LONGREAL</tt>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>&minus;</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><tt>TRUNCD</tt> is analogous to <tt>TRUNC</tt>, but
+yields a result of type <tt>LONGINT</tt>.</p>
+</td>
+</table>
+<a name="2.9. System-dependent facilities (section 12)"></a>
+<h2>2.9. System-dependent facilities (section 12)</h2>
+
+<p>The type <tt>BYTE</tt> is added to the <tt>SYSTEM</tt>
+module. It occupies a storage unit of 8 bits. <tt>ARRAY OF
+BYTE</tt> has a similar effect to <tt>ARRAY OF WORD</tt>,
+but is safer. In some obscure cases the <tt>ARRAY OF
+WORD</tt> mechanism does not quite work properly.</p>
+
+<p>The procedure <tt>IOTRANSFER</tt> is not
+implemented.</p>
+<a name="3. Backwards compatibility"></a>
+<h2>3. Backwards compatibility</h2>
+
+<p>Besides recognizing the language as described in [1],
+the compiler recognizes most of the language described in
+[2], for backwards compatibility. It warns the user for
+old-fashioned constructions (constructions that [1] does not
+allow). If the <i>-Rm2-3</i> option (see [6]) is passed to
+<i>ack</i>, this backwards compatibility feature is
+disabled. Also, it may not be present on some smaller
+machines, like the PDP-11.</p>
+<a name="4. Compile time errors"></a>
+<h2>4. Compile time errors</h2>
+
+<p>The compile time error messages are intended to be
+self-explanatory, and not listed here. The compiler also
+sometimes issues warnings, recognizable by a
+warning-classification between parentheses. Currently, there
+are 3 classifications:</p>
+
+<p>(old-fashioned use)</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>These warnings are given on constructions that are not
+allowed by [1], but are allowed by [2].</p>
+</td>
+</table>
+
+<p>(strict)</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>These warnings are given on constructions that are
+supported by the ACK Modula-2 compiler, but might not be
+supported by others. Examples: functions returning
+structured types, SET types of subranges with negative lower
+bound.</p>
+</td>
+</table>
+
+<p>(warning)</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The other warnings, such as warnings about variables that
+are never assigned, never used, etc.</p></td>
+</table>
+<a name="5. Runtime errors"></a>
+<h2>5. Runtime errors</h2>
+
+<p>The ACK Modula-2 compiler produces code for an EM
+machine as defined in [3]. Therefore, it depends on the
+implementation of the EM machine for detection some of the
+runtime errors that could occur.</p>
+
+<p>The <i>Traps</i> module enables the user to install his
+own runtime error handler. The default one just displays
+what happened and exits. Basically, a trap handler is just a
+procedure that takes an INTEGER as parameter. The INTEGER is
+the trap number. This INTEGER can be one of the EM trap
+numbers, listed in [3], or one of the numbers listed in the
+<i>Traps</i> definition module.</p>
+
+<p>The following runtime errors may occur:</p>
+
+<p>array bound error</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>range bound error</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Range bound errors are always detected, unless runtime
+checks are disabled.</p>
+</td>
+</table>
+
+<p>set bound error</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation. The current implementations detect this
+error.</p>
+</td>
+</table>
+
+<p>integer overflow</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>cardinal overflow</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This error is detected, unless runtime checks are
+disabled.</p>
+</td>
+</table>
+
+<p>cardinal underflow</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This error is detected, unless runtime checks are
+disabled.</p>
+</td>
+</table>
+
+<p>real overflow</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>real underflow</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>divide by 0</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>divide by 0.0</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>undefined integer</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>undefined real</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>conversion error</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This error occurs when assigning a negative value of type
+INTEGER to a variable of type CARDINAL, or when assigning a
+value of CARDINAL that is &gt; MAX(INTEGER), to a variable
+of type INTEGER. It is detected, unless runtime checking is
+disabled.</p>
+</td>
+</table>
+
+<p>stack overflow</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation.</p>
+</td>
+</table>
+
+<p>heap overflow</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>The detection of this error depends on the EM
+implementation. Might happen when ALLOCATE fails.</p>
+</td>
+</table>
+
+<p>case error</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This error occurs when non of the cases in a CASE
+statement are selected, and the CASE statement has no ELSE
+part. The detection of this error depends on the EM
+implementation. All current EM implementations detect this
+error.</p>
+</td>
+</table>
+
+<p>stack size of process too large</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This is most likely to happen if the reserved space for a
+coroutine stack is too small. In this case, increase the
+size of the area given to <tt>NEWPROCESS</tt>. It can also
+happen if the stack needed for the main process is too large
+and there are coroutines. In this case, the only fix is to
+reduce the stack size needed by the main process, f.i. by
+avoiding local arrays.</p>
+</td>
+</table>
+
+<p>too many nested traps + handlers</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This error can only occur when the user has installed his
+own trap handler. It means that during execution of the trap
+handler another trap has occurred, and that several times.
+In some cases, this is an error because of overflow of some
+internal tables.</p>
+</td>
+</table>
+
+<p>no RETURN from function procedure</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This error occurs when a function procedure does not
+return properly (&quot;falls&quot; through).</p>
+</td>
+</table>
+
+<p>illegal instruction</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>This error might occur when floating point operations are
+used on an implementation that does not have floating
+point.</p>
+</td>
+</table>
+
+<p>In addition, some of the library modules may give error
+messages. The <b>Traps</b>-module has a suitable mechanism
+for this.</p>
+<a name="6. Calling the compiler"></a>
+<h2>6. Calling the compiler</h2>
+
+<p>See [4,5,6] for a detailed explanation.</p>
+
+<p>The compiler itself has no version checking mechanism. A
+special linker would be needed to do that. Therefore, a
+makefile generator is included [7].</p>
+<a name="7. The procedure call interface"></a>
+<h2>7. The procedure call interface</h2>
+
+<p>Parameters are pushed on the stack in reversed order, so
+that the EM AB (argument base) register indicates the first
+parameter. For VAR parameters, its address is passed, for
+value parameters its value. The only exception to this rule
+is with conformant arrays. For conformant arrays, the
+address is passed, and an array descriptor is passed. The
+descriptor is an EM array descriptor. It consists of three
+fields: the lower bound (always 0), upper bound - lower
+bound, and the size of the elements. The descriptor is
+pushed first. If the parameter is a value parameter, the
+called routine must make sure that its value is never
+changed, for instance by making its own copy of the array.
+The Modula-2 compiler does exactly this.</p>
+
+<p>When the size of the return value of a function
+procedure is larger than the maximum of
+<tt>SIZE(LONGREAL)</tt> and twice the pointer-size, the
+caller reserves this space on the stack, above the
+parameters. Callee then stores its result there, and returns
+no other value.</p>
+<a name="8. References"></a>
+<h2>8. References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[1]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>Niklaus Wirth, <i>Programming in Modula-2, third,
+corrected edition,</i> Springer-Verlag, Berlin (1985)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[2]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>Niklaus Wirth, <i>Programming in Modula-2,</i>
+Stringer-Verlag, Berlin (1983)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[3]</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>A.S.Tanenbaum, J.W.Stevenson, Hans van Staveren,
+E.G.Keizer, <i>Description of a machine architecture for use
+with block structured languages,</i> Informatica rapport
+IR-81, Vrije Universiteit, Amsterdam</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[4]</p>
+</td>
+<td width="4%"></td>
+<td width="36%">
+
+<p>UNIX manual <i>ack</i>(1)</p>
+</td>
+<td width="53%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[5]</p>
+</td>
+<td width="4%"></td>
+<td width="46%">
+
+<p>UNIX manual <i>modula-2</i>(1)</p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[6]</p>
+</td>
+<td width="4%"></td>
+<td width="40%">
+
+<p>UNIX manual <i>em_m2</i>(6)</p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[7]</p>
+</td>
+<td width="4%"></td>
+<td width="38%">
+
+<p>UNIX manual <i>m2mm</i>(1)</p>
+</td>
+<td width="51%">
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/m2ref.pdf b/src/olddocs/m2ref.pdf
new file mode 100644 (file)
index 0000000..7514bd0
Binary files /dev/null and b/src/olddocs/m2ref.pdf differ
diff --git a/src/olddocs/m68020.html b/src/olddocs/m68020.html
new file mode 100644 (file)
index 0000000..74117c0
--- /dev/null
@@ -0,0 +1,1772 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:30 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>A back end table for the Motorola MC68000, MC68010 and MC68020 microprocessors</title>
+</head>
+<body>
+
+<h1 align=center>A back end table for the Motorola MC68000, MC68010 and MC68020 microprocessors</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The MC68000 and MC68020 micro processors">2. The MC68000 and MC68020 micro processors</a><br>
+<a href="#2.1. Registers">2.1. Registers</a><br>
+<a href="#2.2. Addressing modes">2.2. Addressing modes</a><br>
+<a href="#2.2.1. General addressing modes">2.2.1. General addressing modes</a><br>
+<a href="#2.2.1.1. Register Direct Addressing">2.2.1.1. Register Direct Addressing</a><br>
+<a href="#2.2.1.2. Address Register Indirect">2.2.1.2. Address Register Indirect</a><br>
+<a href="#2.2.1.3. Address Register Indirect With Postincrement">2.2.1.3. Address Register Indirect With Postincrement</a><br>
+<a href="#2.2.1.4. Address Register Indirect With Predecrement">2.2.1.4. Address Register Indirect With Predecrement</a><br>
+<a href="#2.2.1.5. Address Register Indirect With Displacement">2.2.1.5. Address Register Indirect With Displacement</a><br>
+<a href="#2.2.1.6. Address Register Indirect With Index">2.2.1.6. Address Register Indirect With Index</a><br>
+<a href="#2.2.1.7. Absolute Data Addressing">2.2.1.7. Absolute Data Addressing</a><br>
+<a href="#2.2.1.8. Program Counter With Displacement.">2.2.1.8. Program Counter With Displacement.</a><br>
+<a href="#2.2.1.9. Program Counter With Index">2.2.1.9. Program Counter With Index</a><br>
+<a href="#2.2.1.10. Immediate Data">2.2.1.10. Immediate Data</a><br>
+<a href="#2.2.2. Extra MC68020 addressing modes">2.2.2. Extra MC68020 addressing modes</a><br>
+<a href="#2.2.2.1. Address Register Indirect With Index (Base Displacement)">2.2.2.1. Address Register Indirect With Index (Base Displacement)</a><br>
+<a href="#2.2.2.2. Memory Indirect Post-Indexed">2.2.2.2. Memory Indirect Post-Indexed</a><br>
+<a href="#2.2.2.3. Memory Indirect Pre-Indexed">2.2.2.3. Memory Indirect Pre-Indexed</a><br>
+<a href="#2.2.3. Addressing modes used in the table">2.2.3. Addressing modes used in the table</a><br>
+<a href="#3. The M68000 and MC68020 back end table">3. The M68000 and MC68020 back end table</a><br>
+<a href="#3.1. Constant Definitions">3.1. Constant Definitions</a><br>
+<a href="#3.2. Properties">3.2. Properties</a><br>
+<a href="#3.3. Registers">3.3. Registers</a><br>
+<a href="#3.4. Tokens">3.4. Tokens</a><br>
+<a href="#3.4.1. Token names">3.4.1. Token names</a><br>
+<a href="#3.4.2. Special tokens for the MC68000">3.4.2. Special tokens for the MC68000</a><br>
+<a href="#3.5. Sets">3.5. Sets</a><br>
+<a href="#3.6. Instructions">3.6. Instructions</a><br>
+<a href="#3.7. Moves">3.7. Moves</a><br>
+<a href="#3.8. Tests">3.8. Tests</a><br>
+<a href="#3.9. Stackingrules">3.9. Stackingrules</a><br>
+<a href="#3.10. Coercions">3.10. Coercions</a><br>
+<a href="#3.11. Patterns">3.11. Patterns</a><br>
+<a href="#3.11.1. Group 0: rules for register variables">3.11.1. Group 0: rules for register variables</a><br>
+<a href="#3.11.2. Groups 1 and 2: load and store instructions">3.11.2. Groups 1 and 2: load and store instructions</a><br>
+<a href="#3.11.3. Groups 3 and 4: integer and unsigned arithmetic">3.11.3. Groups 3 and 4: integer and unsigned arithmetic</a><br>
+<a href="#3.11.4. Group 5: floating point arithmetic">3.11.4. Group 5: floating point arithmetic</a><br>
+<a href="#3.11.5. Group 6: pointer arithmetic">3.11.5. Group 6: pointer arithmetic</a><br>
+<a href="#3.11.6. Group 9: logical instructions">3.11.6. Group 9: logical instructions</a><br>
+<a href="#3.11.7. Group 11: arrays">3.11.7. Group 11: arrays</a><br>
+<a href="#3.11.8. Group 14: procedure calls instructions">3.11.8. Group 14: procedure calls instructions</a><br>
+<a href="#3.11.9. Group 15: miscellaneous instructions">3.11.9. Group 15: miscellaneous instructions</a><br>
+<a href="#3.11.10. Extra group: optimalization">3.11.10. Extra group: optimalization</a><br>
+<a href="#4. The library routines">4. The library routines</a><br>
+<a href="#5. Testing the table">5. Testing the table</a><br>
+<a href="#6. Performance of the back end">6. Performance of the back end</a><br>
+<a href="#7. Some timing results">7. Some timing results</a><br>
+<a href="#8. Some final remarks">8. Some final remarks</a><br>
+<a href="#References">References</a><br>
+
+<hr>
+
+<p align=center><i><small>ABSTRACT</small></i></p>
+
+<p align=center><i><small>Frank Doodeman</small></i></p>
+
+<p><small>A back end table is part of the Amsterdam
+Compiler Kit (ACK). It is used to produce the actual back
+end, a program that translates the intermediate language
+family EM to assembly language for some target machine. The
+table discussed here can be used for two back ends, suitable
+for in total three machines: the MC68000 and MC68010 (the
+difference between these two is so small that one back end
+table can be used for either one), or for the
+MC68020.</small></p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p><small>To simplify the task of producing portable
+(cross) compilers and interpreters the Vrije Universiteit
+designed an integrated collection of programs, the Amsterdam
+Compiler Kit (ACK) [2]. It is based on the old UNCOL idea
+[1] which attempts to solve the problem of how to make a
+compiler for each of N languages on M different machines
+without having to write N&times;M programs.</small></p>
+
+<p><small>The UNCOL approach is to write N <i>front
+ends,</i> which translate the source language into a common
+intermediate language UNCOL (Universal Computer Oriented
+Language), and M <i>back ends,</i> each of which translates
+programs in UNCOL into a specific machine language. Under
+these conditions only M+N programs must be written to
+provide all N languages on all M machines, instead of
+M&times;N programs.</small></p>
+
+<p><small>The intermediate language for the Amsterdam
+Compiler Kit is the machine language for a simple stack
+machine called EM (Encoding Machine) [3]. So a back end for
+the MC68020 translates EM code into MC68020 assembly
+language. Writing such a table [4] suffices to get the back
+end.</small></p>
+
+<p><small>The back end is a single program that is driven
+by a machine dependent driving table. This table, the back
+end table, defines the mapping of EM code to the MC68000,
+MC68010 or MC68020 assembly language.</small></p>
+<a name="2. The MC68000 and MC68020 micro processors"></a>
+<h2>2. The MC68000 and MC68020 micro processors</h2>
+
+<p><small>In this document the name MC68000 will be used
+for both the MC68000 and the MC68010 micro processors,
+because as far as the back end table is concerned there is
+no difference between them. For a complete and detailed
+description of the MC68020 one is referred to [5]; for the
+MC68000 one might also use [6]. In this section some
+relevant parts will be handled.</small></p>
+<a name="2.1. Registers"></a>
+<h2>2.1. Registers</h2>
+
+<p><small>Both the MC68000 and the MC68020 have eight
+32-bit data registers (D <small><small>0</small></small> -D
+<small><small>7</small></small> ) that can be used for byte
+(8-bit), word (16-bit) and long word (32-bit) data
+operations. They also have seven 32-bit address registers (A
+<small><small>0</small></small> -A
+<small><small>6</small></small> ) that may be used as
+software stack pointers and base address registers; address
+register A <small><small>7</small></small> is used as the
+system stack pointer. Address registers may also be used for
+word and long word address operations.</small></p>
+<a name="2.2. Addressing modes"></a>
+<h2>2.2. Addressing modes</h2>
+
+<p><small>First the MC68000 addressing modes will be
+discussed. Since the MC68020&rsquo;s set of addressing modes
+is an extension of the MC68000&rsquo;s set, of course this
+section also applies to the MC68020.</small></p>
+
+<p><small>In the description we use:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%">
+
+<p><small>A <small><small>n</small></small></small></p>
+</td>
+<td width="6%"></td>
+<td width="42%">
+
+<p><small>for address register;</small></p>
+</td>
+<td width="48%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%">
+
+<p><small>D <small><small>n</small></small></small></p>
+</td>
+<td width="6%"></td>
+<td width="36%">
+
+<p><small>for data register;</small></p>
+</td>
+<td width="54%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%">
+
+<p><small>R <small><small>n</small></small></small></p>
+</td>
+<td width="6%"></td>
+<td width="58%">
+
+<p><small>for address or data register;</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%">
+
+<p><small>X <small><small>n</small></small></small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>for index register (either data or address
+register);</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>PC</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>for program counter;</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%">
+
+<p><small>d <small><small>8</small></small></small></p>
+</td>
+<td width="6%"></td>
+<td width="62%">
+
+<p><small>for 8 bit displacement integer;</small></p>
+</td>
+<td width="28%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>d <small><small>16</small></small></small></p>
+</td>
+<td width="4%"></td>
+<td width="64%">
+
+<p><small>for 16 bit displacement integer;</small></p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>bd</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>for base displacement (may be null, word or
+long);</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>od</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>for outer displacement (may be null, word or
+long).</small></p>
+</td>
+</table>
+<a name="2.2.1. General addressing modes"></a>
+<h2>2.2.1. General addressing modes</h2>
+<a name="2.2.1.1. Register Direct Addressing"></a>
+<h2>2.2.1.1. Register Direct Addressing</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="3%">
+
+<p><small>R <small><small>n</small></small></small></p>
+</td>
+<td width="80%">
+</td>
+</table>
+
+<p><small>This addressing mode (it can be used with either
+a data register or an address register) specifies that the
+operand is in one of the 16 multifunction
+registers.</small></p>
+<a name="2.2.1.2. Address Register Indirect"></a>
+<h2>2.2.1.2. Address Register Indirect</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="7%">
+
+<p><small>(A <small><small>n</small></small> )</small></p>
+</td>
+<td width="76%">
+</td>
+</table>
+
+<p><small>The address of the operand is in the address
+register specified.</small></p>
+<a name="2.2.1.3. Address Register Indirect With Postincrement"></a>
+<h2>2.2.1.3. Address Register Indirect With Postincrement</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="9%">
+
+<p><small>(A <small><small>n</small></small> )+</small></p>
+</td>
+<td width="74%">
+</td>
+</table>
+
+<p><small>The address of the operand is in the address
+register specified. After the operand address is used, the
+address register is incremented by one, two or four
+depending upon whether the size of the operand is byte, word
+or long. If the address register is the stack pointer and
+the operand size is byte, the address register is
+incremented by two rather than one to keep the stack pointer
+on a word boundary.</small></p>
+<a name="2.2.1.4. Address Register Indirect With Predecrement"></a>
+<h2>2.2.1.4. Address Register Indirect With Predecrement</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="9%">
+
+<p><small>&minus;(A <small><small>n</small></small>
+)</small></p>
+</td>
+<td width="74%">
+</td>
+</table>
+
+<p><small>The address of the operand is in the address
+register specified. Before the operand address is used, the
+address register is decremented by one, two or four
+depending upon whether the size of the operand is byte, word
+or long. If the address register is the stack pointer and
+the operand size is byte, the address register is
+decremented by two rather than one to keep the stack pointer
+on a word boundary.</small></p>
+<a name="2.2.1.5. Address Register Indirect With Displacement"></a>
+<h2>2.2.1.5. Address Register Indirect With Displacement</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="84%">
+
+<p><small>d <small><small>16</small></small> (A
+<small><small>n</small></small> ) for the MC68000, (d
+<small><small>16</small></small> ,A
+<small><small>n</small></small> ) for the
+MC68020</small></p>
+</td>
+</table>
+
+<p><small>This address mode requires one word of extension.
+The address of the operand is the sum of the contents of the
+address register and the sign extended 16-bit integer in the
+extension word.</small></p>
+<a name="2.2.1.6. Address Register Indirect With Index"></a>
+<h2>2.2.1.6. Address Register Indirect With Index</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="84%">
+
+<p><small>d <small><small>8</small></small> (A
+<small><small>n</small></small> ,X
+<small><small>n</small></small> .size) for the MC68000, (d
+<small><small>8</small></small> ,A
+<small><small>n</small></small> ,X
+<small><small>n</small></small> .size) for the
+MC68020</small></p>
+</td>
+</table>
+
+<p><small>This address mode requires one word of extension
+according to a certain format, which specifies</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1.</small></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><small>which register to use as index
+register;</small></p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>a flag that indicates whether the index register
+is a data register or an address register;</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>a flag that indicates the index size; this is
+<i>word</i> when the low order part of the index register is
+to be used, and <i>long</i> when the whole long value in the
+register is to be used as index;</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>an 8-bit displacement integer (the low order byte
+of the extension word).</small></p>
+</td>
+</table>
+
+<p><small>The address of the operand is the sum of the
+contents of the address register, the possibly sign extended
+contents of index register and the sign extended 8-bit
+displacement.</small></p>
+<a name="2.2.1.7. Absolute Data Addressing"></a>
+<h2>2.2.1.7. Absolute Data Addressing</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="84%">
+
+<p><small>address for the MC68000, (address) for the
+MC68020</small></p>
+</td>
+</table>
+
+<p><small>Two different kinds of this mode are
+available:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Absolute Short Address; this mode requires one
+word of extension. The address of the operand is the sign
+extended 16-bit extension word.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Absolute Long Address; this mode requires two
+words of extension. The address of the operand is developed
+by concatenation of the two extension words; the high order
+part of the address is the first extension word, the low
+order part is the second.</small></p>
+</td>
+</table>
+<a name="2.2.1.8. Program Counter With Displacement."></a>
+<h2>2.2.1.8. Program Counter With Displacement.</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="84%">
+
+<p><small>d <small><small>16</small></small> (PC) for the
+MC68000, (d <small><small>16</small></small> ,PC) for the
+MC68020</small></p>
+</td>
+</table>
+
+<p><small>This mode requires one word of extension. The
+address of the operand is the sum of the address in the
+program counter and the sign extended 16-bit displacement
+integer in the extension word. The value in the program
+counter is the address of the extension word.</small></p>
+<a name="2.2.1.9. Program Counter With Index"></a>
+<h2>2.2.1.9. Program Counter With Index</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="84%">
+
+<p><small>d <small><small>8</small></small> (PC,X
+<small><small>n</small></small> .size) for the MC68000, (d
+<small><small>8</small></small> ,PC,X
+<small><small>n</small></small> .size) for the
+MC68020</small></p>
+</td>
+</table>
+
+<p><small>This mode requires one word of extension as
+described under <i>Address Register Indirect With Index.</i>
+The address of the operand is the sum of the value in the
+program counter, the possibly sign extended index register
+and the sign extended 8-bit displacement integer in the
+extension word. The value in the program counter is the
+address of the extension word.</small></p>
+<a name="2.2.1.10. Immediate Data"></a>
+<h2>2.2.1.10. Immediate Data</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="34%">
+
+<p><small>.if !r0x .nr 0x 0</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+
+<p><small>This addressing mode requires either one or two
+words of extension, depending on the size of the
+operation;</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>byte operation - the operand is in the low order
+byte of extension word;</small></p>
+<!-- INDENTATION -->
+<p><small>word operation - the operand is in the extension
+word;</small></p>
+<!-- INDENTATION -->
+<p><small>long operation - the operand is in the two
+extension words, the high order 16-bits are in the first
+extension word, the low order 16-bits in the
+second.</small></p></td>
+</table>
+<a name="2.2.2. Extra MC68020 addressing modes"></a>
+<h2>2.2.2. Extra MC68020 addressing modes</h2>
+
+<p><small>The MC68020 has three more addressing modes.
+These modes all use a displacement (some even two), an
+address register and an index register. Instead of the
+address register one may also use the program counter. Any
+of these may be omitted. If all addends are omitted the
+processor creates an effective address of zero. All of these
+three modes require at least one extension word, the <i>Full
+Format Extension Word,</i> which specifies:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1.</small></p>
+</td>
+<td width="6%"></td>
+<td width="64%">
+
+<p><small>the index register number (0-7);</small></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>the index register type (address or data
+register);</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>the size of the index (only low order part or the
+whole register)</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>a scale factor. This is a number from 0 to 3
+which specifies how many bits the contents of the index
+register is to be shifted to the left before being used as
+an index;</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>5.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>a flag that specifies whether the base (address)
+register is to be added or to be suppressed;</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>6.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>a flag that specifies whether to add or suppress
+the index operand;</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>7.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>two bits that specify the size of the base
+displacement (null, word or long);</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>8.</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>three bits that in combination with (6) above
+specify which of the three addressing modes (described
+below) to use and, if used, the size of the outer
+displacement (null, word or long).</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>N.B.</small></p>
+</td>
+<td width="2%"></td>
+<td width="90%">
+
+<p><small>All modes mentioned above for the MC68000 that
+use an index register may have this register scaled (only
+when using the MC68020).</small></p>
+</td>
+</table>
+
+<p><small>The three extra addressing modes are:</small></p>
+<a name="2.2.2.1. Address Register Indirect With Index (Base Displacement)"></a>
+<h2>2.2.2.1. Address Register Indirect With Index (Base Displacement)</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="70%">
+
+<p><small>(bd,A <small><small>n</small></small> ,X
+<small><small>n</small></small> .size*scale) (MC68020
+only)</small></p>
+</td>
+<td width="13%">
+</td>
+</table>
+
+<p><small>The address of the operand is the sum of the
+contents of the address register, the scaled contents of the
+possibly scaled index register and the possibly sign
+extended base displacement. When the program counter is used
+instead of the address register, the value in the program
+counter is the address of the full format extension word.
+This mode requires one or two more extension words when the
+size of the base displacement is word or long
+respectively.</small></p>
+
+<p><small>Note that without the index operand, this mode is
+an extension of the <i>Address Register Indirect With
+Displacement</i> mode; when using the MC68020 one is no
+longer limited to a 16-bit displacement. Also note that with
+the index operand added, this mode is an extension of the
+<i>Address Register Indirect With Index</i> mode; when using
+the MC68020 one is no longer limited to an 8-bit
+displacement.</small></p>
+<a name="2.2.2.2. Memory Indirect Post-Indexed"></a>
+<h2>2.2.2.2. Memory Indirect Post-Indexed</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="80%">
+
+<p><small>([bd,A <small><small>n</small></small> ],X
+<small><small>n</small></small> .size*scale,od) (MC68020
+only)</small></p>
+</td>
+<td width="3%">
+</td>
+</table>
+
+<p><small>This mode may use an outer displacement. First an
+intermediate memory address is calculated by adding the
+contents of the address register and the possibly sign
+extended base displacement. This address is used for in
+indirect memory access of a long word, followed by adding
+the index operand (scaled and possibly signed extended).
+Finally the outer displacement is added to yield the address
+of the operand. When the program counter is used, the value
+in the program counter is the address of the full format
+extension word.</small></p>
+<a name="2.2.2.3. Memory Indirect Pre-Indexed"></a>
+<h2>2.2.2.3. Memory Indirect Pre-Indexed</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>Syntax:</small></p>
+</td>
+<td width="2%"></td>
+<td width="80%">
+
+<p><small>([bd,A <small><small>n</small></small> ,X
+<small><small>n</small></small> .size*scale],od) (MC68020
+only)</small></p>
+</td>
+<td width="3%">
+</td>
+</table>
+
+<p><small>This mode may use an outer displacement. First an
+intermediate memory address is calculated by adding the
+contents of the address register, the scaled contents of the
+possibly sign extended index register and the possibly sign
+extended base displacement. This address is used for an
+indirect memory access of a long word, followed by adding
+the outer displacement to yield the address of the operand.
+When the program counter is used, the value in the program
+counter is the address of the full format extension
+word.</small></p>
+<a name="2.2.3. Addressing modes used in the table"></a>
+<h2>2.2.3. Addressing modes used in the table</h2>
+
+<p><small>Not all addressing modes mentioned above are used
+in code generation. It is clear that none of the modes that
+use the program counter PC can be used, since at code
+generation time nothing is known about the value in PC. Also
+some of the possibilities of the three MC68020 addressing
+modes are not used; e.g. it is possible to use a <i>Data
+Register Indirect</i> mode, which actually is the <i>Address
+Register Indirect With Index</i> mode, with the address
+register and the displacement left out. However such a mode
+would require two extra bytes for the full format extension
+word, and it would also be much slower than using <i>Address
+Register Indirect.</i> For this kind of reasons several
+possible addressing modes are not used in the generation of
+code. In the table address registers are only used for
+holding addresses, and for index registers only data
+registers are used.</small></p>
+<a name="3. The M68000 and MC68020 back end table"></a>
+<h2>3. The M68000 and MC68020 back end table</h2>
+
+<p><small>The table itself has to be run through the C
+preprocessor before it can be used to generate the back end
+(called <i>code generator</i> or <i>cg</i> for short). When
+no flags are given to the preprocessor an MC68020 code
+generator is produced; for the MC68000 code generator one
+has to run the table through the preprocessor using the
+<i>-Dm68k4</i> flag.</small></p>
+
+<p><small>The table is designed as described in [4]. For
+the overall design of a back end table one is referred to
+this document. This section only deals with problems
+encountered in writing the table and other things worth
+noting.</small></p>
+<a name="3.1. Constant Definitions"></a>
+<h2>3.1. Constant Definitions</h2>
+
+<p><small>Wordsize and pointersize (EM_WSIZE and EM_PSIZE
+respectively) are defined as four (bytes). EM_BSIZE, the
+hole between AB (the parameter base) and LB (the local
+base), is eight bytes: only the return address and the
+localbase are saved.</small></p>
+<a name="3.2. Properties"></a>
+<h2>3.2. Properties</h2>
+
+<p><small>Since Hans van Staveren in his document [4]
+clearly states that <i>cg</i> execution time is negatively
+influenced by the number of properties, only four different
+properties have been defined. Besides, since the registers
+really are multifunctional, these four are really all that
+are needed.</small></p>
+<a name="3.3. Registers"></a>
+<h2>3.3. Registers</h2>
+
+<p><small>The table uses register variables: D
+<small><small>3</small></small> - D
+<small><small>7</small></small> are used as general register
+variables, and address registers A
+<small><small>2</small></small> - A
+<small><small>5</small></small> are used as pointer register
+variables. A <small><small>6</small></small> is reserved for
+the localbase.</small></p>
+<a name="3.4. Tokens"></a>
+<h2>3.4. Tokens</h2>
+
+<p><small>At first glance one might wonder about the amount
+of tokens, especially for the MC68020, considering the small
+amount of different addressing modes. However, the last
+three addressing modes mentioned for the MC68020 may omit
+any of the addends, and this leads to a large amount of
+different tokens. I did consider the possibility of
+enlarging the number of tokens and sets even further,
+because there might be assemblers that don&rsquo;t handle
+displacements of zero optimally (they might generate a 2
+byte extension word holding zero). The small profit in bytes
+in the generated code however does not justify the increase
+in size of the token section, the set section and the
+patterns section, so this idea was not developed any
+further.</small></p>
+
+<p><small>The timing cost of the tokens may be incorrect
+for some MC68000 tokens. This is because the MC68000 uses a
+16-bit data bus which causes the need of two separate memory
+accesses for getting 32-bit operands.</small></p>
+<a name="3.4.1. Token names"></a>
+<h2>3.4.1. Token names</h2>
+
+<p><small>The amount of tokens and the limited capability
+of the authors imagination might have caused the names of
+some tokens not to be very clarifying. Some information
+about the names may be in place here.</small></p>
+
+<p><small>Whenever part of a token name is in capitals that
+part is memory indirected (i.e. in square brackets). In
+token names <i>OFF</i> and <i>off</i> mean an offsetted
+address register, so an address register with a displacement
+(either base displacement or outer displacement). <i>IND,
+ind</i> and <i>index</i> stand for indexed, or index
+register. <i>ABS</i> and <i>abs</i> stand for absolute,
+which actually is just a displacement (base or outer). These
+&lsquo;rules&rsquo; only apply to names of tokens that
+represent actual operands. There are also tokens that
+represent addresses of operands. These (with a few
+exceptions) contain <i>regA, regX</i> and <i>con</i> as
+parts of there names, which stand for address register,
+index register and displacement (always base displacement)
+respectively. If the address to which the token refers uses
+memory indirection, that part of the name comes first (in
+small letters), followed by an underscore. The memory
+indirection part follows the &lsquo;rules&rsquo; for operand
+token names.</small></p>
+
+<p><small>Of course there are exceptions to these
+&lsquo;rules&rsquo; but in those cases the names are self
+explanatory.</small></p>
+
+<p><small>Two special cases: <i>ext_regX</i> is the name of
+the token that represents the address of an absolute indexed
+operand, syntax (bd,X <small><small>n</small></small>
+.size*scale); <i>regX</i> does not represent any real mode,
+but is used with EM array instructions and pointer
+arithmetic.</small></p>
+<a name="3.4.2. Special tokens for the MC68000"></a>
+<h2>3.4.2. Special tokens for the MC68000</h2>
+
+<p><small>The MC68000 requires two extra tokens, which are
+called <i>t_regAcon</i> and <i>t_regAregXcon.</i> They are
+necessary because <i>regAcon</i> can only have a 16-bit
+displacement on the MC68000, and <i>regAregXcon</i> uses
+only 8 bits for its displacement. To prevent these
+addressing modes to be used with displacements that are too
+large, the extra tokens are needed. Whenever the
+displacements become too large and they need to be used in
+the generation of assembly code, these tokens are
+transformed into other tokens. To prevent the table from
+becoming too messy I defined <i>t_regAcon</i> and
+<i>t_regAregXcon</i> to be identical to <i>regAcon</i> and
+<i>regAregXcon</i> respectively for the MC68020.</small></p>
+<a name="3.5. Sets"></a>
+<h2>3.5. Sets</h2>
+
+<p><small>Most set names used in the table are self
+explanatory, especially to the reader who is familiar with
+the four addressing categories as mentioned in [5]: <i>data,
+memory, alterable</i> and <i>control.</i> In the sets
+definition part some sets are defined that are not used
+elsewhere in the table, but are only used to be part of the
+definition of some other set. This keeps the set definition
+part from getting too unreadable.</small></p>
+
+<p><small>The sets called <i>imm_cmp</i> consist of all
+tokens that can be used to compare with a
+constant.</small></p>
+<a name="3.6. Instructions"></a>
+<h2>3.6. Instructions</h2>
+
+<p><small>Only the instructions that are used in code
+generation are listed here. The first few instructions are
+meant especially for the use with register variables. The
+operand LOCAL used here refers to a register variable. The
+reader may not conclude that these operations are also
+allowed on ordinary locals. The space and timing cost of
+these instructions have been adapted, but the use of the
+word LOCAL for register variables causes these cost to be
+inaccurate anyway.</small></p>
+
+<p><small>The <i>killreg</i> instruction, which generates a
+comment in the assembly language output and which is meant
+to let <i>cg</i> know that the data register operand has its
+contents destroyed, needs some explaining but this
+explanation is better in place in the discussion of groups 3
+and 4 of the section about patterns.</small></p>
+
+<p><small>The timing cost of the instructions are probably
+not very accurate for the MC68020 because the MC68020 uses
+an instruction cache and prefetch. The cost used in the
+table are the &lsquo;worst case cost&rsquo; as mentioned in
+section 9 of [5].</small></p>
+<a name="3.7. Moves"></a>
+<h2>3.7. Moves</h2>
+
+<p><small>These are all pretty straightforward, except
+perhaps when <i>t_regAcon</i> and <i>t_regAregXcon</i> are
+used. In these cases the size of the displacement has to be
+checked before moving. This also applies to the stacking
+rules and the coercions.</small></p>
+<a name="3.8. Tests"></a>
+<h2>3.8. Tests</h2>
+
+<p><small>These three tests (one fore each operation size)
+could not be more straightforward than they are
+now.</small></p>
+<a name="3.9. Stackingrules"></a>
+<h2>3.9. Stackingrules</h2>
+
+<p><small>The only peculiar stackingrule is the one for
+<i>regX.</i> This token is only used with EM array
+instructions and with pointer arithmetic. Whenever it is put
+on the fake stack, some EM instructions are left in the
+instruction stream to remove this token. Consequently it
+should never have to be stacked. However the <i>code
+generator generator</i> (or <i>cgg</i> for short) complained
+about not having a stackingrule for this token, so it had to
+be added nevertheless.</small></p>
+<a name="3.10. Coercions"></a>
+<h2>3.10. Coercions</h2>
+
+<p><small>These are all straightforward. There are no
+splitting coercions since the fake stack never contains any
+tokens that can be split. There are only two unstacking
+coercions. The rest are all transforming coercions. Almost
+all coercions transform tokens into either a data register
+or an address register, except in the MC68000 part of the
+table the <i>t_regAcon</i> and <i>t_regAregXcon</i> tokens
+are transformed into real <i>regAcon</i> and
+<i>regAregXcon</i> tokens with displacements that are
+properly sized.</small></p>
+<a name="3.11. Patterns"></a>
+<h2>3.11. Patterns</h2>
+
+<p><small>This is the largest part of the table. It is
+subdivided into 17 groups. We will take a closer look at the
+more interesting groups.</small></p>
+<a name="3.11.1. Group 0: rules for register variables"></a>
+<h2>3.11.1. Group 0: rules for register variables</h2>
+
+<p><small>This group makes sure that EM instructions using
+register variables are handled efficiently. This group
+includes: local loads and stores; arithmetic, shifts and
+logical operations on locals and indirect locals and pointer
+handling, where C expressions like <i>*cp++</i> are handled.
+For such an expression there are several EM instruction
+sequences the front end might generate. For an integer
+pointer e.g.:</small></p>
+<pre><small><b>     lol lol adp stl loi $1==$2 &amp;&amp; $1==$4 &amp;&amp; $3==4 &amp;&amp; $5==4
+</b></small></pre>
+
+<p><small>or</small></p>
+<pre><small><b>     lol loi lol adp stl $1==$3 &amp;&amp; $3==$5 &amp;&amp; $2==4 &amp;&amp; $5==4
+</b></small></pre>
+
+<p><small>or perhaps even</small></p>
+<pre><small><b>     lil lol adp stl $1==$2 &amp;&amp; $2==$4 &amp;&amp; $3==4
+</b></small></pre>
+
+<p><small>Each of these is included, since which one is
+generated is is up to the front end. If the front end is
+consistent this will mean that some of these patterns will
+never be used in code generation. This might seem a waist,
+but anyone who thinks that will certainly change his mind
+when his new C front end generates a different EM
+instruction sequence.</small></p>
+<a name="3.11.2. Groups 1 and 2: load and store instructions"></a>
+<h2>3.11.2. Groups 1 and 2: load and store instructions</h2>
+
+<p><small>In these groups <b>lof</b> and <b>stf</b> ,
+<b>loi</b> and <b>sti</b> , <b>ldf</b> and <b>sdf</b> are
+the important instructions. These are the large parts in
+this group, especially the <b>loi</b> and <b>sti</b>
+instructions, because they come in three basic sizes (byte,
+word and long). Note that with these instructions in the
+MC68000 part the <i>exact</i> is omitted in front of
+<i>regAcon</i> and <i>regAregXcon.</i> This makes sure that
+<i>t_regAcon</i> and <i>t_regAregXcon</i> are transformed
+into proper tokens before they are used as
+addresses.</small></p>
+
+<p><small>Also note that the <i>regAregXcon</i> token is
+completely left out from the <b>lof</b>, <b>stf</b>,
+<b>ldf</b> and <b>sdf</b> instruction handling. This is
+because the sum of the token displacement and the offset
+provided in the instruction cannot be checked and is likely
+to exceed 8 bits. Unfortunately <i>cgg</i> does not allow
+the inspection of subregisters of tokens that are on the
+fake stack. This same problem might also occur with the
+<i>regAcon</i> token, but this is less likely because it
+uses 16-bit displacements. Besides if it would have been
+left out the <b>lof</b>, <b>stf</b>, <b>ldf</b> and
+<b>sdf</b> instructions would have been handled considerably
+less efficient.</small></p>
+<a name="3.11.3. Groups 3 and 4: integer and unsigned arithmetic"></a>
+<h2>3.11.3. Groups 3 and 4: integer and unsigned arithmetic</h2>
+
+<p><small>EM instruction <b>sbi</b> also works with address
+registers, because the <b>cmp</b> instruction in group 12 is
+replaced by <b>sbi 4</b>.</small></p>
+
+<p><small>For the MC68000 <b>mli</b>, <b>mlu</b>,
+<b>dvi</b>, <b>dvu</b>, <b>rmi</b> and <b>rmu</b> are
+handled by library routines. This is because the MC68000 has
+only 16-bit multiplications and divisions.</small></p>
+
+<p><small>The MC68020 does have 32-bit multiplications and
+divisions, but for the <b>rmi</b> and <b>rmu</b> EM
+instructions peculiar things happen anyway: they generate
+the <i>killreg</i> instruction. This is necessary because
+the data register that first held the dividend now holds the
+quotient; the original contents are destroyed without
+<i>cg</i> knowing about it (the destruction of the two
+registers that make up the <i>DREG_pair</i> token
+couldn&rsquo;t be noted in the instructions part of the
+table). To let <i>cg</i> know that these contents are
+destroyed, we have to use this &lsquo;pseudo
+instruction&rsquo; from lack of a better
+solution.</small></p>
+<a name="3.11.4. Group 5: floating point arithmetic"></a>
+<h2>3.11.4. Group 5: floating point arithmetic</h2>
+
+<p><small>Since floating point arithmetic is not
+implemented traps will be generated here.</small></p>
+<a name="3.11.5. Group 6: pointer arithmetic"></a>
+<h2>3.11.5. Group 6: pointer arithmetic</h2>
+
+<p><small>This also is a very important group, along with
+groups 1 and 2. The MC68020 has many different addressing
+modes and if possible they should be used in the generation
+of assembly language.</small></p>
+
+<p><small>The <i>regX</i> token is generated here too. It
+is meant to make efficient use of the MC68020 possibility of
+scaling index registers.</small></p>
+
+<p><small>Note that I would have liked one extra pattern to
+handle C-statements like</small></p>
+<pre><small><i>     pointer += expr ? constant1 : constant2;
+</i></small></pre>
+
+<p><small>efficiently. This pattern would have looked
+like:</small></p>
+<pre><small>     pat ads
+     with const
+     leaving adp %1.num
+</small></pre>
+
+<p><small>but when <i>cg</i> is coming to the EM
+replacement part, the constant has already been removed from
+the fake stack, causing <i>%1.num</i> to have a wrong
+value.</small></p>
+<a name="3.11.6. Group 9: logical instructions"></a>
+<h2>3.11.6. Group 9: logical instructions</h2>
+
+<p><small>The EM instructions <b>and</b>, <b>ior</b> and
+<b>xor</b> are so much alike that procedures can be used
+here, except for the <b>xor $1==4</b> instruction, because
+the MC68000 <i>eor</i> instruction does not allow as many
+kinds of operands as <i>and</i> and <i>or.</i></small></p>
+<a name="3.11.7. Group 11: arrays"></a>
+<h2>3.11.7. Group 11: arrays</h2>
+
+<p><small>This group also tries to make efficient use of
+the available addressing modes, but it leaves the actual
+work to group 6 mentioned above.</small></p>
+
+<p><small>The <i>regX</i> token is also generated here. In
+this group this token is very useful for handling array
+instructions for arrays with one, two, four or eight byte
+elements; the array index goes into the index register,
+which can then be scaled appropriately. An offset is used
+when the first array element has an index other than
+zero.</small></p>
+
+<p><small>I would have liked some extra patterns here too
+but they won&rsquo;t work for the same reasons as explained
+in the discussion of group 6.</small></p>
+<a name="3.11.8. Group 14: procedure calls instructions"></a>
+<h2>3.11.8. Group 14: procedure calls instructions</h2>
+
+<p><small>The function return area consists of registers D
+<small><small>0</small></small> and D
+<small><small>1</small></small> .</small></p>
+<a name="3.11.9. Group 15: miscellaneous instructions"></a>
+<h2>3.11.9. Group 15: miscellaneous instructions</h2>
+
+<p><small>In many cases here library routines are called.
+These will be discussed later.</small></p>
+
+<p><small>Two special EM instructions are included here:
+<b>dch</b>, and <b>lpb</b>. I don&rsquo;t know when they are
+generated by a front end, but these instructions were also
+in the back end table for the PDP. In the PDP table these
+instructions were replaced by <b>loi 4</b> and <b>adp 8</b>
+respectively. I included them both, since they
+couldn&rsquo;t do any harm.</small></p>
+<a name="3.11.10. Extra group: optimalization"></a>
+<h2>3.11.10. Extra group: optimalization</h2>
+
+<p><small>This group is handling EM patterns with more than
+one instruction. This group is not absolutely necessary but
+it makes the generation of code more efficient. Among the
+things that are handled here are: arithmetic and logical
+operations on locals, externals and indirect locals;
+shifting of locals, externals and indirect locals by one;
+some pointer arithmetic; tests in combination with logical
+and&rsquo;s and or&rsquo;s or with branches. Finally there
+are sixteen patterns about divisions that could be handled
+more efficiently by right shifts and which I think should be
+handled by the peephole optimizer (since it also handles the
+same patterns with multiplication).</small></p>
+<a name="4. The library routines"></a>
+<h2>4. The library routines</h2>
+
+<p><small>The table is supplied with two separate
+libraries: one for the MC68000 and one for the MC68020. The
+MC68000 uses a couple more routines than the MC68020 because
+it doesn&rsquo;t have 32-bit division and
+multiplication.</small></p>
+
+<p><small>The routines that need to pop their operands
+first store their return address. Routines that need other
+register besides D <small><small>0</small></small> -D
+<small><small>2</small></small> and A
+<small><small>0</small></small> -A
+<small><small>1</small></small> first store the original
+contents of those registers. D
+<small><small>0</small></small> -D
+<small><small>2</small></small> and A
+<small><small>0</small></small> -A
+<small><small>1</small></small> do not have to be saved
+because if they contain anything useful, their contents are
+pushed on the stack before the routine is
+called.</small></p>
+
+<p><small>The <i>.trp</i> routine just prints a message
+stating the trap number and exits (except of course when
+that particular trap number is masked). Usually higher level
+languages use their own trap handling routines.</small></p>
+
+<p><small>The <i>.mon</i> routine doesn&rsquo;t do anything
+useful at all. It just prints a message stating that the
+specified system call is not implemented and then exits.
+Front ends usually generate calls to special routines rather
+than the EM instruction <b>mon</b>. These routines have to
+be supplied in another library. They may be system dependent
+(e.g. the MC68000 machine this table was tested on first
+moves the parameters to registers, then moves the system
+call number to D <small><small>0</small></small> and then
+executes <i>trap #0,</i> whereas the MC68020 machine this
+table was tested on required the parameters to be on the
+stack rather than in registers). Therefor this library is
+not discussed here.</small></p>
+
+<p><small>The <i>.printf</i> routine is included for EM
+diagnostic messages. It can print strings using %s, 16-bit
+decimal numbers using %d and 32-bit hexadecimal numbers
+using %x.</small></p>
+
+<p><small>The <i>.strhp</i> routine stores a new EM heap
+pointer, and sometimes it needs to allocate more heap space.
+This is done by calling the system call routine <i>_brk</i>.
+Chunks of 1K bytes are allocated, but this can easily be
+changed into larger or smaller chunks.</small></p>
+
+<p><small>The MC68000 library also contains a routine to
+handle the EM instruction <b>rck</b>. The MC68020 has an
+instruction <i>cmp2</i> that is specially meant for range
+checking so the MC68020 library can do without that
+routine.</small></p>
+
+<p><small>The MC68000 library has two multiplication
+routines, one for unsigned and the other for signed
+multiplication. The one for signed multiplication first
+tests the sizes of the operands, to see if it can perform
+the 16 bit machine instruction instead of the routine. If
+not, it considers it&rsquo;s two operands being two digit
+numbers in a 65535-radix system. It uses the 16-bit unsigned
+multiply instruction <i>mulu</i> three times (it does not
+calculate the high order result), and adds up the
+intermediary results the proper way. The signed
+multiplication routine calculates the sign of the result,
+calculates the result as it it were an unsigned
+multiplication, and adjusts the sign of the result. Here
+testing the operands for there sizes would be less simple,
+because the operands are signeds; so that is not done
+here.</small></p>
+
+<p><small>The MC68000 library also has two division
+routines. The routine for unsigned division uses the popular
+algorithm, where the divisor is shifted out and the quotient
+shifted in. The signed division routine calculates the sign
+of both the quotient and the remainder, calls the unsigned
+division routine and adjusts the signs for the quotient and
+the remainder.</small></p>
+
+<p><small>The <i>.nop</i> routine is included for testing
+purposes. This routine prints the line number and the value
+in the stack pointer. Calls to this routine are generated by
+the EM instruction <b>nop</b>, which is ordinarily left out
+by the peephole optimizer.</small></p>
+<a name="5. Testing the table"></a>
+<h2>5. Testing the table</h2>
+
+<p><small>There are special test programs available for
+testing back end tables. First there is the EM test set,
+which tests most EM instructions, making good use of the
+<b>nop</b> instruction. Then there are the Pascal and C test
+programs. The Pascal test programs report errors, which
+makes it relatively easy to find out what was wrong in the
+table. The C test programs just generate some output, which
+then has to be compared to the expected output. Differences
+are not only caused by errors but also e.g. by the use of
+four byte integers and unsigneds (which this table does),
+the use of signed characters instead of unsigned characters
+(the C front end I used generated signed characters) or
+because the back end does not support floating point. These
+differences have to be &lsquo;filtered out&rsquo; to reveal
+the differences caused by actual errors in the back end
+table. These errors then have to be found out by examining
+the assembly code, for no proper diagnostic messages are
+generated.</small></p>
+
+<p><small>After these three basic tests there still remain
+a number of patterns that haven&rsquo;t been tested yet.
+Fortunately <i>cgg</i> offers the possibility of generating
+a special <i>cg</i> that can print a list of patterns that
+haven&rsquo;t been used in code generation yet. For these
+patterns the table writer has to write his own test
+programs. This may complicate things a bit because errors
+may now be caused by errors in the back end table as well as
+errors in the test programs. The latter happened quite often
+to me, because I found EM to be an uncomfortable programming
+language (of course it isn&rsquo;t meant to be a programming
+language, but an intermediary language).</small></p>
+
+<p><small>There still remain a couple of patterns in this
+table that haven&rsquo;t been tested yet. However these
+patterns all have very similar cases that have been tested
+(an example of this is mentioned in the section on group 0
+of the patterns section of the table). Some patterns have to
+do with floating point numbers. These EM instructions all
+generate traps, so they didn&rsquo;t all have to be tested.
+The two instructions <b>dch</b> and <b>lpb</b> haven&rsquo;t
+been tested in this table, but since they only use EM
+replacement and they have been tested in the PDP back end
+table, these two should be all right.</small></p>
+<a name="6. Performance of the back end"></a>
+<h2>6. Performance of the back end</h2>
+
+<p><small>To test the performance of the back end I
+gathered a couple of C programs and compiled them on the
+machines I used to test the back ends on. I compiled them
+using the C compiler that was available there and I also
+compiled them using the back end. I then compared the sizes
+of the text segments in the object files. The final results
+of these comparisons are in fig. 1 and fig. 2.</small></p>
+
+
+<p align=center><small><img src="grohtml-105631.png"></small></p>
+
+<p align=center><small>fig 1.</small></p>
+
+
+<p align=center><small><img src="grohtml-105632.png"></small></p>
+
+<p align=center><small>fig 2.</small></p>
+
+<p><small>Fig. 1 also includes results of an old m68k4 back
+end (a back end for the MC68000 with four byte word and
+pointersize). The table for this back end was given to me as
+an example, but I thought it didn&rsquo;t make good use of
+the MC68000&rsquo;s addressing capabilities, it hardly did
+any optimalization, and it sometimes even generated code
+that the assembler would not swallow. This was sufficient
+reason for me to write a completely new table.</small></p>
+
+<p><small>The results from the table may not be taken too
+seriously. The sizes measured are the sizes of the text
+segments of the user programs, i.e. without the inclusion of
+library routines. Of course these segments do contain calls
+to these routines. Another thing is that the <i>rom</i>
+segment may be included in the text segment (this is why the
+results for the MC68000 for <i>compute.c</i> look so
+bad).</small></p>
+
+<p><small>Some other things must be said about these
+results. The quality of EM code generated by the C front end
+is certainly not optimal. The front end uses temporary
+locals (extra locals that are used to evaluate expressions)
+far too quickly: for a simple C expression like</small></p>
+<pre><small><i>     *(pointer) += constant
+</i></small></pre>
+
+<p><small>where <i>pointer</i> is a register variable, the
+C front end generates (for obscure reasons) a temporary
+local that holds the contents of <i>pointer</i>. This way
+the pattern for</small></p>
+<pre><small><b>     loc lil adi sil $2==$4 &amp;&amp; $3==4
+</b></small></pre>
+
+<p><small>for register variables is not used and longer,
+less efficient code is generated. But even in spite of this,
+the back end seems to generate rather compact
+code.</small></p>
+<a name="7. Some timing results"></a>
+<h2>7. Some timing results</h2>
+
+<p><small>In order to measure the performance of the code
+generated by the back end some timing tests were done. The
+reason I chose these particular tests is that they were also
+done for many other back ends; the reader can compare the
+results if he so wishes (of course comparing the results
+only show a global difference in speed of the various
+machines; it doesn&rsquo;t show whether some back end
+generates relatively better code than another).</small></p>
+
+<p><small>On the MC68000 machine the statements were
+executed one million times. On the MC68020 machine the
+statements had to be executed four million times because
+this machine was so fast that timing results would be very
+unreliable if the statements were executed only one million
+times.</small></p>
+
+<p><small>For testing I used the following C test
+program:</small></p>
+<pre><small><i>     main()
+     {
+         int i, j, ...
+         ...
+         for (i=0; i&lt;1000; i++)
+             for (j=0; j&lt;1000; j++)
+</i></small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small><i>STATEMENT;</i></small></p>
+</table>
+
+<p><small><i>}</i></small></p>
+
+<p><small>where <i>STATEMENT</i> is any of the test
+statements or the empty statement. For the MC68020 tests I
+used 2000 instead of 1000. The results of the test with the
+empty statement were used to calculate the execution times
+of the other test statements.</small></p>
+
+<p><small>Figures 3 and 4 show many results. For each
+machine actually two tests were done: one with register
+variables, and the other without them. I noticed that the
+original C compilers on both machines did not generate the
+use of register variables, unless specifically requested.
+The back end uses register variables when and where they are
+profitable, even if the user did not ask for
+them.</small></p>
+
+
+<p align=center><small><img src="grohtml-105633.png"></small></p>
+
+<p align=center><small>Fig. 3</small></p>
+
+
+<p align=center><small><img src="grohtml-105634.png"></small></p>
+
+<p align=center><small>Fig. 4</small></p>
+
+<p><small>The reader may have noticed that on both machines
+the back end seems to generate considerably slower code for
+tests where a &lsquo;condition&rsquo; is used in the rhs of
+an assignment statement. This is in fact not true: it is the
+front end that generates bad code. Two examples: for the C
+statement</small></p>
+<pre><small><i>     int1 = (int2 &lt; 0);
+</i></small></pre>
+
+<p><small>the front end generates the following code for
+the rhs (I used arbitrary labels):</small></p>
+<pre><small><b>     lol -16
+     zlt *10
+     loc 0
+     bra *11
+     10
+     loc 1
+     11
+</b></small></pre>
+
+<p><small>while in this case (to my opinion) it should have
+generated</small></p>
+<pre><small><b>     lol -16
+     tlt
+</b></small></pre>
+
+<p><small>which is much shorter. Another example: for the C
+statement</small></p>
+<pre><small><i>     int1 = (int2 &lt; 3);
+</i></small></pre>
+
+<p><small>the front end generates for the rhs</small></p>
+<pre><small><b>     lol -16
+     loc 3
+     blt *10
+     loc 0
+     bra *11
+     10
+     loc 1
+     11
+</b></small></pre>
+
+<p><small>while a much better translation would
+be</small></p>
+<pre><small><b>     lol -16
+     loc 3
+     cmi 4
+     tlt
+</b></small></pre>
+
+<p><small>Another statement that the back end seems to
+generate slower code for is the C switch statement. This is
+true, but it is also caused by the way these things are done
+in EM. EM uses the <b>csa</b> or <b>csb</b> instruction, and
+for these two I had to use library routines. On larger
+switch statements the <i>.csa</i> routine will perform
+relatively better.</small></p>
+
+<p><small>The back end generates considerably faster code
+for procedure and function calls, especially in the MC68020
+case, and also for the C statement</small></p>
+<pre><small><i>     int1 = int1 + 1;
+</i></small></pre>
+
+<p><small>The original C compilers use the same method for
+this instruction as for</small></p>
+<pre><small><i>     int1 = int2 - 1;
+</i></small></pre>
+
+<p><small>they perform the addition in a scratch register,
+and then store the result. For the former C statement this
+is not necessary, because the MC68000 and MC68020 have an
+instruction that can add constants to almost anything (in
+this case: to locals). The MC68000 and MC68020 back ends do
+use this instruction.</small></p>
+<a name="8. Some final remarks"></a>
+<h2>8. Some final remarks</h2>
+
+<p><small>As mentioned a few times before, the C front end
+compiler does not generate optimal code and as a consequence
+of this the back end does not always generate optimal code.
+This is especially the case with temporary locals, which the
+front end generates much too quickly, and also with
+conditional expressions that are used in the rhs of an
+assignment statement (fortunately this is not needed so
+much).</small></p>
+
+<p><small>If <i>cgg</i> would have been able to accept
+operands separated by any character instead of just by
+commas (in the instruction definitions part), I
+wouldn&rsquo;t have had the need of the <i>killreg</i>
+pseudo instruction. It would also be handy to have
+<i>cgg</i> accept all normal C operators. At the moment
+<i>cgg</i> does not accept binary ands, ors and exors, even
+though in [4] it is stated that <i>cgg</i> does accept all
+normal C operators. As it happens I did not need the binary
+operators, but at some time in developing the table I
+thought I did.</small></p>
+
+<p><small>I would also like <i>cg</i> to do more with the
+condition codes information that is supplied with each
+instruction in the instruction definitions section of the
+table. Sometimes <i>cg</i> generates test instructions which
+actually were not necessary. This of course causes the
+generated programs to be slightly larger and slightly
+slower.</small></p>
+
+<p><small>In spite of the few minor shortcomings mentioned
+above I found <i>cgg</i> a very comfortable tool to
+use.</small></p>
+<a name="References"></a>
+<h2>References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[1]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>T. B. Steel Jr., <i>UNCOL: The myth and the
+Fact,</i> in Ann. Rev. Auto. Prog., R. Goodman (ed.), Vol. 2
+(1969), pp 325 - 344</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[2]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>A. S. Tanenbaum, H. van Staveren, E. G. Keizer,
+J. W. Stevenson, <i>A practical toolkit for making portable
+compilers,</i> Informatica Report 74, Vrije Universiteit,
+Amsterdam, 1983</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[3]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>A. S. Tanenbaum, H. van Staveren, E. G. Keizer,
+J. W. Stevenson, <i>Description of an experimental machine
+architecture for use with block structured languages,</i>
+Informatica Report 81, Vrije Universiteit, Amsterdam,
+1983</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[4]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>H. van Staveren <i>The table driven code
+generator from the Amsterdam Compiler Kit, Second Revised
+Edition,</i> Vrije Universiteit, Amsterdam</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[5]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small><i>MC68020 32-bit Microprocessor User&rsquo;s
+Manual,</i> Second Edition, Motorola Inc., 1985,
+1984</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>[6]</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small><i>MC68000 16-bit Microprocessor User&rsquo;s
+Manual, Preliminary,</i> Motorola Inc., 1979</small></p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/m68020.pdf b/src/olddocs/m68020.pdf
new file mode 100644 (file)
index 0000000..428f911
Binary files /dev/null and b/src/olddocs/m68020.pdf differ
diff --git a/src/olddocs/ncg.html b/src/olddocs/ncg.html
new file mode 100644 (file)
index 0000000..017b62e
--- /dev/null
@@ -0,0 +1,6654 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:10 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The table driven code generator</title>
+</head>
+<body>
+
+<h1 align=center>The table driven code generator</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. What has changed since version 1 ?">2. What has changed since version 1 ?</a><br>
+<a href="#3. Global overview of the workings of the code generator.">3. Global overview of the workings of the code generator.</a><br>
+<a href="#4. Register variables">4. Register variables</a><br>
+<a href="#5. Description of the machine table">5. Description of the machine table</a><br>
+<a href="#5.1. Constant section">5.1. Constant section</a><br>
+<a href="#5.2. Property definition">5.2. Property definition</a><br>
+<a href="#5.3. Register definition">5.3. Register definition</a><br>
+<a href="#5.4. Stack token definition">5.4. Stack token definition</a><br>
+<a href="#5.5. Sets">5.5. Sets</a><br>
+<a href="#5.6. Instruction definitions">5.6. Instruction definitions</a><br>
+<a href="#5.7. Expressions">5.7. Expressions</a><br>
+<a href="#5.8. Token descriptions">5.8. Token descriptions</a><br>
+<a href="#5.9. Code rules">5.9. Code rules</a><br>
+<a href="#5.9.1. The EM pattern">5.9.1. The EM pattern</a><br>
+<a href="#5.9.2. The stack pattern">5.9.2. The stack pattern</a><br>
+<a href="#5.9.3. The kills part">5.9.3. The kills part</a><br>
+<a href="#5.9.4. The allocates part">5.9.4. The allocates part</a><br>
+<a href="#5.9.5. The generates part">5.9.5. The generates part</a><br>
+<a href="#5.9.6. Stack replacement">5.9.6. Stack replacement</a><br>
+<a href="#5.9.7. EM replacement">5.9.7. EM replacement</a><br>
+<a href="#5.9.8. Examples">5.9.8. Examples</a><br>
+<a href="#5.10. Code rules using procedures">5.10. Code rules using procedures</a><br>
+<a href="#5.11. Move definitions">5.11. Move definitions</a><br>
+<a href="#5.12. Test definitions">5.12. Test definitions</a><br>
+<a href="#5.13. Some explanation about the rules behind coercions">5.13. Some explanation about the rules behind coercions</a><br>
+<a href="#5.14. Stack definitions">5.14. Stack definitions</a><br>
+<a href="#5.15. Coercions">5.15. Coercions</a><br>
+<a href="#6. The files mach.h and mach.c">6. The files mach.h and mach.c</a><br>
+<a href="#6.1. Types in the code generator">6.1. Types in the code generator</a><br>
+<a href="#6.2. Global variables to work with">6.2. Global variables to work with</a><br>
+<a href="#6.3. Macros in mach.h">6.3. Macros in mach.h</a><br>
+<a href="#6.3.1. Example mach.h for the PDP-11">6.3.1. Example mach.h for the PDP-11</a><br>
+<a href="#6.4. Functions in mach.c">6.4. Functions in mach.c</a><br>
+<a href="#6.4.1. Example mach.c for the PDP-11">6.4.1. Example mach.c for the PDP-11</a><br>
+<a href="#7. Internal workings of the code generator.">7. Internal workings of the code generator.</a><br>
+<a href="#7.1. Description of tables.c and tables.h contents">7.1. Description of tables.c and tables.h contents</a><br>
+<a href="#7.1.1. Tables.c">7.1.1. Tables.c</a><br>
+<a href="#7.1.2. tables.h">7.1.2. tables.h</a><br>
+<a href="#7.2. Other important data structures">7.2. Other important data structures</a><br>
+<a href="#7.3. A tour through the sources">7.3. A tour through the sources</a><br>
+<a href="#7.3.1. codegen.c">7.3.1. codegen.c</a><br>
+<a href="#7.3.1.1. DO_DLINE">7.3.1.1. DO_DLINE</a><br>
+<a href="#7.3.1.2. DO_NEXTEM">7.3.1.2. DO_NEXTEM</a><br>
+<a href="#7.3.1.3. DO_COERC">7.3.1.3. DO_COERC</a><br>
+<a href="#7.3.1.4. DO_XMATCH">7.3.1.4. DO_XMATCH</a><br>
+<a href="#7.3.1.5. DO_MATCH">7.3.1.5. DO_MATCH</a><br>
+<a href="#7.3.1.6. DO_REMOVE">7.3.1.6. DO_REMOVE</a><br>
+<a href="#7.3.1.7. DO_DEALLOCATE">7.3.1.7. DO_DEALLOCATE</a><br>
+<a href="#7.3.1.8. DO_REALLOCATE">7.3.1.8. DO_REALLOCATE</a><br>
+<a href="#7.3.1.9. DO_ALLOCATE">7.3.1.9. DO_ALLOCATE</a><br>
+<a href="#7.3.1.10. DO_INSTR">7.3.1.10. DO_INSTR</a><br>
+<a href="#7.3.1.11. DO_MOVE">7.3.1.11. DO_MOVE</a><br>
+<a href="#7.3.1.12. DO_TEST">7.3.1.12. DO_TEST</a><br>
+<a href="#7.3.1.13. DO_ERASE">7.3.1.13. DO_ERASE</a><br>
+<a href="#7.3.1.14. DO_TOKREPLACE">7.3.1.14. DO_TOKREPLACE</a><br>
+<a href="#7.3.1.15. DO_EMREPLACE">7.3.1.15. DO_EMREPLACE</a><br>
+<a href="#7.3.1.16. DO_COST">7.3.1.16. DO_COST</a><br>
+<a href="#7.3.1.17. DO_RETURN">7.3.1.17. DO_RETURN</a><br>
+<a href="#7.3.1.18. DO_LABDEF">7.3.1.18. DO_LABDEF</a><br>
+<a href="#7.3.2. compute.c">7.3.2. compute.c</a><br>
+<a href="#7.3.3. equiv.c">7.3.3. equiv.c</a><br>
+<a href="#7.3.4. fillem.c">7.3.4. fillem.c</a><br>
+<a href="#7.3.5. gencode.c">7.3.5. gencode.c</a><br>
+<a href="#7.3.6. glosym.c">7.3.6. glosym.c</a><br>
+<a href="#7.3.7. label.c">7.3.7. label.c</a><br>
+<a href="#7.3.8. main.c">7.3.8. main.c</a><br>
+<a href="#7.3.9. move.c">7.3.9. move.c</a><br>
+<a href="#7.3.10. nextem.c">7.3.10. nextem.c</a><br>
+<a href="#7.3.11. reg.c">7.3.11. reg.c</a><br>
+<a href="#7.3.12. salloc.c">7.3.12. salloc.c</a><br>
+<a href="#7.3.13. state.c">7.3.13. state.c</a><br>
+<a href="#7.3.14. subr.c">7.3.14. subr.c</a><br>
+<a href="#7.3.14.1. match">7.3.14.1. match</a><br>
+<a href="#7.3.14.2. instance,cinstance">7.3.14.2. instance,cinstance</a><br>
+<a href="#7.3.14.3. eqtoken">7.3.14.3. eqtoken</a><br>
+<a href="#7.3.14.4. distance">7.3.14.4. distance</a><br>
+<a href="#7.3.14.5. split">7.3.14.5. split</a><br>
+<a href="#7.3.14.6. docoerc">7.3.14.6. docoerc</a><br>
+<a href="#7.3.14.7. stackupto">7.3.14.7. stackupto</a><br>
+<a href="#7.3.14.8. findcoerc">7.3.14.8. findcoerc</a><br>
+<a href="#7.3.15. var.c">7.3.15. var.c</a><br>
+
+<hr>
+
+<p><b>from the<br>
+Amsterdam Compiler Kit<br>
+Second Revised Edition</b></p>
+
+<p align=center><i><small>ABSTRACT</small></i></p>
+
+<p align=center><i><small>Hans van
+Staveren</small></i><small><br>
+Dept. of Mathematics and Computer Science<br>
+Vrije Universiteit<br>
+Amsterdam, The Netherlands</small></p>
+
+<p><small>The Amsterdam Compiler Kit is a collection of
+tools designed to help automate the process of compiler
+building. Part of it is a table driven code generator,
+called <i>cg</i>, and a program to check and translate
+machine description tables called <i>cgg</i>. This document
+provides a description of the internal workings of
+<i>cg</i>, and a description of syntax and semantics of the
+driving table. This is required reading for those wishing to
+write a new table.</small></p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p><small>Part of the Amsterdam Compiler Kit is a code
+generator system consisting of a code generator generator
+(<i>cgg</i> for short) and some machine independent C code.
+<i>Cgg</i> reads a machine description table and creates two
+files, tables.h and tables.c. These are then used together
+with other C code to produce a code generator for the
+machine at hand.</small></p>
+
+<p><small>This in turn reads compact EM code and produces
+assembly code. The remainder of this document will first
+broadly describe the working of the code generator, then the
+machine table will be described after which some light is
+shed onto the internal workings of the code
+generator.</small></p>
+
+<p><small>The reader is assumed to have at least a vague
+notion about the semantics of the intermediary EM code.
+Someone wishing to write a table for a new machine should be
+thoroughly acquainted with EM code and the assembly code of
+the machine at hand.</small></p>
+<a name="2. What has changed since version 1 ?"></a>
+<h2>2. What has changed since version 1 ?</h2>
+
+<p><small>This section can be skipped by anyone not
+familiar with the first version. It is not needed to
+understand the current version.</small></p>
+
+<p><small>This paper describes the second version of the
+code generator system. Although the code generator itself is
+for the main part unchanged, the table format has been
+drastically redesigned and the opportunities to make faulty
+tables are reduced. The format is now aesthaticly more
+pleasing (according to <i>me</i> that is), mainly because
+the previous version was designed for one line code rules,
+which did not work out that way.</small></p>
+
+<p><small>The &lsquo;SCRATCH&rsquo; property is now
+automatically generated by <i>cgg</i>, <i>erase</i> and
+<i>setcc</i> calls and their ilk are now no longer needed
+(read: can no longer be forgotten) and all this because the
+table now <i>knows</i> what the machine instructions look
+like and what arguments they destroy.</small></p>
+
+<p><small>Checks are now made for register types, so it is
+no longer possible to generate a &lsquo;regind2&rsquo; token
+with a floating point register as a base. In general, if the
+instructions of the machine are correctly defined, it is no
+longer possible to generate code that does not assemble,
+which of course does not mean that it is not possible to
+generate assembly code that does not do what was
+intended!</small></p>
+
+<p><small>Checks are made now for missing moves, tests,
+coercions, etc. There is a form of procedure call now to
+reduce table size: it is no longer necessary to write the
+code for conditional instructions six times.</small></p>
+
+<p><small>The inreg() pseudo-function returns other
+results!!</small></p>
+<a name="3. Global overview of the workings of the code generator."></a>
+<h2>3. Global overview of the workings of the code generator.</h2>
+
+<p><small>The code generator or <i>cg</i> tries to generate
+good code by simulating the stack of the compiled program
+and delaying emission of code as long as possible. It also
+keeps track of register contents, which enables it to
+eliminate redundant moves, and tries to eliminate redundant
+tests by keeping information about condition code status, if
+applicable for the machine.</small></p>
+
+<p><small><i>Cg</i> maintains a &lsquo;fake stack&rsquo;
+containing &lsquo;tokens&rsquo; that are built by executing
+the pseudo code contained in the code rules given by the
+table writer. One can think of the fake stack as a logical
+extension of the real stack the compiled program will have
+when run. Alternatively one can think of the real stack as
+an infinite extension at the bottom of the fake stack. Both
+ways, the concatenation of the real stack and the fake stack
+will be the stack as it would have been on a real EM machine
+(see figure).</small></p>
+
+
+<p align=center><small><img src="grohtml-99451.png"></small></p>
+
+<p><small>During code generation tokens will be kept on the
+fake stack as long as possible but when they are moved to
+the real stack, by generating code for the push, all tokens
+above&dagger;</small></p>
+
+
+<p align=center><small><img src="grohtml-99452.png"></small></p>
+
+<p><small>the pushed tokens will be pushed also, so the
+fake stack will not contain holes.</small></p>
+
+<p><small>The information about the machine that <i>cg</i>
+needs has to be given in a machine description table, with
+as a major part a list of code rules telling <i>cg</i> what
+to do when certain EM-instructions occur with certain tokens
+on the fake stack. Not all possible fake stack possibilities
+have to be given of course, there is a possibility for
+providing rewriting rules, or <i>coercions</i> as they are
+called in this document.</small></p>
+
+<p><small>The main loop of <i>cg</i> is:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>find a pattern of EM instructions starting at the
+current one to generate code for. This pattern will usually
+be of length one but longer patterns can be used. Process
+any pseudo-instructions found.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Select one of the possibly many stack patterns
+that go with this EM pattern on the basis of heuristics,
+look ahead or both. The cost fields provided in the token
+definitions and instruction definitions are used to compute
+costs during look ahead.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Force the current fake stack contents to match
+the pattern. This may involve copying tokens to registers,
+making dummy transformations, e.g. to transform a
+&lsquo;local&rsquo; into an &lsquo;indexed from
+register&rsquo; or might even cause the move of the complete
+fake stack contents to the real stack and then back into
+registers if no suitable coercions were provided by the
+table writer.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Execute the pseudocode associated with the code
+rule just selected, this may cause registers to be
+allocated, code to be emitted etc..</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>5)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Put tokens onto the fake stack to reflect the
+result of the operation.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>6)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Insert some EM instructions into the stream; this
+is possible but not common.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>7)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Account for the cost. The cost is kept in a
+(space, time) vector and look ahead decisions are based on a
+linear combination of these. The code generator calls on
+itself recursively during look ahead, and the recursive
+incarnations return the costs they made. The costs the
+top-level code generator makes is of course
+irrelevant.</small></p>
+</td>
+</table>
+
+<p><small>The table that drives <i>cg</i> is not read in
+every time, but instead is used at compile time of <i>cg</i>
+to set parameters and to load pseudocode tables. A program
+called <i>cgg</i> reads the table and produces large lists
+of numbers that are compiled together with machine
+independent code to produce a code generator for the machine
+at hand.</small></p>
+
+<p><small>Part of the information needed is not easily
+expressed in this table format and must be supplied in two
+separate files, mach.h and mach.c. Their contents are
+described later in this document.</small></p>
+<a name="4. Register variables"></a>
+<h2>4. Register variables</h2>
+
+<p><small>If the machine has more than enough registers to
+generate code with, it is possible to reserve some of them
+for use as register variables. If it has not, this section
+may be skipped and any references to register variables in
+the rest of this document may be ignored.</small></p>
+
+<p><small>The front ends generate messages to the back ends
+telling them which local variables could go into registers.
+The information given is the offset of the local, its size
+and type and a scoring number, roughly the number of times
+it occurs.</small></p>
+
+<p><small>The decision which variable to put in which
+register is taken by the machine independent part of
+<i>cg</i> with the help of a scoring function provided by
+the table writer in mach.c. The types of variables known
+are</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>reg_any</small></p>
+</td>
+<td width="10%"></td>
+<td width="76%">
+
+<p><small>Just a variable of some integer type. Nothing
+special known about it.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>reg_float</small></p>
+</td>
+<td width="6%"></td>
+<td width="52%">
+
+<p><small>A floating point variable.</small></p>
+</td>
+<td width="23%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>reg_loop</small></p>
+</td>
+<td width="8%"></td>
+<td width="48%">
+
+<p><small>A loop control variable.</small></p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>reg_pointer</small></p>
+</td>
+<td width="2%"></td>
+<td width="76%">
+
+<p><small>A pointer variable. Usually they are better
+candidates to put in registers.</small></p>
+</td>
+</table>
+
+<p><small>If register variables are used, more functions
+must be supplied in mach.c. These functions are explained
+later.</small></p>
+<a name="5. Description of the machine table"></a>
+<h2>5. Description of the machine table</h2>
+
+<p><small>The machine description table consists of the
+concatenation of the following sections:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>Constant definitions</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>Property definitions</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>Register definitions</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4)</small></p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p><small>Token definitions</small></p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>5)</small></p>
+</td>
+<td width="6%"></td>
+<td width="30%">
+
+<p><small>Set definitions</small></p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>6)</small></p>
+</td>
+<td width="6%"></td>
+<td width="46%">
+
+<p><small>Instruction definitions</small></p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>7)</small></p>
+</td>
+<td width="6%"></td>
+<td width="32%">
+
+<p><small>Move definitions</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>8)</small></p>
+</td>
+<td width="6%"></td>
+<td width="32%">
+
+<p><small>Test definitions</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>9)</small></p>
+</td>
+<td width="6%"></td>
+<td width="34%">
+
+<p><small>Stack definitions</small></p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>10)</small></p>
+</td>
+<td width="4%"></td>
+<td width="18%">
+
+<p><small>Coercions</small></p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>11)</small></p>
+</td>
+<td width="4%"></td>
+<td width="20%">
+
+<p><small>Code rules</small></p>
+</td>
+<td width="69%">
+</td>
+</table>
+
+<p><small>This is the order in the table but the
+descriptions in this document will use a slightly different
+order. All sections except the first start with an uppercase
+header word. Examples may be given in early stages that use
+knowledge that is explained in a later stage. If something
+is not clear the first time, please read on. All will clear
+up in a couple of pages.</small></p>
+
+<p><small>Input is in free format, white space and newlines
+may be used at will to improve legibility. Identifiers used
+in the table have the same syntax as C identifiers, upper
+and lower case considered different, all characters
+significant. Here is a list of reserved words; all of these
+are unavailable as identifiers.</small></p>
+
+
+<p align=center><small><img src="grohtml-99453.png"></small></p>
+
+<p><small>C style comments are accepted.</small></p>
+<pre><small>     /* this is a comment */
+</small></pre>
+
+<p><small>If the standard constant facility is not enough
+the C-preprocessor can be used to enhance the table
+format.</small></p>
+
+<p><small>Integers in the table have the normal C-style
+syntax. Decimal by default, octal when preceded by a 0 and
+hexadecimal when preceded by 0x.</small></p>
+<a name="5.1. Constant section"></a>
+<h2>5.1. Constant section</h2>
+
+<p><small>In the first part of the table some constants can
+be defined, most with the syntax</small></p>
+<pre><small>     NAME=value
+</small></pre>
+
+<p><small>value being an integer or string. Three constants
+must be defined here:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>EM_WSIZE</small></p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p><small>Number of bytes in a machine word. This is the
+number of bytes a <b>loc</b> instruction will put on the
+stack.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>EM_PSIZE</small></p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p><small>Number of bytes in a pointer. This is the number
+of bytes a <b>lal</b> instruction will put on the
+stack.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>EM_BSIZE</small></p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p><small>Number of bytes in the hole between AB and LB. If
+the calling sequence just saves PC and LB this size will be
+twice the pointersize.</small></p>
+</td>
+</table>
+
+<p><small>EM_WSIZE and EM_PSIZE are checked when a program
+is compiled with the resulting code generator. EM_BSIZE is
+used by <i>cg</i> to add to the offset of instructions
+dealing with locals having positive offsets, i.e.
+parameters.</small></p>
+
+<p><small>Other constants can be defined here to be used as
+mnemonics later in the table.</small></p>
+
+<p><small>Optional is the definition of a printformat for
+integers in the code file. This is given as</small></p>
+<pre><small>     FORMAT = string
+</small></pre>
+
+<p><small>The string must be a valid printf(III) format,
+and defaults to &quot;%ld&quot;. For example on the PDP-11
+one can use</small></p>
+<pre><small>     FORMAT= &quot;0%lo&quot;
+</small></pre>
+
+<p><small>to satisfy the old UNIX assembler that reads
+octal unless followed by a period, and the ACK assembler
+that follows C conventions.</small></p>
+
+<p><small>Tables under control of source code control
+systems like <i>sccs</i> or <i>rcs</i> can put their
+id-string here, for example</small></p>
+<pre><small>     rcsid=&quot;$Header$&quot;
+</small></pre>
+
+<p><small>These strings, like all strings in the table,
+will eventually end up in the binary code generator
+produced.</small></p>
+
+<p><small>Optionally one can give the factors with which
+the size and time parts of the cost vector have to be
+multiplied to ensure they have the same order of magnitude.
+This can be done as</small></p>
+<pre><small>     SIZEFACTOR = C3/C4
+
+
+     TIMEFACTOR = C1/C2
+</small></pre>
+
+<p><small>Above numbers must be read as rational numbers.
+Defaults are 1/1 for both of them. These constants set the
+default size/time tradeoff in the code generator, so if
+TIMEFACTOR and SIZEFACTOR are both 1 the code generator will
+choose at random between two code sequences where one has
+cost (10,4) and the other has cost (8,6). See also the
+description of the cost field below.</small></p>
+<a name="5.2. Property definition"></a>
+<h2>5.2. Property definition</h2>
+
+<p><small>This part of the table defines the list of
+properties that can be used to differentiate between
+register classes. It consists of a list of user-defined
+identifiers optionally followed by the size of the property
+in parentheses, default EM_WSIZE. Example for the
+PDP-11:</small></p>
+
+
+<p align=center><small><img src="grohtml-99454.png"></small></p>
+
+<p><small>Registers are allocated by asking for a property,
+so if for some reason in later parts of the table one
+particular register must be allocated it has to have a
+unique property.</small></p>
+<a name="5.3. Register definition"></a>
+<h2>5.3. Register definition</h2>
+
+<p><small>The next part of the tables describes the various
+registers of the machine and defines identifiers to be used
+in later parts of the tables. Syntax:</small></p>
+<pre><small>     &lt;register definitions&gt; : REGISTERS &lt;list of definitions&gt;
+     &lt;definition&gt; : &lt;registerlist&gt; &rsquo;:&rsquo; &lt;propertylist&gt; &lt;optional regvar&gt; &rsquo;.&rsquo;
+     &lt;register&gt; : ident [ &rsquo;(&rsquo; string &rsquo;)&rsquo; ] [ &rsquo;=&rsquo; ident [ &rsquo;+&rsquo; ident ] ]
+</small></pre>
+
+<p><small>Example for the PDP-11:</small></p>
+
+
+<p align=center><small><img src="grohtml-99455.png"></small></p>
+
+<p><small>The names in the left hand lists are names of
+registers as used in the table. They can optionally be
+followed by a string in parentheses, their name as far as
+the assembler is concerned. The default assembler name is
+the same as the table name. A name can also be followed
+by</small></p>
+<pre><small>     = othername
+</small></pre>
+
+<p><small>or</small></p>
+<pre><small>     = othername + othername
+</small></pre>
+
+<p><small>which says that the register is composed of the
+parts after the &rsquo;=&rsquo; sign. The identifiers at the
+right hand side of the lists are names of properties. The
+end of each register definition is a period.</small></p>
+
+<p><small>It might seem wise to list every property of a
+register, so one might give r0 the extra property MFPTREG
+named after the not too well known MFPT instruction on newer
+PDP-11 types, but this is not a good idea, especially since
+no use can be made of that instruction anyway. Every extra
+property means the register set is more unorthogonal and
+<i>cg</i> execution time is influenced by that, because it
+has to take into account a larger set of registers that are
+not equivalent. So try to keep the number of different
+register classes to a minimum. When faced with the choice
+between two possible code rules for a nonfrequent EM
+sequence, one being elegant but requiring an extra property,
+and the other less elegant, elegance should probably
+loose.</small></p>
+
+<p><small>Tables that implement register variables must
+mark registers to be used for variable storage here by
+following the list of properties by one of the
+following:</small></p>
+<pre><small>     regvar <i>or</i> regvar(reg_any)
+     regvar(reg_loop)
+     regvar(reg_pointer)
+     regvar(reg_float)
+</small></pre>
+
+<p><small>meaning they are candidates for that type of
+variable. All register variables of one type must be of the
+same size, and they may have no subregisters. Such registers
+are not available for normal code generation.</small></p>
+<a name="5.4. Stack token definition"></a>
+<h2>5.4. Stack token definition</h2>
+
+<p><small>The next part describes all possible tokens that
+can reside on the fake stack during code generation.
+Attributes of a token are described as a C struct
+declaration; this is followed by the size of the token in
+bytes, optionally followed by the cost of the token when
+used as an addressing mode and the format to be used on
+output.</small></p>
+
+<p><small>In general, when writing a table, it is not wise
+to try to think of all necessary tokens in advance. While
+writing the necessity or advisability for some token will be
+seen and it can then be added together with the stacking
+rules and coercions needed.</small></p>
+
+<p><small>Tokens should usually be declared for every
+addressing mode of the machine at hand and for every size
+directly usable in a machine instruction. Example for the
+PDP-11 (incomplete):</small></p>
+
+
+<p align=center><small><img src="grohtml-99456.png"></small></p>
+
+<p><small>Types allowed in the struct are ADDR, INT and all
+register properties. The type ADDR means a string and an
+integer, which is output as string+integer, and arithmetic
+on mixed ADDR and INT is possible. This is the right mode
+for anything that can be an assembler address expression.
+The type of the register in the token is strict. At any
+assignment of an expression of type register to a token
+attribute of type register <i>cgg</i> will check if the set
+of possible results from the expression is a subset of the
+set of permissible values for the token
+attribute.</small></p>
+
+<p><small>The cost-field is made up by the word <i>cost</i>
+followed by two numbers in parentheses, the size and
+timecosts of this token when output in the code file. If
+omitted, zero cost is assumed. While generating code,
+<i>cg</i> keeps track of a linear combination of these costs
+together with the costs of the instructions itself which we
+will see later. The coefficients of this linear combination
+are influenced by two things:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>The SIZEFACTOR and TIMEFACTOR constants, as
+mentioned above.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>A run time option to <i>cg</i> that can adjust
+the time/space tradeoff to all positions from 100% time to
+100% space.</small></p>
+</td>
+</table>
+
+<p><small>By supplying different code rules in certain
+situations it is possible to get a code generator that can
+adjust its code to the need of the moment. This is probably
+most useful with small machines, experience has shown that
+on the larger micro&rsquo;s and mini&rsquo;s the difference
+between time-optimal and space-optimal code is often
+small.</small></p>
+
+<p><small>The printformat consists of a list of strings
+intermixed with attributes from the token. Strings are
+output literally, attributes are printed according to their
+type and value. Tokens without a printformat should never be
+output, and <i>cgg</i> checks for this.</small></p>
+
+<p><small>Notice that tokens need not correspond to
+addressing modes; the regconst2 token listed above, meaning
+the sum of the contents of the register and the constant,
+has no corresponding addressing mode on the PDP-11, but is
+included so that a sequence of add constant, load indirect,
+can be handled efficiently. This regconst2 token is needed
+as part of the path</small></p>
+<pre><small>     REG -&gt; regconst2 -&gt; regind2
+</small></pre>
+
+<p><small>of which the first and the last &quot;exist&quot;
+and the middle is needed only as an intermediate
+step.</small></p>
+
+<p><small>Tokens with name &lsquo;LOCAL&rsquo; or
+&lsquo;DLOCAL&rsquo; are a special case when register
+variables are used, this is explained further in the section
+on token descriptions.</small></p>
+<a name="5.5. Sets"></a>
+<h2>5.5. Sets</h2>
+
+<p><small>Usually machines have certain collections of
+addressing modes that can be used with certain instructions.
+The stack patterns in the table are lists of these
+collections and since it is cumbersome to write out these
+long lists every time, there is a section here to give names
+to these collections. Please note that it is not forbidden
+to write out a set in the remainder of the table, but for
+clarity it is usually better not to.</small></p>
+
+<p><small>Example for the PDP-11 (incomplete):</small></p>
+
+
+<p align=center><small><img src="grohtml-99457.png"></small></p>
+
+<p><small>Permissible in the set construction are all the
+usual set operators, i.e.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>+</small></p>
+</td>
+<td width="8%"></td>
+<td width="18%">
+
+<p><small>set union</small></p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="28%">
+
+<p><small>set difference</small></p>
+</td>
+<td width="61%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>*</small></p>
+</td>
+<td width="8%"></td>
+<td width="32%">
+
+<p><small>set intersection</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+
+<p><small>Normal operator priorities apply, and parentheses
+can be used. Every token identifier is also a set identifier
+denoting the singleton collection of tokens containing just
+itself. Every register property as defined above is also a
+set matching all registers with that property. The standard
+set identifier ALL denotes the collection of all
+tokens.</small></p>
+<a name="5.6. Instruction definitions"></a>
+<h2>5.6. Instruction definitions</h2>
+
+<p><small>In the next part of the table the instructions
+for the machine are declared together with information about
+their operands. Example for the PDP-11(very
+incomplete):</small></p>
+<pre><small>     INSTRUCTIONS
+     /* default cost */
+
+
+     cost(2,600)
+
+
+     /* Normal instructions */
+
+
+     adc dst2:rw:cc .
+     add src2:ro,dst2:rw:cc cost(2,450).
+     ash src2:ro,REG:rw:cc .
+     ashc src2:ro,REGPAIR+ODDREG:rw .
+     asl dst2:rw:cc .
+     asr dst2:rw:cc .
+     bhis &quot;bcc&quot; label .
+
+
+     /* floating point instructions */
+
+
+     movf &quot;ldf&quot; fsrc,freg .
+     movf &quot;stf&quot; freg,fdst .
+</small></pre>
+
+<p><small>As the examples show an instruction definition
+consists of the name of the instruction, optionally followed
+by an assembler mnemonic in quotes-default is the name
+itself-and then a list of operands, optionally followed by
+the cost and then a period. If the cost is omitted the cost
+just after the word INSTRUCTIONS is assumed, if that is also
+omitted the cost is zero. The cost must be known by
+<i>cg</i> of course if it has multiple code generation paths
+to choose from.</small></p>
+
+<p><small>For each operand we have the set of possible
+token values, followed by a qualifier that can
+be</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>:ro</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>signifies that this operand is read only, so it
+can be replaced by a register with the same contents if
+available.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>:rw</small></p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p><small>signifies that the operand is
+read-write</small></p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>:wo</small></p>
+</td>
+<td width="4%"></td>
+<td width="82%">
+
+<p><small>signifies that the operand is write
+only.</small></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>:cc</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>says that after the instruction is finished, the
+condition codes are set to this operand. If none of the
+operands have the :cc qualifier set, <i>cg</i> will assume
+that condition codes were unaffected (but see
+below).</small></p>
+</td>
+</table>
+
+<p><small>The first three qualifiers are of course mutually
+exclusive. The :ro qualifier does not cause any special
+action in the current implementation, and the :wo and :rw
+qualifiers are treated equal. It must be recommended however
+to be precise in the specifications, since later
+enhancements to the code generator might use
+them.</small></p>
+
+<p><small>As the last examples show it is not necessary to
+give one definition for an instruction. There are machines
+that have very unorthogonal instruction sets, in fact most
+of them do, and it is possible to declare each possible
+combination of operands. The <i>cgg</i> program will check
+all uses of the instruction to find out which one was
+meant.</small></p>
+
+<p><small>Although not in the PDP-11 example above there is
+a possibility to describe instructions that have side
+effects to registers not in the operand list. The only thing
+possible is to say that the instruction is destructive to
+some registers or the condition codes, by following the
+operand list with the word <i>kills</i> and a list of the
+things destroyed. Example for some hypothetic accumulator
+machine:</small></p>
+<pre><small>     add source2:ro kills ACCU :cc .
+</small></pre>
+
+<p><small>The cost fields in the definitions for tokens and
+instructions are added together when generating code. It
+depends on the machine at hand whether the costs are
+orthogonal enough to make use of both these costs, in
+extreme cases every combination of instructions and operands
+can be given in this section, all with their own
+costs.</small></p>
+<a name="5.7. Expressions"></a>
+<h2>5.7. Expressions</h2>
+
+<p><small>Throughout the rest of the table expressions can
+be used in some places. This section will give the syntax
+and semantics of expressions. There are four types of
+expressions: integer, address, register and undefined.
+Really the type register is nonexistent as such, for each
+register expression <i>cgg</i> keeps a set of possible
+values, and this set can be seen as the real
+type.</small></p>
+
+<p><small>Type checking is performed by <i>cgg</i>. An
+operator with at least one undefined operand returns
+undefined except for the defined() function mentioned below.
+An undefined expression is interpreted as FALSE when it is
+needed as a truth value. It is the responsibility of the
+table writer to ensure no undefined expressions are ever
+used as initialisers for token attributes. This is
+unfortunately almost impossible to check for <i>cgg</i> so
+be careful.</small></p>
+
+<p><small>Basic terms in an expression are</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>number</small></p>
+</td>
+<td width="20%"></td>
+<td width="68%">
+
+<p><small>A number is a constant of type integer. Also
+usable is an identifier defined to a number in the constant
+definition section.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>&quot;string&quot;</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>A string within double quotes is a constant of
+type address. All the normal C style escapes may be used
+within the string. Also usable is an identifier defined to a
+string in the constant definition section.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>[0-9][bf]</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>This must be read as a grep-pattern. It evaluates
+to a string that is the label name for the temporary label
+meant. More about this in the section on code
+rules.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>REGIDENT</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>The name of a register is a constant of type
+register.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>$<i>i</i></small></p>
+</td>
+<td width="28%"></td>
+<td width="68%">
+
+<p><small>A dollarsign followed by a number is the
+representation of the argument of EM instruction . The type
+of the operand is dependent on the instruction, sometimes it
+is integer, sometimes it is address. It is undefined when
+the instruction has no operand. Instructions with
+type-letter w can occur without an operand. This can be
+checked in the code rule with the defined() pseudo
+function.</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="31%"></td>
+<td width="68%">
+<p><small>If it is unimaginable for the operand of the
+instruction ever to be something different from a plain
+integer, the type is integer, otherwise it is address.<br>
+Those who want to know it exactly, the integer instruction
+types are the instructions marked with the type-letters
+c,f,l,n,o,s,r,w,z in the EM manual.<i><br>
+Cg</i> makes all necessary conversions, like adding EM_BSIZE
+to positive arguments of instructions dealing with locals,
+prepending underlines to global names, converting code
+labels into a unique representation etc. Details about this
+can be found in the section about machine dependent C
+code.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>%1</small></p>
+</td>
+<td width="28%"></td>
+<td width="68%">
+
+<p><small>This in general means the token mentioned first
+in the stack pattern. When used inside an expression the
+token must be a simple register. Type of this is
+register.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>%1.off</small></p>
+</td>
+<td width="20%"></td>
+<td width="68%">
+
+<p><small>This means attribute &quot;off&quot; of the first
+stack pattern token. Type is the same as that of attribute
+&quot;off&quot;. To use this expression implies a check that
+all tokens in the set used have the same attribute in the
+same place.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>%off</small></p>
+</td>
+<td width="24%"></td>
+<td width="68%">
+
+<p><small>This means attribute &quot;off&quot; in the
+&lsquo;current&rsquo; token. This can only be used when no
+confusion is possible about which token was meant, eg. in
+the optional boolean expressions following token sets in the
+move and test rules, in coercions or in the kills section
+inside the code rules. Same check as above.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>%1.1</small></p>
+</td>
+<td width="24%"></td>
+<td width="68%">
+
+<p><small>This is the first subregister of the first token.
+Previous comments apply.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>%b</small></p>
+</td>
+<td width="28%"></td>
+<td width="68%">
+
+<p><small>A percent sign followed by a lowercase letter
+stands for an allocated register. This is the second
+allocated register.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p><small>%a.2</small></p>
+</td>
+<td width="24%"></td>
+<td width="68%">
+
+<p><small>The second subregister of the first allocated
+register.</small></p>
+</td>
+</table>
+
+<p><small>All normal C operators apply to integers, the +
+operator on addresses behaves as one would expect and the
+only operators allowed on register expressions are == and !=
+. Furthermore there are some special
+&lsquo;functions&rsquo;:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>defined(e)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Returns 1 if expression <i>e</i> is defined, 0
+otherwise.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p><small>samesign(e1,e2)</small></p>
+</td>
+<td width="2%"></td>
+<td width="68%">
+
+<p><small>Returns 1 if integer expression <i>e1</i> and
+<i>e2</i> have the same sign.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>sfit(e1,e2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="68%">
+
+<p><small>Returns 1 if integer expression <i>e1</i> fits as
+a signed integer into a field of <i>e2</i> bits, 0
+otherwise.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>ufit(e1,e2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="68%">
+
+<p><small>Same as above but now for unsigned
+<i>e1</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>rom($a,n)</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>Integer expression giving word <i>n</i> from the
+<b>rom</b> descriptor pointed at by EM instruction number
+<i>a</i> in the EM-pattern. Undefined if that descriptor
+does not exist.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>is_rom($a)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Integer expression indicating whether EM
+instruction number <i>a</i> in the EM-pattern refers to ROM.
+This may be useful for generating position-independent code
+with the ROM in read-only memory. <i>Is_rom</i> enables one
+to see the difference between ROM references and other data
+references.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>loww($a)</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Returns the lower half of the argument of EM
+instruction number <i>a</i>. This is used to split the
+arguments of a <b>ldc</b> instruction.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>highw($a)</small></p>
+</td>
+<td width="14%"></td>
+<td width="40%">
+
+<p><small>Same for upper half.</small></p>
+</td>
+<td width="27%">
+</td>
+</table>
+
+<p><small>The next two &lsquo;functions&rsquo; are only
+needed in a table that implements register
+variables.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>inreg(e)</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Returns the status of the local variable with
+offset <i>e</i> from the localbase. Value is an integer,
+negative if the local was not allowed as a register
+variable, zero if it was allowed but not assigned to a
+register, and the type of the register if it was assigned to
+a register. This makes it possible to write</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="31%"></td>
+<td width="68%">
+<pre><small>     inreg($1)==reg_pointer
+</small></pre>
+<!-- INDENTATION -->
+<p><small>and similar things.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>regvar(e,t)</small></p>
+</td>
+<td width="10%"></td>
+<td width="68%">
+
+<p><small>Type of this is register. It returns the register
+the local with offset <i>e</i> is assigned to. The table
+writer guarantees the register is one of type <i>t</i>, with
+<i>t</i> one of reg_any, reg_loop, reg_pointer or reg_float.
+If <i>t</i> is omitted reg_any is assumed. Undefined if
+inreg(<i>e</i>)&lt;=0 .</small></p>
+</td>
+</table>
+
+<p><small>The next two &lsquo;functions&rsquo; are only
+needed in a table that uses the top element size
+information.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="28%">
+
+<p><small>topeltsize($a)</small></p>
+</td>
+<td width="4%"></td>
+<td width="68%">
+
+<p><small>Returns the size of the element on top of the
+EM-stack at the label identified by $a. This can be used to
+put the top of the stack in a register at the moment of an
+unconditional jump. At an unconditional jump, the size of
+the top-element will always look 0.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p><small>fallthrough($a)</small></p>
+</td>
+<td width="2%"></td>
+<td width="68%">
+
+<p><small>Returns 1 if the label identified by $a can be
+reached via fallthrough, 0 otherwise.</small></p>
+</td>
+</table>
+<a name="5.8. Token descriptions"></a>
+<h2>5.8. Token descriptions</h2>
+
+<p><small>Throughout the rest of the table tokens must be
+described, be it as operands of instructions or as
+stack-replacements. In all those cases we will speak about a
+token description. The possibilities for these will be
+described here.</small></p>
+
+<p><small>All expressions of type register are token
+descriptions. The construct %1 means the token matched first
+in the stack pattern. All other token descriptions are those
+that are built on the spot. They look like this:</small></p>
+<pre><small>     { &lt;tokenname&gt; , &lt;list of token attribute initializing expressions&gt; }
+</small></pre>
+
+<p><small>All expressions are type-checked by <i>cgg</i>,
+and the number of initializers is also checked.</small></p>
+
+<p><small>A special case of the last token descriptions
+occurs when the token name is &lsquo;LOCAL&rsquo; or
+&lsquo;DLOCAL&rsquo; and the table uses register variables.
+The first token attribute then must be of type integer and
+the token description is automagically replaced by the
+register chosen if the LOCAL (wordsize) or DLOCAL (twice the
+wordsize) was assigned to a register.</small></p>
+<a name="5.9. Code rules"></a>
+<h2>5.9. Code rules</h2>
+
+<p><small>The largest section of the tables consists of the
+code generation rules. They specify EM patterns, stack
+patterns, code to be generated etc. Broadly the syntax
+is</small></p>
+<pre><small>code rule : EM-part code-part
+EM-part : EM-pattern | procedure-heading
+code-part : code-description | procedure-call
+code-description : stackpattern kills allocates generates yields leaving
+</small></pre>
+
+<p><small>Ignoring the &quot;procedure&quot;-part for now,
+the description for the EM-pattern and the code-description
+follows. Almost everything here is optional, the minimum
+code rule is:</small></p>
+<pre><small>     pat nop
+</small></pre>
+
+<p><small>that will simply throw away <i>nop</i>
+instructions.</small></p>
+<a name="5.9.1. The EM pattern"></a>
+<h2>5.9.1. The EM pattern</h2>
+
+<p><small>The EM pattern consists of a list of EM mnemonics
+preceded by the word <i>pat</i> optionally followed by a
+boolean expression. Examples:</small></p>
+<pre><small>     pat <b>loe
+</b></small></pre>
+
+<p><small>will match a single <b>loe</b>
+instruction,</small></p>
+<pre><small>     pat <b>loc loc cif</b> $1==2 &amp;&amp; $2==8
+</small></pre>
+
+<p><small>is a pattern that will match</small></p>
+<pre><small><b>     loc</b> 2
+<b>     loc</b> 8
+<b>     cif
+</b></small></pre>
+
+<p><small>and</small></p>
+<pre><small>     pat <b>lol inc stl</b> $1==$3
+</small></pre>
+
+<p><small>will match for example</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="6" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small><b>lol</b> 6</small></p>
+<td width="9%"></td>
+<td width="20%">
+
+<p><small><b>lol</b> -2</small></p>
+</td>
+<td width="20%">
+</td>
+<td width="20%">
+
+<p><small><b>lol</b> 4<b><br>
+inc</b></small></p>
+</td>
+<td width="20%"></td>
+<td width="9%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="20%">
+
+<p><small><b>inc</b></small></p>
+</td>
+<td width="20%">
+
+<p><small>but <i>not</i></small></p>
+</td>
+<td width="20%">
+
+<p><small><b>inc<br>
+stl</b> 6</small></p>
+</td>
+<td width="20%"></td>
+<td width="9%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="20%">
+
+<p><small><b>stl</b> -2</small></p>
+</td>
+<td width="20%">
+</td>
+<td width="20%">
+
+<p><small><b>stl</b> -4</small></p>
+</td>
+<td width="20%"></td>
+<td width="9%">
+</td>
+</table>
+
+<p><small>A missing boolean expression evaluates to
+TRUE.</small></p>
+
+<p><small>The code generator will match the longest EM
+pattern on every occasion, if two patterns of the same
+length match the first in the table will be chosen, while
+all patterns of length greater than or equal to three are
+considered to be of the same length. This rule of three is
+an unfortunate implementation dependent restriction, but
+patterns longer than three EM instructions are luckily not
+needed too often.</small></p>
+
+<p><small>The EM mnemonic may also be the
+pseudo-instruction <b>lab</b>, which matches a label. Its
+argument can be used in testing on topeltsize and
+fallthrough. When this pattern is specified, the label
+should be defined explicitly with a <i>labeldef</i>
+statement.</small></p>
+
+<p><small>Following the EM-pattern there may be more than
+one code rule, <i>cg</i> will choose using heuristics and
+the cost information provided with the instruction and token
+definitions. Owing to parsing reasons of the table, the word
+<i>with</i> (see below) is mandatory when there are more
+code rules attached to one EM-pattern. The stack pattern may
+be empty however.</small></p>
+<a name="5.9.2. The stack pattern"></a>
+<h2>5.9.2. The stack pattern</h2>
+
+<p><small>The optional stack pattern is a list of token
+sets preceded by the word <i>with</i>. The token sets are
+usually represented by set identifiers for clarity. No
+boolean expression is allowed here. The first expression is
+the one that matches the top of the stack.</small></p>
+
+<p><small>If the pattern is followed by the word STACK it
+only matches if there is nothing else on the fake stack, and
+the code generator will stack everything not matched at the
+start of the rule.</small></p>
+
+<p><small>The pattern can be preceded with the word
+<i>exact</i> following the <i>with</i> that tells the code
+generator not to try to coerce to the pattern but only to
+use it when it is already present on the fake stack. There
+are two reasons for this construction, correctness and
+speed. It is needed for correctness when the pattern
+contains a register that is not transparent when data is
+moved through it.</small></p>
+
+<p><small>Example: on the PDP-11 the shortest code
+for</small></p>
+<pre><small><b>     lae</b> a
+<b>     loi</b> 8
+<b>     lae</b> b
+<b>     sti</b> 8
+</small></pre>
+
+<p><small>is</small></p>
+<pre><small>     movf _a,fr0
+     movf fr0,_b
+</small></pre>
+
+<p><small>if the floating point processor is in double
+precision mode and fr0 is free. Unfortunately this is not
+correct since a trap can occur on certain kinds of data.
+This could happen if there was a stack pattern for
+<b>sti</b> 8 like this:</small></p>
+<pre><small>     with DBLREG
+</small></pre>
+
+<p><small>The code generator would then find that coercing
+the 8-byte global _a to a floating point register and then
+storing it to _b was the cheapest, if the space/time knob
+was turned far enough to space. This can be prevented by
+changing the stack pattern to</small></p>
+<pre><small>     with exact DBLREG
+</small></pre>
+
+<p><small>It is unfortunate that the type information is no
+longer present, since if _a really is a floating point
+number the move could be made without error.</small></p>
+
+<p><small>The second reason for the <i>exact</i> construct
+is speed. When the code generator has a long list of
+possible stack patterns for one EM pattern it can waste much
+time trying to find coercions to all of them, while the mere
+presence of such a long list indicates that the table writer
+has given many special cases. Prepending all the special
+cases by <i>exact</i> will stop the code generator from
+trying to find things that either cannot be done, or are too
+expensive anyway.</small></p>
+
+<p><small>So in general it is wise to prepend all stack
+patterns that cannot be made by coercions with
+<i>exact</i>.</small></p>
+
+<p><small>Using both <i>exact</i> and STACK in the stack
+pattern has the effect that the rule will only be taken if
+there is nothing else on the fake stack.</small></p>
+<a name="5.9.3. The kills part"></a>
+<h2>5.9.3. The kills part</h2>
+
+<p><small>The optional kills part describes certain tokens
+that should neither remain on the fake stack, nor remembered
+as contents of registers. This is usually only required with
+store operations. The entire fake stack, except for the part
+matched in the stack pattern, is searched for tokens
+matching the expression and they are copied to the real
+stack. Every register that contains the token is marked as
+empty.</small></p>
+
+<p><small>Syntax is</small></p>
+<pre><small>     kills &lt;list of things to kill separated by commas&gt;
+     thing to kill : token set optionally followed by boolean expression
+</small></pre>
+
+<p><small>Example:</small></p>
+<pre><small>     kills regind2 %reg != lb || %off == $1
+</small></pre>
+
+<p><small>is a kills part used for example in the
+<b>inl</b> or <b>stl</b> code rule. It removes all register
+offsetted tokens where the register is not the localbase
+plus the local in which the store is done. The necessity for
+this can be seen from the following example:</small></p>
+<pre><small><b>     lol</b> 4
+<b>     inl</b> 4
+<b>     stl</b> 6
+</small></pre>
+
+<p><small>Without a proper kills part in the rule for
+<b>inl</b> code would be generated as here</small></p>
+<pre><small>     inc 4(r5)
+     mov 4(r5),6(r5)
+</small></pre>
+
+<p><small>so local 6 would be given the new value of local
+4 instead of the old as the EM code prescribed.</small></p>
+
+<p><small>When generating code for an EM-instruction like
+<b>sti</b> it is necessary to write a line in the table
+like</small></p>
+<pre><small>     kills all_except_constant_or_register
+</small></pre>
+
+<p><small>where the long identifier is a set containing all
+tokens that can be the destination of some random indirect
+store. These indirect stores are the main reason to prevent
+this <i>kills</i> line to be deduced automatically by
+<i>cgg</i>.</small></p>
+
+<p><small>When generating something like a branch
+instruction it might be needed to empty the fake stack
+completely. This can of course be done with</small></p>
+<pre><small>     kills ALL
+</small></pre>
+
+<p><small>or by ending the stack pattern with the word
+STACK, if the stack pattern does not start with
+<i>exact</i>. The latter does not erase the contents of
+registers.</small></p>
+
+<p><small>It is unfortunate that this part is still present
+in the table but it is too much for now to let the
+<i>cgg</i> program discover what rules ruin what kind of
+tokens. Maybe some day .....</small></p>
+<a name="5.9.4. The allocates part"></a>
+<h2>5.9.4. The allocates part</h2>
+
+<p><small>The optional register allocation part describes
+the registers needed. Syntax is</small></p>
+<pre><small>     uses &lt;list of use elements separated by commas&gt;
+</small></pre>
+
+<p><small>where itemlist is a list of three kinds of
+things:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small><i>reusing</i> &lt; a token description &gt;, for
+example %1.</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This will instruct the code generator that all
+registers contained in this token can be reused if they are
+not used in another token on the fakestack, so that they are
+available for allocation in this <i>uses</i> line if they
+were only used in that token. See example below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="40%">
+
+<p><small>a register property.</small></p>
+</td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This will allocate a register with that property,
+that is marked as empty at this point. Look ahead can be
+performed if there is more than one register
+available.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p><small>a register property with
+initialization.</small></p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This will allocate the register as in 2) but will
+also initialize it. This eases the task of the code
+generator because it can find a register already filled with
+the right value if it exists.</small></p>
+</td>
+</table>
+
+<p><small>Examples:</small></p>
+<pre><small>     uses ODDREG
+</small></pre>
+
+<p><small>will allocate an odd register, while</small></p>
+<pre><small>     uses REG={regind2,lb,$1}
+</small></pre>
+
+<p><small>will allocate a register while simultaneously
+filling it with the asked value.<br>
+Inside the coercion from xsrc2 to REG in the PDP-11 table
+the following line can be found.</small></p>
+<pre><small>     uses reusing %1, REG=%1
+</small></pre>
+
+<p><small>This tells the code generator that registers
+contained in %1 can be used again and asks to fill the
+register allocated with %1. So if
+%1={regind2,r3,&quot;4&quot;} and r3 is not in use elsewhere
+on the fake stack the following code might be
+generated.</small></p>
+<pre><small>     mov 4(r3),r3
+</small></pre>
+
+<p><small>In the rest of the line the registers allocated
+can be named by %a and %b.1,%b.2, i.e. with lower case
+letters in order of allocation.</small></p>
+<a name="5.9.5. The generates part"></a>
+<h2>5.9.5. The generates part</h2>
+
+<p><small>Code to be generated, also optionally, is
+specified as the word <i>gen</i> followed by a list of items
+of the following kind:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>An instruction name followed by a comma-separated
+list of token descriptions. <i>Cgg</i> will search the
+instruction definitions for the machine to find a suitable
+instruction. At code generation time the assembler name of
+the instruction will be output followed by a space, followed
+by a comma separated list of tokens.</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>In the table an instruction without operands must
+be followed by a period. The author of <i>cgg</i> could not
+get <i>yacc</i> to accept his syntax without it. Sorry about
+this.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="88%">
+
+<p><small>a <i>move</i> call. This has the following
+syntax:</small></p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><small>     move &lt;token description&gt;,&lt;token description&gt;
+</small></pre>
+<!-- INDENTATION -->
+<p><small>Moves are handled specially since that enables the
+code generator to keep track of register contents.
+Example:</small></p>
+<!-- INDENTATION -->
+<pre><small>     move r3,{regind2,lb,$1}
+</small></pre>
+<!-- INDENTATION -->
+<p><small>will generate code to move r3 to $1(r5) except
+when r3 already was a copy of $1(r5). Then the code will be
+omitted. The rules describing how to move things to each
+other can be found in the move definitions section described
+below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>For machines that have condition codes, which
+alas most of them do, there are provisions to remember
+condition code settings and prevent needless testing. To set
+the condition code to a token put in the code the following
+call:</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><small>     test &lt;token description&gt;
+</small></pre>
+<!-- INDENTATION -->
+<p><small>This will generate a test if the condition codes
+were not already set to that token. The rules describing how
+to test things can be found in the test definitions section
+described below. See also the :cc qualifier that can be used
+at instruction definition time.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>The <i>return</i> statement. Only used when
+register variables are in use. This statement causes a call
+to the machine dependent C-routine <i>regreturn</i>.
+Explanation of this must wait for the description of the
+file mach.c below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>5)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>The <i>labeldef</i> statement. Its only argument
+should be that of the <i>lab</i> pseudo-instruction. This is
+needed to generate local labels when the top element size
+information is used. It takes the form</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>labeldef $i</small></p>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>6)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>A temporary label of the form &lt;digit&gt;: may
+be placed here. Expressions of the form [0-9][bf] in this
+code rule generate the same string as is used for this
+label. The code generator system could probably easily be
+changed to make this work for assemblers that do not support
+this type of label by generating unique labels itself.
+Implementation of this is not contemplated at the
+moment.</small></p>
+</td>
+</table>
+<a name="5.9.6. Stack replacement"></a>
+<h2>5.9.6. Stack replacement</h2>
+
+<p><small>The optional stack replacement is a possibly
+empty list of tokens to be pushed onto the fake stack. It
+start with the word <i>yields</i>, and is followed by a list
+of token descriptions.</small></p>
+
+<p><small>All tokens matched by the stack pattern at the
+beginning of the code rule are first removed and their
+registers deallocated. Items are pushed in the order of
+appearance. This means that the last item will be on the top
+of the stack after the push. So if the stack pattern
+contained two sets and they must be pushed back unchanged,
+they have to be specified as stack replacement</small></p>
+<pre><small>     yields %2 %1
+</small></pre>
+
+<p><small>and not the other way around. This is known to
+cause errors in tables so watch out for this!</small></p>
+<a name="5.9.7. EM replacement"></a>
+<h2>5.9.7. EM replacement</h2>
+
+<p><small>In exceptional cases it might be useful to leave
+part of an EM-pattern undone. For example, a <b>sdl</b>
+instruction might be split into two <b>stl</b> instructions
+when there is no 4-byte quantity on the stack. The EM
+replacement part allows one to express this. It is activated
+by the word <i>leaving</i>.</small></p>
+
+<p><small>Example:</small></p>
+<pre><small>     leaving <b>stl</b> $1 <b>stl</b> $1+2
+</small></pre>
+
+<p><small>The instructions are inserted in the stream so
+that they can match the first part of a pattern in the next
+step. Note that since the code generator traverses the EM
+instructions in a strict linear fashion, it is impossible to
+let the EM replacement match later parts of a pattern. So if
+there is a pattern</small></p>
+<pre><small><b>     loc stl</b> $1==0
+</small></pre>
+
+<p><small>and the input is</small></p>
+<pre><small><b>     loc</b> 0 <b>sdl</b> 4
+</small></pre>
+
+<p><small>the <b>loc</b> 0 will be processed first, then
+the <b>sdl</b> might be split into two <b>stl</b>&rsquo;s
+but the pattern cannot match now.</small></p>
+<a name="5.9.8. Examples"></a>
+<h2>5.9.8. Examples</h2>
+
+<p><small>A list of examples for the PDP-11 is given here.
+Far from being complete it gives examples of most kinds of
+instructions.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>pat loc</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {const2, $1}</small></p>
+
+<p><small>pat ldc</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {const2, loww($1)} {const2,
+highw($1)}</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>These simple patterns just push one or more
+tokens onto the fake stack.</small></p>
+<pre><small>     pat lof
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>with REG</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {regind2,%1,$1}<br>
+with exact regconst2</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {regind2,%1.reg,$1+%1.off}<br>
+with exact addr_external</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {relative2,$1+%1.off}<br>
+with exact addr_local</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {LOCAL, %1.ind + $1,2}</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>This pattern shows the possibility to do
+different things depending on the fake stack contents, there
+are some rules for some specific cases plus a general rule,
+not preceded by <i>exact</i> that can always be taken after
+a coercion, if necessary.</small></p>
+<pre><small>     pat lxl $1&gt;3
+     uses REG={LOCAL, SL, 2}, REG={const2,$1-1}
+     gen 1:
+         move {regind2,%a, SL},%a
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>sob %b,{label,1b}</small></p>
+<td width="17%"></td>
+<td width="50%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>This rule shows register allocation with
+initialisation, and the use of a temporary label. The
+constant SL used here is defined to be the offset from lb of
+the static link, that is pushed by the Pascal compiler as
+the last argument of a function.</small></p>
+<pre><small>     pat stf
+     with regconst2 xsrc2
+       kills allexeptcon
+       gen move %2,{regind2,%1.reg,$1+%1.off}
+     with addr_external xsrc2
+       kills allexeptcon
+       gen move %2,{relative2,$1+%1.off}
+</small></pre>
+
+<p><small>This rule shows the use of a <i>kills</i> part in
+a store instruction. The set allexeptcon contains all tokens
+that can be the destination of an indirect
+store.</small></p>
+<pre><small>     pat sde
+     with exact FLTREG
+       kills posextern
+       gen move %1,{relative4,$1}
+     with exact ftolong
+       kills posextern
+       gen setl.
+           movfi %1.reg,{relative4,$1}
+           seti.
+     with src2 src2
+       kills posextern
+       gen move %1, {relative2, $1 }
+           move %2, {relative2, $1+2}
+</small></pre>
+
+<p><small>The rule for <b>sde</b> shows the use of the
+<i>exact</i> clause in both qualities, the first is for
+correctness, the second for efficiency. The third rule is
+taken by default, resulting in two separate stores, nothing
+better exists on the PDP-11.</small></p>
+<pre><small>     pat sbi $1==2
+     with src2 REG
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen sub %1,%2</small></p>
+<td width="13%"></td>
+<td width="54%">
+
+<p><small>yields %2</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>with exact REG src2-REG<br>
+gen sub %2,%1</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>neg %1</small></p>
+<td width="21%"></td>
+<td width="46%">
+
+<p><small>yields %1</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>This rule for <i>sbi</i> has a normal first part,
+and a hand optimized special case as its second
+part.</small></p>
+<pre><small>     pat mli $1==2
+     with ODDREG src2
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen mul %2,%1</small></p>
+<td width="13%"></td>
+<td width="54%">
+
+<p><small>yields %1</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>with src2 ODDREG</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen mul %1,%2</small></p>
+<td width="13%"></td>
+<td width="54%">
+
+<p><small>yields %2</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>This shows the general property for rules with
+commutative operators, heuristics or look ahead will have to
+decide which rule is the best.</small></p>
+<pre><small>     pat loc sli $1==1 &amp;&amp; $2==2
+     with REG
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen asl %1</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %1</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>A simple rule involving a longer EM-pattern, to
+make use of a specialized instruction available.</small></p>
+<pre><small>     pat loc loc cii $1==1 &amp;&amp; $2==2
+     with src1or2
+     uses reusing %1,REG
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen movb %1,%a</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>A somewhat more complicated example of the same.
+Note the <i>reusing</i> clause.</small></p>
+<pre><small>     pat loc loc loc cii $1&gt;=0 &amp;&amp; $2==2 &amp;&amp; $3==4
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>leaving loc $1 loc 0</small></p>
+</table>
+
+<p><small>Shows a trivial example of EM-replacement. This
+is a rule that could be done by the peephole optimizer, if
+word order in longs was defined in EM. On a
+&lsquo;big-endian&rsquo; machine the two replacement
+instructions would be the other way around.</small></p>
+<pre><small>     pat and $1==2
+     with const2 REG
+       gen bic {const2,~%1.num},%2yields %2
+     with REG const2
+       gen bic {const2,~%2.num},%1yields %1
+     with REG REG
+       gen com %1
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>bic %1,%2</small></p>
+<td width="21%"></td>
+<td width="46%">
+
+<p><small>yields %2</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>Shows the way to handle the absence of an
+<i>and</i>-instruction.</small></p>
+<pre><small>     pat set $1==2
+     with REG
+     uses REG={const2,1}
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen ash %1,%a</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>Shows the building of a word-size
+set.</small></p>
+<pre><small>     pat lae aar $2==2 &amp;&amp; rom($1,3)==1 &amp;&amp; rom($1,1)==0
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>leaving adi 2</small></p>
+</table>
+
+<p><small>pat lae aar $2==2 &amp;&amp; rom($1,3)==1
+&amp;&amp; rom($1,1)!=0</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>leaving adi 2 adp 0-rom($1,1)</small></p>
+</table>
+
+<p><small>Two rules showing the use of the rom pseudo
+function, and some array optimalisation.</small></p>
+<pre><small>     pat bra
+     with STACK
+     gen jbr {label, $1}
+</small></pre>
+
+<p><small>A simple jump. The stack pattern guarantees that
+everything will be stacked before the jump is
+taken.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="11" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>pat lab</small></p>
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>topeltsize($1)==2 &amp;&amp; !fallthrough($1)<br>
+gen labeldef $1</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>yields r0</small></p>
+
+<p><small>pat lab</small></p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>topeltsize($1)==2 &amp;&amp;
+fallthrough($1)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+</table>
+
+<p><small>with src2<br>
+gen move %1,r0</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="9" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>labeldef $1</small></p>
+<td width="17%"></td>
+<td width="2%">
+</td>
+<td width="30%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>yields r0</small></p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+</table>
+
+<p><small>pat lab topeltsize($1)!=2<br>
+with STACK<br>
+kills all<br>
+gen labeldef $1</small></p>
+
+<p><small>pat bra topeltsize($1)==2<br>
+with src2 STACK<br>
+gen move %1,d0</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>jbr {label, $1}</small></p>
+</table>
+
+<p><small>pat bra topeltsize($1)!=2<br>
+with STACK<br>
+gen jbr {label, $1}</small></p>
+
+<p><small>The combination of these patterns make sure that
+the top of the EM-stack will be in register r0 whenever
+necessary. The top element size mechanism will also show a
+size of 0 whenever a conditional branch to a label occurs.
+This saves a lot of patterns and hardly decreases
+performance. When the same register is used to return
+function results, this can save many moves to and from the
+stack.</small></p>
+<pre><small>     pat cal
+     with STACK
+     gen jsr pc,{label, $1}
+</small></pre>
+
+<p><small>A simple call. Same comments as previous
+rule.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>pat lfr $1==2</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields r0<br>
+pat lfr $1==4</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields r1 r0</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>Shows the return area conventions of the PDP-11
+table. At this point a reminder: the <b>asp</b> instruction,
+and some other instructions must leave the function return
+area intact. See the defining document for EM for exact
+information.</small></p>
+<pre><small>     pat ret $1==0
+     with STACK
+     gen mov lb,sp
+         rts pc
+</small></pre>
+
+<p><small>This shows a rule for <b>ret</b> in a table not
+using register variables. In a table with register variables
+the <i>gen</i> part would just contain
+<i>return</i>.</small></p>
+<pre><small>     pat blm
+     with REG REG
+     uses REG={const2,$1/2}
+     gen 1:
+         mov {autoinc,%2},{autoinc,%1}
+         sob %a,{label,1b}
+</small></pre>
+
+<p><small>This rule for <b>blm</b> already uses three
+registers of the same type. <i>Cgg</i> contains code to
+check all rules to see if they can be applied from an empty
+fakestack. It uses the marriage thesis from Hall, a thesis
+from combinatorial mathematics, to accomplish
+this.</small></p>
+<pre><small>     pat exg $1==2
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>with src2 src2</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %1 %2</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>This rule shows the exchanging of two elements on
+the fake stack.</small></p>
+<a name="5.10. Code rules using procedures"></a>
+<h2>5.10. Code rules using procedures</h2>
+
+<p><small>To start this section it must be admitted at once
+that the word procedure is chosen here mainly for its
+advertising value. It more resembles a glorified goto but
+this of course can not be admitted in the glossy brochures.
+This document will continue to use the word
+procedure.</small></p>
+
+<p><small>The need for procedures was felt after the first
+version of the code generator system was made, mainly
+because of conditional instructions. Often the code
+sequences for <b>tlt</b>, <b>tle</b>, <b>teq</b>,
+<b>tne</b>, <b>tge</b> and <b>tgt</b> were identical apart
+from one opcode in the code rule. The code sequence had to
+be written out six times however. Not only did this increase
+the table size and bore the table writer, it also led to
+errors when changing the table since it happened now and
+then that five out of six rules were changed.</small></p>
+
+<p><small>In general the procedures in this table format
+are used to keep one copy instead of six of the code rules
+for all sorts of conditionals and one out of two for things
+like increment/decrement.</small></p>
+
+<p><small>And now the syntax, first the procedure
+definition, which must indeed be defined before the call
+because <i>cgg</i> is one-pass. The procedure heading
+replaces the EM-pattern in a code rule and looks like
+this:</small></p>
+<pre><small>     proc &lt;identifier&gt; &lt;optional example&gt;
+</small></pre>
+
+<p><small>The identifier is used in later calls and the
+example must be used if expressions like $1 are used in the
+code rule.</small></p>
+<pre><small>     &lt;optional example&gt; : example &lt;list of EM-instructions&gt;
+</small></pre>
+
+<p><small>so an example looks just like an EM-pattern, but
+without the optional boolean expression. The example is
+needed to know the types of $1 expressions. The current
+version of <i>cgg</i> does not check correctness of the
+example, so be careful.</small></p>
+
+<p><small>A procedure is called with string-parameters,
+that are assembler opcodes. They can be accessed by
+appending the string &lsquo;[&lt;number&gt;]&rsquo; to a
+table opcode, where &lt;number&gt; is the parameter number.
+The string &lsquo;*&rsquo; can be used as an equivalent for
+&lsquo;[1]&rsquo;. Just in case this is not clear, here is
+an example for a procedure to increment/decrement a
+register.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>incop REG:rw:cc .</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>/* in the INSTRUCTIONS part of course
+*/</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>proc incdec<br>
+with REG</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen incop* %1</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %1</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>The procedure is called with parameter
+&quot;inc&quot; or &quot;dec&quot;.</small></p>
+
+<p><small>The procedure call is given instead of the
+code-part of the code rule and looks like this</small></p>
+<pre><small>     call &lt;identifier&gt; &rsquo;(&rsquo; &lt;comma-separated list of strings&gt; &rsquo;)&rsquo;
+</small></pre>
+
+<p><small>which leads to the following large
+example:</small></p>
+<pre><small>     proc bxx example beq
+     with src2 src2 STACK
+     gen cmp %2,%1
+         jxx* {label, $1}
+
+
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>pat blt</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>call bxx(&quot;jlt&quot;)<br>
+pat ble</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>call bxx(&quot;jle&quot;)<br>
+pat beq</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>call bxx(&quot;jeq&quot;)<br>
+pat bne</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>call bxx(&quot;jne&quot;)<br>
+pat bgt</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>call bxx(&quot;jgt&quot;)<br>
+pat bge</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>call bxx(&quot;jge&quot;)</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+<a name="5.11. Move definitions"></a>
+<h2>5.11. Move definitions</h2>
+
+<p><small>We now jump back to near the beginning of the
+table where the move definitions are found. The move
+definitions directly follow the instruction
+definitions.</small></p>
+
+<p><small>In certain cases a move is called for, either
+explicitly when a <i>move</i> instruction is used in a code
+rule, or implicitly in a register initialization. The
+different code rules possible to move data from one spot to
+another are described here. Example for the
+PDP-11:</small></p>
+<pre><small>     MOVES
+
+
+     from const2 %num==0 to dst2
+     gen clr %2
+
+
+     from src2 to dst2
+     gen mov %1,%2
+
+
+     from FLTREG to longf4-FLTREG
+     gen movfo %1,%2
+
+
+     from longf4-FLTREG to FLTREG
+     gen movof %1,%2
+</small></pre>
+
+<p><small>The example shows that the syntax is
+just</small></p>
+<pre><small>     from &lt;source&gt; to &lt;destination&gt; gen &lt;list of instructions&gt;
+</small></pre>
+
+<p><small>Source and destination are a token set,
+optionally followed by a boolean expression. The code
+generator will take the first move that matches, whenever a
+move is necessary. <i>Cgg</i> checks whether all moves
+called for in the table are present.</small></p>
+<a name="5.12. Test definitions"></a>
+<h2>5.12. Test definitions</h2>
+
+<p><small>This part describes the instructions necessary to
+set the condition codes to a certain token. These rules are
+needed when the <i>test</i> instruction is used in code
+rules. Example for the PDP-11:</small></p>
+<pre><small>     TESTS
+
+
+     to test src2
+     gen tst %1
+</small></pre>
+
+<p><small>So syntax is just</small></p>
+<pre><small>     to test &lt;source&gt; gen &lt;instruction list&gt;
+</small></pre>
+
+<p><small>Source is the same thing as in the move
+definition. <i>Cgg</i> checks whether all tests called for
+in the table are present.</small></p>
+<a name="5.13. Some explanation about the rules behind coercions"></a>
+<h2>5.13. Some explanation about the rules behind coercions</h2>
+
+<p><small>A central part in code generation is taken by the
+<i>coercions</i>. It is the responsibility of the table
+writer to provide all necessary coercions so that code
+generation can continue. The minimal set of coercions are
+the coercions to unstack every token expression, in
+combination with the rules to stack every token. It should
+not be possible to smuggle a table through <i>cgg</i>
+without these basic set available.</small></p>
+
+<p><small>If these are present the code generator can
+always make the necessary transformations by stacking and
+unstacking. Of course for code quality it is usually best to
+provide extra coercions to prevent this stacking to take
+place. <i>Cg</i> discriminates three types of
+coercions:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Unstacking coercions. This category can use the
+<i>uses</i> clause in its code.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Splitting coercions, these are the coercions that
+split larger tokens into smaller ones.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Transforming coercions, these are the coercions
+that transform a token into another of the same size. This
+category can use the <i>uses</i> clause in its
+code.</small></p>
+</td>
+</table>
+
+<p><small>When a stack configuration does not match the
+stack pattern <i>coercions</i> are searched for in the
+following order:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>First tokens are split if necessary to get their
+sizes right.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Then transforming coercions are found that will
+make the pattern match.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Finally if the stack pattern is longer than the
+fake stack contents unstacking coercions will be used to
+fill up the pattern.</small></p>
+</td>
+</table>
+
+<p><small>At any point, when coercions are missing so code
+generation could not continue, the offending tokens are
+stacked.</small></p>
+<a name="5.14. Stack definitions"></a>
+<h2>5.14. Stack definitions</h2>
+
+<p><small>The next part of the table defines the stacking
+rules for the machine. Each token that may reside on the
+fake stack must have a rule attached to put it on the real
+stack. Example for the PDP-11:</small></p>
+<pre><small>     STACKINGRULES
+
+
+     from const2 %num==0 to STACK
+     gen clr {autodec,sp}
+
+
+     from src2 to STACK
+     gen mov %1,{autodec,sp}
+
+
+     from regconst2 to STACK
+     gen mov %1.reg,{autodec,sp}
+         add {addr_external, %1.off},{regdef2,sp}
+
+
+     from DBLREG to STACK
+     gen movf %1,{autodec,sp}
+
+
+     from FLTREG  to STACK
+     gen movfo %1,{autodec,sp}
+
+
+     from regind8 to STACK
+     uses REG
+     gen move %1.reg,%a
+         add {addr_external, 8+%1.off},%a
+         mov {autodec, %a},{autodec,sp}
+         mov {autodec, %a},{autodec,sp}
+         mov {autodec, %a},{autodec,sp}
+         mov {autodec, %a},{autodec,sp}
+</small></pre>
+
+<p><small>These examples should be self-explanatory, except
+maybe for the last one. It is possible inside a
+stacking-rule to use a register. Since however the stacking
+might also take place at a moment when no registers are
+free, it is mandatory that for each token there is one
+stackingrule that does not use a register. The code
+generator uses the first rule possible.</small></p>
+<a name="5.15. Coercions"></a>
+<h2>5.15. Coercions</h2>
+
+<p><small>The next part of the table defines the coercions
+that are possible on the defined tokens. Example for the
+PDP-11:</small></p>
+<pre><small>     COERCIONS
+
+
+     from STACK
+     uses REG
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen mov {autoinc,sp},%a</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>from STACK<br>
+uses DBLREG</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen movf {autoinc,sp},%a</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>from STACK<br>
+uses REGPAIR<br>
+gen mov {autoinc,sp},%a.1</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>mov {autoinc,sp},%a.2</small></p>
+<td width="17%"></td>
+<td width="50%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>These three coercions just deliver a certain type
+of register by popping it from the real stack.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>from LOCAL</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {regind2,lb,%1.ind}</small></p>
+
+<p><small>from DLOCAL</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {regind4,lb,%1.ind}</small></p>
+
+<p><small>from REG</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {regconst2, %1, 0}</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>These three are zero-cost rewriting
+rules.</small></p>
+<pre><small>     from regconst2 %1.off==1
+     uses reusing %1,REG=%1.reg
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen inc %a</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>from regconst2<br>
+uses reusing %1,REG=%1.reg<br>
+gen add {addr_external, %1.off},%ayields %a</small></p>
+
+<p><small>from addr_local<br>
+uses REG<br>
+gen mov lb,%a</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>add {const2, %1.ind},%a</small></p>
+<td width="17%"></td>
+<td width="50%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>The last three are three different cases of the
+coercion register+constant to register. Only in the last
+case is it always necessary to allocate an extra register,
+since arithmetic on the localbase is
+unthinkable.</small></p>
+<pre><small>     from xsrc2
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>uses reusing %1, REG=%1</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>from longf4</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>uses FLTREG=%1</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>from double8</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>uses DBLREG=%1</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>from src1<br>
+uses REG={const2,0}</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>gen bisb %1,%a</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %a</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>These examples show the coercion of different
+tokens to a register of the needed type. The last one shows
+the trouble needed on a PDP-11 to ensure bytes are not
+sign-extended. In EM it is defined that the result of a
+<b>loi</b> 1 instruction is an integer in the range
+0..255.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>from REGPAIR</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields %1.2 %1.1</small></p>
+
+<p><small>from regind4</small></p>
+</td>
+<td width="32%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {regind2,%1.reg,2+%1.off}</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>{regind2,%1.reg,%1.off}</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><small>from relative4</small></p>
+<td width="9%"></td>
+<td width="58%">
+
+<p><small>yields {relative2,2+%1.off}</small></p>
+</td>
+<td width="32%">
+</td>
+</table>
+
+<p><small>{relative2,%1.off}</small></p>
+
+<p><small>The last examples are splitting
+rules.</small></p>
+
+<p><small>The examples show that all coercions change one
+token on the fake stack into one or more others, possibly
+generating code. The STACK token is supposed to be on the
+fake stack when it is really empty, and can only be changed
+into one other token.</small></p>
+<a name="6. The files mach.h and mach.c"></a>
+<h2>6. The files mach.h and mach.c</h2>
+
+<p><small>The table writer must also supply two files
+containing machine dependent declarations and C code. These
+files are mach.h and mach.c.</small></p>
+<a name="6.1. Types in the code generator"></a>
+<h2>6.1. Types in the code generator</h2>
+
+<p><small>Three different types of integer coexist in the
+code generator and their range depends on the machine at
+hand. They are defined depending on the Target EM_WSIZE, or
+TEM_WSIZE, and TEM_PSIZE. The type &rsquo;int&rsquo; is used
+for things like counters that won&rsquo;t require more than
+16 bits precision. The type &rsquo;word&rsquo; is used among
+others to assemble datawords and is of type
+&rsquo;long&rsquo;. The type &rsquo;full&rsquo; is used for
+addresses and is of type &rsquo;long&rsquo; if
+TEM_WSIZE&gt;2 or TEM_PSIZE&gt;2.</small></p>
+
+<p><small>In macro and function definitions in later
+paragraphs implicit typing will be used for parameters, that
+is parameters starting with an &rsquo;s&rsquo; will be of
+type string, and the letters
+&rsquo;i&rsquo;,&rsquo;w&rsquo;,&rsquo;f&rsquo; will stand
+for int, word and full respectively.</small></p>
+<a name="6.2. Global variables to work with"></a>
+<h2>6.2. Global variables to work with</h2>
+
+<p><small>Some global variables are present in the code
+generator that can be manipulated by the routines in mach.h
+and mach.c.</small></p>
+
+<p><small>The declarations are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>FILE *codefile;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* code is emitted on this stream */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>word part_word;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* words to be output are put together here
+*/</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>int part_size;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* number of bytes already put in part_word
+*/</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>char str[];</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* Last string read in */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="40%">
+
+<p><small>long argval;</small></p>
+</td>
+<td width="60%">
+
+<p><small>/* Last int read and kept */</small></p>
+</td>
+</table>
+<a name="6.3. Macros in mach.h"></a>
+<h2>6.3. Macros in mach.h</h2>
+
+<p><small>In the file mach.h a collection of macros is
+defined that have to do with formatting of assembly code for
+the machine at hand. Some of these macros can of course be
+left undefined in which case the macro calls are left in the
+source and will be treated as function calls. These
+functions can then be defined in <i>mach.c</i>.</small></p>
+
+<p><small>The macros to be defined are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>ex_ap(s)</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Must print the magic incantations that will mark
+the symbol to be exported to other modules. This is the
+translation of the EM <b>exa</b> and <b>exp</b>
+instructions.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>in_ap(s)</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Same to import the symbol. Translation of
+<b>ina</b> and <b>inp</b>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>newplb(s)</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>Must print the definition of procedure label
+<i>s</i>. If left undefined the newilb() macro is used
+instead.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>newilb(s)</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>Must print the definition of instruction label
+<i>s</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>newdlb(s)</small></p>
+</td>
+<td width="14%"></td>
+<td width="68%">
+
+<p><small>Must print the definition of data label
+<i>s</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p><small>dlbdlb(s1,s2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="68%">
+
+<p><small>Must define data label <i>s1</i> to be equal to
+<i>s2</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p><small>newlbss(s,f)</small></p>
+</td>
+<td width="8%"></td>
+<td width="68%">
+
+<p><small>Must declare a piece of memory initialized to
+BSS_INIT(see below) of length <i>f</i> and with label
+<i>s</i>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>cst_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used when converting constant
+arguments of EM instructions to string. Argument to be
+formatted will be &rsquo;full&rsquo;.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>off_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for integer part of
+label+constant, argument will be
+&rsquo;full&rsquo;.</small></p>
+</td>
+</table>
+
+<p><small>fmt_ilb(ip,il,s)</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="31%"></td>
+<td width="68%">
+<p><small>Must use the numbers <i>ip</i> and <i>il</i> that
+are a procedure number and a label number respectively and
+copy a string to <i>s</i> that must be unique for that
+combination. This procedure is optional, if it is not given
+ilb_fmt must be defined as below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>ilb_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for creation of unique
+instruction labels. Arguments will be a unique procedure
+number (int) and the label number (int).</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>dlb_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for printing numeric data
+labels. Argument will be &rsquo;int&rsquo;.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>hol_fmt</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for generation of labels for
+space generated by a <b>hol</b> pseudo. Argument will be
+&rsquo;int&rsquo;.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>hol_off</small></p>
+</td>
+<td width="18%"></td>
+<td width="68%">
+
+<p><small>Format to be used for printing of the address of
+an element in <b>hol</b> space. Arguments will be the offset
+in the <b>hol</b> block (word) and the number of the
+<b>hol</b> (int).</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>con_cst(w)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Must generate output that will assemble into one
+machine word.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>con_ilb(s)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Must generate output that will put the address of
+the instruction label into the datastream.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><small>con_dlb(s)</small></p>
+</td>
+<td width="12%"></td>
+<td width="68%">
+
+<p><small>Must generate output that will put the address of
+the data label into the datastream.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p><small>fmt_id(sf,st)</small></p>
+</td>
+<td width="6%"></td>
+<td width="68%">
+
+<p><small>Must take the string in <i>sf</i> that is a
+nonnumeric global label, and transform it into a copy made
+to <i>st</i> that will not collide with reserved assembler
+words and system labels. This procedure is optional, if it
+is not given the id_first macro is used as defined
+below.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>id_first</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Must be a character. This is prepended to all
+nonnumeric global labels if their length is shorter than the
+maximum allowed(currently 8) or if they already start with
+that character. This is to avoid conflicts of user labels
+with system labels.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>BSS_INIT</small></p>
+</td>
+<td width="16%"></td>
+<td width="68%">
+
+<p><small>Must be a constant. This is the value filled in
+all the words not initialized explicitly. This is loader and
+system dependent. If omitted no initialization is
+assumed.</small></p>
+</td>
+</table>
+<a name="6.3.1. Example mach.h for the PDP-11"></a>
+<h2>6.3.1. Example mach.h for the PDP-11</h2>
+<pre><small>#define ex_ap(y)fprintf(codefile,&quot;\t.globl %s\n&quot;,y)
+#define in_ap(y)/* nothing */
+
+
+#define newplb(x)fprintf(codefile,&quot;%s:\n&quot;,x)
+#define newilb(x)fprintf(codefile,&quot;%s:\n&quot;,x)
+#define newdlb(x)fprintf(codefile,&quot;%s:\n&quot;,x)
+#define dlbdlb(x,y)fprintf(codefile,&quot;%s=%s\n&quot;,x,y)
+#define newlbss(l,x)fprintf(codefile,&quot;%s:.=.+%d.\n&quot;,l,x);
+
+
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%">
+
+<p><small>#define cst_fmt</small></p>
+</td>
+<td width="68%">
+
+<p><small>&quot;$%d.&quot;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="32%">
+
+<p><small>#define off_fmt</small></p>
+</td>
+<td width="68%">
+
+<p><small>&quot;%d.&quot;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="32%">
+
+<p><small>#define ilb_fmt</small></p>
+</td>
+<td width="68%">
+
+<p><small>&quot;I%x_%x&quot;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="32%">
+
+<p><small>#define dlb_fmt</small></p>
+</td>
+<td width="68%">
+
+<p><small>&quot;_%d&quot;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="32%">
+
+<p><small>#define hol_fmt</small></p>
+</td>
+<td width="68%">
+
+<p><small>&quot;hol%d&quot;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="32%">
+
+<p><small>#define hol_off</small></p>
+</td>
+<td width="68%">
+
+<p><small>&quot;%ld.+hol%d&quot;</small></p>
+</td>
+</table>
+
+<p><small>#define
+con_cst(x)fprintf(codefile,&quot;%ld.\n&quot;,x)<br>
+#define con_ilb(x)fprintf(codefile,&quot;%s\n&quot;,x)<br>
+#define
+con_dlb(x)fprintf(codefile,&quot;%s\n&quot;,x)</small></p>
+
+<p><small>#define id_first&rsquo;_&rsquo;<br>
+#define BSS_INIT0</small></p>
+<a name="6.4. Functions in mach.c"></a>
+<h2>6.4. Functions in mach.c</h2>
+
+<p><small>In mach.c some functions must be supplied, mostly
+manipulating data resulting from pseudoinstructions. The
+specifications are given here, implicit typing of parameters
+as above.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="36%">
+
+<p><small>con_part(isz,word)</small></p>
+</td>
+<td width="53%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function must manipulate the globals
+part_word and part_size to append the isz bytes contained in
+word to the output stream. If part_word is full, i.e.
+part_size==TEM_WSIZE the function part_flush() may be called
+to empty the buffer. This is the function that must go
+through the trouble of doing byte order in words
+correct.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="32%">
+
+<p><small>con_mult(w_size)</small></p>
+</td>
+<td width="57%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function must take the string str[] and
+create an integer from the string of size w_size and
+generate code to assemble global data for that integer. Only
+the sizes for which arithmetic is implemented need be
+handled, so if 200-byte integer division is not implemented,
+200-byte integer global data don&rsquo;t have to be
+implemented. Here one must take care of word order in long
+integers.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p><small>con_float()</small></p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function must generate code to assemble a
+floating point number of which the size is contained in
+argval and the ASCII representation in str[].</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="34%">
+
+<p><small>prolog(f_nlocals)</small></p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function is called at the start of every
+procedure. Function prolog code must be generated, and room
+made for local variables for a total of f_nlocals
+bytes.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="24%">
+
+<p><small>mes(w_mesno)</small></p>
+</td>
+<td width="65%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function is called when a <b>mes</b> pseudo
+is seen that is not handled by the machine independent part.
+The example below shows all one probably have to know about
+that.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="18%">
+
+<p><small>segname[]</small></p>
+</td>
+<td width="71%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This is not a function, but an array of four
+strings. These strings are put out whenever the code
+generator switches segments. Segments are SEGTXT, SEGCON,
+SEGROM and SEGBSS in that order.</small></p>
+</td>
+</table>
+
+<p><small>If register variables are used in a table, the
+program <i>cgg</i> will define the word REGVARS during
+compilation of the sources. So the following functions
+described here should be bracketed by #ifdef REGVARS and
+#endif.</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p><small>regscore(off,size,typ,freq,totyp) long
+off;</small></p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function should assign a score to a register
+variable, the score should preferably be the estimated
+number of bytes gained when it is put in a register. Off and
+size are the offset and size of the variable, typ is the
+type, that is reg_any, reg_pointer, reg_loop or reg_float.
+Freq is the count of static occurrences, and totyp is the
+type of the register it is planned to go into.<br>
+Keep in mind that the gain should be net, that is the cost
+for register save/restore sequences and the cost of
+initialisation in the case of parameters should already be
+included.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p><small>i_regsave()</small></p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function is called at the start of a
+procedure, just before register saves are done. It can be
+used to initialise some variables if needed.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p><small>f_regsave()</small></p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>This function is called at end of the register
+save sequence. It can be used to do the real saving if
+multiple register move instructions are
+available.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>regsave(regstr,off,size) char *regstr; long
+off;</small></p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Should either do the real saving or set up a table
+to have it done by f_regsave. Note that initialisation of
+parameters should also be done, or planned here.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="22%">
+
+<p><small>regreturn()</small></p>
+</td>
+<td width="67%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>Should restore saved registers and return. The
+function result is already in the function return area by
+now.</small></p></td>
+</table>
+<a name="6.4.1. Example mach.c for the PDP-11"></a>
+<h2>6.4.1. Example mach.c for the PDP-11</h2>
+
+<p><small>As an example of the sort of code expected, the
+mach.c for the PDP-11 is presented here.</small></p>
+<pre><small>/*
+ * machine dependent back end routines for the PDP-11
+ */
+
+
+con_part(sz,w) register sz; word w; {
+
+
+</small></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>while (part_size % sz)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>part_size++;</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>if (part_size == 2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>part_flush();</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>if (sz == 1) {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>w &amp;= 0xFF;</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>if (part_size)</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>w &lt;&lt;= 8;</small></p>
+</td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>part_word |= w;</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>} else {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>assert(sz == 2);</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>part_word = w;</small></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>}</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p><small>part_size += sz;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>con_mult(sz) word sz; {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>long l;</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (sz != 4)</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fatal(&quot;bad icon/ucon
+size&quot;);</small></p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>l = atol(str);</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+
+<p><small>fprintf(codefile,&quot;\t%o;%o\n&quot;,(int)(l&gt;&gt;16),(int)l);</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>con_float() {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>double f;</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>register short *p,i;</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>/*</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>* This code is correct only when the code
+generator is</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>* run on a PDP-11 or VAX-11 since it assumes
+native</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>* floating point format is PDP-11
+format.</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>*/</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (argval != 4 &amp;&amp; argval !=
+8)</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fatal(&quot;bad fcon size&quot;);</small></p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>f = atof(str);</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>p = (short *) &amp;f;</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>i = *p++;</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (argval == 8) {</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+
+<p><small>fprintf(codefile,&quot;\t%o;%o;&quot;,i,*p++);</small></p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>i = *p++;</small></p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>}</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+
+<p><small>fprintf(codefile,&quot;\t%o;%o\n&quot;,i,*p++);</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>#ifdef REGVARS</small></p>
+
+<p><small>char Rstring[10];<br>
+full lbytes;<br>
+struct regadm {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>char *ra_str;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>long ra_off;</small></p>
+</td>
+</table>
+
+<p><small>} regadm[2];<br>
+int n_regvars;</small></p>
+
+<p><small>regscore(off,size,typ,score,totyp) long off;
+{</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="9" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>/*</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>* This function is full of magic
+constants.</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>* They are a result of
+experimentation.</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>*/</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (size != 2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>return(-1);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>score -= 1;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>/* allow for save/restore */</small></p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (off&gt;=0)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>score -= 2;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (typ==reg_pointer)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>score *= 17;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>else if (typ==reg_loop)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>score = 10*score+50;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%">
+
+<p><small>/* Guestimate */</small></p>
+</td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>else</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>score *= 10;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>return(score);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><small>/* 10 * estimated # of words of profit
+*/</small></p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="19%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>i_regsave() {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>Rstring[0] = 0;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>n_regvars=0;</small></p>
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>f_regsave() {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="9" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>register i;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (n_regvars==0 || lbytes==0) {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;mov r5,-(sp)\nmov
+sp,r5\n&quot;);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>if (lbytes == 2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;tst
+-(sp)\n&quot;);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>else if (lbytes!=0)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;sub
+$0%o,sp\n&quot;,lbytes);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>for (i=0;i&lt;n_regvars;i++)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;mov
+%s,-(sp)\n&quot;,regadm[i].ra_str);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>} else {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>if (lbytes&gt;6) {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;mov
+$0%o,r0\n&quot;,lbytes);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;jsr
+r5,PR%s\n&quot;,Rstring);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>} else {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;jsr
+r5,PR%d%s\n&quot;,lbytes,Rstring);</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>}</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>}</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>for (i=0;i&lt;n_regvars;i++)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>if (regadm[i].ra_off&gt;=0)</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;mov
+0%lo(r5),%s\n&quot;,regadm[i].ra_off,</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>regadm[i].ra_str);</small></p>
+</td>
+<td width="29%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>regsave(regstr,off,size) char *regstr; long off;
+{</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>fprintf(codefile,&quot;/ Local %ld into
+%s\n&quot;,off,regstr);</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>strcat(Rstring,regstr);</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>regadm[n_regvars].ra_str = regstr;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>regadm[n_regvars].ra_off = off;</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>n_regvars++;</small></p>
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>regreturn() {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>fprintf(codefile,&quot;jmp
+RT%s\n&quot;,Rstring);</small></p>
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>#endif</small></p>
+
+<p><small>prolog(nlocals) full nlocals; {</small></p>
+
+<p><small>#ifndef REGVARS</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;mov r5,-(sp)\nmov
+sp,r5\n&quot;);</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (nlocals == 0)</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>return;</small></p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>if (nlocals == 2)</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;tst
+-(sp)\n&quot;);</small></p>
+</td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>else</small></p>
+</td>
+<td width="10%"></td>
+<td width="69%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;sub
+$0%o,sp\n&quot;,nlocals);</small></p>
+</td>
+<td width="69%">
+</td>
+</table>
+
+<p><small>#else</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>lbytes = nlocals;</small></p>
+</td>
+</table>
+
+<p><small>#endif<br>
+}</small></p>
+
+<p><small>mes(type) word type; {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>int argt ;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>switch ( (int)type ) {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>case ms_ext :</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>for (;;) {</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>switch ( argt=getarg(</small></p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) )
+{</small></p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>case sp_cend :</small></p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>return ;</small></p>
+</td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>default:</small></p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>strarg(argt) ;</small></p>
+</td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>fprintf(codefile,&quot;.globl %s\n&quot;,argstr)
+;</small></p>
+</td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>break ;</small></p>
+</td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>}</small></p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>}</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>default :</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>while ( getarg(any_ptyp) != sp_cend )
+;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><small>break ;</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p><small>}</small></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+
+<p><small>}</small></p>
+
+<p><small>char *segname[] = {</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;.text&quot;, /* SEGTXT */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;.data&quot;, /* SEGCON */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;.data&quot;, /* SEGROM */</small></p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p><small>&quot;.bss&quot; /* SEGBSS */</small></p>
+</td>
+</table>
+
+<p><small>};</small></p>
+<a name="7. Internal workings of the code generator."></a>
+<h2>7. Internal workings of the code generator.</h2>
+<a name="7.1. Description of tables.c and tables.h contents"></a>
+<h2>7.1. Description of tables.c and tables.h contents</h2>
+
+<p><small>In this section the intermediate files will be
+described that are produced by <i>cgg</i> and compiled with
+machine independent code to produce a code
+generator.</small></p>
+<a name="7.1.1. Tables.c"></a>
+<h2>7.1.1. Tables.c</h2>
+
+<p><small>Tables.c contains a large number of initialized
+array&rsquo;s of all sorts. Description of each
+follows:</small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>byte coderules[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Pseudo code interpreted by the code generator.
+Always starts with some opcode followed by operands
+depending on the opcode. Some of the opcodes have an
+argument encoded in the upper three bits of the opcode byte.
+Integers in this table are between 0 and 32767 and have a
+one byte encoding if between 0 and 127.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>char wrd_fmt[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>The format used for output of
+words.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>char stregclass[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Number of computed static register class per
+register. Two registers are in the same class if they have
+the same properties and don&rsquo;t share a common
+subregister.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>struct reginfo machregs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Info per register. Initialized with representation
+string, size, members of the register and set of registers
+affected when this one is changed. Also contains room for
+run time information, like contents and reference
+count.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>tkdef_t tokens[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Information per tokentype. Initialized with size,
+cost, type of operands and formatstring.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>node_t enodes[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of triples representing expressions for the
+code generator.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>string codestrings[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of strings. All strings are put in a list and
+checked for duplication, so only one copy per string will
+reside here.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>set_t machsets[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of token expression sets. Bit 0 of the set is
+used for the SCRATCH property of registers, bit 1 upto NREG
+are for the corresponding registers and bit NREG+1 upto the
+end are for corresponding tokens.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>inst_t tokeninstances[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of descriptions for building tokens. Contains
+type of rule for building one, plus operands depending on
+the type.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>move_t moves[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of move rules. Contains token expressions for
+source and destination plus index for code
+rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>test_t tests[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of test rules. Contains token expressions for
+source plus index for code rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>byte pattern[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>EM patterns. This is structured internally as
+chains of patterns, each chain pointed at by pathash[].
+After each pattern the list of possible code rules is
+given.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>int pathash[256]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>Indices into pattern[] for all patterns with a
+certain low order byte of the hashing
+function.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>c1_t c1coercs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of rules to stack tokens. Contains token
+expressions, register needed, cost and code
+rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>c2_t c2coercs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of splitting coercions. Token expressions,
+split factor, replacements and code rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>c3_t c3coercs[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of one to one coercions. Token expressions,
+register needed, replacement and code rule.</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>struct reginfo **reglist[]</small></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p><small>List of lists of pointers to register information.
+For every property the list is here to find the registers
+corresponding to it.</small></p></td>
+</table>
+<a name="7.1.2. tables.h"></a>
+<h2>7.1.2. tables.h</h2>
+
+<p><small>In tables.h various derived constants for the
+tables are given. They are then used to determine array
+sizes in the actual code generator, plus loop termination in
+some cases.</small></p>
+<a name="7.2. Other important data structures"></a>
+<h2>7.2. Other important data structures</h2>
+
+<p><small>During code generation some other data structures
+are used and here is a short description of some of the
+important ones.</small></p>
+
+<p><small>Tokens are kept in the code generator as a struct
+consisting of one integer <i>t_token</i> which is -1 if the
+token is a register, and the number of the token otherwise,
+plus an array of <i>TOKENSIZE</i> unions <i>t_att</i> of
+which the first is the register number in case of a
+register.</small></p>
+
+<p><small>The fakestack is an array of these tokens, there
+is a global variable <i>stackheight</i>.</small></p>
+
+<p><small>The results of expressions are kept in a struct
+<i>result</i> with elements <i>e_typ</i>, giving the type of
+the expression: <i>EV_INT</i>, <i>EV_REG</i> or
+<i>EV_ADDR</i>, and a union <i>e_v</i> which contains the
+real result.</small></p>
+<a name="7.3. A tour through the sources"></a>
+<h2>7.3. A tour through the sources</h2>
+<a name="7.3.1. codegen.c"></a>
+<h2>7.3.1. codegen.c</h2>
+
+<p><small>The file codegen.c contains one large function
+consisting of one giant switch statement. It is the
+interpreter for the code generator pseudo code as contained
+in code rules[]. This function can call itself recursively
+when doing look ahead. Arguments are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p><small>codep</small></p>
+</td>
+<td width="10%"></td>
+<td width="80%">
+
+<p><small>Pointer into code rules, pseudo program
+counter.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>ply</small></p>
+</td>
+<td width="14%"></td>
+<td width="80%">
+
+<p><small>Number of EM pattern look ahead
+allowed.</small></p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>toplevel</small></p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p><small>Boolean telling whether this is the toplevel
+codegen() or a deeper incarnation.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>costlimit</small></p>
+</td>
+<td width="2%"></td>
+<td width="80%">
+
+<p><small>A cutoff value to limit searches. If the cost
+crosses costlimit the incarnation can terminate.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p><small>forced</small></p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p><small>A register number if nonzero. This is used inside
+coercions to force the allocate() call to allocate a
+register determined by earlier look ahead.</small></p>
+</td>
+</table>
+
+<p><small>The instructions inplemented in the
+switch:</small></p>
+<a name="7.3.1.1. DO_DLINE"></a>
+<h2>7.3.1.1. DO_DLINE</h2>
+
+<p><small>Prints debugging information if the code
+generator runs in debug mode. This information is only
+generated if <i>cgg</i> was called with the -d
+flag.</small></p>
+<a name="7.3.1.2. DO_NEXTEM"></a>
+<h2>7.3.1.2. DO_NEXTEM</h2>
+
+<p><small>Matches the next EM pattern and does look ahead
+if necessary to find the best code rule associated with this
+pattern. Heuristics are used to determine best code rule
+when possible. This is done by calling the distance()
+function. It can also handle the procedure
+mechanism.</small></p>
+<a name="7.3.1.3. DO_COERC"></a>
+<h2>7.3.1.3. DO_COERC</h2>
+
+<p><small>This sets the code generator in the state to do a
+from stack coercion.</small></p>
+<a name="7.3.1.4. DO_XMATCH"></a>
+<h2>7.3.1.4. DO_XMATCH</h2>
+
+<p><small>This is done when a match no longer has to be
+checked. Used when the nocoercions: trick is used in the
+table.</small></p>
+<a name="7.3.1.5. DO_MATCH"></a>
+<h2>7.3.1.5. DO_MATCH</h2>
+
+<p><small>This is the big one inside this function. It has
+the task to transform the contents of the current fake stack
+to match the pattern given after it.</small></p>
+
+<p><small>Since the code generator does not know combining
+coercions, i.e. there is no way to make a big token out of
+two smaller ones, the first thing done is to stack every
+token that is too small. After that all tokens too big are
+split if possible to the right size.</small></p>
+
+<p><small>Next the coercions are sought that would
+transform tokens in place to the right one, plus the
+coercions that would pop tokens of the stack. Each of those
+might need a register, so a list of registers is generated
+and at the end of looking for coercions the function
+<i>tuples()</i> is called to generate the list of all
+possible <i>n</i>-tuples, where <i>n</i> equals the number
+of registers needed.</small></p>
+
+<p><small>Look ahead is now performed if the number of
+tuples is greater than one. If no possibility is found
+within the costlimit, the fake stack is made smaller by
+pushing the bottom token, and this process is repeated until
+either a way is found or the fake stack is completely empty
+and there is still no way to make the match.</small></p>
+
+<p><small>If there is a way the corresponding coercions are
+executed and the code is finished.</small></p>
+<a name="7.3.1.6. DO_REMOVE"></a>
+<h2>7.3.1.6. DO_REMOVE</h2>
+
+<p><small>Here the kills clause is executed, all tokens
+matched by the token expression plus boolean expression are
+pushed. In the current implementation there is no attempt to
+move those tokens to registers, but that is a possible
+future extension.</small></p>
+<a name="7.3.1.7. DO_DEALLOCATE"></a>
+<h2>7.3.1.7. DO_DEALLOCATE</h2>
+
+<p><small>This one temporarily decrements by one the
+reference count of all registers contained in the token
+given as argument.</small></p>
+<a name="7.3.1.8. DO_REALLOCATE"></a>
+<h2>7.3.1.8. DO_REALLOCATE</h2>
+
+<p><small>Here all temporary deallocates are made
+undone.</small></p>
+<a name="7.3.1.9. DO_ALLOCATE"></a>
+<h2>7.3.1.9. DO_ALLOCATE</h2>
+
+<p><small>This is the part that allocates a register and
+decides which one to use. If the <i>forced</i> argument was
+given its task is simple, otherwise some work must be done.
+First the list of possible registers is scanned, all free
+registers noted and it is noted whether any of those
+registers is already containing the initialization. If no
+registers are available some fakestack token is stacked and
+the process is repeated.</small></p>
+
+<p><small>After that if an exact match was found, the list
+of registers is reduced to one register matching exactly out
+of every register class. Now look ahead is performed if
+necessary and the register chosen. If an initialization was
+given the corresponding move is performed, otherwise the
+register is marked empty.</small></p>
+<a name="7.3.1.10. DO_INSTR"></a>
+<h2>7.3.1.10. DO_INSTR</h2>
+
+<p><small>This prints an instruction and its operands. Only
+done on toplevel.</small></p>
+<a name="7.3.1.11. DO_MOVE"></a>
+<h2>7.3.1.11. DO_MOVE</h2>
+
+<p><small>Calls the move() function in the code generator
+to implement the move instruction in the table.</small></p>
+<a name="7.3.1.12. DO_TEST"></a>
+<h2>7.3.1.12. DO_TEST</h2>
+
+<p><small>Calls the test() function in the code generator
+to implement the test instruction in the table.</small></p>
+<a name="7.3.1.13. DO_ERASE"></a>
+<h2>7.3.1.13. DO_ERASE</h2>
+
+<p><small>Marks the register that is its argument as
+empty.</small></p>
+<a name="7.3.1.14. DO_TOKREPLACE"></a>
+<h2>7.3.1.14. DO_TOKREPLACE</h2>
+
+<p><small>This is the token replacement part. It is also
+called if there is no token replacement because it has some
+other functions as well.</small></p>
+
+<p><small>First the tokens that will be pushed on the fake
+stack are computed and stored in a temporary array. Then the
+tokens that were matched in this rule are popped and their
+embedded registers have their reference count decremented.
+After that the replacement tokens are pushed.</small></p>
+
+<p><small>Finally all registers allocated in this rule have
+their reference count decremented. If they were not pushed
+on the fake stack they will be available again in the next
+code rule.</small></p>
+<a name="7.3.1.15. DO_EMREPLACE"></a>
+<h2>7.3.1.15. DO_EMREPLACE</h2>
+
+<p><small>Places replacement EM instructions back into the
+instruction stream.</small></p>
+<a name="7.3.1.16. DO_COST"></a>
+<h2>7.3.1.16. DO_COST</h2>
+
+<p><small>Accounts for cost as given in the code
+rule.</small></p>
+<a name="7.3.1.17. DO_RETURN"></a>
+<h2>7.3.1.17. DO_RETURN</h2>
+
+<p><small>Returns from this level of codegen(). Is used at
+the end of coercions, move rules etc..</small></p>
+<a name="7.3.1.18. DO_LABDEF"></a>
+<h2>7.3.1.18. DO_LABDEF</h2>
+
+<p><small>This prints a label when the top element size
+mechanism is used. Only done on toplevel.</small></p>
+<a name="7.3.2. compute.c"></a>
+<h2>7.3.2. compute.c</h2>
+
+<p><small>This module computes the various expressions as
+given in the enodes[] array. Nothing very special happens
+here, it is just a recursive function computing leaves of
+expressions and applying the operator.</small></p>
+<a name="7.3.3. equiv.c"></a>
+<h2>7.3.3. equiv.c</h2>
+
+<p><small>In this module the tuples() function is
+implemented. It is given the number of registers needed and
+a list of register lists and it constructs a list of tuples
+where the <i>n</i>&rsquo;th register comes from the
+<i>n</i>&rsquo;th list. Before the list is constructed
+however the dynamic register classes are computed. Two
+registers are in the same dynamic class if they are in the
+same static class and their contents is the
+same.</small></p>
+
+<p><small>After that the permute() recursive function is
+called to generate the list of tuples. After construction a
+generated tuple is added to the list if it is not already
+pairwise in the same class or if the register relations are
+not the same, i.e. if the first and second register share a
+common subregister in one tuple and not in the other they
+are considered different.</small></p>
+<a name="7.3.4. fillem.c"></a>
+<h2>7.3.4. fillem.c</h2>
+
+<p><small>This is the routine that does the reading of EM
+instructions and the handling of pseudos. The mach.c module
+provided by the table writer is included at the end of this
+module. The routine fillemlines() is called by nextem() at
+toplevel to make sure there are enough instruction to match.
+It fills the EM instruction buffer up to 5 places from the
+end to keep room for EM replacement instructions, or up to a
+pseudo.</small></p>
+
+<p><small>The dopseudo() function performs the function of
+the pseudo last encountered. If the pseudo is a <b>rom</b>
+the corresponding label is saved with the contents of the
+<b>rom</b> to be available to the code generator later. The
+rest of the routines are small service routines for either
+input or data output.</small></p>
+<a name="7.3.5. gencode.c"></a>
+<h2>7.3.5. gencode.c</h2>
+
+<p><small>This module contains routines called by codegen()
+to generate the real code to the codefile. The function
+genstr() gets a string as argument and copies it to
+codefile. The prtoken() function interprets the tokenformat
+as given in the tokens[] array.</small></p>
+<a name="7.3.6. glosym.c"></a>
+<h2>7.3.6. glosym.c</h2>
+
+<p><small>This module maintains a list of global symbols
+that have a <b>rom</b> pseudo associated. There are
+functions to enter a symbol and to find a
+symbol.</small></p>
+<a name="7.3.7. label.c"></a>
+<h2>7.3.7. label.c</h2>
+
+<p><small>This module contains routines to handle the top
+element size messages.</small></p>
+<a name="7.3.8. main.c"></a>
+<h2>7.3.8. main.c</h2>
+
+<p><small>Main routine of the code generator. Processes
+arguments and flags. Flags available are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>-d</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Sets debug mode if the code generator was not
+compiled with the NDEBUG macro defined. The flag can be
+followed by a digit specifying the amount of debugging
+wanted, and by @labelname giving the start of debugging.
+Debug mode gives very long output on stderr indicating all
+steps of the code generation process including nesting of
+the codegen() function.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>-p<i>n</i></small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Sets the look ahead depth to <i>n</i>, the
+<i>p</i> stands for ply, a well known word in chess playing
+programs.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>-w<i>n</i></small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Sets the weight percentage for size in the cost
+function to <i>n</i> percent. Uses Euclides algorithm to
+simplify rationals.</small></p>
+</td>
+</table>
+<a name="7.3.9. move.c"></a>
+<h2>7.3.9. move.c</h2>
+
+<p><small>Function to implement the move instruction in the
+tables, register initialization and the test instruction and
+associated bookkeeping. First tests are made to try to
+prevent the move from really happening. After that, if there
+is an after that, the move rule is found and the code
+executed.</small></p>
+<a name="7.3.10. nextem.c"></a>
+<h2>7.3.10. nextem.c</h2>
+
+<p><small>The entry point of this module is nextem(). It
+hashes the next three EM instructions, and uses the low
+order byte of the hash as an index into the array pathash[],
+to find a chain of patterns in the array pattern[], that are
+all tried for a match.</small></p>
+
+<p><small>The function trypat() does most of the work
+checking patterns. When a pattern is found to match all
+instructions the operands of the instruction are placed into
+the dollar[] array. Then the boolean expression is tried. If
+it matches the function can return, leaving the operands
+still in the dollar[] array, so later in the code rule they
+can still be used.</small></p>
+<a name="7.3.11. reg.c"></a>
+<h2>7.3.11. reg.c</h2>
+
+<p><small>Collection of routines to handle registers.
+Reference count routines are here, chrefcount() and
+getrefcount(), plus routines to erase a single register or
+all of them, erasereg() and cleanregs().</small></p>
+
+<p><small>If NDEBUG hasn&rsquo;t been defined, here is also
+the routine that checks if the reference count kept with the
+register information is in agreement with the number of
+times it occurs on the fake stack.</small></p>
+<a name="7.3.12. salloc.c"></a>
+<h2>7.3.12. salloc.c</h2>
+
+<p><small>Module for string allocation and garbage
+collection. Contains entry points myalloc(), a routine
+calling malloc() and checking whether room is left,
+myfree(), just free(), popstr() a function called from
+state.c to free all strings made since the last saved
+status. Furthermore there is salloc() which has the size of
+the string as parameter and returns a pointer to the
+allocated space, while keeping a copy of the pointer for
+garbage allocation purposes.</small></p>
+
+<p><small>The function garbage_collect is called from
+codegen() at toplevel every now and then, and checks all
+places where strings may reside to mark strings as being in
+use. Strings not in use are returned to the pool of free
+space.</small></p>
+<a name="7.3.13. state.c"></a>
+<h2>7.3.13. state.c</h2>
+
+<p><small>Set of routines called to save current status and
+restore a previous saved state.</small></p>
+<a name="7.3.14. subr.c"></a>
+<h2>7.3.14. subr.c</h2>
+
+<p><small>Random set of leftover routines.</small></p>
+<a name="7.3.14.1. match"></a>
+<h2>7.3.14.1. match</h2>
+
+<p><small>Computes whether a certain token matches a
+certain token expression. Just computes a bitnumber
+according to the algorithm explained with machsets[], and
+tests the bit and the boolean expression if it is
+there.</small></p>
+<a name="7.3.14.2. instance,cinstance"></a>
+<h2>7.3.14.2. instance,cinstance</h2>
+
+<p><small>These two functions compute a token from a
+description. They differ very slight, cinstance() is used to
+compute the result of a coercion in a certain context and
+therefore has more arguments, which it uses instead of the
+global information instance() works on.</small></p>
+<a name="7.3.14.3. eqtoken"></a>
+<h2>7.3.14.3. eqtoken</h2>
+
+<p><small>eqtoken computes whether two tokens can be
+considered identical. Used to check register contents during
+moves mainly.</small></p>
+<a name="7.3.14.4. distance"></a>
+<h2>7.3.14.4. distance</h2>
+
+<p><small>This is the heuristic function that computes a
+distance from the current fake stack contents to the token
+pattern in the table. It likes exact matches most, then
+matches where at least the sizes are correct and if the
+sizes are not correct it likes too large sizes more than too
+small, since splitting a token is easier than combining
+one.</small></p>
+<a name="7.3.14.5. split"></a>
+<h2>7.3.14.5. split</h2>
+
+<p><small>This function tries to find a splitting coercion
+and executes it immediately when found. The fake stack is
+shuffled thoroughly when this happens, so pieces below the
+token that must be split are saved first.</small></p>
+<a name="7.3.14.6. docoerc"></a>
+<h2>7.3.14.6. docoerc</h2>
+
+<p><small>This function executes a coercion that was found.
+The same shuffling is done, so the top of the stack is again
+saved.</small></p>
+<a name="7.3.14.7. stackupto"></a>
+<h2>7.3.14.7. stackupto</h2>
+
+<p><small>This function gets a pointer into the fake stack
+and must stack every token including the one pointed at up
+to the bottom of the fake stack. The first stacking rule
+possible is used, so rules using registers must come
+first.</small></p>
+<a name="7.3.14.8. findcoerc"></a>
+<h2>7.3.14.8. findcoerc</h2>
+
+<p><small>Looks for a one to one coercion, if found it
+returns a pointer to it and leaves a list of possible
+registers to use in the global variable curreglist. This is
+used by codegen().</small></p>
+<a name="7.3.15. var.c"></a>
+<h2>7.3.15. var.c</h2>
+
+<p><small>Global variables used by more than one module.
+External definitions are in extern.h.</small></p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/ncg.pdf b/src/olddocs/ncg.pdf
new file mode 100644 (file)
index 0000000..826a805
Binary files /dev/null and b/src/olddocs/ncg.pdf differ
diff --git a/src/olddocs/nopt.html b/src/olddocs/nopt.html
new file mode 100644 (file)
index 0000000..0f2e172
--- /dev/null
@@ -0,0 +1,1527 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:36 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>A Tour of the New Peephole Optimizer</title>
+</head>
+<body>
+
+<h1 align=center>A Tour of the New Peephole Optimizer</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The optimization table">2. The optimization table</a><br>
+<a href="#3. Incompatibilities with Previous Optimizer">3. Incompatibilities with Previous Optimizer</a><br>
+<a href="#4. The Parser">4. The Parser</a><br>
+<a href="#5. Structure of the Resulting Library">5. Structure of the Resulting Library</a><br>
+<a href="#6. Miscellaneous Issues">6. Miscellaneous Issues</a><br>
+
+<hr>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>The peephole optimizer consists of four major parts:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>a)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>the table describing the optimization to be
+performed</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>b)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>a program to parse these tables and build input and
+output routines to interface to the library and a dfa based
+routine to recognize patterns and make the requested
+replacements.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>c)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>common routines for the library that are independent of
+the table of a)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>d)</p>
+</td>
+<td width="6%"></td>
+<td width="78%">
+
+<p>a stand alone version of the optimizer.</p>
+</td>
+<td width="11%">
+</td>
+</table>
+
+<p>The library conforms to the <i>EM_CODE(3)</i> module
+interface but with routine names of the form
+<b><i>C_</i></b>xxx replaced by names like
+<b><i>O_</i></b>xxx. Furthermore there is also no routine
+<i>O_getid</i> and no variable <i>O_tmpdir</i> in the
+module. The library module results in calls to the usual
+<i>EM_CODE(3)</i> module. It is possible to write a front
+end so that it can call either the normal <i>EM_CODE(3)</i>
+module or this new module by adding <b>#define PEEPHOLE</b>
+before the line <b>#include &lt;em.h&gt;</b> This will map
+all calls to the routine <b><i>C_</i></b>xxx into a call to
+the routine <b><i>O_</i></b>xxx.</p>
+
+<p>We shall now describe each of these major parts in some
+detail.</p>
+<a name="2. The optimization table"></a>
+<h2>2. The optimization table</h2>
+
+<p>The file <i>patterns</i> contains the patterns of EM
+instructions to be recognized by the optimizer and the EM
+instructions to replace them. Each pattern may have an
+optional restriction that must be satisfied before the
+replacement is made. The syntax of the table will be
+described using extended BNF notation used by <i>LLGen</i>
+where:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>[...]</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>- are used to group items<br>
+|</i></p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>- is used to separate alternatives<br>
+;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>- terminates a rule<br>
+?</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>- indicates item is optional<br>
+*</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>- indicates item is repeated zero or more times<br>
++</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>- indicates item is repeated one or more
+times</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+
+<p>The format of each rule in the table is:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>rule</i></p>
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>: pattern global_restriction? &rsquo;:&rsquo;
+replacement</i></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="59%">
+</td>
+</table>
+
+<p>Each rule must be on a single line except that it may be
+broken after the colon if the next line begins with a tab
+character. The pattern has the syntax:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>pattern</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: [ EM_mnem [ local_restriction ]? ]+</i></p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>;<br>
+EM-mnem : &quot;An EM instruction mnemonic&quot;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>| &rsquo;lab&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+
+<p>and consists of a sequence of one or more EM
+instructions or <i>lab</i> which stands for a defined
+instruction label. Each EM-mnem may optionally be followed
+by a local restriction on the argument of the mnemonic and
+take one of the following forms depending on the type of the
+EM instruction it follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>local_restriction</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: normal_restriction</i></p>
+</td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| opt_arg_restriction</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| ext_arg_restriction</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+</table>
+
+<p>A normal restriction is used after all types of EM
+instruction except for those that allow an optional
+argument, (such as <i>adi</i> ) or those involving external
+names, (such as <i>lae</i> ) and takes the form:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>normal_restriction</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: [ rel_op ]? expression</i></p>
+</td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;<br>
+rel_op</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: &rsquo;==&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>| &rsquo;!=&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>| &rsquo;&lt;=&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>| &rsquo;&lt;&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>| &rsquo;&gt;=&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>| &rsquo;&gt;&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+</table>
+
+<p>If the rel_op is missing, the equality <i>==</i>
+operator is assumed. The general form of expression is
+defined later but basically it involves simple constants,
+references to EM_mnem arguments that appear earlier in the
+pattern and expressions similar to those used in C
+expressions.</p>
+
+<p>The form of the restriction after those EM instructions
+like <i>adi</i> whose arguments are optional takes the
+form:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>opt_arg_restriction</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: normal_restriction</i></p>
+</td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;defined&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;undefined&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+</table>
+
+<p>The <i>defined</i> and <i>undefined</i> indicate that
+the argument is present or absent respectively. The normal
+restriction form implies that the argument is present and
+satisfies the restriction.</p>
+
+<p>The form of the restriction after those EM instructions
+like <i>lae</i> whose arguments refer to external object
+take the form:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>ext_arg_restriction</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: patarg offset_part?</i></p>
+</td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;<br>
+offset_part</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>: [ &rsquo;+&rsquo; | &rsquo;-&rsquo; ]
+expression</i></p>
+</td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+</table>
+
+<p>Such an argument has one of three forms: a offset with
+no name, an offset form a name or an offset from a label.
+With no offset part the restriction requires the argument to
+be identical to a previous external argument. With an offset
+part it requires an identical name part, (either empty, same
+name or same label) and supplies a relationship among the
+offset parts. It is possible to refer to test for the same
+external argument, the same name or to obtain the offset
+part of an external argument using the <i>sameext</i> ,
+<i>samenam</i> and <i>offset</i> functions given below.</p>
+
+<p>The general form of an expression is:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="6" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>expression</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: expression binop expression</i></p>
+</td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| unaryop expression</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;(&rsquo; expression &rsquo;)&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| bin_function &rsquo;(&rsquo; expression
+&rsquo;,&rsquo; expression &rsquo;)&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| ext_function &rsquo;(&rsquo; patarg &rsquo;,&rsquo;
+patarg &rsquo;)&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;offset&rsquo; &rsquo;(&rsquo; patarg
+&rsquo;)&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| patarg</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;p&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;w2&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;w&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| INTEGER</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="6" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>bin_function</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: &rsquo;sfit&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;ufit&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;samesign&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;rotate&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="6" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>ext_function</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: &rsquo;samenam&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>| &rsquo;sameext&rsquo;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;<br>
+patarg</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>: &rsquo;$&rsquo; INTEGER</i></p>
+</td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;<br>
+binop</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>: &quot;As for C language&quot;<br>
+unaryop</i></p>
+</td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>: &quot;As for C language&quot;</i></p>
+</td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+</table>
+
+<p>The INTEGER in the <i>patarg</i> refers to the first,
+second, etc. argument in the pattern and it is required to
+refer to a pattern that appears earlier in the pattern The
+<i>w</i> and <i>p</i> refer to the word size and pointer
+size (in bytes) respectively. The <i>w2</i> refers to twice
+the word size. The various function test for:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>sfit</p>
+</td>
+<td width="12%"></td>
+<td width="80%">
+
+<p>the first argument fits as a signed value of the number
+of bit specified by the second argument.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>ufit</p>
+</td>
+<td width="12%"></td>
+<td width="72%">
+
+<p>as for sfit but for unsigned values.</p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>samesign</p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p>the first argument has the same sign as the second.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>rotate</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>the value of the first argument rotated by the number of
+bit specified by the second argument.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>samenam</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>both arguments refer to externals and have either no
+name, the same name or same label.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>sameext</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>both arguments refer to the same external.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>offset</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>the argument is an external and this yields it offset
+part.</p>
+</td>
+</table>
+
+<p>The global restriction takes the form:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>global_restriction</i></p>
+<td width="19%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+
+<p><i>: &rsquo;?&rsquo; expression</i></p>
+</td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><i>;</i></p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="29%">
+</td>
+</table>
+
+<p>and is used to express restrictions that cannot be
+expressed as simple restrictions on a single argument or are
+can be expressed in a more readable fashion as a global
+restriction. An example of such a rule is:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>dup w ldl stf ? p==2*w : ldl $2 stf $3 ldl $2 lof
+$3</i></p>
+</table>
+
+<p>which says that this rule only applies if the pointer
+size is twice the word size.</p>
+<a name="3. Incompatibilities with Previous Optimizer"></a>
+<h2>3. Incompatibilities with Previous Optimizer</h2>
+
+<p>The current table format is not compatible with previous
+versions of the peephole optimizer tables. In particular the
+previous table had no provision for local restrictions and
+only the equivalent of the global restriction. This meant
+that our <i>&rsquo;?&rsquo;</i> character that announces the
+presence of the optional global restriction was not
+required. The previous optimizer performed a number of other
+tasks that were unrelated to optimization that were possible
+because the old optimizer read the EM code for a complete
+procedure at a time. This included tasks such as register
+variable reference counting and moving the information
+regarding the number of bytes of local storage required by a
+procedure from it <i>end</i> pseudo instruction to
+it&rsquo;s <i>pro</i> pseudo instruction. These tasks are no
+longer done by this module but have been moved to other
+modules or programs in the pipeline. The register variable
+reference counting is now performed by the front end. The
+reordering of code, such as the moving of mes instructions
+and the local storage requirements from the end to beginning
+of procedures, is now performed using the insertpart
+mechanism in the <i>EM_CODE</i> (or <i>EM_OPT</i> ) module.
+The removal of dead code is performed by the global
+optimizer. Various <i>ext_functions</i> available in the old
+tables are no longer available as they rely on information
+that is not available to the current program. These are the
+<i>notreg</i> and the <i>rom</i> functions. The previous
+optimizer allowed the use of <i>LLP, LEP, SLP</i> and
+<i>SEP</i> in patterns. For example <i>LLP</i> stood for
+either <i>lol</i> if the pointer size was the same as the
+word size, or for <i>ldl</i> if the pointer size was twice
+the word size. In the current optimizer it is necessary to
+include two patterns for each such single pattern in the old
+table. For example for a pattern containing <i>LLP</i> there
+would be one pattern with <i>lol</i> and with a global
+restriction of the form <i>p=w</i> and another pattern with
+ldl and a global restriction of the form <i>p=2*w.</i></p>
+<a name="4. The Parser"></a>
+<h2>4. The Parser</h2>
+
+<p>The program to parse the tables and build the pattern
+table dependent dfa routines is built from the files:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>parser.h</p>
+</td>
+<td width="14%"></td>
+<td width="22%">
+
+<p>header file</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>parser.g</p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>LLGen source file defining syntax of table</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>syntax.l</p>
+</td>
+<td width="14%"></td>
+<td width="70%">
+
+<p>Lex sources file defining form of tokens in table.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>initlex.c</p>
+</td>
+<td width="12%"></td>
+<td width="70%">
+
+<p>Uses the data in the library <i>em_data.a</i> to
+initialize the lexical analyzer to recognize EM instruction
+mnemonics.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>outputdfa.c</p>
+</td>
+<td width="8%"></td>
+<td width="70%">
+
+<p>Routines to output the dfa when it has been constructed.
+It outputs the files <i>dfa.c</i> and <i>trans.c</i></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>outcalls.c</p>
+</td>
+<td width="10%"></td>
+<td width="70%">
+
+<p>Routines to output the file <i>incalls.r</i> defined in
+the next section.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p>findworst.c</p>
+</td>
+<td width="8%"></td>
+<td width="70%">
+
+<p>Routines to analyze patterns to find how to continue
+matching after a successful replacement or failed match.</p>
+</td>
+</table>
+
+<p>The parser checks that the tables conform to the syntax
+outlined in the previous section and also makes a number of
+semantic checks on their validity. Further versions could
+make further checks such as looking for cycles in the rules
+or checking that each replacement leaves the same number of
+bytes on the stack as the pattern it replaces. The parser
+builds an internal dfa representation of the rules by
+combining rules with common prefixes. All local and global
+restrictions are combined into a single test to be performed
+are a complete pattern has been detected in the input. The
+idea is to build a structure so that each of the patterns
+can be matched and then the corresponding tests made and the
+first that succeeds is replaced. If two rules have the same
+pattern and both their tests also succeed the one that
+appears first in the tables file will be done. Somewhat less
+obvious is that if one pattern is a proper prefix of a
+longer pattern and its test succeeds then the second pattern
+will not be checked for.</p>
+
+<p>A major task of the parser if to decide on the action to
+take when a rule has been partially matched or when a
+pattern has been completely matched but its test does not
+succeed. This requires a search of all patterns to see if
+any part of the part matched could be part of some other
+pattern. for example given the two patterns:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>loc adi w loc adi w : loc $1+$3 adi w<br>
+loc adi w loc sbi w : loc $1-$3 adi w</i></p>
+</table>
+
+<p>If the first pattern fails after seeing the input:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>loc adi loc</i></p>
+</table>
+
+<p>the parser will still need to check whether the second
+pattern matches. This requires a decision on how to fix up
+any internal data structures in the dfa matcher, such as
+moving some instructions from the pattern to the output
+queue and moving the pattern along and then deciding what
+state it should continue from. Similar decisions are
+requires after a pattern has been replaced. For example if
+the replacement is empty it is necessary to backup
+<i>n-1</i> instructions where <i>n</i> is the length of the
+longest pattern in the tables.</p>
+<a name="5. Structure of the Resulting Library"></a>
+<h2>5. Structure of the Resulting Library</h2>
+
+<p>The major data structures maintained by the library
+consist of three queues; an <i>output</i> queue of
+instructions awaiting output, a <i>pattern</i> queue
+containing instructions that match the current prefix, and a
+<i>backup</i> queue of instructions that have been backed up
+over and need to be reparsed for further pattern matches.
+These three queues are maintained in a single fixed size
+buffer as explained in more detail in the next section.
+Also, after a successful match, a replacement queue is
+constructed.</p>
+
+<p>If no errors are detected by the parser in the tables it
+output the following files if they have changed from the
+existing version of the file:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>dfa.c</p>
+</td>
+<td width="10%"></td>
+<td width="80%">
+
+<p>this contains the dfa encoded into a number of arrays
+using the technique of row displacement for compacted sparse
+matricies. Given an opcode and the current state, the value
+of <i>OO_base[OO_state]</i> is consulted to obtain a pointer
+into the array <i>OO_checknext.</i> If this pointer in zero
+or the <i>check</i> field of the addressed structure does
+not correspond to the curerent state then it is known there
+is no entry for this opcode/state pair and the
+<i>OO_default</i> array is consulted instead. If the check
+field does match then the <i>next</i> field contains the new
+state. After each transition the array <i>OO_ftrans</i> is
+consulted to see if this state corresponds to a final state
+(i.e. a complete pattern) and if so the corresponding
+function is called.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p>trans.c</p>
+</td>
+<td width="6%"></td>
+<td width="80%">
+
+<p>this contains external declarations of transition
+routines with names like <b>OO_xxxdotrans</b> (where
+<i>xxx</i> is a small integer). These are called when there
+a transition to state <i>xxx</i> that corresponds to a
+complete pattern. Any tests are performed if necessary to
+confirm that the pattern matches and then the replacement
+instructions are placed on the output queue and the routine
+<i>OO_mkrepl</i> is called to make the replacement and if
+backup the amount required. If there are a number of
+patterns with the same instructions but different tests,
+these will all appear in the same routine and the tests
+performed in the order they appear in the original
+<i>patterns</i> file.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>incalls.r</p>
+</td>
+<td width="2%"></td>
+<td width="80%">
+
+<p>this contains an entry for every EM instruction (plus
+<i>lab</i> ) giving information on how to build a routine
+with the name <b><i>O_</i></b>xxx for the library version of
+the module. If the EM instruction does not appear in the
+tables patterns at all then the dfa routine is called to
+flush any current queued output and the the output
+<b><i>C_</i></b>xxx routine is called. If the EM instruction
+does appear in a pattern then the instruction data structure
+fields are initialized and it is added onto the end of the
+pattern queue. The dfa routines are then called to attempted
+to make a transition. This file is input to the <i>awk</i>
+program <i>makefuns.awk.</i></p>
+</td>
+</table>
+
+<p>The following files contain code that is independent of
+the pattern tables:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>main.c</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>this is used only in the stand alone version of the
+optimizer and consists of code to open the input file, read
+the input using the <i>READ_EM(3)</i> module and call the
+dfa routines. This version does not require the routines
+constructed from the incalls.r file described above.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>nopt.c</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>general routines to initialize, and maintain the data
+structures. The file handling routines <i>O_open</i> etc are
+defined here. Also defined are routines for flushing the
+output queue by calling the <i>EM_mkcalls</i> routine from
+the <i>READ_EM(3)</i> module and moving instructions from
+the output to the backup queue. Routines to free the strings
+stored in instructions with types of <i>sof_ptyp, pro_ptyp,
+str_ptyp, ico_ptyp, uco_ptyp,</i> and also<i>fco_ptyp</i>are
+is extended by <i>Realloc</i> if it overflows. The strings
+can be thrown away on any flush that occurs when the backup
+queue is empty.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p>mkstrct.c</p>
+</td>
+<td width="2%"></td>
+<td width="80%">
+
+<p>contains routines to build the data structure from the
+input <b><i>C_</i></b>xxx routines and place the structure
+on the pattern queue. These routines are also used to build
+the data structures when a replacement is constructed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>aux.c</p>
+</td>
+<td width="10%"></td>
+<td width="80%">
+
+<p>routines to implement the external functions used in the
+pattern table.</p>
+</td>
+</table>
+
+<p>The following files are also used in building the module
+library:</p>
+
+<p>makefuns.awk</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="80%">
+<p>this <i>awk</i> program is used to produce individual C
+files with names like <b><i>O_</i></b>xxx.c each containing
+a single function definition and then call the <i>cc</i>
+compiler to produce a single output file. This enables the
+loader to only load those routines that are actually needed
+when the library is loaded.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p>pseudo.r</p>
+</td>
+<td width="4%"></td>
+<td width="80%">
+
+<p>this file is like the <i>incalls.r</i> file produced by
+the parser but is built by hand and handles the pseudo EM
+instructions. It is also processed by
+<i>makefuns.awk.</i></p>
+</td>
+</table>
+<a name="6. Miscellaneous Issues"></a>
+<h2>6. Miscellaneous Issues</h2>
+
+<p>The output, pattern and backup queues are maintained in
+fixed length array, <i>OO_buffer</i> allocated of size
+<i>MAXBUFFER</i> (a constant declared in nopt.h) at run
+time. It consists of an array of the <i>e_instr</i> data
+structure used by the <i>READ_EM(3)</i> module. At any time
+the pointers <i>OO_patternqueue</i> and <i>OO_nxtpatt</i>
+point to the beginning and end of the current pattern prefix
+that corresponds to the current state. Any instructions on
+the backup queue are between <i>OO_nxtpatt</i> and
+<i>OO_endbackup.</i> If there are no instructions on the
+backup queue then <i>OO_endbackup</i> will be 0 (zero). The
+size of the replacement queue is set to the length of the
+maximum replacement length by the tables output by the
+parser.</p>
+
+<p>The fixed size of the buffer causes no difficulty in
+practice and can only result in some potential optimizations
+being missed. When space for a new instruction is required
+and the buffer is full the routine <i>OO_halfflush</i> is
+called to flush half the buffer and move all the data
+structures left. It should be noted that it is not possible
+to statically determine the maximum possible size for these
+queues as they need to be unbounded in the worst case. A
+study of the rule</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p><i>inc dec :</i></p>
+</table>
+
+<p>with the input consisting of <i>N inc</i> and then <i>N
+dec</i> instructions requires an output queue length of
+<i>N-1</i> to find all possible replacements.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/nopt.pdf b/src/olddocs/nopt.pdf
new file mode 100644 (file)
index 0000000..9737f66
Binary files /dev/null and b/src/olddocs/nopt.pdf differ
diff --git a/src/olddocs/occam.html b/src/olddocs/occam.html
new file mode 100644 (file)
index 0000000..51627c7
--- /dev/null
@@ -0,0 +1,445 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:31 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>An Occam Compiler</title>
+</head>
+<body>
+
+<h1 align=center>An Occam Compiler</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The Compiler">2. The Compiler</a><br>
+<a href="#2.1. The LLgen Parser Generator">2.1. The LLgen Parser Generator</a><br>
+<a href="#2.2. Indentation">2.2. Indentation</a><br>
+<a href="#3. Implementation">3. Implementation</a><br>
+<a href="#3.1. Channels">3.1. Channels</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Kees Bot<br>
+Edwin Scheffer</i><br>
+Vrije Universiteit<br>
+Amsterdam, The Netherlands</p>
+
+<p>This document describes the implementation of an
+<b>Occam</b> to <b>EM</b> compiler. The lexical analysis is
+done using <b>Lex</b>. For the semantic analysis the
+extended LL(1) parser generator <b>LLgen</b> is used. To
+handle the Occam-specific features as channels and
+parallelism some library routines are required.</p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>Occam [1] is a programming language which is based on
+the concepts of concurrency and communication. These
+concepts enable today&rsquo;s applications of
+microprocessors and computers to be implemented more
+effectively.</p>
+
+<p>An Occam program consists of a (dynamically determined)
+number of processes communicating through channels. To
+communicate with the outside world some predefined channels
+are needed. A channel has only one writer and one reader; it
+carries machine words and bytes, at the
+reader/writer&rsquo;s discretion. The process with its
+communication in Occam replaces the procedure with
+parameters in other languages (there are no procedures in
+Occam).</p>
+
+<p>In addition to the normal assignment statement, Occam
+has two more information-transfer statements, the input and
+the output:</p>
+<pre>          chan1 ? x        -- reads a value from chan1 into x
+          chan2 ! x        -- writes the value of x onto chan2
+</pre>
+
+<p>Both the outputting and the inputting processes wait
+until the other is there. Channels are declared and given
+names.</p>
+
+<p><b>2</b></p>
+
+<p>Arrays of channels are possible.</p>
+
+<p>Processes come in 5 varieties: sequential, parallel,
+alternative, conditional and repetitive. A process starts
+with a reserved word telling its nature, followed by an
+indented list of other processes. (Indentation is used to
+indicate block structure.) It may be preceded by
+declarations. The processes in a sequential/parallel process
+are executed sequentially/in parallel. The processes in an
+alternative process have guards based on the availability of
+input; the first to be ready is executed (this is waiting
+for multiple input). The conditional and repetitive
+processes are normal <b>IF</b>s and <b>WHILE</b>s.</p>
+
+<p><i>Producer-consumer example:</i></p>
+<pre>     CHAN buffer:                    -- declares the channel buffer
+     PAR
+       WHILE TRUE                    -- the producer
+         VAR x:                      -- a local variable
+         SEQ
+           produce(x)                -- in some way
+           buffer ! x                -- and send it
+       WHILE TRUE                    -- the consumer
+         VAR x:
+         SEQ
+           buffer ? x                -- get a value
+           consume(x)                -- in some way
+</pre>
+
+<p><b>3</b></p>
+
+<p>Processes can be replicated from a given template; this
+combines with arrays of variables and/or channels.</p>
+
+<p><i>Example: 20 window-sorters in series:</i></p>
+<pre>     CHAN s[20]:                     -- 20 channels
+     PAR i = [ 0 FOR 19 ]            -- 19 processes
+       WHILE TRUE
+         VAR v1, v2:
+         SEQ
+           s[i] ? v1; v2             -- wait for 2 variables from s[i]
+           IF
+             v1 &lt;= v2                -- ok
+               s[i+1] ! v1; v2
+             v1 &gt; v2                 -- reorder
+               s[i+1] ! v2; v1
+</pre>
+
+<p>A process may wait for a condition, which must include a
+comparison with <b>NOW</b>, the present clock value.</p>
+
+<p>Processes may be distributed over several processors;
+all processes under a <b>VAR</b> declaration must run on the
+same processor. Concurrency can be improved by avoiding
+<b>VAR</b> declarations, and replacing them by <b>CHAN</b>
+declarations. Processes can be allocated explicitly on named
+processors and channels can be connected to physical
+ports.</p>
+<a name="2. The Compiler"></a>
+<h2>2. The Compiler</h2>
+
+<p>The compiler is written in <b>C</b> using LLgen and Lex
+and compiles Occam programs to EM code, using the procedural
+interface as defined for EM. In the following sub-sections
+we describe the LLgen parser generator and the aspect of
+indentation.</p>
+<a name="2.1. The LLgen Parser Generator"></a>
+<h2>2.1. The LLgen Parser Generator</h2>
+
+<p>LLgen accepts a Context Free syntax extended with the
+operators &lsquo;<tt>*</tt>&rsquo;, &lsquo;<tt>?</tt>&rsquo;
+and &lsquo;<tt>+</tt>&rsquo; that have effects similar to
+those in regular expressions. The &lsquo;<tt>*</tt>&rsquo;
+is the closure set operator without an upperbound;
+&lsquo;<tt>+</tt>&rsquo; is the positive closure operator
+without an upperbound; &lsquo;<tt>?</tt>&rsquo; is the
+optional operator; &lsquo;<tt>[</tt>&rsquo; and
+&lsquo;<tt>]</tt>&rsquo; can be used for grouping. For
+example, a comma-separated list of expressions can be</p>
+
+<p><b>4</b></p>
+
+<p>described as:</p>
+<pre>          expression_list:
+                 expression [ &rsquo;,&rsquo; expression ]*
+               ;
+</pre>
+
+<p>Alternatives must be separated by
+&lsquo;<tt>|</tt>&rsquo;. C code
+(&lsquo;&lsquo;actions&rsquo;&rsquo;) can be inserted at all
+points between the colon and the semicolon. Variables global
+to the complete rule can be declared just in front of the
+colon enclosed in the brackets &lsquo;<tt>{</tt>&rsquo; and
+&lsquo;<tt>}</tt>&rsquo;. All other declarations are local
+to their actions. Nonterminals can have parameters to pass
+information. A more mature version of the above example
+would be:</p>
+<pre>            expression_list(expr *e;)       {     expr e1, e2;   } :
+                     expression(&amp;e1)
+                     [ &rsquo;,&rsquo; expression(&amp;e2)
+                                            {     e1=append(e1, e2);  }
+                     ]*
+                                            {     *e=e1;    }
+                   ;
+</pre>
+
+<p>As LLgen generates a recursive-descent parser with no
+backtrack, it must at all times be able to determine what to
+do, based on the current input symbol. Unfortunately, this
+cannot be done for all grammars. Two kinds of conflicts are
+possible, viz. the <b>alternation</b> and <b>repetition</b>
+conflict. An alternation confict arises if two sides of an
+alternation can start with the same symbol. E.g.</p>
+
+<p><b>5</b></p>
+<pre>          plus:     &rsquo;+&rsquo; | &rsquo;+&rsquo; ;
+</pre>
+
+<p>The parser doesn&rsquo;t know which
+&lsquo;<tt>+</tt>&rsquo; to choose (neither do we). Such a
+conflict can be resolved by putting an <b>if-condition</b>
+in front of the first conflicting production. It consists of
+a <b>&lsquo;&lsquo;%if&rsquo;&rsquo;</b> followed by a
+C-expression between parentheses. If a conflict occurs (and
+only if it does) the C-expression is evaluated and parsing
+continues along this path if non-zero. Example:</p>
+<pre>          plus:
+                 %if (some_plusses_are_more_equal_than_others())
+                 &rsquo;+&rsquo;
+               |
+                 &rsquo;+&rsquo;
+               ;
+</pre>
+
+<p>A repetition conflict arises when the parser cannot
+decide whether
+&lsquo;&lsquo;<tt>productionrule</tt>&rsquo;&rsquo; in e.g.
+&lsquo;&lsquo;<tt>[ productionrule ]*</tt>&rsquo;&rsquo;
+must be chosen once more, or that it should continue. This
+kind of conflicts can be resolved by putting a
+<b>while-condition</b> right after the opening parentheses.
+It consists of a <b>&lsquo;&lsquo;%while&rsquo;&rsquo;</b>
+followed by a C-expression between parentheses. As an
+example, we can look at the <b>comma-expression</b> in C.
+The comma may only be used for the comma-expression if the
+total expression is not part of another comma-separated
+list:</p>
+<pre>          comma_expression:
+                 sub_expression
+                 [ %while (not_part_of_comma_separated_list())
+                      &rsquo;,&rsquo; sub_expression
+                 ]*
+</pre>
+
+<p><b>6</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p><tt>;</tt></p>
+</td>
+<td width="69%">
+</td>
+</table>
+
+<p>Again, the <b>&lsquo;&lsquo;%while&rsquo;&rsquo;</b> is
+only used in case of a conflict.</p>
+
+<p>Error recovery is done almost completely automatically.
+All the LLgen-user has to do is write a routine called
+<i>LLmessage</i> to give the necessary error messages and
+supply information about terminals found missing.</p>
+<a name="2.2. Indentation"></a>
+<h2>2.2. Indentation</h2>
+
+<p>The way conflicts can be resolved are of great use to
+Occam. The use of indentation, to group statements, leads to
+many conflicts because the spaces used for indentation are
+just token separators to the lexical analyzer, i.e.
+&lsquo;&lsquo;white space&rsquo;&rsquo;. The lexical
+analyzer can be instructed to generate &lsquo;BEGIN&rsquo;
+and &lsquo;END&rsquo; tokens at each indentation change, but
+that leads to great difficulties as expressions may occupy
+several lines, thus leading to indentation changes at the
+strangest moments. So we decided to resolve the conflicts by
+looking at the indentation ourselves. The lexical analyzer
+puts the current indentation level in the global variable
+<i>ind</i> for use by the parser. The best example is the
+<b>SEQ</b> construct, which exists in two flavors, one with
+a replicator and one process:</p>
+<pre>          seq i = [ 1 for str[byte 0] ]
+               out ! str[byte i]
+</pre>
+
+<p>and one without a replicator and several processes:</p>
+<pre>          seq
+               in ? c
+               out ! c
+</pre>
+
+<p><b>7</b></p>
+
+<p>The LLgen skeleton grammar to handle these two is:</p>
+<pre>          SEQ            {    line=yylineno; oind=ind; }
+          [      %if (line==yylineno)
+                 replicator
+                 process
+               |
+                 [ %while (ind&gt;oind) process ]*
+          ]
+</pre>
+
+<p>This shows clearly that, a replicator must be on the
+same line as the <b>SEQ</b>, and new processes are collected
+as long as the indentation level of each process is greater
+than the indentation level of <b>SEQ</b> (with appropriate
+checks on this identation).</p>
+
+<p>Different indentation styles are accepted, as long as
+the same amount of spaces is used for each indentation
+shift. The ascii tab character sets the indentation level to
+an eight space boundary. The first indentation level found
+in a file is used to compare all other indentation levels
+to.</p>
+<a name="3. Implementation"></a>
+<h2>3. Implementation</h2>
+
+<p>It is now time to describe the implementation of some of
+the occam-specific features such as channels and <b>NOW</b>.
+Also the way communication with UNIX&dagger; is performed
+must be described.</p>
+
+<p align=center><img src="grohtml-106061.png"></p>
+
+<p>For a thorough description of the library routines to
+simulate parallelism, which are e.g. used by the channel
+routines and by the <b>PAR</b> construct in Appendix B, see
+[6].</p>
+<a name="3.1. Channels"></a>
+<h2>3.1. Channels</h2>
+
+<p>There are currently two types of channels (see Figure
+1.) indicated by the type field of a channel variable:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>An interprocess communication channel with two
+additional fields:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>A synchronization field to hold the state of an
+interprocess communication channel.</p>
+</td>
+</table>
+
+<p><b>8</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>An integer variable to hold the value to be send.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p>An outside world communication channel. This is a member
+of an array of channels connected to UNIX files. Its
+additional fields are:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>A flags field holding a readahead flag and a flag that
+tells if this channel variable is currently connected to a
+file.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>A preread character, if readahead is done.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="8%"></td>
+<td width="80%">
+
+<p>An index field to find the corresponding UNIX file.</p>
+</td>
+</table>
+
+<p align=center><img src="grohtml-106062.png"></p>
+
+<p align=center><i>Figure 1. Interprocess and outside world
+communication channels</i></p>
+
+<p>The basic channel handling is done by <tt>chan_in</tt>
+and <tt>chan_out</tt>. All other routines are based on them.
+The routine <tt>chan_any</tt> only checks if there&rsquo;s a
+value available on a given channel. (It does not read this
+value!) <tt>C_init</tt> initializes an array of interprocess
+communication channels.</p>
+
+<p><b>9</b></p>
+
+<p>The following table shows Occam statements paired with
+the routines used to execute them.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/occam.pdf b/src/olddocs/occam.pdf
new file mode 100644 (file)
index 0000000..852d984
Binary files /dev/null and b/src/olddocs/occam.pdf differ
diff --git a/src/olddocs/pascal.html b/src/olddocs/pascal.html
new file mode 100644 (file)
index 0000000..242c129
--- /dev/null
@@ -0,0 +1,4088 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:13 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The ACK Pascal Compiler</title>
+</head>
+<body>
+
+<h1 align=center>The ACK Pascal Compiler</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. The compiler">2. The compiler</a><br>
+<a href="#2.1. Lexical Analysis">2.1. Lexical Analysis</a><br>
+<a href="#2.2. Syntax Analysis">2.2. Syntax Analysis</a><br>
+<a href="#2.2.1. Alternation conflict">2.2.1. Alternation conflict</a><br>
+<a href="#2.2.2. Repetition conflict">2.2.2. Repetition conflict</a><br>
+<a href="#2.3. Semantic Analysis">2.3. Semantic Analysis</a><br>
+<a href="#2.4. Code Generation">2.4. Code Generation</a><br>
+<a href="#2.5. Error Handling">2.5. Error Handling</a><br>
+<a href="#2.6. Memory Allocation and Garbage Collection">2.6. Memory Allocation and Garbage Collection</a><br>
+<a href="#3. Translation of Pascal to EM code">3. Translation of Pascal to EM code</a><br>
+<a href="#3.1. Global Variables">3.1. Global Variables</a><br>
+<a href="#3.2. Expressions">3.2. Expressions</a><br>
+<a href="#3.3. Statements">3.3. Statements</a><br>
+<a href="#3.3.1. Assignment Statement">3.3.1. Assignment Statement</a><br>
+<a href="#3.3.2. Goto Statement">3.3.2. Goto Statement</a><br>
+<a href="#3.3.3. If Statement">3.3.3. If Statement</a><br>
+<a href="#3.3.4. Repeat Statement">3.3.4. Repeat Statement</a><br>
+<a href="#3.3.5. While Statement">3.3.5. While Statement</a><br>
+<a href="#3.3.6. Case Statement">3.3.6. Case Statement</a><br>
+<a href="#3.3.7. For Statement">3.3.7. For Statement</a><br>
+<a href="#3.3.8. With Statement">3.3.8. With Statement</a><br>
+<a href="#3.4. Procedure and Function Calls">3.4. Procedure and Function Calls</a><br>
+<a href="#3.5. Register Messages">3.5. Register Messages</a><br>
+<a href="#3.6. Compile-time optimizations">3.6. Compile-time optimizations</a><br>
+<a href="#4. Conformant Arrays">4. Conformant Arrays</a><br>
+<a href="#4.1. Variable conformant array parameters">4.1. Variable conformant array parameters</a><br>
+<a href="#4.2. Value conformant array parameters">4.2. Value conformant array parameters</a><br>
+<a href="#5. Compiler options">5. Compiler options</a><br>
+<a href="#5.1. Compile time options">5.1. Compile time options</a><br>
+<a href="#5.2. Run time options">5.2. Run time options</a><br>
+<a href="#6. Extensions to Pascal as specified by ISO 7185">6. Extensions to Pascal as specified by ISO 7185</a><br>
+<a href="#7. Deviations from the standard">7. Deviations from the standard</a><br>
+<a href="#8. Hints to change the standard">8. Hints to change the standard</a><br>
+<a href="#9. Testing the compiler">9. Testing the compiler</a><br>
+<a href="#10. Comparison with the Pascal-VU compiler">10. Comparison with the Pascal-VU compiler</a><br>
+<a href="#10.1. Deviations">10.1. Deviations</a><br>
+<a href="#10.2. Extensions">10.2. Extensions</a><br>
+<a href="#10.3. Compiler options">10.3. Compiler options</a><br>
+<a href="#11. Improvements to the compiler">11. Improvements to the compiler</a><br>
+<a href="#12. History &amp; Acknowledgements">12. History &amp; Acknowledgements</a><br>
+<a href="#13. References">13. References</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Aad Geudeke<br>
+Frans Hofmeester</i><br>
+Dept. of Mathematics and Computer Science<br>
+Vrije Universiteit<br>
+Amsterdam, The Netherlands</p>
+
+<p>This document describes the implementation of a Pascal
+to EM compiler. The compiler is written in C. The lexical
+analysis is done using a hand-written lexical analyzer.
+Semantic analysis makes use of the extended LL(1) parser
+generator LLgen. Several EM utility modules are used in the
+compiler.</p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>The Pascal front end of the Amsterdam Compiler Kit (ACK)
+complies with the requirements of the international standard
+published by the International Organization for
+Standardization (ISO) [ISO]. An informal description, which
+unfortunately is not conforming to the standard, of the
+programming language Pascal is given in [JEN].</p>
+
+<p>The main reason for rewriting the Pascal compiler was
+that the old Pascal compiler was written in Pascal itself,
+and a disadvantage of it was its lack of flexibility. The
+compiler did not meet the needs of the current
+ACK-framework, which makes use of modern parsing techniques
+and utility modules. In this framework it is, for example,
+possible to use a fast back end. Such a back end translates
+directly to object code [ACK]. Our compiler is written in C
+and it is designed similar to the current C and Modula-2
+compiler of ACK.</p>
+
+<p>Chapter 2 describes the basic structure of the compiler.
+Chapter 3 discusses the code generation of the main Pascal
+constructs. Chapter 4 covers one of the major components of
+Pascal, viz. the conformant array. In Chapter 5 the various
+compiler options that can be used are enumerated. The
+extensions to the standard and the deviations from the
+standard are listed in Chapter 6 and 7. Chapter 8 presents
+some ideas to improve the standard. Chapter 9 gives a short
+overview of testing the compiler. The major differences
+between the old and new compiler can be found in Chapter 10.
+Suggestions to improve the compiler are described in Chapter
+11. The appendices contain the grammar of Pascal and the
+changes made to the ACK Pascal run time library. A
+translation of a Pascal program to EM code as example is
+presented.</p>
+<a name="2. The compiler"></a>
+<h2>2. The compiler</h2>
+
+<p>The compiler can be divided roughly into four
+modules:</p>
+
+<p>&bull; lexical analysis<br>
+&bull; syntax analysis<br>
+&bull; semantic analysis<br>
+&bull; code generation</p>
+
+<p>The four modules are grouped into one pass. The activity
+of these modules is interleaved during the pass.<br>
+The lexical analyzer, some expression handling routines and
+various datastructures from the Modula-2 compiler
+contributed to the project.</p>
+<a name="2.1. Lexical Analysis"></a>
+<h2>2.1. Lexical Analysis</h2>
+
+<p>The first module of the compiler is the lexical
+analyzer. In this module, the stream of input characters
+making up the source program is grouped into <i>tokens</i>,
+as defined in <b>ISO 6.1</b>. The analyzer is hand-written,
+because the lexical analyzer generator, which was at our
+disposal, <i>Lex</i> [LEX], produces much slower analyzers.
+A character table, in the file <i>char.c</i>, is created
+using the program <i>tab</i> which takes as input the file
+<i>char.tab</i>. In this table each character is placed into
+a particular class. The classes, as defined in the file
+<i>class.h</i>, represent a set of tokens. The strategy of
+the analyzer is as follows: the first character of a new
+token is used in a multiway branch to eliminate as many
+candidate tokens as possible. Then the remaining characters
+of the token are read. The constant INP_NPUSHBACK, defined
+in the file <i>input.h</i>, specifies the maximum number of
+characters the analyzer looks ahead. The value has to be at
+least 3, to handle input sequences such as:<br>
+1e+4 (which is a real number)<br>
+1e+a (which is the integer 1, followed by the identifier
+&quot;e&quot;, a plus, and the identifier &quot;a&quot;)</p>
+
+<p>Another aspect of this module is the insertion and
+deletion of tokens required by the parser for the recovery
+of syntactic errors (see also section 2.2). A generic input
+module [ACK] is used to avoid the burden of I/O.</p>
+<a name="2.2. Syntax Analysis"></a>
+<h2>2.2. Syntax Analysis</h2>
+
+<p>The second module of the compiler is the parser, which
+is the central part of the compiler. It invokes the routines
+of the other modules. The tokens obtained from the lexical
+analyzer are grouped into grammatical phrases. These phrases
+are stored as parse trees and handed over to the next part.
+The parser is generated using <i>LLgen</i>[LL], a tool for
+generating an efficient recursive descent parser with no</p>
+
+<p>backtrack from an Extended Context Free Syntax.<br>
+An error recovery mechanism is generated almost completely
+automatically. A routine called <i>LLmessage</i> had to be
+written, which gives the necessary error messages and deals
+with the insertion and deletion of tokens. The routine
+<i>LLmessage</i> must accept one parameter, whose value is a
+token number, zero or -1. A zero parameter indicates that
+the current token (the one in the external variable
+<i>LLsymb</i>) is deleted. A -1 parameter indicates that the
+parser expected end of file, but did not get it. The parser
+will then skip tokens until end of file is detected. A
+parameter that is a token number (a positive parameter)
+indicates that this token is to be inserted in front of the
+token currently in <i>LLsymb</i>. Also, care must be taken,
+that the token currently in <i>LLsymb</i> is again returned
+by the <b>next</b> call to the lexical analyzer, with the
+proper attributes. So, the lexical analyzer must have a
+facility to push back one token.<br>
+Calls to the two standard procedures <i>write</i> and
+<i>writeln</i> can be different from calls to other
+procedures. The syntax of a write-parameter is different
+from the syntax of an actual-parameter. We decided to
+include them, together with <i>read</i> and <i>readln</i>,
+in the grammar. An alternate solution would be to make the
+syntax of an actual-parameter identical to the syntax of a
+write-parameter. Afterwards the parameter has to be checked
+to see whether it is used properly or not.</p>
+
+<p>As the parser is LL(1), it must always be able to
+determine what to do, based on the last token read
+(<i>LLsymb</i>). Unfortunately, this was not the case with
+the grammar as specified in [ISO]. Two kinds of problems
+appeared, viz. the <b>alternation</b> and <b>repetition</b>
+conflict. The examples given in the following paragraphs are
+taken from the grammar.</p>
+<a name="2.2.1. Alternation conflict"></a>
+<h2>2.2.1. Alternation conflict</h2>
+
+<p>An alternation conflict arises when the parser can not
+decide which production to choose.<b><br>
+Example:</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<pre>procedure-declaration    : procedure-heading <b>&rsquo;;&rsquo;</b> directive |
+                           procedure-identification <b>&rsquo;;&rsquo;</b> procedure-block |
+                           procedure-heading <b>&rsquo;;&rsquo;</b> procedure-block ;
+procedure-heading        : <b>procedure</b> identifier [ formal-parameter-list ]? ;
+procedure-identification : <b>procedure</b> procedure-identifier ;
+</pre>
+</td>
+</table>
+
+<p>A sentence that starts with the terminal
+<b>procedure</b> is derived from the three alternative
+productions. This conflict can be resolved in two ways:
+adjusting the grammar, usually some rules are replaced by
+one rule and more work has to be done in the semantic
+analysis; using the LLgen conflict resolver,
+&quot;<b>%if</b> (C-expression)&quot;, if the C-expression
+evaluates to non-zero, the production in question is chosen,
+otherwise one of the remaining rules is chosen. The grammar
+rules were rewritten to solve this conflict. The new rules
+are given below. For more details see the file
+<i>declar.g</i>.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<pre>procedure-declaration : procedure-heading <b>&rsquo;;&rsquo;</b> ( directive | procedure-block ) ;
+procedure-heading     : <b>procedure</b> identifier [ formal-parameter-list ]? ;
+</pre>
+</td>
+</table>
+
+<p>A special case of an alternation conflict, which is
+common to many block structured languages, is the
+<i>&quot;dangling-else&quot;</i> ambiguity.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<pre>if-statement : <b>if</b> boolean-expression <b>then</b> statement [ else-part ]? ;
+else-part    : <b>else</b> statement ;
+</pre>
+</td>
+</table>
+
+<p>The following statement that can be derived from the
+rules above is ambiguous:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p><b>if</b> <tt>boolean-expr-1</tt> <b>then if</b>
+<tt>boolean-expr-2</tt> <b>then</b> <tt>statement-1</tt>
+<b>else</b> <tt>statement-2</tt></p>
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-100601.png"></small></p>
+
+<p><small>(a) (b)</small></p>
+
+<p align=center><small>Two parse trees showing the
+<i>dangling-else</i> ambiguity</small></p>
+
+<p><small>According to the standard, <b>else</b> is matched
+with the nearest preceding unmatched <b>then</b>, i.e. parse
+tree (a) is valid (<b>ISO 6.8.3.4</b>). This conflict is
+statically resolved in LLgen by using
+&quot;<b>%prefer</b>&quot;, which is equivalent in behaviour
+to &quot;<b>%if</b>(1)&quot;.</small></p>
+<a name="2.2.2. Repetition conflict"></a>
+<h2>2.2.2. Repetition conflict</h2>
+
+<p>A repetition conflict arises when the parser can not
+decide whether to choose a production once more, or
+not.<b><br>
+Example:</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<pre>field-list : [ ( fixed-part [ <b>&rsquo;;&rsquo;</b> variant-part ]? | variantpart ) [;]? ]? ;
+fixed-part : record-section [ <b>&rsquo;;&rsquo;</b> record-section ]* ;
+</pre>
+</td>
+</table>
+
+<p>When the parser sees the semicolon, it can not decide
+whether another record-section or a variant-part follows.
+This conflict can be resolved in two ways: adjusting the
+grammar or using the conflict resolver, &quot;<b>%while</b>
+(C-expression)&quot;. The grammar rules that deal with this
+conflict were completely rewritten. For more details, the
+reader is referred to the file <i>declar.g</i>.</p>
+<a name="2.3. Semantic Analysis"></a>
+<h2>2.3. Semantic Analysis</h2>
+
+<p>The third module of the compiler is the checking of
+semantic conventions of ISO-Pascal. To check the program
+being parsed, actions have been used in LLgen. An action
+consists of several C-statements, enclosed in brackets
+&quot;{&quot; and &quot;}&quot;. In order to facilitate
+communication between the actions and <i>LLparse</i>, the
+parsing routines can be given C-like parameters and local
+variables. An important part of the semantic analyzer is the
+symbol table. This table stores all information concerning
+identifiers and their definitions. Symbol-table lookup and
+hashing is done by a generic namelist module [ACK]. The
+parser turns each program construction into a parse tree,
+which is the major datastructure in the compiler. This parse
+tree is used to exchange information between various
+routines.</p>
+<a name="2.4. Code Generation"></a>
+<h2>2.4. Code Generation</h2>
+
+<p>The final module in the compiler is that of code
+generation. The information stored in the parse trees is
+used to generate the EM code [EM]. EM code is generated with
+the help of a procedural EM-code interface [ACK]. The use of
+static exchanges is not desired, since the fast back end can
+not cope with static code exchanges, hence the EM
+pseudoinstruction <b>exc</b> is never generated.<br>
+Chapter 3 discusses the code generation in more detail.</p>
+<a name="2.5. Error Handling"></a>
+<h2>2.5. Error Handling</h2>
+
+<p>The first three modules have in common that they can
+detect errors in the Pascal program being compiled. If this
+is the</p>
+
+<p>case, a proper message is given and some action is
+performed. If code generation has to be aborted, an error
+message is given, otherwise a warning is given. The constant
+MAXERR_LINE, defined in the file <i>errout.h</i>, specifies
+the maximum number of messages given per line. This can be
+used to avoid long lists of error messages caused by, for
+example, the omission of a &rsquo;;&rsquo;. Three kinds of
+errors can be distinguished: the lexical error, the
+syntactic error, and the semantic error. Examples of these
+errors are respectively, nested comments, an expression with
+unbalanced parentheses, and the addition of two
+characters.</p>
+<a name="2.6. Memory Allocation and Garbage Collection"></a>
+<h2>2.6. Memory Allocation and Garbage Collection</h2>
+
+<p>The routines <i>st_alloc</i> and <i>st_free</i> provide
+a mechanism for maintaining free lists of structures, whose
+first field is a pointer called <b>next</b>. This field is
+used to chain free structures together. Each structure,
+suppose the tag of the structure is ST, has a free list
+pointed by h_ST. Associated with this list are the
+operations: <i>new_ST()</i>, an allocating mechanism which
+supplies the space for a new ST struct; and
+<i>free_ST()</i>, a garbage collecting mechanism which links
+the specified structure into the free list.</p>
+<a name="3. Translation of Pascal to EM code"></a>
+<h2>3. Translation of Pascal to EM code</h2>
+
+<p>A short description of the translation of Pascal
+constructs to EM code is given in the following paragraphs.
+The EM instructions and Pascal terminal symbols are printed
+in <b>boldface</b>. A sentence in <i>italics</i> is a
+description of a group of EM (pseudo)instructions.</p>
+<a name="3.1. Global Variables"></a>
+<h2>3.1. Global Variables</h2>
+
+<p>For every global variable, a <b>bss</b> block is
+reserved. To enhance the readability of the EM-code
+generated, the variable-identifier is used as a data label
+to address the block.</p>
+<a name="3.2. Expressions"></a>
+<h2>3.2. Expressions</h2>
+
+<p>Operands are always evaluated, so the execution of</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>if</b> ( p &lt;&gt; nil ) <b>and</b> ( p^.value
+&lt;&gt; 0 ) <b>then</b> .....</p></td>
+</table>
+
+<p>might cause a run-time error, if p is equal to nil.</p>
+
+<p>The left-hand operand of a dyadic operator is almost
+always evaluated before the right-hand side. Peculiar
+evaluations exist for the following cases:</p>
+
+<p>the expression: set1 &lt;= set2, is evaluated as follows
+:</p>
+<pre>- evaluate set2
+- evaluate set1
+- compute set2+set1
+- test set2 and set2+set1 for equality
+</pre>
+
+<p>the expression: set1 &gt;= set2, is evaluated as follows
+:</p>
+<pre>- evaluate set1
+- evaluate set2
+- compute set1+set2
+- test set1 and set1+set2 for equality
+</pre>
+
+<p>Where allowed, according to the standard, constant
+integral expressions are compile-time evaluated while an
+effort is made to report overflow on target machine basis.
+The integral expressions are evaluated in the type
+<i>arith</i>. The size of an arith is assumed to be at least
+the size of the integer type on the target machine. If the
+target machine&rsquo;s integer size is less than the size of
+an arith, overflow can be detected at compile-time. However,
+the following call to the standard procedure new, <i>new(p,
+3+5)</i>, is illegal, because the second parameter is not a
+constant according to the grammar.</p>
+
+<p>Constant floating expressions are not compile-time
+evaluated, because the precision on the target machine and
+the precision on the machine on which the compiler runs
+could be different. The boolean expression <i>(1.0 + 1.0) =
+2.0</i> could evaluate to false.</p>
+<a name="3.3. Statements"></a>
+<h2>3.3. Statements</h2>
+<a name="3.3.1. Assignment Statement"></a>
+<h2>3.3.1. Assignment Statement</h2>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><tt>(variable-access | function-identifier)</tt>
+<b>:=</b> <tt>expression</tt></p>
+<!-- INDENTATION -->
+<p>EM :</p>
+<!-- INDENTATION -->
+<p><i>evaluate expression<br>
+store in variable-access or function-identifier</i></p>
+<!-- INDENTATION -->
+<p>In case of a function-identifier, a hidden temporary
+variable is used to keep the function result.</p>
+</td>
+</table>
+<a name="3.3.2. Goto Statement"></a>
+<h2>3.3.2. Goto Statement</h2>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>GOTO</b> <tt>label</tt></p>
+<!-- INDENTATION -->
+<p>EM : Two cases can be distinguished :</p></td>
+</table>
+
+<p>- local goto,</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>in which a <b>bra</b> is generated.</p>
+<!-- INDENTATION -->
+<p>- non-local goto, a goto_descriptor is build, containing
+the ProgramCounter of the instruction jumped to and an
+offset in the target procedure frame which contains the
+value of the StackPointer after the jump. The code for the
+jump itself is to load the address of the goto_descriptor,
+followed by a push of the LocalBase of the target procedure
+and a <b>cal</b> $_gto. A message is generated to indicate
+that a procedure or function contains a statement which is
+the target of a non-local goto.</p></td>
+</table>
+<a name="3.3.3. If Statement"></a>
+<h2>3.3.3. If Statement</h2>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>IF</b> <tt>boolean-expression</tt> <b>THEN</b>
+<tt>statement</tt></p>
+</td>
+</table>
+
+<p>EM :</p>
+<pre><i>    evaluation boolean-expression
+</i><b>    zeq</b> *exit_label
+<i>    code statement
+</i>   exit_label
+</pre>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>IF</b> <tt>boolean-expression</tt> <b>THEN</b>
+<tt>statement-1</tt> <b>ELSE</b> <tt>statement-2</tt></p>
+</td>
+</table>
+
+<p>EM :</p>
+<pre><i>    evaluation boolean-expression
+</i><b>    zeq</b> *else_label
+<i>    code statement-1
+</i><b>    bra</b> *exit_label
+   else_label
+<i>    code statement-2
+</i>   exit_label
+</pre>
+<a name="3.3.4. Repeat Statement"></a>
+<h2>3.3.4. Repeat Statement</h2>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>REPEAT</b> <tt>statement-sequence</tt> <b>UNTIL</b>
+<tt>boolean-expression</tt></p>
+</td>
+</table>
+
+<p>EM :</p>
+<pre>   repeat_label
+</pre>
+
+<p><i>code statement-sequence evaluation
+boolean-expression</i> <b>zeq</b> *repeat_label</p>
+<a name="3.3.5. While Statement"></a>
+<h2>3.3.5. While Statement</h2>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>WHILE</b> <tt>boolean-expression</tt> <b>DO</b>
+<tt>statement</tt></p>
+</td>
+</table>
+
+<p>EM :</p>
+<pre>   while_label
+<i>    evaluation boolean-expression
+</i><b>    zeq</b> *exit_label
+<i>    code statement
+</i><b>    bra</b> *while_label
+   exit_label
+</pre>
+<a name="3.3.6. Case Statement"></a>
+<h2>3.3.6. Case Statement</h2>
+
+<p>The case-statement is implemented using the <b>csa</b>
+and <b>csb</b> instructions.</p>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>CASE</b> <tt>case-expression</tt> <b>OF</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p><tt>case-constant-list-1</tt> <b>:</b>
+<tt>statement-1</tt> <b>;</b><tt><br>
+case-constant-list-2</tt> <b>:</b> <tt>statement-2</tt>
+<b>;</b><tt><br>
+.<br>
+.<br>
+case-constant-list-n</tt> <b>:</b> <tt>statement-n
+[</tt><b>;</b><tt>]</tt></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>END</b></p></td>
+</table>
+
+<p>The <b>csa</b> instruction is used if the range of the
+case-expression value is dense, i.e.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><tt>( upperbound &minus; lowerbound ) /
+number_of_cases</tt></p></td>
+</table>
+
+<p>is less than the constant DENSITY, defined in the file
+<i>density.h</i>.</p>
+
+<p>If the range is sparse, a <b>csb</b> instruction is
+used.</p>
+
+<p>EM :</p>
+<pre><i>    evaluation case-expression
+</i><b>    bra</b> *l1
+   c1
+<i>    code statement-1
+</i><b>    bra *</b>exit_label
+   c2
+<i>    code statement-2
+</i><b>    bra *</b>exit_label
+    .
+    .
+   cn
+<i>    code statement-n
+</i><b>    bra *</b>exit_label
+   .case_descriptor
+<i>    generation case_descriptor
+</i>   l1
+<b>    lae</b> .case_descriptor
+<b>    csa</b> size of (case-expression)
+   exit_label
+</pre>
+<a name="3.3.7. For Statement"></a>
+<h2>3.3.7. For Statement</h2>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>FOR</b> <tt>control-variable</tt> <b>:=</b>
+<tt>initial-value (</tt><b>TO</b> <tt>|</tt>
+<b>DOWNTO</b><tt>) final-value</tt> <b>DO</b>
+<tt>statement</tt></p>
+</td>
+</table>
+
+<p>The initial-value and final-value are evaluated at the
+beginning of the loop. If the values are not constant, they
+are evaluated once and stored in a temporary.</p>
+
+<p>EM :</p>
+<pre><i>    load initial-value
+    load final-value
+</i><b>    bgt</b> exit-label            (* DOWNTO : <b>blt</b> <i>exit-label</i> *)
+<i>    load initial-value
+</i>   l1
+<i>    store in control-variable
+    code statement
+    load control-variable
+</i><b>    dup</b> <i>control-variable
+    load final-value
+</i><b>    beq</b> exit_label
+<b>    inc</b> <i>control-variable</i>    (* DOWNTO : <b>dec</b> <i>control-variable</i> *)
+<b>    bra *</b>l1
+   exit_label
+</pre>
+
+<p>Note: testing must be done before
+incrementing(decrementing) the control-variable,<br>
+because wraparound could occur, which could lead to an
+infinite loop.</p>
+<a name="3.3.8. With Statement"></a>
+<h2>3.3.8. With Statement</h2>
+
+<p>PASCAL :</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>WITH</b> <tt>record-variable-list</tt> <b>DO</b>
+<tt>statement</tt></p>
+<!-- INDENTATION -->
+<p>The statement <b>WITH</b> r
+<small><small>1</small></small> , r
+<small><small>2</small></small> , ..., r
+<small><small>n</small></small> <b>DO</b>
+<tt>statement</tt></p>
+<!-- INDENTATION -->
+<p>is equivalent to <b>WITH</b> r
+<small><small>1</small></small> <b>DO WITH</b> r
+<small><small>2</small></small> <b>DO</b> ... <b>WITH</b> r
+<small><small>n</small></small> <b>DO</b>
+<tt>statement</tt></p>
+</td>
+</table>
+
+<p>The translation of</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>WITH</b> r <small><small>1</small></small> <b>DO</b>
+<tt>statement</tt></p></td>
+</table>
+
+<p>is</p>
+<pre><i>   push address of r<small><small>1
+</small></small>   store address in temporary
+   code statement
+</i></pre>
+
+<p>An occurrence of a field is translated into:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><i>load temporary<br>
+add field-offset</i></p></td>
+</table>
+<a name="3.4. Procedure and Function Calls"></a>
+<h2>3.4. Procedure and Function Calls</h2>
+
+<p>In general, the call</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>p(a <small><small>1</small></small> , a
+<small><small>2</small></small> , ...., a
+<small><small>n</small></small> )</p></td>
+</table>
+
+<p>is translated into the sequence:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><i>evaluate a<small><small>n
+</small></small>.
+.
+evaluate a<small><small>2
+</small></small>evaluate a<small><small>1
+</small></small>push localbase
+</i><b>cal</b> $p
+<i>pop parameters
+</i></pre>
+</td>
+</table>
+
+<p>i.e. the order of evaluation and binding of the
+actual-parameters is from right to left. In general, a copy
+of the actual-parameter is made when the formal-parameter is
+a value-parameter. If the formal-parameter is a
+variable-parameter, a pointer to the actual-parameter is
+pushed.</p>
+
+<p>In case of a function call, a <b>lfr</b> is generated,
+which pushes the function result on top of the stack.</p>
+<a name="3.5. Register Messages"></a>
+<h2>3.5. Register Messages</h2>
+
+<p>A register message can be generated to indicate that a
+local variable is never referenced indirectly. This implies
+that a register can be used for a variable. We distinguish
+the following classes, given in decreasing priority:</p>
+
+<p>&bull; control-variable and final-value of a
+for-statement</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>to speed up testing, and execution of the body of the
+for-statement</p>
+<!-- INDENTATION -->
+<p>&bull; record-variable of a with-statement</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>to improve the field selection of a record</p>
+<!-- INDENTATION -->
+<p>&bull; remaining local variables and parameters</p>
+</td>
+</table>
+<a name="3.6. Compile-time optimizations"></a>
+<h2>3.6. Compile-time optimizations</h2>
+
+<p>The only optimization that is performed is the
+evaluation of constant integral expressions. The
+optimization of constructs like</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><b>if</b> <tt>false</tt> <b>then</b>
+<tt>statement</tt>,</p></td>
+</table>
+
+<p>is left to either the peephole optimizer, or a global
+optimizer.</p>
+<a name="4. Conformant Arrays"></a>
+<h2>4. Conformant Arrays</h2>
+
+<p>A fifth kind of parameter, besides the value, variable,
+procedure, and function parameter, is the conformant array
+parameter (<b>ISO 6.6.3.7</b>). This parameter, undoubtedly
+the major addition to Pascal from the compiler
+writer&rsquo;s point of view, has been implemented. With
+this kind of parameter, the required bounds of the
+index-type of an actual parameter are not fixed, but are
+restricted to a specified range of values. Two types of
+conformant array parameters can be distinguished: variable
+conformant array parameters and value conformant array
+parameters.</p>
+<a name="4.1. Variable conformant array parameters"></a>
+<h2>4.1. Variable conformant array parameters</h2>
+
+<p>The treatment of variable conformant array parameters is
+comparable with the normal variable parameter. Both have in
+common that the parameter mechanism used is <i>call by
+reference</i>.<br>
+An example is:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>to sort variable length arrays of integers, the following
+Pascal procedure could be used:</p>
+<!-- INDENTATION -->
+<pre><b>procedure</b> bubblesort(<b>var</b> A : <b>array</b>[low..high : integer] <b>of</b> integer);
+<b>var</b> i, j : integer;
+<b>begin
+        for</b> j := high - 1 <b>downto</b> low <b>do
+                for</b> i := low <b>to</b> j <b>do
+                        if</b> A[i+1] &lt; A[i] <b>then</b> <i>interchange A[i] and A[i+1]
+</i><b>end</b>;
+</pre>
+</td>
+</table>
+
+<p>For every actual parameter, the base address of the
+array is pushed on the stack and for every
+index-type-specification, exactly one array descriptor is
+pushed.</p>
+<a name="4.2. Value conformant array parameters"></a>
+<h2>4.2. Value conformant array parameters</h2>
+
+<p>The treatment of value conformant array parameters is
+more complex than its variable counterpart.<br>
+An example is:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>an unpacked array of characters could be printed as a
+string with the following program part:</p>
+<!-- INDENTATION -->
+<pre><b>procedure</b> WriteAsString( A : <b>array</b>[low..high : integer] <b>of</b> char);
+<b>var</b> i : integer;
+<b>begin
+        for</b> i := low <b>to</b> high <b>do</b> write(A[i]);
+<b>end</b>;
+</pre>
+</td>
+</table>
+
+<p>The calling procedure pushes the base address of the
+actual parameter and the array descriptors belonging to it
+on the stack. Subsequently the procedure using the
+conformant array parameter is called. Because it is a
+<i>call by value</i>, the called procedure has to create a
+copy of the actual</p>
+
+<p>parameter. This implies that the calling procedure knows
+how much space on the stack must be reserved for the
+parameters. If the actual-parameter is a conformant array,
+the called procedure keeps track of the size of the
+activation record. Hence the restrictions on the use of
+value conformant array parameters, as specified in <b>ISO
+6.6.3.7.2</b>, are dropped.</p>
+
+<p>A description of the EM code generated by the compiler
+is:</p>
+<pre><i>load the stack adjustment sofar
+load base address of array parameter
+compute the size in bytes of the array
+add this size to the stack adjustment
+copy the array
+remember the new address of the array
+</i></pre>
+<a name="5. Compiler options"></a>
+<h2>5. Compiler options</h2>
+
+<p>There are some options available to control the
+behaviour of the compiler. Two types of options can be
+distinguished: compile-time options and run-time
+options.</p>
+<a name="5.1. Compile time options"></a>
+<h2>5.1. Compile time options</h2>
+
+<p>There are some options that can be set when the compiler
+is installed. Those options can be found in the file
+<i>Parameters</i>. To set a parameter just modify its
+definition in the file <i>Parameters</i>. The shell script
+in the file <i>make.hfiles</i> creates for each parameter a
+separate .h file. This mechanism is derived from the C
+compiler in ACK.</p>
+
+<p><b>IDFSIZE</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>The maximum number of characters that are significant in
+an identifier. This value has to be at least the value of
+<b>MINIDFSIZE</b>, defined in the file <i>options.c</i>. A
+compile-time check is included to see if the value of
+<b>MINIDFSIZE</b> is legal. The compiler will not recognize
+some keywords if <b>IDFSIZE</b> is too small.</p></td>
+</table>
+
+<p><b>ISTRSIZE</b>, <b>RSTRSIZE</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>The lexical analyzer uses these two values for the
+allocation of memory needed to store a string.
+<b>ISTRSIZE</b> is the initial number of bytes allocated.
+<b>RSTRSIZE</b> is the step size used for enlarging the
+memory needed.</p></td>
+</table>
+
+<p><b>NUMSIZE</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>The maximum length of a numeric constant recognized by
+the lexical analyzer. It is an error if this length is
+exceeded.</p></td>
+</table>
+
+<p><b>ERROUT</b>, <b>MAXERR_LINE</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>Used for error messages. <b>ERROUT</b> defines the file
+on which the messages are written. <b>MAXERR_LINE</b> is the
+maximum number of error messages given per line.</p></td>
+</table>
+
+<p><b>SZ_CHAR</b>, <b>AL_CHAR</b>, etc</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>The default values of the target machine sizes and
+alignments. The values can be overruled with the &minus;V
+option.</p></td>
+</table>
+
+<p><b>MAXSIZE</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>This value must be set to the maximum of the values of
+the target machine sizes. This parameter is used in overflow
+detection (see also section 3.2).</p></td>
+</table>
+
+<p><b>DENSITY</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>This parameter is used to decide what EM instruction has
+to be generated for a case-statement. If the range of the
+index value is sparse, i.e.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="84%">
+<p>(upperbound - lowerbound) / number_of_cases</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>is more than some threshold (<b>DENSITY</b>) the
+<b>csb</b> instruction is chosen. If the range is dense a
+jump table is generated (<b>csa</b>). This uses more space.
+Reasonable values are 2, 3 or 4.<br>
+Higher values might also be reasonable on machines, which
+have lots of address space and memory (see also section
+3.3.3).</p></td>
+</table>
+
+<p><b>INP_READ_IN_ONE</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>Used by the generic input module. It can either be
+defined or not defined. Defining it has the effect that
+files will be read completely into memory using only one
+read-system call. This should be used only on machines with
+lots of memory.</p></td>
+</table>
+
+<p><b>DEBUG</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<pre>If this parameter is defined some built-in compiler-debugging tools can be used:
+  &bull; only lexical analyzing is done, if the &minus;l option is given.
+  &bull; if the &minus;I option is turned on, the allocated number of structures is printed.
+  &bull; the routine debug can be used to print miscellaneous information.
+  &bull; the routine PrNode prints a tree of nodes.
+  &bull; the routine DumpType prints information about a type structure.
+  &bull; the macro DO_DEBUG(x,y) defined as ((x) &amp;&amp; (y)) can be used to perform
+    several actions.
+
+
+</pre>
+</td>
+</table>
+<a name="5.2. Run time options"></a>
+<h2>5.2. Run time options</h2>
+
+<p>The run time options can be given in the command line
+when the compiler is called.<br>
+They all have the form: &minus;&lt;character&gt;<br>
+Depending on the option, a character string has to be
+specified. The following options are currently
+available:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>&minus;<b>C</b></p>
+</td>
+<td width="32%"></td>
+<td width="64%">
+
+<p>The lower case and upper case letters are treated
+different (<b>ISO 6.1.1</b>).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>&minus;<b>u</b></p>
+</td>
+<td width="32%"></td>
+<td width="64%">
+
+<p>The character &rsquo;_&rsquo; is treated like a letter,
+so it is allowed to use the underscore in identifiers.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="64%">
+<p>Note: identifiers starting with an underscore may cause
+problems, because<br>
+most identifiers in library routines start with an
+underscore.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>&minus;<b>n</b></p>
+</td>
+<td width="32%"></td>
+<td width="64%">
+
+<p>This option suppresses the generation of register
+messages.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>&minus;<b>r</b></p>
+</td>
+<td width="32%"></td>
+<td width="64%">
+
+<p>With this option rangechecks are generated where
+necessary.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>&minus;<b>L</b></p>
+</td>
+<td width="32%"></td>
+<td width="64%">
+
+<p>Do not generate EM <b>lin</b> and <b>fil</b>
+instructions. These instructions are used only for
+profiling.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>&minus;<b>M</b>&lt;number&gt;</p>
+</td>
+<td width="16%"></td>
+<td width="64%">
+
+<p>Set the number of characters that are significant in an
+identifier to &lt;number&gt;. The maximum significant
+identifier length depends on the constant IDFSIZE, defined
+in <i>idfsize.h</i>.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p>&minus;<b>i</b>&lt;number&gt;</p>
+</td>
+<td width="16%"></td>
+<td width="64%">
+
+<p>With this flag the setsize for a set of integers can be
+changed. The number must be the number of bits per set.
+Default value : (#bits in a word) &minus; 1</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>&minus;<b>w</b></p>
+</td>
+<td width="32%"></td>
+<td width="64%">
+
+<p>Suppress warning messages (see also section 2.5).</p>
+</td>
+</table>
+
+
+<p>&minus;<b>V</b>[[<b>w</b>|<b>i</b>|<b>f</b>|<b>p</b>|<b>S</b>][<i>size</i>]?[<i>.alignment</i>]?]*</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="35%"></td>
+<td width="64%">
+<p>Option to set the object sizes and alignments on the
+target machine dynamically. The objects that can be
+manipulated are:<b><br>
+w</b> word<b><br>
+i</b> integer<b><br>
+f</b> float<b><br>
+p</b> pointer<b><br>
+S</b> structure<br>
+In case of a structure, <i>size</i> is discarded and the
+<i>alignment</i> is the initial alignment of the structure.
+The effective alignment is the least common multiple of
+<i>alignment</i> and the alignment of its members. This
+option has been implemented so that the compiler can be used
+as cross compiler.</p>
+</td>
+</table>
+<a name="6. Extensions to Pascal as specified by ISO 7185"></a>
+<h2>6. Extensions to Pascal as specified by ISO 7185</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><b>ISO 6.1.3:</b></p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>The underscore is treated as a letter when the &minus;u
+option is turned on (see also section 5.2). This is
+implemented to be compatible with Pascal-VU and can be used
+in identifiers to increase readability.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p><b>ISO 6.1.4:</b></p>
+</td>
+<td width="4%"></td>
+<td width="72%">
+
+<p>The directive <i>extern</i> can be used in a
+procedure-declaration or function-declaration to specify
+that the procedure-block or function-block corresponding to
+that declaration is external to the program-block. This can
+be used in conjunction with library routines.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p><b>ISO 6.1.9:</b> An</p>
+</td>
+<td width="2%"></td>
+<td width="68%">
+
+<p>alternative representation for the following</p>
+</td>
+</table>
+
+<p>tokens and delimiting characters is recognized:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="37%"></td>
+<td width="62%">
+<p><b>token alternative token</b></p>
+<!-- INDENTATION -->
+<p><tt>^ @</tt></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p><tt>[ (.<br>
+] .)</tt></p>
+<!-- INDENTATION -->
+<p><b>delimiting character alternative delimiting pair of
+characters</b></p>
+<!-- INDENTATION -->
+<p><tt>{ (*<br>
+} *)</tt></p>
+</td>
+</table>
+
+<p><b>ISO 6.6.3.7.2:</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p>A conformant array parameter can be passed as value
+conformant array parameter without the restrictions imposed
+by the standard. The compiler gives a warning. This is
+implemented to keep the parameter mechanism orthogonal (see
+also Chapter 4).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p><b>ISO 6.9.3.1:</b> If</p>
+</td>
+<td width="2%"></td>
+<td width="68%">
+
+<p>the value of the argument <i>TotalWidth</i> of the</p>
+</td>
+</table>
+
+<p>required procedure <i>write</i> is zero or negative, no
+characters are written for character, string or boolean type
+arguments. If the value of the argument <i>FracDigits</i> of
+the required procedure <i>write</i> is zero or negative, the
+fraction and &rsquo;.&rsquo; character are suppressed for
+fixed-point arguments.</p>
+<a name="7. Deviations from the standard"></a>
+<h2>7. Deviations from the standard</h2>
+
+<p>The compiler deviates from the ISO 7185 standard with
+respect to the following clauses:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><b>ISO 6.1.3:</b></p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>Identifiers may be of any length and all characters of
+an identifier shall be significant in distinguishing between
+them.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>The constant IDFSIZE, defined in the file
+<i>idfsize.h</i>, determines the (maximum) significant
+length of an identifier. It can be set at run time with the
+&minus;M option (see also section on compiler
+options).</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><b>ISO 6.1.8:</b></p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>There shall be at least one separator between any pair
+of consecutive tokens made up of identifiers, word-symbols,
+labels or unsigned-numbers.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>A token separator is not needed when a number is followed
+by an identifier or a word-symbol. For example the input
+sequence, 2<b>then</b>, is recognized as the integer 2
+followed by the keyword <b>then</b>.</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="34%">
+
+<p><b>ISO 6.2.1:</b> The</p>
+</td>
+<td width="4%"></td>
+<td width="62%">
+
+<p>label-declaration-part shall specify all</p>
+</td>
+</table>
+
+<p>labels that prefix a statement in the corresponding
+statement-part.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>The compiler generates a warning if a label is declared
+but never defined.</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="20%">
+
+<p><b>ISO 6.2.2:</b></p>
+</td>
+<td width="8%"></td>
+<td width="72%">
+
+<p>The scope of identifiers and labels should start at the
+beginning of the block in which these identifiers or labels
+are declared.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>The compiler, as most other one pass compilers deviates
+in this respect, because the scope of variables and labels
+start at their defining-point.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p><b>program</b> deviates<b>;<br>
+const</b><br>
+x <b>=</b> 3<b>;<br>
+procedure</b> p<b>;<br>
+const</b></p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>y <b>=</b> x<b>;</b><br>
+x <b>=</b> true<b>;</b></p>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p><b>begin end;<br>
+begin<br>
+end.</b></p>
+<!-- INDENTATION -->
+<p>In procedure p, the constant y has the integer value 3.
+This program does not conform to the standard. In [SAL] a
+simple algorithm is described for enforcing the scope rules,
+it involves numbering all scopes encoutered in the program
+in order of their opening, and recording in each identifier
+table entry the number of the latest scope in which it is
+used.</p>
+<!-- INDENTATION -->
+<p>Note: The compiler does not deviate from the standard in
+the following program:</p>
+<!-- INDENTATION -->
+<pre><b>       program</b> conforms<b>;
+       type
+</b></pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>x <b>=</b> real<b>;</b></p>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p><b>procedure</b> p<b>;<br>
+type</b></p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>y <b>= ^</b>x<b>;</b><br>
+x <b>=</b> boolean<b>;</b></p>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p><b>var</b></p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>p <b>:</b> y<b>;</b></p>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="27%"></td>
+<td width="72%">
+<p><b>begin end;<br>
+begin<br>
+end.</b></p>
+<!-- INDENTATION -->
+<p>In procedure p, the variable p is a pointer to
+boolean.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="26%">
+
+<p><b>ISO 6.4.3.2:</b></p>
+</td>
+<td width="2%"></td>
+<td width="72%">
+
+<p>The standard specifies that any ordinal type is allowed
+as index-type.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>The required type <i>integer</i> is not allowed as
+index-type, i.e.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="37%"></td>
+<td width="62%">
+<p><b>ARRAY [</b> <i>integer</i> <b>] OF</b>
+&lt;component-type&gt; is not permitted.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>This could be implemented, but this might cause problems
+on machines with a small memory.</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%">
+
+<p><b>ISO 6.4.3.3:</b></p>
+</td>
+<td width="4%"></td>
+<td width="72%">
+
+<p>The type possessed by the variant-selector, called the
+tag-type, must be an ordinal type, so the integer type is
+permitted. The values denoted by all case-constants shall be
+distinct and the set thereof shall be equal to the set of
+values specified by the tag-type.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>Because it is impracticable to enumerate all integers as
+case-constants, the integer type is not permitted as
+tag-type. It would not make a great difference to allow it
+as tagtype.</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="30%">
+
+<p><b>ISO 6.8.3.9:</b></p>
+</td>
+<td width="4%"></td>
+<td width="66%">
+
+<p>The standard specifies that the</p>
+</td>
+</table>
+
+<p>control-variable of a for-statement is not allowed to be
+modified while executing the loop.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="33%"></td>
+<td width="66%">
+<p>Violation of this rule is not detected. An algorithm to
+implement this rule can be found in [PCV].</p>
+</td>
+</table>
+<a name="8. Hints to change the standard"></a>
+<h2>8. Hints to change the standard</h2>
+
+<p>We encoutered some difficulties when the compiler was
+developed. In this chapter some hints are presented to
+change the standard, which would make the implementation of
+the compiler less difficult. The semantics of Pascal would
+not be altered by these adaptions.</p>
+
+<p>&minus; Some minor changes in the grammar of Pascal from
+the user&rsquo;s point of view, but which make the writing
+of an LL(1) parser considerably easier, could be:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<pre>field-list   : [ ( fixed-part [ variant-part ] | variant-part ) ] .
+fixed-part   : record-section <b>;</b> { record-section <b>;</b> } .
+variant-part : <b>case</b> variant-selector <b>of</b> variant <b>;</b> { variant <b>;</b> } .
+
+case-statement : <b>case</b> case-index <b>of</b> case-list-element <b>;</b> { case-list-element <b>;</b> } <b>end</b> .
+</pre>
+</td>
+</table>
+
+<p>&minus; To ease the semantic checking on sets, the
+principle of qualified sets could be used, every
+set-constructor must be preceeded by its
+type-identifier:</p>
+<pre>   set-constructor : type-identifier <b>[</b> [ member-designator { <b>,</b> member-designator } ] <b>]</b> .
+</pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>Example:</p>
+</td>
+<td width="10%">
+
+<p>t1 = set of 1..5;</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%"></td>
+<td width="10%">
+
+<p>t2 = set of integer;</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p>The type of [3, 5] would be ambiguous, but the type of
+t1[3, 5] not.</p>
+
+<p>&minus; Another problem arises from the fact that a
+function name can appear in three distinct &rsquo;use&rsquo;
+contexts: function call, assignment of function result and
+as function parameter.<br>
+Example:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><b>program</b> function_name;
+
+<b>function</b> p(x : integer; function y : integer) : integer;
+<b>begin</b> .. <b>end</b>;
+
+<b>function</b> f : integer;
+<b>begin
+</b>        f := p(f, f);     (*)
+<b>end</b>;
+
+<b>begin</b> .. <b>end</b>.
+</pre>
+</td>
+</table>
+
+<p>A possible solution in case of a call (also a procedure
+call) would be to make the (possibly empty)
+actual-parameter-list mandatory. The assignment of the
+function result could be changed in a <i>return</i>
+statement. Though this would change the semantics of the
+program slightly.<br>
+The above statement (*) would look like this: return p(f(),
+f);</p>
+
+<p>&minus; Another extension to the standard could be the
+implementation of an <i>otherwise</i> clause in a
+case-statement. This would behave exactly like the
+<i>default</i> clause in a switch-statement in C.</p>
+<a name="9. Testing the compiler"></a>
+<h2>9. Testing the compiler</h2>
+
+<p>Although it is practically impossible to prove the
+correctness of a compiler, a systematic method of testing
+the compiler is used to increase the confidence that it will
+work satisfactorily in practice. The first step was to see
+if the lexical analysis was performed correctly. For this
+purpose, the routine LexScan() was used (see also the
+&minus;l option). Next we tested the parser generated by
+LLgen, to see whether correct Pascal programs were accepted
+and garbage was dealed with gracefully. The biggest test
+involved was the validation of the semantic analysis.
+Simultaneously we tested the code generation. First some
+small Pascal test programs were translated and executed.
+When these programs work correctly, the Pascal validation
+suite and a large set of Pascal test programs were compiled
+to see whether they behaved in the manner the standard
+specifies. For more details about the Pascal validation
+suite, the reader is referred to [PCV].</p>
+<a name="10. Comparison with the Pascal-VU compiler"></a>
+<h2>10. Comparison with the Pascal-VU compiler</h2>
+
+<p>In this chapter, the differences with the Pascal-VU
+compiler [IM2] are listed. The points enumerated below can
+be used as improvements to the compiler (see also Chapter
+11).</p>
+<a name="10.1. Deviations"></a>
+<h2>10.1. Deviations</h2>
+
+<p>- large labels</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>only labels in the closed interval 0..9999 are allowed,
+as opposed to the Pascal-VU compiler. The Pascal-VU compiler
+allows every unsigned integer as label.</p></td>
+</table>
+
+<p>- goto</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>the new compiler conforms to the standard as opposed to
+the old one. The following program, which contains an
+illegal jump to label 1, is accepted by the Pascal-VU
+compiler.</p>
+<!-- INDENTATION -->
+<pre><b>program</b> illegal_goto(output);
+<b>label</b> 1;
+<b>var</b> i : integer;
+<b>begin
+</b></pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="10%">
+
+<p><b>goto</b> 1;</p>
+</td>
+<td width="10%"></td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="10%">
+
+<p><b>for</b> i := 1 <b>to</b> 10 <b>do</b></p>
+</td>
+<td width="10%"></td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="10%">
+
+<p><b>begin</b></p>
+</td>
+<td width="10%"></td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>1 : writeln(i);</p>
+</td>
+<td width="63%">
+</td>
+<tr valign="top" align="left">
+<td width="15%"></td>
+<td width="10%">
+
+<p><b>end</b>;</p>
+</td>
+<td width="10%"></td>
+<td width="63%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p><b>end</b>.</p>
+</td>
+</table>
+
+<p>This program is rejected by the new compiler.</p>
+<a name="10.2. Extensions"></a>
+<h2>10.2. Extensions</h2>
+
+<p>The extensions implemented by the Pascal-VU compiler are
+listed in Chapter 5 of [IM2].</p>
+
+<p>- separate compilation</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>the new compiler only accepts programs, not modules.</p>
+<!-- INDENTATION -->
+<p>- assertions not implemented.</p>
+<!-- INDENTATION -->
+<p>- additional procedures the procedures <i>halt, mark</i>
+and <i>release</i> are not available.</p>
+</td>
+</table>
+
+<p>- UNIX&trade; interfacing</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>the &minus;c option is not implemented.</p></td>
+</table>
+
+<p align=center><img src="grohtml-100602.png"></p>
+
+<p>- double length integers</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="5%"></td>
+<td width="94%">
+<p>integer size can be set with the &minus;V option, so the
+additional type <i>long</i> is not implemented.</p>
+</td>
+</table>
+<a name="10.3. Compiler options"></a>
+<h2>10.3. Compiler options</h2>
+
+<p>The options implemented by the Pascal-VU compiler are
+listed in Chapter 7 of [IM2].</p>
+
+<p>The construction &quot;{$....}&quot; is not
+recognized.</p>
+
+<p>The options: <i>a, c, d, s</i> and <i>t</i> are not
+available.</p>
+
+<p>The &minus;l option has been changed into the &minus;L
+option.</p>
+
+<p>The size of reals can be set with the &minus;V
+option.</p>
+<a name="11. Improvements to the compiler"></a>
+<h2>11. Improvements to the compiler</h2>
+
+<p>In consideration of portability, a restricted option
+could be implemented. Under this option, the extensions and
+warnings should be considered as errors.</p>
+
+<p>The restrictions imposed by the standard on the control
+variable of a for-statment should be implemented (<b>ISO
+6.8.3.9</b>).</p>
+
+<p>To check whether a function returns a valid result, the
+following algorithm could be used. When a function is
+entered a hidden temporary variable of type boolean is
+created. This variable is initialized with the value false.
+The variable is set to true, when an assignment to the
+function name occurs. On exit of the function a test is
+performed on the variable. If the value of the variable is
+false, a run-time error occurs.<br>
+Note: The check has to be done run-time.</p>
+
+<p>The <i>undefined value</i> should be implemented. A
+problem arises with local variables, for which space on the
+stack is allocated. A possible solution would be to generate
+code for the initialization of the local variables with the
+undefined value at the beginning of a procedure or
+function.</p>
+
+<p>The implementation for the global variables is easy,
+because <b>bss</b> blocks are used.</p>
+
+<p>Closely related to the last point is the generation of
+warnings when variables are never used or assigned. This is
+not yet implemented.</p>
+
+<p>The error messages could specify more details about the
+errors occurred, if some additional testing is done.</p>
+
+<p>Every time the compiler detects sets with different
+base-types, a warning is given. Sometimes this is
+superfluous.</p>
+<pre><b>program</b> sets(output);
+<b>type
+</b></pre>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>week = (sunday, monday, tuesday, wednesday, thursday,
+friday, saturday);</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+
+<p>workweek = monday..friday;</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p><b>var</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p>s : <b>set of</b> workweek;</p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+
+<p>day : week;</p>
+</td>
+</table>
+
+<p><b>begin</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="7" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p>day := monday;</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p>s := [day];</p>
+</td>
+<td width="20%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>(* warning *)</p>
+</td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p>day := saturday;</p>
+</td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="39%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="0%"></td>
+<td width="10%">
+
+<p>s := [day];</p>
+</td>
+<td width="20%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>(* warning *)</p>
+</td>
+<td width="39%">
+</td>
+</table>
+
+<p><b>end</b>.<br>
+The new compiler gives two warnings, the first one is
+redundant.</p>
+
+<p>A nasty point in the compiler is the way the procedures
+<i>read, readln, write</i> and <i>writeln</i> are handled
+(see also section 2.2). They have been added to the grammar.
+This implies that they can not be redefined as opposed to
+the other required procedures and functions. They should be
+removed from the grammar altogether. This could imply that
+more semantic checks have to be performed.</p>
+
+<p>No effort is made to detect possible run-time errors
+during compilation.<br>
+E.g. a : <b>array</b>[1..10] <b>of</b> <i>something</i>, and
+the array selection a[11] would occur.</p>
+
+<p>Some assistance to implement the improvements mentioned
+above, can be obtained from [PCV].</p>
+<a name="12. History &amp; Acknowledgements"></a>
+<h2>12. History &amp; Acknowledgements</h2>
+
+<p><b>History</b></p>
+
+<p>The purpose of this project was to make a Pascal
+compiler which should satisfy the conditions of the ISO
+standard. The task was considerably simplified, because
+parts of the Modula-2 compiler were used. This gave the
+advantage of increasing the uniformity of the compilers in
+ACK.<br>
+While developing the compiler, a number of errors were
+detected in the Modula-2 compiler, EM utility modules and
+the old Pascal compiler.</p>
+
+<p><b>Acknowledgements</b></p>
+
+<p>During the development of the compiler, valuable support
+was received from a number of persons. In this regard we owe
+a debt of gratitude to Fred van Beek, Casper Capel, Rob
+Dekker, Frank Engel, Jos&eacute; Gouweleeuw and Sonja
+Keijzer (Jut and Jul !!), Herold Kroon, Martin van
+Nieuwkerk, Sjaak Schouten, Eric Valk, and Didan Westra.<br>
+Special thanks are reserved for Dick Grune, who introduced
+us to the field of Compiler Design and who helped testing
+the compiler. Ceriel Jacobs, who developed LLgen and the
+Modula-2 compiler of ACK. Finally we would like to thank
+Erik Baalbergen, who had the supervision on this entire
+project and gave us many valuable suggestions.</p>
+<a name="13. References"></a>
+<h2>13. References</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[ISO]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>ISO 7185 Specification for Computer Programming Language
+Pascal, 1982, Acornsoft ISO-PASCAL, 1984</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>[EM]</p>
+</td>
+<td width="8%"></td>
+<td width="84%">
+
+<p>A.S. Tanenbaum, H. van Staveren, E.G. Keizer and J.W.
+Stevenson, <i>Description Of A Machine Architecture for use
+with Block Structured Languages</i>, Informatica Rapport
+IR-81, Vrije Universiteit, Amsterdam, 1983</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>[C]</p>
+</td>
+<td width="10%"></td>
+<td width="84%">
+
+<p>B.W. Kernighan and D.M. Ritchie, <i>The C Programming
+Language</i>, Prentice-Hall, 1978</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>[LL]</p>
+</td>
+<td width="8%"></td>
+<td width="84%">
+
+<p>C.J.H. Jacobs, <i>Some Topics in Parser Generation</i>,
+Informatica Rapport IR-105, Vrije Universiteit, Amsterdam,
+October 1985</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[IM2]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>J.W. Stevenson, <i>Pascal-VU Reference Manual and Unix
+Manual Pages</i>, Informatica Manual IM-2, Vrije
+Universiteit, Amsterdam, 1980</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[JEN]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>K. Jensen and N.Wirth, <i>Pascal User Manual and
+Report</i>, Springer-Verlag, 1978</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[ACK]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p><i>ACK Manual Pages</i>: ALLOC, ASSERT, EM_CODE, EM_MES,
+IDF, INPUT, PRINT, STRING, SYSTEM</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[AHO]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>A.V. Aho, R. Sethi and J.D. Ullman, <i>Compiler
+Principles, Techniques, and Tools</i>, Addison Wesley,
+1985</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[LEX]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>M.E. Lesk, <i>Lex - A Lexical Analyser Generator</i>,
+Comp. Sci. Tech. Rep. No. 39, Bell Laboratories, Murray
+Hill, New Jersey, October 1975</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[PCV]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>B.A. Wichmann and Z.J. Ciechanowicz, <i>Pascal Compiler
+Validation</i>, John Wiley &amp; Sons, 1983</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>[SAL]</p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p>A.H.J. Sale, <i>A Note on Scope, One-Pass Compilers and
+Pascal</i>, Australian Communications, 1, 1, 80-82, 1979</p>
+</td>
+</table>
+
+<p><b>Appendix A: ISO-PASCAL grammar</b></p>
+
+<p><b>A.1 Lexical tokens</b></p>
+
+<p>The syntax describes the formation of lexical tokens
+from characters and the separation of these tokens, and
+therefore does not adhere to the same rules as the syntax in
+A.2.</p>
+
+<p>The lexical tokens used to construct Pascal programs
+shall be classified into special-symbols, identifiers,
+directives, unsigned-numbers, labels and character-strings.
+The representation of any letter (upper-case or lower-case,
+differences of font, etc) occurring anywhere outside of a
+character-string shall be insignificant in that occurrence
+to the meaning of the program.</p>
+
+<p>letter = <b>a</b> | <b>b</b> | <b>c</b> | <b>d</b> |
+<b>e</b> | <b>f</b> | <b>g</b> | <b>h</b> | <b>i</b> |
+<b>j</b> | <b>k</b> | <b>l</b> | <b>m</b> | <b>n</b> |
+<b>o</b> | <b>p</b> | <b>q</b> | <b>r</b> | <b>s</b> |
+<b>t</b> | <b>u</b> | <b>v</b> | <b>w</b> | <b>x</b> |
+<b>y</b> | <b>z</b> .</p>
+
+<p>digit = <b>0</b> | <b>1</b> | <b>2</b> | <b>3</b> |
+<b>4</b> | <b>5</b> | <b>6</b> | <b>7</b> | <b>8</b> |
+<b>9</b> .</p>
+
+<p>The special symbols are tokens having special meanings
+and shall be used to delimit the syntactic units of the
+language.</p>
+
+<p>special-symbol = <b>+</b> | <b>&minus;</b> | <b>*</b> |
+<b>/</b> | <b>=</b> | <b>&lt;</b> | <b>&gt;</b> | <b>[</b> |
+<b>]</b> | <b>.</b> | <b>,</b> | <b>:</b> | <b>;</b> |
+<b>^</b> | <b>(</b> | <b>)</b> | <b>&lt;&gt;</b> |
+<b>&lt;=</b> | <b>&gt;=</b> | <b>:=</b> | <b>..</b> |
+word-symbol .</p>
+
+<p>word-symbol = <b>and</b> | <b>array</b> | <b>begin</b> |
+<b>case</b> | <b>const</b> | <b>div</b> | <b>do</b> |
+<b>downto</b> | <b>else</b> | <b>end</b> | <b>file</b> |
+<b>for</b> | <b>function</b> | <b>goto</b> | <b>if</b> |
+<b>in</b> | <b>label</b> | <b>mod</b> | <b>nil</b> |
+<b>not</b> | <b>of</b> | <b>or</b> | <b>packed</b> |
+<b>procedure</b> | <b>program</b> | <b>record</b> |
+<b>repeat</b> | <b>set</b> | <b>then</b> | <b>to</b> |
+<b>type</b> | <b>until</b> | <b>var</b> | <b>while</b> |
+<b>with</b> .</p>
+
+<p>Identifiers may be of any length. All characters of an
+identifier shall be significant. No identifier shall have
+the same spelling as any word-symbol.</p>
+
+<p>identifier = letter { letter | digit } .</p>
+
+<p>A directive shall only occur in a procedure-declaration
+or function-declaration. No directive shall have the same
+spelling as any word-symbol.</p>
+
+<p>directive = letter {letter | digit} .</p>
+
+<p>Numbers are given in decimal notation.</p>
+<pre>unsigned-integer = digit-sequence .
+unsigned-real = unsigned-integer <b>.</b> fractional-part [ <b>e</b> scale-factor ] | unsigned-integer <b>e</b> scale-factor .
+digit-sequence = digit {digit} .
+fractional-part = digit-sequence .
+</pre>
+
+<p>scale-factor = signed-integer . signed-integer = [sign]
+unsigned-integer . sign = <b>+</b> | <b>&minus;</b> .</p>
+
+<p>Labels shall be digit-sequences and shall be
+distinguished by their apparent integral values and shall be
+in the closed interval 0 to 9999.</p>
+
+<p>label = digit-sequence .</p>
+
+<p>A character-string containing a single string-element
+shall denote a value of the required char-type. Each
+string-character shall denote an implementation- defined
+value of the required char-type.</p>
+<pre>character-string = <b>&rsquo;</b> string-element { string-element } <b>&rsquo;</b> .
+string-element = apostrophe-image | string-character .
+apostrophe-image = <b>&rsquo;&rsquo;</b> .
+string-character = All 7-bits ASCII characters except linefeed (10), vertical tab (11), and new page (12).
+</pre>
+
+<p>The construct:</p>
+
+<p><b>{</b>
+any-sequence-of-characters-and-separations-of-lines-
+not-containing-right-brace <b>}</b></p>
+
+<p>shall be a comment if the &quot;{&quot; does not occur
+within a character-string or within a comment. The
+substitution of a space for a comment shall not alter the
+meaning of a program.</p>
+
+<p>Comments, spaces (except in character-strings), and the
+separation of consecutive lines shall be considered to be
+token separators. Zero or more token separators may occur
+between any two consecutive tokens, or before the first
+token of a program text. No separators shall occur within
+tokens.</p>
+
+<p><b>A.2 Grammar</b></p>
+
+<p>The non-terminal symbol <i>program</i> is the start
+symbol of the grammar.</p>
+<pre>actual-parameter : expression | variable-access | procedure-identifier | function-identifier .
+actual-parameter-list : <b>(</b> actual-parameter { <b>,</b> actual-parameter } <b>)</b> .
+adding-operator : <b>+</b> | <b>&minus;</b> | <b>or</b> .
+array-type : <b>array [</b> index-type { <b>,</b> index-type } <b>] of</b> component-type .
+array-variable : variable-access .
+assignment-statement : ( variable-access | function-identifier ) <b>:=</b> expression .
+
+base-type : ordinal-type .
+block : label-declaration-part constant-definition-part type-definition-part variable-declaration-part
+        procedure-and-function-declaration-part statement-part .
+Boolean-expression : expression .
+bound-identifier : identifier .
+buffer-variable : file-variable <b>^</b> .
+
+case-constant : constant .
+case-constant-list : case-constant { <b>,</b> case-constant } .
+case-index : expression .
+case-list-element : case-constant-list <b>:</b> statement .
+case-statement : <b>case</b> case-index <b>of</b> case-list-element { <b>;</b> case-list-element } [ <b>;</b> ] <b>end</b> .
+component-type : type-denoter .
+component-variable : indexed-variable | field-designator .
+compound-statement : <b>begin</b> statement-sequence <b>end</b> .
+conditional-statement : if-statement | case-statement .
+conformant-array-parameter-specification : value-conformant-array-specification |
+                  variable-conformant-array-specification .
+conformant-array-schema : packed-conformant-array-schema | unpacked-conformant-array-schema .
+constant : [ sign ] ( unsigned-number | constant-identifier ) | character-string .
+constant-definition : identifier <b>=</b> constant .
+constant-definition-part : [ <b>const</b> constant-definition <b>;</b> { constant-definition <b>;</b> } ] .
+constant-identifier : identifier .
+control-variable : entire-variable .
+
+domain-type : type-identifier .
+
+else-part : <b>else</b> statement .
+empty-statement : .
+entire-variable : variable-identifier .
+enumerated-type : <b>(</b> identifier-list <b>)</b> .
+expression : simple-expression [ relational-operator simple-expression ] .
+</pre>
+
+<p>factor : variable-access | unsigned-constant |
+bound-identifier | function-designator | set-constructor |
+<b>(</b> expression <b>)</b> | <b>not</b> factor .
+field-designator : record-variable <b>.</b> field-specifier
+| field-designator-identifier . field-designator-identifier
+: identifier . field-identifier : identifier . field-list :
+[ ( fixed-part [ <b>;</b> variant-part ] | variant-part ) [
+<b>;</b> ] ] . field-specifier : field-identifier .
+file-type : <b>file of</b> component-type . file-variable :
+variable-access . final-value : expression . fixed-part :
+record-section { <b>;</b> record-section } . for-statement :
+<b>for</b> control-variable <b>:=</b> initial-value (
+<b>to</b> | <b>downto</b> ) final-value <b>do</b> statement
+. formal-parameter-list : <b>(</b> formal-parameter-section
+{ <b>;</b> formal-parameter-section } <b>)</b> .
+formal-parameter-section : value-parameter-specification |
+variable-parameter-specification |
+procedural-parameter-specification |
+functional-parameter-specification |
+conformant-array-parameter-specification . function-block :
+block . function-declaration : function-heading <b>;</b>
+directive | function-identification <b>;</b> function-block
+| function-heading <b>;</b> function-block .
+function-designator : function-identifier [
+actual-parameter-list ] . function-heading : <b>function</b>
+identifier [ formal-parameter-list ] <b>:</b> result-type .
+function-identification : <b>function</b>
+function-identifier . function-identifier : identifier .
+functional-parameter-specification : function-heading .</p>
+
+<p>goto-statement : <b>goto</b> label .</p>
+
+<p>identified-variable : pointer-variable <b>^</b> .
+identifier-list : identifier { <b>,</b> identifier } .
+if-statement : <b>if</b> Boolean-expression <b>then</b>
+statement [ else-part ] . index-expression : expression .
+index-type : ordinal-type . index-type-specification :
+identifier <b>..</b> identifier <b>:</b>
+ordinal-type-identifier . indexed-variable : array-variable
+<b>[</b> index-expression { <b>,</b> index-expression }
+<b>]</b> . initial-value : expression .</p>
+
+<p>label : digit-sequence . label-declaration-part : [
+<b>label</b> label { <b>,</b> label } <b>;</b> ] .</p>
+
+<p>member-designator : expression [ <b>..</b> expression ]
+. multiplying-operator : <b>*</b> | <b>/</b> | <b>div</b> |
+<b>mod</b> | <b>and</b> .</p>
+
+<p>new-ordinal-type : enumerated-type | subrange-type .
+new-pointer-type : <b>^</b> domain-type .
+new-structured-type : [ <b>packed</b> ]
+unpacked-structured-type . new-type : new-ordinal-type |
+new-structured-type | new-pointer-type .</p>
+
+<p>ordinal-type : new-ordinal-type |
+ordinal-type-identifier . ordinal-type-identifier :
+type-identifier .</p>
+
+<p>packed-conformant-array-schema : <b>packed array [</b>
+index-type-specification <b>] of</b> type-identifier .
+pointer-type-identifier : type-identifier . pointer-variable
+: variable-access . procedural-parameter-specification :
+procedure-heading . procedure-and-function-declaration-part
+: { ( procedure-declaration | function-declaration )
+<b>;</b> } . procedure-block : block . procedure-declaration
+: procedure-heading <b>;</b> directive |
+procedure-identification <b>;</b> procedure-block |
+procedure-heading <b>;</b> procedure-block .
+procedure-heading : <b>procedure</b> identifier [
+formal-parameter-list ] . procedure-identification :
+<b>procedure</b> procedure-identifier . procedure-identifier
+: identifier . procedure-statement : procedure-identifier (
+[ actual-parameter-list ] | read-parameter-list |
+readln-parameter-list | write-parameter-list |
+writeln-parameter-list ) . program : program-heading
+<b>;</b> program-block <b>.</b> . program-block : block .
+program-heading : <b>program</b> identifier [ <b>(</b>
+program-parameters <b>)</b> ] . program-parameters :
+identifier-list .</p>
+
+<p>read-parameter-list : <b>(</b> [ file-variable <b>,</b>
+] variable-access { <b>,</b> variable-access } <b>)</b> .
+readln-parameter-list : [ <b>(</b> ( file-variable |
+variable-access ) { <b>,</b> variable-access } <b>)</b> ] .
+record-section : identifier-list <b>:</b> type-denoter .
+record-type : <b>record</b> field-list <b>end</b> .
+record-variable : variable-access . record-variable-list :
+record-variable { <b>,</b> record-variable } .
+relational-operator : <b>=</b> | <b>&lt;&gt;</b> |
+<b>&lt;</b> | <b>&gt;</b> | <b>&lt;=</b> | <b>&gt;=</b> |
+<b>in</b> . repeat-statement : <b>repeat</b>
+statement-sequence <b>until</b> Boolean-expression .
+repetitive-statement : repeat-statement | while-statement |
+for-statement . result-type : simple-type-identifier |
+pointer-type-identifier .</p>
+
+<p>set-constructor : <b>[</b> [ member-designator {
+<b>,</b> member-designator } ] <b>]</b> . set-type : <b>set
+of</b> base-type . sign : <b>+</b> | <b>&minus;</b> .
+simple-expression : [ sign ] term { adding-operator term } .
+simple-statement : empty-statement | assignment-statement |
+procedure-statement | goto-statement .
+simple-type-identifier : type-identifier .</p>
+
+<p>statement : [ label <b>:</b> ] ( simple-statement |
+structured-statement ) . statement-part : compound-statement
+. statement-sequence : statement { <b>;</b> statement } .
+structured-statement : compound-statement |
+conditional-statement | repetitive-statement |
+with-statement . subrange-type : constant <b>..</b> constant
+.</p>
+
+<p>tag-field : identifier . tag-type :
+ordinal-type-identifier . term : factor {
+multiplying-operator factor } . type-definition : identifier
+<b>=</b> type-denoter . type-definition-part : [ <b>type</b>
+type-definition <b>;</b> { type-definition <b>;</b> } ] .
+type-denoter : type-identifier | new-type . type-identifier
+: identifier .</p>
+
+<p>unpacked-conformant-array-schema : <b>array [</b>
+index-type-specification { <b>;</b> index-type-specification
+} <b>] of</b> ( type-identifier | conformant-array-schema )
+. unpacked-structured-type : array-type | record-type |
+set-type | file-type . unsigned-constant : unsigned-number |
+character-string | constant-identifier | <b>nil</b> .
+unsigned-number : unsigned-integer | unsigned-real .</p>
+
+<p>value-conformant-array-specification : identifier-list
+<b>:</b> conformant-array-schema .
+value-parameter-specification : identifier-list <b>:</b>
+type-identifier . variable-access : entire-variable |
+component-variable | identified-variable | buffer-variable .
+variable-conformant-array-specification : <b>var</b>
+identifier-list <b>:</b> conformant-array-schema .
+variable-declaration : identifier-list <b>:</b> type-denoter
+. variable-declaration-part : [ <b>var</b>
+variable-declaration <b>;</b> { variable-declaration
+<b>;</b> } ] . variable-identifier : identifier .
+variable-parameter-specification : <b>var</b>
+identifier-list <b>:</b> type-identifier . variant :
+case-constant-list <b>: (</b> field-list <b>)</b> .
+variant-part : <b>case</b> variant-selector <b>of</b>
+variant { <b>;</b> variant } . variant-selector : [
+tag-field <b>:</b> ] tag-type .</p>
+
+<p>while-statement : <b>while</b> Boolean-expression
+<b>do</b> statement . with-statement : <b>with</b>
+record-variable-list <b>do</b> statement . write-parameter :
+expression [ <b>:</b> expression [ <b>:</b> expression ] ] .
+write-parameter-list : <b>(</b> [ file-variable <b>,</b> ]
+write-parameter { <b>,</b> write-parameter } <b>)</b> .
+writeln-parameter-list : [ <b>(</b> ( file-variable |
+write-parameter ) { <b>,</b> write-parameter } <b>)</b> ]
+.</p>
+
+<p><b>Appendix B: Changes to the run time library</b></p>
+
+<p>Some minor changes in the run time library have been
+made concerning the external files (i.e. program arguments).
+The old compiler reserved space for the file structures of
+the external files in one <b>hol</b> block. In the new
+compiler, every file structure is placed in a separate
+<b>bss</b> block. This implies that the arguments with which
+<i>_ini</i> is called are slightly different. The second
+argument was the base of the <b>hol</b> block to relocate
+the buffer addresses, it is changed into an integer denoting
+the size of the array passed as third argument. The third
+argument was a pointer to an array of integers containing
+the description of external files, this argument is changed
+into a pointer to an array of pointers to file
+structures.</p>
+
+<p>The differences in the generated EM code for an
+arbitrary Pascal program are listed below (only the relevant
+parts are shown):</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre><b>program</b> external_files(output,f);
+<b>var
+</b></pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+
+<p>f : <b>file of</b> <i>some-type</i>;</p>
+</td>
+<td width="69%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>.<br>
+.<b><br>
+end</b>.</p>
+<!-- INDENTATION -->
+<p>EM code generated by Pascal-VU:<br>
+.<br>
+.<br>
+hol 1088,-2147483648,0 ; space belonging to file structures
+of the program arguments<br>
+.<br>
+.<br>
+.<br>
+.2<br>
+con 3, -1, 544, 0 ; description of external files<br>
+lxl 0<br>
+lae .2<br>
+lae 0 ; base of hol block, to relocate buffer addresses<br>
+lxa 0<br>
+cal $_ini<br>
+asp 16<br>
+.<br>
+.</p>
+<!-- INDENTATION -->
+<p>EM code generated by our compiler:<br>
+.<br>
+.<br>
+f<br>
+bss 540,0,0 ; space belonging to file structure of program
+argument f<br>
+output<br>
+bss 540,0,0 ; space belonging to file structure of standard
+output</p>
+</td>
+</table>
+
+<p>. . . .2 con 0U4, output, f ; the absence of standard
+input is denoted by a null pointer lxl 0 lae .2 loc 3 ;
+denotes the size of the array of pointers to file structures
+lxa 0 cal $_ini asp 16 . .</p>
+
+<p>The following files in the run time library have been
+changed:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="98%">
+<p>pc_file.h hlt.c ini.c opn.c pentry.c pexit.c</p></td>
+</table>
+
+<p><b>Appendix C: An example</b></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>1</p>
+<td width="1%"></td>
+<td width="8%"></td>
+<td width="10%">
+
+<p><b>program</b> factorials(input, output);<br>
+2</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="8%"></td>
+<td width="10%">
+
+<p>{ This program prints factorials }</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p>3</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>4</p>
+<td width="1%"></td>
+<td width="8%"></td>
+<td width="10%">
+
+<p><b>const</b><br>
+5</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="8%"></td>
+<td width="10%">
+
+<p>FAC1 = 1;<br>
+6</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="8%"></td>
+<td width="10%">
+
+<p><b>var</b><br>
+7</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="8%"></td>
+<td width="10%">
+
+<p>i : integer;</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p>8</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>9</p>
+</td>
+<td width="10%">
+
+<p><b>function</b> factorial(n : integer) : integer;</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>10</p>
+</td>
+<td width="10%">
+
+<p><b>begin</b></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>11</p>
+</td>
+<td width="10%">
+
+<p><b>if</b> n = FAC1 <b>then</b></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>12</p>
+</td>
+<td width="10%">
+
+<p>factorial := FAC1</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>13</p>
+</td>
+<td width="10%">
+
+<p><b>else</b></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>14</p>
+</td>
+<td width="10%">
+
+<p>factorial := n * factorial(n-1);</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>15</p>
+</td>
+<td width="10%">
+
+<p><b>end</b>;</p>
+</td>
+<td width="79%">
+</td>
+</table>
+
+<p>16</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>17</p>
+</td>
+<td width="10%">
+
+<p><b>begin</b></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>18</p>
+</td>
+<td width="10%">
+
+<p>write(&rsquo;Give a number : &rsquo;);</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>19</p>
+</td>
+<td width="10%">
+
+<p>readln(i);</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>20</p>
+</td>
+<td width="10%">
+
+<p><b>if</b> i &lt; 1 <b>then</b></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>21</p>
+</td>
+<td width="10%">
+
+<p>writeln(&rsquo;No factorial&rsquo;)</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>22</p>
+</td>
+<td width="10%">
+
+<p><b>else</b></p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>23</p>
+</td>
+<td width="10%">
+
+<p>writeln(factorial(i):1);</p>
+</td>
+<td width="79%">
+</td>
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>24</p>
+</td>
+<td width="10%">
+
+<p><b>end</b>.</p>
+</td>
+<td width="79%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="11" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>mes 2,4,4</p>
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>loc 16<br>
+.1</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_wrs<br>
+rom &rsquo;factorials.p\000&rsquo;</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 12<br>
+i</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lin 19<br>
+bss 4,0,0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lae input<br>
+output</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_rdi<br>
+bss 540,0,0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 4<br>
+input</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lfr 4<br>
+bss 540,0,0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>ste i<br>
+exp $factorial</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lae input<br>
+pro $factorial, ?</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_rln<br>
+mes 9,4</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 4<br>
+lin 11</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lin 20<br>
+lol 0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>loe i<br>
+loc 1</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>loc 1<br>
+cmi 4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cmi 4<br>
+teq</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>tlt<br>
+zeq *1</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>zeq *1<br>
+lin 12</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lin 21<br>
+loc 1</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>.4<br>
+stl -4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>rom &rsquo;No factorial&rsquo;<br>
+bra *2</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lae output<br>
+1</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lae .4<br>
+lin 14</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>loc 12<br>
+lol 0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_wrs<br>
+lol 0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 12<br>
+loc 1</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lae output<br>
+sbi 4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_wln<br>
+cal $factorial</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 4<br>
+asp 4</p>
+</td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>bra *2<br>
+lfr 4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>1<br>
+mli 4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lin 23<br>
+stl -4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lae output<br>
+2</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>loe i<br>
+lin 15</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $factorial<br>
+mes 3,0,4,0,0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 4<br>
+lol -4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lfr 4<br>
+ret 4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>loc 1<br>
+end 4</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_wsi<br>
+exp $m_a_i_n</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 12<br>
+pro $m_a_i_n, ?</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lae output<br>
+mes 9,0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_wln<br>
+fil .1</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>asp 4<br>
+.2</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>2<br>
+con input, output</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>lin 24<br>
+lxl 0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>loc 0<br>
+lae .2</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>cal $_hlt<br>
+loc 2</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>end 0<br>
+lxa 0</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>mes 4,24,&rsquo;factorials.p\000&rsquo;</p>
+</td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+</table>
+
+<p>cal $_ini asp 16 lin 18 .3 rom &rsquo;Give a number :
+&rsquo; lae output lae .3</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/pascal.pdf b/src/olddocs/pascal.pdf
new file mode 100644 (file)
index 0000000..34ea952
Binary files /dev/null and b/src/olddocs/pascal.pdf differ
diff --git a/src/olddocs/pcref.html b/src/olddocs/pcref.html
new file mode 100644 (file)
index 0000000..5486ff3
--- /dev/null
@@ -0,0 +1,2036 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:13 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title></title>
+</head>
+<body>
+
+<hr>
+
+<p align=center><b>Amsterdam Compiler Kit-Pascal reference
+manual</b></p>
+
+<p align=center>by</p>
+
+<p align=center>Johan W. Stevenson</p>
+
+<p align=center>( January 4, 1983 )</p>
+
+<p align=center>(revised)</p>
+
+<p align=center>Hans van Eck</p>
+
+<p align=center>( May 1, 1989 )</p>
+
+<p align=center>Vakgroep Informatica<br>
+Vrije Universiteit<br>
+De Boelelaan 1081<br>
+Amsterdam</p>
+
+<p><b>1. Introduction</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This document refers to the (1982) BSI standard for
+Pascal [1]. Ack-Pascal complies with the requirements of
+level 1 of BS 6192: 1982, with the exceptions as listed in
+this document.</p>
+<!-- INDENTATION -->
+<p>The standard requires an accompanying document describing
+the implementation-defined and implementation-dependent
+features, the reaction on errors and the extensions to
+standard Pascal. These four items will be treated in the
+rest of this document, each in a separate chapter. The other
+chapters describe the deviations from the standard and the
+list of options recognized by the compiler.</p>
+<!-- INDENTATION -->
+<p>The Ack-Pascal compiler produces code for an EM machine
+as defined in [2]. It is up to the implementor of the EM
+machine to decide whether errors like integer overflow,
+undefined operand and range bound error are recognized or
+not.</p>
+<!-- INDENTATION -->
+<p>There does not (yet) exist a hardware EM machine.
+Therefore, EM programs must be interpreted, or translated
+into instructions for a target machine. The Ack-Pascal
+compiler is currently available for use with the VAX,
+Motorola MC68020, Motorola MC68000, PDP-11, and Intel 8086
+code-generators. For the 8086, MC68000, and MC68020,
+floating point emulation is used. This is made available
+with the <i>-fp</i> option, which must be passed to
+<i>ack</i>[3].</p></td>
+</table>
+
+<p><b>2. Implementation-defined features</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>For each implementation-defined feature mentioned in the
+BSI standard we give the section number, the quotation from
+that section and the definition. First we quote the
+definition of implementation-defined:</p>
+<!-- INDENTATION -->
+<p>Possibly differing between processors, but defined for
+any particular processor.</p></td>
+</table>
+
+<p><b>BS 6.1.7:</b> Each string-character shall denote an
+implementation-defined value of the required char-type.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>All 7-bits ASCII characters except linefeed LF (10) are
+allowed.</p></td>
+</table>
+
+<p><b>BS 6.4.2.2:</b> The values of type real shall be an
+implementation-defined subset of the real numbers denoted as
+specified by 6.1.5 bu signed real.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The format of reals is not defined in EM. Even the size
+of reals depends on the EM-implementation. The compiler can
+be instructed, by the V-option, to use a different size for
+real values. The size of reals is preset by the calling
+program <i>ack</i> [3] to the proper size.</p></td>
+</table>
+
+<p><b>BS 6.4.2.2:</b> The type char shall be the
+enumeration of a set of implementation-defined characters,
+some possibly without graphic representations.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The 7-bits ASCII character set is used, where LF (10)
+denotes the end-of-line marker on text-files.</p>
+</td>
+</table>
+
+<p><b>BS 6.4.2.2:</b> The ordinal numbers of the character
+values shall be values of integer-type, that are
+implementation-defined, and that are determined by mapping
+the character values on to consecutive non-negative integer
+values starting at zero.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The normal ASCII ordering is used:
+ord(&rsquo;0&rsquo;)=48, ord(&rsquo;A&rsquo;)=65,
+ord(&rsquo;a&rsquo;)=97, etc.</p></td>
+</table>
+
+<p><b>BS 6.6.5.2:</b> The post-assertions imply
+corresponding activities on the external entities, if any,
+to which the file-variables are bound. These activities, and
+the point at which they are actually performed, shall be
+implementation-defined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The reading and writing writing of objects on files is
+buffered. This means that when a program terminates
+abnormally, IO may be unfinished. Terminal IO is unbuffered.
+Files are closed whenever they are rewritten or reset, or on
+program termination.</p>
+</td>
+</table>
+
+<p><b>BS 6.7.2.2:</b> The predefined constant maxint shall
+be of integer-type and shall denote an
+implementation-defined value, that satisfies the</p>
+
+<p>following conditions:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="1%"></td>
+<td width="98%">
+<p>(a) All integral values in the closed interval from
+-maxint to +maxint shall be values of the integer-type. (b)
+Any monadic operation performed on an integer value in this
+interval shall be correctly performed according to the
+mathematical rules for integer arithmetic. (c) Any dyadic
+integer operation on two integer values in this same
+interval shall be correctly performed according to the
+mathematical rules for integer arithmetic, provided that the
+result is also in this interval. (d) Any relational
+operation on two integer values in this same interval shall
+be correctly performed according to the mathematical rules
+for integer arithmetic.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The representation of integers in EM is a <i>n</i>*8-bit
+word using two&rsquo;s complement arithmetic. Where <i>n</i>
+is called wordsize. The range of available integers depends
+on the EM implementation: For 2-byte machines, the integers
+range from -32767 to +32767. For 4-byte machines, the
+integers range from -2147483647 to 2147483647. The number
+-maxint-1 may be used to indicate
+&rsquo;undefined&rsquo;.</p></td>
+</table>
+
+<p><b>BS 6.7.2.2:</b> The result of the real arithmetic
+operators and functions shall be approximations to the
+corresponding mathematical results. The accuracy of this
+approximation shall be implementation-defined</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Since EM doesn&rsquo;t specify floating point format, it
+is not possible to specify the accuracy. When the floating
+point emulation is used, and the default size of reals is 8
+bytes, the accuracy is 11 bits for the exponent, and 53 bits
+for the mantissa. This gives an accuracy of about 16 digits,
+and exponents ranging from -309 to +307.</p></td>
+</table>
+
+<p><b>BS 6.9.3.1:</b> The default TotalWidth values for
+integer, Boolean and real types shall be
+implementation-defined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The defaults are: integer 6 for 2-byte machines, 11 for
+4-byte machines Boolean 5 real 14</p>
+</td>
+</table>
+
+<p><b>BS 6.9.3.4.1:</b> ExpDigits, the number of digits
+written in an exponent part of a real, shall be
+implementation-defined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>ExpDigits is defined as 3. This is sufficient for all
+implementations currently available. When the representation
+would need more than 3 digits, then the string
+&rsquo;***&rsquo; replaces the exponent.</p>
+</td>
+</table>
+
+<p><b>BS 6.9.3.4.1:</b> The character written as part of
+the representation of a real to indicate the beginning of
+the exponent part shall be implementation-defined, either
+&rsquo;E&rsquo; or &rsquo;e&rsquo;.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The exponent part starts with &rsquo;e&rsquo;.</p>
+</td>
+</table>
+
+<p><b>BS 6.9.3.5:</b> The case of the characters written as
+representation of the Boolean values shall be
+implementation-defined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The representations of true and false are
+&rsquo;true&rsquo; and &rsquo;false&rsquo;.</p>
+</td>
+</table>
+
+<p><b>BS 6.9.5:</b> The effect caused by the standard
+procedure page on a text file shall be
+implementation-defined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The ASCII character form feed FF (12) is written.</p>
+</td>
+</table>
+
+<p><b>BS 6.10:</b> The binding of the variables denoted by
+the program-parameters to entities external to the program
+shall be implementation-defined if the variable is of a
+file-type.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The program parameters must be files and all, except
+input and output, must be declared as such in the program
+block.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>The program parameters input and output, if specified,
+will correspond with the UNIX streams &rsquo;standard
+input&rsquo; and &rsquo;standard output&rsquo;.</p>
+<!-- INDENTATION -->
+<p>The other program parameters will be mapped to the
+argument strings provided by the caller of this program. The
+argument strings are supposed to be path names of the files
+to be opened or created. The order of the program parameters
+determines the mapping: the first parameter is mapped onto
+the first argument string etc. Note that input and output
+are ignored in this mapping.</p>
+<!-- INDENTATION -->
+<p>The mapping is recalculated each time a program parameter
+is opened for reading or writing by a call to the standard
+procedures reset or rewrite. This gives the programmer the
+opportunity to manipulate the list of string arguments using
+the external procedures argc, argv and argshift available in
+libpc [6].</p>
+</td>
+</table>
+
+<p><b>BS 6.10:</b> The effect of an explicit use of reset
+or rewrite on the standard textfiles input or output shall
+be implementation-defined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The procedures reset and rewrite are no-ops if applied to
+input or output.</p></td>
+</table>
+
+<p><b>3. Implementation-dependent features</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>For each implementation-dependent feature mentioned in
+the BSI standard, we give the section number, the quotation
+from that section and the way this feature is treated by the
+Ack-Pascal system. First we quote the definition of
+&rsquo;implementation-dependent&rsquo;:</p>
+<!-- INDENTATION -->
+<p>Possibly differing between processors and not necessarily
+defined for any particular processor.</p></td>
+</table>
+
+<p><b>BS 6.7.2.1:</b> The order of evaluation of the
+operands of a dyadic operator shall be
+implementation-dependent.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Operands are always evaluated, so the program part</p>
+<!-- INDENTATION -->
+<p>if (p&lt;&gt;nil) and (p^.value&lt;&gt;0) then</p>
+<!-- INDENTATION -->
+<p>is probably incorrect.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>The left-hand operand of a dyadic operator is almost
+always evaluated before the right-hand side. Some peculiar
+evaluations exist for the following cases:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="11%"></td>
+<td width="88%">
+<p>1. the modulo operation is performed by a library routine
+to check for negative values of the right operand.</p>
+<!-- INDENTATION -->
+<p>2. the expression</p>
+<!-- INDENTATION -->
+<pre>        set1 &lt;= set2
+</pre>
+<!-- INDENTATION -->
+<p>where set1 and set2 are compatible set types is evaluated
+in the following steps:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>- evaluate set2<br>
+- evaluate set1<br>
+- compute set2+set1<br>
+- test set2 and set2+set1 for equality</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="11%"></td>
+<td width="88%">
+<p>3. the expression</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>set1 &gt;= set2</p>
+<!-- INDENTATION -->
+<p>where set1 and set2 are compatible set types is evaluated
+in the following steps:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>- evaluate set1<br>
+- evaluate set2<br>
+- compute set1+set2<br>
+- test set1 and set1+set2 for equality</p></td>
+</table>
+
+<p><b>BS 6.7.3:</b> The order of evaluation, accessing and
+binding of the</p>
+
+<p>actual-parameters for functions shall be
+implementation-dependent.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The order of evaluation is from right to left.</p>
+</td>
+</table>
+
+<p><b>BS 6.8.2.2:</b> The decision as to the order of
+accessing the variable and evaluating the expression in an
+assignment-statement, shall be implementation-dependent.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The expression is evaluated first.</p>
+</td>
+</table>
+
+<p><b>BS 6.8.2.3:</b> The order of evaluation and binding
+of the actual-parameters for procedures shall be
+implementation-dependent.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The same as for functions.</p>
+</td>
+</table>
+
+<p><b>BS 6.9.5:</b> The effect of inspecting a text file to
+which the page procedure was applied during generation is
+implementation-dependent.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The formfeed character written by page is treated like a
+normal character, with ordinal value 12.</p>
+</td>
+</table>
+
+<p><b>BS 6.10:</b> The binding of the variables denoted by
+the program-parameters to entities external to the program
+shall be implementation-dependent unless the variable is of
+a file-type.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Only variables of a file-type are allowed as program
+parameters.</p></td>
+</table>
+
+<p><b>4. Error handling</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>There are three classes of errors to be distinguished. In
+the first class are the error messages generated by the
+compiler. The second class consists of the occasional errors
+generated by the other programs involved in the compilation
+process. Errors of the third class are the errors as defined
+in the standard by:</p>
+<!-- INDENTATION -->
+<p>An error is a violation by a program of the requirements
+of this standard that a processor is permitted to leave
+undetected.</p></td>
+</table>
+
+<p><b>4.1. Compiler errors</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Error are written on the standard error output. Each line
+has the form:</p></td>
+</table>
+
+<p>&lt;file&gt;, line &lt;number&gt;:
+&lt;description&gt;<br>
+Every time the compiler detects an error that does not have
+influence on the code produced by the compiler or on the
+syntax decisions, a warning messages is given. If only
+warnings are generated, compilation proceeds and probably
+results in a correctly compiled program.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Sometimes the compiler produces several errors for the
+same line. They are only shown up to a maximum of 5 errors
+per line. Warning are also shown up to a maximum of 5 per
+line.</p>
+<!-- INDENTATION -->
+<p>Extensive treatment of these errors is outside the scope
+of this manual.</p>
+</td>
+</table>
+
+<p><b>4.2. Runtime errors</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Errors detected at run time cause an error message to be
+generated on the diagnostic output stream (UNIX file
+descriptor 2). The message consists of the name of the
+program followed by a message describing the error, possibly
+followed by the source line number. Unless the -L-option is
+turned on, the compiler generates code to keep track of
+which source line causes which EM instructions to be
+generated. It depends on the EM implementation whether these
+LIN instructions are skipped or executed.</p>
+<!-- INDENTATION -->
+<p>For each error mentioned in the standard we give the
+section number, the quotation from that section and the way
+it is processed by the Pascal-compiler or runtime
+system.</p>
+<!-- INDENTATION -->
+<p>For detected errors the corresponding message and trap
+number are given. Trap numbers are useful for
+exception-handling routines. Normally, each error causes the
+program to terminate. By using exception-handling routines
+one can ignore errors or perform alternate actions. Only
+some of the errors can be ignored by restarting the failing
+instruction. These errors are marked as non-fatal, all
+others</p></td>
+</table>
+
+<p>as fatal. A list of errors with trap number between 0
+and 63 (EM errors) can be found in [2]. Errors with trap
+number between 64 and 127 (Pascal errors) are listed in
+[7].</p>
+
+<p><b>BS 6.4.6:</b> It shall be an error if a value of type
+T2 must be assignment-compatible with type T1, while T1 and
+T2 are compatible ordinal-types and the value of type T2 is
+not in the closed interval specified by T1.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The compiler distinguishes between array-index
+expressions and the other places where
+assignment-compatibility is required.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Array subscripting is done using the EM array
+instructions. These instructions have three arguments: the
+array base address, the index and the address of the array
+descriptor. An array descriptor describes one dimension by
+three values: the lower bound on the index, the number of
+elements minus one and the element-size. It depends on the
+EM implementation whether these bounds are checked. Since
+most implementations don&rsquo;t, an extra compiler flag is
+added to force these checks.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The other places where assignment-compatibility is
+required are:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>- assignment<br>
+- value parameters<br>
+- procedures read and readln<br>
+- the final value of the for-statement</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>For these places the compiler generates an EM range check
+instruction, except when the R-option is turned on, or when
+the range of values of T2 is enclosed in the range of T1. If
+the expression consists of a single variable and if that
+variable is of a subrange type, then the subrange type
+itself is taken as T2, not its host-type. Therefore, a range
+instruction is only generated if T1 is a subrange type and
+if the expression is a constant, an expression with two or
+more operands, or a single variable with a type not enclosed
+in T1. If a constant is assigned, then the EM optimizer
+removes the range check instruction, except when the value
+is out of bounds.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>It depends on the EM implementation whether the range
+check instruction is executed or skipped.</p>
+</td>
+</table>
+
+<p><b>BS 6.4.6:</b> It shall be an error if a value of type
+T2 must be assignment-compatible with type T1, while T1 and
+T2 are compatible set-types and any member of the value of
+type T2 is not in the closed interval specified by the
+base-type of the type T1.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is not detected.</p>
+</td>
+</table>
+
+<p><b>BS 6.5.3.3:</b> It shall be an error if a component
+of a variant-part of a variant, where the selector of the
+variant-part is not a field, is accessed unless the variant
+is active for the entirety of each reference and access to
+each component of the variant.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is not detected.</p>
+</td>
+</table>
+
+<p><b>BS 6.5.4:</b> It shall be an error if the
+pointer-variable of an identified-variable either denotes a
+nil-value or is undefined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The EM definition does not specify the binary
+representation of pointer values, so that it is not possible
+to choose an otherwise illegal binary representation for the
+pointer value NIL. Rather arbitrary the compiler uses the
+integer value zero to represent NIL. For all current
+implementations this does not cause problems.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>The size of pointers depends on the implementation and is
+preset in the compiler by <i>ack</i> [3]. The compiler can
+be instructed, by the V-option, to use another size for
+pointer objects. NIL is represented here by the appropriate
+number of zero words.</p>
+<!-- INDENTATION -->
+<p>It depends on the EM implementation whether
+de-referencing of a pointer with value NIL causes an
+error.</p></td>
+</table>
+
+<p><b>BS 6.5.4:</b> It shall be an error to remove the
+identifying-value of an identified variable from its
+pointer-type when a reference to the variable exists.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>When the identified variable is an element of the
+record-variable-list of a with_statement, a warning is given
+at compile-time. Otherwise, this error is not detected.</p>
+</td>
+</table>
+
+<p><b>BS 6.5.5:</b> It shall be an error to alter the value
+of a file-variable f when a reference to the buffer-variable
+f^ exists.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>When f is altered when it is an element of the
+record-variable-list of a with-statement, a warning is
+given. When a buffer-variable is used as a
+variable-parameter, an error is given. This is done at
+compile-time.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.5.2:</b> It shall be an error if the stated
+pre-assertion does not hold immediately prior to any use of
+the file handling procedures rewrite, put, reset and
+get.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>For each of these four operations the pre-assertions can
+be reformulated as:</p>
+<!-- INDENTATION -->
+<p>rewrite(f): no pre-assertion.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>put(f): f is opened for writing and f^ is not
+undefined.<br>
+reset(f): f exists.<br>
+get(f): f is opened for reading and eof(f) is false.</p>
+<!-- INDENTATION -->
+<p>The following errors are detected for these
+operations:</p>
+<!-- INDENTATION -->
+<p>rewrite(f):</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>more args expected, trap 64, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>f is a program-parameter and the corresponding file name
+is not supplied by the caller of the program.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>rewrite error, trap 101, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>the caller of the program lacks the necessary access
+rights to create the file in the file system or
+operating</p></td>
+</table>
+
+<p>system problems like table overflow prevent creation of
+the file.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>put(f):</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>file not yet open, trap 72, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>reset or rewrite are never applied to the file. The
+checks performed by the run time system are not
+foolproof.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>not writable, trap 96, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>f is opened for reading.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>write error, trap 104, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>probably caused by file system problems. For instance,
+the file storage is exhausted. Because IO is buffered to
+improve performance, it might happen that this error occurs
+if the file is closed. Files are closed whenever they are
+rewritten or reset, or on program termination.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>reset(f):</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>more args expected, trap 64, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>same as for rewrite(f).</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>reset error, trap 100, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>f does not exist, or the caller has insufficient access
+rights, or operating system tables are exhausted.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>get(f):</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>file not yet open, trap 72, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>as for put(f).</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>not readable, trap 97, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>f is opened for writing.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>end of file, trap 98, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>eof(f) is true just before the call to get(f).</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>read error, trap 103, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>unlikely to happen. Probably caused by hardware problems
+or by errors elsewhere in the program that destroyed the
+file information maintained by the run time system.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>truncated, trap 99, fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>the file is not properly formed by an integer number of
+file elements. For instance, the size of a file of integer
+is odd.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>non-ASCII char read, trap 106, non-fatal:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>the character value of the next character-type file
+element is out of range (0..127). Only for text
+files.</p></td>
+</table>
+
+<p><b>BS 6.6.5.3:</b> It shall be an error if a variant of
+a variant-part within the new variable becomes active and a
+different variant of the variant-part is one of the
+specified variants.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is not detected.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.5.3:</b> It shall be an error to use
+dispose(q) if the identifying variable has been allocated
+using the form new(p,c1,...,cn).</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is not detected. However, this error can cause
+more memory to be freed then was allocated. Dispose causes a
+fatal trap 73 when memory already on the free list is freed
+again.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.5.3:</b> It shall be an error to use
+dispose(q,k1,...,km) if the identifying variable has been
+allocated using the form new(p,c1,...,cn) and m is not equal
+to n.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is not detected. However, this error can cause
+more memory to be freed then was allocated. Dispose causes a
+fatal trap 73 when memory already on the free list is freed
+again.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.5.3:</b> It shall be an error if the variants
+of a variable to be disposed are different from those
+specified by the case-constants to dispose.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is not detected.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.5.3:</b> It shall be an error if the value of
+the pointer parameter of dispose has nil-value or is
+undefined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The same comments apply as for de-referencing NIL or
+undefined pointers.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.5.3:</b> It shall be an error if a variable
+created using the second form of new is accessed by the
+identified variable of the variable-access of a factor, of
+an assignment-statement, or of an actual-parameter.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is not detected.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.2:</b> It shall be an error if the value of
+sqr(x) does not exist.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected for real-type arguments (real
+overflow, trap 4, non-fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.2:</b> It shall be an error if x in ln(x) is
+smaller than or equal to 0.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (error in ln, trap 66,
+non-fatal)</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.2:</b> It shall be an error if x in sqrt(x)
+is smaller than 0.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (error in sqrt, trap 67,
+non-fatal)</p>
+<!-- INDENTATION -->
+<p>In addition to these errors, overflow in the expression
+exp(x) is detected (error in exp, trap 65, non-fatal; real
+overflow, trap 4, non-fatal)</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.3:</b> It shall be an error if the integer
+value of trunc(x) does not exist.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>It depends on the implementations whether this error is
+detected. The floating-point emulation detects this error
+(conversion error, trap 10, non-fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.3:</b> It shall be an error if the integer
+value of round(x) does not exist.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>It depends on the implementations whether this error is
+detected. The floating-point emulation detects this error
+(conversion error, trap 10, non-fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.4:</b> It shall be an error if the integer
+value of ord(x) does not exist.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error can not occur, because the compiler will not
+allow such ordinal types.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.4:</b> It shall be an error if the character
+value of chr(x) does not exist.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Except when the R-option is off, the compiler generates
+an EM range check instruction. The effect of this
+instruction depends on the EM implementation.</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.4:</b> It shall be an error if the value of
+succ(x) does not exist.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Same comments as for chr(x).</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.4:</b> It shall be an error if the value of
+pred(x) does not exist.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Same comments as for chr(x).</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.5:</b> It shall be an error if f in eof(f)
+is undefined.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (file not yet open, trap 72,
+fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.6.6.5:</b> It shall be an error if f in eoln(f)
+is undefined, or if eof(f) is true at that time.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The following errors may occur:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>file not yet open, trap 72, fatal;<br>
+not readable, trap 97, fatal;<br>
+end of file, trap 98, fatal.</p></td>
+</table>
+
+<p><b>BS 6.7.1:</b> It shall be an error if a
+variable-access used as an operand in an expression is
+undefined at the time of its use.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The compiler performs some limited checks to see if
+identifiers are used before they are set. Since it can not
+always be sure (one could, for instance, jump out of a
+loop), only a warning is generated. When an expression
+contains a function-call, an error occur if the function is
+not assigned at run-time.</p>
+</td>
+</table>
+
+<p><b>BS 6.7.2.2:</b> A term of the form x/y shall be an
+error if y is zero.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>It depends on the EM implementation whether this error is
+detected. On some machines, a trap may occur.</p>
+</td>
+</table>
+
+<p><b>BS 6.7.2.2:</b> It shall be an error if j is zero in
+&rsquo;i div j&rsquo;.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>It depends on the EM implementation whether this error is
+detected. On some machines, a trap may occur.</p></td>
+</table>
+
+<p><b>BS 6.7.2.2:</b> It shall be an error if j is zero or
+negative in i MOD j.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (only positive j in &rsquo;i mod
+j&rsquo;, trap 71, non-fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.7.2.2:</b> It shall be an error if the result of
+any operation on integer operands is not performed according
+to the mathematical rules for integer arithmetic.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The reaction depends on the EM implementation. Most
+implementations, however, will not notice integer
+overflow.</p>
+</td>
+</table>
+
+<p><b>BS 6.8.3.5:</b> It shall be an error if none of the
+case-constants is equal to the value of the case-index upon
+entry to the case-statement.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (case error, trap 20, fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.9.1:</b> It shall be an error if the sequence of
+characters read looking for an integer does not form a
+signed-integer as specified in 6.1.5.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (digit expected, trap 105,
+non-fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.9.1:</b> It shall be an error if the sequence of
+characters read looking for a real does not form a
+signed-number as specified in 6.1.5.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (digit expected, trap 105,
+non-fatal).</p>
+</td>
+</table>
+
+<p><b>BS 6.9.1:</b> When read is applied to f, it shall be
+an error if the buffer-variable f^ is undefined or the
+pre-assertions for get do not hold.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (see get(f)).</p>
+</td>
+</table>
+
+<p><b>BS 6.9.3:</b> When write is applied to a textfile f,
+it shall be an error if f is undefined or f is opened for
+reading.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (see put(f)). Furthermore, this
+error is also detected when f is not a textfile.</p>
+</td>
+</table>
+
+<p><b>BS 6.9.3.1:</b> The values of TotalWidth or
+FracDigits shall be greater than or equal to one; it shall
+be an error if either value is less then one.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>When either value is less than zero, an error (illegal
+field width, trap 75, non-fatal) occurs. Zero values are
+allowed, in order to maintain some compatibility with the
+old Ack-Pascal compiler.</p>
+</td>
+</table>
+
+<p><b>BS 6.9.5:</b> It shall be an error if the
+pre-assertion required for writeln(f) doe not hold prior to
+the invocation of page(f);</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>This error is detected (see put(f)).</p></td>
+</table>
+
+<p><b>5. Extensions to the standard</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>1. External routines</p>
+<!-- INDENTATION -->
+<p>Except for the required directive &rsquo;forward&rsquo;
+the Ack-Pascal compiler recognizes the directive
+&rsquo;extern&rsquo;. This directive tells the compiler that
+the procedure block of this procedure will not be present in
+the current program. The code for the body of this procedure
+must be included at a later stage of the compilation
+process.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>This feature allows one to build libraries containing
+often used routines. These routines do not have to be
+included in all the programs using them. Maintenance is much
+simpler if there is only one library module to be changed
+instead of many Pascal programs.</p>
+<!-- INDENTATION -->
+<p>Another advantage is that these library modules may be
+written in a different language, for instance C or the EM
+assembly language. This is useful for accessing some
+specific EM instructions not generated by the Pascal
+compiler. Examples are the system call routines and some
+floating point conversion routines. Another motive could be
+the optimization of some time-critical program parts.</p>
+<!-- INDENTATION -->
+<p>The use of external routines, however, is dangerous. The
+compiler normally checks for the correct number and type of
+parameters when a procedure is called and for the result
+type of functions. If an external routine is called these
+checks are not sufficient, because the compiler can not
+check whether the procedure heading of the external routine
+as given in the Pascal program matches the actual routine
+implementation. It should be the loader&rsquo;s task to
+check this. However, the current loaders are not that smart.
+Another solution is to check at run time, at least the
+number of words for parameters. Some EM implementations
+check this.</p>
+<!-- INDENTATION -->
+<p>For those who wish the use the interface between C and
+Pascal we give an incomplete list of corresponding formal
+parameters in C and Pascal.</p>
+<!-- INDENTATION -->
+<p>HTML-IMAGE.nr 3c 0</p>
+<!-- INDENTATION -->
+<pre>Pascal                  C
+
+
+
+
+
+a:integer               int a
+
+
+
+
+
+a:char                  int a
+
+
+
+
+
+a:boolean               int a
+
+
+
+
+
+a:real                  double a
+
+
+
+
+
+a:^type                 type *a
+
+
+
+
+
+var a:type              type *a
+
+
+
+
+
+procedure a(pars)       struct {
+
+
+
+
+
+                        void (*a)() ;
+
+
+
+
+
+                        char *static_link ;
+
+
+
+
+
+                   }
+
+
+
+
+
+function a(pars):type   struct {
+
+
+
+
+
+                        type (*a)() ;
+
+
+
+
+
+                        char *static_link ;
+
+
+
+
+
+                   }
+
+
+
+</pre>
+<!-- INDENTATION -->
+<p>HTML-IMAGE-ENDThe Pascal runtime system uses the
+following algorithm when calling function/procedures passed
+as parameters. HTML-IMAGE.nr 3c 0</p>
+<!-- INDENTATION -->
+<pre>if ( static_link )   (*a)(static_link,pars) ;
+
+
+
+
+
+else                 (*a)(pars) ;
+
+
+
+</pre>
+<!-- INDENTATION -->
+<p>HTML-IMAGE-END.ti -3 2. Separate compilation.</p>
+<!-- INDENTATION -->
+<p>The compiler is able to (separately) compile a collection
+of declarations, procedures and functions to form a library.
+The library may be linked with the main program, compiled
+later. The syntax of these modules is</p>
+<!-- INDENTATION -->
+<pre>module = [constant-definition-part]
+         [type-definition-part]
+         [var-declaration-part]
+         [procedure-and-function-declaration-part]
+</pre>
+<!-- INDENTATION -->
+<p>The compiler accepts a program or a module:</p>
+<!-- INDENTATION -->
+<pre>unit = program | module
+</pre>
+<!-- INDENTATION -->
+<p>All variables declared outside a module must be imported
+by parameters, even the files input and output. Access to a
+variable declared in a module is only possible using the
+procedures and functions declared in that same module. By
+giving the correct procedure/function heading followed by
+the directive &rsquo;extern&rsquo; procedures and functions
+declared in other units may be used.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>3. Assertions.</p>
+<!-- INDENTATION -->
+<p>When the s-option is off, Ack-Pascal compiler recognizes
+an additional statement, the assertion. Assertions can be
+used as an aid in debugging and documentation. The syntax
+is:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>assertion = &rsquo;assert&rsquo; Boolean-expression</p>
+<!-- INDENTATION -->
+<p>An assertion is a simple-statement, so</p>
+<!-- INDENTATION -->
+<pre>simple-statement = [assignment-statement |
+                    procedure-statement |
+                    goto-statement |
+                    assertion
+                   ]
+</pre>
+<!-- INDENTATION -->
+<p>An assertion causes an error if the Boolean-expression is
+false. That is its only purpose. It does not change any of
+the variables, at least it should not. Therefore, do not use
+functions with side-effects in the Boolean-expression. If
+the a-option is turned on, then assertions are skipped by
+the compiler. &rsquo;assert&rsquo; is not a word-symbol
+(keyword) and may be used as identifier. However, assignment
+to a variable and calling of a procedure with that name will
+be impossible. If the s-option is turned on, the compiler
+will not know a thing about assertions, so using assertions
+will then give a parse error.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>4. Additional procedures.</p>
+<!-- INDENTATION -->
+<p>Three additional standard procedures are available:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="11%"></td>
+<td width="88%">
+<p>halt: a call of this procedure is equivalent to jumping
+to the end of the program. It is always the last statement
+executed. The exit status of the program may be supplied as
+optional argument. If not, it will be zero. release: mark:
+for most applications it is sufficient to use the heap as
+second stack. Mark and release are suited for this type of
+use, more suited than dispose. mark(p), with p of type
+pointer, stores the current value of the heap pointer in p.
+release(p), with p initialized by a call of mark(p),
+restores the heap pointer to its old value. All the heap
+objects, created by calls of new between the call of mark
+and the call of release, are removed and the space they used
+can be reallocated. Never use mark and release together with
+dispose!</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>5. UNIX interfacing.</p>
+<!-- INDENTATION -->
+<p>If the c-option is turned on, then some special features
+are available to simplify an interface with the UNIX
+environment. First of all, the compiler allows for a
+different type of string constants. These string constants
+are delimited by double quotes (&rsquo;&quot;&rsquo;). To
+put a double quote into these strings, the double quote must
+be repeated, like the single quote in normal string
+constants. These special string constants are terminated by
+a zero byte (chr(0)). The type of these constants is a
+pointer to a packed array of characters, with lower bound 1
+and unknown upper bound.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Secondly, the compiler predefines a new type identifier
+&rsquo;string&rsquo; denoting this just described string
+type.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>These features are only useful for declaration of
+constants and variables of type &rsquo;string&rsquo;. String
+objects may not be allocated on the heap and string pointers
+may not be de-referenced. Still these strings are very
+useful in combination with external routines. The procedure
+write is extended to print these zero-terminated strings
+correctly.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>6. Double length (32 bit) integers.</p>
+<!-- INDENTATION -->
+<p>If the d-option is turned on, then the additional type
+&rsquo;long&rsquo; is known to the compiler. By default,
+long variables have integer values in the range
+-2147483647..+2147483647, but this can be changed with the
+-V option (if the backend can support this). Long constants
+can not be declared. Longs can not be used as
+control-variables. It is not allowed to form subranges of
+type long. All operations allowed on integers are also
+allowed on longs and are indicated by the same operators:
+&rsquo;+&rsquo;, &rsquo;-&rsquo;, &rsquo;*&rsquo;,
+&rsquo;/&rsquo;, &rsquo;div&rsquo;, &rsquo;mod&rsquo;. The
+procedures read and write have been extended to handle long
+arguments correctly. It is possible to read longs from a
+file of integers and vice-versa, but only if longs and
+integers have the same size. The default width for longs is
+11. The standard procedures &rsquo;abs&rsquo; and
+&rsquo;sqr&rsquo; have been extended to work on long
+arguments. Conversion from integer to long, long to real,
+real to long and long to integer are automatic, like the
+conversion from integer to real. These conversions may cause
+a</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>conversion error, trap 10, non-fatal</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>7. Underscore as letter.</p>
+<!-- INDENTATION -->
+<p>The character &rsquo;_&rsquo; may be used in forming
+identifiers, if the u- or U-option is turned on. It is
+forbidden to start identifiers with underscores, since this
+may cause name-clashes with run-time routines.</p>
+<!-- INDENTATION -->
+<p>8. Zero field width in write.</p>
+<!-- INDENTATION -->
+<p>Zero TotalWidth arguments are allowed. No characters are
+written for character, string or Boolean type arguments
+then. A zero FracDigits argument for fixed-point
+representation of reals causes the fraction and the
+character &rsquo;.&rsquo; to be suppressed.</p>
+<!-- INDENTATION -->
+<p>9. Pre-processing.</p>
+<!-- INDENTATION -->
+<p>If the very first character of a file containing a Pascal
+program is the sharp (&rsquo;#&rsquo;, ASCII 23(hex)) the
+file is preprocessed in the same way as C programs. Lines
+beginning with a &rsquo;#&rsquo; are taken as preprocessor
+command lines and not fed to the Pascal compiler proper. C
+style comments, /*......*/, are removed by the C
+preprocessor, thus C comments inside Pascal programs are
+also removed when they are fed through the
+preprocessor.</p></td>
+</table>
+
+<p><b>6. Deviations from the standard</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Ack-Pascal deviates from the standard proposal in the
+following ways:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>1. Standard procedures and functions are not allowed as
+parameters in Ack-Pascal. The same result can be obtained
+with negligible loss of performance by declaring some user
+routines like:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>function sine(x:real):real;<br>
+begin<br>
+sine:=sin(x)<br>
+end;</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>2. The standard procedures read, readln, write and
+writeln are implemented as word-symbols, and can therefore
+not be redeclared.</p></td>
+</table>
+
+<p><b>7. Compiler options</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Some options of the compiler may be controlled by using
+&quot;{$....}&quot;. Each option consists of a lower case
+letter followed by +, - or an unsigned number. Options are
+separated by commas. The following options exist:</p></td>
+</table>
+
+<p>a +/- this option switches assertions on and off. If
+this option is on, then code is included to test these
+assertions at run time. Default +.</p>
+
+<p>c +/- this option, if on, allows the use of C-type
+string constants surrounded by double quotes. Moreover, a
+new type identifier &rsquo;string&rsquo; is predefined.
+Default -.</p>
+
+<p>d +/- this option, if on, allows the use of variables of
+type &rsquo;long&rsquo;. Default -.</p>
+
+<p>i &lt;num&gt; with this flag the setsize for a set of
+integers can be manipulated. The number must be the number
+of bits per set. The default value is wordsize-1.</p>
+
+<p>l +/- if + then code is inserted to keep track of the
+source line number. When this flag is switched on and off,
+an incorrect line number may appear if the error occurs in a
+part of the program for which this flag is off. These same
+line numbers are used for the profile, flow and count
+options of the EM interpreter em [5]. Default +.</p>
+
+<p>r +/- if + then code is inserted to check subrange
+variables against lower and upper subrange limits. Default
++.</p>
+
+<p>s +/- if + then the compiler will hunt for places in the
+program where non-standard features are used, and for each
+place found it will generate a warning. Default -.</p>
+
+<p>t +/- if + then each time a procedure is entered, the
+routine &rsquo;procentry&rsquo; is called, and each time a
+procedure exits, the procedure &rsquo;procexit&rsquo; is
+called. Both &rsquo;procentry&rsquo; and
+&rsquo;procexit&rsquo; have a &rsquo;string&rsquo; as
+parameter. This means that when a user specifies his or her
+own procedures, the c-option must be used. Default
+procedures are present in the run time library. Default
+-.</p>
+
+<p>u +/- if + then the character &rsquo;_&rsquo; is treated
+like a letter, so that it may be used in identifiers.
+Procedure and function identifiers are not allowed to start
+with an underscore because they may collide with library
+routine names. Default -.</p>
+
+<p>Some of these flags (c, d, i, s, u, C and U) are only
+effective when they appear before the &rsquo;program&rsquo;
+symbol. The others may be switched on and off.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>A very powerful debugging tool is the knowledge that
+inaccessible statements and useless tests are removed by the
+EM optimizer. For</p></td>
+</table>
+
+<p>instance, a statement like:</p>
+<pre>        if debug then
+          writeln(&rsquo;initialization done&rsquo;);
+</pre>
+
+<p>is completely removed by the optimizer if debug is a
+constant with value false. The first line is removed if
+debug is a constant with value true. Of course, if debug is
+a variable nothing can be removed.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>A disadvantage of Pascal, the lack of preinitialized
+data, can be diminished by making use of the possibilities
+of the EM optimizer. For instance, initializing an array of
+reserved words is sometimes optimized into 3 EM
+instructions. To maximize this effect variables must be
+initialized as much as possible in order of declaration and
+array entries in order of decreasing index.</p></td>
+</table>
+
+<p><b>8. References</b></p>
+
+<p>[1] BSI standard BS 6192: 1982 (ISO 7185).</p>
+
+<p>[2] A.S.Tanenbaum, J.W.Stevenson, Hans van Staveren,
+E.G.Keizer, &quot;Description of a machine architecture for
+use with block structured languages&quot;, Informatica
+rapport IR-81.</p>
+
+<p>[3] UNIX manual ack(I).</p>
+
+<p>[4] UNIX manual ld(I).</p>
+
+<p>[5] UNIX manual em(I).</p>
+
+<p>[6] UNIX manual libpc(VII)</p>
+
+<p>[7] UNIX manual pc_prlib(VII)</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/pcref.pdf b/src/olddocs/pcref.pdf
new file mode 100644 (file)
index 0000000..8646f3d
Binary files /dev/null and b/src/olddocs/pcref.pdf differ
diff --git a/src/olddocs/peep.html b/src/olddocs/peep.html
new file mode 100644 (file)
index 0000000..1e71e3a
--- /dev/null
@@ -0,0 +1,1189 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:05 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>Internal documentation on the peephole optimizer</title>
+</head>
+<body>
+
+<h1 align=center>Internal documentation on the peephole optimizer</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. Table format">2. Table format</a><br>
+<a href="#3. Internal format">3. Internal format</a><br>
+<a href="#4. A tour through the sources">4. A tour through the sources</a><br>
+<a href="#4.1. The header files">4.1. The header files</a><br>
+<a href="#4.1.1. alloc.h">4.1.1. alloc.h</a><br>
+<a href="#4.1.2. assert.h">4.1.2. assert.h</a><br>
+<a href="#4.1.3. ext.h">4.1.3. ext.h</a><br>
+<a href="#4.1.4. line.h">4.1.4. line.h</a><br>
+<a href="#4.1.5. lookup.h">4.1.5. lookup.h</a><br>
+<a href="#4.1.6. optim.h">4.1.6. optim.h</a><br>
+<a href="#4.1.7. param.h">4.1.7. param.h</a><br>
+<a href="#4.1.8. pattern.h">4.1.8. pattern.h</a><br>
+<a href="#4.1.9. proinf.h">4.1.9. proinf.h</a><br>
+<a href="#4.1.10. tes.h">4.1.10. tes.h</a><br>
+<a href="#4.1.11. types.h">4.1.11. types.h</a><br>
+<a href="#4.2. The C code itself.">4.2. The C code itself.</a><br>
+<a href="#4.2.1. main.c">4.2.1. main.c</a><br>
+<a href="#4.2.2. getline.c">4.2.2. getline.c</a><br>
+<a href="#4.2.3. process.c">4.2.3. process.c</a><br>
+<a href="#4.2.4. backward.c">4.2.4. backward.c</a><br>
+<a href="#4.2.5. peephole.c">4.2.5. peephole.c</a><br>
+<a href="#4.2.6. tes.c">4.2.6. tes.c</a><br>
+<a href="#4.2.7. putline.c">4.2.7. putline.c</a><br>
+
+<hr>
+
+<p><b>from the Amsterdam Compiler Kit</b></p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p><small>Part of the Amsterdam Compiler Kit is a program
+to do peephole optimization on an EM program. The optimizer
+scans the program to match patterns from a table and if
+found makes the optimization from the table, and with the
+result of the optimization it tries to find yet another
+optimization continuing until no more optimizations are
+found.</small></p>
+
+<p><small>Furthermore it does some optimizations that can
+not be called peephole optimizations for historical reasons,
+like branch chaining and the deletion of unreachable
+code.</small></p>
+
+<p><small>The peephole optimizer consists of three
+parts</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="30%">
+
+<p><small>A driving table</small></p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>A program translating the table to internal
+format</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>C code compiled with the table to make the
+optimizer proper</small></p>
+</td>
+</table>
+
+<p><small>In this document the table format, internal
+format and data structures in the optimizer will be
+explained, plus a hint on what the code does where it might
+not be obvious. It is a simple program mostly.</small></p>
+<a name="2. Table format"></a>
+<h2>2. Table format</h2>
+
+<p><small>The driving table consists of pattern/replacement
+pairs, in principle one per line, although a line starting
+with white space is considered a continuation line for the
+previous. The general format is:</small></p>
+<pre><small>     optimization : pattern &rsquo;:&rsquo; replacement &rsquo;\n&rsquo;
+
+
+     pattern : EMlist optional_boolean_expression
+
+
+     replacement : EM_plus_operand_list
+</small></pre>
+
+<p><small>Example of a simple one</small></p>
+<pre><small>     loc stl $1==0 : zrl $2
+</small></pre>
+
+<p><small>There is no real limit for the length of the
+pattern or the replacement, the replacement might even be
+longer than the pattern, and expressions can be made
+arbitrarily complicated.</small></p>
+
+<p><small>The expressions in the table are made of the
+following pieces:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="34%">
+
+<p><small>Integer constants</small></p>
+</td>
+<td width="55%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>$<i>n</i>, standing for the operand of the
+<i>n</i>&rsquo;th EM instruction in the pattern, undefined
+if that instruction has no operand.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>w, standing for the wordsize of the code
+optimized.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="46%">
+
+<p><small>p, for the pointersize.</small></p>
+</td>
+<td width="43%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="88%">
+
+<p><small>defined(expr), true if expression is
+defined</small></p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>samesign(expr,expr), true if expressions have the
+same sign.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>sfit(expr,expr), ufit(expr,expr), true if the
+first expression fits signed or unsigned in the number of
+bits given in the second expression.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>rotate(expr,expr), first expression rotated left
+the number of bits given by the second
+expression.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>notreg(expr), true if the local with the
+expression as number is not a candidate to put in a
+register.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>rom(<i>n</i>,expr), contents of the rom
+descriptor at index expr that is associated with the global
+label that should be the argument of the <i>n</i>&rsquo;th
+EM instruction. Undefined if such a thing does not
+exist.</small></p>
+</td>
+</table>
+
+<p><small>The usual arithmetic operators may be used on
+integer values, if any operand is undefined the expression
+is undefined, except for the defined() function above. An
+undefined expression used for its truth value is false. All
+arithmetic on local label operands is forbidden, only things
+allowed are tests for equality. Arithmetic on global labels
+makes sense, i.e. one can add a global label and a constant,
+but not two global labels.</small></p>
+
+<p><small>In the table one can use five additional EM
+instructions in patterns. These are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>lab</small></p>
+</td>
+<td width="4%"></td>
+<td width="48%">
+
+<p><small>Stands for a local label</small></p>
+</td>
+<td width="41%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>LLP</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Load Local Pointer, translates into a <b>lol</b>
+or into a <b>ldl</b> depending on the relationship between
+wordsize and pointersize.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>LEP</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>Load External Pointer, translates into a
+<b>loe</b> or into a <b>lde</b>.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>SLP</small></p>
+</td>
+<td width="4%"></td>
+<td width="64%">
+
+<p><small>Store Local Pointer, <b>stl</b> or
+<b>sdl</b>.</small></p>
+</td>
+<td width="25%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>SEP</small></p>
+</td>
+<td width="4%"></td>
+<td width="70%">
+
+<p><small>Store External Pointer, <b>ste</b> or
+<b>sde</b>.</small></p>
+</td>
+<td width="19%">
+</td>
+</table>
+
+<p><small>There is only one peephole optimizer, so the
+substitutions to be made for the last four instructions are
+made at run time before the first optimizations are
+made.</small></p>
+<a name="3. Internal format"></a>
+<h2>3. Internal format</h2>
+
+<p><small>The translating program, <i>mktab</i> converts
+the table into an array of bytes where all patterns follow
+unaligned. Format of a pattern is:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>1)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>One byte for high byte of hash value, will be
+explained later on.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>2)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Two bytes for the index of the next pattern in a
+chain.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>3)</small></p>
+</td>
+<td width="6%"></td>
+<td width="24%">
+
+<p><small>An integer*,</small></p>
+</td>
+<td width="65%">
+</td>
+</table>
+
+
+<p align=center><small><img src="grohtml-99071.png"></small></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p><small>pattern length.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>4)</small></p>
+</td>
+<td width="6%"></td>
+<td width="84%">
+
+<p><small>The list of pattern opcodes, one per
+byte.</small></p>
+</td>
+<td width="5%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>5)</small></p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p><small>An integer expression index, 0 if not
+used.</small></p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>6)</small></p>
+</td>
+<td width="6%"></td>
+<td width="62%">
+
+<p><small>An integer, replacement length.</small></p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>7)</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>A list of pairs consisting of a one byte opcode
+and an integer expression index.</small></p>
+</td>
+</table>
+
+<p><small>The expressions are kept in an array of triples,
+implementing a binary tree. The <i>mktab</i> program tries
+to minimize the number of triples by reusing duplicates and
+even reverses the operands of commutative operators when
+doing so would spare a triple.</small></p>
+<a name="4. A tour through the sources"></a>
+<h2>4. A tour through the sources</h2>
+
+<p><small>Now we will walk through the sources and note
+things of interest.</small></p>
+<a name="4.1. The header files"></a>
+<h2>4.1. The header files</h2>
+
+<p><small>The header files are the place where data
+structures and options reside.</small></p>
+<a name="4.1.1. alloc.h"></a>
+<h2>4.1.1. alloc.h</h2>
+
+<p><small>In the header file alloc.h several defines can be
+used to select various kinds of core allocation schemes.
+This is important on small machines like the PDP-11 since a
+complete procedure must be in core at the same space, and
+the peephole optimizer should not be the limiting factor in
+determining the maximum size of procedures if possible.
+Options are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>USEMALLOC, standard malloc() and free() are used
+instead of the own core allocation package. Not recommended
+unless the own package does not work on some bizarre
+machine.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>COREDEBUG, prints large amounts of information
+about core management. Not recommended unless the code is
+changed and it stops working.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>SEPID, defining this will add an extra procedure
+that will go through a lot of work to scrape the last bytes
+together if the system won&rsquo;t provide more. This is not
+a good idea if memory is scarce and code and data reside in
+the same spaces, since the room used by the procedure might
+well be more than the room saved.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>STACKROOM, number of shorts used in stack space.
+This is used if memory is scarce and stack space and data
+space are different. On the PDP-11 a UNIX process starts
+with an 8K stack segment which cannot be transferred to the
+data segment. Under these conditions one can use a lot of
+the stack space for storage.</small></p>
+</td>
+</table>
+<a name="4.1.2. assert.h"></a>
+<h2>4.1.2. assert.h</h2>
+
+<p><small>Just defines the assert macro. When compiled with
+-DNDEBUG all asserts will be off.</small></p>
+<a name="4.1.3. ext.h"></a>
+<h2>4.1.3. ext.h</h2>
+
+<p><small>Gives external definitions of variables used by
+more than one module.</small></p>
+<a name="4.1.4. line.h"></a>
+<h2>4.1.4. line.h</h2>
+
+<p><small>Defines the structures used to keep instructions,
+one structure per line of EM code, and the structure to keep
+arguments of pseudos, one structure per argument. Both
+structures essentially contain a pointer to the next, a
+type, and a union containing information depending on the
+type. Core is allocated only for the part of the union
+used.</small></p>
+
+<p><small>The <i>struct line</i> has a very compact
+encoding for small integers, they are encoded in the type
+field. On the PDP-11 this gives a line structure of only 4
+bytes for most instructions.</small></p>
+<a name="4.1.5. lookup.h"></a>
+<h2>4.1.5. lookup.h</h2>
+
+<p><small>Contains definition of the struct used for symbol
+table management, global labels and procedure names are kept
+in one table.</small></p>
+<a name="4.1.6. optim.h"></a>
+<h2>4.1.6. optim.h</h2>
+
+<p><small>If one defines the DIAGOPT option in this header
+file, for every optimization performed a number is written
+on stderr. The number gives the number of the pattern in the
+table or one of the four special numbers in this header
+file.</small></p>
+<a name="4.1.7. param.h"></a>
+<h2>4.1.7. param.h</h2>
+
+<p><small>Contains one settable option, LONGOFF. If this is
+not defined the optimizer can only optimize programs with
+wordsize 2 and pointersize 2. Set this only if it must be
+run on a Z80 or something pathetic like that.</small></p>
+
+<p><small>Other defines here should not be
+touched.</small></p>
+<a name="4.1.8. pattern.h"></a>
+<h2>4.1.8. pattern.h</h2>
+
+<p><small>Contains defines of indices in a pattern,
+definition of the expression triples, definitions of the
+various expression operators and definition of the result
+struct where expression results are put.</small></p>
+
+<p><small>This header file is the main one that is also
+included by <i>mktab</i>.</small></p>
+<a name="4.1.9. proinf.h"></a>
+<h2>4.1.9. proinf.h</h2>
+
+<p><small>This one contains definitions for the local label
+table structs and for the struct where all information for
+one procedure is kept. This is in one struct so it can be
+saved easily when recursive procedures have to be
+resolved.</small></p>
+<a name="4.1.10. tes.h"></a>
+<h2>4.1.10. tes.h</h2>
+
+<p><small>Contains the data structure used by the top
+element size computation.</small></p>
+<a name="4.1.11. types.h"></a>
+<h2>4.1.11. types.h</h2>
+
+<p><small>Collection of typedefs to be used by almost all
+modules.</small></p>
+<a name="4.2. The C code itself."></a>
+<h2>4.2. The C code itself.</h2>
+
+<p><small>The C code will now be the center of our
+attention. We will make a walk through the sources and we
+will try to follow the sources in a logical order. So we
+will start at</small></p>
+<a name="4.2.1. main.c"></a>
+<h2>4.2.1. main.c</h2>
+
+<p><small>The main.c module contains the main() function.
+Here nothing spectacular happens, only thing of interest is
+the handling of flags:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>-L</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>This is an instruction to the peephole optimizer
+to perform one of its auxiliary functions, the generation of
+a library module. This makes the peephole optimizer write
+its output on a temporary file, and at the end making the
+real output by first generating a list of exported symbols
+and then copying the temporary file behind it.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p><small>-n</small></p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p><small>Disables all optimization. Only thing the
+optimizer does now is filling in the blank after the
+<i>END</i> pseudo and resolving recursive
+procedures.</small></p>
+</td>
+</table>
+
+<p><small>The place where main() is left is the call to
+getlines() which brings us to</small></p>
+<a name="4.2.2. getline.c"></a>
+<h2>4.2.2. getline.c</h2>
+
+<p><small>This module reads the EM code and constructs a
+list of <i>struct line</i> records, linked together
+backwards, i.e. the first instruction read is the last in
+the list. Pseudos are handled here also, for most pseudos
+this just means that a chain of argument records is linked
+into the linked line list but some pseudos get special
+attention:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>exc</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>This pseudo is acted upon right away. Lines read
+are shuffled around according to instruction.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>mes</small></p>
+</td>
+<td width="4%"></td>
+<td width="82%">
+
+<p><small>Some messages are acted upon. These
+are:</small></p>
+</td>
+<td width="7%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="12%">
+
+<p><small>ms_err</small></p>
+</td>
+<td width="4%"></td>
+<td width="74%">
+
+<p><small>The input is drained, just in case it is a pipe.
+After that the optimizer exits.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="12%">
+
+<p><small>ms_opt</small></p>
+</td>
+<td width="4%"></td>
+<td width="74%">
+
+<p><small>The do not optimize flag is set. Acts just like
+-n on the command line.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="12%">
+
+<p><small>ms_emx</small></p>
+</td>
+<td width="4%"></td>
+<td width="74%">
+
+<p><small>The word- and pointersize are read, complain if
+we are not able to handle this.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="12%">
+
+<p><small>ms_reg</small></p>
+</td>
+<td width="4%"></td>
+<td width="74%">
+
+<p><small>We take notice of the offset of this local. See
+also comments in the description of peephole.c</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>pro</small></p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p><small>A new procedure starts, if we are already in one
+save the status, else process collected input. Collect
+information about this procedure and if already in a
+procedure call getlines() recursively.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p><small>end</small></p>
+</td>
+<td width="4%"></td>
+<td width="48%">
+
+<p><small>Process collected input.</small></p>
+</td>
+<td width="41%">
+</td>
+</table>
+
+<p><small>The phrase &quot;process collected input&quot; is
+used twice, which brings us to</small></p>
+<a name="4.2.3. process.c"></a>
+<h2>4.2.3. process.c</h2>
+
+<p><small>This module contains the entry point process()
+which is called at any time the collected input must be
+processed. It calls a variety of other routines to get the
+real work done. Routines in this module are in chronological
+order:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>symknown</small></p>
+</td>
+<td width="8%"></td>
+<td width="76%">
+
+<p><small>Marks all symbols seen until now as known, i.e.
+it is now known whether their scope is local or global. This
+information is used again during output.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%">
+
+<p><small>symvalue</small></p>
+</td>
+<td width="8%"></td>
+<td width="76%">
+
+<p><small>Runs through the chain of pseudos to give values
+to data labels. This needs an extra pass. It cannot be done
+during the getlines pass, since an <b>exc</b> pseudo could
+destroy things. Nor can it be done during the backward pass
+since it is impossible to do good fragment numbering
+backward.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="18%">
+
+<p><small>checklocs</small></p>
+</td>
+<td width="6%"></td>
+<td width="76%">
+
+<p><small>Checks whether all local labels referenced are
+defined. It needs to be sure about this since otherwise the
+semi global optimizations made cannot work.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="14%">
+
+<p><small>relabel</small></p>
+</td>
+<td width="10%"></td>
+<td width="76%">
+
+<p><small>This routine finds the final destination for each
+label in the procedure. Labels followed by unconditional
+branches or other labels are marked during the peephole fase
+and this leeds to chains of identical labels. These chains
+are followed here, and in the local label table each label
+has associated with it its replacement label, after this
+procedure is run. Care is taken in this routine to prevent a
+loop in the program to cause the optimizer to
+loop.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="22%">
+
+<p><small>cleanlocals</small></p>
+</td>
+<td width="2%"></td>
+<td width="76%">
+
+<p><small>This routine empties the local label table after
+everything is processed.</small></p>
+</td>
+</table>
+
+<p><small>But before this can all be done, the backward
+linked list of instructions first has to be reversed, so
+here comes</small></p>
+<a name="4.2.4. backward.c"></a>
+<h2>4.2.4. backward.c</h2>
+
+<p><small>The routine backward has a number of
+functions:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>It reverses the backward linked list, making two
+forward linked lists, one for the instructions and one for
+the pseudos.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>It notes the last occurrence of data labels in
+the backward linked list and puts it in the global symbol
+table. This is of course the first occurence in the
+procedure. This information is needed to decide whether the
+symbols are global or local to this module.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>It decides about the fragment boundaries of data
+blocks. Fragments are numbered backwards starting at 3. This
+is done to be able to make the type of an expression
+containing a symbol equal to its fragment. This type can
+then not clash with the types integer and local
+label.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>It allocates a rom buffer to every data label
+with a rom behind it, if that rom contains only plain
+integers at the start.</small></p>
+</td>
+</table>
+
+<p><small>The first thing done after process() has called
+backward() and some of its own little routines is a call to
+the real routine, the one that does the work the program was
+written for</small></p>
+<a name="4.2.5. peephole.c"></a>
+<h2>4.2.5. peephole.c</h2>
+
+<p><small>The first routines in peephole.c implement a
+linked list for the offsets of local variables that are
+candidates for a register implementation. Several patterns
+use the notreg() function, since it is forbidden to combine
+a load of that variable with the load of another and it is
+not allowed to take the address of that
+variable.</small></p>
+
+<p><small>The routine peephole hashes the patterns the
+first time it is called after which it doesn&rsquo;t do much
+more than calling optimize. But first
+hashpatterns().</small></p>
+
+<p><small>The patterns are hashed at run time of the
+optimizer because of the <b>LLP</b>, <b>LEP</b>, <b>SLP</b>
+and <b>SEP</b> instructions added to the instruction set in
+this optimizer. These are first replaced everywhere in the
+table by the correct replacement after which the first three
+instructions of the pattern are hashed and the pattern is
+linked into one of the 256 linked lists. There is a define
+CHK_HASH in this module that can be set if the randomness of
+the hashing function is not trusted.</small></p>
+
+<p><small>The attention now shifts to optimize(). This
+routine calls basicblock() for every piece of code between
+two labels. It also notes which labels have another label or
+a branch behind them so the relabel() routine from process.c
+can do something with that.</small></p>
+
+<p><small>Basicblock() keeps making passes over its basic
+block until no more optimizations are found. This might be
+inefficient if there is a long basicblock with some deep
+recursive optimization in one part of it. The entire basic
+block is then scanned a lot of times just for that one
+piece. The alternative is backing up after making an
+optimization and running through the same code again, but
+that is difficult in a single linked list.</small></p>
+
+<p><small>It hashes instructions and calls trypat() for
+every pattern that has a full hash value match, i.e. lower
+byte and upper byte equal. Longest pattern is tried
+first.</small></p>
+
+<p><small>Trypat() checks length and opcodes of the
+pattern. If correct it fills the iargs[] array with argument
+values and calculates the expression. If that is also
+correct the work shifts to tryrepl().</small></p>
+
+<p><small>Tryrepl() generates the list of replacement
+instructions, links it into the list and returns true. Why
+then the name tryrepl() if it always succeeds? Well, there
+is a mechanism in the optimizer, unused until today that
+makes it possible to do optimizations that cannot be
+described by the table. It is possible to give a number as a
+replacement which will cause the optimizer to call a routine
+special() to do some work. This routine might decide not to
+do an optimization and return false.</small></p>
+
+<p><small>The last routine that is called from process() is
+putline() to write the optimized code, bringing us
+to</small></p>
+<a name="4.2.6. tes.c"></a>
+<h2>4.2.6. tes.c</h2>
+
+<p><small>Contains the routines used by the top element
+size computation phase, which is run after the
+peephole-optimisation. The main routine of tes.c is
+tes_instr(). This looks at an instruction and decides the
+size of the element on top of the stack after the
+instruction is executed. When a label is defined or used,
+the size of the top element is remembered for later use.
+When the information in consistent throuhout the procedure,
+it is passed to the code generator by means of an ms_tes
+message.</small></p>
+<a name="4.2.7. putline.c"></a>
+<h2>4.2.7. putline.c</h2>
+
+<p><small>The major part of putline.c is the standard set
+of routines that makes EM compact code. The extra functions
+performed are:</small></p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>For every occurence of a global symbol it might
+be necessary to output a <b>exa</b>, <b>exp</b>, <b>ina</b>
+or <b>inp</b> pseudo instruction. That task is
+performed.</small></p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p><small>-</small></p>
+</td>
+<td width="8%"></td>
+<td width="90%">
+
+<p><small>The <b>lin</b> instructions are optimized here,
+<b>lni</b> instructions added for <b>lin</b> instructions
+and superfluous <b>lin</b> instructions deleted.</small></p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/peep.pdf b/src/olddocs/peep.pdf
new file mode 100644 (file)
index 0000000..1932aab
Binary files /dev/null and b/src/olddocs/peep.pdf differ
diff --git a/src/olddocs/regadd.html b/src/olddocs/regadd.html
new file mode 100644 (file)
index 0000000..5a6f7e7
--- /dev/null
@@ -0,0 +1,510 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:11 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>Addition of register variables to an existing table.</title>
+</head>
+<body>
+
+<h1 align=center>Addition of register variables to an existing table.</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. Modifications to the table itself.">2. Modifications to the table itself.</a><br>
+<a href="#2.1. Register section">2.1. Register section</a><br>
+<a href="#2.2. Codesection">2.2. Codesection</a><br>
+<a href="#3. Modifications to mach.c">3. Modifications to mach.c</a><br>
+<a href="#4. Examples">4. Examples</a><br>
+<a href="#5. Afterthoughts.">5. Afterthoughts.</a><br>
+
+<hr>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p>This is a short description of the newest feature in the
+table driven code generator for the Amsterdam Compiler Kit.
+It describes how to add register variables to an existing
+table. This assumes a distribution of October 1983 or later.
+It is not clear whether one should read this when starting
+with a table for a new machine, or waiting till the table is
+well debugged already.</p>
+<a name="2. Modifications to the table itself."></a>
+<h2>2. Modifications to the table itself.</h2>
+<a name="2.1. Register section"></a>
+<h2>2.1. Register section</h2>
+
+<p>Just before the properties of the register one of the
+following can be added:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="12%">
+
+<p>regvar</p>
+</td>
+<td width="83%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="36%">
+
+<p>regvar ( pointer )</p>
+</td>
+<td width="59%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="30%">
+
+<p>regvar ( loop )</p>
+</td>
+<td width="65%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="32%">
+
+<p>regvar ( float )</p>
+</td>
+<td width="63%">
+</td>
+</table>
+
+<p>All register variables of one type must be of the same
+size, and they may have no subregisters.</p>
+<a name="2.2. Codesection"></a>
+<h2>2.2. Codesection</h2>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="96%">
+
+<p>Two pseudo functions are added to the list allowed
+inside expressions:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="2%"></td>
+<td width="90%">
+
+<p>inreg ( expr ) has as a parameter the offset of a local,
+and returns 0,1 or 2:</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>2:</p>
+</td>
+<td width="2%"></td>
+<td width="66%">
+
+<p>if the variable is in a register.</p>
+</td>
+<td width="17%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>1:</p>
+</td>
+<td width="2%"></td>
+<td width="84%">
+
+<p>if the variable could be in a register but
+isn&rsquo;t.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="4%">
+
+<p>0:</p>
+</td>
+<td width="2%"></td>
+<td width="80%">
+
+<p>if the variable cannot be in a register.</p>
+</td>
+<td width="3%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="2%"></td>
+<td width="90%">
+
+<p>regvar ( expr ) returns the register associated with the
+variable. Undefined if it is not in a register. So regvar (
+expr ) is defined if and only if inreg (expr ) == 2.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="96%">
+
+<p>It is now possible to remove() a register expression,
+this is of course needed for a store into a register
+local.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="96%">
+
+<p>The return out of a procedure may now involve register
+restores, so the special word &rsquo;return&rsquo; in the
+table will invoke a user defined function.</p>
+</td>
+</table>
+<a name="3. Modifications to mach.c"></a>
+<h2>3. Modifications to mach.c</h2>
+
+<p>If register variables are used in a table, the program
+<i>cgg</i> will define the word REGVARS during compilation
+of the sources. So the following functions described here
+should be bracketed by #ifdef REGVARS and #endif.</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="86%">
+
+<p>regscore(off,size,typ,freq,totyp) long off;</p>
+</td>
+<td width="9%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>This function should assign a score to a register
+variable, the score should preferably be the estimated
+number of bytes gained when it is put in a register. Off and
+size are the offset and size of the variable, typ is the
+type, that is reg_any, reg_pointer, reg_loop or reg_float.
+Freq is the number of times it occurs statically, and totyp
+is the type of the register it is planned to go into.<br>
+Keep in mind that the gain should be net, that is the cost
+for register save/restore sequences and the cost of
+initialisation in the case of parameters should already be
+included.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="22%">
+
+<p>i_regsave()</p>
+</td>
+<td width="73%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>This function is called at the start of a procedure, just
+before register saves are done. It can be used to initialise
+some variables if needed.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="22%">
+
+<p>f_regsave()</p>
+</td>
+<td width="73%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>This function is called at end of the register save
+sequence. It can be used to do the real saving if multiple
+register move instructions are available.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="96%">
+
+<p>regsave(regstr,off,size) char *regstr; long off;</p>
+</td>
+<td width="0%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>Should either do the real saving or set up a table to
+have it done by f_regsave. Note that initialisation of
+parameters should also be done, or planned here.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="2%">
+
+<p>-</p>
+</td>
+<td width="2%"></td>
+<td width="22%">
+
+<p>regreturn()</p>
+</td>
+<td width="73%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="3%"></td>
+<td width="96%">
+<p>Should restore saved registers and return. The function
+result is already in the function return area by
+now.</p></td>
+</table>
+<a name="4. Examples"></a>
+<h2>4. Examples</h2>
+
+<p>Here are some examples out of the PDP 11 table</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="8" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+
+<p>lol inreg($1)==2| |</p>
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="30%"></td>
+<td width="10%">
+
+<p>| regvar($1)</p>
+</td>
+<td width="10%">
+</td>
+<td width="20%"></td>
+<td width="10%">
+</td>
+<td width="0%">
+
+<p>| |</p>
+
+<p>lil inreg($1)==2| |</p>
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%">
+</td>
+<td width="30%"></td>
+<td width="10%">
+
+<p>| {regdef2, regvar($1)}</p>
+</td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="0%">
+</td>
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="10%"></td>
+<td width="30%"></td>
+<td width="10%"></td>
+<td width="10%"></td>
+<td width="20%"></td>
+<td width="10%"></td>
+<td width="0%">
+
+<p>| |</p>
+</td>
+</table>
+
+<p>stl inreg($1)==2| xsource2 |</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>remove(regvar($1))</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>move(%[1],regvar($1)) | | |</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+
+<p>inl inreg($1)==2| | remove(regvar($1))</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="5" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>&quot;inc %(regvar($1)%)&quot;</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="19%"></td>
+<td width="10%">
+</td>
+<td width="10%">
+
+<p>setcc(regvar($1)) | | |</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+<a name="5. Afterthoughts."></a>
+<h2>5. Afterthoughts.</h2>
+
+<p>At the time of this writing the tables for the PDP 11
+and the M68000 and the VAX are converted, in all cases the
+two byte wordsize versions. No big problems have occurred,
+but experience has shown that it is necessary to check the
+table carefully for all patterns with locals in them. Code
+may be generated that uses the memoryslot the local is not
+in.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/regadd.pdf b/src/olddocs/regadd.pdf
new file mode 100644 (file)
index 0000000..fab96c9
Binary files /dev/null and b/src/olddocs/regadd.pdf differ
diff --git a/src/olddocs/sparc.html b/src/olddocs/sparc.html
new file mode 100644 (file)
index 0000000..93e6c91
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:36 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title></title>
+</head>
+<body>
+
+<hr>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/sparc.pdf b/src/olddocs/sparc.pdf
new file mode 100644 (file)
index 0000000..ba68476
--- /dev/null
@@ -0,0 +1,28 @@
+%PDF-1.2
+%Çì\8f¢
+3 0 obj
+<< /Type /Pages /Kids [
+] /Count 0
+/Rotate 0>>
+endobj
+1 0 obj
+<</Type /Catalog /Pages 3 0 R
+>>
+endobj
+2 0 obj
+<</Producer(GPL Ghostscript 8.01)
+/CreationDate(D:20050211221909)
+/ModDate(D:20050211221909)
+/Creator(groff version 1.18.1)>>endobj
+xref
+0 4
+0000000000 65535 f 
+0000000077 00000 n 
+0000000125 00000 n 
+0000000015 00000 n 
+trailer
+<< /Size 4 /Root 1 0 R /Info 2 0 R
+>>
+startxref
+265
+%%EOF
diff --git a/src/olddocs/toolkit.html b/src/olddocs/toolkit.html
new file mode 100644 (file)
index 0000000..f25c768
--- /dev/null
@@ -0,0 +1,938 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:16:55 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>A Practical Tool Kit for Making Portable Compilers</title>
+</head>
+<body>
+
+<h1 align=center>A Practical Tool Kit for Making Portable Compilers</h1>
+<a href="#*.">*.</a><br>
+<a href="#Introduction">Introduction</a><br>
+<a href="#*.">*.</a><br>
+<a href="#An Overview of the Amsterdam Compiler Kit">An Overview of the Amsterdam Compiler Kit</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Preprocessor">The Preprocessor</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Front Ends">The Front Ends</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Peephole Optimizer">The Peephole Optimizer</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Global Optimizer">The Global Optimizer</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Back End">The Back End</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Target Machine Optimizer">The Target Machine Optimizer</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Universal Assembler/Linker">The Universal Assembler/Linker</a><br>
+<a href="#*.">*.</a><br>
+<a href="#The Utility Package">The Utility Package</a><br>
+<a href="#*.">*.</a><br>
+<a href="#Summary and Conclusions">Summary and Conclusions</a><br>
+<a href="#*.">*.</a><br>
+<a href="#References">References</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>Andrew S. Tanenbaum<br>
+Hans van Staveren<br>
+E. G. Keizer<br>
+Johan W. Stevenson</i><br>
+Mathematics Dept.<br>
+Vrije Universiteit<br>
+Amsterdam, The Netherlands</p>
+
+<p>The Amsterdam Compiler Kit is an integrated collection
+of programs designed to simplify the task of producing
+portable (cross) compilers and interpreters. For each
+language to be compiled, a program (called a front end) must
+be written to translate the source program into a common
+intermediate code. This intermediate code can be optimized
+and then either directly interpreted or translated to the
+assembly language of the desired target machine. The paper
+describes the various pieces of the tool kit in some detail,
+as well as discussing the overall strategy.</p>
+
+<p>Keywords: Compiler, Interpreter, Portability,
+Translator</p>
+
+<p>CR Categories: 4.12, 4.13, 4.22</p>
+
+<p>Author&rsquo;s present addresses: A.S. Tanenbaum, H. van
+Staveren, E.G. Keizer: Mathematics Dept., Vrije
+Universiteit, Postbus 7161, 1007 MC Amsterdam, The
+Netherlands</p>
+
+<p>J.W. Stevenson: NV Philips, S&amp;I, T&amp;M, Building
+TQ V5, Eindhoven, The Netherlands</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="Introduction"></a>
+<h2>Introduction</h2>
+
+<p>As more and more organizations acquire many micro- and
+minicomputers, the need for portable compilers is becoming
+more and more acute. The present situation, in which each
+hardware vendor provides its own compilers -- each with its
+own deficiencies and extensions, and none of them compatible
+-- leaves much to be desired. The ideal situation would be
+an integrated system containing a family of (cross)
+compilers, each compiler accepting a standard source
+language and producing code for a wide variety of target
+machines. Furthermore, the compilers should be compatible,
+so programs written in one language can call procedures
+written in another language. Finally, the system should be
+designed so as to make adding new languages and new machines
+easy. Such an integrated system is being built at the Vrije
+Universiteit. Its design and implementation is the subject
+of this article.</p>
+
+<p>Our compiler building system, which is called the
+&quot;Amsterdam Compiler Kit&quot; (ACK), can be thought of
+as a &quot;tool kit.&quot; It consists of a number of parts
+that can be combined to form compilers (and interpreters)
+with various properties. The tool kit is based on an idea
+(UNCOL) that was first suggested in 1960 [7], but which
+never really caught on then. The problem which UNCOL
+attempts to solve is how to make a compiler for each of
+<i>N</i> languages on <i>M</i> different machines without
+having to write <i>N</i> x <i>M</i> programs.</p>
+
+<p>As shown in Fig. 1, the UNCOL approach is to write
+<i>N</i> &quot;front ends,&quot; each of which translates
+one source language to a common intermediate language, UNCOL
+(UNiversal Computer Oriented Language), and <i>M</i>
+&quot;back ends,&quot; each of which translates programs in
+UNCOL to a specific machine language. Under these
+conditions, only <i>N</i> + <i>M</i> programs must be
+written to provide all <i>N</i> languages on all <i>M</i>
+machines, instead of <i>N</i> x <i>M</i> programs.</p>
+
+<p>Various researchers have attempted to design a suitable
+UNCOL [2,8], but none of these have become popular. It is
+our belief that previous attempts have failed because they
+have been too ambitious, that is, they have tried to cover
+all languages and all machines using a single UNCOL. Our
+approach is more modest: we cater only to algebraic
+languages and machines whose memory consists of 8-bit bytes,
+each with its own address. Typical languages that could be
+handled include Ada, ALGOL 60, ALGOL 68, BASIC, C, FORTRAN,
+Modula, Pascal, PL/I, PL/M, PLAIN, and RATFOR, whereas
+COBOL, LISP, and SNOBOL would be less efficient. Examples of
+machines that could be included are the Intel 8080 and 8086,
+Motorola 6800, 6809, and 68000, Zilog Z80 and Z8000, DEC
+PDP-11 and VAX, and IBM 370 but not the Burroughs 6700, CDC
+Cyber, or Univac 1108 (because they are not byte-oriented).
+With these restrictions, we believe the old UNCOL idea can
+be used as the basis of a practical compiler-building
+system.</p>
+
+<p align=center>Fig. 1. The UNCOL model.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="An Overview of the Amsterdam Compiler Kit"></a>
+<h2>An Overview of the Amsterdam Compiler Kit</h2>
+
+<p>The tool kit consists of eight components:</p>
+
+<p>1. The preprocessor. 2. The front ends. 3. The peephole
+optimizer. 4. The global optimizer. 5. The back end. 6. The
+target machine optimizer. 7. The universal assembler/linker.
+8. The utility package.</p>
+
+<p>A fully optimizing compiler, depicted in Fig. 2, has
+seven cascaded phases. Conceptually, each component reads an
+input file and writes a transformed output file to be used
+as input to the next component. In practice, some components
+may use temporary files to allow multiple passes over the
+input or internal intermediate files.</p>
+
+<p align=center>Fig. 2. Structure of the Amsterdam Compiler
+Kit.</p>
+
+<p>In the following paragraphs we will briefly describe
+each component. After this overview, we will look at all of
+them again in more detail. A program to be compiled is first
+fed into the (language independent) preprocessor, which
+provides a simple macro facility, and similar textual
+facilties. The preprocessor&rsquo;s output is a legal
+program in one of the programming languages supported,
+whereas the input is a program possibly augmented with
+macros, etc.</p>
+
+<p>This output goes into the appropriate front end, whose
+job it is to produce intermediate code. This intermediate
+code (our UNCOL) is the machine language for a simple stack
+machine called EM (Encoding Machine). A typical front end
+might build a parse tree from the input, and then use the
+parse tree to generate EM code, which is similar to reverse
+Polish. In order to perform this work, the front end has to
+maintain tables of declared variables, labels, etc.,
+determine where to place the data structures in memory, and
+so on.</p>
+
+<p>The EM code generated by the front end is fed into the
+peephole optimizer, which scans it with a window of a few
+instructions, replacing certain inefficient code sequences
+by better ones. Such a search is important because EM
+contains instructions to handle numerous important special
+cases efficiently (e.g., incrementing a variable by 1). It
+is our strategy to relieve the front ends of the burden of
+hunting for special cases because there are many front ends
+and only one peephole optimizer. By handling the special
+cases in the peephole optimizer, the front ends become
+simpler, easier to write and easier to maintain.</p>
+
+<p>Following the peephole optimizer is a global optimizer
+[5], which unlike the peephole optimizer, examines the
+program as a whole. It builds a data flow graph to make
+possible a variety of global optimizations, among them,
+moving invariant code out of loops, avoiding redundant
+computations, live/dead analysis and eliminating tail
+recursion. Note that the output of the global optimizer is
+still EM code.</p>
+
+<p>Next comes the back end, which differs from the front
+ends in a fundamental way. Each front end is a separate
+program, whereas the back end is a single program that is
+driven by a machine dependent driving table. The driving
+table for a specific machine tells how the EM code is mapped
+onto the machine&rsquo;s assembly language. Although a
+simple driving table might just macro expand each EM
+instruction into a sequence of target machine instructions,
+a much more sophisticated translation strategy is normally
+used, as described later. For speed, the back end does not
+actually read in the driving table at run time. Instead, the
+tables are compiled along with the back end in advance,
+resulting in one binary program per machine.</p>
+
+<p>The output of the back end is a program in the assembly
+language of some particular machine. The next component in
+the pipeline reads this program and performs peephole
+optimization on it. The optimizations performed here involve
+idiosyncracies of the target machine that cannot be
+performed in the machine-independent EM-to-EM peephole
+optimizer. Typically these optimizations take advantage of
+special instructions or special addressing modes.</p>
+
+<p>The optimized target machine assembly code then goes
+into the final component in the pipeline, the universal
+assembler/linker. This program assembles the input to object
+format, extracting routines from libraries and including
+them as needed.</p>
+
+<p>The final component of the tool kit is the utility
+package, which contains various test programs, interpreters
+for EM code, EM libraries, conversion programs, and other
+aids for the implementer and user.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Preprocessor"></a>
+<h2>The Preprocessor</h2>
+
+<p>The function of the preprocessor is to extend all the
+programming languages by adding certain generally useful
+facilities to them in a uniform way. One of these is a
+simple macro system, in which the user can give names to
+character strings. The names can be used in the program,
+with the knowledge that they will be macro expanded prior to
+being input to the front end. Macros can be used for named
+constants, expanding short &quot;procedures&quot; in line,
+etc.</p>
+
+<p>Another useful facility provided by the preprocessor is
+the ability to include compile-time libraries. On large
+projects, it is common to have all the declarations and
+definitions gathered together in a few files that are
+textually included in the programs by instructing the
+preprocessor to read them in, thus fooling the front end
+into thinking that they were part of the source program.</p>
+
+<p>A third feature of the preprocessor is conditional
+compilation. The input program can be split up into labeled
+sections. By setting flags, some of the sections can be
+deleted by the preprocessor, thus allowing a family of
+slightly different programs to be conveniently stored on a
+single file.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Front Ends"></a>
+<h2>The Front Ends</h2>
+
+<p>A front end is a program that converts input in some
+source language to a program in EM. At present, front ends
+exist or are in preparation for Pascal, C, and Plain, and
+are being considered for Ada, ALGOL 68, FORTRAN 77, and
+Modula 2. Each of the present front ends is independent of
+all the other ones, although a general-purpose, table-driven
+front end is conceivable, provided one can devise a way to
+express the semantics of the source language in the driving
+tables. The Pascal front end uses a top-down parsing
+algorithm (recursive descent), whereas the C and Plain front
+ends are bottom-up.</p>
+
+<p>All front ends, independent of the language being
+compiled, produce a common intermediate code called EM,
+which is the assembly language for a simple stack machine.
+The EM machine is based on a memory architecture containing
+a stack for local variables, a (static) data area for
+variables declared in the outermost block and global to the
+whole program, and a heap for dynamic data structures. In
+some ways EM resembles P-code [6], but is more general,
+since it is intended for a wider class of languages than
+just Pascal.</p>
+
+<p>The EM instruction set has been described elsewhere
+[9,10,11] so we will only briefly summarize it here.
+Instructions exist to:</p>
+
+<p>1. Load a variable or constant of some length onto the
+stack. 2. Store the top item on the stack in memory. 3. Add,
+subtract, multiply, divide, etc. the top two stack items. 4.
+Examine the top one or two stack items and branch
+conditionally. 5. Call procedures and return from them.</p>
+
+<p>Loads and stores come in several variations,
+corresponding to the most common programming language
+semantics, for example, constants, simple variables, fields
+of a record, elements of an array, and so on. Distinctions
+are also made between variables local to the current block
+(i.e., stack frame), those in the outermost block (static
+storage), and those at intermediate lexicographic levels,
+which are accessed by following the static chain at run
+time.</p>
+
+<p>All arithmetic instructions have a type (integer,
+unsigned, real, pointer, or set) and an operand length,
+which may either be explicit or may be popped from the stack
+at run time. Monadic branch instructions pop an item from
+the stack and branch if it is less than zero, less than or
+equal to zero, etc. Dyadic branch instructions pop two
+items, compare them, and branch accordingly.</p>
+
+<p>In addition to these basic EM instructions, there is a
+collection of special purpose instructions (e.g., to
+increment a local variable), which are typically produced
+from the simple ones by the peephole optimizer. Although the
+complete EM instruction set contains nearly 150
+instructions, only about 60 of them are really primitive;
+the rest are simply abbreviations for commonly occurring EM
+instruction sequences.</p>
+
+<p>Of particular interest is the way object sizes are
+parametrized. The front ends allow the user to indicate how
+many bytes an integer, real, etc. should occupy. Given this
+information, the front ends can allocate memory, determining
+the placement of variables within the stack frame. Sizes for
+primitive types are restricted to 8, 16, 32, 64, etc. bits.
+The front ends are also parametrized by the target
+machine&rsquo;s word length and address size so they can
+tell, for example, how many &quot;load&quot; instructions to
+generate to move a 32-bit integer. In the examples used
+henceforth, we will assume a 16-bit word size and 16-bit
+integers.</p>
+
+<p>Since only byte-addressable target machines are
+permitted, it is nearly always possible to implement any
+requested sizes on any target machine. For example, the
+designer of the back end tables for the Z80 should provide
+code for 8-, 16-, and 32-bit arithmetic. In our view, the
+Pascal, C, or Plain programmer specifies what lengths are
+needed, without reference to the target machine, and the
+back end provides it. This approach greatly enhances
+portability. While it is true that doing all arithmetic
+using 32-bit integers on the Z80 will not be terribly fast,
+we feel that if that is what the programmer needs, it should
+be possible to implement it.</p>
+
+<p>Like all assembly languages, EM has not only machine
+instructions, but also pseudoinstructions. These are used to
+indicate the start and end of each procedure, allocate and
+initialize storage for data, and similar functions. One
+particularly important pseudoinstruction is the one that is
+used to transmit information to the back end for
+optimization purposes. It can be used to suggest variables
+that are good candidates to assign to registers, delimit the
+scope of loops, indicate that certain variables contain a
+useful value (next operation is a load) or not (next
+operation is a store), and various other things.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Peephole Optimizer"></a>
+<h2>The Peephole Optimizer</h2>
+
+<p>The peephole optimizer reads in unoptimized EM programs
+and writes out optimized ones. Both the input and output are
+expressed in a highly compact code, rather than in ASCII, to
+reduce the i/o time, which would otherwise dominate the CPU
+time. The program itself is table driven, and is, by and
+large, ignorant of the semantics of EM. The knowledge of EM
+is contained in a language- and machine-independent table
+consisting of about 400 pattern-replacement pairs. We will
+briefly describe the kinds of optimizations it performs
+below; a more complete discussion can be found in [9].</p>
+
+<p>Each line in the driving table describes one
+optimization, consisting of a pattern part and a replacement
+part. The pattern part is a series of one or more EM
+instructions and a boolean expression. The replacement part
+is a series of EM instructions with operands. A typical
+optimization might be:</p>
+
+<p>LOL LOC ADI STL ($1 = $4) and ($2 = 1) and ($3 = 2)
+==&gt; INL $1</p>
+
+<p>where the text prior to the ==&gt; symbol is the pattern
+and the text after it is the replacement. LOL loads a local
+variable onto the stack, LOC loads a constant onto the
+stack, ADI is integer addition, and STL is store local. The
+pattern specifies that four consecutive EM instructions are
+present, with the indicated opcodes, and that furthermore
+the operand of the first instruction (denoted by $1) and the
+fourth instruction (denoted by $4) are the same, the
+constant pushed by LOC is 1, and the size of the integers
+added by ADI is 2 bytes. (EM instructions have at most one
+operand, so it is not necessary to specify the operand
+number.) Under these conditions, the four instructions can
+be replaced by a single INL (increment local) instruction
+whose operand is equal to that of LOL.</p>
+
+<p>Although the optimizations cover a wide range, the main
+ones can be roughly divided into the following categories.
+<i>Constant folding</i> is used to evaluate constant
+expressions, such as 2*3 + 7 at compile time instead of run
+time. <i>Strength reduction</i> is used to replace one
+operation, such as multiply, by another, such as shift.
+<i>Reordering of expressions</i> helps in cases like -K/5,
+which can be better evaluated as K/-5, because the former
+requires a division and a negation, whereas the latter
+requires only a division. <i>Null instructions</i> include
+resetting the stack pointer after a call with 0 parameters,
+offsetting zero bytes to access the first element of a
+record, or jumping to the next instruction. <i>Special
+instructions</i> are those like INL, which deal with common
+special cases such as adding one to a variable or comparing
+something to zero. <i>Group moves</i> are useful because a
+sequence of consecutive moves can often be replaced with EM
+code that allows the back end to generate a loop instead of
+in line code. <i>Dead code elimination</i> is a technique
+for removing unreachable statements, possibly made
+unreachable by previous optimizations. <i>Branch chain
+compression</i> can be applied when a branch instruction
+jumps to another branch instruction. The first branch can
+jump directly to the final destination instead of
+indirectly.</p>
+
+<p>The last two optimizations logically belong in the
+global optimizer but are in the local optimizer for
+historical reasons (meaning that the local optimizer has
+been the only optimizer for many years and the optimizations
+were easy to do there).</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Global Optimizer"></a>
+<h2>The Global Optimizer</h2>
+
+<p>In contrast to the peephole optimizer, which examines
+the EM code a few lines at a time through a small window,
+the global optimizer examines the program&rsquo;s large
+scale structure. Three distinct types of optimizations can
+be found here:</p>
+
+<p>1. Interprocedural optimizations. 2. Intraprocedural
+optimizations. 3. Basic block optimizations.</p>
+
+<p>We will now look at each of these in turn.</p>
+
+<p>Interprocedural optimizations are those spanning
+procedure boundaries. The most important one is deciding to
+expand procedures in line, especially short procedures that
+occur in loops and pass several parameters. If it takes more
+time or memory to pass the parameters than to do the work,
+the program can be improved by eliminating the procedure.
+The inverse optimization -- discovering long common code
+sequences and turning them into a procedure -- is also
+possible, but much more difficult. Like much of the global
+optimizer&rsquo;s work, the decision to make or not make a
+certain program transformation is a heuristic one, based on
+knowledge of how the back end works, how most target
+machines are organized, etc.</p>
+
+<p>The heart of the global optimizer is its analysis of
+individual procedures. To perform this analysis, the
+optimizer must locate the basic blocks, instruction
+sequences which can be entered only at the top and exited
+only at the bottom. It then constructs a data flow graph,
+with the basic blocks as nodes and jumps between blocks as
+arcs.</p>
+
+<p>From the data flow graph, many important properties of
+the program can be discovered and exploited. Chief among
+these is the presence of loops, indicated by cycles in the
+graph. One important optimization is looking for code that
+can be moved outside the loop, either prior to it or
+subsequent to it. Such code motion saves execution time,
+although it does not save memory. Unrolling loops is also
+possible and desirable in some cases.</p>
+
+<p>Another area in which global analysis of loops is
+especially important is in register allocation. While it is
+true that EM does not have any registers to allocate, the
+optimizer can easily collect information to allow the back
+end to allocate registers wisely. For example, the global
+optimizer can collect static frequency-of-use and live/dead
+information about variables. (A variable is dead at some
+point in the program if its current value is not needed,
+i.e., the next reference to it overwrites it rather than
+reading it; if the current value will eventually be used,
+the variable is live.) If two variables are never
+simultaneously live over some interval of code (e.g., the
+body of a loop), they can be packed into a single variable,
+which, if used often enough, may warrant being assigned to a
+register.</p>
+
+<p>Many loops involve arrays: this leads to other
+optimizations. If an array is accessed sequentially, with
+each iteration using the next higher numbered element, code
+improvement is often possible. Typically, a pointer to the
+bottom element of each array can be set up prior to the
+loop. Within the loop the element is accessed indirectly via
+the pointer, which is also incremented by the element size
+on each iteration. If the target machine has an
+autoincrement addressing mode and the pointer is assigned to
+a register, an array access can often be done in a single
+instruction.</p>
+
+<p>Other intraprocedural optimizations include removing
+tail recursion (last statement is a recursive call to the
+procedure itself), topologically sorting the basic blocks to
+minimize the number of branch instructions, and common
+subexpression recognition.</p>
+
+<p>The third general class of optimizations done by the
+global optimizer is improving the structure of a basic
+block. For the most part these involve transforming
+arithmetic or boolean expressions into forms that are likely
+to result in better target code. As a simple example, A +
+B*C can be converted to B*C + A. The latter can often be
+handled by loading B into a register, multiplying the
+register by C, and then adding in A, whereas the former may
+involve first putting A into a temporary, depending on the
+details of the code generation table. Another example of
+this kind of basic block optimization is transforming -B + A
+&lt; 0 into the equivalent, but simpler, A &lt; B.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Back End"></a>
+<h2>The Back End</h2>
+
+<p>The back end reads a stream of EM instructions and
+generates assembly code for the target machine. Although the
+algorithm itself is machine independent, for each target
+machine a machine dependent driving table must be supplied.
+The driving table effectively defines the mapping of EM code
+to target code.</p>
+
+<p>It will be convenient to think of the EM instructions
+being read as a stream of tokens. For didactic purposes, we
+will concentrate on two kinds of tokens: those that load
+something onto the stack, and those that perform some
+operation on the top one or two values on the stack. The
+back end maintains at compile time a simulated stack whose
+behavior mirrors what the stack of a hardware EM machine
+would do at run time. If the current input token is a load
+instruction, a new entry is pushed onto the simulated
+stack.</p>
+
+<p>Consider, as an example, the EM code produced for the
+statement K := I + 7. If K and I are 2-byte local variables,
+it will normally be LOL I; LOC 7; ADI 2; STL K. Initially
+the simulated stack is empty. After the first token has been
+read and processed, the simulated stack will contain a stack
+token of type MEM with attributes telling that it is a
+local, giving its address, etc. After the second token has
+been read and processed, the top two tokens on the simulated
+stack will be CON (constant) on top and MEM directly
+underneath it.</p>
+
+<p>At this point the back end reads the ADI 2 token and
+looks in the driving table to find a line or lines that
+define the action to be taken for ADI 2. For a typical
+multiregister machine, instructions will exist to add
+constants to registers, but not to memory. Consequently, the
+driving table will not contain an entry for ADI 2 with stack
+configuration CON, MEM.</p>
+
+<p>The back end is now faced with the problem of how to get
+from its current stack configuration, CON, MEM, which is not
+listed, to one that is listed. The table will normally
+contain rules (which we call &quot;coercions&quot;) for
+converting between CON, REG, MEM, and similar tokens.
+Therefore the back end attempts to &quot;coerce&quot; the
+stack into a configuration that <i>is</i> present in the
+table. A typical coercion rule might tell how to convert a
+MEM into a REG, namely by performing the actions of
+allocating a register and emitting code to move the memory
+word to that register. Having transformed the compile-time
+stack into a configuration allowed for ADI 2, the rule can
+be carried out. A typical rule for ADI 2 might have stack
+configuration REG, MEM and would emit code to add the MEM to
+the REG, leaving the stack with a single REG token instead
+of the REG and MEM tokens present before the ADI 2.</p>
+
+<p>In general, there will be more than one possible
+coercion path. Assuming reasonable coercion rules for our
+example, we might be able to convert CON MEM into CON REG by
+loading the variable I into a register. Alternatively, we
+could coerce CON to REG by loading the constant into a
+register. The first coercion path does the add by first
+loading I into a register and then adding 7 to it. The
+second path first loads 7 into a register and then adds I to
+it. On machines with a fast LOAD IMMEDIATE instruction for
+small constants but no fast ADD IMMEDIATE, or vice versa,
+one code sequence will be preferable to the other.</p>
+
+<p>In fact, we actually have more choices than suggested
+above. In both coercion paths a register must be allocated.
+On many machines, not every register can be used in every
+operation, so the choice may be important. On some machines,
+for example, the operand of a multiply must be in an odd
+register. To summarize, from any state (i.e., token and
+stack configuration), a variety of choices can be made,
+leading to a variety of different target code sequences.</p>
+
+<p>To decide which of the various code sequences to emit,
+the back end must have some information about the time and
+memory cost of each one. To provide this information, each
+rule in the driving table, including coercions, specifies
+both the time and memory cost of the code emitted when the
+rule is applied. The back end can then simply try each of
+the legal possibilities (including all the possible register
+allocations) to find the cheapest one.</p>
+
+<p>This situation is similar to that found in a chess or
+other game-playing program, in which from any state a finite
+number of moves can be made. Just as in a chess program, the
+back end can look at all the &quot;moves&quot; that can be
+made from each state reachable from the original state, and
+thus find the sequence that gives the minimum cost to a
+depth of one. More generally, the back end can evaluate all
+paths corresponding to accepting the next <i>N</i> input
+tokens, find the cheapest one, and then make the first move
+along that path, precisely the way a chess program
+would.</p>
+
+<p>Since the back end is analogous to both a parser and a
+chess playing program, some clarifying remarks may be
+helpful. First, chess programs and the back end must do some
+look ahead, whereas the parser for a well-designed grammar
+can usually suffice with one input token because grammars
+are supposed to be unambiguous. In contrast, many legal
+mappings from a sequence of EM instructions to target code
+may exist. Second, like a parser but unlike a chess program,
+the back end has perfect information -- it does not have to
+contend with an unpredictable opponent&rsquo;s moves. Third,
+chess programs normally make a static evaluation of the
+board and label the <i>nodes</i> of the tree with the
+resulting scores. The back end, in contrast, associates
+costs with <i>arcs</i> (moves) rather than nodes (states).
+However, the difference is not essential, since it could
+also label each node with the cumulative cost from the root
+to that node.</p>
+
+<p>As mentioned above, the cost field in the table contains
+<i>both</i> the time and memory costs for the code emitted.
+It should be clear that the back end could use either one or
+some linear combination of them as the scoring function for
+evaluating moves. A user can instruct the compiler to
+optimize for time or for memory or for, say, 0.3 x time +
+0.7 x memory. Thus the same compiler can provide a wide
+range of performance options to the user. The writer of the
+back end table can take advantage of this flexibility by
+providing several code sequences with different tradeoffs
+for each EM instruction (e.g., in line code vs. call to a
+run time routine).</p>
+
+<p>In addition to the time-space tradeoffs, by specifying
+the depth of search parameter, <i>N</i>, the user can
+effectively also tradeoff compile time vs. object code
+quality, for whatever code metric has been chosen. In
+summary, by combining the properties of a parser and a game
+playing program, it is possible to make a code generator
+that is table driven, highly flexible, and has the ability
+to produce good code from a stack machine intermediate
+code.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Target Machine Optimizer"></a>
+<h2>The Target Machine Optimizer</h2>
+
+<p>In the model of Fig 2., the peephole optimizer comes
+before the global optimizer. It may happen that the code
+produced by the global optimizer can also be improved by
+another round of peephole optimization. Conceivably, the
+system could have been designed to iterate peephole and
+global optimizations until no more of either could be
+performed.</p>
+
+<p>However, both of these optimizations are done on the
+machine independent EM code. Neither is able to take
+advantage of the peculiarities and idiosyncracies with which
+most target machines are well endowed. It is the function of
+the final optimizer to do any (peephole) optimizations that
+still remain.</p>
+
+<p>The algorithm used here is the same as in the EM
+peephole optimizer. In fact, if it were not for the
+differences between EM syntax, which is very restricted, and
+target assembly language syntax, which is less so, precisely
+the same program could be used for both. Nevertheless, the
+same ideas apply concerning patterns and replacements, so
+our discussion of this optimizer will be restricted to one
+example.</p>
+
+<p>To see what the target optimizer might do, consider the
+PDP-11 instruction sequence sub #2,r0; mov (r0),x. First 2
+is subtracted from register 0, then the word pointed to by
+it is moved to x. The PDP-11 happens to have an addressing
+mode to perform this sequence in one instruction: mov
+-(r0),x. Although it is conceivable that this instruction
+could be included in the back end driving table for the
+PDP-11, it is awkward to do so because it can occur in so
+many contexts. It is much easier to catch things like this
+in a separate program.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Universal Assembler/Linker"></a>
+<h2>The Universal Assembler/Linker</h2>
+
+<p>Although assembly languages for different machines may
+appear very different at first glance, they have a
+surprisingly large intersection. We have been able to
+construct an assembler/linker that is almost entirely
+independent of the assembly language being processed. To
+tailor the program to a specific assembly language, it is
+necessary to supply a table giving the list of instructions,
+the bit patterns required for each one, and the language
+syntax. The machine independent part of the assembler/linker
+is then compiled with the table to produce an assembler and
+linker for a particular target machine. Experience has shown
+that writing the necessary table for a new machine can be
+done in less than a week.</p>
+
+<p>To enforce a modicum of uniformity, we have chosen to
+use a common set of pseudoinstructions for all target
+machines. They are used to initialize memory, allocate
+uninitialized memory, determine the current segment, and
+similar functions found in most assemblers.</p>
+
+<p>The assembler is also a linker. After assembling a
+program, it checks to see if there are any unsatisfied
+external references. If so, it begins reading the libraries
+to find the necessary routines, including them in the object
+file as it finds them. This approach requires libraries to
+be maintained in assembly language form, but eliminates the
+need for inventing a language to express relocatable object
+programs in a machine independent way. It also simplifies
+the assembler, since producing absolute object code is
+easier than producing relocatable object code. Finally,
+although assembly language libraries may be somewhat larger
+than relocatable object module libraries, the loss in speed
+due to having more input may be more than compensated for by
+not having to pass an intermediate file between the
+assembler and linker.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="The Utility Package"></a>
+<h2>The Utility Package</h2>
+
+<p>The utility package is a collection of programs designed
+to aid the implementers of new front ends or new back ends.
+The most useful ones are the test programs. For example, one
+test set, EMTEST, systematically checks out a back end by
+executing an ever larger subset of the EM instructions. It
+starts out by testing LOC, LOL and a few of the other
+essential instructions. If these appear to work, it then
+tries out new instructions one at a time, adding them to the
+set of instructions &quot;known&quot; to work as they pass
+the tests.</p>
+
+<p>Each instruction is tested with a variety of operands
+chosen from values where problems can be expected. For
+example, on target machines which have 16-bit index
+registers but only allow 8-bit displacements, a
+fundamentally different algorithm may be needed for
+accessing the first few bytes of local variables and those
+with offsets of thousands. The test programs have been
+carefully designed to thoroughly test all relevant
+cases.</p>
+
+<p>In addition to EMTEST, test programs in Pascal, C, and
+other languages are also available. A typical test is:</p>
+
+<p>i := 9; <b>if</b> i + 250 &lt;&gt; 259 <b>then</b>
+error(16);</p>
+
+<p>Like EMTEST, the other test programs systematically
+exercise all features of the language being tested, and do
+so in a way that makes it possible to pinpoint errors
+precisely. While it has been said that testing can only
+demonstrate the presence of errors and not their absence,
+our experience is that the test programs have been
+invaluable in debugging new parts of the system quickly.</p>
+
+<p>Other utilities include programs to convert the highly
+compact EM code produced by front ends to ASCII and vice
+versa, programs to build various internal tables from human
+writable input formats, a variety of libraries written in or
+compiled to EM to make them portable, an EM assembler, and
+EM interpreters for various machines.</p>
+
+<p>Interpreting the EM code instead of translating it to
+target machine language is useful for several reasons.
+First, the interpreters provide extensive run time
+diagnostics including an option to list the original source
+program (in Pascal, C, etc.) with the execution frequency or
+execution time for each source line printed in the left
+margin. Second, since an EM program is typically about
+one-third the size of a compiled program, large programs can
+be executed on small machines. Third, running the EM code
+directly makes it easier to pinpoint errors in the EM output
+of front ends still being debugged.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="Summary and Conclusions"></a>
+<h2>Summary and Conclusions</h2>
+
+<p>The Amsterdam Compiler Kit is a tool kit for building
+portable (cross) compilers and interpreters. The main pieces
+of the kit are the front ends, which convert source programs
+to EM code, optimizers, which improve the EM code, and back
+ends, which convert the EM code to target assembly language.
+The kit is highly modular, so writing one front end (and its
+associated runtime routines) is sufficient to implement a
+new language on a dozen or more machines, and writing one
+back end table and one universal assembler/linker table is
+all that is needed to bring up all the previously
+implemented languages on a new machine. In this manner, the
+contents, and hopefully the usefulness, of the toolkit will
+increase in time.</p>
+
+<p>We believe the principal lesson to be learned from our
+work is that the old UNCOL idea is basically a sound way to
+produce compilers, provided suitable restrictions are placed
+on the source languages and target machines. We also believe
+that although compilers produced by this technology may not
+be equal to the very best handcrafted compilers, in terms of
+object code quality, they are certainly competitive with
+many existing compilers. However, when one factors in the
+cost of producing the compiler, the possible slight loss in
+performance may be more than compensated for by the large
+decrease in production cost. As a consequence of our work
+and similar work by other researchers [1,3,4], we expect
+integrated compiler building kits to become increasingly
+popular in the near future.</p>
+
+<p>The toolkit is now available for various computers
+running the <small>UNIX</small> &reg; operating system. For
+information, contact the authors.</p>
+<a name="*."></a>
+<h2>*.</h2>
+<a name="References"></a>
+<h2>References</h2>
+
+<p><b>1.</b> Graham, S.L. Table-Driven Code Generation.
+<i>Computer 13</i>, 8 (August 1980), 25-34.</p>
+
+<p>A discussion of systematic ways to do code generation,
+in particular, the idea of having a table with templates
+that match parts of the parse tree and convert them into
+machine instructions.</p>
+
+<p><b>2.</b> Haddon, B.K., and Waite, W.M. Experience with
+the Universal Intermediate Language Janus. <i>Software
+Practice &amp; Experience 8</i>, 5 (Sept.-Oct. 1978),
+601-616.</p>
+
+<p>An intermediate language for use with ALGOL 68, Pascal,
+etc. is described. The paper discusses some problems
+encountered and how they were dealt with.</p>
+
+<p><b>3.</b> Johnson, S.C. A Portable Compiler: Theory and
+Practice. <i>Ann. ACM Symp. Prin. Prog. Lang.</i>, Jan.
+1978.</p>
+
+<p>A cogent discussion of the portable C compiler.
+Particularly interesting are the author&rsquo;s thoughts on
+the value of computer science theory.</p>
+
+<p><b>4.</b> Leverett, B.W., Cattell, R.G.G, Hobbs, S.O.,
+Newcomer, J.M., Reiner, A.H., Schatz, B.R., and Wulf, W.A.
+An Overview of the Production-Quality Compiler-Compiler
+Project. <i>Computer 13</i>, 8 (August 1980), 38-49.</p>
+
+<p>PQCC is a system for building compilers similar in
+concept but differing in details from the Amsterdam Compiler
+Kit. The paper describes the intermediate representation
+used and the code generation strategy.</p>
+
+<p><b>5.</b> Lowry, E.S., and Medlock, C.W. Object Code
+Optimization. <i>Commun. ACM 12</i>, (Jan. 1969), 13-22.</p>
+
+<p>A classic paper on global object code optimization. It
+covers data flow analysis, common subexpressions, code
+motion, register allocation and other techniques.</p>
+
+<p><b>6.</b> Nori, K.V., Ammann, U., Jensen, K., Nageli, H.
+The Pascal P Compiler Implementation Notes. Eidgen. Tech.
+Hochschule, Zurich, 1975.</p>
+
+<p>A description of the original P-code machine, used to
+transport the Pascal-P compiler to new computers.</p>
+
+<p><b>7.</b> Steel, T.B., Jr. UNCOL: the Myth and the Fact.
+in <i>Ann. Rev. Auto. Prog.</i> Goodman, R. (ed.), vol 2.,
+(1960), 325-344.</p>
+
+<p>An introduction to the UNCOL idea by its originator.</p>
+
+<p><b>8.</b> Steel, T.B., Jr. A First Version of UNCOL.
+<i>Proc. Western Joint Comp. Conf.</i>, (1961), 371-377.</p>
+
+<p>The first detailed proposal for an UNCOL. By current
+standards it is a primitive language, but it is interesting
+for its historical perspective.</p>
+
+<p><b>9.</b> Tanenbaum, A.S., van Staveren, H., and
+Stevenson, J.W. Using Peephole Optimization on Intermediate
+Code. <i>ACM Trans. Prog. Lang. and Sys. 3</i>, 1 (Jan.
+1982) pp. 21-36.</p>
+
+<p>A detailed description of a table-driven peephole
+optimizer. The driving table provides a list of patterns to
+match as well as the replacement text to use for each
+successful match.</p>
+
+<p><b>10.</b> Tanenbaum, A.S., Stevenson, J.W., Keizer,
+E.G., and van Staveren, H. Description of an Experimental
+Machine Architecture for use with Block Structured
+Languages. Informatica Rapport 81, Vrije Universiteit,
+Amsterdam, 1983.</p>
+
+<p>The defining document for EM.</p>
+
+<p><b>11.</b> Tanenbaum, A.S. Implications of Structured
+Programming for Machine Architecture. <i>Comm. ACM 21</i>, 3
+(March 1978), 237-246.</p>
+
+<p>The background and motivation for the design of EM. This
+early version emphasized the idea of interpreting the
+intermediate code (then called EM-1) rather than compiling
+it.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/toolkit.pdf b/src/olddocs/toolkit.pdf
new file mode 100644 (file)
index 0000000..49e706c
Binary files /dev/null and b/src/olddocs/toolkit.pdf differ
diff --git a/src/olddocs/top.html b/src/olddocs/top.html
new file mode 100644 (file)
index 0000000..e8d4c7e
--- /dev/null
@@ -0,0 +1,1210 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:18 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>The ACK Target Optimizer</title>
+</head>
+<body>
+
+<h1 align=center>The ACK Target Optimizer</h1>
+<a href="#1. Introduction">1. Introduction</a><br>
+<a href="#2. Global structure of the target optimizer">2. Global structure of the target optimizer</a><br>
+<a href="#2.1. Assumptions about the assembly code format">2.1. Assumptions about the assembly code format</a><br>
+<a href="#2.2. Informal description of the machine-dependent tables">2.2. Informal description of the machine-dependent tables</a><br>
+<a href="#2.3. Examples">2.3. Examples</a><br>
+<a href="#2.3.1. Vax examples">2.3.1. Vax examples</a><br>
+<a href="#2.3.2. PDP-11 examples">2.3.2. PDP-11 examples</a><br>
+<a href="#3. Implementation of the target optimizer">3. Implementation of the target optimizer</a><br>
+<a href="#3.1. The window mechanism">3.1. The window mechanism</a><br>
+<a href="#3.2. Pattern matching">3.2. Pattern matching</a><br>
+<a href="#3.3. Data structures">3.3. Data structures</a><br>
+<a href="#4. Implementation of the target optimizer generator">4. Implementation of the target optimizer generator</a><br>
+<a href="#5. References">5. References</a><br>
+<a href="#References">References</a><br>
+<a href="#Appendix A">Appendix A</a><br>
+
+<hr>
+
+<p align=center><i>ABSTRACT</i></p>
+
+<p align=center><i>H.E. Bal</i><br>
+Vrije Universiteit<br>
+Wiskundig Seminarium, Amsterdam</p>
+
+<p>The Target Optimizer is one of several optimizers that
+are part of the Amsterdam Compiler Kit. It operates directly
+on assembly code, rather than on a higher level intermediate
+code, as the Peephole Optimizer and Global Optimizer do.
+Consequently, the Target Optimizer can do optimizations that
+are highly machine-dependent.</p>
+
+<p>Each target machine has its own Target Optimizer. New
+optimizers are generated by the Target Optimizer Generator,
+which uses a machine-dependent table as input. This document
+contains full information on how to write such a table for a
+new machine. It also discusses the implementation of the
+Target Optimizer and its generator.</p>
+<a name="1. Introduction"></a>
+<h2>1. Introduction</h2>
+
+<p align=center><img src="grohtml-102411.png"></p>
+
+<p>This document describes the target optimizer component
+of the Amsterdam Compiler Kit (ACK) .[Tane81a, Tane83a,
+Tane83b] Optimization takes place in several parts of ACK
+compilers, most notably in the Peephole Optimizer[Tane82a]
+and the Global Optimizer,[Bal85b, Bal85a] which are both
+language- and machine-independent, and in the
+machine-specific code generators.[Tane84a] The target
+optimizer is the finishing touch in this sequence of
+optimizers. It can be used to capture those optimizations
+that are hard to express in the other parts of ACK. These
+optimizations will typically be very machine-specific.</p>
+
+<p>The target optimizer operates on the assembly code of
+some target machine. Hence there is one target optimizer per
+machine. However, just as for the ACK code generators and
+assemblers, a framework has been build that allows easy
+generation of target optimizers out of machine-independent
+parts and a machine-dependent description table (see figure
+1.). So the major part of the code of a target optimizer is
+shared among all target optimizers.</p>
+<pre>                                            |-------------------------|
+                                            | machine-independent     |
+                                            | code                    |
+                                            |                         |
+               |-----------------|          |-------------------------|
+     descrip-  |target optimizer |          | machine-dependent code  |
+      tion --&gt; |generator        | ----&gt;    | + tables                |
+     table     |                 |          |                         |
+               |-----------------|          |-------------------------|
+
+
+                                                   target optimizer
+
+
+         Figure 1: Generation of a target optimizer.
+
+
+</pre>
+
+<p>This document focusses on the description of the
+machine-dependent table. In chapter 2 we give an informal
+introduction to the optimization algorithm and to the
+definition of the table format. Chapters 3 and 4 discuss the
+implementation of the target optimizer and the target
+optimizer generator. Appendix A gives full information for
+writing a description table.</p>
+<a name="2. Global structure of the target optimizer"></a>
+<h2>2. Global structure of the target optimizer</h2>
+
+<p>The target optimizer is based on the well understood
+model of a <i>peephole optimizer</i>.[Aho78a] It contains a
+machine-dependent table of (pattern,replacement) pairs. Each
+pattern describes a sequence of one or more assembler
+instructions that can be replaced by zero or more
+equivalent, yet cheaper, instructions (the
+&rsquo;replacement&rsquo;). The optimizer maintains a
+<i>window</i> that moves over the input. At any moment, the
+window contains some contiguous part of the input. If the
+instructions in the current window match some pattern in the
+table, they are replaced by the corresponding replacement;
+else, the window moves one instruction to the right.</p>
+
+<p>In the remainder of this section we will give an
+informal description of the machine-dependent table. A more
+precise definition is given in appendix A. We will first
+discuss the restrictions put on the format of the assembly
+code.</p>
+<a name="2.1. Assumptions about the assembly code format"></a>
+<h2>2.1. Assumptions about the assembly code format</h2>
+
+<p>We assume that a line of assembly code begins with an
+instruction <i>mnemonic</i> (opcode), followed by zero or
+more <i>operands</i>. The mnemonic and the first operand
+must be separated by a special character (e.g. a space or a
+tab). Likewise, the operands must be separated by a special
+character (e.g. a comma). These separators need not be the
+same for all machines.</p>
+<a name="2.2. Informal description of the machine-dependent tables"></a>
+<h2>2.2. Informal description of the machine-dependent tables</h2>
+
+<p>The major part of the table consists of
+(pattern,replacement) pairs called <i>entries</i>.</p>
+
+<p>A pattern is a list of instruction descriptions. Each
+instruction description describes the instruction mnemonic
+and the operands.</p>
+
+<p>A mnemonic is described either by a string constant or
+by the keyword ANY. As all entities dealt with by the target
+optimizer are strings, string constants do not contain
+quotes. A string constant matches only itself. ANY matches
+every instruction mnemonic.</p>
+<pre>Examples of mnemonic descriptions:
+
+       add
+        sub.l
+        mulw3
+        ANY
+</pre>
+
+<p>An operand can also be described by a string
+constant.</p>
+<pre>Examples:
+
+      (sp)+
+       r5
+       -4(r6)
+
+</pre>
+
+<p>Alternatively, it can be described by means of a
+<i>variable name</i>. Variables have values which are
+strings. They have to be declared in the table before the
+patterns. Each such declaration defines the name of a
+variable and a <i>restriction</i> to which its value is
+subjected.</p>
+<pre>Example of variable declarations:
+
+     CONST       { VAL[0] == &rsquo;$&rsquo; };
+      REG         { VAL[0] == &rsquo;r&rsquo; &amp;&amp; VAL[1] &gt;= &rsquo;0&rsquo; &amp;&amp; VAL[1] &lt;= &rsquo;3&rsquo; &amp;&amp;
+                    VAL[2] == &rsquo;\0&rsquo; };
+      X           { TRUE };
+
+</pre>
+
+<p>The keyword VAL denotes the value of the variable, which
+is a null-terminated string. An operand description given
+via a variable name matches an actual operand if the actual
+operand obeys the associated restriction.</p>
+<pre>     CONST  matches   $1, $-5, $foo etc.
+     REG    matches   r0, r1, r2 and r3
+     X      matches   anything
+
+</pre>
+
+<p>The restriction (between curly braces) may be any legal
+&quot;C&quot;[Kern78a] expression. It may also contain calls
+to user-defined procedures. These procedures must be added
+to the table after the patterns.</p>
+<pre>Example:
+
+    FERMAT_NUMBER    { VAL[0] == &rsquo;$&rsquo; &amp;&amp; is_fermat_number(&amp;VAL[1]) };
+
+</pre>
+
+<p>An operand can also be described by a mixture of a
+string constant and a variable name. The most general form
+allowed is:</p>
+<pre>       string_constant1 variable_name string_constant2
+
+Example:
+
+      (REG)+  matches  (r0)+, (r1)+, (r2)+ and (r3)+
+
+</pre>
+
+<p>Any of the three components may be omitted, so the first
+two forms are just special cases of the general form. The
+name of a variable can not be used as a string constant. In
+the above context, it is impossible to define an operand
+that matches the string &quot;REG&quot;. This limitation is
+of little consequence, as the table writer is free to choose
+the names of variables. This approach, however, avoids the
+need for awkward escape sequences.</p>
+
+<p>A pattern consists of one or more instruction
+descriptions (separated by a colon) followed by an optional
+constraint. A pattern &quot;P1 : P2 : .. : Pn C&quot;
+matches the sequence of instructions &quot;I1 I2 .. In&quot;
+if:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p>for each i, 1 &lt;= i &lt;= n, Pi matches Ii, as
+described above;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p>multiple occurrences of the same variable name or of the
+keyword ANY stand for the same values throughout the
+pattern;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>(iii)</p>
+</td>
+<td width="4%"></td>
+<td width="86%">
+
+<p>the optional constraint C is satisfied, i.e. it
+evaluates to TRUE.</p>
+</td>
+</table>
+<pre>The pattern:
+
+     dec REG : move.b CONST,(REG)
+
+matches:
+
+     dec r0 : move.b $4,(r0)
+
+but not:
+
+     dec r0 : move.b $4,(r1)
+
+(as the variable REG matches two different strings).
+</pre>
+
+<p>If a pattern containing different registers must be
+described, extra names for a register should be declared,
+all sharing the same restriction.</p>
+<pre>Example:
+
+    REG1,REG2  { VAL[0] == &rsquo;r&rsquo; &amp;&amp;  .....  };
+
+    addl3 REG1,REG1,REG2 : subl2 REG2,REG1
+</pre>
+
+<p>The optional constraint is an auxiliary &quot;C&quot;
+expression (just like the parameter restrictions). The
+expression may refer to the variables and to ANY.</p>
+<pre>Example:
+
+   move REG1,REG2    { REG1[1] == REG2[1] + 1 }
+
+matches
+
+   move r1,r0
+    move r2,r1
+    move r3,r2
+</pre>
+
+<p>The replacement part of a (pattern,replacement) table
+entry has the same structure as a pattern, except that:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="4%"></td>
+<td width="88%">
+
+<p>it may not contain an additional constraint;</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="2%"></td>
+<td width="32%">
+
+<p>it may be empty.</p>
+</td>
+<td width="57%">
+</td>
+</table>
+
+<p>A replacement may also refer to the values of variables
+and ANY.</p>
+<a name="2.3. Examples"></a>
+<h2>2.3. Examples</h2>
+
+<p>This section contains some realistic examples for
+optimization on PDP-11 and Vax assembly code.</p>
+<a name="2.3.1. Vax examples"></a>
+<h2>2.3.1. Vax examples</h2>
+
+<p>Suppose the table contains the following
+declarations:</p>
+<pre>         X, LOG        { TRUE };
+         LAB           { VAL[0] == &rsquo;L&rsquo; };   /* e.g. L0017 */
+         A             { no_side_effects(VAL) };
+         NUM           { is_number(VAL) };
+
+</pre>
+
+<p>The procedure &quot;no_side_effects&quot; checks if its
+argument contains any side effects, i.e. auto increment or
+auto decrement. The procedure &quot;is_number&quot; checks
+if its argument contains only digits. These procedures must
+be supplied by the table-writer and must be included in the
+table.</p>
+<pre><i>entry:</i>  addl3 X,A,A    -&gt; addl2 X,A;
+
+</pre>
+
+<p>This entry changes a 3-operand instruction into a
+cheaper 2-operand instruction. An optimization like:</p>
+<pre>        addl3 r0,(r2)+,(r2)+   -&gt; addl2 r0,(r2)+
+
+</pre>
+
+<p>is illegal, as r2 should be incremented twice. Hence the
+second argument is required to be side-effect free.</p>
+<pre><i>entry:</i>  addw2 $-NUM,X  -&gt; subw2 $NUM,X;
+
+</pre>
+
+<p>An instruction like &quot;subw2 $5,r0&quot; is cheaper
+than &quot;addw2 $-5,r0&quot;, because constants in the
+range 0 to 63 are represented very efficiently on the
+Vax.</p>
+<pre><i>entry:</i>  bitw $NUM,A : jneq LAB
+                { is_poweroftwo(NUM,LOG) }  -&gt; jbs $LOG,A,LAB;
+
+</pre>
+
+<p>A &quot;bitw x,y&quot; sets the condition codes to the
+bitwise &quot;and&quot; of x and y. A &quot;jbs n,x,l&quot;
+branches to l if bit n of x is set. So, for example, the
+following transformation is possible:</p>
+<pre>      bitw $32,r0 : jneq L0017 -&gt;  jbs $5,r0,L0017
+
+</pre>
+
+<p>The user-defined procedure &quot;is_poweroftwo&quot;
+checks if its first argument is a power of 2 and, if so,
+sets its second argument to the logarithm of the first
+argument. (Both arguments are strings). Note that the
+variable LOG is not used in the pattern itself. It is
+assigned a (string) value by &quot;is_poweroftwo&quot; and
+is used in the replacement.</p>
+<a name="2.3.2. PDP-11 examples"></a>
+<h2>2.3.2. PDP-11 examples</h2>
+
+<p>Suppose we have the following declarations:</p>
+<pre>         X             { TRUE };
+         A             { no_side_effects(VAL) };
+         L1, L2        { VAL[0] == &rsquo;I&rsquo; };
+         REG           { VAL[0] == &rsquo;r&rsquo; &amp;&amp; VAL[1] &gt;= &rsquo;0&rsquo; &amp;&amp; VAL[1] &lt;= &rsquo;5&rsquo; &amp;&amp;
+                         VAL[2] == &rsquo;\0&rsquo; };
+
+</pre>
+
+<p>The implementation of &quot;no_side_effects&quot; may of
+course differ for the PDP-11 and the Vax.</p>
+<pre><i>entry:</i>  mov REG,A : ANY A,X  -&gt;  mov REG,A : ANY REG,X ;
+
+</pre>
+
+<p>This entry implements register subsumption. If A and REG
+hold the same value (which is true after &quot;mov
+REG,A&quot;) and A is used as source (first) operand, it is
+cheaper to use REG instead.</p>
+<pre><i>entry:</i>  jeq L1 : jbr L2 : labdef L1  -&gt;  jne L2 : labdef L1;
+
+</pre>
+
+<p>The &quot;jeq L1&quot; is a &quot;skip over an
+unconditional jump&quot;. &quot;labdef L1&quot; denotes the
+definition (i.e. defining occurrence) of label L1. As the
+target optimizer has to know how such a definition looks
+like, this must be expressed in the table (see Appendix
+A).</p>
+<pre><i>entry:</i>  add $01,X { carry_dead(REST) }  -&gt; inc X;
+
+</pre>
+
+<p>On the PDP-11, an add-one is not equivalent to an
+increment. The latter does not set the carry-bit of the
+condition codes, while the former does. So a look-ahead is
+needed to see if the rest of the input uses the carry-bit
+before changing the condition codes. A look-ahead of one
+instruction is provided by the target optimizer. This will
+normally be sufficient for compiler-generated code. The
+keyword REST contains the mnemonic of the first instruction
+of the rest of the input. If this instruction uses the
+carry-bit (e.g. an adc, subc, bhis) the transformation is
+not allowed.</p>
+<a name="3. Implementation of the target optimizer"></a>
+<h2>3. Implementation of the target optimizer</h2>
+
+<p>The target optimizer reads one input file of assembler
+instructions, processes it, and writes the optimized code to
+the output file. So it performs one pass over the input.</p>
+<a name="3.1. The window mechanism"></a>
+<h2>3.1. The window mechanism</h2>
+
+<p>The optimizer uses a <i>window</i> that moves over the
+input. It repeatedly tries to match the instructions in the
+window with the patterns in the table. If no match is
+possible, the window moves one instruction forwards (to the
+right). After a successful match the matched instructions
+are removed from the window and are replaced by the
+replacement part of the table entry. Furthermore, the window
+is moved a few instructions backwards, as it is possible
+that instructions that were rejected earlier now do match.
+For example, consider the following patterns:</p>
+<pre>     cmp $0, X           -&gt; tst X ;
+     mov REG,X : tst X   -&gt; move REG.X ;   /* redundant test */
+</pre>
+
+<p>If the input is:</p>
+<pre>     mov r0,foo : cmp $0,foo
+</pre>
+
+<p>then the first instruction is initially rejected.
+However, after the transformation</p>
+<pre>     cmp $0,foo   -&gt;  tst foo
+</pre>
+
+<p>the following optimization is possible:</p>
+<pre>     mov r0,foo : tst foo  -&gt;  mov r0,foo
+</pre>
+
+<p>The window is implemented as a <i>queue</i>. Matching
+takes place at the head of the queue. New instructions are
+added at the tail. If the window is moved forwards, the
+instruction at the head is not yet written to the output, as
+it may be needed later on. Instead it is added to a second
+queue, the <i>backup queue</i>. After a successful match,
+the entire backup queue is inserted at the front of the
+window queue, which effectively implements the shift
+backwards.</p>
+
+<p>Both queues have the length of the longest pattern in
+the table. If, as a result of a forward window move, the
+backup queue gets full, the instruction at its head is
+outputted and removed. Instructions are read from the input
+whenever the window queue contains fewer elements than the
+length of the longest pattern.</p>
+<a name="3.2. Pattern matching"></a>
+<h2>3.2. Pattern matching</h2>
+
+<p>Pattern matching is done in three steps:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p>find patterns in the table whose instruction mnemonics
+match the mnemonics of the instructions in the current
+window;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p>check if the operands of the pattern match the operands
+of the instructions in the current window;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>(iii)</p>
+</td>
+<td width="4%"></td>
+<td width="86%">
+
+<p>check if the optional constraint is satisfied.</p>
+</td>
+</table>
+
+<p>For step (i) hashing is used. The mnemonic of the first
+instruction of the window is used to determine a list of
+possible patterns. Patterns starting with ANY are always
+tried.</p>
+
+<p>Matching of operand descriptions against actual operands
+takes place as follows. The general form of an operand
+description is:</p>
+<pre>     string_constant1 variable_name string_constant2
+</pre>
+
+<p>The actual operand should begin with string_constant1
+and end on string_constant2. If so, these strings are
+stripped from it and the remaining string is matched against
+the variable. Matching a string against a variable is
+defined as follows:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>initially (before the entire pattern match) all
+variables are uninstantiated;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>matching a string against an uninstantiated variable
+succeeds if the restriction associated with the variable is
+satisfied. As a side effect, it causes the variable to be
+instantiated to the string;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3.</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>matching a string against an instantiated variable
+succeeds only if the variable was instantiated to the same
+string.</p>
+</td>
+</table>
+
+<p>Matching an actual mnemonic against the keyword ANY is
+defined likewise.</p>
+
+<p>The matching scheme implements the requirement that
+multiple occurrences of the same variable name or of the
+keyword ANY should stand for the same values throughout the
+entire pattern (see section 2.).</p>
+
+<p>Both the parameter restriction of 2. and the constraint
+of step (iii) are checked by executing the &quot;C&quot;
+expression.</p>
+<a name="3.3. Data structures"></a>
+<h2>3.3. Data structures</h2>
+
+<p>The most important data structure is the representation
+of the input instructions. For every instruction we use two
+representations:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="4%"></td>
+<td width="90%">
+
+<p>the textual representation, i.e. the exact code as it
+appeared in the input;</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="2%"></td>
+<td width="90%">
+
+<p>a structural representation, containing the opcode and
+the operands.</p>
+</td>
+</table>
+
+<p>The opcode of an instruction is determined as soon as it
+is read. If the line contains a label definition, the opcode
+is set to &quot;labdef&quot;, so a label definition is
+treated like a normal instruction.</p>
+
+<p>The operands of an instruction are not determined until
+they are needed, i.e. until step (i) of the pattern matching
+process has succeeded. For every instruction we keep track
+of a <i>state</i>. After the opcode has successfully been
+determined, the state is OPC_ONLY. Once the operands have
+been recognized, the state is set to DONE. If the opcode or
+operands can not be determined, or if the instruction cannot
+be optimized for any other reason (see Appendix A), the
+state is set to JUNK and any attempt to match it will
+fail.</p>
+
+<p>For each table entry we record the following
+information:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="8%"></td>
+<td width="86%">
+
+<p>the length of the pattern (i.e. the number of
+instruction descriptions)</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p>a description of the instructions of the pattern</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%">
+
+<p>(iii)</p>
+</td>
+<td width="4%"></td>
+<td width="58%">
+
+<p>the length of the replacement</p>
+</td>
+<td width="27%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(iv)</p>
+</td>
+<td width="6%"></td>
+<td width="86%">
+
+<p>a description of the instructions of the
+replacement.</p>
+</td>
+</table>
+
+<p>The description of an instruction consists of:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="4%"></td>
+<td width="20%">
+
+<p>the opcode</p>
+</td>
+<td width="69%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="2%"></td>
+<td width="90%">
+
+<p>for each operand, a description of the operand.</p>
+</td>
+</table>
+
+<p>The description of an operand of the form:</p>
+<pre>     string_constant1 variable_name string_constant2
+</pre>
+
+<p>contains:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="4%"></td>
+<td width="42%">
+
+<p>both string constants</p>
+</td>
+<td width="47%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="2%"></td>
+<td width="54%">
+
+<p>the number of the variable.</p>
+</td>
+<td width="35%">
+</td>
+</table>
+
+<p>Each declared variable is assigned a unique number. For
+every variable we maintain:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="6%">
+
+<p>(i)</p>
+</td>
+<td width="4%"></td>
+<td width="88%">
+
+<p>its state (instantiated or not instantiated)</p>
+</td>
+<td width="1%">
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="8%">
+
+<p>(ii)</p>
+</td>
+<td width="2%"></td>
+<td width="58%">
+
+<p>its current value (a string).</p>
+</td>
+<td width="31%">
+</td>
+</table>
+
+<p>The restrictions on variables and the constraints are
+stored in a switch-statement, indexed by variable number and
+entry number respectively.</p>
+<a name="4. Implementation of the target optimizer generator"></a>
+<h2>4. Implementation of the target optimizer generator</h2>
+
+<p>The target optimizer generator (<i>topgen</i>) reads a
+target machine description table and produces two files:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>gen.h:</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>contains macro definitions for machine parameters that
+were changed in the parameter section of the table (see
+appendix A) and for some attributes derived from the table
+(longest pattern, number of patterns, number of
+variables).</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="12%">
+
+<p>gen.c:</p>
+</td>
+<td width="6%"></td>
+<td width="82%">
+
+<p>contains the entry description tables, code for checking
+the parameter restrictions and constraints (switch
+statements) and the user-defined procedures.</p>
+</td>
+</table>
+
+<p>These two files are compiled together with some
+machine-independent files to produce a target optimizer.</p>
+
+<p>Topgen is implemented using the LL(1) parser generator
+system LLgen ,[Jaco85a] a powerful tool of the Amsterdam
+Compiler Kit. This system provides a flexible way of
+describing the syntax of the tables. The syntactical
+description of the table format included in Appendix A was
+derived from the LLgen syntax rules.</p>
+
+<p>The parser uses a simple, hand-written, lexical analyzer
+(scanner). The scanner returns a single character in most
+cases. The recognition of identifiers is left to the parser,
+as this eases the analysis of operand descriptions. Comments
+are removed from the input by the scanner, but white space
+is passed to the parser, as it is meaningful in some
+contexts (it separates the opcode description from the
+description of the first operand).</p>
+
+<p>Topgen maintains two symbol tables, one for variable
+names and one for tunable parameters. The symbol tables are
+organized as binary trees.</p>
+<a name="5. References"></a>
+<h2>5. References</h2>
+<a name="References"></a>
+<h2>References</h2>
+
+<p>Aho78a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.V. Aho and J.D. Ullman, <i>Principles of compiler
+design,</i> Addison-Wesley, Reading, Massachusetts
+(1978).</p>
+</td>
+</table>
+
+<p>Bal85a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>H.E. Bal, &ldquo;The Design and Implementation of the EM
+Global Optimizer,&rdquo; Rapport IR-99, Vrije Universiteit,
+Amsterdam (March 1985).</p>
+</td>
+</table>
+
+<p>Bal85b.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>H.E. Bal and A.S. Tanenbaum, &ldquo;Language- and
+Machine-independant Global Optimization on Intermediate
+Code,&rdquo; Rapport IR-98, Vrije Universiteit, Amsterdam
+(March 1985).</p>
+</td>
+</table>
+
+<p>Jaco85a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>C.J.H. Jacobs, &ldquo;Some Topics in Parser
+Generation,&rdquo; Rapport IR-105, Vrije Universiteit,
+Amsterdam (October 1985).</p>
+</td>
+</table>
+
+<p>Kern78a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>B.W. Kernighan and D.M. Ritchie, <i>The C Programming
+Language,</i> Prentice-Hall, Inc, Englewood Cliffs,NJ
+(1978).</p>
+</td>
+</table>
+
+<p>Tane84a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, E.G. Keizer, J.M. van Staveren, and J.W.
+Stevenson, &ldquo;Amsterdam Compiler Kit
+documentation,&rdquo; Rapport nr IR-90, Vrije Universiteit,
+Amsterdam (June 1984).</p>
+</td>
+</table>
+
+<p>Tane81a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, J.M. van Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;A Practical Toolkit for Making Portable
+Compilers,&rdquo; Rapport nr IR-74, Vrije Universiteit,
+Amsterdam (October 1981).</p>
+</td>
+</table>
+
+<p>Tane83a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, J.M. van Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;A Practical Toolkit for Making Portable
+Compilers,&rdquo; <i>CACM,</i> 26, 9, pp. 654-660 (September
+1983).</p>
+</td>
+</table>
+
+<p>Tane83b.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, J.M. van Staveren, E.G. Keizer, and J.W.
+Stevenson, &ldquo;A Unix Toolkit for Making Portable
+Compilers,&rdquo; <i>Proceedings USENIX conf.,</i> 26, pp.
+255-261, Toronto, Canada (July 1983).</p>
+</td>
+</table>
+
+<p>Tane82a.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>A.S. Tanenbaum, J.M. van Staveren, and J.W. Stevenson,
+&ldquo;Using Peephole Optimization on Intermediate
+Code,&rdquo; <i>TOPLAS,</i> 4, 1, pp. 21-36 (January
+1982).</p>
+</td>
+</table>
+<a name="Appendix A"></a>
+<h2>Appendix A</h2>
+
+<p>In this appendix we present a complete definition of the
+target optimizer description table format. This appendix is
+intended for table-writers. We use syntax rules for the
+description of the table format. The following notation is
+used:</p>
+
+<p align=center><img src="grohtml-102412.png"></p>
+
+<p>Terminals are given in quotes, as in
+&rsquo;;&rsquo;.</p>
+
+<p>The table may contain white space and comment at all
+reasonable places. Comments are as in &quot;C&quot;, so they
+begin with /* and end on */. Identifiers are sequences of
+letters, digits and the underscore (&rsquo;_&rsquo;),
+beginning with a letter.</p>
+<pre>     table   -&gt;   {parameter_line} &rsquo;%%;&rsquo; {variable_declaration} &rsquo;%%;&rsquo;
+                  {entry} &rsquo;%%;&rsquo; user_routines.
+</pre>
+
+<p>A table consists of four sections, containing
+machine-dependent constants, variable declarations, pattern
+rules and user-supplied subroutines.</p>
+<pre>     parameter_line -&gt;  identifier value &rsquo;;&rsquo; .
+</pre>
+
+<p>A parameter line defines some attributes of the target
+machines assembly code. For unspecified parameters default
+values apply. The names of the parameters and the
+corresponding defaults are shown in table 1.</p>
+
+<p align=center><img src="grohtml-102413.png"></p>
+
+<p align=center>table 1: parameter names and defaults</p>
+
+<p>The OPC_TERMINATOR is the character that separates the
+instruction mnemonic from the first operand (if any). The
+OP_SEPARATOR separates adjacent operands. A LABEL_STARTER is
+the first character of an instruction label. (Instruction
+labels are assumed to start with the same character). The
+LABEL_TERMINATOR is the last character of a label
+definition. It is assumed that this character is not used in
+an applied occurrence of the label identifier. For example,
+the defining occurrence may be &quot;I0017:&quot; and the
+applied occurrence may be &quot;I0017&quot; as in &quot;jmp
+I0017&quot;. MAXOP defines the maximum number of operands an
+instruction can have. MAXOPLEN is the maximum length (in
+characters) of an operand. MAX_OPC_LEN is the maximum length
+of an instruction opcode. MAXVARLEN is the maximum length of
+a declared string variable. As variables may be set by user
+routines (see &quot;bitw&quot; example for the Vax) the
+table-writer must have access to this length and must be
+able to change it. MAXLINELEN denotes the maximum length of
+a line of assembly code. PAREN_OPEN and PAREN_CLOSE must be
+used when the operand separator can also occur within
+operands, between parentheses of some kind. In this case,
+PAREN_OPEN must be set to a string containing the opening
+parentheses, and PAREN_CLOSE must be set to a string
+containing the closing parentheses.</p>
+
+<p>If a line of assembly code violates any of the
+assumptions or exceeds some limit, the line is not
+optimized. Optimization does, however, proceed with the rest
+of the input.</p>
+<pre>     variable_declaration  -&gt; identifier {&rsquo;,&rsquo; identifier} restriction &rsquo;;&rsquo; .
+
+
+     restriction           -&gt;  &rsquo;{&rsquo; anything &rsquo;}&rsquo; .
+</pre>
+
+<p>A variable declaration declares one or more string
+variables that may be used in the patterns and in the
+replacements. If a variable is used as part of an operand
+description in a pattern, the entire pattern can only match
+if the restriction evaluates to TRUE. If the pattern does
+match, the variable is assigned the matching part of the
+actual operand. Variables that are not used in a pattern are
+initialized to null-strings and may be assigned a value in
+the constraint-part of the pattern.</p>
+
+<p>The restriction must be a legal &quot;C&quot;
+expression. It may not contain a closing bracket
+(&rsquo;}&rsquo;). Inside the expression, the name VAL
+stands for the part of the actual (matching) operand. The
+expression may contain calls to procedures that are defined
+in the user-routines section.</p>
+<pre>     entry             -&gt;  pattern &rsquo;-&gt;&rsquo; replacement &rsquo;;&rsquo; .
+
+
+     pattern           -&gt;  instruction_descr
+                     { &rsquo;:&rsquo; instruction_descr }
+                     constraint .
+
+
+     replacement       -&gt;  [ instruction_descr { &rsquo;:&rsquo; instruction_descr } ] .
+
+
+     instruction_descr -&gt; opcode
+                    white
+                    [ operand_descr { &rsquo;,&rsquo; operand_descr } ] .
+
+
+     constraint        -&gt; &rsquo;{&rsquo; anything &rsquo;}&rsquo; .
+
+
+     operand_descr     -&gt; [ string_constant ]
+                    [ variable_name ]
+                    [ string_constant ] .
+
+
+     variable_name     -&gt; identifier .
+
+
+     opcode            -&gt; anything .
+</pre>
+
+<p>The symbol &rsquo;white&rsquo; stands for white space
+(space or tab). An opcode can be any string not containing
+the special symbols &rsquo;;&rsquo;, &rsquo;{&rsquo;,
+&rsquo;}&rsquo;, &rsquo;:&rsquo;, &rsquo;,&rsquo;,
+&rsquo;-&gt;&rsquo; or white space. To be recognized, it
+must begin with a letter. The opcode should either be a
+mnemonic of a target machine instruction or it should be one
+of the keywords ANY and labdef. ANY matches any actual
+opcode. labdef matches only label definitions.</p>
+
+<p>If an operand description contains an identifier (as
+defined earlier), it is checked if the identifier is the
+name of a declared variable. This effects the semantics of
+the matching rules for the operand, as described in section
+2. An operand may contain at most one such variable
+name.</p>
+
+<p>The constraint must be a legal &quot;C&quot; expression,
+just as the operand restriction. It may call user-defined
+procedures and use or change the value of declared
+variables. It may also use the string variable REST, which
+contains the mnemonic of the first instruction of the rest
+of the input. (REST is a null-string if this mnemonic can
+not be determined).</p>
+<pre>     user_routines -&gt; anything .
+</pre>
+
+<p>The remainder of the table consists of user-defined
+subroutines.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/top.pdf b/src/olddocs/top.pdf
new file mode 100644 (file)
index 0000000..27b6537
Binary files /dev/null and b/src/olddocs/top.pdf differ
diff --git a/src/olddocs/v7bugs.html b/src/olddocs/v7bugs.html
new file mode 100644 (file)
index 0000000..59ff704
--- /dev/null
@@ -0,0 +1,2025 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:05 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title></title>
+</head>
+<body>
+
+<hr>
+
+<p align=center>UNIX version 7 bugs</p>
+
+<p>This document describes the UNIX version 7 errors fixed
+at the Vrije Universiteit, Amsterdam. Several of these are
+discovered at the VU. Others are quoted from a list of bugs
+distributed by BellLabs.</p>
+
+<p>For each error the differences between the original and
+modified source files are given, as well as a test
+program.</p>
+
+<p>ERROR 1: C optimizer bug for unsigned comparison</p>
+
+<p>The following C program caused an IOT trap, while it
+should not (compile with &rsquo;cc -O prog.c&rsquo;):</p>
+<!-- TABS -->
+
+<p>unsigned</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>i = 0;</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>main() {</p></td>
+</table>
+<!-- TABS -->
+
+<p>register j;</p>
+
+<p>j = -1;<br>
+if (i &gt; 40000)</p>
+<td width="-148%"></td>
+<td width="249%">
+
+<p>abort();</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>}</p>
+<!-- INDENTATION -->
+<p>BellLabs suggests to make the following patch in
+c21.c:</p>
+<!-- INDENTATION -->
+<pre>     /* modified /usr/src/cmd/c/c21.c */
+
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<p>189</p>
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if (r==0) {<br>
+190</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* next 2 lines replaced as indicated by<br>
+191</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* Bell Labs bug distribution ( v7optbug )<br>
+192</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;back-&gt;back-&gt;forw = p-&gt;forw;<br>
+193</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;forw-&gt;back = p-&gt;back-&gt;back;<br>
+194</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>End of lines changed */<br>
+195</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if (p-&gt;forw-&gt;op==CBR<br>
+196</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>|| p-&gt;forw-&gt;op==SXT<br>
+197</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>|| p-&gt;forw-&gt;op==CFCC) {<br>
+198</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;back-&gt;forw = p-&gt;forw;<br>
+199</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;forw-&gt;back = p-&gt;back;<br>
+200</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>} else {<br>
+201</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;back-&gt;back-&gt;forw = p-&gt;forw;<br>
+202</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;forw-&gt;back = p-&gt;back-&gt;back;<br>
+203</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>}<br>
+204</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* End of new lines */<br>
+205</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>decref(p-&gt;ref);<br>
+206</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p = p-&gt;back-&gt;back;<br>
+207</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>nchange++;<br>
+208</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>} else if (r&gt;0) {</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>Use the previous program to test before and after the
+modification.</p></td>
+</table>
+
+<p>ERROR 2: The loader fails for large data or text
+portions</p>
+
+<p>The loader &rsquo;ld&rsquo; produces a &quot;local
+symbol botch&quot; error for the following C program.</p>
+<!-- TABS -->
+
+<p>int</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>big1[10000] = {</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>1</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>};</p></td>
+</table>
+<!-- TABS -->
+
+<p>int</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>big2[10000] = {</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>2</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>};</p>
+<!-- INDENTATION -->
+<p>main() {</p></td>
+</table>
+<!-- TABS -->
+
+<p>printf(&quot;loader is fine\n&quot;);</p>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>}</p>
+<!-- INDENTATION -->
+<p>We have made the following fix:</p>
+<!-- INDENTATION -->
+<pre>     /* original /usr/src/cmd/ld.c */
+
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<p>113</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>struct {<br>
+114</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>fmagic;<br>
+115</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>tsize;<br>
+116</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>dsize;<br>
+117</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>bsize;<br>
+118</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>ssize;<br>
+119</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>entry;<br>
+120</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>pad;<br>
+121</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>relflg;<br>
+122</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>} filhdr;</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>/* modified /usr/src/cmd/ld.c */</p>
+</td>
+</table>
+<!-- TABS -->
+
+<p>113</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/*<br>
+114</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* The original Version 7 loader had problems loading
+large<br>
+115</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* text or data portions.<br>
+116</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* Why not include &lt;a.out.h&gt; ???<br>
+117</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* then they would be declared unsigned<br>
+118</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>*/<br>
+119</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>struct {<br>
+120</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>int</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>fmagic;<br>
+121</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>tsize;</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* not int !!! */<br>
+122</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>dsize;</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* not int !!! */<br>
+123</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>bsize;</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* not int !!! */<br>
+124</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>ssize;</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* not int !!! */<br>
+125</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>entry;</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* not int !!! */<br>
+126</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>pad;</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* not int !!! */<br>
+127</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>relflg;</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* not int !!! */<br>
+128</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>} filhdr;</p>
+</td>
+</table>
+
+<p>ERROR 3: Floating point registers</p>
+
+<p>When a program is swapped to disk if it needs more
+memory, then the floating point registers were not saved, so
+that it may have different registers when it is restarted. A
+small assembly program demonstrates this for the status
+register. If the error is not fixed, then the program
+generates an IOT error. A &quot;memory fault&quot; is
+generated if all is fine.</p>
+<!-- TABS -->
+
+<p>start:</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>ldfps</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>$7400<br>
+1:</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>stfps</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r0</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>mov</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r0,-(sp)</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>cmp</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r0,$7400</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>beq</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>1b</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>4</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>Some digging into the kernel is required to fix it. The
+following patch will do:</p>
+<!-- INDENTATION -->
+<pre>     /* original /usr/sys/sys/slp.c */
+
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<p>563</p>
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>a2 = malloc(coremap, newsize);<br>
+564</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if(a2 == NULL) {<br>
+565</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>xswap(p, 1, n);<br>
+566</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;p_flag |= SSWAP;<br>
+567</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>qswtch();<br>
+568</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* no return */<br>
+569</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>}</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>/* modified /usr/sys/sys/slp.c */</p>
+</td>
+</table>
+<!-- TABS -->
+
+<p>590</p>
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>a2 = malloc(coremap, newsize);<br>
+591</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if(a2 == NULL) {<br>
+592</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>#ifdef FPBUG<br>
+593</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/*<br>
+594</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* copy floating point register and status,<br>
+595</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* but only if you must switch processes<br>
+596</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>*/<br>
+597</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if(u.u_fpsaved == 0) {<br>
+598</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>savfp(&amp;u.u_fps);<br>
+599</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>u.u_fpsaved = 1;<br>
+600</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>}<br>
+601</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>#endif<br>
+602</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>xswap(p, 1, n);<br>
+603</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>p-&gt;p_flag |= SSWAP;<br>
+604</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>qswtch();<br>
+605</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* no return */<br>
+606</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>}</p>
+</td>
+</table>
+
+<p>ERROR 4: Floating point registers.</p>
+
+<p>A similar problem arises when a process forks. The child
+will have random floating point registers as is demonstrated
+by the following assembly language program. The child
+process will die by an IOT trap and the father prints the
+message &quot;child failed&quot;.</p>
+<!-- TABS -->
+
+<p>exit</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>= 1.<br>
+fork</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>= 2.<br>
+write</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>= 4.<br>
+wait</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>= 7.</p>
+
+<p>start:</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>ldfps</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>$7400</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>sys</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>fork</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>br</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>child</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>sys</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>wait</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>tst</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r1</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>bne</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>bad</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>stfps</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r2</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>cmp</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r2,$7400</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>beq</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>start</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>4<br>
+child:</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>stfps</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r2</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>cmp</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r2,$7400</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>beq</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>ex</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>4<br>
+bad:</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>clr</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r0</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>sys</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>write;mess;13.<br>
+ex:</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>clr</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>r0</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>sys</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>exit</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>.data<br>
+mess:</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>&lt;child failed\n&gt;</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>The same file slp.c should be patched as follows:</p>
+<!-- INDENTATION -->
+<pre>     /* original /usr/sys/sys/slp.c */
+
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<p>499</p>
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/*<br>
+500</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* When the resume is executed for the new process,<br>
+501</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* here&rsquo;s where it will resume.<br>
+502</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>*/<br>
+503</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if (save(u.u_ssav)) {<br>
+504</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>sureg();<br>
+505</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>return(1);<br>
+506</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>}<br>
+507</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>a2 = malloc(coremap, n);<br>
+508</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/*<br>
+509</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* If there is not enough core for the<br>
+510</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* new process, swap out the current process to generate
+the<br>
+511</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* copy.<br>
+512</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>*/</p>
+</td>
+</table>
+
+<p>/* modified /usr/sys/sys/slp.c */</p>
+<!-- TABS -->
+
+<p>519</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/*<br>
+520</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* When the resume is executed for the new process,<br>
+521</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* here&rsquo;s where it will resume.<br>
+522</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>*/<br>
+523</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if (save(u.u_ssav)) {<br>
+524</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>sureg();<br>
+525</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>return(1);<br>
+526</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>}<br>
+527 #ifdef FPBUG<br>
+528</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/* copy the floating point registers and status to child
+*/<br>
+529</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>if(u.u_fpsaved == 0) {<br>
+530</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>savfp(&amp;u.u_fps);<br>
+531</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>u.u_fpsaved = 1;<br>
+532</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>}<br>
+533 #endif<br>
+534</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>a2 = malloc(coremap, n);<br>
+535</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>/*<br>
+536</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* If there is not enough core for the<br>
+537</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* new process, swap out the current process to generate
+the<br>
+538</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>* copy.<br>
+539</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>*/</p>
+</td>
+</table>
+
+<p>ERROR 5: /usr/src/libc/v6/stat.c</p>
+
+<p>Some system calls are changed from version 6 to version
+7. A library of system call entries, that make a version 6
+UNIX look like a version 7 system, is provided to run some
+useful version 7 utilities, like &rsquo;tar&rsquo;, on
+UNIX-6. The entry for &rsquo;stat&rsquo; contained two bugs:
+the 24-bit file size was incorrectly converted to 32 bits
+(sign extension of bit 15) and the uid/gid fields suffered
+from sign extension.</p>
+
+<p>Transferring files from version 6 to version 7 using
+&rsquo;tar&rsquo; will fail for all files for which</p>
+<!-- TABS -->
+<td width="-49%"></td>
+<td width="149%">
+
+<p>( (size &amp; 0100000) != 0 )</p>
+</td>
+</table>
+
+<p>These two errors are fixed if stat.c is modified as
+follows:</p>
+<!-- INDENTATION -->
+<td width="-49%"></td>
+<td width="149%">
+<p>/* original /usr/src/libc/v6/stat.c */</p>
+</td>
+</table>
+<!-- TABS -->
+
+<p>11</p>
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>char os_size0;<br>
+12</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>short os_size1;<br>
+13</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>short os_addr[8];</p>
+
+<p>49</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_nlink = osbuf.os_nlinks;<br>
+50</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_uid = osbuf.os_uid;<br>
+51</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_gid = osbuf.os_gid;<br>
+52</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_rdev = 0;</p>
+</td>
+</table>
+
+<p>/* modified /usr/src/libc/v6/stat.c */</p>
+<!-- TABS -->
+
+<p>11</p>
+<td width="-99%"></td>
+<td width="199%">
+
+<p>char os_size0;<br>
+12</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>unsigned os_size1;<br>
+13</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>short os_addr[8];</p>
+
+<p>49</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_nlink = osbuf.os_nlinks;<br>
+50</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_uid = osbuf.os_uid &amp; 0377;<br>
+51</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_gid = osbuf.os_gid &amp; 0377;<br>
+52</p>
+</td>
+<tr valign="top" align="left">
+<td width="-99%"></td>
+<td width="199%">
+
+<p>buf-&gt;st_rdev = 0;</p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/v7bugs.pdf b/src/olddocs/v7bugs.pdf
new file mode 100644 (file)
index 0000000..3ff6f73
Binary files /dev/null and b/src/olddocs/v7bugs.pdf differ
diff --git a/src/olddocs/val.html b/src/olddocs/val.html
new file mode 100644 (file)
index 0000000..f7f666b
--- /dev/null
@@ -0,0 +1,2352 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:13 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title></title>
+</head>
+<body>
+
+<hr>
+
+<p align=center><b>Pascal Validation Suite Report</b></p>
+
+<p><b>Pascal processor identification</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The ACK-Pascal compiler produces code for an EM machine
+as defined in [1]. It is up to the implementor of the EM
+machine whether errors like integer overflow, undefined
+operand and range bound error are recognized or not.
+Therefore it depends on the EM machine implementation
+whether these errors are recognized in Pascal programs or
+not. The validation suite results of all known
+implementations are given.</p>
+<!-- INDENTATION -->
+<p>There does not (yet) exist a hardware EM machine.
+Therefore, EM programs must be interpreted, or translated
+into instructions for a target machine. The following
+implementations currently exist:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Implementation 1: an interpreter running on a PDP-11
+(using UNIX). The normal mode of operation for this
+interpreter is to check for undefined integers, overflow,
+range errors etc.</p>
+<!-- INDENTATION -->
+<p>Implementation 2: a translator into PDP-11 instructions
+(using UNIX). Less checks are performed than in the
+interpreter, because the translator is intended to speed up
+the execution of well-debugged programs.</p></td>
+</table>
+
+<p><b>Test Conditions</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Tester: E.G. Keizer<br>
+Date: October 1983<br>
+Validation Suite version: 3.0</p>
+<!-- INDENTATION -->
+<p>The final test run is made with a slightly modified
+validation suite.</p>
+<!-- INDENTATION -->
+<p><b>Erroneous programs</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Some test did not conform to the standard proposal of
+February 1979. It is this version of the standard proposal
+that is used by the authors of the validation suite.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.3.7-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The semicolon between high and integer on line 17 is
+replaced by a colon.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.2-13:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The div operator on line 14 replaced by mod.</p></td>
+</table>
+
+<p><b>Conformance tests</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of tests passed = 150<br>
+Number of tests failed = 6</p>
+<!-- INDENTATION -->
+<p><b>Details of failed tests</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.2-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Character sequences starting with the 8 characters
+&rsquo;procedur&rsquo; or &rsquo;function&rsquo; are
+erroneously classified as the word-symbols
+&rsquo;procedure&rsquo; and &rsquo;function&rsquo;.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.3-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Identifiers identical in the first eight characters, but
+differing in ninth or higher numbered characters are treated
+as identical.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.1-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>ACK-Pascal requires all formal program parameters to be
+declared with type <i>file</i>.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.5-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Gives run-time error eof seen at call to eoln. A have a
+hunch that this is a error in the suit.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.4.1-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Redefining the names of some standard procedures leads to
+incorrect behaviour of the runtime system. In this case it
+crashes without a sensible error message.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.5.1-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>This test can not be translated by our compiler because
+two non-identical variables are used in the same block with
+the same first eight characters. The test passed after
+replacement of one of those names.</p></td>
+</table>
+
+<p><b>Deviance tests</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of deviations correctly detected = 120<br>
+Number of tests not detecting deviations = 20</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p><b>Details of deviations</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>The following tests are compiled without a proper error
+indication although they do not conform to the standard.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.6-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>ACK-Pascal allows labels in the range 0..32767. A warning
+is produced when testing for deviations from the
+standard.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.8-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>A missing space between a number and a word symbol is not
+detected.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.2.2-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.3-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.1-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.1-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.1-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Undetected scope error. The scope of an identifier should
+start at the beginning of the block in which it is declared.
+In the ACK-Pascal compiler the scope starts just after the
+declaration, however.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-7:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The values of fields from one variant are accessible from
+another variant. The correlation is exact.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.3.3-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The passing as a variable parameter of the selector of a
+variant part is not detected. A runtime error is produced
+because the variant selector is not initialized.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.4-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.4-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.4-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.4-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.4-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The ACK-Pascal compiler does not restrict the places from
+where a jump to a label by means of a goto-statement is
+allowed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-7:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-16:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>There are no errors produced for assignments to a
+variable in use as control-variable of a
+for-statement.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-9:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Use of a controlled variable after leaving the loop
+without intervening initialization is not detected.</p></td>
+</table>
+
+<p><b>Error handling</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The results depend on the EM implementation.</p>
+<!-- INDENTATION -->
+<p>Number of errors correctly detected =</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Implementation 1: 32<br>
+Implementation 2: 17</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of errors not detected =</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Implementation 1: 21<br>
+Implementation 2: 36</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of errors incorrectly detected =</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Implementation 1: 2<br>
+Implementation 2: 2</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p><b>Details of errors not detected</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>The following test fails because the ACK-Pascal compiler
+only generates a warning that does not prevent to run the
+tests.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.2-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>A warning is produced if there is no assignment to a
+function-identifier.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>With this test the ACK-Pascal compiler issues an error
+message for a legal construct not directly related to the
+error to be detected.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.5-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Program does not compile. Buffer variable of text file is
+not allowed as variable parameter.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>The following errors are not detected at all.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.2.1-11:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Implementation 2: The use of an undefined integer is not
+caught as an error.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-10:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-11:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-12:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-13:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The notion of &rsquo;current variant&rsquo; is not
+implemented, not even if a tagfield is present.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.5-15:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.6-9:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.6-10:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.6-11:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.3.2-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Implementation 2: Subrange bounds are not checked.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.6-12:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.6-13:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.4-4:</p></td>
+</table>
+
+<p>If the base-type of a set is a subrange, then the set
+elements are not checked against the bounds of the subrange.
+Only the host-type of this subrange-type is relevant for
+ACK-Pascal.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.4-1:</p></td>
+</table>
+
+<p>Implementation 2: Nil pointers are not detected.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.4-2:</p></td>
+</table>
+
+<p>Implementation 2: Undefined pointers are not
+detected.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.5-3:</p></td>
+</table>
+
+<p>Changing the file position while the window is in use as
+actual variable parameter or as an element of the record
+variable list of a with-statement is not detected.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.2-9:</p></td>
+</table>
+
+<p>An undefined function result is not detected, because it
+is never used in an expression.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.5.3-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.5.3-7:</p></td>
+</table>
+
+<p>Disposing a variable while it is in use as actual
+variable parameter or as an element of the record variable
+list of a with-statement is not detected.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.5.3-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.5.3-9:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.5.3-10:</p></td>
+</table>
+
+<p>It is not detected that a record variable, created with
+the variant form of new, is used as an operand in an
+expression or as the variable in an assignment or as an
+actual value parameter.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.5.3-11:</p></td>
+</table>
+
+<p>Use of a variable that is not reinitialized after a
+dispose is not detected.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.4-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.4-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.4-7:</p></td>
+</table>
+
+<p>Implementation 2: There are no range checks for pred,
+succ and chr.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.5-6:</p></td>
+</table>
+
+<p>ACK-Pascal considers a rewrite of a file as a defining
+occurence.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.2-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.2-9:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.2-10:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.2-12:</p></td>
+</table>
+
+<p>Implementation 2: Division by 0 or integer overflow
+is</p>
+
+<p>not detected.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-18:</p></td>
+</table>
+
+<p>The use of the some control variable in two nested for
+statements in not detected.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-19:</p></td>
+</table>
+
+<p>Access of a control variable after leaving the loop
+results in the final-value, although an error should be
+produced.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.2-3:</p></td>
+</table>
+
+<p>The program stops with a file not open error. The
+rewrite before the write is missing in the program.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.2-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.2-5:</p></td>
+</table>
+
+<p>Illegal FracDigits values are not detected.</p>
+
+<p><b>Implementation dependence</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of tests run = 14<br>
+Number of tests incorrectly handled = 0</p>
+<!-- INDENTATION -->
+<p><b>Details of implementation dependence</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.9-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Alternate comment delimiters are implemented</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.9-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The equivalent symbols @ for ^, (. for [ and .) for ] are
+not implemented.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.2.2-10:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Maxint = 32767</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.4-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Only elements with non-negative ordinal value are allowed
+in sets.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.1-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Standard procedures and functions are not allowed as
+parameters.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.2-11:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Details of the machine characteristics regarding real
+numbers:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<pre>beta =       2
+t =         56
+rnd =        1
+ngrd =       0
+
+
+<p>machep = -56<br>
+negep = -56<br>
+iexp = 8<br>
+minexp = -128<br>
+maxexp = 127<br>
+eps = 1.387779e-17<br>
+epsneg = 1.387779e-17<br>
+xmin = 2.938736e-39<br>
+xmax = 1.701412e+38</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.3-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.3-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>All operands of boolean expressions are evaluated.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.2-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.2-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The expression in an assignment statement is evaluated
+before the variable selection if this involves pointer
+dereferencing or array indexing.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.2.3-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Actual parameters are evaluated in reverse order.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.2-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The default width for integer, Boolean and real are 6, 5
+and 13.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.5.1-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The number of digits written in an exponent is 2.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.6-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The representations of true and false are ( true) and
+(false). The parenthesis serve to indicate width.</p></td>
+</table>
+
+<p><b>Quality measurement</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of tests run = 60<br>
+Number of tests handled incorrectly = 1</p>
+<!-- INDENTATION -->
+<p><b>Results of tests</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Several test perform operations on reals on indicate the
+error introduced by these operations. For each of these
+tests the following two quality measures are extracted:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>maxRE: maximum relative error<br>
+rmsRE: root-mean-square relative error</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 1.2-1:</p></td>
+</table>
+
+<p>Implementation 1: 25 thousand Whetstone instructions per
+second.<br>
+Implementation 2: 169 thousand Whetstone instructions per
+second.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 1.2-2:</p></td>
+</table>
+
+<p>The value of (TRUEACC-ACC)*2^56/100000 is 1.4 . This is
+well within the bounds specified in [3].<br>
+The GAMM measure is:<br>
+Implementation 1: 238 microseconds<br>
+Implementation 2: 26.3 microseconds.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 1.2-3:</p></td>
+</table>
+
+<p>The number of procedure calls calculated in this test
+exceeds the maximum integer value. The program stops
+indicating overflow.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.3-3:</p></td>
+</table>
+
+<p>The number of significant characters for identifiers is
+8.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.5-8:</p></td>
+</table>
+
+<p>There is no maximum to the line length.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.5-9:</p></td>
+</table>
+
+<p>The error message &quot;too many digits&quot; is given
+for numbers larger than maxint.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.5-10:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.5-11:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.5-12:</p></td>
+</table>
+
+<p>Normal values are allowed for real constants and
+variables.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.7-14:</p></td>
+</table>
+
+<p>A reasonably large number of strings is allowed.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.8-6:</p></td>
+</table>
+
+<p>No warning is given for possibly unclosed comments.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.2.1-12:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.2.1-13:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.2.1-14:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.2.1-15:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.1-2:</p></td>
+</table>
+
+<p>Large lists of declarations are possible in each
+block.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.2-6:</p></td>
+</table>
+
+<p>An &rsquo;array[integer] of&rsquo; is not allowed.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.2-7:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.2-8:</p></td>
+</table>
+
+<p>Large values are allowed for arrays and indices.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-14:</p></td>
+</table>
+
+<p>Large amounts of case-constant values are allowed in
+variants.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-15:</p></td>
+</table>
+
+<p>Large amounts of record sections can appear in the fixed
+part of a record.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.3-16:</p></td>
+</table>
+
+<p>Large amounts of variants are allowed in a record.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.4.3.4-4:</p></td>
+</table>
+
+<p>Size and speed of Warshall&rsquo;s algorithm depend on
+the implementation of EM:</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>Implementation 1:<br>
+size: 122 bytes<br>
+speed: 5.2 seconds</p>
+<!-- INDENTATION -->
+<p>Implementation 2:<br>
+size: 196 bytes<br>
+speed: 0.7 seconds</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.3.2-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Deep nesting of array indices is allowed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.3.2-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.5.3.2-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Arrays can have at least 8 dimensions.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.1-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Deep static nesting of procedure is allowed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.3.1-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Large amounts of formal parameters are allowed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.5.3-12:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Dispose is fully implemented.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.2-6:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Test sqrt(x): no errors. The error is within acceptable
+bounds.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -55.50<br>
+rmsRE: 2 ** -57.53</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.2-7:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Test arctan(x): may cause underflow or overflow errors.
+The error is within acceptable bounds.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -55.00<br>
+rmsRE: 2 ** -56.36</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.2-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Test exp(x): may cause underflow or overflow errors. The
+error is not within acceptable bounds.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -50.03<br>
+rmsRE: 2 ** -51.03</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.2-9:</p></td>
+</table>
+
+<p>Test sin(x): may cause underflow errors. The error is
+not within acceptable bounds.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -38.20<br>
+rmsRE: 2 ** -43.68</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Test cos(x): may cause underflow errors. The error is not
+within acceptable bounds.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -41.33<br>
+rmsRE: 2 ** -46.62</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.6.2-10:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Test ln(x): The error is not within acceptable
+bounds.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -54.05<br>
+rmsRE: 2 ** -55.77</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.1-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.1-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.1-5:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Complex nested expressions are allowed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.2-14:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Test real division: The error is within acceptable
+bounds.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 0<br>
+rmsRE: 0</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.2.2-15:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Operations of reals in the integer range are exact.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.7.3-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.2-1:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.4-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.5-15:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.7-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.8-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.9-20:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.10-7:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Static deep nesting of function calls, compound
+statements, if statements, case statements, repeat loops,
+while loops, for loops and with statements is possible.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.2-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Large amounts of statements are allowed in a compound
+statement.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.5-12:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The compiler requires case constants to be compatible
+with the case selector.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.5-13:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.5-14:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Large case statements are possible.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9-2:</p></td>
+</table>
+
+<p>Recursive IO on the same file is well-behaved.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.1-6:</p></td>
+</table>
+
+<p>The reading of real values from a text file is done with
+sufficient accuracy.</p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -54.61<br>
+rmsRE: 2 ** -56.32</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.1-7:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.2-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3-3:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.4-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Read, readln, write and writeln may have large amounts of
+parameters.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.1-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The loss of precision for reals written on a text file
+and read back is:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 2 ** -53.95<br>
+rmsRE: 2 ** -55.90</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>File IO buffers without trailing marker are correctly
+flushed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.9.3.5.2-2:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Reals are written with sufficient accuracy.</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="32%"></td>
+<td width="67%">
+<p>maxRE: 0<br>
+rmsRE: 0</p></td>
+</table>
+
+<p><b>Level 1 conformance tests</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of test passed = 4<br>
+Number of tests failed = 1</p>
+<!-- INDENTATION -->
+<p><b>Details of failed tests</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.3.7-4:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>An expression indicated by parenthesis whose value is a
+conformant array is not allowed.</p></td>
+</table>
+
+<p><b>Level 1 deviance tests</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of deviations correctly detected = 4<br>
+Number of tests not detecting deviations = 0</p></td>
+</table>
+
+<p><b>Level 1 error handling</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>The results depend on the EM implementation.</p>
+<!-- INDENTATION -->
+<p>Number of errors correctly detected =</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Implementation 1: 1<br>
+Implementation 2: 0</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of errors not detected =</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Implementation 1: 0<br>
+Implementation 2: 1</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p><b>Details of errors not detected</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.3.7-9:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Implementation 2: Subrange bounds are not
+checked.</p></td>
+</table>
+
+<p><b>Level 1 quality measurement</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of tests run = 1</p>
+<!-- INDENTATION -->
+<p><b>Results of test</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.6.3.7-10:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>Large conformant arrays are allowed.</p></td>
+</table>
+
+<p><b>Extensions</b></p>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="7%"></td>
+<td width="91%">
+<p>Number of tests run = 3</p>
+<!-- INDENTATION -->
+<p><b>Details</b></p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.9-7:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The alternative relational operators are not allowed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.1.9-8:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The alternative symbols for colon, semicolon and
+assignment are not allowed.</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="16%"></td>
+<td width="83%">
+<p>Test 6.8.3.5-16:</p></td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="24%"></td>
+<td width="75%">
+<p>The otherwise selector in case statements is not
+allowed.</p></td>
+</table>
+
+<p><b>References</b></p>
+
+<p>[1] A.S.Tanenbaum, E.G.Keizer, J.W.Stevenson, Hans van
+Staveren, &quot;Description of a machine architecture for
+use with block structured languages&quot;, Informatica
+rapport IR-81. [2] ISO standard proposal ISO/TC97/SC5-N462,
+dated February 1979. The same proposal, in slightly modified
+form, can be found in: A.M.Addyman e.a., &quot;A draft
+description of Pascal&quot;, Software, practice and
+experience, May 1979. An improved version, received March
+1980, is followed as much as possible for the current
+ACK-Pascal. [3] B. A. Wichman and J du Croz, A program to
+calculate the GAMM measure, Computer Journal, November
+1979.</p>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/val.pdf b/src/olddocs/val.pdf
new file mode 100644 (file)
index 0000000..66a69dd
Binary files /dev/null and b/src/olddocs/val.pdf differ
diff --git a/src/olddocs/z80.html b/src/olddocs/z80.html
new file mode 100644 (file)
index 0000000..e0174cc
--- /dev/null
@@ -0,0 +1,298 @@
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Fri Feb 11 22:17:17 2005 -->
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>THE Z80 BACK END TABLE</title>
+</head>
+<body>
+
+<h1 align=center>THE Z80 BACK END TABLE</h1>
+<a href="#1. INTRODUCTION">1. INTRODUCTION</a><br>
+<a href="#2. IMPLEMENTATION">2. IMPLEMENTATION</a><br>
+
+<hr>
+<a name="1. INTRODUCTION"></a>
+<h2>1. INTRODUCTION</h2>
+
+<p>This table was written to make it run, not to make it
+clever! The effect is, that the table written for the intel
+8080, which was made very clever runs faster and requiers
+less space!! So, for anyone to run programs on a z80
+machine: n attempt could be made to make this table as
+clever as the one for the i80, or the i80 table could be
+used, for that can run on every z80 too.</p>
+<a name="2. IMPLEMENTATION"></a>
+<h2>2. IMPLEMENTATION</h2>
+
+<p>It will not be possible to run the entire Amsterdam
+Compiler Kit on a Z80-based computer system. One has to
+write a program on another system, a system where the
+compiler kit runs on. This program may be a mixture of
+high-level languages, such as C or Pascal, EM and z80
+assembly code. The program should be compiled using the
+compiler kit, producing z80 machine code. This code should
+come available to the z80 machine for example by downloading
+or by storing it in ROM (Read Only Memory). Depending on the
+characteristics of the particular z80 based system, some
+adaptions have to be made:</p>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>1)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>In <i>head_em</i>: the base address, which is the
+address where the first z80 instruction will be stored, and
+the initial value of the stackpointer are set to 0x1000 and
+0x7ffe respectivally. The latter because it could run on a
+32K machine as well. Other systems require other values.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>2)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>In <i>head_em</i>: before calling &quot;__m_a_i_n&quot;,
+the environment pointer, argument vector and argument count
+will have to be pushed onto the stack. Since this back-end
+is tested on a system without any knowledge of these things,
+dummies are pushed now.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>3)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>In <i>tail_em</i>: proper routines &quot;putchar&quot;
+and &quot;getchar&quot; should be provided. They should
+write resp. read a character on/from the monitor. Maybe some
+conversions will have to be made. The ones for the Nascom
+and Hermac z80 micro&rsquo;s are to be found in the
+EM-library.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>4)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>In <i>head_em</i>: an application program returns
+control to the monitor by jumping to address 0x20. Thie may
+have to be changed on different systems. For an CPM-machine
+for example this should be 0x5, to provide a warm boot.</p>
+</td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="3" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="4%">
+
+<p>5)</p>
+</td>
+<td width="6%"></td>
+<td width="90%">
+
+<p>In <i>tail_em</i>: the current version of the z80
+back-end has very limited I/O capabilities, because it was
+tested on a system that had no knowlegde of files. So the
+implementation of the EM-instruction <i>mon</i> is very
+simple; it can only do the following things:</p>
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<pre>        Monitor call 1:
+</pre>
+</td>
+</table>
+<!-- TABS -->
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>Exit</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Monitor call 3:</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>read, always reads from the monitor.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>echos the read character.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>ignores file descriptor.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Monitor call 4:</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>write, always writes on the monitor.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>ignores file descriptor.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Monitor call 5:</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>open file, returns file descriptor -1.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Monitor call 6:</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>close file, returns error code = 0.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>Monitor call 54:</p></td>
+</table>
+<!-- TABS -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="4" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="29%"></td>
+<td width="10%">
+
+<p>io-control, returns error code = 0.</p>
+</td>
+<td width="10%"></td>
+<td width="49%">
+</td>
+</table>
+<!-- INDENTATION -->
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="9%"></td>
+<td width="90%">
+<p>If the system should do file-handling the routine
+&quot;.mon&quot; should be extended thoroughly.</p>
+</td>
+</table>
+<hr>
+</body>
+</html>
diff --git a/src/olddocs/z80.pdf b/src/olddocs/z80.pdf
new file mode 100644 (file)
index 0000000..7ce2445
Binary files /dev/null and b/src/olddocs/z80.pdf differ
diff --git a/testbuild b/testbuild
new file mode 100755 (executable)
index 0000000..a2c6bb4
--- /dev/null
+++ b/testbuild
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./build "`pwd`/src" "`pwd`/staging" "`pwd`/staging"
diff --git a/tpl/_contents.xslt b/tpl/_contents.xslt
new file mode 100644 (file)
index 0000000..9d8f91a
--- /dev/null
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+       
+       <xsl:output method="html"/>
+       <xsl:param name="SRC"/>
+       <xsl:param name="THIS"/>
+       
+       <xsl:variable name="mytitle" select="/html/head/title"/>
+       <xsl:variable name="contentsxml" select="document(concat($SRC, '/contents.xml'))"/>
+       
+       <xsl:key name="title" match="page"
+               use="document(concat($SRC, '/', @src))/html/head/title"/>
+       
+       <xsl:template match="page" mode="site-contents">
+               <xsl:variable name="child" select="document(concat($SRC, '/', @src))"/>
+               <xsl:variable name="childtitle">
+                       <xsl:value-of select="$child/html/head/title"/>
+               </xsl:variable>
+               
+               <xsl:element name="a">
+                       <xsl:attribute name="href">
+                               <xsl:value-of select="$DESTURL"/>
+                               <xsl:text>/</xsl:text>
+                               <xsl:choose>
+                                       <xsl:when test="substring(@src, string-length(@src)-1) = '.i'">
+                                               <xsl:value-of select="substring(@src, 1, string-length(@src)-2)"/>
+                                               <xsl:text>.html</xsl:text>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:value-of select="@src"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:attribute>
+
+                       <xsl:value-of select="$childtitle"/>
+               </xsl:element>
+       </xsl:template>
+
+       <xsl:template match="page" mode="site-contents-li">
+               <li>
+                       <xsl:if test="@src = $THIS">
+                               <xsl:attribute name="class">
+                                       <xsl:text>selected</xsl:text>
+                               </xsl:attribute>
+                       </xsl:if>
+                       
+                       <xsl:apply-templates select="." mode="site-contents"/>
+               </li>
+       </xsl:template>
+       
+       <xsl:template name="sibling-page-list">
+               <xsl:variable name="currentnode" select="$contentsxml//page[@src = $THIS]"/>
+
+               <h4>Page Group</h4>
+               <ul>
+                       <xsl:for-each select="$currentnode/../page">
+                               <xsl:apply-templates select="." mode="site-contents-li"/>
+                       </xsl:for-each>
+               </ul>
+       </xsl:template>
+
+       <xsl:template name="child-page-list">
+               <xsl:variable name="currentnode" select="$contentsxml//page[@src = $THIS]"/>
+               <xsl:variable name="hierarchy" select="$currentnode/ancestor::*"/>
+               
+               <xsl:if test="$currentnode/page">
+                       <h4>Child Pages</h4>
+                       <ul>
+                               <xsl:for-each select="$currentnode/page">
+                                       <xsl:apply-templates select="." mode="site-contents-li"/>
+                               </xsl:for-each>
+                       </ul>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="site-contents">
+               <xsl:variable name="currentnode" select="$contentsxml//page[@src = $THIS]"/>
+               <xsl:variable name="hierarchy" select="$currentnode/ancestor::*"/>
+               
+               <div class="toclist">
+                       <!-- Parents -->
+                       <xsl:for-each select="$hierarchy">
+                               <xsl:variable name="child" select="document(concat($SRC, '/', @src))"/>
+                               <xsl:variable name="childtitle">
+                                       <xsl:value-of select="$child/html/head/title"/>
+                               </xsl:variable>
+                               <div class="parent">
+                                       <xsl:apply-templates select="." mode="site-contents"/>
+                               </div>
+                       </xsl:for-each>
+                       
+                       <xsl:choose>
+                               <xsl:when test="$currentnode/page">
+                                       <!-- The current page has children. Show the page itself. -->
+                                       <div class="parent">
+                                               <xsl:apply-templates select="$currentnode" mode="site-contents"/>
+                                       </div>
+                                       
+                                       <!-- Children, if any -->
+                                       <xsl:for-each select="$currentnode/page">
+                                               <div class="child">
+                                                       <xsl:apply-templates select="." mode="site-contents"/>
+                                               </div>
+                                       </xsl:for-each>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <!-- The current page has no children, so show siblings instead. -->
+                                       <xsl:for-each select="$currentnode/../page">
+                                               <div class="child">
+                                                       <xsl:apply-templates select="." mode="site-contents"/>
+                                               </div>
+                                       </xsl:for-each>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </div>
+       </xsl:template>
+
+       <xsl:template name="path-to-page">
+               <xsl:variable name="currentnode" select="$contentsxml//page[@src = $THIS]"/>
+               
+               <xsl:for-each select="$currentnode/ancestor-or-self::*">
+                       <xsl:if test="position() > 1">
+                               <xsl:text> / </xsl:text>
+                       </xsl:if>
+                       <xsl:apply-templates select="." mode="site-contents"/>
+               </xsl:for-each>
+       </xsl:template>
+
+       <xsl:template name="navigation-block">
+               <xsl:variable name="currentnode" select="$contentsxml//page[@src = $THIS]"/>
+               
+               <xsl:variable name="prevnode" select="$currentnode/preceding-sibling::*[1]"/>
+               <xsl:variable name="upnode" select="$currentnode/parent::*"/>
+               <xsl:variable name="nextnode" select="$currentnode/following-sibling::*[1]"/>
+               
+               <xsl:if test="$prevnode | $nextnode">
+                       <div class="navigation-block">
+                               <table>
+                                       <tr><td class="navigation-left">
+                                               <xsl:if test="$prevnode">
+                                                       <b>«</b>
+                                                       <xsl:apply-templates select="$prevnode" mode="site-contents"/>
+                                               </xsl:if>
+                                       </td><td class="navigation-right">
+                                               <xsl:if test="$nextnode">
+                                                       <xsl:apply-templates select="$nextnode" mode="site-contents"/>
+                                                       <b>»</b>
+                                               </xsl:if>
+                                       </td></tr>
+                               </table>
+                       </div>
+               </xsl:if>
+       </xsl:template>
+       
+       <xsl:template match="a" mode="smartlink">
+               <xsl:variable name="pagename" select="@href"/>
+               <xsl:variable name="currentnode" select="$contentsxml//page[@src = $THIS]"/>
+       
+               <xsl:variable name="targets" select="$contentsxml//page[contains(@src, $pagename)]"/>
+               <xsl:if test="count($targets) = 0">
+                       <xsl:message terminate="yes">
+                               <xsl:value-of select="$pagename"/>
+                               <xsl:text> could not be resolved</xsl:text>
+                       </xsl:message>
+               </xsl:if>
+               <xsl:if test="count($targets) > 1">
+                       <xsl:message terminate="yes">
+                               <xsl:value-of select="$pagename"/>
+                               <xsl:text> is ambiguous among (</xsl:text>
+                               <xsl:for-each select="$targets">
+                                       <xsl:value-of select="@src"/>
+                                       <xsl:text> </xsl:text>
+                               </xsl:for-each>
+                               <xsl:text>)</xsl:text>
+                       </xsl:message>
+               </xsl:if>
+
+               <xsl:apply-templates select="$targets[1]" mode="site-contents"/>
+       </xsl:template>
+       
+       <xsl:template match="*" mode="site-contents">
+               <xsl:message terminate="yes">
+                       <xsl:text>Unsupported tag </xsl:text>
+                       <xsl:value-of select="name(.)"/>
+               </xsl:message>
+       </xsl:template>
+</xsl:stylesheet>
diff --git a/tpl/_htmlx.xslt b/tpl/_htmlx.xslt
new file mode 100644 (file)
index 0000000..dc8bf02
--- /dev/null
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+       
+       <xsl:output method="html"/>
+       
+
+       <xsl:template match="p | i | b | u | tt | hr | ol | ul | li | blockquote | h4 | table | tbody | tr | td | th">
+               <xsl:copy>
+                       <xsl:copy-of select="@*"/>
+                       <xsl:apply-templates/>
+               </xsl:copy>
+       </xsl:template>
+       
+       <xsl:template match="code">
+               <tt>
+                       <xsl:copy-of select="@*"/>
+                       <xsl:apply-templates/>
+               </tt>
+       </xsl:template>
+       
+       <xsl:template match="var | em">
+               <i>
+                       <xsl:copy-of select="@*"/>
+                       <xsl:apply-templates/>
+               </i>
+       </xsl:template>
+       
+       <xsl:template match="pre">
+               <xsl:copy>
+                       <xsl:copy-of select="@*"/>
+                       <xsl:value-of select="."/>
+               </xsl:copy>
+       </xsl:template>
+       
+       <xsl:template match="hr">
+               <hr/>
+       </xsl:template>
+       
+       
+       <xsl:template match="a[@href = text()]">
+               <xsl:apply-templates select="." mode="smartlink"/>
+       </xsl:template>
+
+       <xsl:template match="a">
+               <xsl:copy>
+                       <xsl:copy-of select="@*"/>
+                       <xsl:apply-templates/>
+               </xsl:copy>
+       </xsl:template>
+       
+
+       <xsl:template match="dl">
+               <table columns="2" class="dl">
+                       <xsl:for-each select="dt">
+                               <tr>
+                                       <td>
+                                               <xsl:apply-templates select="node()"/>
+                                       </td><td>
+                                               <xsl:apply-templates select="following-sibling::dd[1]/node()"/>
+                                       </td>
+                               </tr>
+                       </xsl:for-each>
+               </table>
+       </xsl:template>
+       
+       
+       <xsl:template match="img[substring(@src, string-length(@src)-3) = '.svg']">
+               <xsl:element name="object">
+                       <xsl:attribute name="data">
+                               <xsl:value-of select="@src"/>
+                       </xsl:attribute>
+                       <xsl:attribute name="type" value="image/svg+xml"/>
+                       <xsl:text>[An SVG file goes here]</xsl:text>
+               </xsl:element>
+       </xsl:template>
+       
+       <xsl:template match="img">
+               <xsl:copy>
+                       <xsl:copy-of select="@*"/>
+                       <xsl:apply-templates/>
+               </xsl:copy>
+       </xsl:template>         
+
+       <xsl:template match="h1|h2|h3">
+               <h1>
+                       <xsl:element name="a">
+                               <xsl:attribute name="name">
+                                       <xsl:value-of select="generate-id(.)"/>
+                               </xsl:attribute>
+                               <xsl:apply-templates select="." mode="header-label"/>
+                       </xsl:element>
+               </h1>
+       </xsl:template>
+       
+       <xsl:template match="h1" mode="header-label">
+               <xsl:number level="any" count="h1"/>
+               <xsl:text>. </xsl:text>
+               <xsl:apply-templates/>
+       </xsl:template>
+       
+       <xsl:template match="h2" mode="header-label">
+               <xsl:number level="any" count="h1"/>
+               <xsl:text>.</xsl:text>
+               <xsl:number level="any" from="h1" count="h2"/>
+               <xsl:text>. </xsl:text>
+               <xsl:apply-templates/>
+       </xsl:template>
+               
+       <xsl:template match="h3" mode="header-label">
+               <xsl:number level="any" count="h1"/>
+               <xsl:text>.</xsl:text>
+               <xsl:number level="any" from="h1" count="h2"/>
+               <xsl:text>.</xsl:text>
+               <xsl:number level="any" from="h2" count="h3"/>
+               <xsl:text>. </xsl:text>
+               <xsl:apply-templates/>
+       </xsl:template>
+       
+       
+       <xsl:template match="h1" mode="toc-indent">
+       </xsl:template>
+       
+       <xsl:template match="h2" mode="toc-indent">
+               <xsl:text>...</xsl:text>
+       </xsl:template>
+               
+       <xsl:template match="h3" mode="toc-indent">
+               <xsl:text>......</xsl:text>
+       </xsl:template>
+       
+       
+       <xsl:template match="h1" mode="toc-label">
+               <xsl:number level="any" count="h1"/>
+               <xsl:text>. </xsl:text>
+               <xsl:apply-templates/>
+       </xsl:template>
+       
+       <xsl:template match="h2" mode="toc-label">
+               <xsl:number level="any" from="h1" count="h2"/>
+               <xsl:text>. </xsl:text>
+               <xsl:apply-templates/>
+       </xsl:template>
+               
+       <xsl:template match="h3" mode="toc-label">
+               <xsl:number level="any" from="h2" count="h3"/>
+               <xsl:text>. </xsl:text>
+               <xsl:apply-templates/>
+       </xsl:template>
+       
+       <xsl:template match="h4" mode="toc-label">
+       </xsl:template>
+       
+       
+       <xsl:template match="*">
+               <xsl:message terminate="yes">
+                       <xsl:text>Unsupported tag </xsl:text>
+                       <xsl:value-of select="name(.)"/>
+               </xsl:message>
+       </xsl:template>
+</xsl:stylesheet>
diff --git a/tpl/standard.xslt b/tpl/standard.xslt
new file mode 100644 (file)
index 0000000..be91418
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE stylesheet [
+<!ENTITY nbsp "&#160;" >
+]>
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+       
+       <xsl:import href="_htmlx.xslt"/>
+       <xsl:import href="_contents.xslt"/>
+       <xsl:output method="xml"
+               doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+               doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
+               indent="no"
+               encoding="UTF-8"/>
+       
+       <xsl:param name="SRC"/>
+       <xsl:param name="DESTURL"/>
+       <xsl:variable name="DOCUMENT" select="."/>
+       
+       <xsl:key name="parentheader"
+               match="html/body/*[starts-with(local-name(),'h')]"
+               use="generate-id(preceding-sibling::*[local-name()=concat('h', number(substring-after(local-name(current()),'h')) - 1)][1])"/>
+
+       <xsl:template match="/">
+               <html>
+                       <head>
+                               <title><xsl:value-of select="html/head/title"/></title>
+                               <link rel="stylesheet" type="text/css" href="{$DESTURL}/global.css"/>
+                               <link rel="home" type="text/html" href="/"/>
+                       </head>
+                       
+                       <body>
+                               <script type="text/javascript" src="{$DESTURL}/global.js"></script>
+                               <!-- Left-hand column -->
+                               <div class="nav nav-logo">
+                                       <img src="{$DESTURL}/logo.png" alt="Prime Mover"/>
+                               </div>
+                               
+                               <div class="nav nav-related">
+                                       <xsl:call-template name="sibling-page-list"/>
+                               </div>
+                               
+                               <div class="nav nav-children">
+                                       <xsl:call-template name="child-page-list"/>
+                               </div>
+                               
+                               <div class="nav nav-icons">
+                                       <a href="http://validator.w3.org/check?uri=referer">
+                                               <img src="http://www.w3.org/Icons/valid-xhtml10"
+                                                       alt="Valid XHTML 1.0 Strict" height="31" width="88"/>
+                                       </a>
+                                       <br/>
+                                       <a href="http://jigsaw.w3.org/css-validator/">
+                                               <img src="http://jigsaw.w3.org/css-validator/images/vcss"
+                                                       alt="Valid CSS" height="31" width="88"/>
+                                       </a>
+                                       <br/>
+                                       <a href="http://sourceforge.net/projects/primemover">
+                                               <img src="http://sflogo.sourceforge.net/sflogo.php?group_id=157791&amp;type=1"
+                                                       width="88" height="31" alt="SourceForge.net Logo"/>
+                                       </a>
+                               </div>
+                               
+                               <!-- Right-hand column -->
+                               
+                               <div class="page-path">
+                                       <p>
+                                               <xsl:call-template name="path-to-page"/>
+                                       </p>
+                               </div>
+                               
+                               <div class="page-body">
+                                       <xsl:call-template name="navigation-block"/>
+                                       
+                                       <h1 class="title"><xsl:value-of select="html/head/title"/></h1>
+                                       
+                                       <xsl:if test="html/body/h1">
+                                               <div id="toc" class="body-contents">
+                                                       <h4 id="toctitle">Page Contents</h4>
+                                                       <ol class="toclist" style="display:none">
+                                                               <xsl:apply-templates select="html/body/h1" mode="toc"/>
+                                                       </ol>
+                                               </div>
+                                       </xsl:if>
+
+                                       <script type="text/javascript" src="{$DESTURL}/contents.js"></script>
+                                       
+                                       <xsl:apply-templates select="html/body/*"/>
+
+                                       <xsl:call-template name="navigation-block"/>
+                               </div>
+                       </body>
+               </html>
+       </xsl:template>
+
+       <xsl:template match="html/body/h1 | html/body/h2 | html/body/h3" mode="toc">
+               <li>
+                       <xsl:element name="a">
+                               <xsl:attribute name="href">
+                                       <xsl:text>#</xsl:text>
+                                       <xsl:value-of select="generate-id(.)"/>
+                               </xsl:attribute>
+                               <xsl:value-of select="."/>
+                       </xsl:element>
+
+                       <xsl:if test="key('parentheader',generate-id())">
+                               <ol class="toclist">
+                                       <xsl:apply-templates select="key('parentheader',generate-id())" mode="toc"/>
+                               </ol>
+                       </xsl:if>
+               </li>
+       </xsl:template>
+
+       <xsl:template match="html/body/h4" mode="toc"/>
+</xsl:stylesheet>