1 .\" $NetBSD
: pxin2
.n
,v
1.2 1998/01/09 06:41:56 perry Exp $
3 .\" Copyright (c
) 1979 The Regents of the University of California
.
4 .\" All rights reserved
.
6 .\" Redistribution
and use
in source
and binary forms
, with or without
7 .\" modification
, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice
, this list of conditions
and the following disclaimer
.
11 .\" 2. Redistributions
in binary form must reproduce the above copyright
12 .\" notice
, this list of conditions
and the following disclaimer
in the
13 .\" documentation
and/or other materials provided with the distribution
.
14 .\" 3. Neither the name of the University nor the names of its contributors
15 .\" may be used to endorse or promote products derived from
this software
16 .\" without specific prior written permission
.
18 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS
'' AND
19 .\" ANY EXPRESS OR IMPLIED WARRANTIES
, INCLUDING
, BUT NOT LIMITED TO
, THE
20 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 .\" ARE DISCLAIMED
. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 .\" FOR ANY DIRECT
, INDIRECT
, INCIDENTAL
, SPECIAL
, EXEMPLARY
, OR CONSEQUENTIAL
23 .\" DAMAGES (INCLUDING
, BUT NOT LIMITED TO
, PROCUREMENT OF SUBSTITUTE GOODS
24 .\" OR SERVICES
; LOSS OF USE
, DATA
, OR PROFITS
; OR BUSINESS INTERRUPTION
)
25 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY
, WHETHER IN CONTRACT
, STRICT
26 .\" LIABILITY
, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE
) ARISING IN ANY WAY
27 .\" OUT OF THE USE OF THIS SOFTWARE
, EVEN IF ADVISED OF THE POSSIBILITY OF
30 .\" @
(#)pxin2.n 5.2 (Berkeley) 4/17/91
38 Naming conventions
and operation summary
40 Table
2.1 outlines the opcode typing convention
.
41 The expression ``a above b
'' means that `a
' is on top
42 of the stack with `b' below it
.
43 Table
2.3 describes each of the opcodes
.
44 The character `
*' at the end of a name specifies that
45 all operations with the root prefix
47 are summarized by one entry
.
48 Table
2.2 gives the codes used
49 to describe the
type inline data expected by each instruction
.
58 Basic control operations
63 Corresponds to the Pascal procedure
65 causes execution to end with a post
-mortem backtrace
as if a run
-time
70 Causes the second part of the block mark to be created, and
72 bytes of local variable space to be allocated and cleared to zero.
73 Stack overflow is detected here.
75 is the first line of the body of this section for error traceback,
76 and the inline string (length s) the character representation of its name.
82 and used to begin the main program
when the ``p
''
83 option is disabled so that the post
-mortem backtrace will be inhibited
.
87 Complementary to the operators
91 exits the current block
, calling the procedure
93 to flush buffers
for and release any local files
.
94 Restores the environment of the caller from the block mark
.
95 If
this is the end
for the main program
, all files are
97 and the interpreter is exited
.
101 Saves the current line number
, return address
, and active display entry pointer
103 in the first part of the block mark
, then transfers to the entry point
104 given by the relative address
106 that is the beginning of a
118 Used to make space
for the return value of a
120 just before calling it
.
131 returns to remove the arguments from the stack
.
135 Transfer control to relative address
139 or part of a structured statement
.
143 Transfer control to an absolute address
as part of a non
-local
145 or to branch over procedure bodies
.
149 Set current line number to
151 For consistency
, check that the expression stack is empty
152 as it should
be (as this is the start of a statement
.)
153 This consistency check will fail only
if there is a bug
in the
154 interpreter or the interpreter code has somehow been damaged
.
155 Increment the statement count
and if it exceeds the statement limit
,
160 Transfer control to address
162 that is
in the block at level
167 Causes each block to be exited
as if with
169 flushing
and freeing files with
171 until the current display entry is at level
176 Duplicate the word or
long on the top of
178 This is used mostly
for constructing sets
.
181 If
and relational operators
185 The interpreter conditional transfers all take place
using this operator
186 that examines the Boolean value on the top of the stack
.
189 the next code is executed
,
190 otherwise control transfers to the specified address
.
194 These take two arguments on the stack
,
195 and the sub
-operation code specifies the relational operation to
196 be done
, coded
as follows with `a
' above `b' on the stack
:
213 Each operation does a test to set the condition code
214 appropriately
and then does an indexed branch based on the
215 sub
-operation code to a test of the condition here specified
,
216 pushing a Boolean value on the stack
.
218 Consider the statement fragment
:
221 \
*bif
\fR a
= b \
*bthen
\fR
228 are integers
this generates the following code
:
235 IF
\fIElse part offset
\fR
239 \fI\
&... Then part code
...\fR
245 The Boolean operators
250 manipulate values on the top of the stack
.
251 All Boolean values are kept
in single bytes
in memory
,
252 or
in single words on the stack
.
253 Zero represents a Boolean
\fIfalse
\fP
, and one a Boolean
\fItrue
\fP
.
255 Right value
, constant
, and assignment operators
261 The right value operators load values on the stack
.
262 They take a block number
as a sub
-opcode
and load the appropriate
263 number of bytes from that block at the offset specified
264 in the following word onto the stack
. As an example
, consider
269 \fBcvtbl
\fR
(lc
)+,r0
#r0 has display index
270 \fBaddl
3\fR
_display(r0
),(lc
)+,r1
#r1 has variable address
271 \fBpushl
\fR
(r1
) #put value on the stack
275 Here the interpreter places the display level
in r0
.
276 It then adds the appropriate display value to the inline offset
and
277 pushes the value at
this location onto the stack
.
278 Control then returns to the main
282 operators have
short inline data that
283 reduces the space required to address the first
32K of
284 stack space
in each stack frame
.
289 provide explicit conversion to
long as the data
291 This saves the generation of
293 to align arguments to
299 The constant operators load a value onto the stack from inline code
.
300 Small integer values are condensed
and loaded by the
302 operator
, that is given by
306 \fBcvtbw
\fR
(lc
)+,\
-(sp
)
310 Here note that little work was required
as the required constant
311 was available
at (lc
)+.
312 For longer constants
,
314 must be incremented before moving the constant
.
317 takes a length specification
in the sub
-opcode
and can be used to load
318 strings
and other variable length data onto the stack
.
323 provide explicit conversion to
long as the constant is pushed
.
327 The assignment operators are similar to arithmetic
and relational operators
328 in that they take two operands
, both
in the stack
,
329 but the lengths given
for them specify
330 first the length of the value on the stack
and then the length
331 of the target
in memory
.
332 The target address
in memory is under the value to be stored
.
340 is a full
-length
, 4 byte, integer
,
341 will generate the code sequence
353 will load the address of
355 that is really given
as a block number
in the sub
-opcode
and an
356 offset
in the following word
,
357 onto the stack
, occupying a single word
.
359 that is a single word instruction
,
360 then loads the constant
1,
361 that is
in its sub
-opcode
,
363 Since there are not one
byte constants on the stack
,
364 this becomes a
2 byte, single word integer
.
365 The interpreter then assigns a length
2 integer to a length
4 integer
using
367 The code sequence
for
374 \fBcvtwl
\fR
(sp
)+,*(sp
)+
378 Thus the interpreter gets the single word off the stack
,
379 extends it to be a
4 byte integer
380 gets the target address off the stack
,
381 and finally stores the value
in the target
.
382 This is a typical use of the constant
and assignment operators
.
384 Addressing operations
390 The most common operation done by the interpreter
391 is the ``left value
'' or ``address of
'' operation
.
396 \fBcvtbl
\fR
(lc
)+,r0
#r0 has display index
397 \fBaddl
3\fR
_display(r0
),(lc
)+,\
-(sp
) #push address onto the stack
401 It calculates an address
in the block specified
in the sub
-opcode
402 by adding the associated display entry to the
403 offset that appears
in the following word
.
406 operator has a
short inline data that reduces the space
407 required to address the first
32K of stack space
in each call frame
.
411 The offset operator is used
in field names
.
412 Thus to get the address of
418 would generate the sequence
432 given its block
in the sub
-opcode
and offset
in the following word
,
433 and the interpreter then adds the offset of the field
435 in its record to get the correct address
.
437 takes its argument
in the sub
-opcode
if it is small enough
.
441 The example above is incomplete
, lacking a check
for a
444 The code generated would be
456 operation checks
for a
458 pointer
and generates the appropriate runtime error
if it is
.
462 A pointer to the specified length inline data is pushed
464 This is primarily used for
468 (see sections 3.6 and 3.8)
476 are used for subscripting.
477 For example, the statement
487 ``array [1..1000] of real''
502 operation takes the address of
504 and places it on the stack.
507 is then placed on top of this on the stack.
508 The array address is indexed by the
509 length 4 index (a length 2 index would use
511 where the individual elements have a size of 8 bytes.
520 \fBcvtwl\fR (lc)+,r0 #r0 has size of records
522 \fBcvtwl\fR (lc)+,r1 #r1 has lower bound
523 \fBmovzwl\fR (lc)+,r2 #r2 has upper-lower bound
524 \fBsubl3\fR r1,(sp)+,r3 #r3 has base subscript
525 \fBcmpl\fR r3,r2 #check for out of bounds
527 \fBmull2\fR r0,r3 #calculate byte offset
528 \fBaddl2\fR r3,(sp) #calculate actual address
531 \fBmovw\fR $ESUBSCR,_perrno
535 Here the lower bound is subtracted, and range checked against the
536 upper minus lower bound.
537 The offset is then scaled to a byte offset into the array
538 and added to the base address on the stack.
539 Multi-dimension subscripts are translated as a sequence of single subscriptings.
543 For indirect references through
545 parameters and pointers,
546 the interpreter has a set of indirection operators that convert a pointer
547 on the stack into a value on the stack from that address.
550 operators are necessary because of the possibility of different
556 operators do conversions to long
557 as they push their data.
561 The interpreter has many arithmetic operators.
562 All operators produce results long enough to prevent overflow
563 unless the bounds of the base type are exceeded.
564 The basic operators available are
566 Addition: ADD*, SUCC*
567 Subtraction: SUB*, PRED*
568 Multiplication: MUL*, SQR*
569 Division: DIV*, DVD*, MOD*
575 The interpreter has several range checking operators.
576 The important distinction among these operators is between values whose
577 legal range begins at zero and those that do not begin at zero,
579 a subrange variable whose values range from 45 to 70.
580 For those that begin at zero, a simpler ``logical'' comparison against
581 the upper bound suffices.
582 For others, both the low and upper bounds must be checked independently,
583 requiring two comparisons.
586 both checks are done using a single index instruction
587 so the only gain is in reducing the inline data.
591 The interpreter includes three operators for
593 statements that are used depending on the width of the
596 For each width, the structure of the case data is the same, and
597 is represented in figure 2.4.
603 case statement operators do a sequential search through the
605 If they find the label value, they take the corresponding entry
606 from the transfer table and cause the interpreter to branch to the
608 If the specified label is not found, an error results.
612 operators take the number of cases as a sub-opcode
614 Three different operators are needed to handle single byte,
615 word, and long case transfer table values.
618 operator has the following code sequence:
624 \fBcvtwl\fR (lc)+,r0 #r0 has length of case table
626 \fBmovaw\fR (lc)[r0],r2 #r2 has pointer to case labels
627 \fBmovzwl\fR (sp)+,r3 #r3 has the element to find
628 \fBlocc\fR r3,r0,(r2) #r0 has index of located element
629 \fBbeql\fR caserr #element not found
630 \fBmnegl\fR r0,r0 #calculate new lc
631 \fBcvtwl\fR (r2)[r0],r1 #r1 has lc offset
635 \fBmovw\fR $ECASE,_perrno
639 Here the interpreter first computes the address of the beginning
640 of the case label value area by adding twice the number of case label
641 values to the address of the transfer table, since the transfer
642 table entries are 2 byte address offsets.
643 It then searches through the label values, and generates an ECASE
644 error if the label is not found.
645 If the label is found, the index of the corresponding entry
646 in the transfer table is extracted and that offset is added
647 to the interpreter location counter.
649 Operations supporting pxp
651 The following operations are defined to do execution profiling.
655 Causes the interpreter to allocate a count buffer
659 and to clear them to zero.
660 The count buffer is placed within an image of the
662 file as described in the
663 .I "PXP Implementation Notes
."
664 The contents of this buffer are written to the file
666 when the program ends.
670 Increments the counter specified by
675 Used at the entry point to procedures and functions,
676 combining a transfer to the entry point of the block with
677 an incrementing of its entry count.
688 and the set relationals
691 The following operations are more interesting.
695 Takes the cardinality of a set of size
697 bytes on top of the stack, leaving a 2 byte integer count.
701 opcode to successively count the number of set bits in the set.
706 This operation requires a non-trivial amount of work,
707 checking bounds and setting individual bits or ranges of bits.
708 This operation sequence is slow,
709 and motivates the presence of the operator
714 include the number of elements
716 in the constructed set,
717 the lower and upper bounds of the set,
721 and a pair of values on the stack for each range in the set, single
722 elements in constructed sets being duplicated with
724 to form degenerate ranges.
733 specifies the size of the set,
736 values the lower and upper bounds of the set.
737 The value on the stack is checked to be in the set on the stack,
738 and a Boolean value of
742 replaces the operands.
748 on a constructed set without constructing it.
751 is on top of the stack followed by the number of pairs in the
753 and then the pairs themselves, all as single word integers.
754 Pairs designate runs of values and single values are represented by
755 a degenerate pair with both value equal.
756 This operator is generated in grammatical constructs such as
758 \fBif\fR character \fBin\fR [`+', '\-', `*', `/']
763 \fBif\fR character \fBin\fR [`a'..`z', `$', `_']
766 These constructs are common in Pascal, and
768 makes them run much faster in the interpreter,
769 as if they were written as an efficient series of
775 Other miscellaneous operators that are present in the interpreter
778 that causes the program to end if the Boolean value on the stack is not
786 that convert between different length arithmetic operands for
787 use in aligning the arguments in
791 calls, and with some untyped built-ins, such as
796 Finally, if the program is run with the run-time testing disabled, there
797 are special operators for
800 and special indexing operators for arrays
801 that have individual element size that is a power of 2.
802 The code can run significantly faster using these operators.
804 Mathematical Functions
806 The transcendental functions
816 are taken from the standard UNIX
817 mathematical package.
818 These functions take double precision floating point
819 values and return the same.
826 take a double precision floating point number.
828 returns an integer representing the machine
829 representation of its argument's exponent,
831 returns the integer part of its argument, and
833 returns the rounded integer part of its argument.
835 System functions and procedures
839 A line limit and a file pointer are passed on the stack.
840 If the limit is non-negative the line limit is set to the
841 specified value, otherwise it is set to unlimited.
842 The default is unlimited.
846 A statement limit is passed on the stack. The statement limit
848 The default is 500,000.
849 No limit is enforced when the ``p'' option is disabled.
856 returns the number of milliseconds of user time used by the program;
858 returns the number of milliseconds of system time used by the program.
862 The number of seconds since some predefined time is
863 returned. Its primary usefulness is in determining
864 elapsed time and in providing a unique time stamp.
867 The other system time procedures are
871 that copy an appropriate text string into a pascal string array.
874 returns the number of command line arguments passed to the program.
877 takes an index on the stack and copies the specified
878 command line argument into a pascal string array.
880 Pascal procedures and functions
886 They function as a memory to memory move with several
888 They do no ``unpacking'' or ``packing'' in the true sense as the
889 interpreter supports no packed data types.
897 of a pointer is passed.
899 allocates a record of a specified size and puts a pointer
900 to it into the pointer variable.
902 deallocates the record pointed to by the pointer
903 and sets the pointer to
909 converts a suitably small integer into an ascii character.
910 Its primary purpose is to do a range check.
915 if its argument is odd and returns
917 if its argument is even.
920 always returns the value