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