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