-." $Header$
.RP
.TL
Back end table for the Intel 8080 micro-processor
.br
The sign bit S is set (cleared) by certain instructions when the most significant
bit of the result of an operation equals one (zero).
-.br
The zero bit Z is set (cleared) by certain operations when the
8-bit result of an operation equals (does not equal) zero.
-.br
The parity bit P is set (cleared) if the 8-bit result of an
operation includes an even (odd) number of ones.
-.br
C is the normal carry bit.
-.br
AC is an auxiliary carry that indicates whether there has been a carry
out of bit 3 of the accumulator.
This auxiliary carry is used only by the DAA instruction, which
.NH 3
Register addressing
.PP
-
-With each intruction using register addressing,
+With each instruction using register addressing,
only one register is specified (except for the MOV instruction),
although in many of them the accumulator is implied as
second operand.
Examples are CMP E, which compares register E with the accumulator,
and DCR B, which decrements register B.
-.br
A few instructions deal with 16 bit register-pairs:
examples are DCX B, which decrements register-pair BC and the
PUSH and POP instructions.
THE 8080 BACK END TABLE
.PP
The back end table is designed as described in [5].
-So for an overall design of a back end table I refer to this document.
+For an overall design of a back end table I refer to this document.
.br
This section deals with problems encountered in writing the
8080 back-end table.
Word size (EM_WSIZE) and pointer size (EM_PSIZE) are both
defined as two bytes.
The hole between AB and LB (EM_BSIZE) is four bytes: only the
-return address and the localbase are saved.
+return address and the local base are saved.
.NH 2
Registers and their properties
.PP
All properties have the default size of two bytes, because one-byte
registers also cover two bytes when put on the real stack.
.sp 1
-The next considerations led to the choise of register-pair BC
-as localbase.
-Though saving the localbase in memory would leave one more register-pair
+The next considerations led to the choice of register-pair BC
+as local base.
+Though saving the local base in memory would leave one more register-pair
available as scratch register, it would slow down instructions
as 'lol' and 'stl' too much.
-So a register-pair should be sacrificed as localbase.
+So a register-pair should be sacrificed as local base.
Because a back-end without a free register-pair HL is completely
-broken-winged, the only reasonable choises are BC and DE.
-Though the choise between them might seem arbitrary at first sight,
+broken-winged, the only reasonable choices are BC and DE.
+Though the choice between them might seem arbitrary at first sight,
there is a difference between register-pairs BC and DE:
the instruction XCHG exchanges the contents of register-pairs DE and
HL.
When DE and HL are both heavily used on the fake-stack, this instruction
-is very usefull.
-Since it won't be usefull too often to exchange HL with the localbase
+is very useful.
+Since it won't be useful too often to exchange HL with the local base
and since an instruction exchanging BC and HL does not exist, BC is
-chosen as localbase.
+chosen as local base.
.sp 1
Many of the register properties are never mentioned in the
PATTERNS part of the table.
the accumulator only
.IP reg:
any of the registers A, D, E, H or L. Of course the registers B and C which are
-used as localbase don't possess this property.
+used as local base don't possess this property.
When there is a single register on the fake-stack, its value
is always considered non-negative.
.IP dereg:
register-pair HL only
.IP hl_or_de:
register-pairs HL and DE both have this property
-.IP localbase:
+.IP local base:
used only once (i.e. in the EM-instruction 'str 0')
.PP
.sp 1
The stackpointer SP and the processor status word PSW have to be
-defined explicitely because they are needed in some instructions
+defined explicitly because they are needed in some instructions
(i.e. SP in LXI, DCX and INX and PSW in PUSH and POP).
.br
It doesn't matter that the processor status word is not just register A
different tokens (four).
Reasons are the limited addressing modes of the 8080 microprocessor,
no index registers etc.
-.br
For example to translate the EM-instruction
.DS
lol 10
the next 8080 instructions are generated:
.DS L
LXI H,10 /* load registers pair HL with value 10 */
-DAD B /* add localbase (BC) to HL */
+DAD B /* add local base (BC) to HL */
MOV E,M /* load E with byte pointed to by HL */
INX H /* increment HL */
MOV D,M /* load D with next byte */
.DE
-Of course, instead of emitting code immmediately, it could be postponed
+Of course, instead of emitting code immediately, it could be postponed
by placing something like a {LOCAL,10} on the fake-stack, but some day the above
mentioned code will have to be generated, so a LOCAL-token is
-hardly usefull.
-.br
+hardly useful.
See also the comment on the load instructions.
.NH 2
Sets
is used instead of register mode, but since the costs are not completely
orthogonal this results in small deficiencies for the DCR, INR and MOV
instructions.
-Although it is not particularly usefull these deficiencies are
+Although it is not particularly useful these deficiencies are
corrected in the INSTRUCTIONS part, by treating the register indirect
-mode seperately.
+mode separately.
.sp 1
The costs of the conditional call and return instructions really
depend on whether or not the call resp. return is actually made.
-Unimportant.
+However, this is not important to the behaviour of the back end.
.sp 1
Instructions not used in this table have been commented out.
Of course many of them are used in the library routines.
.B cgg
from complaining.
.NH 2
-Stackingrules
+Stacking rules
.PP
When, for example, the token {const2,10} has to be stacked while
no free register-pair is available, the next code is generated:
register-pairs.
Before the coercion is carried out other appearances of DE and HL
on the fake-stack will be moved to the real stack, because in
-the INSTRUCTION-part is told that XCHG destroyes the contents
+the INSTRUCTION-part is told that XCHG destroys the contents
of both DE and HL.
-.br
The coercion transposing one register-pair to another one by
emitting two MOV-instructions, will be used only if
-one of the register-pairs is the localbase.
+one of the register-pairs is the local base.
.NH 2
Patterns
.PP
.DE
the 'uses'-clause could have been omitted because
.B cgg
-knows that LHLD destroyes register-pair HL.
+knows that LHLD destroys register-pair HL.
.sp 1
Since there is only one register with property 'hlreg',
there is no difference between 'uses hlreg' (allocate a
all registers with property 'hlreg' from the fake-stack).
The same applies for the property 'dereg'.
.br
-As a consequence 'kills' is rarely used in this back-end table.
+Consequently 'kills' is rarely used in this back-end table.
.NH 3
Group 1: Load instructions
.PP
.B cgg
from emitting the code for 'lol 10' again, an extra
pattern is included in the table for cases like this.
-.br
The same applies for two consecutive 'loe'-s or 'lil'-s.
.sp 1
A bit tricky is 'lof'.
.sp 1
By lookahead,
.B cgg
-can make a clever choise between the first and
+can make a clever choice between the first and
second code rule of 'loi 4'.
The same applies for several other instructions.
.NH 3
Since the 8080 instruction set doesn't provide multiply and
divide instructions, special routines are made to accomplish these tasks.
.sp 1
-Instead of providing four slighty differing routines for 16 bit signed or
+Instead of providing four slightly differing routines for 16 bit signed or
unsigned division, yielding the quotient or the remainder,
the routines are merged.
This saves space and assembly time
when several variants are used in a particular program,
at the cost of a little speed.
-.br
When the routine is called, bit 7 of register A indicates whether
the operands should be considered as signed or as unsigned integers,
and bit 0 of register A indicates whether the quotient or the
.NH 3
Group 5: Floating point arithmetic
.PP
-Floating points are not implemented.
-.br
+Floating point is not implemented.
Whenever an EM-instruction involving floating points is offered
-to the code-generator, it generates the code 'call eunimpl',
-which traps with trap number 63.
+to the code-generator, it calls the corresponding
+library routine with the proper parameters.
+Each floating point library routine calls 'eunimpl',
+trapping with trap number 63.
Some of the Pascal and C library routines output floating point
EM-instructions, so code has to be generated for them.
-Of course this doesn't imply the code will ever be executed.
+Of course this does not imply the code will ever be executed.
.NH 3
Group 12: Compare instructions
.PP
but the current version of
.B cgg
doesn't approve this.
-.br
In any case
.B cgg
chooses either DE or HL to store the result, using lookahead.
LIBRARY ROUTINES
.PP
Most of the library routines start with saving the return address
-and the localbase, so that the parameters are on the top of the stack
+and the local base, so that the parameters are on the top of the stack
and the registers B and C are available as scratch registers.
Since register-pair HL is needed to accomplish these tasks,
and also to restore everything just before the routine returns,
registers-pair DE.
When it returns more than 2 bytes they are pushed onto the stack.
.br
-
It would have been possible to let the 32 bit arithmetic routines
return 2 bytes in DE and the remaining 2 bytes on the stack
(this often would have saved some space and execution time),
Whenever a trap, for example trying to divide by zero,
occurs in a program that originally was written in C or Pascal,
a special trap handler is called.
-.br
This trap handler wants to write an appropriate error message on the
monitor.
It tries to read the message from a file (e.g. etc/pc_rt_errors in the
by storing it in ROM (Read Only Memory).
.sp 1
Depending on the characteristics of the particular 8080 based system, some
-adaptions have to be made:
+adaptations have to be made:
.IP 1) 10
In 'head_em': the base address, which is the address where the first
8080 instruction will be stored, and the initial value of the
-stackpointer are set to 0x1000 and 0x8000 respectivally.
+stackpointer are set to 0x1000 and 0x8000 respectively.
.br
Other systems require other values.
.IP 2)
.IP 5)
In 'tail_em': the current version of the 8080 back-end has very limited I/O
capabilities, because it was tested on a system that
-had no knowlegde of files.
+had no knowledge of files.
So the implementation of the EM-instruction 'mon' is very simple;
it can only do the following things:
.RS
.IP Monitor\ call\ 1: 40
-Exit
+exit
.IP Monitor\ call\ 3:
read, always reads from the monitor.
.br
.NH 2
Introduction
.PP
-At about the same time I develloped the back end
+At about the same time I developed the back end
for the Intel 8080 and Intel 8085,
Frans van Haarlem did the same job for the Zilog z80 microprocessor.
Since the z80 processor is an extension of the 8080,
to a z80 too.
The assembly languages are quite different however.
.br
-During the devellopments of the back ends we have used
-two micro-computers, both equiped with a z80 microprocessor.
+During the developments of the back ends we have used
+two micro-computers, both equipped with a z80 microprocessor.
Of course the output of the 8080 back end is assembled by an
8080 assembler. This should assure I have never used any of
the features that are potentially available in the z80 processor,
Differences between the 8080 and z80 processors
.PP
Except for some features that are less important concerning back ends,
-there are two points where the z80 improves the 8080:
+there are two points where the z80 improves upon the 8080:
.IP First, 18
the z80 has two additional index registers, IX and IY.
They are used as in
Consequences for the 8080 and z80 back end
.PP
The most striking difference between the 8080 and z80 back ends
-is the choise of the localbase.
-The writer of the z80 back end chose index register IY as localbase,
+is the choice of the local base.
+The writer of the z80 back end chose index register IY as local base,
because this results in the cheapest coding of EM-instructions
like 'lol' and 'stl'.
-.br
The z80 instructions that load local 10, for example
.DS
LD E,(IY+10)
it should be noted that as a side effect it may save some
pushing and popping since register pair HL is not used.
.sp 1
-The choise of IY as localbase has its drawbacks too.
+The choice of IY as local base has its drawbacks too.
The root of the problem is that it is not possible to add
IY to HL.
For the EM-instruction
other instructions, for instance in 'lol' when the offset
doesn't fit in one byte.
.sp 1
-Beside the choise of the localbase, I think there is no
+Beside the choice of the local base, I think there is no
fundamental difference between the 8080 and z80 back ends,
except of course that the z80 back end has register pair BC
and, less important, index register IX available as scratch registers.
Then I produced 8080, z80 and 8086 code for them.
Investigating the assembler listing I found the
lengths of the different parts of the generated code.
-.br
I have checked two areas:
.IP 1) 8
the entire text part
For all programs I have computed the ratio of the code-lengths
of the 8080, z80 and 8086.
The averages of all Pascal/C programs are listed in the table,
-standarized to '100' for the 8080.
+standardized to '100' for the 8080.
So the listed '107' indicates that the lengths
of the text parts of the z80 programs that originally were Pascal programs,
averaged 7 percent larger than in the corresponding 8080 programs.
The most striking thing in this table is that the z80 back end appears
to produce larger code than the 8080 back end.
The reason is that the current z80 back end table is
-not very elaborate yet.
+not very sophisticated yet.
For instance it doesn't look for any EM-pattern longer than one.
So the table shows that the preparations in the 8080 back end table
to produce faster code (like recognizing special EM-patterns
was not just for fun, but really improved the generated code
significantly.
.sp 1
-The table shows that the 8080 table is relativelly better
+The table shows that the 8080 table is relatively better
when only the plain user program is considered instead of the entire text part.
This is not very surprising since the 8080 back end sometimes
uses library routines where the z80 and especially the 8086 don't.
.IP [3]
Tanenbaum, A.S., Stevenson, J.W., Keizer, E.G., and van Staveren, H.
.br
-Desciption of an experimental machine architecture for use with block
+Description of an experimental machine architecture for use with block
structured languages,
.br
Informatica report 81, Vrije Universiteit, Amsterdam, 1983.