Переглянути джерело

*** empty log message ***

keie 40 роки тому
батько
коміт
c693044013
1 змінених файлів з 2163 додано та 0 видалено
  1. 2163 0
      doc/6500.doc

+ 2163 - 0
doc/6500.doc

@@ -0,0 +1,2163 @@
+. \" $Header$"
+.po +10
+.ND
+.TL
+.B
+A backend table for the 6500 microprocessor
+.R
+.AU
+Jan van Dalen
+.AB
+The backend table is part of the Amsterdam Compiler Kit (ACK).
+It translates the intermediate language family EM to a machine
+code for the MCS6500 microprocessor family.
+.AE
+.PP
+.bp
+.NH
+Introduction.
+.PP
+As more and more organizations aquire many micro and minicomputers,
+the need for portable compilers is becoming more and more acute.
+The present situation, in which each harware vendor provides its
+own compilers -- each with its own deficiencies and extensions, and
+none of them compatible -- leaves much to be desired.
+The ideal situation would be an integrated system containing
+a family of (cross) compilers, each compiler accepting a standard
+source language and, producing code for a wide variety of target
+machines. Furthermore, the compilers should be compatible, so programs 
+written in one language can call procedures written in another
+language. Finally, the system should be designed so as to make
+adding new languages and, new machines easy. Such an integerated
+system is being built at the Vrije Universiteit.
+.PP
+The compiler building system, which is called the "Amsterdam Compiler
+Kit" (ACK), can be thought of as a "tool kit." It consists of
+a number of parts that can be combined to form compilers (and
+interpreters) with various properties. The tool kit is based
+on an idea (UNCOL) that was first suggested in 1960 [5],
+but which never really caught on then. The problem which UNCOL
+attemps to solve is how to make a compiler for each of
+.B
+N
+.R
+languages on
+.B
+M
+.R
+different machines without having to write
+.B
+N
+.R
+x
+.B
+M
+.R
+programs.
+.PP
+As shown in Fig. 1, the UNCOL approach is to write
+.B
+N
+.R
+"front ends," each of which translates
+one source language to a common
+intermediate language, UNCOL (UNiversal Computer Oriented
+Language), and
+.B
+M
+.R
+"back ends," each of which translates programs
+in UNCOL to a specific machine language. Under these conditions,
+only
+.B
+N
+.R
++
+.B
+M
+.R
+programs must be written to provide all
+.B
+N
+.R
+languages on all
+.B
+M
+.R
+machines, instead of
+.B
+N
+.R
+x
+.B
+M
+.R
+programs.
+.PP
+Various reseachers have attempted to design a suitable UNCOL [1,6],
+but none of these have become popular. It is the believe of the
+designers of the Amsterdam Compiler Kit that previous attemps 
+have failed because they have been too ambitious, that is, they have
+tried to cover all languages and all machines using a single UNCOL.
+The approach of the designers is more modest:
+they cater only to algebraic languages and machines whose memory
+consist of 8-bit bytes, each with its own address.
+Typical languages that could be handled include Ada, ALGOL 60,
+ALGOL 68, BASIC, C, FORTRAN, Modula, Pascal, PL/I, PL/M, PLAIN and
+RATFOR, where COBOL, LISP and SNOBOL would be less efficient.
+Examples of machines that could be included are the Intel 8080 and
+8086, Motorola 6800, 6809 and 68000, Zilog Z80 and Z8000, DEC PDP-11
+and Vax, MOS Technology MCS6500 family and IBM but not the Burroughs
+6700, CDC Cyber or Univac 1108 (because they are not byte_oriented).
+With these restrictions the designers believe that the old UNCOL
+idea can be used as the basis of a practical compiler-building 
+system.
+.sp 10
+.bp
+.NH
+An overview of the Amsterdam Compiler kit
+.PP
+The tool kit consists of eight components:
+.IP 1.
+The preprocessor.
+.IP 2.
+The front ends.
+.IP 3.
+The peephole optimizer.
+.IP 4.
+The global optimizer.
+.IP 5.
+The back end.
+.IP 6.
+The target machine optimizer.
+.IP 7.
+The universal assembler/linker.
+.IP 8.
+The utility package.
+.PP
+A fully optimizing compiler, depicted in Fig. 2, has seven cascaded
+phases. Conceptually, each component reads an input file and writes
+a transformed output file to be used as input to the next component.
+In practice, some components may use temporary files to allow
+multiple passes over the input or internal intermediate files.
+.sp 20
+.PP
+In the following paragraphs a brief decription of each component
+is given.
+A more detailed description of the back end will be given in the 
+rest of this document. For a more detailed descripiton on the rest
+of the components see [7]. A program to be compiled is first fed
+into the (language independed) preprocessor, which provides a
+simple macro facility and similar textual facilities.
+The preprocessor's ouput is a legal program in one of the programming
+languages supported, whereas the input is a program possibly
+augmented with macro's, etc.
+.PP
+This output goes into the appropriate front end, whose job it is to 
+produce intermediate cade.
+This intermediate code (the UNCOL of ACK) is the machine language
+for a simple stack machine EM (Encoding Machine).
+A typical front end might build a parse tree from the input
+and then use the parse tree to generate EM cade,
+which is similar to reverse Polish.
+In order to perform this work, the front end has to maintain tables of declare
+tables of declared variables, labels, etc., determine where
+to place the data structures in memory and so on.
+.PP
+The EM code generated by the front end is fed into the peephole
+optimizer, which scans it with a window of a view instructions,
+replacing certain inefficient code sequences by better ones.
+Such a search is important because EM contains instructions to
+handle numerous important special cases efficiently
+(e.g. incrementing a variable by 1).
+It is our strategy to relieve the front ends of the burden
+of hunting for special cases because there are many front ends
+and just one peephole optimizer.
+By handeling the special cases in the peephole optimizer,
+the front ends become simpler, easier to write and easier to maintain.
+.PP
+Following the peephole optimizer is a global optimizer [2],
+which unlike the peephole optimizer, examines the program as a whole.
+It builts a data flow graph to make possible a variety of global
+optimizations, among them, moving invariant code out of loops,
+avoiding redundant computations, live/dead analysis and
+eliminating tail recursion.
+Note that the output of the global optimizer is still EM code.
+.PP
+Next comes the back end, which differs from the front ends in a
+fundamental way.
+Each front end is a separate program, whereas the back end is a 
+single program that is driven by a machine dependent driving table.
+The driving table for a specific machine tells how EM code is
+mapped onto the machine's assembly language.
+Although a simple driving table just might macro expand each
+EM instruction into a sequence of target machine instructions,
+a much more sophisticated translation strategy is normaly used,
+as described later.
+For speech, the back end does not actually read in the driving
+table at run time.
+Instead, the tables are compiled along with the back end in advance,
+resulting in one binairy program per machine.
+.PP
+The output of the back end is a program in the assembly language
+of some particular machine.
+The next component in the pipeline reads this program and performs
+peephole optimization on it.
+The optimizations performed here involve idiosyncrasies of the
+target machine that cannot be performed by the machine-independent
+EM-to-EM peephole optimizer.
+Typically these optimizations take advantage of the special
+instructions or special addressing modes.
+.PP
+The optimized target machine assembly code then goes into the final
+component in the pipeline, the universal assembler/linker.
+This program assembles the input to object format, extracting
+routines from libraries and including them as needed.
+.PP
+The final component of the tool kit is the utility package,
+which contains various test programs, interpreters for EM code,
+EM libraries, conversion programs and other aids for the
+implementer and user.
+.bp
+.DS C
+.B
+THE MCS6500 MICROPROCESSOR.
+.R
+.DE
+.NH 0
+Introduction
+.PP
+Why a back end table for the MCS6500 microprocessor family.
+Although the MCS6500 microprocessor family has an simple
+instruction set and internal structure, it is used in a
+variety of microcomputers and homecomputers.
+This is because of is low cost.
+As an example the Apple II, a well known and width spread
+microprocessor, uses the MCS6502 CPU.
+Also the BBC homecomputer, whose popularity is growing day
+by day uses the MCS6502 CPU.
+The BBC homecomputer is based on the MCS6502 CPU although 
+better and stronger microprocessors are available.
+The designers of Acorn computer Industries have probably
+choosen for the MCS6502 because of the amount of software
+available for this CPU.
+Since its width spreaded use, a variaty of software
+will be needed for it.
+One can think of games!!, administration programs,
+teaching programs, basic interpreters and other application
+programs.
+Even do it will not be possible to run the total compiler kit
+on a MCS6500 based computer, it is possible to write application
+programs in a high level language, such as Pascal or C on a
+minicomputer.
+These application programs can be tested and compiled on that
+minicomputer and put in a ROM (Read Only Memory), for example,
+cso that it an be executed by a MCS6500 CPU.
+The strategy of writing testprograms on a minicomputer, 
+compile it and then execute it on a MCS6500 based
+microprocessor is used by the development of the back end.
+The minicomputer used is M68000 based one, manufactured by
+Bleasdale Computer Systems Ltd..
+The micro- or homecomputer used is a BBC microcomputer,
+manufactured by Acorn Computer Ltd..
+.NH
+The MOS Technology MCS6500
+.PP
+The MCS6500 is as a family of CPU devices developed by MOS
+Technology.
+The members of the MCS6500 family are the same chips in a 
+different housing.
+The MCS6502, the big brother in the family, can handle 64k
+bytes of memory, while for example the MCS6504 can only handle
+8k bytes of memory.
+This difference is due to the fact that the MCS6502 is in a
+40 pins house and the MCS6504 has a 28 pins house, so less
+address lines are available.
+.bp
+.NH
+The MCS6500 CPU programmable registers
+.PP
+The MCS6500 series is based on the same chip so all have the
+same programmable registers.
+.sp 9
+.NH 2
+The accumulator A.
+.PP
+The accumulator A is the only register on which the arithmetic
+and logical instructions can be used.
+For example, the instruction ADC (add with carry) adds the
+contents of the accumulator A and a byte from memory or data.
+.NH 2
+The index register X.
+.PP
+As the name suggests this register can be used for some
+indirect addressing modes.
+The modes are explaned below.
+.NH 2
+The index register Y.
+.PP
+This register is, just as the index register X, used for
+certain indirect addressing modes.
+These addressing modes are different from the modes which
+use index register X.
+.NH 2
+The program counter PC
+.PP 
+This is the only 16-bit register available.
+It is used to point to the next instruction to be
+carried out.
+.NH 2
+The stack pointer SP
+.PP
+The stack pointer is an 8-bit register, so the stack can contain
+at most 256 bytes.
+The CPU always appends 00000001 as highbyte of any stack address,
+which means that memory locations
+.B
+0100
+.R
+through
+.B
+01FF
+.R
+are permanently assigned to the stack.
+.sp 12
+.NH 2
+The status register
+.PP
+The status register maintains six status flags and a master
+interrupt control bit.
+.br
+These are the six status flags:
+    Carry        (c)
+    Zero         (z)
+    Overflow     (o)
+    Sign         (n)
+    Decimal mode (d)
+    Break        (b)
+
+
+
+
+
+The bit (i) is the master interrupt control bit.
+.NH
+The MCS6500 memory layout.
+.PP
+In the MCS6500 memory space three area's have special meaning.
+These area's are:
+.IP 1)
+Top page.
+.IP 2)
+Zero page.
+.IP 3)
+The stack.
+.PP
+MCS6500 memory is divided up into pages.
+These pages consist 256 bytes.
+So in a memory address the highbyte denotes the page number
+and the lowbyte the offset within the page.
+.NH 2
+Top page.
+.PP
+When a MCS6500 is restared it jumps indirect via memory address
+.B
+FFFC.
+.R
+At
+.B
+FFFC
+.R
+(lowbyte) and 
+.B
+FFFD
+.R
+(highbyte) there must be the address of the bootstrap subroutine.
+When a break instruction (BRK) occurs or an interrupt takes place,
+the MCS6500 jumps indirect through memory address
+.B
+FFFE.
+.R
+.B
+FFFE
+.R
+and 
+.B
+FFFF
+.R
+thus, must contain the address of the interrupt routine.
+The former only goes for maskeble interrupt.
+There also exist a nonmaskeble interrupt.
+This cause the MCS6500 to jump indirect through memory address
+.B
+FFFA.
+.R
+So the top six bytes of memory are used by the operating system
+and therefore not available for the back end.
+.NH 2
+Zero page.
+.PP
+This page has a special meaning in the sence that addressing
+this page uses special opcodes.
+Since a page consists of 256 bytes, only one byte is needed
+for addressing zero page.
+So an instruction which uses zero page occupies two bytes.
+It also uses less clock cycle's while carrying out the instruction.
+Zero page is also needed when indirect addressing is used.
+This means that when indirect addressing is used, the address must
+reside in zero page (two consecutive bytes).
+In this case (the back end), zero page is used, for example
+to hold the local base, the second local base, the stack pointer
+etc.
+.NH 2
+The stack.
+.PP
+The stack is described in paragraph 3.5 about the MCS6500
+programmable registers.
+.NH 
+The memory adressing modes
+.PP
+MCS6500 memory reference instructions use direct addressing,
+indexed addressing, and indirect addressing.
+.NH 2
+direct addressing.
+.PP
+Three-byte instructions use the second and third bytes of the
+object code to provide a direct 16-bit address:
+therefore, 65.536 bytes of memory can be addressed directly.
+The commonly used memory reference instructions also have a two-byte
+object code variation, where the second byte directly addresses
+one of the first 256 bytes.
+.NH 2
+Base page, indexed addressing.
+.PP
+In this case, the instruction has two bytes of object code.
+The contents of either the X or Y index registers are added to the 
+second  object code byte in order to compute a memory address.
+This may be illustrated as follows:
+.sp 15
+Base page, indexed addressing, as illustrated above, is 
+wraparound - which means that there is no carry.
+If the sum of the index register and second object code byte contents
+is more than
+.B
+FF
+.R
+, the carry bit will be dicarded.
+This may be illustrated as follows:
+.sp 9
+.NH 2
+Absolute indexed addressing.
+.PP
+In this case, the contents of either the X or Y register are added
+to a 16-bit direct address provided by the second and third bytes
+of an instruction's object code.
+This may be illustrated as follows:
+.sp 10
+.NH 2
+Indirect addressing.
+.PP
+Instructions that use simple indirect addressing have three bytes of
+object code.
+The second and third object code bytes provide a 16-bit address;
+therefore, the indirect address can be located anywhere in
+memory.
+This is straightforward indirect addressing.
+.NH 3
+Pre-indexed indirect addressing.
+.PP
+In this case, the object code consists of two bytes and the 
+second object code byte provides an 8-bit address.
+Instructions that use pre-indexed indirect addressing add the contents
+of the X index register and the second object code byte to access
+a memory location in the first 256 bytes of memory, where the 
+indirect address will be found:
+.sp 18
+When using pre-indexed indirect addressing, once again wraparound
+addition is used, which means that when the X index register contents
+are added to the second object code byte, any carry will be discarded.
+Note that only the X index register can be used with pre-indexed
+addressing.
+.NH 3
+Post-indexed indirect addressing.
+.PP
+In this case, the object code consists of two bytes and the
+second object code byte provides an 8-bit address.
+Now the second object code byte indentifies a location
+in the first 256 bytes of memory where an indirect address
+will be found.
+The contents of the Y index register are added to this indirect
+address.
+This may be illustrated as follows:
+.sp 18
+Note that only the Y index register can be used with post-indexed
+indirect addressing.
+.bp
+.NH
+What the CPU has and doesn't has.
+.PP
+Although the designers of the MCS6500 CPUs family state that
+there is nothing very significant about the short stack (only
+256 bytes) this stack caused problems for the back end.
+The designers say that a 256-byte stack usually is sufficient
+for any typical microcomputer, this is only true if the stack
+is used only for return addresses of the JSR (jump to
+subroutine) instruction.
+But since the EM machine is suppost to be a stack machine and
+high level languages need the ability of parameters and
+locals in there procedures and function, this short stack
+is unsufficiant.
+So an software stack is implemented in this back end, requiring two
+additional subroutines for stack handling.
+These two stack handling subroutines slow down the processing time
+of a program since the stack is used heavely.
+.PP
+Since parameters and locals of EM procedures are offseted
+from the localbase of that procedure, indirect addressing
+is havily used.
+Offsets are positive (for parameters) and negative (for
+local variables).
+As explaned before the addressing modes the MCS6500 have a
+post indexed indirect addressing mode.
+This addressing mode can only handle positive offsets.
+This raises a problem for accessing the local variables
+I have chosen for the next solution.
+A second local base is introduced.
+This second local base is the real local base subtracted by
+a constant BASE.
+In the present situation of the back end the value of BASE
+is 240.
+This means that there are 240 bytes reseved for local
+variables to be indirect addressed and 14 bytes for
+the parameters.
+.DS C
+.B
+THE CODE GENERATOR.
+.R
+.DE
+.NH 0
+Description of the machine table.
+.PP
+The machine description table consists of the following sections:
+.IP 1.
+The macro definitions.
+.IP 2.
+Constant definitions.
+.IP 3.
+Register definitions.
+.IP 4.
+Token definitions.
+.IP 5.
+Token expressions.
+.IP 6.
+Code rules.
+.IP 7.
+Move definitions.
+.IP 8.
+Test definitions.
+.IP 9.
+Stack definitions.
+.NH 2
+Macro definitions.
+.PP
+The macro definitions at the top of the table are expanded
+by the preprocessor on occurence in the rest of the table.
+.NH 2
+Constant definitions.
+.PP
+There are three constants which must be defined at first.
+The are:
+.IP EM_WSIZE: 11
+Number of bytes in a machine word.
+This is the number of bytes a simple
+.B
+loc
+.R
+instruction will put on the stack.
+.IP EM_PSIZE:
+Number of bytes in a pointer.
+This is the number of bytes a
+.B
+lal
+.R
+instruction will put on the stack.
+.IP EM_BSIZE:
+Number of bytes in the hole between AB and LB.
+The calling sequence only saves LB on the stack so this
+constant is equal to the pointer size.
+.NH 1
+Register definitions.
+.PP
+The only important register definition is the definition of
+the registerpair AX.
+Since the rest of the machine's registers Y, PC, ST serve
+special purposes, the code generator cannot use them.
+.NH 2
+Token definitions
+.PP
+There is a fake token.
+This token is put in the table, since the code generator generator
+complains if it cannot find one.
+.NH 2
+Token expression definitions.
+.PP
+The token expression is also a fake one.
+This token expression is put in the table, since the code generator
+generator complains if it cannot find one.
+.NH 2
+Code rules.
+.PP
+The code rule section is the largest section in the table.
+They specify EM patterns, stack patterns, code to be generated,
+etc.
+The syntax is:
+.IP code rule:
+EM pattern '|' stack pattern '|' code '|'
+stack replacement '|' EM replacement '|'
+.PP
+All patterns are optional, however there must be at least one
+pattern present.
+If the EM pattern is missing the rule becomes a rewriting
+rule or a
+.B
+coercion
+.R
+to be used when code generation cannot continue because of an
+invalid stack pattern.
+The code rules are preceeded by the word CODE:.
+.NH 3
+The EM pattern.
+.PP
+The EM pattern consists of a list of EM mnemonics followed by
+a boolean expression. Examples:
+.sp 1
+.br
+.B
+loe
+.R
+.sp 1
+will match a single
+.B
+loe
+.R
+instruction,
+.sp 1
+.br
+.B
+loc loc cif
+.R
+$1==2 && $2==8
+.sp 1
+is a pattern that will match
+.sp 1
+.br
+.B
+loc
+.R
+2
+.br
+.B
+loc
+.R
+8
+.br
+.B
+cif
+.R
+.sp 1
+and
+.sp 1
+.br
+.B
+lol
+inc
+stl
+.R
+$1==$3
+.sp 1
+will match for example
+.sp 1
+.br
+.B
+lol
+.R
+6
+.br
+.B
+inc
+.R
+.br
+.B
+stl
+.R
+6
+.sp 1
+A missing boolean expession evaluates to TRUE.
+.PP
+The code generator will match the longest EM pattern on every occasion,
+if two patterns of the same length match the first in the table
+will be chosen, while all patterns of length greater than or equal
+to three are considered to be of the same length.
+.NH 3
+The stack pattern.
+.PP
+The only stack pattern that can occur is R16, which means that the
+registerpair AX contains the word on top of the stack.
+If this is not the case a coersion occurs.
+This coersion generates a "jsr Pop", which means that the top
+of the stack is popped and stored in the registerpair AX.
+.NH 3
+The code part.
+.PP
+The code part consists of three parts, stack cleanup, register
+allocation, and code to be generated.
+All of these may be omitted.
+.NH 4
+Stack cleanup.
+.PP
+When generating something like a branch instruction it might be
+needed to empty the fake stack, that is, remove the AX registerpair.
+This is done by the instruction remove(ALL)
+.NH 4
+Register allocation.
+.PP
+If the machine code to be generated uses the registerpair AX,
+this is signaled to the code generator by the allocate(R16)
+instruction.
+If the registerpair AX resides on the fake stack, this will result
+in a "jsr Push", which means that the registerpair AX is pushed on
+the stack and will be free for further use.
+If registerpair AX is not on the fake stack nothing happens.
+.NH 4
+Code to be generated.
+.PP
+Code to be generated is specified as a list of items of the following
+kind:
+.IP 1)
+A string in double quotes("This is a string").
+This is copied to the codefile and a newline ('\n') is appended.
+Inside the string all normal C string conventions are allowed,
+and substitutions can be made of the following sorts.
+.RS
+.IP a)
+$1, $2 etc. These are the operand of the corresponding EM 
+instructions and are printed according to there type.
+To put a real '$' inside the string it must be doubled ('$$').
+.IP b)
+%[1], %[2.reg], %[b.1] etc. these have there obvious meaning.
+If they describe a complete token (%[1]) the printformat for
+the token is used.
+If they stand fo a basic term in an expression they will be
+printed according to their type.
+To put a real '%' inside the string it must be doubled ('%%').
+.IP c)
+%( arbitrary expression %). This allows inclusion of arbitrary
+expressions inside strings.
+Usually not needed very often, so that the akward notation
+is not too bad.
+Note that %(%[1]%) is equivalent to %[1].
+.RE
+.NH 3
+stack replacement.
+.PP
+The stack replacement is a possibly empty list of items to be
+pushed on the fake stack.
+Three things can occur:
+.IP 1)
+%[1] is used if the registerpair AX was on the fake stack and is
+to be pushed back onto it.
+.IP 2)
+%[a] is used if the registerpair AX is allocated with allocate(R16)
+and is to be pushed onto the fake stack.
+.IP 3)
+It can also be empty.
+.NH 3
+EM replacement.
+.PP
+In exeptional cases it might be useful to leave part of the an EM
+pattern undone.
+For example, a
+.B
+sdl
+.R
+instruction might be split into two
+.B
+stl
+.R
+instructions when there is no 4-byte quantity on the stack.
+The EM replacement part allows one to express this.
+Example:
+.sp 1
+.br
+.B
+stl
+.R
+$1
+.B
+stl
+.R
+$1+2
+.sp 1
+The instructions are inserted in the stream so they can match
+the first part of a pattern in the next step.
+Note that since the code generator traverses the EM instructions
+in a strict linear fashion, it is impossible to let the EM
+replacement match later parts of a pattern.
+So if there is a pattern
+.sp 1
+.br
+.B
+loc
+stl
+.R
+$1==0
+.sp1
+and the input is
+.sp 1
+.br
+.B
+loc
+.R
+0
+.B
+sdl
+.R
+4
+.sp 1
+the
+.B
+loc
+.R
+0
+will be processed first, then the
+.B
+sdl
+.R
+might be split into two
+.B
+stl
+.R
+'s but the pattern cannot match now.
+.NH 3
+Move definitions.
+.PP
+This definition is a fake. This definition is put in the
+table, since the code generator generator complains if it
+cannot find one.
+.NH 3
+Test definitions.
+.PP
+Test definitions aren't used by the table.
+.NH 3
+Stack definitions.
+.PP
+When the generator has to push the registerpair AX, it must
+know how to do so.
+The machine code to be generated is defined here.
+.NH 1
+Some remarks.
+.PP
+The above description of the machine table is
+a description of the table for the MCS6500.
+It uses only a part of the possibilities which the code generator
+generator offers.
+For a more precise and detailed description see [4].
+.DS C
+.B
+THE BACK END TABLE.
+.R
+.DE
+.NH 0
+Introduction.
+.PP
+The code rules are divided in 15 groups.
+These groups are:
+.IP 1.
+Load instructions.
+.IP 2.
+Store instructions.
+.IP 3.
+Integer arithmetic instructions.
+.IP 4.
+Unsigned arithmetic instructions.
+.IP 5.
+Floating point arithmetic instructions.
+.IP 6.
+Pointer arithmetic instructions.
+.IP 7.
+Increment, decrement and zero instructions.
+.IP 8.
+Convert instructions.
+.IP 9.
+Logical instructions.
+.IP 10.
+Set manipulation instructions.
+.IP 11.
+Array instructions.
+.IP 12.
+Compare instructions.
+.IP 13.
+Branch instructions.
+.IP 14.
+Procedure call instructions.
+.IP 15.
+Miscellaneous instructions.
+.PP
+From all of these groups one or two typical EM pattern will be explained
+in the next paragraphs.
+Comment is placed between /* and */ (/* This is a comment */).
+.NH
+The instructions.
+.NH 2
+The load instructions.
+.PP
+In this group a typical instruction is
+.B
+lol
+.R
+.
+A
+.B
+lol
+.R
+instruction pushes the word at local base + offset, where offset
+is the instructions argument, onto the stack.
+Since the MCS6500 can only offset by 256 bytes, as explaned at the
+memory addressing modes, there is a need for two code rules in the
+table.
+One which can offset directly and one that must explicit
+calculate the address of the local.
+.NH 3
+The lol instruction with indirect offsetting.
+.PP
+In this case an indirect offsetted load from the second local base
+is possible.
+The table content is:
+.sp 1
+.br
+.B
+lol
+.R
+IN($1) | |
+.br
+allocate(R16)	/* allocate registerpair AX */
+.br
+"ldy #BASE+$1"	/* load Y with the offset from the second
+.br
+					      local base */
+.br
+"lda (LBl),y"	/* load indirect the lowbyte of the word */
+.br
+"tax"		/* move register A to register X */
+.br
+"iny"		/* increment register Y (offset) */
+.br
+"lda (LBl),y"	/* load indirect the highbyte of the word */
+.br
+| %[a] | |	/* push the word onto the fake stack */
+.NH 3
+The lol instruction whose offset is to big.
+.PP
+In this case, the library subroutine "Lol" is used.
+This subroutine expects the offset in registerpair AX, then
+calculates the address of the local or parameter, and loads
+it into registerpair AX.
+The table content is:
+.sp 1
+.br
+.B
+lol
+.R
+| |
+.br
+allocate(R16)	/* allocate registerpair AX */
+.br
+"lda #[$1].h"	/* load highbyte of offset into register A */
+.br
+"ldx #[$1].l"	/* load lowbyte of offset into register X */
+.br
+"jsr Lol"	/* perform the subroutine */
+.br
+| %[a] | |	/* push word onto the fake stack */
+.NH 2
+The store instructions.
+.PP
+In this group a typical instruction is
+.B
+stl.
+.R
+A
+.B
+stl
+.R
+instruction poppes a word from the stack and stores it in the word
+at local base + offset, where offset is the instructions argument.
+Here also is the need for two code rules in the table as a result
+of the offset limits.
+.NH 3
+The stl instruction with indirect offsetting.
+.PP
+In this case it an indirect offsetted store from the second local
+base is possible.
+The table content is:
+.sp 1
+.br
+.B
+stl
+.R
+IN($1) | R16 |	/* expect registerpair AX on top of the
+.br
+							fake stack */
+.br
+"ldy #BASE+1+$1"  /* load Y with the offset from the
+.br
+						second local base */
+.br
+"sta (LBl),y"	/* store the highbyte of the word from A */
+.br
+"txa"		/* move register X to register A */
+.br
+"dey"		/* decrement offset */
+.br
+"sta (LBl),y"	/* store the lowbyte of the word from A */
+.br
+| | |
+.NH 3
+The stl instruction whose offset is to big.
+.PP
+In this case the library subroutine 'Stl' is used.
+This subroutine expects the offset in registerpair AX, then
+calculates the address, poppes the word stores it at its place.
+The table content is:
+.sp 1
+.br
+.B
+stl
+.R
+| |
+.br
+allocate(R16)	/* allocate registerpair AX */
+.br
+"lda #[$1].h"	/* load highbyte of offset in register A */
+.br
+"ldx #[$1].l"	/* load lowbyte of offset in register X */
+.br
+"jsr Stl"	/* perform the subroutine */
+.br
+| | |
+.NH 2
+Integer arithmetic instructions.
+.PP
+In this group typical instructions are
+.B
+adi
+.R
+and
+.B
+mli.
+.R
+These instructions, in this table, are implemented for 2-byte
+and 4-byte integers.
+The only arithmetic instructions available on the MCS6500 are
+the ADC (add with carry), and SBC (subtract with not(carry)).
+Not(carry) here means that in a subtraction, the one's complement
+of the carry is taken.
+The absence of multiply and division instructions forces the
+use of subroutines to handle these cases.
+Because there are no registers left to perform on the multiply
+and division, zero page is used here.
+The 4-byte integer arithmetic is implemented, because in C there
+exists the integer type long.
+A user is freely to use the type long, but will pay in performance.
+.NH 3
+The adi instruction.
+.PP
+In case of the
+.B
+adi
+.R
+2 (and
+.B
+sbi
+.R
+2) instruction there are many EM
+patterns, so that the instruction can be performed in line in
+most cases.
+For the worst case there exists a subroutine in the library
+which deals with the EM instruction.
+In case of a
+.B
+adi
+.R
+4 (or
+.B
+sbi
+.R
+4) there only is a subroutine to deal with it.
+A table content is:
+.sp 1
+.br
+.B
+lol lol adi
+.R
+(IN($1) && IN($2) && $3==2) | | /* is it in range */
+.br
+allocate(R16)	/* allocate registerpair AX */
+.br
+"ldy #BASE+$1+1" /* load Y with offset for first operand */
+.br
+"lda (LBl),y"	/* load indirect highbyte first operand */
+.br
+"pha"		/* save highbyte first operand on hard_stack */
+.br
+"dey"		/* decrement offset first operand */
+.br
+"lda (LBl),y"	/* load indirect lowbyte first operand */
+.br
+"ldy #BASE+$2"	/* load Y with offset for second operand */
+.br
+"clc"		/* clear carry for addition */
+.br
+"adc (LBl),y"	/* add the lowbytes of the operands */
+.br
+"tax"		/* store lowbyte of result in place */
+.br
+"iny"		/* increment offset second operand */
+.br
+"pla"		/* get highbyte first operand */
+.br
+"adc (LBl),y"	/* add the highbytes of the operands */
+.br
+| %[a] | |	/* push the result onto the fake stack */
+.NH 3
+The mli instruction.
+.PP
+The
+.B
+mli
+.R
+2 instruction uses most the subroutine 'Mlinp'.
+This subroutine expects the multiplicand in zero page
+at locations ARTH, ARTH+1, while the multiplier is in zero
+page locations ARTH+2, ARTH+3.
+For a description of the algorithms used for multiplication and
+division, see [9].
+A table content is:
+.sp  1
+.br
+.B
+lol lol mli
+.R
+(IN($1) && IN($2) && $3==2) | |
+.br
+allocate(R16)	/* allocate registerpair AX */
+.br
+"ldy #BASE+$1"	/* load Y with offset of multiplicand */
+.br
+"lda (LBl),y"	/* load indirect lowbyte of multiplicand */
+.br
+"sta ARTH"	/* store lowbyte in zero page */
+.br
+"iny"		/* increment offset of multiplicand */
+.br
+"lda (LBl),y"	/* load indirect highbyte of multiplicand */
+.br
+"sta ARTH+1"	/* store highbyte in zero page */
+.br
+"ldy #BASE+$2"	/* load Y with offset of multiplier */
+.br
+"lda (LBl),y"	/* load indirect lowbyte of multiplier */
+.br
+"sta ARTH+2"	/* store lowbyte in zero page */
+.br
+"iny"		/* increment offset of multiplier */
+.br
+"lda (LBl),y"	/* load indirect highbyte of multiplier */
+.br
+"sta ARTH+3"	/* store highbyte in zero page */
+.br
+"jsr Mlinp"	/* perform the multiply */
+.br
+| %[a] | |	/* push result onto fake stack */
+.NH 2
+The unsgned arithmetic instructions.
+.PP
+Since unsigned addition an subtraction is performed in the same way
+as signed addition and subtraction, these cases are dealt with by
+an EM replacement.
+For mutiplication and division there are special subroutines.
+.NH 3
+Unsigned addition.
+.PP
+This is an example of the EM replacement strategy.
+.sp 1
+.br
+.B
+lol lol adu
+.R
+	| | | |
+.B
+lol
+.R
+$1
+.B
+lol
+.R
+$2
+.B
+adi
+.R
+$3 |
+.NH 2
+Floating point arithmetic.
+.PP
+Floating point arithmetic isn't implemented in this table.
+.NH 2
+Pointer arithmetic instructions.
+.PP
+A typical pointer arithmetic instruction is
+.B
+adp
+.R
+2.
+This instruction adds an offset and a pointer.
+A table content is:
+.sp 1
+.br
+.B
+adp
+.R
+	| | | |
+.B
+loc
+.R
+$1
+.B
+adi
+.R
+2 |
+.NH 2
+Increment, decrement and zero instructions.
+.PP
+In this group a typical instruction is
+.B
+inl
+.R
+, which increments a local or parameter.
+The MCS6500 doesn't have an instruction to increment the
+accumulator A, so the 'ADC' instruction must be used.
+A table content is:
+.sp 1
+.br
+.B
+inl
+.R
+IN($1) | |
+.br
+allocate(R16)	/* allocate registerpair AX */
+.br
+"ldy #BASE+$1"	/* load Y with offset of the local */
+.br
+"clc"		/* clear carry for addition */
+.br
+"lda (LBl),y"	/* load indirect lowbyte of local */
+.br
+"adc #1"	/* increment lowbyte */
+.br
+"sta (LBl),y"	/* restore indirect the incremented lowbyte */
+.br
+"bcc 1f"	/* if carry is clear then ready */
+.br 
+"iny"		/* increment offset of local */
+.br
+"lda (LBl),y"	/* load indirect highbyte of local */
+.br
+"adc #0"	/* add carry to highbyte */
+.br
+"sta (LBl),y\\n1:"  /* restore indirect the highbyte */
+.PP
+If the offset of the local or parameter is to big, first the
+local or parameter is fetched, than incremented, and then
+restored.
+.NH 2
+Convert instructions.
+.PP
+In this case there are two convert instructions
+which really do something.
+One of them is in line code, and deals with the extension of
+a character (1-byte) to an integer.
+The other one is a subroutine which handles the conversion
+between 2-byte integers and 4-byte integers.
+.NH 3
+The in line conversion.
+.PP
+The table content is:
+.sp 1
+.br
+.B
+loc loc cii
+.R
+$1==1 && $2==2 | R16 |
+.br
+"txa"		/* see if sign extension is needed */
+.br
+"bpl 1f"	/* there is no need for sign extension */
+.br
+"lda #0FFh"	/* sign extension here */
+.br
+"bne 2f"	/* conversion ready */
+.br
+"1: lda #0\\n2:"	/* no sign extension here */
+.NH 2
+Logical instructions.
+.PP
+A typical instruction in this group is the logical
+.B
+and
+.R
+on two 2-byte words.
+The logical
+.B
+and
+.R
+on groups of more than two bytes (max 254)
+is also possible and uses a library subroutine.
+.NH 3
+The logical and on 2-byte groups.
+.PP
+The table content is:
+.sp 1
+.br
+.B
+and
+.R
+$1==2 | R16 |	/* one group must be on the fake stack */
+.br
+"sta ARTH+1"	/* temporary save of first group highbyte */
+.br
+"stx ARTH"	/* temporary save of first group lowbyte */
+.br
+"jsr Pop"	/* pop second group from the stack */
+.br
+"and ARTH+1"	/* logical and on highbytes */
+.br
+"pha"		/* temporary save the result's highbyte */
+.br
+"txa"		/* logical and can only be done in A */
+.br
+"and ARTH"	/* logical and on lowbytes */
+.br
+"tax"		/* restore results lowbyte */
+.br
+"pla"		/* restore results highbyte */
+.br
+| %[1] | |	/* push result onto fake stack */
+.NH 2
+Set manipulation instructions.
+.PP
+A typical EM pattern in this group is
+.B
+loc inn zeq
+.R
+$1>0 && $1<16 && $2==2.
+This EM pattern works on sets of 16 bits.
+Sets can be bigger (max 256 bytes = 2048 bits), but than a
+library routine is used instead of in line code.
+The table content of the above EM pattern is:
+.sp 1
+.br
+.B
+loc inn zeq
+.R
+$1>0 && $1<16 && $2==2 | R16 |
+.br
+"ldy #$1+1"	/* load Y with bit number */
+.br
+"stx ARTH"	/* cannot rotate X, so use zero page */
+.br
+"1: lsr a"	/* right shift A */
+.br
+"ror ARTH"	/* right rotate zero page location */
+.br
+"dey"		/* decrement Y */
+.br
+"bne 1b"	/* shift $1 times */
+.br
+"bcc $1"	/* no carry, so bit is zero */
+.NH 2
+Array instructions.
+.PP
+In this group a typical EM pattern is
+.B
+lae lar
+.R
+defined(rom(1,3)) | | | |
+.B
+lae
+.R
+$1
+.B
+aar
+.R
+$2
+.B
+loi
+.R
+rom(1,3).
+This pattern uses the 
+.B
+aar
+.R
+instruction, which is part of a typical EM pattern:
+.sp 1
+.br
+.B
+lae aar
+.R
+$2==2 && rom(1,3)==2 && rom(1,1)==0 | R16 | /* registerpair AX contains
+the index in the array */
+.br
+"pha"		/* save highbyte of index */
+.br
+"txa"		/* move lowbyte of index to A */
+.br
+"asl a"		/* shift left lowbyte == 2 times lowbyte */
+.br
+"tax"		/* restore lowbyte */
+.br
+"pla"		/* restore highbyte */
+.br
+"rol a"		/* rotate left highbyte == 2 times highbyte */
+.br
+| %[1] | adi 2 | /* push new index, add to lowerbound array */
+.NH 2
+Compare instructions.
+.PP
+In this group all EM patterns are performed by calling
+a subroutine.
+Subroutines are used here because comparison is only
+possible byte by byte.
+This means a lot of code, and since compare are used frequently
+a lot of in line code would be generated, and thus reducing
+the space left for the software stack.
+These subroutines can be found in the library.
+.NH 2
+Branch instructions.
+.PP
+A typical branch instruction is
+.B
+beq.
+.R
+The table content for it is:
+.sp 1
+.br
+.B
+beq
+.R
+| R16 |
+.br
+"sta BRANCH+1"	/* save highbyte second operand in zero page */
+.br
+"stx BRANCH"	/* save lowbyte second operand in zero page */
+.br
+"jsr Pop"	/* pop the first operand */
+.br
+"cmp BRANCH+1" 	/* compare the highbytes */
+.br
+"bne 1f"	/* there not equal so go on */
+.br
+"cpx BRANCH"	/* compare the lowbytes */
+.br
+"beq $1\\n1:"	/* lowbytes are also equal, so branch */
+.PP
+Another typical instruction in this group is
+.B
+zeq.
+.R
+The table content is:
+.sp 1
+.br
+.B
+zeq
+.R
+| R16 |
+.br
+"tay"		/* move A to Y for setting testbits */
+.br
+"bmi $1"	/* highbyte s minus so branch */
+.br
+"txa"		/* move X to A for setting testbits */
+.br
+"beq $1\\n1:"	/* lowbyte also zero, thus branch */
+.NH 2
+Procedure call instructions.
+.PP
+In this group one code generation might seem a little
+akward.
+It is the EM instruction
+.B
+cai
+.R
+which generates a 'jsr Indir'.
+This is because there is no indirect jump_subroutine in the
+MCS6500.
+The only solution is to store the address in zero page, and then
+do a 'jsr' to a known label.
+At this label there must be an indirect jump instruction, which
+perform a jump to the address stored in zero page.
+In this case the label is Indir, and the address is stored in
+zero page at the addresses ADDR, ADDR+1.
+The tabel content is:
+.sp 1
+.br
+.B
+cai
+.R
+| R16 |
+.br
+"stx ADDR"	/* store lowbyte of address in zero page */
+.br
+"sta ADDR+1"	/* store highbyte of address in zero page */
+.br
+"jsr Indir"	/* use the indirect jump */
+.br
+| | |
+.NH 2
+Miscellaneous instructions.
+.PP
+In this group, as the name suggests, there is no
+typical EM instruction or EM pattern.
+Most of the MCS6500 code to be generated uses a library subroutine
+or is straightforward.
+.DS C
+.B
+PERFORMANCE.
+.R
+.DE
+.NH 0
+Introduction.
+.PP
+To measure the performance of the back end table some timing
+tests are done.
+What to time?
+In this case, the execution time of several Pascal statements
+are timed.
+Statements in C, which have a Pascal equivalence are timed also.
+The statements are timed as follows.
+A test program is been written, which executes two
+nested  for_loops from 1 to 1.000.
+Within these for_loops the statement, which is to be tested, is placed,
+so the statement will be executed 1.000.000 times.
+Then the same program is executed without the test statement.
+The time difference between the two executions is the time
+neccesairy to execute the test statement 1.000.000 times.
+The total time to execute the test statement requires thus the
+time difference divided by 1.000.000.
+.NH 0
+Testing Pascal statements.
+.PP
+The next statements are tested.
+.IP 1)
+int1 := 0;
+.IP 2)
+int1 := int2 - 1;
+.IP 3)
+int1 := int1 + 1;
+.IP 4)
+int1 := icon1 - icon2;
+.IP 5)
+int1 := icon2 div icon1;
+.IP 6)
+int1 := int2 * int3;
+.IP 7)
+bool := (int1 < 0);
+.IP 8)
+bool := (int1 < 3);
+.IP 9)
+bool := ((int1 > 3) or (int1 < 3))
+.IP 10)
+case int1 of 1: bool := false; 2: bool := true end;
+.IP 11)
+if int1 = 0 then int2 := 3;
+.IP 12)
+while int1 > 0 do int1 := int1 - 1;
+.IP 13)
+m := a[k];
+.IP 14)
+let2 := ['a'..'c'];
+.IP 15)
+P3(x);
+.IP 16)
+dum := F3(x);
+.IP 17)
+s.overhead := 5400;
+.IP 18)
+with s do overhead := 5400;
+.PP
+These statement were tested in a procedure test.
+.sp 1
+.br
+procedure test;
+.br
+var i, j, ... : integer;
+.br
+    bool : boolean;
+.br
+    let2 : set of char;
+.br
+begin
+.br
+    for i := 1 to 1000
+.br
+	for j := 1 to 1000
+.br
+	    STATEMENT
+.br
+end;
+.sp 1
+.PP
+STATEMENT is one of the statements as shown above, or it is
+the empty statement.
+The assignment of used variables, if neccesairy, is done before
+the first for_loop.
+In case of the statement which uses the procedure call, statement
+15, a dummy procedure is declared whose body is empty.
+In case of the statement which uses the function, statement 16,
+this function returns its argument.
+for the timing of C statements a similar test program was
+written.
+.sp 1
+.br
+main()
+.br
+{
+.br
+    int i, j, ...;
+.br
+    for (i = 1; i <= 1000; i++)
+.br
+	for (j = 1; j <= 1000; j++)
+.br
+	    STATEMENT
+.br
+}
+.sp 1
+.NH
+The results.
+.PP
+Here are tables with the results of the time measurments.
+Times are in microseconds (10^-6).
+Some statements appear twice in the tables.
+In the second case an array of 200 integers was declerated
+before the variable to be tested, so this variable cannot
+be accessed by indirect addressing from the second local base.
+This results in a larger execution time of the statement to be
+tested.
+The column 68000 contains the times measured on a Bleasdale,
+M68000 based, computer.
+The times in column pdp are measured on a DEC pdp11/44, where
+the times from column 6500 come from a BBC microcomputer.
+.bp
+.TS
+expand;
+c s s s
+c c c c
+lw35 nw7 nw7 nw7.
+Pascal timing results
+statement	68000	pdp	6500
+_
+T{
+int1 := 0;
+T}	4.0	5.8	16.7
+ 	4.0	4.2	97.8
+_
+T{
+int1 := int2 - 1;
+T}	7.2	7.1	27.2
+ 	6.9	7.1	206.5
+_
+T{
+int1 := int1 + 1;
+T}	6.9	6.8	27.2
+ 	6.4	6.7	106.5
+_
+T{
+int1 := icon1 + icon2;
+T}	6.2	6.2	25.6
+ 	6.2	6.0	106.6
+_
+T{
+int1 := icon2 div icon1;
+T}	14.9	14.3	372.6
+ 	14.9	14.7	453.7
+_
+T{
+int1 := int2 * int3;
+T}	11.5	12.0	558.1
+ 	11.3	11.6	728.6
+_
+T{
+bool := (int1 < 0);
+T}	7.2	6.9	122.8
+ 	7.8	8.1	453.2
+_
+T{
+bool := (int1 < 3);
+T}	7.3	7.6	126.0
+ 	7.2	8.1	232.2
+_
+T{
+bool := ((int1 > 3) or (int1 < 3))
+T}	10.1	12.0	307.8
+ 	10.2	11.9	440.1
+_
+T{
+case int1 of 1: bool := false; 2: bool := true end;
+T}	18.3	17.9	165.7
+_
+T{
+if int1 = 0 then int2 := 3;
+T}	9.5	8.5	133.8
+_
+T{
+while int1 > 0 do int1 := int1 - 1;
+T}	6.9	6.9	126.0
+_
+T{
+m := a[k];
+T}	7.2	6.8	134.3
+_
+T{
+let2 := ['a'..'c'];
+T}	38.4	38.8	447.4
+_
+T{
+P3(x);
+T}	18.9	18.8	180.3
+_
+T{
+dum := F3(x);
+T}	26.8	27.1	343.3
+_
+T{
+s.overhead := 5400;
+T}	4.6	4.1	16.7
+_
+T{
+with s do overhead := 5400;
+T}	4.2	4.3	16.7
+.TE
+.TS
+expand;
+c s s s
+c c c c
+lw35 nw7 nw7 nw7.
+C timing results
+statement	68000time	pdptime	6500time
+_
+T{
+int1 = 0;
+T}	4.1	3.6	17.2
+ 	4.1	4.1	97.7
+_
+T{
+int1 = int2 - 1;
+T}	6.6	6.9	27.2
+ 	6.1	6.5	206.4
+_
+T{
+int1 = int1 + 1;
+T}	6.4	7.3	27.2
+ 	6.3	6.2	206.4
+_
+T{
+int1 = int2 * int3;
+T}	11.4	12.3	522.6
+	9.6	10.1	721.2
+_
+T{
+int1 = (int2 < 0);
+T}	7.2	7.6	126.4
+ 	7.4	7.7	232.5
+_
+T{
+int1 = (int2 < 3);
+T}	7.0	7.5	126.0
+ 	7.8	7.8	232.6
+_
+T{
+int1 = ((int2 > 3) || (int2 < 3));
+T}	11.8	12.2	193.4
+ 	11.5	13.2	245.6
+_
+T{
+switch (int1) { case 1: int1 = 0; break; case 2: int1 = 1; break; }
+T}	28.3	29.2	164.1
+_
+T{
+if (int1 == 0) int2 = 3;
+T}	4.8	4.8	19.4
+_
+T{
+while (int2 > 0) int2 = int2 - 1;
+T}	5.8	6.0	125.9
+_
+T{
+int2 = a[int2];
+T}	4.8	5.1	192.8
+_
+T{
+P3(int2);
+T}	18.8	18.4	180.3
+_
+T{
+int2 = F3(int2);
+T}	27.0	27.2	309.4
+_
+T{
+s.overhead = 5400;
+T}	5.0	4.1	16.7
+.TE
+.NH
+Pascal statements which don't have a C equivalent.
+.PP
+At first, the two statements who perform an operation on constants
+are left out.
+These are left out while the C front end does constant folding,
+while the Pascal front end doesn't.
+So in C the statements int1 = icon1 + icon2; and int1 = icon1 / icont2;
+will use the same amount of time since the expression is evaluated
+by the front end.
+The two other statements (let2 := ['a'..'c']; and
+.B
+with
+.R
+s
+.B
+do
+.R
+overhead := 5400;), aren't included in the C statement timing table,
+because there constructs do not exist in C.
+Although in C there can be direct bit manipulation, and thus can
+be used to implement sets I have not used it here.
+The
+.B
+with
+.R
+statement does not exists in C and there is nothing with the slightest
+resemblance to it.
+.PP
+At first sight in the table , it looked if there is no much difference
+in the times for the M68000 and the pdp11/44, in comparison with the
+times needed by the MCS6500.
+To verify this impression, I calculated the correlation coefficient
+between the times of the M68000 and pdp11/44.
+It turned out to be 0.997 for both the Pascal time tests and the C
+time tests.
+Since the correlation coefficient is near to one and the difference
+between the times is small, they can be considered to be the same
+as seen from the times of the MCS6500.
+Then I have tried to make a grafic of the times from the M68000 and
+the MCS6500.
+Well, there was't any correlation to been seen, taken all the times.
+The only correlation one could see, with some effort, was in the
+times for the first three Pascal statements.
+The two first C statements show also a correlation, which two points
+always do.
+.PP
+Also the three Pascal statements
+.B
+case
+.R
+,
+.B
+if
+.R
+,
+and
+.B
+while
+.R
+have a correlation coefficient of 0.999.
+This is probably because the
+.B
+case
+.R
+statement uses a subroutine in both cases and the other two
+statements
+.B
+if
+.R
+and,
+.B
+while
+.R
+generate in line code.
+The last two Pascal statements use the same time, since the front
+end wil generate the same EM code for both.
+.PP
+The independence between the rest of the test times is because
+in these cases the object code for the MCS6500 uses library
+subroutines, while the other processors can handle the EM code
+with in line code.
+.PP
+It is clear that the MCS6500 is a slower device, it needs longer
+execution times, the need of more library subroutines, but
+there is no constant factor between it execution times and those
+of other processors.
+.PP
+The slowing down of the MCS6500 as result of the need of a
+library subroutine is illustrated by the muliplication
+statement.
+The MCS6500 needs a library subroutine, while the other
+two processors have a machine instruction to perform the
+multiply.
+This results in a factor of 48.5, when the operands can be accessed
+indirect by the MCS6500.
+When the MCS6500 cannot access the operands indirectly the situation
+is even worse.
+The slight differences between the MCS6500 execution times for
+Pascal statements and C statements is probably the result of the
+front end, and thus beyond the scope of this discussion.
+.PP
+Another timing test is done in C on the statement k = i + j + 1983.
+This statement is tested on many UNIX*
+.FS
+* UNIX is a Trademark of Bell Laboratories.
+.FE
+systems.
+For a complete list see appendix A.
+The slowest one is the IBM XT, which runs on a 8088 microprocessor.
+The fasted one is the Amdahl computer.
+Here is short table to illustrate the performance of the
+MCS6500.
+.TS
+c c c
+c n n.
+machine	short	int
+IBM XT	53.4	53.4
+Amdahl	0.5	0.3
+MCS6500	150.2	150.2
+.TE
+The MCS6500 is three times slower than the IBM XT, but threehundred
+times slower than the Amdahl.
+The reason why the times on the IBM XT and the MCS6500 are the
+same for short's and int's, is that most C compilers make the types
+short and integer the same size on 16-bit machines.
+In this project the MCS6500 is regarded as a 16-bit machine.
+.NH
+Length tests.
+.PP
+I have also compiled several programs written in Pascal and C to
+see if there is a resemblance between the number of bytes generated
+in the machine's language.
+In the tables:
+.IP length: 9
+The number of bytes of the source program.
+.IP 68000:
+The number of bytes of the a.out file for a M68000.
+.IP pdp:
+The number of bytes of the a.out file for a pdp11/44.
+.IP 6500:
+The number of bytes of the a.out file for a MCS6500.
+.LP
+These are the results:
+.TS
+c s s s
+c c c c
+n n n n.
+Pascal programs
+length	68000	pdp	6500
+_
+19946	14383	16090	26710
+19484	20169	20190	35416
+10849	10469	11464	18949
+273	4221	5106	7944
+1854	5807	6610	10301
+.TE
+.TS
+c s s s
+c c c c
+n n n n.
+C progams
+length	68000	pdp	6500
+_
+9444	6927	8234	11559
+7655	14353	18240	26251
+4775	11309	15934	19910
+639	6337	9660	12494
+.TE
+.PP
+In contrast to the execution times of the test statements, the
+object code files sizes show a constant factor between them.
+After calculating the correlation coefficient, I have calculated
+the line fitted between sizes.
+.FS
+* x is the number of bytes
+.FE
+.TS
+c s s
+c c c
+l c c.
+Pascal programs
+processor	corr. coef.	fitted line
+_
+68000-pdp	0.996	 
+68000-6500	0.999	1.76x + 502*
+pdp-6500	0.999	1.80x - 1577
+.TE
+.TS
+c s s
+c c c
+l c c.
+C programs
+processor	corr. coef.	fitted line
+_
+68000-pdp	0.974	 
+68000-6500	0.992	1.80x + 502*
+pdp-6500	0.980	1.40x - 1577
+.TE
+.PP
+As seen from the tables above the correlation coefficient for
+Pascal programs is better than the ones for C programs.
+Thus the line fits best for Pascal programs.
+With the formula of the best fitted line one can now estimate
+the size of the object code, which a program needs, for a MCS6500
+without having the compiler at hand.
+One also can see from these formula that the object code
+generated for a MCS6500 is about 1.8 times more than for the other
+processors.
+Since the number of bytes in the source file havily depends on the
+programmer, how many spaces he or she uses, the size of the indenting
+in structured programs, etc., there is no correlation between the
+size of the source file and the size of the object file.
+Also the use of comments has its influence on the size.
+.bp
+.DS C
+.B
+SUMMARY.
+.R
+.DE
+.NH 0
+Summary
+.PP
+In this chapter some final conclusions are made.
+.PP
+In spite of its simplicity, the MCS6500 is strong enough to
+implement a EM machine.
+A serious deficy of the MCS6500 is the missing of 16-bit
+general purpose registers, and especially the missing of a
+16-bit stackpointer.
+As pointed out before, one 16-bit register can be simulated
+by a pair of 8-bit registers, in fact, the accumulator A to
+hold the highbyte, and the index register X to hold the lowbyte
+of the word.
+By lack of a 16-bit stackpointer, zero page must be used to hold
+a stackpointer and there are also two subroutines needed for
+manipulating the stack (Push and Pop).
+.PP
+As seen at the time tests, the simple instruction set of the
+MCS6500 forces the use of library subroutines.
+These library subroutines increas the execution time of the
+programs.
+.PP
+The sizes of the object code files show a strong correlation
+in contrast to the execution times.
+With this correlatiuon one canestimate the size of a program
+if it is to be used on a MCS6500.
+.bp
+.NH 0
+.B
+REFERENCES.
+.R
+.IP 1.
+Haddon. B.K., and Waite, W.M.
+Experience with the Universal Intermediate Language Janus.
+.B
+Software Practice & Experience 8
+.R
+,
+5 (Sept.-Oct. 1978), 601-616.
+.RS
+.PP
+An intermediate language for use with Algol 68, Pascal, etc.
+is described.
+The paper discusses some problems encountered and how they were
+dealt with.
+.RE
+.IP 2.
+Lowry, E.S., and Medlock, C.W. Object Code Optimization.
+.B
+Commun. ACM 12
+.R
+,
+(Jan. 1969), 13-22.
+.RS
+.PP
+A classical paper on global object code optimization.
+It covers data flow analysis, common subexpressions, code motion,
+register allocation and other techniques.
+.RE
+.IP 3.
+Osborn, A., Jacobson, S., and Kane, J. The Mos Technology MCS6500.
+.B
+An Introduction to Microcomputers ,
+.R
+Volume II, Some Real Products (june 1977) chap. 9.
+.RS
+.PP
+A hardware description of some real existing CPU's, such as
+the Intel Z80, MCS6500, etc. is given in this book.
+.RE
+.IP 4.
+van Staveren, H.
+The table driven code generator from the Amsterdam Compiler Kit.
+Vrije Universiteit, Amsterdam, (July 11, 1983).
+.RS
+.PP
+The defining document for writing a back end table.
+.RE
+.IP 5.
+Steel, T.B., Jr. UNCOL: The Myth and the Fact. in
+.B
+Ann. Rev. Auto. Prog.
+.R
+Goodman, R. (ed.), vol 2., (1960), 325-344.
+.RS
+.PP
+An introduction to the UNCOL idea by its originator.
+.RE
+.IP 6.
+Steel. T.B., Jr. A first Version of UNCOL.
+.B
+Proc. Western Joint Comp. Conf.
+.R
+,
+(1961), 371-377.
+.IP 7.
+Tanenbaum, A.S., Stevenson, J.W., Keizer, E.G., and van Staveren,
+H.
+A Practical Tool Kit for Making Portable Compilers.
+Informatica Rapport 74, Vrije Universiteit, Amsterdam, 1983.
+.RS
+.PP
+An overview on the Amsterdam Compiler Kit.
+.RE
+.IP 8.
+Tanenbaum, A.S., Stevenson, J.W., Keizer, E.G., and van Staveren,
+H.
+Description of an Experimental Machine Architecture for use with
+Block Structured Languages.
+Informatica Rapport 81, Vrije Universiteit, Amsterdam, 1983.
+.RS
+.PP
+The defining document for EM.
+.RE
+.IP 9.
+Tanenbaum, A.S. Structured Computer Organization.
+Prentice Hall. (1976).
+.RS
+.PP
+In this book computers are described as a hierarchy of levels,
+with each one performing some well-defined function.
+.RE