407 lines
		
	
	
	
		
			8.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			407 lines
		
	
	
	
		
			8.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
.sp 1.5i
 | 
						|
.de CL
 | 
						|
.ft R
 | 
						|
c\\$1
 | 
						|
.ft 5
 | 
						|
 \fIcode statement-\\$1
 | 
						|
.ft 5
 | 
						|
 \fBbra *\fRexit_label
 | 
						|
.ft 5
 | 
						|
..
 | 
						|
.NH
 | 
						|
Translation of Pascal to EM code
 | 
						|
.nh
 | 
						|
.LP
 | 
						|
.sp
 | 
						|
A short description of the translation of Pascal constructs to EM code is
 | 
						|
given in the following paragraphs. The EM instructions and Pascal terminal
 | 
						|
symbols are printed in \fBboldface\fR. A sentence in \fIitalics\fR is a
 | 
						|
description of a group of EM (pseudo)instructions.
 | 
						|
.sp
 | 
						|
.NH 2
 | 
						|
Global Variables
 | 
						|
.LP
 | 
						|
.sp
 | 
						|
For every global variable, a \fBbss\fR block is reserved. To enhance the
 | 
						|
readability of the EM-code generated, the variable-identifier is used as
 | 
						|
a data label to address the block.
 | 
						|
.sp
 | 
						|
.NH 2
 | 
						|
Expressions
 | 
						|
.LP
 | 
						|
.sp
 | 
						|
Operands are always evaluated, so the execution of
 | 
						|
.br
 | 
						|
.ti +3m
 | 
						|
\fBif\fR ( p <> nil ) \fBand\fR ( p^.value <> 0 ) \fBthen\fR .....
 | 
						|
.br
 | 
						|
might cause a run-time error, if p is equal to nil.
 | 
						|
.LP
 | 
						|
The left-hand operand of a dyadic operator is almost always evaluated before
 | 
						|
the right-hand side. Peculiar evaluations exist for the following cases:
 | 
						|
.sp
 | 
						|
the expression:  set1 <= set2, is evaluated as follows :
 | 
						|
.nf
 | 
						|
- evaluate set2
 | 
						|
- evaluate set1
 | 
						|
- compute set2+set1
 | 
						|
- test set2 and set2+set1 for equality
 | 
						|
.fi
 | 
						|
.sp
 | 
						|
the expression:  set1 >= set2, is evaluated as follows :
 | 
						|
.nf
 | 
						|
- evaluate set1
 | 
						|
- evaluate set2
 | 
						|
- compute set1+set2
 | 
						|
- test set1 and set1+set2 for equality
 | 
						|
.fi
 | 
						|
.sp
 | 
						|
Where allowed, according to the standard, constant integral expressions are
 | 
						|
compile-time evaluated while an effort is made to report overflow on target
 | 
						|
machine basis. The integral expressions are evaluated in the type \fIarith\fR.
 | 
						|
The size of an arith is assumed to be at least the size of the integer type
 | 
						|
on the target machine. If the target machine's integer size is less than the
 | 
						|
size of an arith, overflow can be detected at compile-time. However, the
 | 
						|
following call to the standard procedure new, \fInew(p, 3+5)\fR, is illegal,
 | 
						|
because the second parameter is not a constant according to the grammar.
 | 
						|
.sp
 | 
						|
Constant floating expressions are not compile-time evaluated, because the
 | 
						|
precision on the target machine and the precision on the machine on which the
 | 
						|
compiler runs could be different. The boolean expression \fI(1.0 + 1.0) = 2.0\fR
 | 
						|
could evaluate to false.
 | 
						|
.sp
 | 
						|
.NH 2
 | 
						|
Statements
 | 
						|
.NH 3
 | 
						|
Assignment Statement
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.ti +3m
 | 
						|
\f5(variable-access | function-identifier) \fB:=\f5 expression
 | 
						|
 | 
						|
\fREM :
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
.ft I
 | 
						|
evaluate expression
 | 
						|
store in variable-access or function-identifier
 | 
						|
.ft R
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
 | 
						|
