Initial import from FreeBSD RELENG_4:
[dragonfly.git] / share / doc / papers / px / pxin2.n
1 .\" Copyright (c) 1979 The Regents of the University of California.
2 .\" All rights reserved.
3 .\"
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
6 .\" are met:
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\"    notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\"    notice, this list of conditions and the following disclaimer in the
11 .\"    documentation and/or other materials provided with the distribution.
12 .\" 3. All advertising materials mentioning features or use of this software
13 .\"    must display the following acknowledgement:
14 .\"     This product includes software developed by the University of
15 .\"     California, Berkeley and its contributors.
16 .\" 4. Neither the name of the University nor the names of its contributors
17 .\"    may be used to endorse or promote products derived from this software
18 .\"    without specific prior written permission.
19 .\"
20 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 .\" SUCH DAMAGE.
31 .\"
32 .\"     @(#)pxin2.n     5.2 (Berkeley) 4/17/91
33 .\" $FreeBSD: src/share/doc/papers/px/pxin2.n,v 1.1.1.1.14.1 2000/11/30 17:13:59 ru Exp $
34 .\"
35 .nr H1 1
36 .if n .ND
37 .NH
38 Operations
39 .NH 2
40 Naming conventions and operation summary
41 .PP
42 Table 2.1 outlines the opcode typing convention.
43 The expression ``a above b'' means that `a' is on top
44 of the stack with `b' below it.
45 Table 2.3 describes each of the opcodes.
46 The character `*' at the end of a name specifies that
47 all operations with the root prefix 
48 before the `*'
49 are summarized by one entry.
50 Table 2.2 gives the codes used 
51 to describe the type inline data expected by each instruction.
52 .sp 2
53 .so table2.1.n
54 .sp 2
55 .so table2.2.n
56 .bp
57 .so table2.3.n
58 .bp
59 .NH 2
60 Basic control operations
61 .LP
62 .SH
63 HALT
64 .IP
65 Corresponds to the Pascal procedure
66 .I halt ;
67 causes execution to end with a post-mortem backtrace as if a run-time
68 error had occurred.
69 .SH
70 BEG s,W,w,"
71 .IP
72 Causes the second part of the block mark to be created, and
73 .I W
74 bytes of local variable space to be allocated and cleared to zero.
75 Stack overflow is detected here.
76 .I w
77 is the first line of the body of this section for error traceback,
78 and the inline string (length s) the character representation of its name.
79 .SH
80 NODUMP s,W,w,"
81 .IP
82 Equivalent to
83 .SM BEG ,
84 and used to begin the main program when the ``p''
85 option is disabled so that the post-mortem backtrace will be inhibited.
86 .SH
87 END
88 .IP
89 Complementary to the operators
90 .SM CALL
91 and
92 .SM BEG ,
93 exits the current block, calling the procedure
94 .I pclose
95 to flush buffers for and release any local files.
96 Restores the environment of the caller from the block mark.
97 If this is the end for the main program, all files are
98 .I flushed,
99 and the interpreter is exited.
100 .SH
101 CALL l,A
102 .IP
103 Saves the current line number, return address, and active display entry pointer
104 .I dp
105 in the first part of the block mark, then transfers to the entry point
106 given by the relative address
107 .I A ,
108 that is the beginning of a
109 .B procedure
110 or
111 .B function
112 at level
113 .I l.
114 .SH
115 PUSH s
116 .IP
117 Clears
118 .I s
119 bytes on the stack.
120 Used to make space for the return value of a
121 .B function
122 just before calling it.
123 .SH
124 POP s
125 .IP
126 Pop
127 .I s
128 bytes off the stack.
129 Used after a
130 .B function
131 or
132 .B procedure
133 returns to remove the arguments from the stack.
134 .SH
135 TRA a
136 .IP
137 Transfer control to relative address
138 .I a
139 as a local
140 .B goto
141 or part of a structured statement.
142 .SH
143 TRA4 A
144 .IP
145 Transfer control to an absolute address as part of a non-local
146 .B goto
147 or to branch over procedure bodies.
148 .SH
149 LINO s
150 .IP
151 Set current line number to
152 .I s.
153 For consistency, check that the expression stack is empty
154 as it should be (as this is the start of a statement.)
155 This consistency check will fail only if there is a bug in the
156 interpreter or the interpreter code has somehow been damaged.
157 Increment the statement count and if it exceeds the statement limit,
158 generate a fault.
159 .SH
160 GOTO l,A
161 .IP
162 Transfer control to address
163 .I A
164 that is in the block at level
165 .I l
166 of the display.
167 This is a non-local
168 .B goto.
169 Causes each block to be exited as if with
170 .SM END ,
171 flushing and freeing files with
172 .I pclose,
173 until the current display entry is at level
174 .I l.
175 .SH
176 SDUP*
177 .IP
178 Duplicate the word or long on the top of
179 the stack.
180 This is used mostly for constructing sets.
181 See section 2.11.
182 .NH 2
183 If and relational operators
184 .SH
185 IF a
186 .IP
187 The interpreter conditional transfers all take place using this operator
188 that examines the Boolean value on the top of the stack.
189 If the value is
190 .I true ,
191 the next code is executed,
192 otherwise control transfers to the specified address.
193 .SH
194 REL* r
195 .IP
196 These take two arguments on the stack,
197 and the sub-operation code specifies the relational operation to
198 be done, coded as follows with `a' above `b' on the stack:
199 .DS
200 .mD
201 .TS
202 lb lb
203 c a.
204 Code    Operation
205 _
206 0       a = b
207 2       a <> b
208 4       a < b
209 6       a > b
210 8       a <= b
211 10      a >= b
212 .TE
213 .DE
214 .IP
215 Each operation does a test to set the condition code
216 appropriately and then does an indexed branch based on the
217 sub-operation code to a test of the condition here specified,
218 pushing a Boolean value on the stack.
219 .IP
220 Consider the statement fragment:
221 .DS
222 .mD
223 \*bif\fR a = b \*bthen\fR
224 .DE
225 .IP
226 If
227 .I a
228 and
229 .I b
230 are integers this generates the following code:
231 .DS
232 .TS
233 lp-2w(8) l.
234 RV4:\fIl        a\fR
235 RV4:\fIl        b\fR
236 REL4    \&=
237 IF      \fIElse part offset\fR
238 .sp
239 .T&
240 c s.
241 \fI\&... Then part code ...\fR
242 .TE
243 .DE
244 .NH 2
245 Boolean operators
246 .PP
247 The Boolean operators
248 .SM AND ,
249 .SM OR ,
250 and
251 .SM NOT
252 manipulate values on the top of the stack.
253 All Boolean values are kept in single bytes in memory,
254 or in single words on the stack.
255 Zero represents a Boolean \fIfalse\fP, and one a Boolean \fItrue\fP.
256 .NH 2
257 Right value, constant, and assignment operators
258 .SH
259 LRV* l,A
260 .br
261 RV* l,a
262 .IP
263 The right value operators load values on the stack.
264 They take a block number as a sub-opcode and load the appropriate
265 number of bytes from that block at the offset specified
266 in the following word onto the stack. As an example, consider
267 .SM LRV4 :
268 .DS
269 .mD
270 _LRV4:
271         \fBcvtbl\fR     (lc)+,r0        #r0 has display index
272         \fBaddl3\fR     _display(r0),(lc)+,r1   #r1 has variable address
273         \fBpushl\fR     (r1)    #put value on the stack
274         \fBjmp\fR       (loop)
275 .DE
276 .IP
277 Here the interpreter places the display level in r0.
278 It then adds the appropriate display value to the inline offset and
279 pushes the value at this location onto the stack.
280 Control then returns to the main
281 interpreter loop.
282 The
283 .SM RV* 
284 operators have short inline data that
285 reduces the space required to address the first 32K of
286 stack space in each stack frame.
287 The operators
288 .SM RV14
289 and
290 .SM RV24
291 provide explicit conversion to long as the data
292 is pushed.
293 This saves the generation of
294 .SM STOI
295 to align arguments to 
296 .SM C
297 subroutines.
298 .SH
299 CON* r
300 .IP
301 The constant operators load a value onto the stack from inline code.
302 Small integer values are condensed and loaded by the
303 .SM CON1
304 operator, that is given by
305 .DS
306 .mD
307 _CON1:
308         \fBcvtbw\fR     (lc)+,\-(sp)
309         \fBjmp\fR       (loop)
310 .DE
311 .IP
312 Here note that little work was required as the required constant
313 was available at (lc)+.
314 For longer constants,
315 .I lc
316 must be incremented before moving the constant.
317 The operator
318 .SM CON
319 takes a length specification in the sub-opcode and can be used to load
320 strings and other variable length data onto the stack.
321 The operators 
322 .SM CON14
323 and
324 .SM CON24
325 provide explicit conversion to long as the constant is pushed.
326 .SH
327 AS*
328 .IP
329 The assignment operators are similar to arithmetic and relational operators
330 in that they take two operands, both in the stack,
331 but the lengths given for them specify
332 first the length of the value on the stack and then the length
333 of the target in memory.
334 The target address in memory is under the value to be stored.
335 Thus the statement
336 .DS
337 i := 1
338 .DE
339 .IP
340 where
341 .I i
342 is a full-length, 4 byte, integer,
343 will generate the code sequence
344 .DS
345 .TS
346 lp-2w(8) l.
347 LV:\fIl i\fP
348 CON1:1
349 AS24
350 .TE
351 .DE
352 .IP
353 Here
354 .SM LV
355 will load the address of
356 .I i,
357 that is really given as a block number in the sub-opcode and an
358 offset in the following word,
359 onto the stack, occupying a single word.
360 .SM CON1 ,
361 that is a single word instruction,
362 then loads the constant 1,
363 that is in its sub-opcode,
364 onto the stack.
365 Since there are not one byte constants on the stack,
366 this becomes a 2 byte, single word integer.
367 The interpreter then assigns a length 2 integer to a length 4 integer using
368 .SM AS24 \&.
369 The code sequence for
370 .SM AS24
371 is given by:
372 .DS
373 .mD
374 _AS24:
375         \fBincl\fR      lc
376         \fBcvtwl\fR     (sp)+,*(sp)+
377         \fBjmp\fR       (loop)
378 .DE
379 .IP
380 Thus the interpreter gets the single word off the stack,
381 extends it to be a 4 byte integer
382 gets the target address off the stack,
383 and finally stores the value in the target.
384 This is a typical use of the constant and assignment operators.
385 .NH 2
386 Addressing operations
387 .SH
388 LLV l,W
389 .br
390 LV l,w
391 .IP
392 The most common operation done by the interpreter
393 is the ``left value'' or ``address of'' operation.
394 It is given by:
395 .DS
396 .mD
397 _LLV:
398         \fBcvtbl\fR     (lc)+,r0        #r0 has display index
399         \fBaddl3\fR     _display(r0),(lc)+,\-(sp)       #push address onto the stack
400         \fBjmp\fR       (loop)
401 .DE
402 .IP
403 It calculates an address in the block specified in the sub-opcode
404 by adding the associated display entry to the
405 offset that appears in the following word.
406 The
407 .SM LV
408 operator has a short inline data that reduces the space
409 required to address the first 32K of stack space in each call frame.
410 .SH
411 OFF s
412 .IP
413 The offset operator is used in field names.
414 Thus to get the address of
415 .LS
416 p^.f1
417 .LE
418 .IP
419 .I pi
420 would generate the sequence
421 .DS
422 .mD
423 .TS
424 lp-2w(8) l.
425 RV:\fIl p\fP
426 OFF     \fIf1\fP
427 .TE
428 .DE
429 .IP
430 where the
431 .SM RV
432 loads the value of
433 .I p,
434 given its block in the sub-opcode and offset in the following word,
435 and the interpreter then adds the offset of the field
436 .I f1
437 in its record to get the correct address.
438 .SM OFF
439 takes its argument in the sub-opcode if it is small enough.
440 .SH
441 NIL
442 .IP
443 The example above is incomplete, lacking a check for a
444 .B nil
445 pointer.
446 The code generated would be
447 .DS
448 .TS
449 lp-2w(8) l.
450 RV:\fIl p\fP
451 NIL
452 OFF     \fIf1\fP
453 .TE
454 .DE
455 .IP
456 where the
457 .SM NIL
458 operation checks for a
459 .I nil
460 pointer and generates the appropriate runtime error if it is.
461 .SH
462 LVCON s,"
463 .IP
464 A pointer to the specified length inline data is pushed
465 onto the stack.
466 This is primarily used for
467 .I printf
468 type strings used by 
469 .SM WRITEF .
470 (see sections 3.6 and 3.8)
471 .SH
472 INX* s,w,w
473 .IP
474 The operators
475 .SM INX2
476 and
477 .SM INX4
478 are used for subscripting.
479 For example, the statement
480 .DS
481 a[i] := 2.0
482 .DE
483 .IP
484 with
485 .I i
486 an integer and
487 .I a
488 an
489 ``array [1..1000] of real''
490 would generate
491 .DS
492 .TS
493 lp-2w(8) l.
494 LV:\fIl a\fP
495 RV4:\fIl        i\fP
496 INX4:8  1,999
497 CON8    2.0
498 AS8
499 .TE
500 .DE
501 .IP
502 Here the
503 .SM LV
504 operation takes the address of
505 .I a
506 and places it on the stack.
507 The value of
508 .I i
509 is then placed on top of this on the stack.
510 The array address is indexed by the
511 length 4 index (a length 2 index would use
512 .SM INX2 )
513 where the individual elements have a size of 8 bytes.
514 The code for 
515 .SM INX4
516 is:
517 .DS
518 .mD
519 _INX4:
520         \fBcvtbl\fR     (lc)+,r0
521         \fBbneq\fR      L1
522         \fBcvtwl\fR     (lc)+,r0        #r0 has size of records
523 L1:
524         \fBcvtwl\fR     (lc)+,r1        #r1 has lower bound
525         \fBmovzwl\fR    (lc)+,r2        #r2 has upper-lower bound
526         \fBsubl3\fR     r1,(sp)+,r3     #r3 has base subscript
527         \fBcmpl\fR      r3,r2   #check for out of bounds
528         \fBbgtru\fR     esubscr
529         \fBmull2\fR     r0,r3   #calculate byte offset
530         \fBaddl2\fR     r3,(sp)         #calculate actual address
531         \fBjmp\fR       (loop)
532 esubscr:
533         \fBmovw\fR      $ESUBSCR,_perrno
534         \fBjbr\fR       error
535 .DE
536 .IP
537 Here the lower bound is subtracted, and range checked against the
538 upper minus lower bound.
539 The offset is then scaled to a byte offset into the array
540 and added to the base address on the stack.
541 Multi-dimension subscripts are translated as a sequence of single subscriptings.
542 .SH
543 IND*
544 .IP
545 For indirect references through
546 .B var
547 parameters and pointers,
548 the interpreter has a set of indirection operators that convert a pointer
549 on the stack into a value on the stack from that address.
550 different
551 .SM IND
552 operators are necessary because of the possibility of different
553 length operands.
554 The
555 .SM IND14
556 and
557 .SM IND24
558 operators do conversions to long
559 as they push their data.
560 .NH 2
561 Arithmetic operators
562 .PP
563 The interpreter has many arithmetic operators.
564 All operators produce results long enough to prevent overflow
565 unless the bounds of the base type are exceeded.
566 The basic operators available are
567 .DS
568 Addition:       ADD*, SUCC*
569 Subtraction:    SUB*, PRED*
570 Multiplication: MUL*, SQR*
571 Division:       DIV*, DVD*, MOD*
572 Unary:          NEG*, ABS*
573 .DE
574 .NH 2
575 Range checking
576 .PP
577 The interpreter has several range checking operators.
578 The important distinction among these operators is between values whose
579 legal range begins at zero and those that do not begin at zero, 
580 for example
581 a subrange variable whose values range from 45 to 70.
582 For those that begin at zero, a simpler ``logical'' comparison against
583 the upper bound suffices.
584 For others, both the low and upper bounds must be checked independently,
585 requiring two comparisons.
586 On the 
587 .SM "VAX 11/780"
588 both checks are done using a single index instruction
589 so the only gain is in reducing the inline data.
590 .NH 2
591 Case operators
592 .PP
593 The interpreter includes three operators for
594 .B case
595 statements that are used depending on the width of the 
596 .B case
597 label type.
598 For each width, the structure of the case data is the same, and
599 is represented in figure 2.4.
600 .sp 1
601 .so fig2.4.n
602 .PP
603 The
604 .SM CASEOP
605 case statement operators do a sequential search through the
606 case label values.
607 If they find the label value, they take the corresponding entry
608 from the transfer table and cause the interpreter to branch to the
609 specified statement.
610 If the specified label is not found, an error results.
611 .PP
612 The
613 .SM CASE
614 operators take the number of cases as a sub-opcode
615 if possible.
616 Three different operators are needed to handle single byte,
617 word, and long case transfer table values.
618 For example, the
619 .SM CASEOP1
620 operator has the following code sequence:
621 .DS
622 .mD
623 _CASEOP1:
624         \fBcvtbl\fR     (lc)+,r0
625         \fBbneq\fR      L1
626         \fBcvtwl\fR     (lc)+,r0        #r0 has length of case table
627 L1:
628         \fBmovaw\fR     (lc)[r0],r2     #r2 has pointer to case labels
629         \fBmovzwl\fR    (sp)+,r3        #r3 has the element to find
630         \fBlocc\fR      r3,r0,(r2)      #r0 has index of located element
631         \fBbeql\fR      caserr  #element not found
632         \fBmnegl\fR     r0,r0   #calculate new lc
633         \fBcvtwl\fR     (r2)[r0],r1     #r1 has lc offset
634         \fBaddl2\fR     r1,lc
635         \fBjmp\fR       (loop)
636 caserr:
637         \fBmovw\fR      $ECASE,_perrno
638         \fBjbr\fR       error
639 .DE
640 .PP
641 Here the interpreter first computes the address of the beginning
642 of the case label value area by adding twice the number of case label
643 values to the address of the transfer table, since the transfer
644 table entries are 2 byte address offsets.
645 It then searches through the label values, and generates an ECASE
646 error if the label is not found.
647 If the label is found, the index of the corresponding entry
648 in the transfer table is extracted and that offset is added
649 to the interpreter location counter.
650 .NH 2
651 Operations supporting pxp
652 .PP
653 The following operations are defined to do execution profiling.
654 .SH
655 PXPBUF w
656 .IP
657 Causes the interpreter to allocate a count buffer
658 with
659 .I w
660 four byte counters
661 and to clear them to zero.
662 The count buffer is placed within an image of the
663 .I pmon.out
664 file as described in the
665 .I "PXP Implementation Notes."
666 The contents of this buffer are written to the file
667 .I pmon.out
668 when the program ends.
669 .SH
670 COUNT w
671 .IP
672 Increments the counter specified by
673 .I w .
674 .SH
675 TRACNT w,A
676 .IP
677 Used at the entry point to procedures and functions,
678 combining a transfer to the entry point of the block with
679 an incrementing of its entry count.
680 .NH 2
681 Set operations
682 .PP
683 The set operations:
684 union
685 .SM ADDT,
686 intersection
687 .SM MULT,
688 element removal
689 .SM SUBT,
690 and the set relationals
691 .SM RELT
692 are straightforward.
693 The following operations are more interesting.
694 .SH
695 CARD s
696 .IP
697 Takes the cardinality of a set of size
698 .I s
699 bytes on top of the stack, leaving a 2 byte integer count.
700 .SM CARD
701 uses the 
702 .B ffs
703 opcode to successively count the number of set bits in the set.
704 .SH
705 CTTOT s,w,w
706 .IP
707 Constructs a set.
708 This operation requires a non-trivial amount of work,
709 checking bounds and setting individual bits or ranges of bits.
710 This operation sequence is slow,
711 and motivates the presence of the operator
712 .SM INCT
713 below.
714 The arguments to
715 .SM CTTOT
716 include the number of elements
717 .I s
718 in the constructed set,
719 the lower and upper bounds of the set,
720 the two
721 .I w
722 values,
723 and a pair of values on the stack for each range in the set, single
724 elements in constructed sets being duplicated with
725 .SM SDUP
726 to form degenerate ranges.
727 .SH
728 IN s,w,w
729 .IP
730 The operator
731 .B in
732 for sets.
733 The value
734 .I s
735 specifies the size of the set,
736 the two
737 .I w
738 values the lower and upper bounds of the set.
739 The value on the stack is checked to be in the set on the stack,
740 and a Boolean value of
741 .I true
742 or
743 .I false
744 replaces the operands.
745 .SH
746 INCT
747 .IP
748 The operator
749 .B in
750 on a constructed set without constructing it.
751 The left operand of
752 .B in
753 is on top of the stack followed by the number of pairs in the
754 constructed set,
755 and then the pairs themselves, all as single word integers.
756 Pairs designate runs of values and single values are represented by
757 a degenerate pair with both value equal.
758 This operator is generated in grammatical constructs such as
759 .LS
760 \fBif\fR character \fBin\fR [`+', '\-', `*', `/']
761 .LE
762 .IP
763 or
764 .LS
765 \fBif\fR character \fBin\fR [`a'..`z', `$', `_']
766 .LE
767 .IP
768 These constructs are common in Pascal, and
769 .SM INCT
770 makes them run much faster in the interpreter,
771 as if they were written as an efficient series of
772 .B if
773 statements.
774 .NH 2
775 Miscellaneous
776 .PP
777 Other miscellaneous operators that are present in the interpreter
778 are
779 .SM ASRT
780 that causes the program to end if the Boolean value on the stack is not
781 .I true,
782 and
783 .SM STOI ,
784 .SM STOD ,
785 .SM ITOD ,
786 and
787 .SM ITOS
788 that convert between different length arithmetic operands for
789 use in aligning the arguments in
790 .B procedure
791 and
792 .B function
793 calls, and with some untyped built-ins, such as
794 .SM SIN
795 and
796 .SM COS \&.
797 .PP
798 Finally, if the program is run with the run-time testing disabled, there
799 are special operators for
800 .B for
801 statements
802 and special indexing operators for arrays
803 that have individual element size that is a power of 2.
804 The code can run significantly faster using these operators.
805 .NH 2
806 Mathematical Functions
807 .PP
808 The transcendental functions 
809 .SM SIN ,
810 .SM COS ,
811 .SM ATAN ,
812 .SM EXP ,
813 .SM LN ,
814 .SM SQRT ,
815 .SM SEED ,
816 and
817 .SM RANDOM
818 are taken from the standard UNIX
819 mathematical package.
820 These functions take double precision floating point
821 values and return the same.
822 .PP
823 The functions
824 .SM EXPO ,
825 .SM TRUNC ,
826 and
827 .SM ROUND
828 take a double precision floating point number.
829 .SM EXPO
830 returns an integer representing the machine 
831 representation of its argument's exponent,
832 .SM TRUNC
833 returns the integer part of its argument, and
834 .SM ROUND
835 returns the rounded integer part of its argument.
836 .NH 2
837 System functions and procedures
838 .SH
839 LLIMIT
840 .IP
841 A line limit and a file pointer are passed on the stack.
842 If the limit is non-negative the line limit is set to the
843 specified value, otherwise it is set to unlimited.
844 The default is unlimited.
845 .SH
846 STLIM
847 .IP
848 A statement limit is passed on the stack. The statement limit 
849 is set as specified.
850 The default is 500,000.
851 No limit is enforced when the ``p'' option is disabled.
852 .SH
853 CLCK
854 .br
855 SCLCK
856 .IP
857 .SM CLCK
858 returns the number of milliseconds of user time used by the program;
859 .SM SCLCK
860 returns the number of milliseconds of system time used by the program.
861 .SH
862 WCLCK
863 .IP
864 The number of seconds since some predefined time is
865 returned. Its primary usefulness is in determining
866 elapsed time and in providing a unique time stamp.
867 .sp
868 .LP
869 The other system time procedures are
870 .SM DATE
871 and
872 .SM TIME
873 that copy an appropriate text string into a pascal string array.
874 The function
875 .SM ARGC
876 returns the number of command line arguments passed to the program.
877 The procedure
878 .SM ARGV
879 takes an index on the stack and copies the specified
880 command line argument into a pascal string array.
881 .NH 2
882 Pascal procedures and functions
883 .SH
884 PACK s,w,w,w
885 .br
886 UNPACK s,w,w,w
887 .IP
888 They function as a memory to memory move with several
889 semantic checks. 
890 They do no ``unpacking'' or ``packing'' in the true sense as the
891 interpreter supports no packed data types.
892 .SH
893 NEW s
894 .br
895 DISPOSE s
896 .IP
897 An 
898 .SM LV
899 of a pointer is passed. 
900 .SM NEW
901 allocates a record of a specified size and puts a pointer
902 to it into the pointer variable.
903 .SM DISPOSE
904 deallocates the record pointed to by the pointer
905 and sets the pointer to 
906 .SM NIL .
907 .sp
908 .LP
909 The function
910 .SM CHR*
911 converts a suitably small integer into an ascii character.
912 Its primary purpose is to do a range check.
913 The function
914 .SM ODD*
915 returns 
916 .I true
917 if its argument is odd and returns
918 .I false
919 if its argument is even.
920 The function 
921 .SM UNDEF
922 always returns the value
923 .I false .