xref: /original-bsd/usr.bin/pascal/px/interp.c (revision 1f3a482a)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)interp.c 1.14 06/10/81";
4 
5 #include <math.h>
6 #include "whoami.h"
7 #include "objfmt.h"
8 #include "vars.h"
9 #include "panics.h"
10 #include "h02opcs.h"
11 #include "machdep.h"
12 #include "libpc.h"
13 
14 /*
15  * program variables
16  */
17 union disply	_display;
18 struct disp	*_dp;
19 long	_lino = 0;
20 int	_argc;
21 char	**_argv;
22 long	_mode;
23 bool	_runtst = TRUE;
24 bool	_nodump = FALSE;
25 long	_stlim = 500000;
26 long	_stcnt = 0;
27 long	_seed = 1;
28 #ifdef VAX
29 char	*_minptr = (char *)0x7fffffff;
30 #else
31 char	*_minptr = (char *)0xffff;
32 #endif VAX
33 char	*_maxptr = (char *)0;
34 long	*_pcpcount = (long *)0;
35 long	_cntrs = 0;
36 long	_rtns = 0;
37 
38 /*
39  * standard files
40  */
41 char		_inwin, _outwin, _errwin;
42 struct iorechd	_err = {
43 	&_errwin,		/* fileptr */
44 	0,			/* lcount  */
45 	0x7fffffff,		/* llimit  */
46 	&_iob[2],		/* fbuf    */
47 	FILNIL,			/* fchain  */
48 	STDLVL,			/* flev    */
49 	"Message file",		/* pfname  */
50 	FTEXT | FWRITE | EOFF,	/* funit   */
51 	2,			/* fblk    */
52 	1			/* fsize   */
53 };
54 struct iorechd	output = {
55 	&_outwin,		/* fileptr */
56 	0,			/* lcount  */
57 	0x7fffffff,		/* llimit  */
58 	&_iob[1],		/* fbuf    */
59 	ERR,			/* fchain  */
60 	STDLVL,			/* flev    */
61 	"standard output",	/* pfname  */
62 	FTEXT | FWRITE | EOFF,	/* funit   */
63 	1,			/* fblk    */
64 	1			/* fsize   */
65 };
66 struct iorechd	input = {
67 	&_inwin,		/* fileptr */
68 	0,			/* lcount  */
69 	0x7fffffff,		/* llimit  */
70 	&_iob[0],		/* fbuf    */
71 	OUTPUT,			/* fchain  */
72 	STDLVL,			/* flev    */
73 	"standard input",	/* pfname  */
74 	FTEXT | FREAD | SYNC,	/* funit   */
75 	0,			/* fblk    */
76 	1			/* fsize   */
77 };
78 
79 /*
80  * file record variables
81  */
82 long		_filefre = PREDEF;
83 struct iorechd	_fchain = {
84 	0, 0, 0, 0,		/* only use fchain field */
85 	INPUT			/* fchain  */
86 };
87 struct iorec	*_actfile[MAXFILES] = {
88 	INPUT,
89 	OUTPUT,
90 	ERR
91 };
92 
93 /*
94  * Px profile array
95  */
96 #ifdef PROFILE
97 long _profcnts[NUMOPS];
98 #endif PROFILE
99 
100 /*
101  * debugging variables
102  */
103 #ifdef DEBUG
104 char opc[10];
105 long opcptr = 9;
106 #endif DEBUG
107 
108 interpreter(base)
109 	char *base;
110 {
111 	union progcntr pc;		/* interpreted program cntr */
112 	register char *vpc;		/* register used for "pc" */
113 	struct iorec *curfile;		/* active file */
114 	register struct stack *stp;	/* active stack frame ptr */
115 	/*
116 	 * the following variables are used as scratch
117 	 */
118 	register char *tcp;
119 	register long tl, tl1, tl2;
120 	double td, td1;
121 	struct sze8 t8;
122 	long *tlp;
123 	register short *tsp, *tsp1, ts;
124 	bool tb;
125 	char *tcp1;
126 	struct stack *tstp;
127 	struct formalrtn *tfp;
128 	union progcntr tpc;
129 	struct iorec **ip;
130 
131 	/*
132 	 * Setup sets up any hardware specific parameters before
133 	 * starting the interpreter. Typically this is inline replaced
134 	 * by interp.sed to utilize specific machine instructions.
135 	 */
136 	 setup();
137 	/*
138 	 * necessary only on systems which do not initialize
139 	 * memory to zero
140 	 */
141 	for (ip = &_actfile[3]; ip < &_actfile[MAXFILES]; *ip++ = FILNIL)
142 		/* void */;
143 	/*
144 	 * set up global environment, then ``call'' the main program
145 	 */
146 	_display.frame[0].locvars = pushsp((long)(2 * sizeof(struct iorec *)));
147 	_display.frame[0].locvars += 2 * sizeof(struct iorec *);
148 	*(struct iorec **)(_display.frame[0].locvars + OUTPUT_OFF) = OUTPUT;
149 	*(struct iorec **)(_display.frame[0].locvars + INPUT_OFF) = INPUT;
150 	stp = (struct stack *)pushsp((long)(sizeof(struct stack)));
151 	_dp = &_display.frame[0];
152 	pc.cp = base;
153 	for(;;) {
154 #		ifdef DEBUG
155 		if (++opcptr == 10)
156 			opcptr = 0;
157 		opc[opcptr] = *pc.ucp;
158 #		endif DEBUG
159 #		ifdef PROFILE
160 		_profcnts[*pc.ucp]++;
161 #		endif PROFILE
162 		switch (*pc.ucp++) {
163 		case O_NODUMP:
164 			_nodump = TRUE;
165 			/* and fall through */
166 		case O_BEG:
167 			_dp += 1;		/* enter local scope */
168 			stp->odisp = *_dp;	/* save old display value */
169 			tl = *pc.ucp++;		/* tl = name size */
170 			stp->entry = pc.hdrp;	/* pointer to entry info */
171 			tl1 = pc.hdrp->framesze;/* tl1 = size of frame */
172 			_lino = pc.hdrp->offset;
173 			_runtst = pc.hdrp->tests;
174 			disableovrflo();
175 			if (_runtst)
176 				enableovrflo();
177 			pc.cp += (int)tl;	/* skip over proc hdr info */
178 			stp->file = curfile;	/* save active file */
179 			tcp = pushsp(tl1);	/* tcp = new top of stack */
180 			if (_runtst)		/* zero stack frame */
181 				blkclr(tl1, tcp);
182 			tcp += (int)tl1;	/* offsets of locals are neg */
183 			_dp->locvars = tcp;	/* set new display pointer */
184 			_dp->stp = stp;
185 			stp->tos = pushsp((long)0); /* set tos pointer */
186 			continue;
187 		case O_END:
188 			PCLOSE(_dp->locvars);	/* flush & close local files */
189 			stp = _dp->stp;
190 			curfile = stp->file;	/* restore old active file */
191 			*_dp = stp->odisp;	/* restore old display entry */
192 			if (_dp == &_display.frame[1])
193 				return;		/* exiting main proc ??? */
194 			_lino = stp->lino;	/* restore lino, pc, dp */
195 			pc.cp = stp->pc.cp;
196 			_dp = stp->dp;
197 			_runtst = stp->entry->tests;
198 			disableovrflo();
199 			if (_runtst)
200 				enableovrflo();
201 			popsp(stp->entry->framesze +	/* pop local vars */
202 			      sizeof(struct stack) +	/* pop stack frame */
203 			      stp->entry->nargs);	/* pop parms */
204 			continue;
205 		case O_CALL:
206 			tl = *pc.cp++;
207 			tcp = base + *pc.lp++;/* calc new entry point */
208 			tcp += sizeof(short);
209 			tcp = base + *(long *)tcp;
210 			stp = (struct stack *)
211 				pushsp((long)(sizeof(struct stack)));
212 			stp->lino = _lino;	/* save lino, pc, dp */
213 			stp->pc.cp = pc.cp;
214 			stp->dp = _dp;
215 			_dp = &_display.frame[tl]; /* set up new display ptr */
216 			pc.cp = tcp;
217 			continue;
218 		case O_FCALL:
219 			pc.cp++;
220 			tfp = (struct formalrtn *)popaddr();
221 			stp = (struct stack *)
222 				pushsp((long)(sizeof(struct stack)));
223 			stp->lino = _lino;	/* save lino, pc, dp */
224 			stp->pc.cp = pc.cp;
225 			stp->dp = _dp;
226 			pc.cp = tfp->fentryaddr;/* calc new entry point */
227 			_dp = &_display.frame[tfp->fbn];/* new display ptr */
228 			blkcpy(tfp->fbn * sizeof(struct disp),
229 				&_display.frame[1], &tfp->fdisp[tfp->fbn]);
230 			blkcpy(tfp->fbn * sizeof(struct disp),
231 				&tfp->fdisp[0], &_display.frame[1]);
232 			continue;
233 		case O_FRTN:
234 			tl = *pc.cp++;		/* tl = size of return obj */
235 			if (tl == 0)
236 				tl = *pc.usp++;
237 			tcp = pushsp((long)(0));
238 			tfp = *(struct formalrtn **)(tcp + tl);
239 			if (tl != 0) {
240 				blkcpy(tl, tcp,
241 				    tcp + sizeof(struct formalrtn *));
242 			}
243 			popsp((long)(sizeof(struct formalrtn *)));
244 			blkcpy(tfp->fbn * sizeof(struct disp),
245 			    &tfp->fdisp[tfp->fbn], &_display.frame[1]);
246 			continue;
247 		case O_FSAV:
248 			tfp = (struct formalrtn *)popaddr();
249 			tfp->fbn = *pc.cp++;	/* blk number of routine */
250 			tcp = base + *pc.lp++;	/* calc new entry point */
251 			tcp += sizeof(short);
252 			tfp->fentryaddr = base + *(long *)tcp;
253 			blkcpy(tfp->fbn * sizeof(struct disp),
254 				&_display.frame[1], &tfp->fdisp[0]);
255 			pushaddr(tfp);
256 			continue;
257 		case O_SDUP2:
258 			pc.cp++;
259 			tl = pop2();
260 			push2((short)(tl));
261 			push2((short)(tl));
262 			continue;
263 		case O_SDUP4:
264 			pc.cp++;
265 			tl = pop4();
266 			push4(tl);
267 			push4(tl);
268 			continue;
269 		case O_TRA:
270 			pc.cp++;
271 			pc.cp += *pc.sp;
272 			continue;
273 		case O_TRA4:
274 			pc.cp++;
275 			pc.cp = base + *pc.lp;
276 			continue;
277 		case O_GOTO:
278 			tstp = _display.frame[*pc.cp++].stp; /* ptr to
279 								exit frame */
280 			pc.cp = base + *pc.lp;
281 			stp = _dp->stp;
282 			while (tstp != stp) {
283 				if (_dp == &_display.frame[1])
284 					ERROR("Active frame not found in non-local goto\n", 0); /* exiting prog ??? */
285 				PCLOSE(_dp->locvars); /* close local files */
286 				curfile = stp->file;  /* restore active file */
287 				*_dp = stp->odisp;    /* old display entry */
288 				_dp = stp->dp;	      /* restore dp */
289 				stp = _dp->stp;
290 			}
291 			/* pop locals, stack frame, parms, and return values */
292 			popsp((long)(stp->tos - pushsp((long)(0))));
293 			continue;
294 		case O_LINO:
295 			if (_dp->stp->tos != pushsp((long)(0)))
296 				panic(PSTKNEMP);
297 			_lino = *pc.cp++;	/* set line number */
298 			if (_lino == 0)
299 				_lino = *pc.sp++;
300 			if (_runtst) {
301 				LINO();		/* inc statement count */
302 				continue;
303 			}
304 			_stcnt++;
305 			continue;
306 		case O_PUSH:
307 			tl = *pc.cp++;
308 			if (tl == 0)
309 				tl = *pc.usp++;
310 			tl = (-tl + 1) & ~1;
311 			tcp = pushsp(tl);
312 			if (_runtst)
313 				blkclr(tl, tcp);
314 			continue;
315 		case O_IF:
316 			pc.cp++;
317 			if (pop2()) {
318 				pc.sp++;
319 				continue;
320 			}
321 			pc.cp += *pc.sp;
322 			continue;
323 		case O_REL2:
324 			tl = pop2();
325 			tl1 = pop2();
326 			goto cmplong;
327 		case O_REL24:
328 			tl = pop2();
329 			tl1 = pop4();
330 			goto cmplong;
331 		case O_REL42:
332 			tl = pop4();
333 			tl1 = pop2();
334 			goto cmplong;
335 		case O_REL4:
336 			tl = pop4();
337 			tl1 = pop4();
338 		cmplong:
339 			tl2 = *pc.cp++;
340 			switch (tl2) {
341 			case releq:
342 				push2(tl1 == tl);
343 				continue;
344 			case relne:
345 				push2(tl1 != tl);
346 				continue;
347 			case rellt:
348 				push2(tl1 < tl);
349 				continue;
350 			case relgt:
351 				push2(tl1 > tl);
352 				continue;
353 			case relle:
354 				push2(tl1 <= tl);
355 				continue;
356 			case relge:
357 				push2(tl1 >= tl);
358 				continue;
359 			default:
360 				panic(PSYSTEM);
361 				continue;
362 			}
363 		case O_RELG:
364 			tl2 = *pc.cp++;		/* tc has jump opcode */
365 			tl = *pc.usp++;		/* tl has comparison length */
366 			tl1 = (tl + 1) & ~1;	/* tl1 has arg stack length */
367 			tcp = pushsp((long)(0));/* tcp pts to first arg */
368 			switch (tl2) {
369 			case releq:
370 				tb = RELEQ(tl, tcp + tl1, tcp);
371 				break;
372 			case relne:
373 				tb = RELNE(tl, tcp + tl1, tcp);
374 				break;
375 			case rellt:
376 				tb = RELSLT(tl, tcp + tl1, tcp);
377 				break;
378 			case relgt:
379 				tb = RELSGT(tl, tcp + tl1, tcp);
380 				break;
381 			case relle:
382 				tb = RELSLE(tl, tcp + tl1, tcp);
383 				break;
384 			case relge:
385 				tb = RELSGE(tl, tcp + tl1, tcp);
386 				break;
387 			default:
388 				panic(PSYSTEM);
389 				break;
390 			}
391 			popsp(tl1 << 1);
392 			push2((short)(tb));
393 			continue;
394 		case O_RELT:
395 			tl2 = *pc.cp++;		/* tc has jump opcode */
396 			tl1 = *pc.usp++;	/* tl1 has comparison length */
397 			tcp = pushsp((long)(0));/* tcp pts to first arg */
398 			switch (tl2) {
399 			case releq:
400 				tb = RELEQ(tl1, tcp + tl1, tcp);
401 				break;
402 			case relne:
403 				tb = RELNE(tl1, tcp + tl1, tcp);
404 				break;
405 			case rellt:
406 				tb = RELTLT(tl1, tcp + tl1, tcp);
407 				break;
408 			case relgt:
409 				tb = RELTGT(tl1, tcp + tl1, tcp);
410 				break;
411 			case relle:
412 				tb = RELTLE(tl1, tcp + tl1, tcp);
413 				break;
414 			case relge:
415 				tb = RELTGE(tl1, tcp + tl1, tcp);
416 				break;
417 			default:
418 				panic(PSYSTEM);
419 				break;
420 			}
421 			popsp(tl1 << 1);
422 			push2((short)(tb));
423 			continue;
424 		case O_REL28:
425 			td = pop2();
426 			td1 = pop8();
427 			goto cmpdbl;
428 		case O_REL48:
429 			td = pop4();
430 			td1 = pop8();
431 			goto cmpdbl;
432 		case O_REL82:
433 			td = pop8();
434 			td1 = pop2();
435 			goto cmpdbl;
436 		case O_REL84:
437 			td = pop8();
438 			td1 = pop4();
439 			goto cmpdbl;
440 		case O_REL8:
441 			td = pop8();
442 			td1 = pop8();
443 		cmpdbl:
444 			switch (*pc.cp++) {
445 			case releq:
446 				push2(td1 == td);
447 				continue;
448 			case relne:
449 				push2(td1 != td);
450 				continue;
451 			case rellt:
452 				push2(td1 < td);
453 				continue;
454 			case relgt:
455 				push2(td1 > td);
456 				continue;
457 			case relle:
458 				push2(td1 <= td);
459 				continue;
460 			case relge:
461 				push2(td1 >= td);
462 				continue;
463 			default:
464 				panic(PSYSTEM);
465 				continue;
466 			}
467 		case O_AND:
468 			pc.cp++;
469 			push2(pop2() & pop2());
470 			continue;
471 		case O_OR:
472 			pc.cp++;
473 			push2(pop2() | pop2());
474 			continue;
475 		case O_NOT:
476 			pc.cp++;
477 			push2(pop2() ^ 1);
478 			continue;
479 		case O_AS2:
480 			pc.cp++;
481 			tl = pop2();
482 			*(short *)popaddr() = tl;
483 			continue;
484 		case O_AS4:
485 			pc.cp++;
486 			tl = pop4();
487 			*(long *)popaddr() = tl;
488 			continue;
489 		case O_AS24:
490 			pc.cp++;
491 			tl = pop2();
492 			*(long *)popaddr() = tl;
493 			continue;
494 		case O_AS42:
495 			pc.cp++;
496 			tl = pop4();
497 			*(short *)popaddr() = tl;
498 			continue;
499 		case O_AS21:
500 			pc.cp++;
501 			tl = pop2();
502 			*popaddr() = tl;
503 			continue;
504 		case O_AS41:
505 			pc.cp++;
506 			tl = pop4();
507 			*popaddr() = tl;
508 			continue;
509 		case O_AS28:
510 			pc.cp++;
511 			tl = pop2();
512 			*(double *)popaddr() = tl;
513 			continue;
514 		case O_AS48:
515 			pc.cp++;
516 			tl = pop4();
517 			*(double *)popaddr() = tl;
518 			continue;
519 		case O_AS8:
520 			pc.cp++;
521 			t8 = popsze8();
522 			*(struct sze8 *)popaddr() = t8;
523 			continue;
524 		case O_AS:
525 			tl = *pc.cp++;
526 			if (tl == 0)
527 				tl = *pc.usp++;
528 			tl1 = (tl + 1) & ~1;
529 			tcp = pushsp((long)(0));
530 			blkcpy(tl, tcp, *(char **)(tcp + tl1));
531 			popsp(tl1 + sizeof(char *));
532 			continue;
533 		case O_INX2P2:
534 			tl = *pc.cp++;		/* tl has shift amount */
535 			tl1 = (pop2() - *pc.sp++) << tl;
536 			pushaddr(popaddr() + tl1);
537 			continue;
538 		case O_INX4P2:
539 			tl = *pc.cp++;		/* tl has shift amount */
540 			tl1 = (pop4() - *pc.sp++) << tl;
541 			pushaddr(popaddr() + tl1);
542 			continue;
543 		case O_INX2:
544 			tl = *pc.cp++;		/* tl has element size */
545 			if (tl == 0)
546 				tl = *pc.usp++;
547 			tl1 = pop2();		/* index */
548 			tl2 = *pc.sp++;
549 			pushaddr(popaddr() + (tl1 - tl2) * tl);
550 			tl = *pc.usp++;
551 			if (_runtst)
552 				SUBSC(tl1, tl2, tl); /* range check */
553 			continue;
554 		case O_INX4:
555 			tl = *pc.cp++;		/* tl has element size */
556 			if (tl == 0)
557 				tl = *pc.usp++;
558 			tl1 = pop4();		/* index */
559 			tl2 = *pc.sp++;
560 			pushaddr(popaddr() + (tl1 - tl2) * tl);
561 			tl = *pc.usp++;
562 			if (_runtst)
563 				SUBSC(tl1, tl2, tl); /* range check */
564 			continue;
565 		case O_OFF:
566 			tl = *pc.cp++;
567 			if (tl == 0)
568 				tl = *pc.usp++;
569 			pushaddr(popaddr() + tl);
570 			continue;
571 		case O_NIL:
572 			pc.cp++;
573 			NIL();
574 			continue;
575 		case O_ADD2:
576 			pc.cp++;
577 			push4((long)(pop2() + pop2()));
578 			continue;
579 		case O_ADD4:
580 			pc.cp++;
581 			push4(pop4() + pop4());
582 			continue;
583 		case O_ADD24:
584 			pc.cp++;
585 			tl = pop2();
586 			push4(pop4() + tl);
587 			continue;
588 		case O_ADD42:
589 			pc.cp++;
590 			tl = pop4();
591 			push4(pop2() + tl);
592 			continue;
593 		case O_ADD28:
594 			pc.cp++;
595 			tl = pop2();
596 			push8(pop8() + tl);
597 			continue;
598 		case O_ADD48:
599 			pc.cp++;
600 			tl = pop4();
601 			push8(pop8() + tl);
602 			continue;
603 		case O_ADD82:
604 			pc.cp++;
605 			td = pop8();
606 			push8(pop2() + td);
607 			continue;
608 		case O_ADD84:
609 			pc.cp++;
610 			td = pop8();
611 			push8(pop4() + td);
612 			continue;
613 		case O_SUB2:
614 			pc.cp++;
615 			tl = pop2();
616 			push4(pop2() - tl);
617 			continue;
618 		case O_SUB4:
619 			pc.cp++;
620 			tl = pop4();
621 			push4(pop4() - tl);
622 			continue;
623 		case O_SUB24:
624 			pc.cp++;
625 			tl = pop2();
626 			push4(pop4() - tl);
627 			continue;
628 		case O_SUB42:
629 			pc.cp++;
630 			tl = pop4();
631 			push4(pop2() - tl);
632 			continue;
633 		case O_SUB28:
634 			pc.cp++;
635 			tl = pop2();
636 			push8(pop8() - tl);
637 			continue;
638 		case O_SUB48:
639 			pc.cp++;
640 			tl = pop4();
641 			push8(pop8() - tl);
642 			continue;
643 		case O_SUB82:
644 			pc.cp++;
645 			td = pop8();
646 			push8(pop2() - td);
647 			continue;
648 		case O_SUB84:
649 			pc.cp++;
650 			td = pop8();
651 			push8(pop4() - td);
652 			continue;
653 		case O_MUL2:
654 			pc.cp++;
655 			push4((long)(pop2() * pop2()));
656 			continue;
657 		case O_MUL4:
658 			pc.cp++;
659 			push4(pop4() * pop4());
660 			continue;
661 		case O_MUL24:
662 			pc.cp++;
663 			tl = pop2();
664 			push4(pop4() * tl);
665 			continue;
666 		case O_MUL42:
667 			pc.cp++;
668 			tl = pop4();
669 			push4(pop2() * tl);
670 			continue;
671 		case O_MUL28:
672 			pc.cp++;
673 			tl = pop2();
674 			push8(pop8() * tl);
675 			continue;
676 		case O_MUL48:
677 			pc.cp++;
678 			tl = pop4();
679 			push8(pop8() * tl);
680 			continue;
681 		case O_MUL82:
682 			pc.cp++;
683 			td = pop8();
684 			push8(pop2() * td);
685 			continue;
686 		case O_MUL84:
687 			pc.cp++;
688 			td = pop8();
689 			push8(pop4() * td);
690 			continue;
691 		case O_ABS2:
692 		case O_ABS4:
693 			pc.cp++;
694 			tl = pop4();
695 			push4(tl >= 0 ? tl : -tl);
696 			continue;
697 		case O_ABS8:
698 			pc.cp++;
699 			td = pop8();
700 			push8(td >= 0.0 ? td : -td);
701 			continue;
702 		case O_NEG2:
703 			pc.cp++;
704 			push4((long)(-pop2()));
705 			continue;
706 		case O_NEG4:
707 			pc.cp++;
708 			push4(-pop4());
709 			continue;
710 		case O_NEG8:
711 			pc.cp++;
712 			push8(-pop8());
713 			continue;
714 		case O_DIV2:
715 			pc.cp++;
716 			tl = pop2();
717 			push4(pop2() / tl);
718 			continue;
719 		case O_DIV4:
720 			pc.cp++;
721 			tl = pop4();
722 			push4(pop4() / tl);
723 			continue;
724 		case O_DIV24:
725 			pc.cp++;
726 			tl = pop2();
727 			push4(pop4() / tl);
728 			continue;
729 		case O_DIV42:
730 			pc.cp++;
731 			tl = pop4();
732 			push4(pop2() / tl);
733 			continue;
734 		case O_MOD2:
735 			pc.cp++;
736 			tl = pop2();
737 			push4(pop2() % tl);
738 			continue;
739 		case O_MOD4:
740 			pc.cp++;
741 			tl = pop4();
742 			push4(pop4() % tl);
743 			continue;
744 		case O_MOD24:
745 			pc.cp++;
746 			tl = pop2();
747 			push4(pop4() % tl);
748 			continue;
749 		case O_MOD42:
750 			pc.cp++;
751 			tl = pop4();
752 			push4(pop2() % tl);
753 			continue;
754 		case O_ADD8:
755 			pc.cp++;
756 			push8(pop8() + pop8());
757 			continue;
758 		case O_SUB8:
759 			pc.cp++;
760 			td = pop8();
761 			push8(pop8() - td);
762 			continue;
763 		case O_MUL8:
764 			pc.cp++;
765 			push8(pop8() * pop8());
766 			continue;
767 		case O_DVD8:
768 			pc.cp++;
769 			td = pop8();
770 			push8(pop8() / td);
771 			continue;
772 		case O_STOI:
773 			pc.cp++;
774 			push4((long)(pop2()));
775 			continue;
776 		case O_STOD:
777 			pc.cp++;
778 			td = pop2();
779 			push8(td);
780 			continue;
781 		case O_ITOD:
782 			pc.cp++;
783 			td = pop4();
784 			push8(td);
785 			continue;
786 		case O_ITOS:
787 			pc.cp++;
788 			push2((short)(pop4()));
789 			continue;
790 		case O_DVD2:
791 			pc.cp++;
792 			td = pop2();
793 			push8(pop2() / td);
794 			continue;
795 		case O_DVD4:
796 			pc.cp++;
797 			td = pop4();
798 			push8(pop4() / td);
799 			continue;
800 		case O_DVD24:
801 			pc.cp++;
802 			td = pop2();
803 			push8(pop4() / td);
804 			continue;
805 		case O_DVD42:
806 			pc.cp++;
807 			td = pop4();
808 			push8(pop2() / td);
809 			continue;
810 		case O_DVD28:
811 			pc.cp++;
812 			td = pop2();
813 			push8(pop8() / td);
814 			continue;
815 		case O_DVD48:
816 			pc.cp++;
817 			td = pop4();
818 			push8(pop8() / td);
819 			continue;
820 		case O_DVD82:
821 			pc.cp++;
822 			td = pop8();
823 			push8(pop2() / td);
824 			continue;
825 		case O_DVD84:
826 			pc.cp++;
827 			td = pop8();
828 			push8(pop4() / td);
829 			continue;
830 		case O_RV1:
831 			tcp = _display.raw[*pc.ucp++];
832 			push2((short)(*(tcp + *pc.sp++)));
833 			continue;
834 		case O_RV14:
835 			tcp = _display.raw[*pc.ucp++];
836 			push4((long)(*(tcp + *pc.sp++)));
837 			continue;
838 		case O_RV2:
839 			tcp = _display.raw[*pc.ucp++];
840 			push2(*(short *)(tcp + *pc.sp++));
841 			continue;
842 		case O_RV24:
843 			tcp = _display.raw[*pc.ucp++];
844 			push4((long)(*(short *)(tcp + *pc.sp++)));
845 			continue;
846 		case O_RV4:
847 			tcp = _display.raw[*pc.ucp++];
848 			push4(*(long *)(tcp + *pc.sp++));
849 			continue;
850 		case O_RV8:
851 			tcp = _display.raw[*pc.ucp++];
852 			pushsze8(*(struct sze8 *)(tcp + *pc.sp++));
853 			continue;
854 		case O_RV:
855 			tcp = _display.raw[*pc.ucp++];
856 			tcp += *pc.sp++;
857 			tl = *pc.usp++;
858 			tcp1 = pushsp((tl + 1) & ~1);
859 			blkcpy(tl, tcp, tcp1);
860 			continue;
861 		case O_LV:
862 			tcp = _display.raw[*pc.ucp++];
863 			pushaddr(tcp + *pc.sp++);
864 			continue;
865 		case O_LRV1:
866 			tcp = _display.raw[*pc.ucp++];
867 			push2((short)(*(tcp + *pc.lp++)));
868 			continue;
869 		case O_LRV14:
870 			tcp = _display.raw[*pc.ucp++];
871 			push4((long)(*(tcp + *pc.lp++)));
872 			continue;
873 		case O_LRV2:
874 			tcp = _display.raw[*pc.ucp++];
875 			push2(*(short *)(tcp + *pc.lp++));
876 			continue;
877 		case O_LRV24:
878 			tcp = _display.raw[*pc.ucp++];
879 			push4((long)(*(short *)(tcp + *pc.lp++)));
880 			continue;
881 		case O_LRV4:
882 			tcp = _display.raw[*pc.ucp++];
883 			push4(*(long *)(tcp + *pc.lp++));
884 			continue;
885 		case O_LRV8:
886 			tcp = _display.raw[*pc.ucp++];
887 			pushsze8(*(struct sze8 *)(tcp + *pc.lp++));
888 			continue;
889 		case O_LRV:
890 			tcp = _display.raw[*pc.ucp++];
891 			tcp += (int)*pc.lp++;
892 			tl = *pc.usp++;
893 			tcp1 = pushsp((tl + 1) & ~1);
894 			blkcpy(tl, tcp, tcp1);
895 			continue;
896 		case O_LLV:
897 			tcp = _display.raw[*pc.ucp++];
898 			pushaddr(tcp + *pc.lp++);
899 			continue;
900 		case O_IND1:
901 			pc.cp++;
902 			push2((short)(*popaddr()));
903 			continue;
904 		case O_IND14:
905 			pc.cp++;
906 			push4((long)(*popaddr()));
907 			continue;
908 		case O_IND2:
909 			pc.cp++;
910 			push2(*(short *)(popaddr()));
911 			continue;
912 		case O_IND24:
913 			pc.cp++;
914 			push4((long)(*(short *)(popaddr())));
915 			continue;
916 		case O_IND4:
917 			pc.cp++;
918 			push4(*(long *)(popaddr()));
919 			continue;
920 		case O_IND8:
921 			pc.cp++;
922 			pushsze8(*(struct sze8 *)(popaddr()));
923 			continue;
924 		case O_IND:
925 			tl = *pc.cp++;
926 			if (tl == 0)
927 				tl = *pc.usp++;
928 			tcp = popaddr();
929 			tcp1 = pushsp((tl + 1) & ~1);
930 			blkcpy(tl, tcp, tcp1);
931 			continue;
932 		case O_CON1:
933 			push2((short)(*pc.cp++));
934 			continue;
935 		case O_CON14:
936 			push4((long)(*pc.cp++));
937 			continue;
938 		case O_CON2:
939 			pc.cp++;
940 			push2(*pc.sp++);
941 			continue;
942 		case O_CON24:
943 			pc.cp++;
944 			push4((long)(*pc.sp++));
945 			continue;
946 		case O_CON4:
947 			pc.cp++;
948 			push4(*pc.lp++);
949 			continue;
950 		case O_CON8:
951 			pc.cp++;
952 			push8(*pc.dbp++);
953 			continue;
954 		case O_CON:
955 			tl = *pc.cp++;
956 			if (tl == 0)
957 				tl = *pc.usp++;
958 			tl = (tl + 1) & ~1;
959 			tcp = pushsp(tl);
960 			blkcpy(tl, pc.cp, tcp);
961 			pc.cp += (int)tl;
962 			continue;
963 		case O_CONG:
964 			tl = *pc.cp++;
965 			if (tl == 0)
966 				tl = *pc.usp++;
967 			tl1 = (tl + 1) & ~1;
968 			tcp = pushsp(tl1);
969 			blkcpy(tl1, pc.cp, tcp);
970 			pc.cp += (int)((tl + 2) & ~1);
971 			continue;
972 		case O_LVCON:
973 			tl = *pc.cp++;
974 			if (tl == 0)
975 				tl = *pc.usp++;
976 			tl = (tl + 1) & ~1;
977 			pushaddr(pc.cp);
978 			pc.cp += (int)tl;
979 			continue;
980 		case O_RANG2:
981 			tl = *pc.cp++;
982 			if (tl == 0)
983 				tl = *pc.sp++;
984 			tl1 = pop2();
985 			push2((short)(RANG4(tl1, tl, *pc.sp++)));
986 			continue;
987 		case O_RANG42:
988 			tl = *pc.cp++;
989 			if (tl == 0)
990 				tl = *pc.sp++;
991 			tl1 = pop4();
992 			push4(RANG4(tl1, tl, *pc.sp++));
993 			continue;
994 		case O_RSNG2:
995 			tl = *pc.cp++;
996 			if (tl == 0)
997 				tl = *pc.sp++;
998 			tl1 = pop2();
999 			push2((short)(RSNG4(tl1, tl)));
1000 			continue;
1001 		case O_RSNG42:
1002 			tl = *pc.cp++;
1003 			if (tl == 0)
1004 				tl = *pc.sp++;
1005 			tl1 = pop4();
1006 			push4(RSNG4(tl1, tl));
1007 			continue;
1008 		case O_RANG4:
1009 			pc.cp++;
1010 			tl = *pc.lp++;
1011 			tl1 = pop4();
1012 			push4(RANG4(tl1, tl, *pc.lp++));
1013 			continue;
1014 		case O_RANG24:
1015 			pc.cp++;
1016 			tl = *pc.lp++;
1017 			tl1 = pop2();
1018 			push2((short)(RANG4(tl1, tl, *pc.lp++)));
1019 			continue;
1020 		case O_RSNG4:
1021 			pc.cp++;
1022 			tl = pop4();
1023 			push4(RSNG4(tl, *pc.lp++));
1024 			continue;
1025 		case O_RSNG24:
1026 			pc.cp++;
1027 			tl = pop2();
1028 			push2((short)(RSNG4(tl, *pc.lp++)));
1029 			continue;
1030 		case O_STLIM:
1031 			pc.cp++;
1032 			STLIM();
1033 			popsp((long)(sizeof(long)));
1034 			continue;
1035 		case O_LLIMIT:
1036 			pc.cp++;
1037 			LLIMIT();
1038 			popsp((long)(sizeof(char *)+sizeof(long)));
1039 			continue;
1040 		case O_BUFF:
1041 			BUFF((long)(*pc.cp++));
1042 			continue;
1043 		case O_HALT:
1044 			pc.cp++;
1045 			panic(PHALT);
1046 			continue;
1047 		case O_PXPBUF:
1048 			pc.cp++;
1049 			_cntrs = *pc.lp++;
1050 			_rtns = *pc.lp++;
1051 			NEWZ(&_pcpcount, (_cntrs + 1) * sizeof(long));
1052 			continue;
1053 		case O_COUNT:
1054 			pc.cp++;
1055 			_pcpcount[*pc.usp++]++;
1056 			continue;
1057 		case O_CASE1OP:
1058 			tl = *pc.cp++;		/* tl = number of cases */
1059 			if (tl == 0)
1060 				tl = *pc.usp++;
1061 			tsp = pc.sp + tl;	/* ptr to end of jump table */
1062 			tcp = (char *)tsp;	/* tcp = ptr to case values */
1063 			tl1 = pop2();		/* tl1 = element to find */
1064 			for(; tl > 0; tl--)	/* look for element */
1065 				if (tl1 == *tcp++)
1066 					break;
1067 			if (tl == 0)		/* default case => error */
1068 				ERROR("Label of %D not found in case\n", tl1);
1069 			pc.cp += *(tsp - tl);
1070 			continue;
1071 		case O_CASE2OP:
1072 			tl = *pc.cp++;		/* tl = number of cases */
1073 			if (tl == 0)
1074 				tl = *pc.usp++;
1075 			tsp = pc.sp + tl;	/* ptr to end of jump table */
1076 			tsp1 = tsp;		/* tsp1 = ptr to case values */
1077 			tl1 = (unsigned short)pop2();/* tl1 = element to find */
1078 			for(; tl > 0; tl--)	/* look for element */
1079 				if (tl1 == *tsp1++)
1080 					break;
1081 			if (tl == 0)		/* default case => error */
1082 				ERROR("Label of %D not found in case\n", tl1);
1083 			pc.cp += *(tsp - tl);
1084 			continue;
1085 		case O_CASE4OP:
1086 			tl = *pc.cp++;		/* tl = number of cases */
1087 			if (tl == 0)
1088 				tl = *pc.usp++;
1089 			tsp = pc.sp + tl;	/* ptr to end of jump table */
1090 			tlp = (long *)tsp;	/* tlp = ptr to case values */
1091 			tl1 = pop4();		/* tl1 = element to find */
1092 			for(; tl > 0; tl--)	/* look for element */
1093 				if (tl1 == *tlp++)
1094 					break;
1095 			if (tl == 0)		/* default case => error */
1096 				ERROR("Label of %D not found in case\n", tl1);
1097 			pc.cp += *(tsp - tl);
1098 			continue;
1099 		case O_ADDT:
1100 			tl = *pc.cp++;		/* tl has comparison length */
1101 			if (tl == 0)
1102 				tl = *pc.usp++;
1103 			tcp = pushsp((long)(0));/* tcp pts to first arg */
1104 			ADDT(tcp + tl, tcp + tl, tcp, tl >> 2);
1105 			popsp(tl);
1106 			continue;
1107 		case O_SUBT:
1108 			tl = *pc.cp++;		/* tl has comparison length */
1109 			if (tl == 0)
1110 				tl = *pc.usp++;
1111 			tcp = pushsp((long)(0));/* tcp pts to first arg */
1112 			SUBT(tcp + tl, tcp + tl, tcp, tl >> 2);
1113 			popsp(tl);
1114 			continue;
1115 		case O_MULT:
1116 			tl = *pc.cp++;		/* tl has comparison length */
1117 			if (tl == 0)
1118 				tl = *pc.usp++;
1119 			tcp = pushsp((long)(0));/* tcp pts to first arg */
1120 			MULT(tcp + tl, tcp + tl, tcp, tl >> 2);
1121 			popsp(tl);
1122 			continue;
1123 		case O_INCT:
1124 			tl = *pc.cp++;		/* tl has number of args */
1125 			if (tl == 0)
1126 				tl = *pc.usp++;
1127 			tb = INCT();
1128 			popsp(tl*sizeof(long));
1129 			push2((short)(tb));
1130 			continue;
1131 		case O_CTTOT:
1132 			tl = *pc.cp++;		/* tl has number of args */
1133 			if (tl == 0)
1134 				tl = *pc.usp++;
1135 			tl1 = tl * sizeof(long);
1136 			tcp = pushsp((long)(0)) + tl1; /* tcp pts to result */
1137 			CTTOT(tcp);
1138 			popsp(tl*sizeof(long));
1139 			continue;
1140 		case O_CARD:
1141 			tl = *pc.cp++;		/* tl has comparison length */
1142 			if (tl == 0)
1143 				tl = *pc.usp++;
1144 			tcp = pushsp((long)(0));/* tcp pts to set */
1145 			tl1 = CARD(tcp, tl);
1146 			popsp(tl);
1147 			push2((short)(tl1));
1148 			continue;
1149 		case O_IN:
1150 			tl = *pc.cp++;		/* tl has comparison length */
1151 			if (tl == 0)
1152 				tl = *pc.usp++;
1153 			tl1 = pop4();		/* tl1 is the element */
1154 			tcp = pushsp((long)(0));/* tcp pts to set */
1155 			tl2 = *pc.usp++;	/* lower bound */
1156 			tb = IN(tl1, tl2, (long)(*pc.usp++), tcp);
1157 			popsp(tl);
1158 			push2((short)(tb));
1159 			continue;
1160 		case O_ASRT:
1161 			pc.cp++;
1162 			ts = pop2();
1163 			ASRT(ts, "");
1164 			continue;
1165 		case O_FOR1U:
1166 			pc.cp++;
1167 			tcp = popaddr();	/* tcp = ptr to index var */
1168 			if (*tcp < pop4()) {	/* still going up */
1169 				tl = *tcp + 1;	/* inc index var */
1170 				tl1 = *pc.sp++;	/* index lower bound */
1171 				tl2 = *pc.sp++;	/* index upper bound */
1172 				if (_runtst)
1173 					RANG4(tl, tl1, tl2);
1174 				*tcp = tl;	/* update index var */
1175 				pc.cp += *pc.sp;/* return to top of loop */
1176 				continue;
1177 			}
1178 			pc.sp += 3;		/* else fall through */
1179 			continue;
1180 		case O_FOR2U:
1181 			pc.cp++;
1182 			tsp = (short *)popaddr(); /* tsp = ptr to index var */
1183 			if (*tsp < pop4()) {	/* still going up */
1184 				tl = *tsp + 1;	/* inc index var */
1185 				tl1 = *pc.sp++;	/* index lower bound */
1186 				tl2 = *pc.sp++;	/* index upper bound */
1187 				if (_runtst)
1188 					RANG4(tl, tl1, tl2);
1189 				*tsp = tl;	/* update index var */
1190 				pc.cp += *pc.sp;/* return to top of loop */
1191 				continue;
1192 			}
1193 			pc.sp += 3;		/* else fall through */
1194 			continue;
1195 		case O_FOR4U:
1196 			pc.cp++;
1197 			tlp = (long *)popaddr(); /* tlp = ptr to index var */
1198 			if (*tlp < pop4()) {	/* still going up */
1199 				tl = *tlp + 1;	/* inc index var */
1200 				tl1 = *pc.lp++;	/* index lower bound */
1201 				tl2 = *pc.lp++;	/* index upper bound */
1202 				if (_runtst)
1203 					RANG4(tl, tl1, tl2);
1204 				*tlp = tl;	/* update index var */
1205 				pc.cp += *pc.sp;/* return to top of loop */
1206 				continue;
1207 			}
1208 			pc.sp += 5;		/* else fall through */
1209 			continue;
1210 		case O_FOR1D:
1211 			pc.cp++;
1212 			tcp = popaddr();	/* tcp = ptr to index var */
1213 			if (*tcp > pop4()) {	/* still going down */
1214 				tl = *tcp - 1;	/* inc index var */
1215 				tl1 = *pc.sp++;	/* index lower bound */
1216 				tl2 = *pc.sp++;	/* index upper bound */
1217 				if (_runtst)
1218 					RANG4(tl, tl1, tl2);
1219 				*tcp = tl;	/* update index var */
1220 				pc.cp += *pc.sp;/* return to top of loop */
1221 				continue;
1222 			}
1223 			pc.sp += 3;		/* else fall through */
1224 			continue;
1225 		case O_FOR2D:
1226 			pc.cp++;
1227 			tsp = (short *)popaddr(); /* tsp = ptr to index var */
1228 			if (*tsp > pop4()) {	/* still going down */
1229 				tl = *tsp - 1;	/* inc index var */
1230 				tl1 = *pc.sp++;	/* index lower bound */
1231 				tl2 = *pc.sp++;	/* index upper bound */
1232 				if (_runtst)
1233 					RANG4(tl, tl1, tl2);
1234 				*tsp = tl;	/* update index var */
1235 				pc.cp += *pc.sp;/* return to top of loop */
1236 				continue;
1237 			}
1238 			pc.sp += 3;		/* else fall through */
1239 			continue;
1240 		case O_FOR4D:
1241 			pc.cp++;
1242 			tlp = (long *)popaddr(); /* tlp = ptr to index var */
1243 			if (*tlp > pop4()) {	/* still going down */
1244 				tl = *tlp - 1;	/* inc index var */
1245 				tl1 = *pc.lp++;	/* index lower bound */
1246 				tl2 = *pc.lp++;	/* index upper bound */
1247 				if (_runtst)
1248 					RANG4(tl, tl1, tl2);
1249 				*tlp = tl;	/* update index var */
1250 				pc.cp += *pc.sp;/* return to top of loop */
1251 				continue;
1252 			}
1253 			pc.sp += 5;		/* else fall through */
1254 			continue;
1255 		case O_READE:
1256 			pc.cp++;
1257 			push2((short)(READE(curfile, base + *pc.lp++)));
1258 			continue;
1259 		case O_READ4:
1260 			pc.cp++;
1261 			push4(READ4(curfile));
1262 			continue;
1263 		case O_READC:
1264 			pc.cp++;
1265 			push2((short)(READC(curfile)));
1266 			continue;
1267 		case O_READ8:
1268 			pc.cp++;
1269 			push8(READ8(curfile));
1270 			continue;
1271 		case O_READLN:
1272 			pc.cp++;
1273 			READLN(curfile);
1274 			continue;
1275 		case O_EOF:
1276 			pc.cp++;
1277 			push2((short)(TEOF(popaddr())));
1278 			continue;
1279 		case O_EOLN:
1280 			pc.cp++;
1281 			push2((short)(TEOLN(popaddr())));
1282 			continue;
1283 		case O_WRITEC:
1284 			if (_runtst) {
1285 				WRITEC(curfile);
1286 				popsp((long)(*pc.cp++));
1287 				continue;
1288 			}
1289 			fputc();
1290 			popsp((long)(*pc.cp++));
1291 			continue;
1292 		case O_WRITES:
1293 			if (_runtst) {
1294 				WRITES(curfile);
1295 				popsp((long)(*pc.cp++));
1296 				continue;
1297 			}
1298 			fwrite();
1299 			popsp((long)(*pc.cp++));
1300 			continue;
1301 		case O_WRITEF:
1302 			if (_runtst) {
1303 				WRITEF(curfile);
1304 				popsp((long)(*pc.cp++));
1305 				continue;
1306 			}
1307 			fprintf();
1308 			popsp((long)(*pc.cp++));
1309 			continue;
1310 		case O_WRITLN:
1311 			pc.cp++;
1312 			if (_runtst) {
1313 				WRITLN(curfile);
1314 				continue;
1315 			}
1316 			fputc('\n', ACTFILE(curfile));
1317 			continue;
1318 		case O_PAGE:
1319 			pc.cp++;
1320 			if (_runtst) {
1321 				PAGE(curfile);
1322 				continue;
1323 			}
1324 			fputc('', ACTFILE(curfile));
1325 			continue;
1326 		case O_NAM:
1327 			pc.cp++;
1328 			tl = pop4();
1329 			pushaddr(NAM(tl, base + *pc.lp++));
1330 			continue;
1331 		case O_MAX:
1332 			tl = *pc.cp++;
1333 			if (tl == 0)
1334 				tl = *pc.usp++;
1335 			tl1 = pop4();
1336 			if (_runtst) {
1337 				push4(MAX(tl1, tl, (long)(*pc.usp++)));
1338 				continue;
1339 			}
1340 			tl1 -= tl;
1341 			tl = *pc.usp++;
1342 			push4(tl1 > tl ? tl1 : tl);
1343 			continue;
1344 		case O_MIN:
1345 			tl = *pc.cp++;
1346 			if (tl == 0)
1347 				tl = *pc.usp++;
1348 			tl1 = pop4();
1349 			push4(tl1 < tl ? tl1 : tl);
1350 			continue;
1351 		case O_UNIT:
1352 			pc.cp++;
1353 			curfile = UNIT(popaddr());
1354 			continue;
1355 		case O_UNITINP:
1356 			pc.cp++;
1357 			curfile = INPUT;
1358 			continue;
1359 		case O_UNITOUT:
1360 			pc.cp++;
1361 			curfile = OUTPUT;
1362 			continue;
1363 		case O_MESSAGE:
1364 			pc.cp++;
1365 			PFLUSH();
1366 			curfile = ERR;
1367 			continue;
1368 		case O_PUT:
1369 			pc.cp++;
1370 			PUT(curfile);
1371 			continue;
1372 		case O_GET:
1373 			pc.cp++;
1374 			GET(curfile);
1375 			continue;
1376 		case O_FNIL:
1377 			pc.cp++;
1378 			pushaddr(FNIL(popaddr()));
1379 			continue;
1380 		case O_DEFNAME:
1381 			pc.cp++;
1382 			DEFNAME();
1383 			popsp((long)(2*sizeof(char *)+2*sizeof(long)));
1384 			continue;
1385 		case O_RESET:
1386 			pc.cp++;
1387 			RESET();
1388 			popsp((long)(2*sizeof(char *)+2*sizeof(long)));
1389 			continue;
1390 		case O_REWRITE:
1391 			pc.cp++;
1392 			REWRITE();
1393 			popsp((long)(2*sizeof(char *)+2*sizeof(long)));
1394 			continue;
1395 		case O_FILE:
1396 			pc.cp++;
1397 			pushaddr(ACTFILE(curfile));
1398 			continue;
1399 		case O_REMOVE:
1400 			pc.cp++;
1401 			REMOVE();
1402 			popsp((long)(sizeof(char *)+sizeof(long)));
1403 			continue;
1404 		case O_FLUSH:
1405 			pc.cp++;
1406 			FLUSH();
1407 			popsp((long)(sizeof(char *)));
1408 			continue;
1409 		case O_PACK:
1410 			pc.cp++;
1411 			PACK();
1412 			popsp((long)(5*sizeof(long)+2*sizeof(char*)));
1413 			continue;
1414 		case O_UNPACK:
1415 			pc.cp++;
1416 			UNPACK();
1417 			popsp((long)(5*sizeof(long)+2*sizeof(char*)));
1418 			continue;
1419 		case O_ARGC:
1420 			pc.cp++;
1421 			push4((long)_argc);
1422 			continue;
1423 		case O_ARGV:
1424 			tl = *pc.cp++;		/* tl = size of char array */
1425 			if (tl == 0)
1426 				tl = *pc.usp++;
1427 			tcp = popaddr();	/* tcp = addr of char array */
1428 			tl1 = pop4();		/* tl1 = argv subscript */
1429 			ARGV(tl1, tcp, tl);
1430 			continue;
1431 		case O_CLCK:
1432 			pc.cp++;
1433 			push4(CLCK());
1434 			continue;
1435 		case O_WCLCK:
1436 			pc.cp++;
1437 			push4(time(0));
1438 			continue;
1439 		case O_SCLCK:
1440 			pc.cp++;
1441 			push4(SCLCK());
1442 			continue;
1443 		case O_DISPOSE:
1444 			tl = *pc.cp++;		/* tl = size being disposed */
1445 			if (tl == 0)
1446 				tl = *pc.usp++;
1447 			tcp = popaddr();	/* ptr to ptr being disposed */
1448 			DISPOSE(tcp, tl);
1449 			*(char **)tcp = (char *)0;
1450 			continue;
1451 		case O_NEW:
1452 			tl = *pc.cp++;		/* tl = size being new'ed */
1453 			if (tl == 0)
1454 				tl = *pc.usp++;
1455 			tcp = popaddr();	/* ptr to ptr being new'ed */
1456 			if (_runtst) {
1457 				NEWZ(tcp, tl);
1458 				continue;
1459 			}
1460 			NEW(tcp, tl);
1461 			continue;
1462 		case O_DATE:
1463 			pc.cp++;
1464 			DATE(popaddr());
1465 			continue;
1466 		case O_TIME:
1467 			pc.cp++;
1468 			TIME(popaddr());
1469 			continue;
1470 		case O_UNDEF:
1471 			pc.cp++;
1472 			pop8();
1473 			push2((short)(0));
1474 			continue;
1475 		case O_ATAN:
1476 			pc.cp++;
1477 			push8(atan(pop8()));
1478 			continue;
1479 		case O_COS:
1480 			pc.cp++;
1481 			push8(cos(pop8()));
1482 			continue;
1483 		case O_EXP:
1484 			pc.cp++;
1485 			push8(exp(pop8()));
1486 			continue;
1487 		case O_LN:
1488 			pc.cp++;
1489 			if (_runtst) {
1490 				push8(LN(pop8()));
1491 				continue;
1492 			}
1493 			push8(log(pop8()));
1494 			continue;
1495 		case O_SIN:
1496 			pc.cp++;
1497 			push8(sin(pop8()));
1498 			continue;
1499 		case O_SQRT:
1500 			pc.cp++;
1501 			if (_runtst) {
1502 				push8(SQRT(pop8()));
1503 				continue;
1504 			}
1505 			push8(sqrt(pop8()));
1506 			continue;
1507 		case O_CHR2:
1508 		case O_CHR4:
1509 			pc.cp++;
1510 			if (_runtst) {
1511 				push2((short)(CHR(pop4())));
1512 				continue;
1513 			}
1514 			push2((short)(pop4()));
1515 			continue;
1516 		case O_ODD2:
1517 		case O_ODD4:
1518 			pc.cp++;
1519 			push2((short)(pop4() & 1));
1520 			continue;
1521 		case O_SUCC2:
1522 			tl = *pc.cp++;
1523 			if (tl == 0)
1524 				tl = *pc.sp++;
1525 			tl1 = pop4();
1526 			if (_runtst) {
1527 				push2((short)(SUCC(tl1, tl, (long)(*pc.sp++))));
1528 				continue;
1529 			}
1530 			push2((short)(tl1 + 1));
1531 			pc.sp++;
1532 			continue;
1533 		case O_SUCC24:
1534 			tl = *pc.cp++;
1535 			if (tl == 0)
1536 				tl = *pc.sp++;
1537 			tl1 = pop4();
1538 			if (_runtst) {
1539 				push4(SUCC(tl1, tl, (long)(*pc.sp++)));
1540 				continue;
1541 			}
1542 			push4(tl1 + 1);
1543 			pc.sp++;
1544 			continue;
1545 		case O_SUCC4:
1546 			tl = *pc.cp++;
1547 			if (tl == 0)
1548 				tl = *pc.lp++;
1549 			tl1 = pop4();
1550 			if (_runtst) {
1551 				push4(SUCC(tl1, tl, (long)(*pc.lp++)));
1552 				continue;
1553 			}
1554 			push4(tl1 + 1);
1555 			pc.lp++;
1556 			continue;
1557 		case O_PRED2:
1558 			tl = *pc.cp++;
1559 			if (tl == 0)
1560 				tl = *pc.sp++;
1561 			tl1 = pop4();
1562 			if (_runtst) {
1563 				push2((short)(PRED(tl1, tl, (long)(*pc.sp++))));
1564 				continue;
1565 			}
1566 			push2((short)(tl1 - 1));
1567 			pc.sp++;
1568 			continue;
1569 		case O_PRED24:
1570 			tl = *pc.cp++;
1571 			if (tl == 0)
1572 				tl = *pc.sp++;
1573 			tl1 = pop4();
1574 			if (_runtst) {
1575 				push4(PRED(tl1, tl, (long)(*pc.sp++)));
1576 				continue;
1577 			}
1578 			push4(tl1 - 1);
1579 			pc.sp++;
1580 			continue;
1581 		case O_PRED4:
1582 			tl = *pc.cp++;
1583 			if (tl == 0)
1584 				tl = *pc.lp++;
1585 			tl1 = pop4();
1586 			if (_runtst) {
1587 				push4(PRED(tl1, tl, (long)(*pc.lp++)));
1588 				continue;
1589 			}
1590 			push4(tl1 - 1);
1591 			pc.lp++;
1592 			continue;
1593 		case O_SEED:
1594 			pc.cp++;
1595 			push4(SEED(pop4()));
1596 			continue;
1597 		case O_RANDOM:
1598 			pc.cp++;
1599 			push8(RANDOM(pop8()));
1600 			continue;
1601 		case O_EXPO:
1602 			pc.cp++;
1603 			push4(EXPO(pop8()));
1604 			continue;
1605 		case O_SQR2:
1606 		case O_SQR4:
1607 			pc.cp++;
1608 			tl = pop4();
1609 			push4(tl * tl);
1610 			continue;
1611 		case O_SQR8:
1612 			pc.cp++;
1613 			td = pop8();
1614 			push8(td * td);
1615 			continue;
1616 		case O_ROUND:
1617 			pc.cp++;
1618 			push4(ROUND(pop8()));
1619 			continue;
1620 		case O_TRUNC:
1621 			pc.cp++;
1622 			push4(TRUNC(pop8()));
1623 			continue;
1624 		default:
1625 			panic(PBADOP);
1626 			continue;
1627 		}
1628 	}
1629 }
1630