In case of a function-identifier, a hidden temporary variable is used to
 | 
						|
keep the function result.
 | 
						|
.bp
 | 
						|
.NH 3
 | 
						|
Goto Statement
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.ti +3m
 | 
						|
\fBGOTO\f5 label
 | 
						|
 | 
						|
\fREM :
 | 
						|
.in +3m
 | 
						|
Two cases can be distinguished :
 | 
						|
.br
 | 
						|
- local goto,
 | 
						|
.ti +2m
 | 
						|
in which a \fBbra\fR is generated.
 | 
						|
 | 
						|
- non-local goto,
 | 
						|
.in +2m
 | 
						|
.ll -1i
 | 
						|
a goto_descriptor is build, containing the ProgramCounter of the instruction
 | 
						|
jumped to and an offset in the target procedure frame which contains the
 | 
						|
value of the StackPointer after the jump. The code for the jump itself is to
 | 
						|
load the address of the goto_descriptor, followed by a push of the LocalBase
 | 
						|
of the target procedure and a \fBcal\fR $_gto. A message is generated to
 | 
						|
indicate that a procedure or function contains a statement which is the
 | 
						|
target of a non-local goto.
 | 
						|
.ll +1i
 | 
						|
.in -2m
 | 
						|
.in -3m
 | 
						|
.sp 2
 | 
						|
.NH 3
 | 
						|
If Statement
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.in +3m
 | 
						|
.ft 5
 | 
						|
\fBIF\f5 boolean-expression \fBTHEN\f5 statement
 | 
						|
 | 
						|
.in -3m
 | 
						|
\fREM :
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
 \fIevaluation boolean-expression
 | 
						|
 \fBzeq \fR*exit_label
 | 
						|
 \fIcode statement
 | 
						|
\fRexit_label
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
.sp 2
 | 
						|
\fRPASCAL :
 | 
						|
.in +3m
 | 
						|
.ft 5
 | 
						|
\fBIF\f5 boolean-expression \fBTHEN\f5 statement-1 \fBELSE\f5 statement-2
 | 
						|
 | 
						|
.in -3m
 | 
						|
\fREM :
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
 \fIevaluation boolean-expression
 | 
						|
 \fBzeq \fR*else_label
 | 
						|
 \fIcode statement-1
 | 
						|
 \fBbra \fR*exit_label
 | 
						|
\fRelse_label
 | 
						|
 \fIcode statement-2
 | 
						|
\fRexit_label
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
.sp 2
 | 
						|
.NH 3
 | 
						|
Repeat Statement
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.in +3m
 | 
						|
.ft 5
 | 
						|
\fBREPEAT\f5 statement-sequence \fBUNTIL\f5 boolean-expression
 | 
						|
 | 
						|
.in -3m
 | 
						|
\fREM :
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
\fRrepeat_label
 | 
						|
 \fIcode statement-sequence
 | 
						|
 \fIevaluation boolean-expression
 | 
						|
 \fBzeq\fR *repeat_label
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
.bp
 | 
						|
.NH 3
 | 
						|
While Statement
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.in +3m
 | 
						|
.ft 5
 | 
						|
\fBWHILE\f5 boolean-expression \fBDO\f5 statement
 | 
						|
 | 
						|
.in -3m
 | 
						|
\fREM :
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
\fRwhile_label
 | 
						|
 \fIevaluation boolean-expression
 | 
						|
 \fBzeq\fR *exit_label
 | 
						|
 \fIcode statement
 | 
						|
 \fBbra\fR *while_label
 | 
						|
\fRexit_label
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
.sp 2
 | 
						|
.NH 3
 | 
						|
Case Statement
 | 
						|
.LP
 | 
						|
.sp
 | 
						|
The case-statement is implemented using the \fBcsa\fR and \fBcsb\fR
 | 
						|
instructions.
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.in +3m
 | 
						|
\fBCASE\f5 case-expression \fBOF\f5
 | 
						|
.in +5m
 | 
						|
case-constant-list-1 \fB:\f5 statement-1 \fB;\f5
 | 
						|
