Added
This commit is contained in:
407
doc/pascal/transpem.doc
Normal file
407
doc/pascal/transpem.doc
Normal file
@@ -0,0 +1,407 @@
|
||||
.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.
|
||||
Reference in New Issue
Block a user