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