.br
 | 
						|
case-constant-list-2 \fB:\f5 statement-2 \fB;\f5
 | 
						|
.br
 | 
						|
\&.
 | 
						|
.br
 | 
						|
\&.
 | 
						|
.br
 | 
						|
case-constant-list-n \fB:\f5 statement-n [\fB;\f5]
 | 
						|
.in -5m
 | 
						|
\fBEND\fR
 | 
						|
.in -3m
 | 
						|
.sp 2
 | 
						|
.LP
 | 
						|
.ll -1i
 | 
						|
The \fBcsa\fR instruction is used if the range of the case-expression
 | 
						|
value is dense, i.e.
 | 
						|
.br
 | 
						|
.ti +3m
 | 
						|
\f5( upperbound \- lowerbound ) / number_of_cases\fR
 | 
						|
.br
 | 
						|
is less than the constant DENSITY, defined in the file \fIdensity.h\fR.
 | 
						|
 | 
						|
If the range is sparse, a \fBcsb\fR instruction is used.
 | 
						|
 | 
						|
.ll +1i
 | 
						|
\fREM :
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
 \fIevaluation case-expression
 | 
						|
 \fBbra\fR *l1
 | 
						|
.CL 1
 | 
						|
.CL 2
 | 
						|
 .
 | 
						|
 .
 | 
						|
.CL n
 | 
						|
.ft R
 | 
						|
\&.case_descriptor
 | 
						|
.ft 5
 | 
						|
 \fIgeneration case_descriptor
 | 
						|
\fRl1
 | 
						|
.ft 5
 | 
						|
 \fBlae\fR .case_descriptor
 | 
						|
.ft 5
 | 
						|
 \fBcsa\fR size of (case-expression)
 | 
						|
\fRexit_label
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
.bp
 | 
						|
.NH 3
 | 
						|
For Statement
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.in +3m
 | 
						|
.ft 5
 | 
						|
\fBFOR\f5 control-variable \fB:=\f5 initial-value (\fBTO\f5 | \fBDOWNTO\f5) final-value \fBDO\f5 statement
 | 
						|
 | 
						|
.ft R
 | 
						|
.in -3m
 | 
						|
The initial-value and final-value are evaluated at the beginning of the loop.
 | 
						|
If the values are not constant, they are evaluated once and stored in a
 | 
						|
temporary.
 | 
						|
 | 
						|
EM :
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
 \fIload initial-value
 | 
						|
 \fIload final-value
 | 
						|
 \fBbgt\fR exit-label            (* DOWNTO : \fBblt\fI exit-label\fR *)
 | 
						|
 \fIload initial-value
 | 
						|
\fRl1
 | 
						|
 \fIstore in control-variable
 | 
						|
 \fIcode statement
 | 
						|
 \fIload control-variable
 | 
						|
 \fBdup\fI control-variable
 | 
						|
 \fIload final-value
 | 
						|
 \fBbeq\fR exit_label
 | 
						|
 \fBinc\fI control-variable\fR    (* DOWNTO : \fBdec\fI control-variable\fR *)
 | 
						|
 \fBbra *\fRl1
 | 
						|
\fRexit_label
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
 | 
						|
Note: testing must be done before incrementing(decrementing) the
 | 
						|
control-variable,
 | 
						|
.br
 | 
						|
\h'\w'Note: 'u'because wraparound could occur, which could lead to an infinite
 | 
						|
loop.
 | 
						|
.sp 2
 | 
						|
.NH 3
 | 
						|
With Statement
 | 
						|
 | 
						|
\fRPASCAL :
 | 
						|
.ti +3m
 | 
						|
\fBWITH\f5 record-variable-list \fBDO\f5 statement
 | 
						|
 | 
						|
.ft R
 | 
						|
The statement
 | 
						|
.ti +3m
 | 
						|
\fBWITH\fR r\s-3\d1\u\s0, r\s-3\d2\u\s0, ..., r\s-3\dn\u\s0 \fBDO\f5 statement
 | 
						|
 | 
						|
.ft R
 | 
						|
