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.
 |