home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / compiler / documentation / porting.guide (.txt) < prev    next >
Amigaguide Document  |  1993-11-10  |  180KB  |  3,115 lines

  1.        Emacs: Please use -*- Text -*- mode.  Thank you.
  2. $Id: porting.guide,v 1.26 1993/11/10 22:47:25 gjr Exp $
  3. Copyright (c) 1991-1993 Massachusetts Institute of Technology
  4.             LIAR PORTING GUIDE
  5.                  *DRAFT*
  6. Notes: 
  7. This porting guide applies to Liar version 4.91, but most of the
  8. relevant information has not changed for a while, nor is it likely to
  9. change in major ways any time soon.
  10. This is an early version of this document, and the order of
  11. presentation leaves a lot to be desired.  In particular, the document
  12. does not follow a monotonic progression, but is instead organized in a
  13. dictionary-like manner.  We recommend that you read through the whole
  14. document twice since some important details, apparently omitted, may
  15. have their explanation later in the document.  When reading the
  16. document for the second time, you will have an idea of where this
  17. other information is to be found, if it is present at all.  We have
  18. attempted to insert sufficient forward pointers to make the first
  19. reading bearable, but we may have missed some.
  20. This document implicitly assumes that you are trying to build the
  21. compiler under Unix.  The only compiler sources that depend on Unix
  22. are the sources that contain the pathnames of other files.
  23. The syntax could easily be changed for other file systems.
  24. This document uses Unix pathname syntax and assumes a hierarchical
  25. file system, but it should easy to map these directories to a
  26. different file system.  The DOS runtime library accepts forward
  27. slashes (#\/) as a substitute for backward slashes (#\\), so the
  28. scripts are shared between Unix and DOS.
  29. This document also assumes that you are familiar with MIT Scheme, C,
  30. and the C preprocessor.  It does not describe Liar in detail, and it
  31. does not cover many machine-independent portions at all.  It is
  32. intended to guide a programmer familiar with (MIT) Scheme and C in the
  33. task of porting the compiler to a new architecture, not in modifying
  34. the compiler in any other way.
  35. For questions on Liar not covered by this document, or questions about
  36. this document, contact ``liar-implementors@zurich.ai.mit.edu''.
  37. Text tagged by ==> is intended primarily for the compiler developers.
  38. Good luck!
  39.         Acknowledgments
  40. Liar is the work of many people.  The current version is mostly the
  41. effort of Chris Hanson and Bill Rozas, with significant contributions
  42. from Mark Friedman and Jim Miller.  Arthur Gleckler, Brian LaMacchia,
  43. and Henry Wu have also contributed to the current version of Liar.
  44. Many other people have offered suggestions and criticisms.
  45. The current Liar might never have existed had it not been for the
  46. efforts and help of the now-extinct BBN Butterfly Lisp group.  That
  47. group included Don Allen, Seth Steinberg, Larry Stabile, and Anthony
  48. Courtemanche.  Don Allen, in particular, babysat computers to
  49. painstakingly bootstrap the first version of the then new Liar.
  50. Many of the ideas and algorithms used in Liar, particularly at the RTL
  51. level, are taken from the GNU C compiler, written by Richard Stallman
  52. and many others.
  53. This document was written by Bill Rozas, with modifications and hints
  54. from the people listed above.  The section on the MIT Scheme package
  55. system was written by Arthur Gleckler.
  56.         0. Introduction and a brief walk through Liar.
  57. Liar translates Scode as produced by the procedure SYNTAX, or by the
  58. file syntaxer (SF, for syntax file) into compiled code objects.  The
  59. Scode is translated into a sequences of languages, the last of which
  60. is the binary representation of the compiled code.
  61. The sequence of external languages manipulated is
  62.     Characters --READ--> 
  63.     S-Expressions --SYNTAX--> 
  64.     Scode --COMPILE-SCODE--> 
  65.     compiled code objects.
  66. Liar is a multi-pass compiler, where each major pass has multiple
  67. subpasses.  Many of the subpasses do not manipulate the whole code
  68. graph, but instead follow threads that link the relevant parts of the
  69. graph.
  70. COMPILE-SCODE is the main entry point to Liar, although CBF (for
  71. compile bin file) is the usual entry point.  CBF uses COMPILE-SCODE,
  72. and assumes that the code has been syntaxed by SF producing a .bin
  73. file, and dumps the resulting compiled code into a .com file.  CF (for
  74. compile file) invokes SF and then CBF on a file name argument.
  75. The internal sub-languages used by Liar are:
  76.     Scode --FGGEN--> 
  77.     Flow-graph --RTLGEN--> 
  78.     RTL (Register Transfer Language) --LAPGEN-->
  79.     LAP (Lisp assembly program) --ASSEMBLER--> 
  80.     bits --LINK--> 
  81.     compiled code object.
  82. where FGGEN, etc., are some of the major passes of the compiler.  
  83. The remaining major passes are FGOPT (the flow-graph optimizer), and
  84. RTLOPT (the RTL-level optimizer).  RTL-level register allocation is
  85. performed by RTLOPT, and hardware-level register allocation is
  86. performed by LAPGEN.  ASSEMBLER branch-tensions the output code.
  87. Branch-tensioning is described in a later section.  LINK constructs a
  88. Scheme compiled code object from the bits representing the code and
  89. the fixed data that the compiled code uses at runtime.
  90. compiler/toplev.scm contains the top-level calls of the compiler and
  91. its pass structure.
  92. The ``.com'' files contain compiled code objects, which are linked
  93. further at load time.
  94.     0.1.  Liar's package structure
  95. This section assumes that you are familiar with the MIT Scheme package
  96. system.  If you are not, there is a small description in an appendix
  97. to this document.
  98. The package structure of the compiler reflects the pass structure and
  99. is specified in compiler/machines/port/comp.pkg, where port is the
  100. name of a machine (bobcat, vax, spectrum, mips, i386, alpha, etc.).
  101. The major packages are:
  102. (COMPILER):
  103.     Utilities and data structures shared by most of the compiler.
  104. (COMPILER MACROS):
  105.     Syntax extensions used by the compiler to define language
  106. translation rules.
  107. (COMPILER TOP-LEVEL):
  108.     Top level pass structure of the compiler.
  109. (COMPILER FG-GENERATOR):
  110.     This package contains the flow-graph generator, FGGEN.
  111. (COMPILER FG-OPTIMIZER):
  112.     This package contains the flow-graph analyzer and optimizer,
  113. FGOPT. It has many sub-packages to contain the individual sub-passes.
  114. (COMPILER RTL-GENERATOR):
  115.     This package contains the flow-graph to RTL translator,
  116. RTLGEN. It contains a few sub-packages for the major kinds of
  117. flow-graph operations.
  118. (COMPILER RTL-OPTIMIZER):
  119.     This package contains most of the RTL-level optimizer, RTLOPT.
  120. It has various sub-packages corresponding to some of its sub-passes.
  121. (COMPILER RTL-CSE):
  122.     This package contains the RTL-level common (redundant)
  123. subexpression eliminator pass of the RTL-level optimizer.
  124. (COMPILER LAP-SYNTAXER):
  125.     This package contains most of the machine-dependent parts of
  126. the compiler and the back end utilities.  In particular, it contains
  127. the RTL -> LAP translation rules, and the LAP -> bits translation
  128. rules, i.e. the LAPGEN and ASSEMBLER passes respectively.  It has some
  129. sub-packages for various major utilities (linearizer, map-merger,
  130. etc.).
  131. (COMPILER ASSEMBLER):
  132.     This package contains most of the machine-independent portion of
  133. the assembler.  In particular, it contains the bit-assembler, i.e.
  134. the portion of the assembler that accumulates the bit strings produced
  135. by ASSEMBLER and performs branch-tensioning on the result.
  136. (COMPILER DISASSEMBLER):
  137.     This package contains the disassembler.  It is not needed for
  138. ordinary compiler operation, but is useful for low-level debugging,
  139. and debugging of the compiler and assembler.
  140.     0.2. Liar's sources' directory structure
  141. The directory structure loosely reflects the pass structure of the
  142. compiler.  compiler/machines/port/comp.pkg declares the packages and
  143. the files that constitute them.
  144. compiler/back:
  145.     This directory contains the machine-independent portion of the
  146. back end.  It contains bit-string utilities, symbol table utilities,
  147. label management procedures, the hardware register allocator, and the
  148. top-level assembler calls.
  149. compiler/base:
  150.     This directory contains common utilities used by the whole
  151. compiler, and the top level procedures provided by the compiler.
  152. compiler/etc:
  153.     This directory contains utilities used for cross-compiling,
  154. and checking re-compilations.
  155. compiler/fggen:
  156.     This directory contains the front end of the compiler.  The
  157. code in this directory translates Scode into a flow-graph used by the
  158. analyzer and optimizer.
  159. compiler/fgopt:
  160.     This directory contains the flow-graph analyzer and optimizer.
  161. compiler/rtlbase:
  162.     This directory contains utilities used by the RTL generator and
  163. optimizer.
  164. compiler/rtlgen:
  165.     This directory contains the code that translates the
  166. flow-graph into register transfer language (RTL).
  167. compiler/rtlopt:
  168.     This directory contains the RTL-level optimizer.  It contains
  169. code to perform lifetime analysis, redundant subexpression
  170. elimination, elimination of dead code, etc.
  171. compiler/machines:
  172.     This directory contains a subdirectory for each port of the
  173. compiler.  Each of these subdirectories contains the port (machine)
  174. dependent files of the compiler.
  175. compiler/machines/port:
  176.     This directory contains the definition of machine parameters,
  177. the assembler rules, the disassembler, and RTL to assembly-language
  178. rules for the port.  
  179. All machine-dependent files are in compiler/machines/port and this is
  180. the only directory that needs to be written to port the compiler to a
  181. new architecture.
  182.         1. Liar's runtime model.
  183. Liar does not open code (inline) all operations that the code would
  184. need to execute.  In particular, it leaves error handling and
  185. recovery, interrupt processing, initialization, and invocation of
  186. unknown procedures, to a runtime library written in assembly language.
  187. Although this runtime library need not run in the context of the
  188. CScheme interpreter, currently the only implementation of this library
  189. runs from the interpreter and uses it for many of its operations.
  190. In other words, code generated by Liar does not depend on the
  191. interpreter directly, but indirectly through the runtime library.  It
  192. does depend on the ability to invoke CScheme primitives at runtime,
  193. some of which (eval, etc.)  require the interpreter to be present.  It
  194. should be possible, however, to provide an alternate runtime library
  195. and primitive set that would allow code produced by Liar to run
  196. without the interpreter being present. (Foot) We often toy with this
  197. idea.
  198. On the other hand, since the only instance of the runtime library is
  199. that supplied by the interpreter, Liar currently assumes that the
  200. Scheme object representation is the same as that used by the
  201. interpreter, but this is relatively well abstracted and should not be
  202. hard to change. (Foot) Famous last words.
  203. The runtime library is currently implemented by
  204. microcode/cmpaux-port.m4 and microcode/cmpint.c .  The files
  205. cmpaux.txt and cmpint.txt document these files.  The documentation
  206. files may be found in the microcode or the documentation directories.
  207. microcode/cmpaux-port.m4 is an assembly language machine-dependent file
  208. that allows compiled Scheme to call the C-written library routines and
  209. vice versa.  It is described in cmpaux.txt.
  210. microcode/cmpint.c defines the library in a machine-independent way,
  211. but requires some information about the port and this is provided in
  212. microcode/cmpint2.h, a copy (or link) of the appropriate
  213. microcode/cmpint-port.h file.  The microcode/cmpint-port.h files are
  214. described in cmpint.txt .
  215. cmpint.txt also describes many of the data structures that the
  216. compiled code and runtime library manipulate, and defines some of the
  217. concepts needed to understand the compiler.
  218. The rest of this document assumes that you are using the runtime
  219. library provided by the CScheme interpreter.  If you wish to use Liar
  220. as a compiler for stand-alone programs, a lot of work needs to be
  221. done, and this work is not described here.  Perhaps we will do it in
  222. the future.
  223. If you have not yet read cmpaux.txt and cmpint.txt, please do so
  224. before reading the rest of this document.
  225. You should probably also read [1] and [2] for a discussion of some of
  226. the implementation issues.
  227.         2. Preliminary Observations
  228.     2.1. Constraints on architectures to which Liar can be ported:
  229. - Liar assumes that the target machine is a general-register machine.
  230. That is, operations are based on processor registers, and there is a
  231. set of general-purpose registers that can be used interchangeably.  It
  232. would be hard to port Liar to a pure stack machine, a graph-reduction
  233. engine, a Turing machine, or a 4-counter machine.  However, the
  234. register set required is not huge.  Liar has been ported to the
  235. 386/486 architecture which only has eight registers, four of which are
  236. reserved for implementation quantities (e.g. stack pointer and free
  237. pointer) and four of which are left to the register allocator.
  238. - Liar currently assumes that floating-point registers and integer
  239. registers are separate or the same size.  In other words, currently
  240. Liar cannot handle quantities that need multiple registers to hold
  241. them.  For example, on the DEC VAX and the Motorola 88100, there is a
  242. single set of registers, and double floating point values (the only
  243. kind used by Scheme) take two consecutive integer registers.  The
  244. register allocator in Liar does not currently handle this situation,
  245. and thus, floating-point operations are not currently open-coded on
  246. the VAX.
  247. - Liar assumes that the target machine has an address space that is
  248. flat enough that all Scheme objects can be addressed uniformly.  In
  249. other words, segmented address spaces with segments necessarily
  250. smaller than the Scheme runtime heap (i.e. Intel 286) will make Liar
  251. difficult to port.
  252. - Liar assumes that instructions and data can coexist in the same
  253. address space, and that new code objects that contain machine
  254. instructions can be dynamically allocated from and written to the heap
  255. (memory pool) used to allocate all other Scheme objects.  This
  256. assumption in Liar conflicts with some current hardware that has
  257. programmer-visible separate (split) data and instruction caches --
  258. that is, there are two different caches, one used by the processor for
  259. instruction references and the other for data references, and storing
  260. data into memory only updates the data cache, but not the instruction
  261. cache, and perhaps not even memory.  Most of the problems this causes
  262. can be resolved if the user is given enough control over the hardware
  263. caches, i.e. some way to flush or synchronize them.  Furthermore, a
  264. true Harvard architecture, with separate code and data memories, would
  265. be hard to accommodate without relatively major changes.  At some
  266. point in the future we may write a C back end for Liar that handles
  267. this case, since C code space and data space are typically kept
  268. separate by the operating system.  Whatever technique the C back end
  269. may use can probably be emulated by architectures with such a strong
  270. division, although it is likely to be expensive.
  271.     2.2. Some implementation decisions that may make your job
  272. harder or impair the quality of the output code:
  273. - Liar generates code that passes arguments to procedures on a stack.
  274. This decision especially affects the performance on load-store
  275. architectures, common these days.  Liar may be changed in the future
  276. to generate code that passes arguments in registers because most
  277. modern machines have large register sets and memory-based operations
  278. are slower than register-based operations even when the memory
  279. locations have been cached.
  280. - Liar assumes that pushing and popping elements from a stack is
  281. cheap.  Currently Liar does not attempt to bump the stack pointer once
  282. per block of operations, but instead bumps it once per item.  This is
  283. expensive on many modern machines where pre-and-post incrementing are
  284. not supported by the hardware.  This may also change in the
  285. not-too-far future.
  286. - Liar assumes that it is cheap to compute overflow conditions on
  287. integer arithmetic operations.  Generic arithmetic primitives have the
  288. frequent fixnum (small integer) case open coded, and the overflow and
  289. non-fixnum cases coded out of line, but this depends on the ability of
  290. the code to detect and branch on overflow conditions cheaply.  This is
  291. not true of some modern machines, notably MIPS processors.  If your
  292. processor does not make branching on such conditions reasonably cheap,
  293. you may have to use code similar to that used in the MIPS port.  The
  294. MIPS processor has trapping and non-trapping arithmetic instructions.
  295. The trapping arithmetic instructions trap on overflow, but the trap
  296. recovery code is typically so expensive that the generated code
  297. computes the overflow conditions explicitly.
  298. - Liar assumes that extracting, inserting, and comparing bit-fields is
  299. relatively cheap.  The current object representation for Liar
  300. (compatible with the interpreter) consists of using a number of bits
  301. (usually 6) in the most significant bit positions of a machine word as
  302. a type tag, and the rest as the datum, usually an encoded address.
  303. Not only must extracting, comparing, and inserting these tags be
  304. cheap, but decoding the address must be cheap as well.  These
  305. operations are relatively cheap on architectures with bit-field
  306. instructions, but more expensive if they must be emulated with bitwise
  307. boolean operations and shifts, as on the MIPS R3000.  Decoding a datum
  308. into an address may involve inserting segment bits in some of the
  309. positions where the tag is placed, further increasing the dependency
  310. on cheap bit-field manipulation.
  311. - The CScheme interpreter uses a particularly poor representation for
  312. fixnums, forcing Liar's hand.  Fixnums are suitably small integers.
  313. They are immediate objects with a particular tag.  This tag was not
  314. wisely chosen, making fixnum operations more expensive than they need
  315. to be.  This tag may be changed in the future.
  316. - The CScheme interpreter manipulates a stack that grows in a fixed
  317. direction (from higher to lower addresses).  On many modern machines,
  318. there are no special instructions to deal with the stack, so the
  319. decision is arbitrary.  On some machines, however, there are special
  320. instructions to pop and push elements on the stack.  Liar may not be
  321. able to use these instructions if the machine's preferred direction of
  322. stack growth does not match the interpreter's.
  323.     2.3. Emulating an existing port.
  324. The simplest way to port Liar is to find an architecture to which Liar
  325. has already been ported that is sufficiently similar to the target
  326. architecture that most of the code can be written by copying or
  327. trivially translating existing code.  In particular, if the
  328. architectures are really close, there may be no need for
  329. architecture-specific additional tuning.
  330. The compiler is primarily developed on Motorola MC68020 processors, so
  331. this is the best-tuned version, and the other ports are not very well
  332. tuned or not tuned at all.  If you improve an existing port, please
  333. share the improvements by notifying liar-implementors.
  334. - If you have a Vax-like CISC machine, you can try starting from the
  335. Vax, the Motorola MC68020, or the i386 ports.  The Vax and i386 ports
  336. were written by starting from the MC68020 port.  This is probably the
  337. best solution for some architectures like the NS32000, and perhaps
  338. even the IBM 370.
  339. - If you have an ``enlarged'' RISC processor, with some complex
  340. addressing modes, and bit-field instructions, you may want to start by
  341. looking at the Spectrum (HP Precision Architecture) port.  This is
  342. probably a good starting point for the Motorola 88000 and for the IBM
  343. RS/6000.
  344. - If you have a bare-bones RISC processor, similar to a MIPS R3000
  345. processor, you may want to start from this port.  Since the MIPS R3000
  346. is a minimalist architecture, it almost subsumes all other RISCs, and
  347. may well be a good starting point for all of them.  This is probably a
  348. good starting point for the Sparc.  The MIPS port used the Spectrum
  349. port as its model, and the Alpha port used the MIPS port as its model.
  350. - If you have a machine significantly different from those listed
  351. above, you are out of luck and will have to write a port from scratch.
  352. For example, the port to the Intel 386+387/486 uses some of the
  353. concepts and code from ports to other CISCs, but due to the
  354. floating-point stack architecture (instead of register-based), the
  355. floating-point stack management is different (but not very good).
  356. Of course, no architecture is identical to any other, so you may want
  357. to mix and match ideas from many of the ports already done, and it is
  358. probably a good idea for you to compare how the various ports solve
  359. the various problems.
  360.         3. Compiler operation, LAPGEN rules and ASSEMBLER rules.
  361. The front end of the compiler translates Scode into a flow-graph that
  362. is then translated into RTL.  The back end does machine-independent
  363. optimization on the RTL, generates assembly language (in LAP format)
  364. from the RTL, and assembles the resulting bits.
  365. Although RTL is a machine-independent language, the particular RTL
  366. generated for a given program will vary from machine to machine.  The
  367. RTL can vary in the following ways:
  368. - RTL is a language for manipulating the contents of conceptual
  369. registers.  RTL registers are divided into ``pseudo registers'' and
  370. ``machine registers''.  Machine registers represent physical hardware
  371. registers, some of which have been reserved and given fixed meanings
  372. by the port (stack pointer, value register, etc.)  while
  373. pseudo-registers represent conceptual locations that contain
  374. quantities that will need physical registers or memory locations to
  375. hold them in the final translation.  An RTL pseudo register can be
  376. mapped to any number of physical registers in the final translation,
  377. and may ``move'' between physical registers.  In order to make the RTL
  378. more homogeneous, the RTL registers are not distinguished
  379. syntactically in the RTL, but are instead distinguished by their value
  380. range.  Machine registers are represented as the N lowest numbered RTL
  381. registers (where N is the number of hardware registers), and all
  382. others are pseudo registers.  Since some RTL instructions explicitly
  383. mention machine registers and these (and their numbers) vary from
  384. architecture to architecture, the register numbers in an RTL program
  385. will vary depending on the back end in use.  Machine registers may be
  386. divided into separate classes (e.g.  address, data, and floating-point
  387. registers) that can contain different types of values.  Pseudo
  388. registers are not distinguished a-priori, but the values stored in
  389. them must be consistent.  For example, if a floating point value is
  390. stored into a particular pseudo register, the register can only be
  391. mapped to floating-point machine registers, and non-floating-point
  392. values cannot be stored in it.
  393. - RTL assumes a load-store architecture, but can accommodate
  394. architectures that allow memory operands and rich addressing modes.
  395. RTL is constructed by generating statements that include relatively
  396. complex expressions.  These expressions may represent multiple memory
  397. indirections or other operations.  An RTL simplifier runs over this
  398. initial RTL, assigning these intermediate quantities to new pseudo
  399. registers and rewriting the original statements to manipulate the
  400. original and new pseudo-registers.  Typically this simplification
  401. results in a sequence of assignments to pseudo-registers with single
  402. operations per assignment and where the only memory operations are
  403. load and store.  However, this simplification pass is controlled by
  404. the port.  The port supplies a set of rewriting rules to the
  405. simplifier that causes the simplifier to leave more complex
  406. expressions untouched, or to be simplified in different ways,
  407. depending on the availability of memory operands or richer addressing
  408. modes.  Since these rules vary from port to port, the final RTL
  409. differs for the different ports.  The simplification process is also
  410. controlled by the availability of various rules in the port, and ports
  411. for richer instruction sets may require less simplification because
  412. hardware instructions and addressing modes that encode more
  413. complicated RTL patterns are directly available.
  414. - The open coding (inlining) of Scheme primitives is
  415. machine-dependent.  On some machines, for example, there is no
  416. instruction to multiply integers, and it may not be advantageous to
  417. open code the multiplication primitive.  The RTL for a particular
  418. program may reflect the set of primitive operations that the back end
  419. for the port can open code.
  420. The resulting RTL program is represented as a control flow-graph where
  421. each of the nodes has an associated list of RTL statements.  The edges
  422. in the graph correspond to conditional and unconditional branches in
  423. the code, and include a low-level predicate used to choose between the
  424. alternatives.  The graph is linearized after the instructions have
  425. been translated to LAP.  There is a debugging RTL linearizer used by
  426. the RTL output routine.
  427. Besides assignments and tests, the RTL has some higher level
  428. statements that correspond to procedure headers, continuation (return
  429. address) headers, etc.  Thus an RTL program is made mostly of register
  430. to register operation statements, a few conditional tests, and a few
  431. higher-level ``glue'' statements.
  432. Once a program has been translated to RTL, the RTL code is optimized
  433. in a machine-independent way by minimizing the number of RTL
  434. pseudo-registers used, removing redundant subexpressions, eliminating
  435. dead code, and by using various other techniques.
  436. The RTL program is then translated into a Lisp-format
  437. assembly-language program (LAP).  Hardware register allocation occurs
  438. during this translation.  The register allocator is
  439. machine-independent and can accommodate different register classes,
  440. but does not currently accommodate register pairs (this is why floating
  441. point operations are not currently open coded on the Vax).
  442. The register allocator works by considering unused machine registers
  443. (those not reserved by the port) to be a cache for the
  444. pseudo-registers.  Thus a particular pseudo-register may map into
  445. multiple machine registers of different types, and these aliases are
  446. invalidated as the pseudo-registers are written or the corresponding
  447. machine registers reused.  Thus the most basic facility that the
  448. register allocator provides is a utility to allocate an alias of a
  449. particular type for a given pseudo-register.
  450. The port defines the types and numbers of machine registers and the
  451. subset that is available for allocation, and the register allocator
  452. manages the associations between the pseudo-registers and their
  453. aliases and the set of free machine registers.  The register allocator
  454. also automatically spills the contents of machine registers to memory
  455. when pressed for machine registers, and reloads the values when
  456. necessary.
  457. Thus the resulting LAP program is the collection of the code issued by
  458. the rules that translate RTL into LAP, the instructions issued behind
  459. the scenes by the register allocator, and the instructions used to
  460. linearize the control flow graph.
  461. The back end provides a set of rules for the translation of RTL to
  462. LAP, and a set of procedures that the register allocator and the
  463. linearizer use to generate such instructions.  The rules are written
  464. using a special syntax that creates entries in a data base used by a
  465. pattern matcher to translate the RTL into LAP.
  466. The linear LAP is then translated into binary form by using the same
  467. pattern matcher with a different set of rules.  These rules define the
  468. translation between assembly language and machine language for the
  469. architecture.  Most of these rules output bit strings to be collected
  470. together, but some output a set of directives to the bit-level
  471. assembler to define labels, or choose between alternative encoding of
  472. the fields depending on the final value of a displacement.  These
  473. alternative encodings are typically used for PC-relative quantities.
  474. The machine-independent bit-assembler collects all the bits together
  475. and keeps track of a virtual program counter used to determine the
  476. distance between instruction fields.  A relaxation process is used to
  477. reduce the size of the resulting encoding (to tension branches, i.e.
  478. to choose the smallest encoding that will do the job when there are
  479. alternatives).
  480. Since most of the LAPGEN rules generate almost fixed assembly language,
  481. where the only difference is the register numbers, most of the LAP to
  482. bits translation can be done when the compiler is compiled.  A
  483. compiler switch, ``COMPILER:ENABLE-EXPANSION-DECLARATIONS?'' allows this
  484. process to take place.  This mechanism has not been used for a while,
  485. however, because the resulting compiler was, although somewhat faster,
  486. considerably bigger, so this switch may not currently work.
  487. Several other compiler parameters and switches control various aspects
  488. of the operation of the back end.  Most parameters and switches are
  489. machine independent, and are defined in compiler/base/switch.scm .
  490. The remaining parameters and switches are defined in
  491. compiler/machines/port/machin.scm.  All compiler parameters and
  492. switches are exported to the Scheme global package for easy
  493. manipulation.
  494. The following switches are of special importance to the back end
  495. writer:
  496. * COMPILER:COMPILE-BY-PROCEDURES? This switch controls whether the
  497. compiler should compile each top-level lambda expression independently
  498. or compile the whole input program (or file) as a block.  It is
  499. usually set to true, but must be set to false for cross-compilation.
  500. The cross-compiler does this automatically.  (Foot) The reason for
  501. this is that the gc offset words in compiled entry points may differ
  502. for the source and target machines, and thus the source machine's
  503. garbage collector may be confused by the target machine's compiled
  504. entry points.  This is circumvented by having the cross compiler
  505. generate a single compiled code block object, manipulated and dumped
  506. as a vector object (instead of as an entry point).  The final entry
  507. points are generated by cross-compile-bin-file-end running interpreted
  508. on the target machine.
  509. * COMPILER:OPEN-CODE-PRIMITIVES? This switch controls whether Liar
  510. will open code (inline) MIT Scheme primitives.  It is usually set to
  511. true and should probably be left that way.  On the other hand, it is
  512. possible to do a lot less work in porting the compiler by not
  513. providing the open coding of primitives and turning this switch off.
  514.  Some of the primitives are open coded by the machine-independent
  515. portion of the compiler, since they depend only on structural
  516. information, and not on the details of the particular architecture.
  517. In other words, CAR, CONS, and many others can be open-coded in a
  518. machine-independent way since their open codings are performed
  519. directly in the RTL.  Turning this switch to false would prevent the
  520. compiler from open coding these primitives as well.
  521. * COMPILER:GENERATE-RTL-FILES? and COMPILER:GENERATE-LAP-FILES? These
  522. are mostly compiler debugging switches.  They control whether the
  523. compiler will issue .rtl and .lap files for every file compiled.  The
  524. .rtl file will contain the RTL for the program, and the .lap file will
  525. contain the input to the assembler.  Their usual value is false.
  526. * COMPILER:INTERSPERSE-RTL-IN-LAP? This is another debugging switch.
  527. If turned on, and COMPILER:GENERATE-LAP-FILES? is also on, the lap
  528. output file includes the RTL statements as comments preceding their
  529. LAP translations.  Its usual value is true.
  530.  ==> RTL predicates are not included, making the control-flow hard to
  531. follow.  This should be fixed.
  532. * COMPILER:OPEN-CODE-FLOATING-POINT-ARITHMETIC? This switch is
  533. defined in compiler/machines/port/machin.scm and determines whether
  534. floating point primitives can and should be open coded by the compiler
  535. or not.  If the port provides open codings for them, it should be set
  536. to true, otherwise to false.
  537. * COMPILER:PRIMITIVES-WITH-NO-OPEN-CODING This parameter is defined in
  538. compiler/machines/port/machin.scm.  It contains a list of primitive
  539. names that the port cannot open code.  Currently there is no simple
  540. list of all the primitives that Liar can open-code.  The list is
  541. implicit in the code contained in rtlgen/opncod.scm.
  542.  ==> The last two parameters should probably be combined and inverted.
  543. COMPILER:PRIMITIVES-WITH-OPEN-CODINGS should replace both of the
  544. above.  This has the advantage that if the RTL level is taught how to
  545. deal with additional primitives, but not all ports have open codings
  546. for them, there is no need to change all the machin.scm files, only
  547. those for which the open coding has been provided.
  548.         4. Description of the machine-specific files
  549. The following is the list of files that usually appears in the port
  550. directory.  The files can be organized differently for each port, but
  551. it is probably easiest if the same pattern is kept.  In particular,
  552. the best way to write most is by editing the corresponding files from
  553. an existing port.  Keeping the structure identical will make writing
  554. decls.scm, comp.pkg, and comp.sf straightforward, and will make future
  555. updates easier to track.
  556. A useful thing to do when writing new port files is to keep
  557. track of the original version from which you started, and
  558. additionally, that on which your original is based.  For example, if
  559. you use machines/mips/assmd.scm as a model for your version, in it you
  560. would find something like
  561.   $ Header: assmd.scm,v 1.1 90/05/07 04:10:19 GMT jinx Exp $
  562.   $MC68020-Header: assmd.scm,v 1.36 89/08/28 18:33:33 GMT cph Exp $
  563. In order to allow an easier merge in the future, it would
  564. be good if you transformed this header into
  565.   $ Header $
  566.   $mips-Header: assmd.scm,v 1.1 90/05/07 04:10:19 GMT jinx Exp $
  567.   $MC68020-Header: assmd.scm,v 1.36 89/08/28 18:33:33 GMT cph Exp $
  568. The new $ Header $ line would be used by RCS to keep track of the
  569. versions of your port and the others could be used to find updates to
  570. the originals that would make updating your port easier.
  571.     4.1. Compiler building files:
  572. * comp.pkg:
  573.     This file describes the Scheme package structure of the
  574. compiler, the files loaded into each package, and what names are
  575. exported and imported from each package.
  576.     To write this file, copy the similar file from an existing
  577. port, change the name of the port (i.e. mips -> sparc), and add or
  578. remove files as appropriate.  You should only need to add or remove
  579. assembler and LAPGEN files.
  580. * comp.cbf:
  581.     This file is a script that can be used to compile the compiler
  582. from scratch.  You can copy this file from another port, and change
  583. the port name.  There is more information in a later section about how
  584. to build the compiler.
  585. * comp.sf:
  586.     This file is a script that is used to pre-process the compiler
  587. sources before they are loaded to be interpreted or compiled.  You
  588. should be able to copy the file from an existing port and replace the
  589. name of the port.  You should also edit the names of the instruction
  590. files in the assembler instruction database section, although this
  591. section is no longer used by default.
  592. The previous three files should be copied or linked to the top-level
  593. compiler directory.  I.E., compiler/comp.pkg should be a link (symbolic
  594. preferably) or copy of compiler/machines/port/comp.pkg .
  595. * comp.con, comp.ldr, comp.bcon, and comp.bldr:
  596.     These files are generated by the CREF subsystem from the
  597. information in the cref.pkg file.  The .bcon and .bldr files are
  598. binary versions of the others, which are scheme sources.  The .con
  599. file contains the ``connectivity code'', that is, the code to create and
  600. link the package objects specified in the .pkg file.  The .ldr file
  601. contains the ``loading code'', that is, the code to load the source
  602. files into the appropriate packages and, in theory, to initialize the
  603. packages.  The CREF subsystem also generates a comp.cref file that
  604. includes cross-reference information.  It is useful to examine this
  605. file to find unbound references (often typos).
  606. * make.scm:
  607.     This file is used to load the compiler on top of a runtime
  608. system that has the file syntaxer (SF) loaded, and defines the version
  609. of the compiler.  The list of files does not appear here because the
  610. comp.pkg already declares them, CREF will build the comp.con and
  611. comp.ldr files that contain this information and will be loaded by
  612. make.scm.
  613. * decls.scm:
  614.     This file defines the pre-processing dependencies between the
  615. various source files.  There are three kinds of pre-processing
  616. dependencies:
  617.   - Syntactic: Different files need to be processed in different syntax
  618. tables that define the macros used by the files.
  619.   - Integrations: Different files import integrable (inline) definitions
  620. from other files, and must be processed in the right sequence in order
  621. to obtain the maximum effect from the integrations (mostly because of
  622. transitive steps).
  623.   - Expansions: Certain procedures can be expanded at compiler
  624. pre-processing time into accumulations of simpler calls.  This is how
  625. the assembly language in the LAPGEN rules can be translated into bits
  626. at compiler pre-processing time.  The files that define the
  627. pre-processing-time expansion functions must be loaded in order to
  628. process those files that use the procedures that can be expanded.
  629. decls.scm builds a database of the dependencies.  This database is
  630. topologically sorted by some of the code in decls.scm itself in order
  631. to determine the processing order.  Since there are circularities in
  632. the integration dependencies, some of the files are processed multiple
  633. times, but the mechanism in decls takes care of doing this correctly.
  634. You should be able to edit the version from another port in the
  635. appropriate way.  Mostly you will need to rename the port (i.e. mips
  636. -> sparc), and add/delete instruction and rule files as needed.
  637.  ==> decls.scm should probably be split into two sections: The
  638. machine-independent dependency management code, and the actual
  639. declaration of the dependencies for each port.  This would allow us to
  640. share more of the code, and make the task of rewriting it less
  641. daunting.
  642.     4.2. Miscellaneous files:
  643. * rgspcm.scm:
  644.     This file declares a set of primitives that can be coded by
  645. invoking runtime library procedures.  This file is no longer machine
  646. dependent, since the portable library has made all the sets identical.
  647. It lives in machines/port for historical reasons, and should probably
  648. move elsewhere.  Obviously, you can just copy it from another port.
  649.  ==> Let's move it or get rid of it!
  650. * rulrew.scm:
  651.     This file defines the simplifier rules that allow more
  652. efficient use of the hardware's addressing modes and other
  653. capabilities.  The rules use the same syntax as the LAPGEN rules, but
  654. belong in the (rule) rewriting database.  Although these rules are
  655. machine-dependent, it should be straightforward to emulate what other
  656. ports have done in order to arrive at a working set.  Moreover, it is
  657. possible to start out with an empty set and only add them as
  658. inefficiencies are discovered in the output assembly language.  These
  659. rules manipulate RTL expressions by using the procedures defined in
  660. compiler/rtlbase/rtlty1.scm and compiler/rtlbase/rtlty2.scm.
  661. * lapopt.scm:
  662.     This file defines a LAP-level peephole optimizer.  Currently
  663. only used in the MIPS port to reduce the number of NOPs in the ``delay
  664. slots'' of load instructions.  The instructions in each LAP-level
  665. basic block are passed to optimize-linear-lap, which outputs the new
  666. sequence of instructions corresponding to the basic block.  Currently
  667. all ports (except the MIPS port) implement this procedure as the
  668. identity procedure.
  669. * machin.scm:
  670.     This file defines architecture and port parameters needed by
  671. various parts of the compiler.  The following is the current list of
  672. the primary parameters.  The definitions of derived parameters not
  673. mentioned here should be copied verbatim from existing ports.  Some of
  674. these parameters are not currently in use, but should all be provided
  675. for completeness.
  676. - USE-PRE/POST-INCREMENT?: Should be true or false depending on
  677. whether the architecture has addressing modes that update the base
  678. address.  It is true on the MC68020, Vax, i386, and HP-PA, and false
  679. on the MIPS and Alpha.
  680. - ENDIANNESS: Should be the symbol LITTLE if an address, when used as
  681. a byte address, refers to the least significant byte of the long-word
  682. addressed by it.  It should be BIG if it refers to the most
  683. significant byte of the long-word.  The compiler has not been ported
  684. to any machines where the quantum of addressability is not an 8-bit
  685. byte, so the notion may not apply to those.
  686. - ADDRESSING-GRANULARITY: How many bits are addressed by the
  687. addressing quantum.  I.e., increasing an address by 1 will bump the
  688. address to point past this number of bits.  Again, the compiler has
  689. not been ported to any machine where this value is not 8.
  690. - SCHEME-OBJECT-WIDTH: How many bits are taken up by a Scheme object.
  691. This should be the number of bits in a C ``unsigned long'', since Scheme
  692. objects are declared as such by the portable runtime library.
  693. - SCHEME-TYPE-WIDTH: How many bits at the most-significant end of a
  694. Scheme object are taken up by the type tag.  The value of
  695. TYPE_CODE_LENGTH in the microcode must match this value.  The value is
  696. currently 6 for systems with a compiler and 8 for systems without one.
  697. - ADDRESS-UNITS-PER-PACKED-CHAR: This parameter defines how much to
  698. increment an address by in order to make it point to the next
  699. character in a string.  The compiler has not been ported to any
  700. configuration where this is not 1, but may be if 16-bit characters are
  701. used in the future.
  702. - FLONUM-SIZE: This is the ceiling of the ratio of the size of a C
  703. ``double'' to the size of a C ``unsigned long''.  It reflects how many
  704. Scheme units of memory (measured in Scheme objects) the data in a
  705. Scheme floating point object will take.
  706. - FLOAT-ALIGNMENT: This value defines the bit-alignment constraints
  707. for a C ``double''.  It must be a multiple of scheme-object-width.  If
  708. floating point values can only be stored at even long-word addresses,
  709. for example, this value should be twice scheme-object-width.
  710. - SIGNED-FIXNUM/UPPER-LIMIT: This parameter should be derived from
  711. others, but is specified as a constant due to a shortcoming of the
  712. compiler pre-processing system (EXPT is not constant-folded).  Use the
  713. commented-out expression to derive the value for your port.  All
  714. values that should be derived but are instead specified as constants
  715. are tagged by a comment containing ``***''.
  716. - STACK->MEMORY-OFFSET: This procedure is provided to accommodate
  717. stacks that grow in either direction, but we have not tested any port
  718. in which the stack grows towards larger addresses, because the CScheme
  719. interpreter imposes its own direction of growth.  It should probably
  720. be copied verbatim.
  721. - EXECUTE-CACHE-SIZE: This should match EXECUTE_CACHE_ENTRY_SIZE in
  722. microcode/cmpint-port.h, and is explained in cmpint.txt.
  723.  ==> We should probably rename one or the other to be alike.
  724. The following parameters describe to the front-end the format of
  725. closures containing multiple entry points.  Closures are described in
  726. some detail in cmpint.txt and in section 5.3.3.  Very briefly, a
  727. closure is a procedure object that contains a code pointer and a set
  728. of free variable locations or values.
  729. - CLOSURE-OBJECT-FIRST-OFFSET: This procedure takes a single argument,
  730. the number of entry points in a closure object, and computes the
  731. distance in long-words between the first long-word in the closure
  732. object, and the first long-word containing a free variable.  This is
  733. the number of long-words taken up by the closure object's header, and
  734. the code to represent N closure entry points.
  735. - CLOSURE-FIRST-OFFSET: This procedure takes two arguments, the number
  736. of entry points in a closure object, and the index of one of them, the
  737. first being zero.  It computes the distance between that entry's
  738. environment pointer and the first free variable in the closure object.
  739. The entry's environment pointer will be the address of the entry point
  740. itself if closure entry points are always aligned on long-word
  741. boundaries, or the address of the first entry point if they are not.
  742. - CLOSURE-ENTRY-DISTANCE: This procedure is given the number of entry
  743. points in a closure object, and the indices for two of its entry
  744. points, and computes the number of bytes that separate the two entry
  745. points in the closure object.  This distance should be a multiple of
  746. the parameter COMPILED_CLOSURE_ENTRY_SIZE described in cmpint.txt and
  747. defined in microcode/cmpint-port.h.
  748. - CLOSURE-ENVIRONMENT-ADJUSTMENT: This procedure takes two parameters,
  749. the number of entry points in a closure object, and the index of one
  750. of them.  It computes the number of bytes that must be added to the
  751. entry point's address to result in the entry point's environment
  752. pointer.  If entry points are always aligned on long-word boundaries,
  753. this number should always be zero, otherwise it should be the distance
  754. to the first (lowest addressed) entry point.
  755. The remaining code in machin.scm describes the register set of the
  756. architecture and defines the register conventions imposed by the port.
  757. These conventions must match the expectations of
  758. microcode/cmpaux-port.m4 described in cmpaux.txt.
  759. Machine registers are assigned a contiguous range of non-negative
  760. integers starting from zero.  Typically symbolic names are given to
  761. each of these integers for use in some of the rules, especially those
  762. dealing with the assembly language interface.
  763. - NUMBER-OF-MACHINE-REGISTERS should be the number of machine registers,
  764. i.e. one greater than the number assigned to the last machine register.
  765. - NUMBER-OF-TEMPORARY-REGISTERS is the number of reserved memory
  766. locations used for storing the contents of spilled pseudo-registers.
  767. Liar requires certain fixed locations to hold various implementation
  768. quantities such as the stack pointer, the heap (free memory) pointer,
  769. the pointer to the runtime library and interpreter's ``register''
  770. array, and the dynamic link ``register''.  Typically each of these
  771. locations is a fixed machine register.  In addition, a processor
  772. register is typically reserved for returned values and another for
  773. holding a bit-mask used to clear type tags from objects (the pointer
  774. or datum mask).  All of these registers should be given additional
  775. symbolic names.
  776.  ==> What is MACHINE-REGISTER-KNOWN-VALUE used for?  It would seem that
  777. the datum mask is a known value, but...  Currently all the ports seem
  778. to have the same definition.
  779. The contents of pseudo-registers are divided into various classes to
  780. allow some consistency checking.  Some machine registers always
  781. contain values in a fixed class (e.g. floating point registers and the
  782. register holding the datum mask).
  783. - MACHINE-REGISTER-VALUE-CLASS is a procedure that maps a register to
  784. its inherent value class.  The main value classes are
  785. value-class=object, value-class=address, and value-class=float.
  786. The registers allocated for the special implementation quantities have
  787. fixed value classes.  The remaining registers, managed by the
  788. compiler's register allocator, may be generic (value-class=word) or
  789. allow only certain values to be stored in them (value-class=float,
  790. value-class=address, etc.).
  791. Most of the remainder of compiler/machines/port/machin.scm is a set of
  792. procedures that return and compare the port's chosen locations for
  793. various operations.  Some of these operations are no longer used by
  794. the compiler, and reflect a previous reliance on the interpreter to
  795. accomplish certain environment operations.  These operations are now
  796. handled by invoking the appropriate primitives rather than using
  797. special entry points in the runtime library for them.  Under some
  798. compiler switch settings the older methods for handling these
  799. operations can be re-activated, but this never worked completely, and
  800. may no longer work at all.
  801. - RTL:MACHINE-REGISTER? should return a machine register for those
  802. special RTL registers that have been allocated to fixed registers, and
  803. false otherwise.
  804. - RTL:INTERPRETER-REGISTER? should return the long-word offset in the
  805. runtime library's memory ``register'' array for those special RTL
  806. registers not allocated to fixed registers, and false otherwise.
  807. - RTL:INTERPRETER-REGISTER->OFFSET errors when the special RTL
  808. register has not been allocated to a fixed register, and otherwise
  809. returns the long-word offset into the register  array.
  810. - RTL:CONSTANT-COST is a procedure that computes some metric of how
  811. expensive is to generate a particular constant.  If the constant is
  812. cheaply reconstructed, the register allocator may decide to flush it
  813. (rather than spill it to memory) and re-generate it the next time it
  814. is needed.  The best estimate is the number of cycles that
  815. constructing the constant would take, but the number of bytes of
  816. instructions can be used instead.
  817. - COMPILER:OPEN-CODE-FLOATING-POINT-ARITHMETIC? and
  818. COMPILER:PRIMITIVES-WITH-NO-OPEN-CODING have been described in the
  819. section on compiler switches and parameters.
  820.     4.3. LAPGEN files:
  821. The following files control the RTL -> LAP translation.  They define
  822. the rules used by the pattern matcher to perform the translation, and
  823. procedures used by the register allocator and linearizer to connect
  824. the code that results from each rule.  The rules, and how to write
  825. them, are described further in a later section.
  826. The rule set is partitioned into multiple subsets.  This is not
  827. necessary, but makes re-compiling the compiler faster and reduces the
  828. memory requirements of the compiler.  The partition can be done in a
  829. different way, but is probably best left as uniform as possible
  830. between the different ports to facilitate comparison and updating.
  831. The LAPGEN (RTL->LAP) rules are separated into two different data
  832. bases.  The larger is the statement data base, used to translate whole
  833. RTL instructions.  The smaller is the predicate data base, used to
  834. translate decisions to branch between the RTL basic blocks.
  835. * lapgen.scm:
  836.     This file does not define any rules, but provides a set of
  837. utilities for the back end.  It provides utilities for the rules,
  838. typically procedures for generating code that manipulates the object
  839. representation, additional entry points to the register allocator that
  840. are better suited to the port, and the interface procedures for the
  841. register allocator and the linearizer.
  842. The following definitions constitute the register allocator interface
  843. and must be provided by lapgen.scm:
  844. - AVAILABLE-MACHINE-REGISTERS is a list of the RTL register numbers
  845. corresponding to those registers that the register allocator should
  846. manage.  This should include all machine registers except those
  847. reserved by the port.
  848. - SORT-MACHINE-REGISTERS is a procedure that reorders a list of
  849. registers into the preferred allocation order.
  850.  ==> Is this right?
  851. - REGISTER-TYPE is a procedure that maps RTL register numbers to their
  852. inherent register types (typically GENERAL and FLOAT).
  853. - REGISTER-TYPES-COMPATIBLE? is a boolean procedure that decides
  854. whether two registers can hold the same range of values.
  855. - REGISTER-REFERENCE maps RTL register numbers into register
  856. references, i.e. pieces of assembly language used to refer to those
  857. registers.
  858. - REGISTER->REGISTER-TRANSFER issues code to copy the contents of one
  859. RTL register into another.
  860. - REFERENCE->REGISTER-TRANSFER issues code to copy the contents of a
  861. machine register described by its reference into a given RTL register.
  862. - PSEUDO-REGISTER-HOME maps RTL registers to a fragment of assembly
  863. language used to refer to the memory location into which they will be
  864. spilled if necessary.  This is typically a location (or set of
  865. locations) in the Scheme ``register'' array.
  866. - HOME->REGISTER-TRANSFER generates code that copies the contents of
  867. an RTL register's home (its spill location) into a machine register.
  868. - REGISTER->HOME-TRANSFER generates code that copies the contents of
  869. an RTL register, currently held in a machine register, into its memory
  870. home.
  871. The following definitions constitute the linearizer interface, and
  872. must be provided by lapgen.scm:
  873. - LAP:MAKE-LABEL-STATEMENT generates an assembly language directive
  874. that defines the specified label.
  875. - LAP:MAKE-UNCONDITIONAL-BRANCH generates a fragment of assembly
  876. language used to unconditionally transfer control to the specified
  877. label.
  878. - LAP:MAKE-ENTRY-POINT generates a fragment of assembly language used
  879. to precede the root of the control flow graph.  Its output should use
  880. the assembler directive ENTRY-POINT and generate format and GC words
  881. for the entry point.
  882. The rest of the code in lapgen.scm is a machine-specific set of utilities
  883. for the LAPGEN rules.  Some of the more common procedures are
  884. described in the section that covers the rules.
  885. Of special interest are the utility procedures for manipulating
  886. pc-relative addresses and loads on RISC machines.  RISC machines
  887. typically only have pc-relative branch instructions, but no
  888. pc-relative loads or pc-relative load-effective-address instructions.
  889. On the other hand, they usually have a branch-and-link instruction
  890. that performs a pc-relative branch and stores the return address in
  891. a processor register.  This instruction can be used (by branching to
  892. the next instruction) to obtain its own address, and pc-relative
  893. addresses and loads can use them.  The MIPS back end currently
  894. implements a simple pc-relative address caching scheme that attempts
  895. to reduce the number of such branches by re-using the values produced
  896. by previous branches if they are still available.  This code can be
  897. suitably modified to work on most RISC architectures.
  898. * rules1.scm:
  899.     This file contains RTL statement rules for simple register assignments
  900. and operations.  In particular, it contains the rules for constructing
  901. and destructuring Scheme objects, allocating storage, and memory <->
  902. register transfers.
  903. * rules2.scm:
  904.     This file contains RTL predicate rules for simple equality
  905. predicates (EQ-TEST, TYPE-TEST).
  906. * rules3.scm:
  907.     This file contains RTL statement rules for control-flow
  908. statements like continuation (return address) invocation, several
  909. mechanisms for invoking procedures, stack reformatting prior to
  910. invocation, procedure headers, closure object allocation, expression
  911. headers and declaring the data segment of compiled code blocks for
  912. assembly.  See [1] for some background information on stack
  913. reformatting, and [2] for a discussion of how calls to (the values of)
  914. free variables are handled by Liar.
  915. * rules4.scm:
  916.     This file contains RTL statement rules for runtime library
  917. routines that handle manipulation of variables in first class
  918. environments.  Many of these rules are no longer used by the compiler
  919. unless some switch settings are changed.  See [2] for a discussion of
  920. how Liar handles references to free variables.
  921. * rulfix.scm:
  922.     This file contains statement and predicate rules for
  923. manipulating fixnums (small integers represented in immediate
  924. form).  The rules handle tagging and de-tagging fixnum objects,
  925. arithmetic on them, comparison predicates, and overflow tests.
  926. * rulflo.scm:
  927.     This file contains statement and predicate rules for
  928. manipulating flonums (floating point data in boxed form).  The rules
  929. handle boxing and un-boxing of flonums, arithmetic on them, and
  930. comparison predicates.
  931.     4.4. Assembler files:
  932. * assmd.scm:
  933.     This file defines the following machine-dependent parameters
  934. and utilities for the bit-level assembler:
  935. - MAXIMUM-PADDING-LENGTH: If instructions are not always long-word
  936. aligned, the maximum distance in bits between the end of an
  937. instruction and the next (higher) long-word boundary.
  938. - PADDING-STRING: A bit-string used for padding the instruction block
  939. to a long-word boundary.  If possible, it should encode a HALT or
  940. ILLEGAL instruction.  The length of this bit-string should evenly
  941. divide maximum-padding-length.
  942. - BLOCK-OFFSET-WIDTH: This should be the size in bits of format_word
  943. described in cmpint.txt.  It should be 16 for all byte-addressed
  944. machines where registers hold 32 bits.
  945. - MAXIMUM-BLOCK-OFFSET: The maximum byte offset that can be encoded in
  946. block-offset-width bits.  This depends on the encoding described in
  947. cmpint.txt.  The least significant bit is always used to indicate
  948. whether this block offset points to the start of the object or to
  949. another block offset, so the range may be smaller than the obvious
  950. value.  Furthermore, if instruction alignment constraints are tighter
  951. than byte boundaries, this range may be larger.  For example, if
  952. instructions always start on even long-word boundaries, the bottom two
  953. bits (always zero) are encoded implicitly, and the range is
  954. accordingly larger.
  955. - BLOCK-OFFSET->BIT-STRING: This procedure is given a byte offset and
  956. a boolean flag indicating whether this is the offset to the start of a
  957. compiled code block or to another block-offset, and returns the
  958. encoded value of this offset.
  959. - MAKE-NMV-HEADER: This procedure is given the size in long-words of a
  960. block of instructions, and constructs the non-marked-vector header
  961. that must precede the instructions in memory in order to prevent the
  962. garbage collector from examining the data as Scheme objects.  This
  963. header is just an ``object'' whose type tag is manifest-nm-vector
  964. (TC_MANIFEST_NM_VECTOR in the microcode) and whose datum is the size
  965. in long-words (excluding the header itself).
  966. The following three parameters define how instruction fields are to be
  967. assembled in memory depending on the ``endianness'' (byte ordering) of
  968. the architecture.  You should be able to use the MC68020 (big endian)
  969. or the Vax (little endian) version, or the MIPS version which is
  970. conditionalized for both possibilities since MIPS processors can be
  971. configured either way.
  972. - INSTRUCTION-INSERT! is a procedure, that given a bit-string encoding
  973. instruction fields, a larger bit-string into which the smaller should
  974. be inserted, a position within the larger one, and a continuation,
  975. inserts the smaller bit-string into the larger at the specified
  976. position, and returns the new bit position at which the immediately
  977. following instruction field should be inserted.
  978. - INSTRUCTION-INITIAL-POSITION is a procedure, that given a bit-string
  979. representing a segment of compiled code, returns the bit-string
  980. position at which instruction-insert! should insert the first
  981. instruction.
  982. - INSTRUCTION-APPEND is a procedure, that given the bit-string
  983. encoding successive (fields of) instructions, produces the bit-string
  984. that corresponds to their concatenation in the correct order.
  985. * coerce.scm:
  986.     This file defines a set of coercion procedures.  These
  987. procedures are used to fill fields in instructions.  Each coercion
  988. procedure checks the range of its argument and produces a bit string
  989. of the appropriate length encoding the argument.  Most coercions will
  990. coerce their signed or unsigned argument into a bit string of the
  991. required fixed length.  On some machines (e.g. HP PA), some coercions
  992. may permute the bits appropriately.
  993. * insmac.scm:
  994.     This file defines machine-specific syntax used in the assembler,
  995. and the procedure PARSE-INSTRUCTION, invoked by the syntax expander
  996. for DEFINE-INSTRUCTION to parse the body of each of the instruction
  997. rules.  This code is typically complex and you are encouraged to
  998. emulate one of the existing ports in order to reuse its code.
  999. The following ports use the following syntax for describing
  1000. instructions in machine language:
  1001. - Spectrum and MIPS:
  1002.     (LONG (<width 1> <value 1> <coercion type 1>)
  1003.       (<width 2> <value 2> <coercion type 2>)
  1004.       ...    
  1005.       (<width n> <value n> <coercion type n>))
  1006. where all the widths must add up to an even multiple of 32.
  1007. - Vax:
  1008. Instruction descriptions are made of arbitrary sequences of the
  1009. following field descriptors:
  1010.     (BYTE (<width 1> <value 1> <coercion type 1>)
  1011.       (<width 2> <value 2> <coercion type 2>)
  1012.       ...    
  1013.       (<width n> <value n> <coercion type n>))
  1014.     (OPERAND <size> <value>)
  1015.     (DISPLACEMENT (<width> <value>))
  1016. The total width of each of these field descriptors must add up to a
  1017. multiple of 8.
  1018. BYTE is used primarily for instruction opcodes.
  1019. OPERAND is used for general addressing modes.
  1020. DISPLACEMENT is used for PC-relative branch displacements.
  1021. - MC68020:
  1022.     (WORD (<width 1> <value 1> <coercion type 1> <size 1>)
  1023.       (<width 2> <value 2> <coercion type 2> <size 2>)
  1024.       ...    
  1025.       (<width n> <value n> <coercion type n> <size 3>))
  1026. where all the widths must add up to an even multiple of 16.
  1027. Size refers to immediate operands to be encoded in the instruction,
  1028. and are omitted when irrelevant.
  1029. A missing coercion type means that the ordinary unsigned coercion (for
  1030. the corresponding number of bits) should be used.
  1031. Additionally, each of these ports provides a syntax for specifying
  1032. instructions whose final format must be determined by the
  1033. branch-tensioning algorithm in the bit assembler.  The syntax of these
  1034. instructions is usually
  1035.     (VARIABLE-WIDTH (<name> <expression>)
  1036.       ((<low-1> <high-1>)
  1037.        <instruction-specifier-1>)
  1038.       ((<low-2> <high-2>)
  1039.        <instruction-specifier-2>)
  1040.       ...
  1041.       ((() ())
  1042.        <instruction-specifier-n>))
  1043. Each instruction specifier is an ordinary (i.e. not VARIABLE-WIDTH)
  1044. instruction specifier.  NAME is a variable to be bound to the
  1045. bit-assembly-time value of EXPRESSION.  Each of the ranges
  1046. <low-1>-<high-1> <low-2>-<high-2>, etc. must be properly nested in the
  1047. next, and () specifies no bound.  The final format chosen is that
  1048. corresponding to the lowest numbered range containing the value of
  1049. <expression>.  Successive instruction specifiers must yield
  1050. instructions of non-decreasing lengths for the branch tensioner to
  1051. work correctly.  The MC68020 port uses GROWING-WORD instead of
  1052. VARIABLE-WIDTH as the keyword for this syntax.
  1053.  ==> This should probably be changed.
  1054. * inerly.scm:
  1055.     This file provides alternative expanders for the
  1056. machine-specific syntax.  These alternative expanders are used when
  1057. the assembly language that appears in the LAPGEN rules is assembled
  1058. (early) at compiler pre-processing time.  That is, the procedures
  1059. defined in this file are only used if
  1060. COMPILER:ENABLE-EXPANSION-DECLARATIONS? is set to true.  If you reuse
  1061. the code in insmac.scm from another port, you should be able to reuse
  1062. the inerly.scm file from the same port.  Alternatively, you can write
  1063. a dummy version of this code and require
  1064. COMPILER:ENABLE-EXPANSION-DECLARATIONS? to be always false.  This
  1065. switch defaults to false, currently.  The Spectrum and MIPS versions
  1066. currently have dummy versions of this code.
  1067. * insutl.scm:
  1068.     This file defines machine-specific rule qualifiers and
  1069. transformers.  It is often used to define addressing-mode filters and
  1070. handling procedures for architectures with general addressing modes.
  1071. This file does not exist in the Spectrum port because all the relevant
  1072. code has been placed in instr1.scm, and the MIPS port has no
  1073. machine-specific qualifiers and transformers.  Qualifiers and
  1074. transformers are described further in the chapter on the syntax of
  1075. translation rules.
  1076. * instr<n>.scm:
  1077.     These files define the instruction set of the architecture by
  1078. using the syntax defined in insmac.scm and inerly.scm.  There can be
  1079. as many of these files or as few as desired by whoever writes the
  1080. assembler.  They are usually split according to the size of the files
  1081. or along the divisions in the architecture manual.  Not all
  1082. instructions in the architecture need to be listed here -- only those
  1083. actually used by the back end in the LAPGEN rules and utility procedures.
  1084. Privileged/supervisory instructions, BCD (binary coded decimal)
  1085. instructions, COBOL-style EDIT instructions, etc., can probably be
  1086. safely ignored.
  1087.     4.5. Disassembler files:
  1088.     The disassembler is almost completely machine dependent.  For
  1089. many machines, a reasonable disassembler could be derived from the
  1090. description of the instruction set used to assemble programs.  The Vax
  1091. disassembler, is essentially constructed this way.  Unfortunately this
  1092. has not been generalized, and currently each port has its own
  1093. disassembler, often duplicating information contained in the
  1094. assembler.
  1095. The disassembler is not necessary for the operation of the compiler
  1096. proper.  It is, however, a good debugging tool.  You can bring the
  1097. compiler up without a disassembler by providing stubs for the
  1098. procedures referenced in dassm2.
  1099. * dassm1.scm:
  1100.     This file contains the top-level of the disassembler.  It is
  1101. not machine-dependent, and should probably be moved to another directory.
  1102.  ==> Is compiler/back the right place for this?
  1103. * dassm2.scm:
  1104.     This file contains various utilities for the disassembler.  In
  1105. particular, it contains the definitions of
  1106. - COMPILED-CODE-BLOCK/BYTES-PER-OBJECT
  1107. - COMPILED-CODE-BLOCK/OBJECTS-PER-PROCEDURE-CACHE
  1108. - COMPILED-CODE-BLOCK/OBJECTS-PER-VARIABLE-CACHE
  1109.   These parameters specify various relative sizes.
  1110.  ==> Shouldn't these be in machin.scm?  The first two have
  1111. counterparts there, and the last is always 1.
  1112. - DISASSEMBLER/READ-VARIABLE-CACHE
  1113. - DISASSEMBLER/READ-PROCEDURE-CACHE
  1114.   These procedures are used to extract free variable information from
  1115. a linked compiled code block.  Variable caches are maintained as
  1116. native addresses (i.e. no tag bits), and procedure (execute) caches
  1117. contain absolute jump instructions that must be decoded to extract the
  1118. address of the called procedure.  Appropriate type bits must be added
  1119. to both values before they are returned.
  1120. This file also contains a state machine that allows the disassembler
  1121. to display data appearing in the instruction stream in an appropriate
  1122. format (gc and format words, mainly), and heuristics for displaying
  1123. addressing modes and PC-relative offsets in a more legible form.
  1124. The output of the disassembler need not be identical to the input of
  1125. the assembler.  The disassembler is used almost exclusively for
  1126. debugging, and additional syntactic hints make it easier to read.
  1127. * dassm3.scm:
  1128.     This file contains the code to disassemble one instruction at
  1129. a time.  It is completely machine dependent at the time, and any old
  1130. way of doing it is fine.
  1131. * dinstr<n>.scm:
  1132.     In the VAX port, these are copies (or links) to the
  1133. instr<n>.scm files.  They are processed with a different syntax table
  1134. to construct the disassembler tables instead of the assembler tables.
  1135. * dsyn.scm:
  1136.     In the VAX port, this file provides the alternative expansion
  1137. of DEFINE-INSTRUCTION used to construct the disassembler tables
  1138. instead of the assembler rule data base.
  1139.         5. All about rules
  1140. There are three subsystems in Liar that use rule-based languages.
  1141. They are the RTL simplifier, LAPGEN (RTL->LAP translation), and the
  1142. assembler.  The assembler need not be rule-based, but given the
  1143. availability of the rule language, using the rule mechanism may be the
  1144. easiest way to write it.
  1145.     5.1. Rule syntax
  1146. The assembler rules use a somewhat different syntax from the rest and
  1147. will be described later.
  1148. The rest of the rules are defined in the following way:
  1149.     (DEFINE-RULE <rule-database>
  1150.       <rule pattern>
  1151.       <qualifier>                ; optional
  1152.       <rule body>)
  1153. * <rule-database> is an expression evaluating to a rule database.  
  1154. It should be one of STATEMENT, PREDICATE, or REWRITING.
  1155. * <rule pattern> is a list that represents the pattern to match.
  1156. Variables in the pattern are written by using the ``?'' syntax.
  1157. For example,
  1158. - (hello) matches the constant list (hello)
  1159. - (? thing) matches anything, and THING is bound in <qualifier> and
  1160. <rule body> to whatever was matched.
  1161. - (hello (? person)) matches a list of two elements whose first
  1162. element is the symbol HELLO, and whose second element can be anything.
  1163. The variable PERSON will be bound in <qualifier> and <rule body> and
  1164. will have as its value the second element of the list matched.
  1165. Thus it would match (hello bill) and PERSON would be the symbol BILL,
  1166. (hello (bill rozas)) would match and PERSON would be the list (BILL ROZAS).
  1167. - (hello . (? person)) matches a list of one or more elements whose
  1168. first element is the symbol HELLO.  PERSON is bound to the rest of the
  1169. list.
  1170. Thus (hello my dog likes frankfurters) would match and PERSON would be
  1171. (MY DOG LIKES FRANKFURTERS).  (hello (my dog)) would match, and PERSON
  1172. would be ((MY DOG)).
  1173. Variable syntax is further described below.
  1174. * <qualifier> is (QUALIFIER <expression>) where <expression> evaluates
  1175. to a boolean and further filters matches.  If the qualifier expression
  1176. evaluates to false, the rule is not fired.  Otherwise it is.
  1177. For example,
  1178.     (DEFINE-RULE <some database>
  1179.       (multiple (? number) (? divisor))
  1180.       (QUALIFIER (and (number? number)
  1181.               (number? divisor)
  1182.               (zero? (remainder number divisor))))
  1183.       <rule body>)
  1184. will match (MULTIPLE 14 7) and (MULTIPLE 36 4), but will not match
  1185. (MULTIPLE FOO 3), (MULTIPLE 37 4), (MULTIPLE 2), (MULTIPLE 14 2 3),
  1186. nor (HELLO 14 7).
  1187. Rule qualifiers are optional.
  1188. * <rule body> is an arbitrary Lisp expression whose value is the
  1189. translation determined by the rule.  It will typically use the
  1190. variables bound by ``?'' to perform the translation.  The statement
  1191. and predicate rules use the LAP macro to generate sequences of
  1192. assembly language instructions.
  1193. The assembler rules use the following syntax:
  1194.     (DEFINE-INSTRUCTION <opcode>
  1195.       (<pattern1> <qualifier1> <body1>)
  1196.       (<pattern2> <qualifier2> <body2>)
  1197.       ...
  1198.       )
  1199. Where <opcode> is the name of the instruction, and the patterns will
  1200. be matched against the cdr of lists whose car is <opcode>.  
  1201. The <patterns>, <qualifiers>, and <bodies> are as in the RTL rules,
  1202. except that there are typically no qualifiers, and the bodies are
  1203. typically written in a special syntax defined in
  1204. compiler/machines/port/insmac.scm and described in section 4.4.
  1205. For example,
  1206.     (DEFINE-INSTRUCTION ADD
  1207.       (((R (? target)) (R (? reg1)) (R (? reg2)))
  1208.        (WORD (6 #x24)
  1209.          (5 target)
  1210.          (5 reg1)
  1211.          (5 reg2)
  1212.          (11 0)))
  1213.       (((R (? target)) (R (? reg)) (& (? constant)))
  1214.        (WORD (6 #x23)
  1215.          (5 target)
  1216.          (5 reg)
  1217.          (16 constant SIGNED))))
  1218. would match (ADD (R 1) (R 2) (R 3)) and (ADD (R 7) (R 22) (& 257)),
  1219. firing the corresponding body.
  1220. The bodies are defined in terms of the WORD syntax defined in
  1221. insmac.scm, and the ``commas'' used with the pattern variables in the
  1222. rule bodies are a consequence of the WORD syntax.  The meaning of the
  1223. commas is identical to the meaning of the commas in a ``backquote''
  1224. Scheme expression, and is briefly described in section 5.3.1.
  1225.     5.2. Rule variable syntax.
  1226. Although qualifiers and the simple variable syntax shown are
  1227. sufficient, some additional variable syntax is available for common
  1228. patterns.  Moreover, the early matcher (used when
  1229. COMPILER:ENABLE-EXPANSION-DECLARATIONS? is true) cannot currently
  1230. handle qualifiers but can handle the additional variable syntax that
  1231. can supplant most qualifiers.  The early matcher is used only on the
  1232. assembler rules, so if you want to use it, you only need to use the
  1233. restricted language when writing those rules.
  1234. The complete variable syntax is as follows:
  1235. * (? <name>)  This syntax matches anything in that position of the
  1236. potential instance, and binds <name> to the sub-structure matched.
  1237. * (? <name> <transform>) This syntax matches anything in that position
  1238. of the potential instance as long as <transform> returns non-false on
  1239. the sub-structure matched.  <name> is bound to the result returned by
  1240. <transform>.  For example,
  1241.     (? q (lambda (obj) (and (number? obj) (* 2 obj))))
  1242. will match 2, and Q will be bound to 4, but will not match FOO.
  1243. * (? <name1> <transform> <name2>)  <name1> and <transform> have the same
  1244. meaning as in the previous syntax, and this syntax matches exactly the
  1245. same objects, but provides the additional convenience of binding
  1246. <name2> to the sub-structure matched, before the transformation.
  1247. For example,
  1248.     (? q (lambda (obj)
  1249.        (and (pair? obj) 
  1250.         (number? (car obj))
  1251.         (- (car obj) 23)))
  1252.        z)
  1253. will match (2 . HELLO), Q will be bound to -21, and Z will be bound to
  1254. (2 . HELLO), and will not match 34 or (HELLO . 2).
  1255.  ==> The pattern parser seems to understand (?@ <name>) as well, but
  1256. this syntax is used nowhere.  The early parser does not understand it.
  1257. Should it be flushed?
  1258.     5.3. Writing statement rules.
  1259. Statement rules provide the translation between RTL instructions and
  1260. fragments of assembly language.  Most RTL instructions are
  1261. assignments, where an RTL register is written with the contents of a
  1262. virtual location or the result of some operation.
  1263.     5.3.1. Output of the statement rules
  1264. The output of the statement rules is a fragment of assembly language
  1265. written in the syntax expected by the LAP assembler.  The fragments,
  1266. containing any number of machine instructions, are constructed by
  1267. using the LAP macro, built on top of Scheme's QUASIQUOTE (back-quote).
  1268. Within a LAP form, you can use UNQUOTE (comma) and UNQUOTE-SPLICING
  1269. (comma at-sign) to tag subexpressions that should be evaluated and
  1270. appended.  For example,
  1271.     (LAP (MOV L ,r1 ,r2)
  1272.      (ADD L ,r3 ,r2))
  1273. constructs a fragment with two instructions in it where the values of
  1274. r1, r2, and r3 are substituted in the instructions.
  1275. The code
  1276.     (LAP (MOV L ,r1 ,r2)
  1277.      ,@(generate-test r2))
  1278. constructs a fragment whose first instruction is a MOV instruction,
  1279. and the rest is the fragment returned by generate-test.
  1280. The INST macro is similar to LAP but constructs a single instruction.
  1281. It should not be used unless necessary (i.e. in
  1282. LAP:MAKE-LABEL-STATEMENT), since you may find yourself later wanting
  1283. to change a single instruction into a fragment in a utility procedure,
  1284. and having to find every use of the procedure.
  1285.  ==> We should change the linearizer to expect
  1286. LAP:MAKE-LABEL-STATEMENT to return a fragment, and do away with INST.
  1287. An additional macro, INST-EA, is provided to construct a piece of
  1288. assembly language representing an addressing mode.  For example,
  1289. INST-EA is used by the following procedure in the Vax back-end:
  1290.     (define (non-pointer->ea type datum)
  1291.       (if (and (zero? type)
  1292.            (<= 0 datum 63))
  1293.       (INST-EA (S ,datum))
  1294.       (INST-EA (&U ,(make-non-pointer-literal type datum)))))
  1295. where non-pointer->ea may be used in
  1296.     (LAP (MOV L ,(non-pointer->ea <type> <datum>)
  1297.         ,(any-register-reference target)))
  1298. INST-EA is superfluous on machines without general addressing modes
  1299. (i.e. load-store architectures).
  1300. Each port provides a procedure, named REGISTER-REFERENCE, that maps
  1301. between RTL machine registers and the assembly language syntax used to
  1302. refer to the registers.  It uses INST-EA to build such references.
  1303. The macros LAP, INST, and INST-EA, besides providing the functionality
  1304. of QUASIQUOTE, also provide a hook for the compiler pre-processing
  1305. time assembly of the code generated by the rules.
  1306.     5.3.2. Hardware register allocation
  1307. Hardware register allocation occurs during the RTL->LAP translation.
  1308. The rules, besides generating assembly language, invoke utilities
  1309. provided by the register allocator to reserve and free hardware
  1310. registers on which the operations can be performed.
  1311. Hardware registers are often divided into different non-overlapping
  1312. types that are used in different operations.  For example, modern
  1313. hardware typically has a set of integer registers and a set of
  1314. floating point registers.  Address operations typically require
  1315. operands in integer registers, while floating point operations
  1316. typically require floating point registers.  On some machines, notably
  1317. the Motorola 68K family, the integer register set is further
  1318. subdivided into types with specific operations (address and data).
  1319. The register allocator manipulates RTL registers.  RTL registers are
  1320. just small integers.  The low end of the valid range of RTL registers
  1321. is used to represent the physical registers of the processor (called
  1322. machine registers), and the rest of the numbers represent virtual
  1323. (pseudo) registers.  The core allocator operations are given an RTL
  1324. register number and a register type, and return a suitable machine
  1325. register to be used for the operation.
  1326. A machine register that holds the value of a pseudo register is called
  1327. an ``alias'' for the pseudo register.  A pseudo register may have many
  1328. valid aliases simultaneously, usually of different types.  Any
  1329. assignment to the pseudo register will invalidate all aliases but one,
  1330. namely the machine register actually written, rather than copy the new
  1331. value into all the previous aliases.  Thus source references and
  1332. destination references have different effects, and are handled by
  1333. different procedures in the register allocator.
  1334. Pseudo registers have associated homes, memory locations that hold
  1335. their values when the machine registers are needed for other purposes.
  1336. Most pseudo registers are never written to their homes, since a pseudo
  1337. register's value is usually kept in machine register aliases until the
  1338. pseudo register is dead, i.e. until its value is no longer needed.  A
  1339. pseudo register's aliases can be reused for other purposes if there
  1340. are other remaining aliases or this is the last reference to the
  1341. pseudo register.  An alias that can be reused is a ``reusable'' alias.
  1342. Occasionally, the value of a pseudo register may be transferred to the
  1343. register's home and the last alias invalidated, if the register
  1344. allocator is running out of registers.  This is called ``spilling'' a
  1345. register.
  1346. The register allocator maintains a table of associations, called the
  1347. ``register map'', that associates each pseudo register with its valid
  1348. aliases, and each machine register with the pseudo register whose
  1349. value it holds (if any).  The register allocator routines modify the
  1350. register map after aliases are requested and invalidated, and they
  1351. generate assembly language instructions to perform the necessary data
  1352. motion for spilling and re-loading at run time.  These instructions
  1353. are usually inserted before the code output of the RTL rule in
  1354. execution.
  1355. If you have chosen your RTL register numbers for machine registers so
  1356. that they match the hardware numbers, and your assembly language does
  1357. not distinguish between references to a register and other fields, you
  1358. can ignore register references and use the RTL register numbers
  1359. directly.  This is commonly the case when using integer registers in
  1360. load-store architectures.
  1361. As a convenience, the register allocator also provides operations that
  1362. manipulate register references.  A register reference is a fragment of
  1363. assembly language, typically a register addressing mode for general
  1364. register machines, that when inserted into a LAP instruction, denotes
  1365. the appropriate register.  For example, on the Motorola MC68020,
  1366. physical register A3 is represented as RTL register number 11, and a
  1367. register reference for it would be ``(A 3)''.  RTL pseudo register 44
  1368. may at some point have RTL machine register 11 as its only
  1369. address-register alias.  At that time, (REGISTER-ALIAS 44 'ADDRESS)
  1370. would return 11.
  1371. The interface to the register allocator is defined in
  1372. compiler/back/lapgn2.scm.  Not all ports use all of the procedures
  1373. defined there.  Often a smaller subset is sufficient depending on
  1374. whether there are general addressing modes, etc.  A list of the most
  1375. frequently used follows:
  1376. * REGISTER-ALIAS expects an RTL register and a register type, and
  1377. returns a machine register of the specified type that is a valid alias
  1378. for that RTL register if there is one, or false if there is none.
  1379. This procedure should only be used for source operand RTL registers.
  1380. If the register type is false, then REGISTER-ALIAS will return any
  1381. valid alias.
  1382. * LOAD-ALIAS-REGISTER! is like REGISTER-ALIAS but always returns a
  1383. machine register, allocating one of the specified type if necessary.
  1384. This procedure should only be used for source operand RTL registers.
  1385. * REFERENCE-ALIAS-REGISTER! performs the same action as
  1386. LOAD-ALIAS-REGISTER! but returns a register reference instead of an
  1387. RTL register number.
  1388. * ALLOCATE-ALIAS-REGISTER! expects an RTL register and a register
  1389. type, and returns a machine register of the specified type that is the
  1390. only alias for the RTL register and should be written with the new
  1391. contents of the RTL register.  ALLOCATE-ALIAS-REGISTER! is used to
  1392. generate aliases for target RTL registers.
  1393. * REFERENCE-TARGET-ALIAS!  performs the same action as
  1394. ALLOCATE-ALIAS-REGISTER! but returns a register reference instead of
  1395. an RTL register number.  See CLEAR-REGISTERS! below.
  1396. * STANDARD-REGISTER-REFERENCE expects an RTL register, a register
  1397. type, and a boolean.  It will return a reference for an alias of the
  1398. specified register containing the current value of the RTL register.
  1399. This reference will be of the specified type if the boolean is false,
  1400. or sometimes of other types if the boolean is true.  In other words,
  1401. the boolean argument determines whether other types are acceptable,
  1402. although not desirable.  The register type may be false, specifying
  1403. that there really is no preference for the type, and any reference is
  1404. valid.  STANDARD-REGISTER-REFERENCE should be used only for source
  1405. operands (i.e. those that already contain data), and may return a
  1406. memory reference for those machines with general addressing modes if
  1407. there is no preferred type and alternates are acceptable.
  1408. * MOVE-TO-ALIAS-REGISTER! expects a source RTL register, a register
  1409. type, and a target RTL register.  It returns a new alias for the
  1410. target of the specified type containing a copy of the current contents
  1411. of the source.  Often this is accomplished by choosing an alias of the
  1412. source that already contains the correct data and making it the only
  1413. alias for target.  MOVE-TO-ALIAS-REGISTER! attempts to reuse an alias
  1414. for the source register.
  1415. * MOVE-TO-TEMPORARY-REGISTER! expects a source RTL register and a
  1416. register type and returns an appropriate register containing a copy of
  1417. the source.  The register is intended for temporary use, that is, use
  1418. only within the code generated by the expansion of the current RTL
  1419. instruction, and as such it should not be permanently recorded in the
  1420. register map.  The register becomes automatically freed for subsequent
  1421. RTL instructions.  MOVE-TO-TEMPORARY-REGISTER! attempts to reuse an
  1422. alias for the source register.
  1423. * REUSE-PSEUDO-REGISTER-ALIAS! expects an RTL register, a register
  1424. type, and two procedures.  It attempts to find a reusable alias for
  1425. the RTL register of the specified type, and invokes the first
  1426. procedure giving it the alias if it succeeds, or the second procedure
  1427. with no arguments if it fails.  MOVE-TO-ALIAS-REGISTER!  and
  1428. MOVE-TO-TEMPORARY-REGISTER! use REUSE-PSEUDO-REGISTER-ALIAS! but
  1429. occasionally neither meets the requirements.
  1430. * NEED-REGISTER! expects an RTL machine register and informs the
  1431. register allocator that the rule in use requires that register so it
  1432. should not be available for subsequent requests while translating the
  1433. current RTL instruction.  The register is available for later RTL
  1434. instructions unless the relevant rules invoke NEED-REGISTER! again.
  1435. The procedures described above that allocate and assign aliases and
  1436. temporary registers call NEED-REGISTER! behind the scenes, but you will
  1437. need to invoke it explicitly when calling out-of-line routines.
  1438. * LOAD-MACHINE-REGISTER! expects an RTL register and an RTL machine
  1439. register and generates code that copies the current value of the RTL
  1440. register to the machine register.  It is used to pass arguments in
  1441. fixed registers to out-of-line code, typically in the compiled code
  1442. runtime library.
  1443. * ADD-PSEUDO-REGISTER-ALIAS! expects an RTL pseudo-register and an
  1444. available machine register (no longer an alias), and makes the
  1445. specified machine register an alias for the pseudo-register.
  1446. * CLEAR-REGISTERS! expects any number of RTL registers and clears them
  1447. from the register map, preserving their current contents in memory if
  1448. needed.  It returns the code that will perform the required motion at
  1449. runtime.  It should be used before invoking LOAD-MACHINE-REGISTER! to
  1450. ensure that the potentially valid previous contents of the machine
  1451. register have been saved.
  1452. * CLEAR-MAP! deletes all aliases from the register map, pushing the
  1453. data only held in aliases into the memory homes if needed.  This
  1454. procedure returns an assembly language code fragment, and is typically
  1455. used before invoking out-of-line code.
  1456. * DELETE-DEAD-REGISTERS! informs the register allocator that RTL
  1457. pseudo registers whose contents will not be needed after the current
  1458. RTL instruction can be eliminated from the register map and their
  1459. aliases subsequently used for other purposes.
  1460. Most of the rules are actually written in terms of machine-specific
  1461. procedures that invoke the procedures listed above in fixed ways.
  1462. Rule bodies typically match the following code pattern:
  1463.     (let* ((rs1 (standard-source source1))
  1464.        (rs2 (standard-source source2))
  1465.        (rt (standard-target target)))
  1466.       (LAP ...))
  1467. where STANDARD-SOURCE and STANDARD-TARGET are machine-specific
  1468. procedures.  The reason for the use of LET* (instead of LET) is given
  1469. below.
  1470. On a machine with general addressing modes and memory operands, we
  1471. might provide their definitions as follows:
  1472.     (define (standard-source rtl-reg)
  1473.       (standard-register-reference rtl-reg 'GENERAL true))
  1474.     (define (standard-target rtl-reg)
  1475.       (delete-dead-registers!)
  1476.       (reference-target-alias! rtl-reg 'GENERAL))
  1477. while on a load-store architecture we might define them as follows:
  1478.     (define (standard-source rtl-reg)
  1479.       (load-alias-register! rtl-reg 'GENERAL))
  1480.     (define (standard-target rtl-reg)
  1481.       (delete-dead-registers!)
  1482.       (allocate-alias-register! rtl-reg 'GENERAL))
  1483.         - VERY IMPORTANT: -
  1484. This example brings up the cardinal rule of RTL assignments: 
  1485.     Any rule that writes into an RTL pseudo-register MUST invoke
  1486.     DELETE-DEAD-REGISTERS! after allocating aliases for the necessary
  1487.     sources but before allocating an alias for the target.
  1488. If this is not done, the register allocator may decide to spill
  1489. no-longer valid data into memory, which will probably make the
  1490. compiler get confused in other ways or cause garbage collection
  1491. problems later.  If it is done too early, the last valid alias for a
  1492. source operand may have been reused in the interim, and the compiler
  1493. will assume that the source quantity is contained in memory and will
  1494. often generate code that fetches and operates on garbage.
  1495. The example above uses LET* instead of LET.  LET would not work in the
  1496. above example because Scheme does not specify the order of argument
  1497. evaluation, and Liar chooses arbitrary orders, so the
  1498. DELETE-DEAD-REGISTERS! implicit in STANDARD-TARGET might be called too
  1499. early possibly causing STANDARD-SOURCE to fail.
  1500. MOVE-TO-ALIAS-REGISTER! invokes DELETE-DEAD-REGISTERS! because it
  1501. simultaneously allocates an alias for a source and for a target.
  1502. Thus, if there are other source operands, their aliases must be
  1503. allocated before MOVE-TO-ALIAS-REGISTER! is invoked.
  1504.     5.3.3. Invocation rules, etc.
  1505. The meaning and intent of most statement rules in an existing port is
  1506. readily apparent.  The more arcane rules have to do with procedures
  1507. and the representation of numbers.  What follows is a description of
  1508. some of the more obscure rules related to procedures and some of the
  1509. implementation concepts required to understand them.
  1510. In the invocation rules, FRAME-SIZE is the number of arguments passed
  1511. in the call (often plus one), and there is often more than one rule
  1512. with the same keyword, typically to handle the common cases (small
  1513. FRAME-SIZE) more efficiently.
  1514. Various of the rules specify the number of arguments that the
  1515. resulting procedure will accept.  The range is described in terms of
  1516. two parameters, MIN and MAX:
  1517.  - MIN is always positive and it is one greater than the smallest
  1518. number of arguments allowed.
  1519.  - MAX may be positive or negative.  If positive, it is one greater
  1520. than the largest number of arguments allowed.  If negative, it
  1521. indicates that the procedure will accept an unbounded number of
  1522. arguments, and the absolute value of MAX, minus (MIN + 1), is the
  1523. number of positional optional parameters.  Either way, the absolute
  1524. value of MAX is the size of the procedure's call frame counting the
  1525. procedure itself.
  1526.  These two values are encoded in the format word of the resulting
  1527. procedures so that dynamic APPLY can check the number of arguments
  1528. passed and reformat the stack frame appropriately.
  1529.  Non-positive MINs are used to indicate that the compiled entry point
  1530. is not a procedure, but a return address, a compiled expression, or a
  1531. pointer to an internal label.
  1532. The CONS-CLOSURE rules will dynamically create some instructions in
  1533. the runtime heap, and these instructions must be visible to the
  1534. processor's instruction fetch unit.  If the instruction and data
  1535. caches are not automatically kept consistent by the hardware,
  1536. especially for newly addressed memory, the caches must be explicitly
  1537. synchronized by the Scheme system.  On machines where the programmer
  1538. is given no control over the caches, this will be very hard to do.  On
  1539. machines where the control is minimal or flushing is expensive, the
  1540. following solution can be used to amortize the cost:
  1541. The CONS-CLOSURE rules can generate code to allocate a closure from a
  1542. pre-allocated pool and invoke an out-of-line routine to refill the
  1543. pool when it is empty.  The routine allocates more space from the
  1544. heap, initializes the instructions, and synchronizes the caches.
  1545. Since the real entry points are not known until the closure objects
  1546. are created, instead of using absolute jumps to the real entry points,
  1547. the pre-allocated closures can contain jumps to a fixed routine that
  1548. will extract the real entry point from the word pointed at by the
  1549. return address and invoke it.  In other words, the code inserted in
  1550. closure objects will be
  1551.     jsr fixed-routine
  1552.     <storage for real-entry-point>
  1553. and fixed-routine, written in assembly language, will do something like
  1554.     load    0(return-address),rtemp
  1555.     jmp    0(rtemp)
  1556. The 68040 version of the Motorola 68000 family port uses this trick
  1557. because the 68040 cache is typically configured in copyback mode, and
  1558. synchronizing the caches involves an expensive supervisor (OS) call.
  1559. The Alpha back-end also uses this trick because the caches can be
  1560. synchronized only by using the CALL_PAL IMB instruction, which flushes
  1561. the complete instruction cache, therefore implying a large re-start
  1562. cost.  The Alpha version of this code is currently better than the
  1563. 68040 version, so you should probably emulate that version.
  1564. * (INVOCATION:UUO-LINK (? frame-size) (? continuation) (? name))
  1565.   This rule is used to invoke a procedure named by a free variable.
  1566. It is the rule used to generate a branch to an execute cache as
  1567. described in cmpint.txt.  The rule should allocate a new execute cache
  1568. in the compiled code block by using FREE-UUO-LINK-LABEL, and should
  1569. then branch to the instruction portion of the execute cache.
  1570. FRAME-SIZE is the number of arguments passed in the call, plus one.
  1571. * (INVOCATION:GLOBAL-LINK (? frame-size) (? continuation) (? name))
  1572.   This rule is identical to the previous one, except that the free
  1573. variable must be looked up in the global environment.  It is used to
  1574. improve the expansion of some macros that insert explicit references
  1575. to the global environment (e.g. The expansion for FLUID-LET inserts
  1576. uses (ACCESS DYNAMIC-WIND #f) as the operator of a call).
  1577. * (INVOCATION-PREFIX:MOVE-FRAME-UP (? frame-size) (? address))
  1578.   This rule is used to shift call frames on the stack to maintain
  1579. proper tail recursion.  ADDRESS specifies where to start pushing the
  1580. frame.  It should be a pointer into the used portion of the stack,
  1581. i.e. point to a higher address.
  1582. For example, assume that what follows depicts the stack before
  1583.   (INVOCATION-PREFIX:MOVE-FRAME-UP 3 addr)
  1584.     |        ...        |
  1585.     |                |
  1586.     +-------------------------------+
  1587.     |        <value n>        |
  1588. addr ->    +-------------------------------+
  1589.     |                | direction of
  1590.     |                | stack growth
  1591.     |                |
  1592.     |        ...        |    |
  1593.     |                |    |
  1594.     |                |    V
  1595.     |                |
  1596.     +-------------------------------+
  1597.     |        <value 3>        |
  1598.     +-------------------------------+
  1599.     |        <value 2>        |
  1600.     +-------------------------------+
  1601.     |        <value 1>        |
  1602. spbf ->    +-------------------------------+
  1603. Where spbf is the contents of the stack pointer register.
  1604. After the invocation prefix, it will look as follows:
  1605.     |        ...        |
  1606.     |                |
  1607.     +-------------------------------+
  1608.     |        <value n>        | direction of
  1609. addr ->    +-------------------------------+ stack growth
  1610.     |        <value 3>        |
  1611.     +-------------------------------+    |
  1612.     |        <value 2>        |    |
  1613.     +-------------------------------+    V
  1614.     |        <value 1>        |
  1615. spaf ->    +-------------------------------+
  1616. The stack pointer register will now contain the value of spaf.
  1617. * (INVOCATION-PREFIX:DYNAMIC-LINK (? frame-size) (? address-1) (? address-2))
  1618.   This rule is similar to the INVOCATION-PREFIX:MOVE-FRAME-UP rule,
  1619. but is used when the destination of the frame is not known at compile
  1620. time.  The destination depends on the continuation in effect at the
  1621. time of the call, and the section of the stack that contains enclosing
  1622. environment frames for the called procedure.  Two addresses are
  1623. specified and the one that is closest to the current stack pointer
  1624. should be used, that is, the target address is the numerically smaller
  1625. of the two addresses since the Liar stack grows towards smaller
  1626. addresses.
  1627.  ==> This rule need not need not exist in the RTL.  It could be
  1628. expanded into a comparison and a use of
  1629. INVOCATION-PREFIX:MOVE-FRAME-UP with a computed address.
  1630. * (ASSIGN (REGISTER (? target))
  1631.       (CONS-CLOSURE (ENTRY:PROCEDURE (? procedure-label))
  1632.             (? min) (? max) (? size)))
  1633.   This rule issues the code to create a closure object whose real
  1634. entry point is PROCEDURE-LABEL, that will accept a number of arguments
  1635. specified by MIN and MAX, and that will have storage for SIZE free
  1636. variables.  The free variable storage need not be initialized since it
  1637. will be written immediately by subsequent RTL instructions.  The entry
  1638. point of the resulting closure object should be written to RTL
  1639. register TARGET.  The format of closure objects is described in
  1640. cmpint.txt.
  1641. * (ASSIGN (REGISTER (? target))
  1642.       (CONS-MULTICLOSURE (? nentries) (? size) (? entries)))
  1643.   This rule is similar to the previous rule, but issues code to
  1644. allocate a closure object with NENTRIES entry points.  ENTRIES is a
  1645. vector of entry-point descriptors, each being a list containing a
  1646. label, a min, and a max as in the previous rule.  TARGET receives the
  1647. compiled code object corresponding to the first entry.
  1648. * (OPEN-PROCEDURE-HEADER (? label-name))
  1649.   This rule and its siblings are used to generate the entry code to
  1650. procedures and return addresses.  On entry to procedures and
  1651. continuations, a gc/interrupt check is performed, and the appropriate
  1652. routine in the runtime library is invoked if necessary.  This check is
  1653. performed by comparing the memory Free pointer to the compiled code's
  1654. version of the MemTop pointer.  The low-level interrupt handlers
  1655. change the MemTop pointer to guarantee that such comparisons will fail
  1656. in the future.  A standard header generates the following code:
  1657.     (LABEL gc-label)
  1658.     <code to invoke the runtime library>
  1659.     <format and gc words for the entry point>
  1660.     (LABEL label-name)
  1661.     <branch to gc-label if Free >= MemTop>
  1662. Each kind of header invokes a different runtime library utility.  In
  1663. addition, procedures that expect dynamic links must guarantee that the
  1664. dynamic link is preserved around the execution of the interrupt
  1665. handler.  This is accomplished by passing the contents of the dynamic
  1666. link register to the appropriate runtime library utility.
  1667. * (CLOSURE-HEADER (? label-name) (? nentries) (? num-entry))
  1668.   NENTRIES is the number of entry points in the closure object, and
  1669. NUM-ENTRY is the zero-based index for this entry point.  Closure
  1670. headers are similar to other procedure headers but also have to
  1671. complete the Hand-Shake initiated by the instructions stored in the
  1672. closure objects so that the closure object appears on top of the
  1673. stack.  On architectures where it is necessary, they also have to map
  1674. closure objects to their canonical representatives, and back when
  1675. backing out because of interrupts or garbage collection.
  1676. The file compiler/machines/port/rules3.scm contains most of these
  1677. procedure-related rules.  It also contains three procedures that
  1678. generate assembly language and are required by the compiler.  These
  1679. procedures are used to generate initialization code for compiled code
  1680. blocks.
  1681. Compiled code blocks have two sections, a code section that contains
  1682. the instructions, and a ``constants'' section that contains scheme
  1683. objects referenced by the code (e.g. quoted lists and symbols), the
  1684. free variable caches for the code, the debugging information
  1685. descriptor (more on this later), and the environment where the free
  1686. variables in the code must be referenced.  This environment is not
  1687. known at compile time, so the compiler allocates a slot in the
  1688. constants section for it, but the code itself must store it on first
  1689. entry.  In addition, the linker is invoked on first entry to look up
  1690. the free variables and fill the variable caches with their correct
  1691. contents.  The compiler allocates enough space for each free variable
  1692. cache and initializes the space with the information required by the
  1693. linker to patch the reference.  This information consists of the name
  1694. of the free variable in addition to the number of actual arguments
  1695. passed (plus one) for execute references.
  1696. If COMPILER:COMPILE-BY-PROCEDURES? is true, the compiler will generate
  1697. multiple compiled code blocks, one corresponding to each top-level
  1698. lambda expression.  Each of these must be initialized and linked, but
  1699. instead of initializing them on first entry, the root compiled code
  1700. block links all of them when it is entered.
  1701. The linker (a runtime library utility) expects three arguments:
  1702.   The address of the first word of the compiled code block, the word
  1703. containing the GC vector header for the compiled code block.
  1704.   The address of the first linker section in the constants area of the
  1705. compiled code block.  The linker sections contain the free variable
  1706. caches and are all contiguous.
  1707.   The number of linker sections in the compiled code block.
  1708. * (GENERATE/QUOTATION-HEADER env-label free-label n-sections)
  1709.   This procedure generates the code that initializes the environment
  1710. slot at location labeled ENV-LABEL.  The environment is fetched from
  1711. the interpreter's environment register.  It also generates code to
  1712. invoke the linker on the executing compiled code block.  The first
  1713. word of the compiled code block is labeled by the value of
  1714. *BLOCK-LABEL*, the first linker section is labeled by FREE-LABEL, and
  1715. the number of linker sections is N-SECTIONS.
  1716. * (GENERATE/REMOTE-LINK label env-offset free-offset n-sections)
  1717.   This procedure is similar to GENERATE/QUOTATION-HEADER but is used
  1718. to generate code that initializes and links a different compiled code
  1719. block.  It is used to generate the code to insert into the root
  1720. compiled code block to link each of the other compiled code blocks
  1721. generated when COMPILER:COMPILE-BY-PROCEDURES? is true.
  1722.   LABEL is a label in current block's constant section where the
  1723. pointer to the code block to be linked is stored,
  1724.   ENV-OFFSET is the vector offset in the other code block where the
  1725. environment of evaluation should be stored,
  1726.   FREE-OFFSET is the vector offset of the first linker section in the
  1727. other compiled code block, and
  1728.   N-SECTIONS is the number of linker sections in the other block.
  1729. * (GENERATE/CONSTANTS-BLOCK consts reads writes execs global-execs statics)
  1730.   This procedure generates the assembler pseudo-ops used to generate
  1731. the constants and linker section for a compiled code block.  This
  1732. section consists of:
  1733.   - The constant objects (e.g. quoted lists) referenced by the code.
  1734.   - The read variable caches used by the code.
  1735.   - The write variable caches used by the code.
  1736.   - The execute variable caches used by the code.
  1737.   - The global execute variable caches used by the code.
  1738.   - The locations for static variables.
  1739.   - A slot for the debugging information descriptor generated by the
  1740. compiler.
  1741.   - A slot for the environment where the code is linked.  
  1742. Each word of storage in the constants block is allocated by using a
  1743. SCHEME-OBJECT assembler pseudo-op, and the order in which they appear
  1744. is the same as the order in which they appear in the final object.
  1745. The linker sections (free variable cache sections) must be contiguous,
  1746. and each has a one-word header describing the kind of section and its
  1747. length.  The environment slot must be the last word in the compiled
  1748. code block, immediately preceded by the debugging information
  1749. descriptor.  Each SCHEME-OBJECT directive takes a label and the
  1750. initial contents of the slot.
  1751. This procedure is almost machine-independent, and you should be able
  1752. to trivially modify an existing version.  The only machine dependence
  1753. is the layout and size of the storage allocated for each execute cache
  1754. (uuo link).  This machine-dependence consists entirely of the
  1755. definition of the TRANSMOGRIFLY procedure.
  1756. TRANSMOGRIFLY takes a list of the following form:
  1757.   ((free-variable-1 (frame-size-1-1 . label-1-1)
  1758.                 (frame-size-1-2 . label-1-2)
  1759.             ...)
  1760.    (free-variable-2 (frame-size-2-1 . label-2-1)
  1761.                 (frame-size-2-2 . label-2-2)
  1762.             ...)
  1763.    ...)
  1764. This list is interpreted as follows: an execute cache for calls to
  1765. FREE-VARIABLE-1 with frame size FRAME-SIZE-1-1 (number of arguments
  1766. plus one) must be created, and labeled LABEL-1-1, similarly for
  1767.  <FREE-VARIABLE-1, FRAME-SIZE-1-2, LABEL-1-2>, 
  1768.  <FREE-VARIABLE-2, FRAME-SIZE-2-1, LABEL-2-1>, etc.
  1769. Assuming that the initial layout of an execute cache is
  1770.   free variable name        ; labeled word
  1771.   false                ; optional storage (e.g. for branch delay slot)
  1772.   frame size of call        ; arity + 1
  1773. TRANSMOGRIFLY will return a list of the following form:
  1774.   ((frame-variable-1 label-1-1)
  1775.    (#f               dummy-label-1-1)    ; optional word(s)
  1776.    (frame-size-1-1   dummy-label-1-1)
  1777.    (frame-variable-1 label-1-2)
  1778.    (#f               dummy-label-1-2)    ; optional word(s)
  1779.    (frame-size-1-2   dummy-label-1-2)
  1780.    ...
  1781.    (frame-variable-2 label-2-1)
  1782.    (#f               dummy-label-2-1)    ; optional word(s)
  1783.    (frame-size-2-1   dummy-label-2-1)
  1784.    ...)
  1785. There may be any number of optional words, but the layout must match
  1786. that expected by the macros defined in microcode/cmpint-port.h.  In
  1787. particular, the length in longwords must match the definition of
  1788. EXECUTE_CACHE_ENTRY_SIZE in microcode/cmpint-port.h, and the definition
  1789. of EXECUTE-CACHE-SIZE in compiler/machines/port/machin.scm.
  1790. Furthermore, the instructions that the linker will insert should
  1791. appear at the word labeled by LABEL-N-M, and should not overwrite the
  1792. relevant part of FRAME-SIZE-N-M, since the frame size will be needed
  1793. when re-linking after an incremental definition or assignment.
  1794. The output format of TRANSMOGRIFLY is the input format for the read
  1795. and write execute cache sections.  The procedure DECLARE-CONSTANTS,
  1796. local to GENERATE/CONSTANTS-BLOCK, reformats such lists into the final
  1797. SCHEME-OBJECT directives and tacks on the appropriate linkage section
  1798. headers.
  1799.     5.3.4. Fixnum rules.
  1800. Scheme's generic arithmetic primitives cannot be open-coded fully for
  1801. space reasons.  Most Scheme code that manipulates numbers manipulates
  1802. small integers used as counters, vector indices, etc., and using
  1803. out-of-line arithmetic procedures to operate on them would make the
  1804. code too slow.  The compromise, therefore, is to open-code the common
  1805. small integer case, and to handle the rest out of line.  This, of
  1806. course, does not perform particularly well for the other common case
  1807. of floating point data.
  1808. Scheme integers are represented in two formats.  The most common,
  1809. fixnum representation, uses the datum field of the objects to directly
  1810. encode the values.  The other format, bignum representation, stores
  1811. the values in multiple words in memory, and the datum is a pointer to
  1812. this storage.  Scheme generic arithmetic procedures will generate
  1813. fixnums whenever possible, resorting to bignums when the value exceeds
  1814. the range that can be represented in fixnum format.
  1815. Since the open-codings provided for the compiler only handle fixnums,
  1816. these open-codings must also detect when the result will not fit in a
  1817. fixnum in order to invoke the out-of-line utility that will handle
  1818. them correctly.  
  1819. Most hardware provides facilities for detecting and branching if an
  1820. integer operation overflows.  Fixnums cannot use these facilities
  1821. directly, because of the tag bits at the high-end of the word.  To be
  1822. able to use these facilities (and get the sign bit in the right
  1823. place), Scheme fixnums are converted to an internal format before they
  1824. are operated on, and converted back to Scheme object format before
  1825. storing them in memory or returning them as values.
  1826. In this internal format, the value has been shifted left so that the
  1827. fixnum sign-bit coincides with the integer sign bit, and a number of
  1828. bits in the least-significant end of the word hold zeros.  The shift
  1829. amount is the length of the type-tag field.
  1830. The rules
  1831.     (ASSIGN (REGISTER (? target)) (OBJECT->FIXNUM (REGISTER (? source))))
  1832.     (ASSIGN (REGISTER (? target)) (FIXNUM->OBJECT (REGISTER (? source))))
  1833. perform this translation.
  1834. The open-coding of fixnum arithmetic assumes that the sources and the
  1835. result are in this format.  This format is good for value comparisons,
  1836. addition, subtraction, and bitwise logical operations, but must be
  1837. transformed for multiplication, division, and shifting operations.
  1838. In addition to open-coding fixnum operations within generic
  1839. arithmetic, fixnum primitives can be invoked directly, and the code
  1840. can be open coded as well.  Under these circumstances, the result will
  1841. not be checked for overflow, and the code generated can be quite
  1842. different.  The RTL instructions that perform fixnum arithmetic have a
  1843. boolean flag that specifies whether overflow conditions should be
  1844. generated or not.
  1845. The compiler does not generally require fixnum arithmetic to be open
  1846. coded.  If the names of all the fixnum primitives are listed in
  1847. COMPILER:PRIMITIVES-WITH-NO-OPEN-CODING, all of them will be handled
  1848. by issuing code to invoke them out of line.
  1849. There is one exception to this, however.  The following rules MUST be
  1850. provided:
  1851.     (ASSIGN (REGISTER (? target))
  1852.         (FIXNUM-2-ARGS MULTIPLY-FIXNUM
  1853.                (OBJECT->FIXNUM (CONSTANT 4))
  1854.                (OBJECT->FIXNUM (REGISTER (? source)))
  1855.                #F))
  1856.     (ASSIGN (REGISTER (? target))
  1857.         (FIXNUM-2-ARGS MULTIPLY-FIXNUM
  1858.                (OBJECT->FIXNUM (REGISTER (? source)))
  1859.                (OBJECT->FIXNUM (CONSTANT 4))
  1860.                #F))
  1861. The reason is that VECTOR-REF and VECTOR-SET! translate into a
  1862. sequence that uses these patterns when the index is not a compile-time
  1863. constant.  Of course, you can include VECTOR-REF and VECTOR-SET! in
  1864. compiler:PRIMITIVES-WITH-NO-OPEN-CODING to avoid the problem
  1865. altogether, but this is probably not advisable.
  1866.     5.3.5. Rules used to invoke the runtime library
  1867. Some of the rules issue code that invokes the runtime library.  The
  1868. runtime library is invoked through a primary entry point,
  1869. SCHEME-TO-INTERFACE, typically directly accessible through a dedicated
  1870. processor register.  SCHEME-TO-INTERFACE expects at least one and up
  1871. to five arguments.  The first argument is the index of the runtime
  1872. library service to invoke, and the rest are the parameters to the
  1873. service routine.  These arguments are passed in fixed locations,
  1874. typically registers.  Runtime library utilities return their values
  1875. (if any) in the compiler's value register.  The following is a typical
  1876. example of such an invocation where INVOKE-INTERFACE expects the index
  1877. of a utility, and generates the code that writes the index into the
  1878. appropriate location and jumps to SCHEME-TO-INTERFACE.
  1879.     (define-rule statement
  1880.       (INVOCATION:APPLY (? frame-size) (? continuation))
  1881.       (LAP ,@(clear-map!)
  1882.        ,@(load-rn frame-size 2)
  1883.        (MOV L (@R+ 14) (R 1))
  1884.        ,@(invoke-interface code:compiler-apply)))
  1885. The code names are typically defined in
  1886. compiler/machines/port/lapgen.scm.
  1887. Many of the utilities expect return addresses as their first argument,
  1888. and it is convenient to define a procedure, INVOKE-INTERFACE-JSB
  1889. (sometimes called LINK-TO-INTERFACE) which receives an index but
  1890. leaves the appropriate return address in the first argument's
  1891. location.  INVOKE-INTERFACE-JSB can be written by using
  1892. INVOKE-INTERFACE (and SCHEME-TO-INTERFACE), but given the frequency of
  1893. this type of call, it is often written in terms of an alternate entry
  1894. point to the runtime library (e.g.  SCHEME-TO-INTERFACE-JSB).
  1895. An example of a more complicated call to the runtime library is
  1896.     (define-rule statement
  1897.       (INTERPRETER-CALL:CACHE-ASSIGNMENT (? extension) (? value))
  1898.       (QUALIFIER (and (interpreter-call-argument? extension)
  1899.               (interpreter-call-argument? value)))
  1900.       (let* ((set-extension
  1901.           (interpreter-call-argument->machine-register! extension r2))
  1902.          (set-value 
  1903.           (interpreter-call-argument->machine-register! value r3))
  1904.          (clear-map (clear-map!)))
  1905.     (LAP ,@set-extension
  1906.          ,@set-value
  1907.          ,@clear-map
  1908.          ,@(invoke-interface-jsb code:compiler-assignment-trap))))
  1909. where INTERPRETER-CALL-ARGUMENT->MACHINE-REGISTER! invokes
  1910. CLEAR-REGISTERS! and NEED-REGISTER! besides performing the assignment.
  1911. For very frequent calls, the assembly language part of the runtime
  1912. library can provide additional entry points.  The calling convention
  1913. for these would be machine-dependent, but frequently they take
  1914. arguments in the same way that SCHEME-TO-INTERFACE and
  1915. SCHEME-TO-INTERFACE-JSB take them, but avoid passing the utility
  1916. index, and may do part or all of the work of the utility in assembly
  1917. language instead of invoking the portable C version.  Many of the
  1918. ports have out-of-line handlers for generic arithmetic, with the
  1919. commond fixnum/flonum cases handled there.
  1920. The following is a possible specialized version of apply
  1921. where the special entry point expects the procedure argument on the
  1922. stack rather than in a fixed register:
  1923.     (define-rule statement
  1924.       (INVOCATION:APPLY (? frame-size) (? continuation))
  1925.       (LAP ,@(clear-map!)
  1926.        ,@(load-rn frame-size 2)
  1927.         (JMP ,entry:compiler-apply)))
  1928. The procedure object will have been pushed on the stack by earlier
  1929. code.
  1930.     5.4. Writing predicate rules.
  1931. Predicate rules are used to generate code to discriminate between
  1932. alternatives at runtime.  The code generated depends on the
  1933. conditional branch facilities of the hardware at hand.  There are two
  1934. main ways in which architectures provide conditional branching
  1935. facilities:
  1936. * condition codes.  Arithmetic instructions compute condition codes
  1937. that are stored in hardware registers.  These hardware registers may
  1938. be targeted explicitly by the programmer or implicitly by the
  1939. hardware.  Conditional branch instructions determine whether to branch
  1940. or not depending on the contents of the condition registers at the
  1941. time the branch instruction is executed.  These condition registers
  1942. may be named explicitly by the instructions, or assumed implicitly.
  1943. * compare-and-branch instructions.  The instruction set includes
  1944. instructions that compare two values (or a value against 0) and branch
  1945. depending on the comparison.  The results of the comparison are not
  1946. stored in special or explicit registers, since they are used
  1947. immediately, by the instruction itself, to branch to the desired
  1948. target.
  1949. Liar accommodates both models for branching instructions.
  1950. Predicate rules generate code that precede the actual branches, and
  1951. then invoke the procedure SET-CURRENT-BRANCHES! informing it of the
  1952. code to generate to branch to the target.
  1953. Depending on the model, the prefix code may be empty, and all the code
  1954. may appear in the arguments to SET-CURRENT-BRANCHES!
  1955. SET-CURRENT-BRANCHES! expects two procedures as arguments.  Each of
  1956. them receives a label as an argument, and is supposed to generate code
  1957. that branches to the label if the predicate condition is true (first
  1958. argument) or false (second argument).  Both options are provided
  1959. because linearization of the control-flow graph occurs after LAP
  1960. generation, and it is therefore not known when the predicate rule is
  1961. fired which of the two possible linearizations will be chosen.
  1962. Thus on an architecture with condition codes, the rule will return the
  1963. code that performs the comparison, targeting the appropriate
  1964. condition-code registers (if they are not implicit), and the arguments
  1965. to SET-CURRENT-BRANCHES! will just generate the conditional-branch
  1966. instructions that use the generated condition codes.
  1967. On an architecture with compare-and-branch instructions, the code
  1968. returned by the rule body will perform any work needed before the
  1969. compare-and-branch instructions, and the arguments to
  1970. SET-CURRENT-BRANCHES! will generate the compare-and-branch
  1971. instructions.
  1972. For example, on the DEC Vax, a machine with implicit condition codes,
  1973. where compare (and most) instructions set the hidden condition-code
  1974. register, a predicate rule could be as follows:
  1975.     (define-rule predicate
  1976.       (EQ-TEST (REGISTER (? register-1)) (REGISTER (? register-2)))
  1977.       (set-current-branches!
  1978.        (lambda (label)
  1979.      (LAP (B EQL (@PCR ,label))))
  1980.        (lambda (label)
  1981.      (LAP (B NEQ (@PCR ,label)))))
  1982.       (LAP (CMP L ,(any-register-reference register-1)
  1983.         ,(any-register-reference register-2))))
  1984. The prefix code performs the comparison.  The arguments to
  1985. SET-CURRENT-BRANCHES! branch depending on the result.
  1986. On the HP Precision Architecture (Spectrum), a machine with
  1987. compare-and-branch instructions, the same rule would be written as
  1988. follows:
  1989.     (define-rule predicate
  1990.       ;; test for two registers EQ?
  1991.       (EQ-TEST (REGISTER (? source1)) (REGISTER (? source2)))
  1992.       (let* ((r1 (standard-source! source1))
  1993.          (r2 (standard-source! source2)))
  1994.     (set-current-branches!
  1995.      (lambda (label)
  1996.        (LAP (COMB (EQ) ,r1 ,r2 (@PCR ,label))
  1997.         (NOP ())))            ; handle delay slot
  1998.      (lambda (label)
  1999.        (LAP (COMB (LTGT) ,r1 ,r2 (@PCR ,label))
  2000.         (NOP ()))))            ; handle delay slot
  2001.     (LAP)))
  2002. There is no prefix code, and the arguments to SET-CURRENT-BRANCHES!
  2003. perform the comparison and branch.
  2004. The (OVERFLOW-TEST) predicate condition does not fit this model
  2005. neatly.  The current compiler issues overflow tests when open-coding
  2006. generic arithmetic.  Fixnum overflow implies that bignums should be
  2007. used for the result, and this predicate is used to conditionally
  2008. invoke out-of-line utilities.
  2009. The problem is that the decomposition of the code assumes that the
  2010. result of the overflow test is stored implicitly by the code that
  2011. generates the arithmetic instructions, and that this condition can be
  2012. later used for branching by the code generated for (OVERFLOW-TEST).
  2013. The code for the test will be adjacent to the code for the
  2014. corresponding arithmetic operation, but the compiler assumes that the
  2015. condition can be passed implicitly between these adjacent
  2016. instructions.  This decomposition only matches hardware with condition
  2017. codes.
  2018. Hardware with compare-and-branch instructions can be accommodated by
  2019. explicitly computing conditions into a hardware register reserved for
  2020. this purpose, and the code generated by the predicate rule can then
  2021. branch according to the contents of this register.  On these machines,
  2022. the arithmetic operator will not only generate the desired result, but
  2023. will set or clear a fixed register according to whether the
  2024. computation overflowed or not.  The predicate code will then branch
  2025. when the fixed register contains a non-zero value for the first
  2026. linearization choice, or zero for the other possibility.
  2027. This problem is particularly acute on MIPS processors.  The MIPS
  2028. architecture does not detect overflow conditions, so the overflow
  2029. condition must be computed by examining the inputs and outputs of the
  2030. arithmetic instructions.  There are conditional branches used just to
  2031. store the correct overflow condition in a register, and the code
  2032. generated for the overflow test will then branch again depending on
  2033. the value stored.  This makes the code generated by the open-coding of
  2034. generic arithmetic contain multiple branches and quite large.
  2035. The Spectrum port solves this problem a little differently.  On the
  2036. Spectrum, arithmetic instructions can conditionally cause the
  2037. following instruction to be skipped.  Since the code generated by
  2038. (OVERFLOW-TEST) is guaranteed to follow the code generated by the
  2039. arithmetic operation, the last instruction generated by the arithmetic
  2040. operations conditionally skips if there is no overflow.  The
  2041. (OVERFLOW-TEST) code generates an unconditional branch for the first
  2042. linearization choice, and an unconditional skip and an unconditional
  2043. branch for the alternative linearization.
  2044. A more efficient solution, currently employed in the MIPS port
  2045. (version 4.87 or later) depends on the fact that the RTL instruction
  2046. immediately preceding an RTL OVERFLOW-TEST encodes the arithmetic
  2047. operation whose overflow condition is being tested.  Given this
  2048. assumption (that the arithmetic operation producing the overflow
  2049. conditions and the test of such condition are adjacent), the rule for
  2050. OVERFLOW-TEST need not generate any code, and the rule for the
  2051. arithmetic operation can generate both the prefix code and invoke
  2052. SET-CURRENT-BRANCHES! as appropriate.  This is possible because the
  2053. RTL encoding of arithmetic operations includes a boolean flag that
  2054. specifies whether the overflow condition is desired or not.
  2055.         6. Suggested ordering of tasks.
  2056. The task of porting the compiler requires a lot of work.  In the past,
  2057. it has taken approximately three full weeks for a single person
  2058. knowledgeable with MIT Scheme and the compiler, but without
  2059. documentation.  This guide was written after the first three ports.
  2060. One unfortunate aspect is that a lot of mechanism must be in place
  2061. before most of the compiler can be tried out.  In other words, there
  2062. is a lot of code that needs to be written before small pieces can be
  2063. tested, and the compiler is not properly organized so that parts of it
  2064. can be run independently.  
  2065. Note also that cmpint-port.h, machin.scm, rules3.scm, and
  2066. cmpaux-port.m4 are very intertwined, and you may often have to iterate
  2067. while writing them until you converge on a final design.
  2068. Keeping all this in mind, here is a suggested ordering of the tasks:
  2069.     6.1. Learn the target instruction set well.  
  2070. In particular, pay close attention to the branch and jump instructions
  2071. and to the facilities available for controlling the processor caches
  2072. (if necessary).  You may need to find out the facilities that the
  2073. operating system provides if the instructions to control the cache are
  2074. privileged instructions.
  2075.     6.2. Write microcode/cmpint-port.h:
  2076. cmpint.txt documents most of the definitions that this file must
  2077. provide.
  2078.  6.2.1. Design the trampoline code format.  Trampolines are used to
  2079. invoke C utilities indirectly.  In other words, Scheme code treats
  2080. trampolines like compiled Scheme entry points, but they immediately
  2081. invoke a utility to accomplish their task.  Since
  2082. return-to-interpreter is implemented as a trampoline, you will need to
  2083. get this working before you can run any compiled code at all.
  2084.  6.2.1. Design the closure format and the execute cache format.  This
  2085. is needed to get the Scheme part of the compiler up AND to get the
  2086. compiled code interface in the microcode working.  Try to keep the
  2087. number of instructions low since closures and execute caches are very
  2088. common.
  2089.  6.2.2. Design the interrupt check instructions that are executed on
  2090. entry to every procedure, continuation, and closure.  Again, try to
  2091. keep the number of instructions low, and attempt to make the
  2092. non-interrupting case fast at the expense of the case when interrupts
  2093. must be processed.  Note that when writing the Scheme code to generate
  2094. the interrupt sequences, you can use the ADD-END-OF-BLOCK-CODE!
  2095. procedure to make sure that the interrupt sequence does not confuse
  2096. your hardware's branch prediction strategy.
  2097.  6.2.3. Given all this, write cmpint-port.h.  Be especially careful
  2098. with the code used to extract and insert absolute addresses into
  2099. closures and execute caches.  A bug in this code would typically
  2100. manifest itself much later, after a couple of garbage collections.
  2101. During this process you will be making decisions about what registers
  2102. will be fixed by the port, namely the stack pointer, the free pointer,
  2103. the register block pointer, and at least one register holding the
  2104. address of a label used to get back to C, typically
  2105. scheme_to_interface.
  2106.     6.3. Write machin.scm:
  2107. Most of the definitions in this file have direct counterparts or are
  2108. direct consequences of the code in and microcode/cmpint-port.h, so it
  2109. will be mostly a matter of re-coding the definitions in Scheme rather
  2110. than C.
  2111. In particular, you will have to decide how registers are going to be
  2112. used and split between your C compiler and Liar.  If your architecture
  2113. has a large register set, you can let C keep those registers to which
  2114. it assigns a fixed meaning (stack pointer, frame pointer, global
  2115. pointer), and use the rest for Liar.  If your machine has few
  2116. registers or you feel more ambitious, you can give all the registers
  2117. to Liar, but the code for transferring control between both languages
  2118. in cmpaux-port.m4 will become more complex.  Either way, you will need
  2119. to choose appropriate registers for the Liar fixed registers (stack
  2120. pointer, free pointer, register block pointer, dynamic link register
  2121. and optionally, datum mask, return value register, memtop register,
  2122. and scheme_to_interface address pointer).
  2123.     6.4. Write the assembler:
  2124. You can write the assembler any old way you want, but it is easier to
  2125. use the branch tensioner and the rest of the facilities if you use the
  2126. same conventions that the existing assemblers use.  In particular,
  2127. with any luck, you will be able to copy inerly.scm, insmac.scm, and
  2128. parts of assmd.scm verbatim from an existing port, and for most
  2129. machines, coerce.scm is straightforward to write.
  2130. assmd.scm defines procedures that depend only on the endianness of the
  2131. architecture.  You may want to start with the MIPS version since this
  2132. version accommodates both endianness possibilities as MIPS processors
  2133. can be configured either way.  If your processor has fixed endianness,
  2134. you can prune the inappropriate code.  The block-offset definitions
  2135. must agree with those in microcode/cmpint-port.h, and the padding
  2136. definitions are simple constants.
  2137. Assuming that you decide to use the same structure as existing
  2138. assemblers, you may need to write parsers for addressing modes if your
  2139. machine has them.  You can use the versions in the MC68020 (bobcat),
  2140. Vax, and i386 (Intel 386) ports for guidance.  Addressing modes are
  2141. described by a set of conditions under which they are valid, and some
  2142. output code to issue.  The higher-level code that parses instructions
  2143. in insmac.scm must decide where the bits for the addressing modes must
  2144. appear.  The MC68020 version divides the code into two parts, the part
  2145. that is inserted into the opcode word of the instruction (further
  2146. subdivided into two parts), and the part that follows the opcode word
  2147. as an extension.  The Vax version produces all the bits at once since
  2148. addressing modes are not split on that architecture.  You should write
  2149. the addressing mode definitions in port/insutl.scm, plus any
  2150. additional transformers that the instruction set may require.
  2151. Once you have the code for the necessary addressing modes and
  2152. transformers (if any), and the parsing code for their declarations in
  2153. port/insmac.scm, writing the instr<n>.scm files should not be hard.
  2154. Remember to include pseudo-opcodes for inserting constants in the
  2155. assembly language, and for declaring external labels so that the
  2156. gc-offset to the beginning of the compiled code block will be inserted
  2157. correctly.  See for example, the definition of the EXTERNAL-LABEL
  2158. pseudo-opcode in machines/mips/instr1.scm, and its use in
  2159. machines/mips/rules3.scm.
  2160.     6.5. Write the LAPGEN rules:
  2161. You will need to write lapgen.scm, rules1.scm, rules2.scm, rules3.scm,
  2162. and parts of rules4.scm.  Most of rules4.scm is not used by the
  2163. compiler with the ordinary switch settings and the code may no longer
  2164. work in any of the ports, and rulfix.scm and rulflo.scm are only
  2165. necessary to open code fixnum and flonum arithmetic.  A good way to
  2166. reduce the amount of code needed at first is to turn primitive open
  2167. coding off, and ignore rulfix.scm and rulflo.scm.
  2168. Lapgen.scm need not include the shared code used to deal with fixnums
  2169. and flonums, but will require the rest, especially the code used to
  2170. invoke utilities in the compiled code interface.
  2171. rules1.scm and rules2.scm are relatively straightforward since the
  2172. RTL instructions whose translations are provided there typically map
  2173. easily into instructions.
  2174. rules4.scm need only have the INTERPRETER-CALL:CACHE-??? rules, and
  2175. these are simple invocations of runtime library routines which you can
  2176. emulate from exisiting ports.
  2177. rules3.scm is an entirely different matter.  It is probably the
  2178. hardest file to write when porting the compiler.  The most complicated
  2179. parts to understand, and write, are the closure code, the invocation
  2180. prefix code, and the block assembly code.
  2181.  The block assembly code can be taken from another port.  You will
  2182. only have to change how the transmogrifly procedure works to take into
  2183. account the size and layout of un-linked execute caches.
  2184.  The invocation prefix code is used to adjust the stack pointer, and
  2185. move a frame in the stack prior to a call to guarantee proper tail
  2186. recursion.  The frame moved is the one pointed at by the stack
  2187. pointer, and it may be moved a distance known at compile time
  2188. (invocation-prefix:move-frame-up rules) or a distance that cannot be
  2189. computed statically (invocation-prefix:dynamic-link rules).  The
  2190. move-frame-up rules are simple, but you should remember that the
  2191. starting and ending locations for the frame may overlap, so you must
  2192. ensure that data is not overwritten prematurely.  The dynamic link
  2193. rules are similar to the move-frame-up rules (and typically share the
  2194. actual moving code) but must first decide the location where the frame
  2195. should be placed.  This is done by comparing two possible values for
  2196. the location, and choosing the value closest to the current stack
  2197. pointer (i.e. numerically lower since the stack grows towards smaller
  2198. addresses).  Again, the source and target locations for the frame may
  2199. overlap, so the generated code must be careful to move the data in
  2200. such a way that no data will be lost.
  2201.  The closure code is the most painful to write.  When writing
  2202. cmpint-port.h you decided what the actual code in closure entries
  2203. would be, and the code for closure headers is a direct consequence of
  2204. this.  The combination of the instructions in a closure object, the
  2205. helper instructions in assembly language (if any), and the
  2206. instructions in the closure header must ultimately push the closure
  2207. object (or its canonical representative) on the stack as if it were
  2208. the last argument to the procedure, and pending interrupts (and gc)
  2209. must be checked on entry to the closure.  The interrupt back-out code
  2210. is different from the ordinary procedure interrupt back-out code
  2211. because the procedure object (the closure or its representative) is on
  2212. top of the stack.
  2213.  The cons-closure rules are used to allocate closure objects from the
  2214. runtime heap.  Some of this allocation/initialization may be done out
  2215. of line, especially if ``assembling'' the appropriate instructions on
  2216. the fly would require a lot of code.  In addition, you may have to
  2217. call out-of-line routines to synchronize the processor caches or
  2218. block-allocate multiple closure entries.
  2219.     6.6. Write stubs for remaining port files: 
  2220. rgspcm.scm and dassm1.scm can be copied verbatim from any other port.
  2221. lapopt.scm only needs to define an identity procedure.
  2222. rulfix.scm, rulflo.scm, and rulrew.scm need not define any rules,
  2223. since you can initially turn off open coding of primitive operators.
  2224. dassm2.scm and dassm3.scm need not be written at first, but they are
  2225. useful to debug the assembler (since disassembling some code should
  2226. produce code equivalent to the input to the assembler) and compiler
  2227. output when you forgot to make it output the LAP.
  2228.     6.7. Write the compiler-building files:
  2229. make.scm, and comp.cbf should be minorly modified copies of the
  2230. corresponding files in another port.
  2231. comp.sf and decls.scm can be essentially copied from another port, but
  2232. you will need to change the pathnames to refer to your port directory
  2233. instead of the one you copied them from, and in addition, you may have
  2234. to add or remove instr<n> and other files as appropriate.
  2235.     6.8. Write microcode/cmpaux-port.m4:
  2236. cmpaux.txt documents the entry points that this file must provide.
  2237. You need not use m4, but it is convenient to conditionalize the code
  2238. for debugging and different type code size.  If you decide not to use
  2239. it, you should call your file cmpaux-port.s
  2240.  6.8.1. Determine your C compiler's calling convention.  Find out what
  2241. registers have fixed meanings, which are supposed to be saved by
  2242. callees if written, and which are supposed to be saved by callers if
  2243. they contain useful data.
  2244.  6.8.2. Find out how C code returns scalars and small C structures.
  2245. If the documentation for the compiler does not describe this, you can
  2246. write a C program consisting of two procedures, one of which returns a
  2247. two-word (two int) struct to the other, and you can examine the
  2248. assembly language produced by the compiler.
  2249.  6.8.3. Design how scheme compiled code will invoke the C utilities.
  2250. Decide where the parameters (maximum of four) to the utilities will be
  2251. passed (preferably wherever C procedures expect arguments), and where
  2252. the utility index will be passed (preferably in a C caller-saves
  2253. register).
  2254.  6.8.4. Given all this, write a minimalist cmpaux-port.m4.  In other
  2255. words, write those entry points that are absolutely required
  2256. (C_to_interface, interface_to_C, interface_to_scheme, and
  2257. scheme_to_interface).  Be especially careful with the code that
  2258. switches between calling conventions and register sets.
  2259. C_to_interface and interface_to_scheme must switch between C and Liar
  2260. conventions, while scheme_to_interface must switch the other way.
  2261. interface_to_C must return from the original call to C_to_interface.
  2262. Make sure that C code always sees a valid C register set and that code
  2263. compiled by Liar always sees a valid Scheme register set.
  2264.     6.9. After the preliminary code works:
  2265. Once the compiler is up enough to successfully compile moderately
  2266. complex test programs, and the compiled code and the interface have
  2267. been tested by running the code, you probably will want to go back and
  2268. write the files that were skipped over.  In particular, you definitely
  2269. should write rulfix.scm and rulrew.scm, and rulflo.scm and the
  2270. disassembler if at all possible.
  2271.         7. Building and testing the compiler.
  2272. Once the port files have been written, you are ready to build and test
  2273. the compiler.  The first step is to build an interpreted compiler and
  2274. run simple programs.  Most simple bugs will be caught by this.
  2275.     7.1. Re-building scheme.
  2276. You need to build a version of the microcode with the compiled code
  2277. interface (portable runtime library) in it.  Besides writing
  2278. cmpint-port.h and cmpaux-port.m4, you will need to do the following:
  2279. - Copy (or link) cmpint-port.h to cmpint2.h.
  2280. - Modify m.h to use 6-bit-long type tags (rather than the default 8)
  2281. if you did not do this when you installed the microcode.  If you do
  2282. this, you will not be able to load .bin files created with 8 bit type
  2283. tags.  You can overcome this problem by using the original .psb files
  2284. again to regenerate the .bin files.  Alternatively, you can use a
  2285. version of Bintopsb compiled with 8-bit tags to generate new .psb
  2286. files, and a version of Psbtobin compiled with 6-bit tags to generate
  2287. the new .bin files.  Anotheroption is to bring the compiler up using 8
  2288. bit tags, but you may run out of address space.  The simplest way to
  2289. specify 6-bit type tags is to add a definition of C_SWITCH_MACHINE
  2290. that includes -DTYPE_CODE_LENGTH=6 .  Be sure to add any m4 switches
  2291. that you may need so that the assembly language will agree on the
  2292. number of tag bits if it needs it at all.  If your version of m4 does
  2293. not support command-line definitions, you can use the s/ultrix.m4
  2294. script to overcome this problem.  Look at the m/vax.h and s/ultrix.h
  2295. files for m4-related definitions.
  2296.  ==> We should just switch the default to 6 bits and be done with it.
  2297. - Modify ymakefile to include the processor dependent section that
  2298. lists the cmpint-port.h and cmpaux-port.m4 files.  You can emulate the
  2299. version for any other compiler port.  It is especially important that
  2300. the microcode sources be compiled with HAS_COMPILER_SUPPORT defined.
  2301. - Remove (or save elsewhere) all the .o files, scheme.touch, and
  2302. scheme, the linked scheme microcode.
  2303. - Do ``make xmakefile;make -f xmakefile scheme'' to generate a new
  2304. linked microcode.
  2305. Once you have a new linked microcode, you need to regenerate the
  2306. runtime system image files even if you have not changed the length of
  2307. the type tags.  This is done as follows:
  2308. - Re-generate a runtime.com (actually runtime.bin) image file by
  2309. invoking scheme with the options ``-large -fasl make.bin'' while
  2310. connected to the runtime directory, and then typing
  2311.   (disk-save "<lib directory pathname>/runtime.com")
  2312. at the Scheme prompt.
  2313. - You should probably also generate a runtime+sf.com file by typing
  2314.   (begin
  2315.     (cd "<sf directory pathname>")
  2316.     (load "make")
  2317.     (disk-save "<lib directory pathname>/runtime+sf.com"))
  2318. at the Scheme prompt.
  2319. You also need to have a working version of cref.  This can be done by
  2320. invoking scheme with the options ``-band runtime+sf.com'', and then
  2321. typing
  2322.   (begin
  2323.      (cd "<cref directory pathname>")
  2324.      (load "cref.sf"))
  2325. at the Scheme prompt.
  2326. If this errors because of the lack of a ``runtim.glob'' file, try it
  2327. again after executing
  2328.   (begin
  2329.      (cd "<runtime directory pathname>")
  2330.      (load "runtim.sf"))
  2331.     7.2. Building an interpreted compiler.
  2332. Once you have a new microcode, compatible runtime system, and ready
  2333. cref, you can pre-process the compiler as follows:
  2334. - Copy (or link) comp.pkg, comp.sf, and comp.cbf from the
  2335. compiler/machines/port directory to the compiler directory.
  2336. - For convenience, make a link from compiler/machines/port to
  2337. compiler/port.
  2338. - Invoke scheme with the ``-band runtime+sf.com'' option, and then
  2339. execute
  2340.   (begin
  2341.      (cd "<compiler directory pathname>")
  2342.      (load "comp.sf"))
  2343. This will take quite a while, and pre-process some of the files twice.
  2344. At the end of this process, you should have a .bin file for each of
  2345. the .scm files, a .ext file for some of them, and a bunch of
  2346. additional files in the compiler directory (comp.con, comp.ldr,
  2347. comp.bcon, comp.bldr, comp.glob, comp.free, comp.cref).
  2348. It is a good idea to look at the comp.cref file.  This is a
  2349. cross-reference of the compiler and may lead you to find typos or
  2350. other small mistakes.  The first section of the cref file (labeled
  2351. ``Free References:'') lists all variables that are not defined in the
  2352. compiler or the runtime system.  The only variables that should be in
  2353. this list are SF, and SF/PATHNAME-DEFAULTING.  The ``Undefined
  2354. Bindings:'' section lists those variables defined in the runtime
  2355. system and referenced freely by the compiler sources.  The remainder
  2356. of the cref file lists the compiler packages and the cross reference
  2357. of the procedures defined by it.
  2358. - Load up the compiler.  Invoke scheme with the options 
  2359. ``-compiler -band runtime+sf.com'', and then type
  2360.   (begin
  2361.      (cd "<compiler directory pathname>")
  2362.      (load "port/make")
  2363.      (disk-save "<lib directory pathname>/compiler.com"))
  2364. You should then be able to invoke the compiler by giving scheme the
  2365. ``-compiler'' option, and use it by invoking CF.
  2366.     7.3. Testing the compiler.
  2367. There is no comprehensive test suite for the compiler.  There is,
  2368. however, a small test suite that is likely to catch gross errors.  The
  2369. files for the test suite are in compiler/etc/tests.  Each file
  2370. contains a short description of how it can be used.
  2371. Make sure, in particular, that you test the closure code thoroughly,
  2372. especially if closure allocation hand-shakes with out-of-line code to
  2373. accomodate the CPU's caches.
  2374. A good order to try the test suite in is
  2375.     three.scm
  2376.     expr.scm
  2377.     pred.scm
  2378.     close.scm
  2379.     blast.scm
  2380.     reverse.scm
  2381.     arith.scm
  2382.     bitwse.scm
  2383.     fib.scm
  2384.     vector.scm
  2385.     reptd.scm
  2386.     lexpr.scm
  2387.     klexpr.scm
  2388.     close2.scm
  2389.     prim.scm
  2390.     free.scm
  2391.     uvuuo.scm
  2392.     link.scm
  2393.     uuo.scm
  2394.     unv.scm
  2395.     tail.scm
  2396.     y.scm
  2397.     sort/*.scm (see sort/README for a description)
  2398.  The programs in the first list test various aspects of code
  2399. generation.
  2400.  The programs in the second list test the handling of various dynamic
  2401. conditions (e.g. error recovery).
  2402.  The programs in the third list are somewhat larger, and register
  2403. allocation bugs, etc., are more likely to show up in them.
  2404. A good idea at the beginning is to turn COMPILER:GENERATE-RTL-FILES?
  2405. and COMPILER:GENERATE-LAP-FILES? on and compare them for plausibility.
  2406. If you have ported the disassembler as well, you should try
  2407. disassembling some files and comparing them to the input LAP.  They
  2408. won't be identical, but they should be similar.  The disassembler can
  2409. be invoked as follows:
  2410.     (compiler:write-lap-file "<pathname of .com file>") ; writes a .lap file.
  2411.     (compiler:disassemble <compiled entry point>) ; writes on the screen.
  2412. The .lap filename extension is used by COMPILER:WRITE-LAP-FILE and by
  2413. the compiler when COMPILER:GENERATE-LAP-FILES? is true, so you may
  2414. want to rename the .lap file generated by the compiler to avoid
  2415. overwriting it when using COMPILER:WRITE-LAP-FILE.
  2416. Various runtime system files also make good tests.  In particular, you
  2417. may want to try list.scm, vector.scm, and arith.scm.  You can try them
  2418. by loading them, and invoking procedures defined in them, but you must
  2419. execute
  2420.     (initialize-microcode-dependencies!)
  2421. after loading arith.com and before invoking procedures defined there.
  2422.     7.4. Compiling the compiler.
  2423. The real test of the compiler comes when it is used to compile itself
  2424. and the runtime system.  Re-compiling the system is a slow process,
  2425. that can take a few hours even with a compiled compiler on a fast
  2426. machine.  Compiling the compiler with an interpreted compiler would
  2427. probably take days.
  2428. There are two ways to speed up the process:
  2429. * Cross-compiling:
  2430. If you can access some machines on which the compiler already runs,
  2431. you can cross-compile the sources using a compiled compiler.  This
  2432. method is somewhat involved because you will need binaries for both
  2433. machines, since neither can load or dump the other's .bin files.
  2434. Imagine that you have a Vax, and you are porting to a Sparc.  You will
  2435. need to pre-process and compile the Sparc's compiler on the Vax to use
  2436. it as a cross-compiler.  This can be done by following the same
  2437. pattern that you used to generate the interpreted compiler on the
  2438. Sparc, but running everything on the Vax, and then compiling the
  2439. cross-compiler on the Vax by running scheme with the ``-compiler''
  2440. option, and typing
  2441.     (begin
  2442.     (cd "<sparc compiler directory>")
  2443.     (load "comp.cbf")
  2444.     (disk-restore "runtime+sf.com"))
  2445.     ;; After the disk-restore
  2446.     (begin
  2447.     (load "make")
  2448.     (in-package (->environment '(compiler))
  2449.       (set! compiler:cross-compiling? true))
  2450.     (disk-save "sparccom.com"))
  2451. to produce a cross-compiler band called "sparccom.com".
  2452. Once you have the cross-compiler, you can use CROSS-COMPILE-BIN-FILE
  2453. to generate .moc files.  The .moc files can be translated to .psb
  2454. files on the Vax.  These .psb files can in turn be translated to .moc
  2455. files on the Sparc, and you can generate the final .com files by using
  2456. CROSS-COMPILE-BIN-FILE-END defined in compiler/base/crsend.
  2457. compiler/base/crsend can be loaded on a plain runtime system (i.e.
  2458. without SF or a compiler).  You will probably find the following
  2459. idioms useful:
  2460.     (for-each cross-compile-bin-file (directory-read "<some dir>/*.bin"))
  2461.     (for-each cross-compile-bin-file-end (directory-read "<some dir>/*.moc")).
  2462. To translate the original .moc files to .psb files, you should use
  2463. microcode/Bintopsb on the Vax as follows:
  2464.     Bintopsb ci_processor=?? <foo.moc >foo.psb
  2465. where the value of ci_processor should be the value of
  2466. COMPILER_PROCESSOR_TYPE defined in microcode/cmpint-port.h.
  2467. You can then generate the target .moc files by using
  2468. microcode/Psbtobin on the Sparc as follows:
  2469.     Psbtobin allow_cc <foo.psb >foo.moc
  2470. * Distributing the task over several machines:
  2471. You can use more than one machine to compile the sources.  If the
  2472. machines do not share a file system, you will have to pre-partition
  2473. the job and generate a script for each machine.  If the machines share
  2474. a (network) file system, you can try to use compiler/etc/xcbfdir.
  2475. This file defines two procedures, COMPILE-DIRECTORY, and
  2476. CROSS-COMPILE-DIRECTORY, that use a simple-minded protocol based on
  2477. creating .tch files to reserve files to compile, and can therefore be
  2478. run on many machines simultaneously without uselessly repeating work
  2479. or getting in each other's way.
  2480. These two methods are not exclusive.  We typically bring up the
  2481. compiler on a new machine by distributing the cross-compilation job.
  2482. The compiler and the cross-compiler use a lot of memory while running,
  2483. and virtual memory is really no substitute for physical memory.  You
  2484. may want to increase your physical memory limit on those systems where
  2485. this can be controlled (e.g. under BSD use the ``limit'' command).  If
  2486. your machines don't have much physical memory, or it is too painful to
  2487. increase your limit, i.e. you have to re-compile or re-link the
  2488. kernel, you may want to use microcode/bchscheme instead of
  2489. microcode/scheme.  Bchscheme uses a disk file for the spare heap,
  2490. rather than a region of memory, putting the available memory to use at
  2491. all times.
  2492.     7.5. Compiler convergence testing.
  2493. Once you have a compiled compiler, you should run the same test suite
  2494. that you ran with the interpreted compiler.  Once you have some degree
  2495. of confidence that the compiled compiler works, you should make sure
  2496. that it can correctly compile itself and the runtime system.  This
  2497. re-compilation can manifest second-order compiler bugs, that is, bugs
  2498. in the compiler that cause it to compile parts of itself incorrectly
  2499. without crashing, so that programs compiled by this
  2500. incorrectly-compiled compiler fail even though these programs did not
  2501. fail when compiled by the original compiler.
  2502. Of course, you can never really tell if the compiler has compiled
  2503. itself successfully.  You can only tell that it is not obviously wrong
  2504. (i.e. it did not crash).  Furthermore, there could be higher-order bugs
  2505. that would take many re-compilations to find.  However, if the binaries
  2506. produced by two successive re-compilations are identical, further
  2507. re-compilations would keep producing identical binaries and no
  2508. additional bugs will be found this way.  Moreover, if the compiler
  2509. and system survive a couple of re-compilations, the compiler is likely
  2510. to be able to compile correctly most programs.
  2511. To run this compiler convergence test, you need to re-compile the
  2512. compiler.  In order to do this, you need to move the .com files from
  2513. the source directories so that COMPILE-DIRECTORY and
  2514. RECOMPILE-DIRECTORY will not skip all the files (they avoid compiling
  2515. those already compiled).  The simplest way to move all these files is
  2516. to type ``make stage1'' at your shell in the source directories
  2517. (runtime, sf, cref, and compiler).  This command will create a STAGE1
  2518. subdirectory for each of the source directories, and move all the .com
  2519. and .binf files there.  You can then use compiler/comp.cbf, or
  2520. compiler/etc/xcbfdir and RECOMPILE-DIRECTORY to regenerate the
  2521. compiler.
  2522. If you generated the stage1 compiled compiler by running the compiler
  2523. interpreted, the new .com files should match the stage1 .com files.
  2524. If you generated the stage1 compiler by cross-compilation, they will
  2525. not.  The cross-compiler turns COMPILER:COMPILE-BY-PROCEDURES? off,
  2526. while the default setting is on.  In the latter case, you want to
  2527. generate one more stage to check for convergence, i.e. execute ``make
  2528. stage2'' in each source directory, and re-compile once more, at each
  2529. stage using the compiler produced by the previous stage.
  2530. Once you have two stages that you think should have identical
  2531. binaries, you can use COMPARE-COM-FILES, defined in
  2532. compiler/etc/comcmp, to compare the binaries.  The simplest way to use
  2533. it is to also load compiler/etc/comfiles and then use the CHECK-STAGE
  2534. procedure.
  2535.     (check-stage "STAGE2" '("runtime" "sf" "compiler/base"))
  2536. will compare the corresponding .com files from runtime and
  2537. runtime/STAGE2, sf and sf/STAGE2, and compiler/base and
  2538. compiler/base/STAGE2.
  2539. If nothing is printed, the binaries are identical.  Otherwise some
  2540. description of the differences is printed.  COMPARE-COM-FILES does not
  2541. check for isomorphism of Scode objects, so any sources that reference
  2542. Scode constants (e.g. runtime/advice.scm) will show some differences
  2543. that can safely be ignored.  Generally, differences in constants can
  2544. be ignored, but length and code differences should be understood.  The
  2545. code in question can be disassembled to determine whether the
  2546. differences are real or not.
  2547. While testing the compiler, in addition to checking for the correct
  2548. operation of the compiled code, you should also watch out for crashes
  2549. and other forms of unexpected failure.  In particular, hardware traps
  2550. (e.g.  segmentation violations, bus errors, illegal instructions)
  2551. occurring during the re-compilation process are a good clue that there
  2552. is a problem somewhere.
  2553.         8. Debugging.
  2554. The process of porting a compiler, due to its complexity, is unlikely
  2555. to proceed perfectly.  Things are likely to break more than once while
  2556. running the compiler and testing the compiled code.
  2557. Debugging a compiler is not trivial, because often the failures
  2558. (especially after a while) will not manifest themselves until days,
  2559. weeks, or months after the compiler was released, at which point the
  2560. context of debugging the compiler has been swapped out by the
  2561. programmer.  Second-order compiler bugs do not make things any easier.
  2562. Liar does not have many facilities to aid in debugging.  This section
  2563. mentions some of the few, and some techniques to use with
  2564. assembly-language debuggers (gdb, dbx, or adb).
  2565. The main assumption in this section is that the front end and other
  2566. machine-independent parts of the compiler work correctly.  Of course,
  2567. this cannot be guaranteed, but in all likelihood virtually all of the
  2568. bugs that you will meet when porting the compiler will be in the new
  2569. machine-specific code.
  2570. If you need to examine some of the front-end data structures, you may
  2571. want to use the utilities in base/debug.scm which is loaded in the
  2572. compiler by default.  In particular, you will want to use PO (for
  2573. print-object) to examine compiler data structures, and
  2574. DEBUG/FIND-PROCEDURE to map procedure names to the data structures
  2575. that represent the procedures, or more correctly, the lambda
  2576. expressions.
  2577.     8.1. Preliminary debugging of the compiled code interface.
  2578. The first item of business, after the microcode interface
  2579. (cmpaux-port.m4 and cmpint-port.h) has been written, is to guarantee
  2580. that properly constructed compiled code addresses do not confuse the
  2581. garbage collector.  This can be done before writing any of the
  2582. remaining files, but you must have rebuilt the microcode and the
  2583. runtime.com band.
  2584. A simple test to run is the following:
  2585.   (define foo
  2586.     ((make-primitive-procedure 'COERCE-TO-COMPILED-PROCEDURE)
  2587.      (lambda (x y)
  2588.        (+ x y))
  2589.      2))
  2590.            
  2591.   (gc-flip)
  2592.   (gc-flip)
  2593.   (gc-flip)
  2594. If the system does not crash or complain, in all likelihood the
  2595. garbage collector can now properly relocate compiled code objects.
  2596. This object can also be used to test parts of the compiled code
  2597. interface.  FOO is bound to a trampoline that will immediately revert
  2598. back to the interpreter when invoked.
  2599. The next test is to determine that FOO works properly.  You can follow
  2600. the execution of FOO by using a debugger and placing breakpoints at
  2601.   cmpint.c:apply_compiled_procedure,
  2602.   cmpaux-port.s:C_to_interface, 
  2603.   cmpaux-port.s:scheme_to_interface (or trampoline_to_interface if it
  2604. is written),
  2605.   cmpint.c:comutil_operator_apply_trap, 
  2606.   cmpint.c:comutil_apply, and
  2607.   cmpaux-port.s:interface_to_C
  2608. and then evaluating (FOO 3 4).
  2609. When setting the breakpoints, remember that C_to_interface,
  2610. scheme_to_interface, and interface_to_scheme are not proper C
  2611. procedures, so you should use the instruction-level breakpoint
  2612. instructions or formats, not the C procedure breakpoint instructions
  2613. or formats.  If you are using adb, this is moot, since adb is purely
  2614. an assembly-language debugger.  If you are using gdb, you should use
  2615. ``break *&C_to_interface'' instead of ``break C_to_interface''.  If
  2616. you are using dbx, you will want to use the ``stopi'' command, instead
  2617. of the ``stop'' command to set breakpoints in the assembly language
  2618. routines.
  2619. Make sure that the arguments to comutil_operator_apply_trap look
  2620. plausible and that the registers have the appropriate contents when
  2621. going into scheme code and back into C.  In particular, you probably
  2622. should examine the contents of the registers right before jumping into
  2623. the trampoline code, and single step the trampoline code until you get
  2624. back to scheme_to_interface.
  2625. In order to parse the Scheme objects, you may want to keep a copy of
  2626. microcode/type.names handy.  This file contains the names of all the
  2627. scheme type tags and their values as they appear in the most
  2628. significant byte of the word when type tags are 8 bits long and 6
  2629. bits long.  Remember that you may have to insert segment bits into
  2630. addresses in order to examine memory locations.
  2631. You should also make sure that an error is signalled when FOO is
  2632. invoked with the wrong number of arguments, and that the system
  2633. correctly recovers from the error (i.e., it gives a meaningful error
  2634. message and an error prompt, and resets itself when you type ^G).
  2635. This test exercises most of the required assembly language code.  The
  2636. only entry point not exercised is interface_to_scheme.
  2637.     8.2. Debugging the assembler.
  2638. Assuming that the compiler generates correctly formatted compiled code
  2639. objects, fasdump should be able to dump them out without a problem.
  2640. If you have problems when dumping the first objects, and assuming that
  2641. you ran the tests in section 8.1., then in all likelihood the block
  2642. offsets are not computed correctly.  You should probably re-examine
  2643. the rule for the EXTERNAL-LABEL pseudo operation, and the block-offset
  2644. definitions in machines/port/assmd.scm.
  2645. Once you can dump compiled code objects, you should test the
  2646. assembler.  A simple, but somewhat inconvenient way of doing this is
  2647. to use adb as a disassembler as follows:
  2648. Scheme binary (.bin and .com) files have a 50 longword header that
  2649. contain relocation information.  The longword that follows immediately
  2650. is the root of the dumped object.  
  2651. If COMPILER:COMPILE-BY-PROCEDURES? is false, the compiler dumps a
  2652. compiled entry point directly, so the format word for the first entry
  2653. is at longword location 53 (* 4 = 0xd4), and the instructions follow
  2654. immediately.
  2655. If COMPILER:COMPILE-BY-PROCEDURES? is true, the compiler dumps an
  2656. Scode object that contains the first entry point as the ``comment
  2657. expression''.  The format word for the first entry point is then at
  2658. longword location 55 (* 4 = 0xdc), and the instructions for the
  2659. top-level block follow immediately.
  2660. Thus, assuming that there are four bytes per Scheme object (unsigned
  2661. long in C), and that foo.com was dumped by the compiler with
  2662. COMPILER:COMPILE-BY-PROCEDURES? set to false, the following would
  2663. disassemble the first 10 instructions of the generated code.
  2664.   adb foo.com
  2665.   0xd8?10i
  2666. If COMPILER:COMPILE-BY-PROCEDURES? was set to true, the following
  2667. would accomplish the same task:
  2668.   adb foo.com
  2669.   0xe0?10i
  2670. You can use adb in this way to compare the input assembly language to
  2671. its binary output.  Remember that you can obtain the input assembly
  2672. language by using the COMPILER:GENERATE-LAP-FILES? switch.
  2673.     8.3. Setting breakpoints in Scheme compiled code.
  2674. Compiled code is not likely to work correctly at first even after the
  2675. compiler stops signalling errors.  In general, when you find that
  2676. compiled code executes incorrectly, you should try to narrow it down
  2677. as much as possible by trying the individual procedures, etc., in the
  2678. code, but ultimately you may need the ability to set instruction-level
  2679. breakpoints and single-step instructions in compiled code.
  2680. A problem peculiar to systems in which code is relocated on the fly is
  2681. that you cannot, in general, obtain a permanent address for a
  2682. procedure or entry point.  The code may move at every garbage
  2683. collection, and if you set a machine-level breakpoint with a Unix
  2684. debugger, and then the code moves, you will probably get spurious
  2685. traps when re-running the code.  Unix debuggers typically replace some
  2686. instructions at the breakpoint location with instructions that will
  2687. cause a specific trap, and then look up the trapping location in some
  2688. table when the debugged process signals the trap.
  2689. One way around this problem is to ``purify'' all compiled scheme code
  2690. that you will be setting breakpoints in.  If you purify the code, it
  2691. will move into ``constant space'' and remain at a constant location
  2692. across garbage collections.  The PURIFY procedure expects an object
  2693. to purify as the first argument, a boolean flag specifying whether the
  2694. object should be moved into constant space (if false) or pure space
  2695. (if true) as a second argument, and a boolean flag specifying whether
  2696. purification should occur immediately (if false) or be delayed until
  2697. the next convenient time (if true) as a third argument.  You should
  2698.   (purify <object> false false)
  2699. when moving compiled code objects to constant space for debugging
  2700. purposes.  Alternatively, you can specify that you want the code to be
  2701. purified when you load it by passing appropriate arguments to LOAD.
  2702. Since load delays the actual purification, you will need to invoke
  2703. GC-FLIP twice to flush the purification queue.
  2704. At any rate, setting the actual breakpoints is not completely trivial,
  2705. since you must find the virtual address of the instructions, and then
  2706. use them with your assembly-language debugger.
  2707. The simplest way to do this is to get Scheme to print the datum of
  2708. the entry points for you, and then type one of Scheme's interrupt
  2709. characters to gain the debugger's attention and set the breakpoint.
  2710. Continuing from the debugger will allow you to type further
  2711. expressions to Scheme.
  2712. Imagine, for example, that we have compiled the runtime file list.scm
  2713. and some of the procedures in it, namely MEMBER and MEMQ, do not work
  2714. properly.  After purifying the code, you can type ``memq'' at the
  2715. read-eval-print loop and it will respond with something like
  2716.  ;Value 37: #[compiled-procedure 37 ("list" #x5A) #x10 #x10FE880]
  2717. This specifies that MEMQ is bound to an ordinary compiled procedure
  2718. (not a closure), that it was originally compiled as part of file
  2719. ``list'' and it was part of compiled code block number 90 (= #x5a) in
  2720. that file.  The current datum of the object is #x10FE880 (this is the
  2721. address without the segment bits if any), and the offset to the
  2722. beginning of the containing compiled code block is #x10.  Thus you
  2723. could then gain the attention of the debugger and set a breakpoint at
  2724. address 0x10fe880 (remember to add the segment bits if necessary) and
  2725. after continuing back into Scheme, use MEMQ normally to trigger the
  2726. breakpoint.
  2727. The case with MEMBER is similar.  Typing ``member'' at the
  2728. read-eval-print loop will cause something like
  2729.  ;Value 36: #[compiled-closure 36 ("list" #x56) #x5C #x10FE484 #x1180DF8]
  2730. to be printed.
  2731. This specifies that MEMBER is bound to a compiled closure, originally
  2732. in compiled code block number 86 (= #x56) in file ``list'', that the
  2733. entry point to the closure is at datum #x1180DF8, that the entry point
  2734. shared by all closures of the same lambda expression (the ``real''
  2735. entry point) is at datum #x10FE484, and that this entry point is at
  2736. offset #x5C of its containing compiled code block.
  2737. Thus if you want to single step the closure code (a good idea when you
  2738. try them at first), you would want to set a breakpoint at address
  2739. #x1180DF8 (plus appropriate segment bits), and if you want to single
  2740. step or examine the real code, then you should use address #x10FE484.
  2741. If you purified the code when you loaded it, the real code would be
  2742. pure, but the closure itself would not be, since it was not a part of
  2743. the file being loaded (closures are created dynamically).  Thus,
  2744. before setting any breakpoints in a closure, you should probably
  2745. purify it as specified above, and obtain its address again, since it
  2746. would have moved in the meantime.
  2747. For example, if you are using adb on an HP-PA (where the top two bits
  2748. of a data segment address are always 01, and thus the top nibble of a
  2749. Scheme's object address is always 4), assuming that the interpreter
  2750. printed the above addresses,
  2751. 0x41180df8:b    would set a breakpoint in the MEMBER closure,
  2752. 0x410fe484:b    would set a breakpoint at the start of the code shared
  2753.         by MEMBER and all closures of the same lambda expression,
  2754. 0x410fe880:b    would set a breakpoint at the start of MEMQ.
  2755. If you are using gdb on a Motorola MC68020 machine, with no segment bits
  2756. for the data segment, the equivalent commands would be
  2757. break *0x1180df8    for a breakpoint in the MEMBER closure,
  2758. break *0x10fe484    for a breakpoint in MEMBER's shared code
  2759. break *0x10fe880    for a breakpoint in MEMQ.
  2760. If you are using dbx, you will need to use a command like 
  2761.  ``stopi at 0x10fe484'' to achieve the same effect.
  2762.     8.4. Examining arguments to Scheme procedures.
  2763. Commonly, after setting a breakpoint at some interesting procedure,
  2764. you will want to examine the arguments.  Currently, Liar passes all
  2765. arguments on the stack.  The Scheme stack always grows towards
  2766. decreasing addresses, and arguments are pushed from left to right. 
  2767. On entry to a procedure, the stack frame must have been reformatted so
  2768. that optional arguments have been defaulted, and tail (lexpr)
  2769. arguments have been collected into a list (possibly empty).  Thus on
  2770. entry to an ordinary procedure's code the stack pointer points to the
  2771. rightmost parameter in the lambda list, and the rest of the parameters
  2772. follow at increasing longword addresses.  
  2773. This is also the case on entry to a closure object's instructions, but
  2774. by the time the shared code starts executing the body of the lambda
  2775. expression, the closure object itself (or its canonical
  2776. representative) will be on top of the stack with the arguments
  2777. following in the standard format.  On entry to a closure's shared
  2778. code, the stack will contain the arguments in the standard format, but
  2779. the closure object will typically be in the process of being
  2780. constructed and pushed, depending on the distribution of the task
  2781. between the instructions in the closure object, the optional helper
  2782. instructions in assembly language, and the instructions in the closure
  2783. header.
  2784. If you are using adb, you can use the following commands:
  2785.  $r        displays the names and contents of the processor
  2786.         registers,
  2787.  <r23=X        displays the contents of the r23 register in hex,
  2788.  0x4040c/4X    displays four longwords in memory at increasing
  2789.         addresses starting with 0x4040c.
  2790. When using gdb, you can achieve the same effect by using the following
  2791. commands:
  2792.  info reg    displays the names and contents of the processor
  2793.         registers,
  2794.  p/x $gr23    displays the contents of processor register gr23,
  2795.  x/4wx 0x4040c    displays four longwords in memory starting at
  2796.         address 0x4040c.
  2797. If you are using dbx, you can use the following commands:
  2798.  print $l4    to display the contents of processor register l4,
  2799.  0x4040c/4X    to display four longwords in memory starting at
  2800.         address 0x4040c.
  2801.     8.5. Tracing the call stack.
  2802. Procedures compiled by Liar receive additional implicit arguments used
  2803. to communicate the lexical environment and the implicit continuation.
  2804. Most procedures receive a return address argument that points to the
  2805. procedure that is waiting for the one at hand to finish.  Some
  2806. procedures receive a static link argument.  Static links are pointers
  2807. into other frames in the stack, used to thread together environments
  2808. when the distance between lexically nested frames cannot be statically
  2809. computed.  Some procedures receive a dynamic link argument.  Dynamic
  2810. links are pointers to return addresses on the stack, and are used when
  2811. the compiler cannot determine statically the distance on the stack
  2812. between the last argument and the return address for a procedure.
  2813. Dynamic links are rarely needed, and static links are needed only
  2814. somewhat more frequently.  Only one of the programs in the test suite
  2815. uses dynamic and static links, and it was carefully constructed to
  2816. make the compiler generate code that uses them.  All externally
  2817. callable procedures, including all those ``closed'' at top level,
  2818. expect return addresses and no other links.
  2819. In general, it is impossible to find out what procedure called another
  2820. in Scheme, due to tail recursion.  Procedures whose last action is a
  2821. call to another procedure, and whose local frames are not part of the
  2822. environment of their callees, will have their frames popped off the
  2823. stack before the callee is entered, and there will be no record left
  2824. of their execution.  The interpreter uses a cache of previous frames
  2825. (called the history) to provide additional debugging information.
  2826. On the other hand, most calls are not in tail position, and a return
  2827. address will be ``passed'' to the callee indicating who the caller
  2828. was.  Occasionally the static and dynamic links will have to be traced
  2829. to find the return address, but this is rare.
  2830. The following assumes that we are dealing with an ordinary procedure
  2831. that expects a return address.
  2832. The return address is passed on the stack, immediately below the
  2833. leftmost argument.  It is a compiled-code entry object whose datum is
  2834. the encoded address of the instruction at which the ``caller'' should
  2835. be reentered.  If the procedure was called from the interpreter, the
  2836. ``caller'' will be a special trampoline (return_to_interpreter) that
  2837. will give control back to the interpreter by using the compiled code
  2838. interface.  There is a little hanky panky in the interpreter to
  2839. guarantee that interpreted code ``tail recursing'' into compiled code
  2840. and viceversa will not push spurious return_to_interpreter return
  2841. addresses and return_to_compiled_code interpreter return codes that
  2842. would break proper tail recursion, but you need not concern yourself
  2843. with this.
  2844. If your debugger allows you to dynamically call C procedures, and it
  2845. is not hopelessly confused by the Scheme register set, you can use the
  2846. C procedure ``compiled_entry_filename'' to determine the filename that
  2847. a return address (or other compiled entry) belongs to.  Its only
  2848. argument should be the compiled entry object whose origin you want to
  2849. find.  Unfortunately, debuggers are often confused by the register
  2850. assignments within Scheme compiled code, precisely when you need them
  2851. most.  You can bypass this problem the following way:
  2852. On entry to a procedure whose return address you wish to examine,
  2853. write down the return address object, change the compiled code's
  2854. version of MemTop so that the comparison with free will fail and the
  2855. code will take an interrupt, set a breakpoint in the runtime library
  2856. routine ``compiler_interrupt_common'', and continue the code.  When
  2857. the new breakpoint is hit, you can use ``compiled_entry_filename'' to
  2858. examine the return address you had written down.
  2859. Here is how to do this the hard way, which you will have to resort to
  2860. often:
  2861. Compiled code blocks generated by the compiler always encompass two
  2862. special locations.  The last location in the compiled code block
  2863. contains the environment where the compiled code block was loaded
  2864. (after the code has been evaluated).  The immediately preceding
  2865. location contains a debugging information descriptor.  This descriptor
  2866. is either a string, namely the name of the file where the compiler
  2867. dumped the debugging information for the block, or a pair whose car is
  2868. the name of the debugging information filename and whose cdr is the
  2869. block number (a fixnum) of the compiled code block in the file, or the
  2870. debugging information itself if the compiled code block was generated
  2871. in core and not dumped.
  2872. Given that the word immediately preceding an external entry point in
  2873. the compiler always contains a gc-offset from the entry point to the
  2874. first word of the compiled code block (i.e. the vector header), or to
  2875. another external entry point if the distance is too large, it is a
  2876. simple, but involved, matter to find this debugging information.  Note
  2877. that all return addresses, full closures, and top-level procedures are
  2878. external entry points.
  2879. For example, imagine that the return address for a procedure is
  2880. 0xa08fe2ee.  Furthermore, assume that we are running on a Motorola
  2881. MC68020 with four bytes per longword, no segment bits, and for which
  2882. cmpint-mc68k.h defines PC_ZERO_BITS to be 1.
  2883. Extracting the word at address 0x8fe2ea (four bytes before the entry
  2884. point), will yield the format longword, that consists of the format
  2885. field in its high halfword, and the encoded gc offset field in the
  2886. lower halfword.
  2887. The gdb command ``x/2hx 0x4fc564'' will print these two halfwords,
  2888. and let's assume that the output is
  2889.  0x8fe2ea <fpa_loc+10445546>:    0x8280    0x003e
  2890. The adb (and dbx) command ``0x4fc564/2x'' should yield similar output.
  2891. This confirms that the object in question is a return address because
  2892. the most significant bit of the format word is a 1, and it would be a
  2893. 0 for a procedure.  The encoded gc offset is 0x3e.  GC offsets and
  2894. format words are described in detail in cmpint.txt.
  2895. Since the least significant bit of the GC offset is 0, it points
  2896. directly to the vector header of a compiled code block.  The real
  2897. offset is
  2898.  ((0x3e >> 1) << PC_ZERO_BITS) = 0x3e
  2899. Thus the compiled code block starts at location
  2900.  0x8fe2ee-0x3e = 0x008fe2b0
  2901. Examining the top two words at this address (using the gdb command
  2902.  ``x/2wx 0x008fe2b0'' or the adb and dbx command ``0x8fe2b0/2X'') we
  2903.  0x8fe2b0 <fpa_loc+10445488>:    0x00000028    0x9c00001d
  2904. The first word is an ordinary vector header, and the second a
  2905. non-marked vector header used to inform the GC that 0x1d longwords of
  2906. binary data, the actual instructions, follow.
  2907. The last location in the vector, containing the environment, is at
  2908. address
  2909.  0x8fe2b0+4*0x28 = 0x8fe350
  2910. Examining the preceding adjacent location and this one (using gdb's
  2911.  ``x/2wx 0x8fe34c'' or a similar command for a different debugger)
  2912. will yield
  2913.  0x8fe34c <fpa_loc+10445644>:    0x0498ef9c    0x4898e864
  2914. The second object is the loading environment, and the first object is
  2915. the debugging information, in this case a pair.  This pair can be
  2916. examined (using gdb's ``x/2wx 0x98ef9c'' or an analogous command for a
  2917. different debugger) to yield
  2918.  0x98ef9c <fpa_loc+11038620>:    0x789ac5ec    0x6800001c
  2919. The first object is a string, and the second a fixnum, indicating that
  2920. the return address at hand belongs to the compiled code block numbered
  2921. 0x1c in the file whose name is that string.
  2922. Scheme strings have two longwords of header, followed by an ordinary C
  2923. string that includes a null terminating character, thus the C string
  2924. starts at address 0x9ac5ec+4*2=0x9ac5f4, and the gdb command
  2925.  ``x/s 0x9ac5f4'' or the adb and dbx command ``0x9ac5f4/s''
  2926. will display something like:
  2927.  0x9ac5f4 <fpa_loc+11159028>:    
  2928.     (char *) 0x9ac5f4 "/usr/local/lib/mit-scheme/SRC/runtime/parse.binf"
  2929. Thus the return address we are examining is at offset 0x3e in compiled
  2930. code block number 0x1c of the runtime system file ``parse.com''.
  2931. If the disassembler is available, you can then use
  2932.  (compiler:write-lap-file "parse")
  2933. to find out what this return address is, or if you compiled (or
  2934. re-compile) parse.scm generating lap files, you can probably guess
  2935. what return address is at offset 0x3e (the input lap files do not
  2936. contain computed offsets, since these are computed on final assembly).
  2937. This interaction would remain very similar for other machines and
  2938. compiled entry points, given the same or similar debuggers.  The
  2939. variations would be the following:
  2940. - Segment bits might have to be added to the object datum components
  2941. to produce addresses.  For example, on the HP-PA with segment bits 01
  2942. at the most significant end of a word, the C string for Scheme string
  2943. object 0x789ac5ec would start at address 0x409ac5ec+8=0x409ac5f4,
  2944. instead of at address 0x9ac5ec+8=0x9ac5f4.
  2945. - The gc offset might be computed differently, depending on the value
  2946. of PC_ZERO_BITS.  For example, on a Vax, where PC_ZERO_BITS has the
  2947. value 0, an encoded offset of value 0x3e would imply a real offset of
  2948. value (0x3e >> 1)=0x1f.  On a MIPS R3000, where PC_ZERO_BITS is 2, the
  2949. same encoded offset would encode the real offset value 
  2950.  ((0x3e >> 1) << 2)=0x7c.  In addition, if the low order bit of the
  2951. encoded gc offset field were 1, a new gc offset would have to be
  2952. extracted, and the process repeated until the beginning of the block
  2953. was reached.
  2954. - The constant offsets added to various addresses (e.g. that added to
  2955. a string object's address to obtain the C string's address) would vary
  2956. if the number of bytes per Scheme object (sizeof (unsigned long)) in C
  2957. were not 4.
  2958. - Not all compiled entry points have debugging information descriptors
  2959. accessible the same way.  Trampolines don't have them at all, and
  2960. closures have them in the shared code, not in the closure objects.  To
  2961. check whether something is a trampoline, you can check the format
  2962. field (most trampolines have 0xfffd) or verify that the instructions
  2963. immediately call the compiled code interface.  Closure objects have
  2964. type code MANIFEST-COMPILED-CLOSURE instead of MANIFEST-VECTOR in the
  2965. length word of the compiled code block.  Once you obtain the real
  2966. entry point for a closure, you can use the same method to find out the
  2967. information about it.
  2968.     8.6. Things to watch out for.
  2969. The worst bugs to track are interrupt and garbage-collection related.
  2970. They will often make the compiled code crash at seemingly random
  2971. points, and are very hard to reproduce.  A common source of this kind
  2972. of bug is a problem in the rules for procedure headers.  Make sure
  2973. that the rules for the various kinds of procedure headers generate the
  2974. desired code, and that the desired code operates correctly.  You can
  2975. test this explicitly by using an assembly-language debugger to set
  2976. breakpoints at the entry points of various kinds of procedures.  When
  2977. the breakpoints are reached, you can bump the Free pointer to a value
  2978. larger than MemTop, so that the interrupt branch will be taken.  If
  2979. the code continues to execute correctly, you are probably safe.  You
  2980. should especially check procedures that expect dynamic links for these
  2981. must be saved and restored correctly.  Closures should also be tested
  2982. carefully, since they need to be reentered correctly, and the closure
  2983. object on the stack may have to be de-canonicalized.  Currently
  2984. C_to_interface and interface_to_scheme must copy the interpreter's
  2985. value register into the compiler's value register, and must extract
  2986. the address of this value and store it in the dynamic link register.
  2987. Register allocation bugs also manifest themselves in unexpected ways.
  2988. If you forget to use NEED-REGISTER! on a register used by a LAPGEN
  2989. rule, or if you allocate registers for the sources and target of a
  2990. rule in the wrong order (remember the cardinal rule!), you may not
  2991. notice for a long time, but some poor program will.  If this happens,
  2992. you will be lucky if you can find and disassemble a relatively small
  2993. procedure that does not operate properly, but typically the only
  2994. notice you will get is when Scheme crashes in an unrelated place.
  2995. Fortunately, this type of bug is reproducible.  In order to find the
  2996. incorrectly compiled code, you can use binary search on the sources by
  2997. mixing interpreted and compiled binaries.  When loading the compiler,
  2998. .bin files will be used for those files for which the corresponding
  2999. .com file does not exist.  Thus you can move .com files in and out of
  3000. the appropriate directories, reload, and test again.  Once you
  3001. determine the procedure in which the bug occurs, re-compiling the
  3002. module and examining the resulting RTL and LAP programs should lead to
  3003. identification of the bug.
  3004.         9. Bibliography
  3005. 1. "Efficient Stack Allocation for Tail-Recursive Languages" by Chris
  3006. Hanson, in Proceedings of the 1990 ACM Conference on Lisp and
  3007. Functional Programming.
  3008. 2. "Free Variables and First-Class Environments" by James S. Miller
  3009. and Guillermo J. Rozas, in Lisp and Symbolic Computation, 4, 107-141,
  3010. 1991, Kluwer Academic Publishers.
  3011. 3. "MIT Scheme User's Manual for Scheme Release 7.1" by Chris Hanson,
  3012. distributed with MIT CScheme version 7.1.
  3013. 4. "MIT Scheme Reference Manual for Scheme Release 7.1" by Chris
  3014. Hanson, distributed with MIT CScheme version 7.1.
  3015. 5. "Taming the Y Operator" by Guillermo J. Rozas, in Proceedings of
  3016. the 1992 ACM Conference on Lisp and Functional Programming.
  3017.         A.1. MIT Scheme package system
  3018. The MIT Scheme package system is used to divide large programs into
  3019. separate name spaces which are then ``wired together''.  A large
  3020. program, like the runtime system, Edwin, or the compiler, has many
  3021. files and variable names all of which must exist at the same time
  3022. without conflict.  The package system is a prototype system to
  3023. accomplish this separation, but will probably be replaced once a
  3024. better module system is developed.
  3025. Currently, each package corresponds, at runtime, to a Scheme
  3026. environment.  Environments have their usual, tree-shaped structure,
  3027. and packages are also structured in a tree, but the trees need not be
  3028. isomorphic, although they often are.
  3029. Each package is given a name, e.g.:
  3030.   (compiler reference-contexts)
  3031. whose corresponding environment can be found using the procedure
  3032. ->ENVIRONMENT:
  3033.   (->environment '(compiler reference-contexts))    ;; Call this CR
  3034. By convention, this package corresponds to an environment below the
  3035.   (->environment '(compiler))                ;; Call this C
  3036. environment, and therefore CR contains all variables defined in C, as
  3037. well as those specifically defined in CR.  The package name ``()''
  3038. corresponds to the system global environment.
  3039. The package structure for the compiler is defined in the file
  3040.   <compiler-directory>/machines/<machine-name>/comp.pkg
  3041. In that file, each package has a description of the form:
  3042.   (define-package <NAME>
  3043.     (files <FILES>)
  3044.     (parent <PACKAGE-NAME>)
  3045.     (export <PACKAGE-NAME> <VARIABLES>)
  3046.     (import <PACKAGE-NAME> <VARIABLES>))
  3047. where <FILES> are the names of the files that should be loaded in to
  3048. package <NAME>.
  3049.   (parent <PACKAGE-NAME>)
  3050. declares the package whose name is <PACKAGE-NAME> to be the parent
  3051. package of <NAME>.  Lexical scoping will make all variables visible in
  3052. <PACKAGE-NAME> also visible in <NAME>.
  3053. The EXPORT and IMPORT declarations are used to describe cross-package
  3054. links.  A package may export any of its variables to any other
  3055. package using EXPORT; these variables will appear in both packages
  3056. (environments), and any side effect to one of these variables in
  3057. either package will be immediately visible in the other package.
  3058. Similarly, a package may import any of another package's variables
  3059. using IMPORT.  Any number (including zero) of IMPORT and EXPORT
  3060. declarations may appear in any package declaration.
  3061. Here is an example package declaration, drawn from the compiler:
  3062.   (define-package (compiler top-level)
  3063.     (files "base/toplev"
  3064.        "base/crstop")
  3065.     (parent (compiler))
  3066.     (export ()
  3067.         cf
  3068.         compile-bin-file
  3069.         compile-procedure
  3070.         compile-scode
  3071.         compiler:reset!
  3072.         cross-compile-bin-file
  3073.         cross-compile-bin-file-end)
  3074.     (export (compiler fg-generator)
  3075.         compile-recursively)
  3076.     (export (compiler rtl-generator)
  3077.         *ic-procedure-headers*
  3078.         *rtl-continuations*
  3079.         *rtl-expression*
  3080.         *rtl-graphs*
  3081.         *rtl-procedures*)
  3082.     (export (compiler lap-syntaxer)
  3083.         *block-label*
  3084.         *external-labels*
  3085.         label->object)
  3086.     (export (compiler debug)
  3087.         *root-expression*
  3088.         *rtl-procedures*
  3089.         *rtl-graphs*)
  3090.     (import (runtime compiler-info)
  3091.         make-dbg-info-vector)
  3092.     (import (runtime unparser)
  3093.         *unparse-uninterned-symbols-by-name?*))
  3094. The read-eval-print loop of Scheme evaluates all expressions in the
  3095. same environment.  It is possible to change this environment using the
  3096. procedure GE, e.g.:
  3097.   (ge (->environment '(compiler top-level)))
  3098. To find the package name of the current read-eval-print loop
  3099. environment, if there is one, evaluate:
  3100.   (pe)
  3101. The package system is currently completely static; it is difficult to
  3102. create packages and wire them together on the fly.  If you find that
  3103. you need to temporarily wire a variable to two different environments
  3104. (as you would do with an IMPORT or EXPORT declaration), use the
  3105. procedure ENVIRONMENT-LINK-NAME:
  3106.   (environment-link-name <TO-ENVIRONMENT>
  3107.              <FROM-ENVIRONMENT>
  3108.              <VARIABLE-SYMBOL-NAME>)
  3109. For example, to make WRITE-RESTARTS, originally defined in the
  3110. (runtime debugger) package, also visible in the (edwin debugger)
  3111. package, evaluate:
  3112.   (environment-link-name (->environment '(edwin debugger))
  3113.              (->environment '(runtime debugger))
  3114.              'write-restarts)
  3115.