is equivalent to
 | 
						|
.in +3m
 | 
						|
\fBWITH\fR r\s-3\d1\u\s0 \fBDO\fR
 | 
						|
   \fBWITH\fR r\s-3\d2\u\s0 \fBDO\fR
 | 
						|
      ...
 | 
						|
         \fBWITH\fR r\s-3\dn\u\s0 \fBDO\f5 statement
 | 
						|
 | 
						|
.ft R
 | 
						|
.in -3m
 | 
						|
The translation of
 | 
						|
.ti +3m
 | 
						|
\fBWITH\fR r\s-3\d1\u\s0 \fBDO\f5 statement
 | 
						|
.br
 | 
						|
.ft R
 | 
						|
is
 | 
						|
.nf
 | 
						|
.in +3m
 | 
						|
\fIpush address of r\s-3\d1\u\s0
 | 
						|
\fIstore address in temporary
 | 
						|
\fIcode statement
 | 
						|
.in -3m
 | 
						|
.fi
 | 
						|
 | 
						|
.ft R
 | 
						|
An occurrence of a field is translated into:
 | 
						|
.in +3m
 | 
						|
\fIload temporary
 | 
						|
.br
 | 
						|
\fIadd field-offset
 | 
						|
.in -3m
 | 
						|
.bp
 | 
						|
.NH 2
 | 
						|
Procedure and Function Calls
 | 
						|
 | 
						|
.ft R
 | 
						|
In general, the call
 | 
						|
.ti +5m
 | 
						|
p(a\s-3\d1\u\s0, a\s-3\d2\u\s0, ...., a\s-3\dn\u\s0)
 | 
						|
.br
 | 
						|
is translated into the sequence:
 | 
						|
 | 
						|
.in +5m
 | 
						|
.nf
 | 
						|
\fIevaluate a\s-3\dn\u\s0
 | 
						|
\&.
 | 
						|
\&.
 | 
						|
\fIevaluate a\s-3\d2\u\s0
 | 
						|
\fIevaluate a\s-3\d1\u\s0
 | 
						|
\fIpush localbase
 | 
						|
\fBcal\fR $p
 | 
						|
\fIpop parameters
 | 
						|
.ft R
 | 
						|
.fi
 | 
						|
.in -5m
 | 
						|
 | 
						|
i.e. the order of evaluation and binding of the actual-parameters is from
 | 
						|
right to left. In general, a copy of the actual-parameter is made when the
 | 
						|
formal-parameter is a value-parameter. If the formal-parameter is a
 | 
						|
variable-parameter, a pointer to the actual-parameter is pushed.
 | 
						|
 | 
						|
In case of a function call, a \fBlfr\fR is generated, which pushes the
 | 
						|
function result on top of the stack.
 | 
						|
.sp 2
 | 
						|
.NH 2
 | 
						|
Register Messages
 | 
						|
 | 
						|
.ft R
 | 
						|
A register message can be generated to indicate that a local variable is never
 | 
						|
referenced indirectly. This implies that a register can be used for a variable.
 | 
						|
We distinguish the following classes, given in decreasing priority:
 | 
						|
 | 
						|
\(bu control-variable and final-value of a for-statement
 | 
						|
.br
 | 
						|
.ti +5m
 | 
						|
to speed up testing, and execution of the body of the for-statement
 | 
						|
.sp
 | 
						|
\(bu record-variable of a with-statement
 | 
						|
.br
 | 
						|
.ti +5m
 | 
						|
to improve the field selection of a record
 | 
						|
.sp
 | 
						|
\(bu remaining local variables and parameters
 | 
						|
.sp 2
 | 
						|
.NH 2
 | 
						|
Compile-time optimizations
 | 
						|
 | 
						|
.ft R
 | 
						|
The only optimization that is performed is the evaluation of constant
 | 
						|
integral expressions. The optimization of constructs like
 | 
						|
.ti +5m
 | 
						|
\fBif\f5 false \fBthen\f5 statement\fR,
 | 
						|
.br
 | 
						|
is left to either the peephole optimizer, or a global optimizer.
 |