home *** CD-ROM | disk | FTP | other *** search
- /*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
- #ifndef lint
- static char sccsid[] = "@(#)interp.c 5.8 (Berkeley) 4/16/91";
- #endif /* not lint */
-
- #include <math.h>
- #include <signal.h>
- #include "whoami.h"
- #include "vars.h"
- #include "objfmt.h"
- #include "h02opcs.h"
- #include "machdep.h"
- #include "libpc.h"
-
- /*
- * program variables
- */
- union display _display;
- struct dispsave *_dp;
- long _lino = 0;
- int _argc;
- char **_argv;
- long _mode;
- long _runtst = (long)TRUE;
- bool _nodump = FALSE;
- long _stlim = 500000;
- long _stcnt = 0;
- long _seed = 1;
- #ifdef ADDR32
- char *_minptr = (char *)0x7fffffff;
- #endif ADDR32
- #ifdef ADDR16
- char *_minptr = (char *)0xffff;
- #endif ADDR16
- char *_maxptr = (char *)0;
- long *_pcpcount = (long *)0;
- long _cntrs = 0;
- long _rtns = 0;
-
- /*
- * standard files
- */
- char _inwin, _outwin, _errwin;
- struct iorechd _err = {
- &_errwin, /* fileptr */
- 0, /* lcount */
- 0x7fffffff, /* llimit */
- stderr, /* fbuf */
- FILNIL, /* fchain */
- STDLVL, /* flev */
- "Message file", /* pfname */
- FTEXT | FWRITE | EOFF, /* funit */
- 2, /* fblk */
- 1 /* fsize */
- };
- struct iorechd output = {
- &_outwin, /* fileptr */
- 0, /* lcount */
- 0x7fffffff, /* llimit */
- stdout, /* fbuf */
- ERR, /* fchain */
- STDLVL, /* flev */
- "standard output", /* pfname */
- FTEXT | FWRITE | EOFF, /* funit */
- 1, /* fblk */
- 1 /* fsize */
- };
- struct iorechd input = {
- &_inwin, /* fileptr */
- 0, /* lcount */
- 0x7fffffff, /* llimit */
- stdin, /* fbuf */
- OUTPUT, /* fchain */
- STDLVL, /* flev */
- "standard input", /* pfname */
- FTEXT|FREAD|SYNC|EOLN, /* funit */
- 0, /* fblk */
- 1 /* fsize */
- };
-
- /*
- * file record variables
- */
- long _filefre = PREDEF;
- struct iorechd _fchain = {
- 0, 0, 0, 0, /* only use fchain field */
- INPUT /* fchain */
- };
- struct iorec *_actfile[MAXFILES] = {
- INPUT,
- OUTPUT,
- ERR
- };
-
- /*
- * stuff for pdx to watch what the interpreter is doing.
- * The .globl is #ifndef DBX since it breaks DBX to have a global
- * asm label in the middle of a function (see _loopaddr: below).
- */
-
- union progcntr pdx_pc;
- #ifndef DBX
- asm(".globl _loopaddr");
- #endif DBX
-
- /*
- * Px profile array
- */
- #ifdef PROFILE
- long _profcnts[NUMOPS];
- #endif PROFILE
-
- /*
- * debugging variables
- */
- #ifdef PXDEBUG
- char opc[10];
- long opcptr = 9;
- #endif PXDEBUG
-
- void
- interpreter(base)
- char *base;
- {
- /* register */ union progcntr pc; /* interpreted program cntr */
- struct iorec *curfile; /* active file */
- register struct blockmark *stp; /* active stack frame ptr */
- /*
- * the following variables are used as scratch
- */
- register char *tcp;
- register short *tsp;
- register long tl, tl1, tl2, tl3;
- char *tcp2;
- long tl4;
- double td, td1;
- struct sze8 t8;
- register short *tsp1;
- long *tlp;
- char *tcp1;
- bool tb;
- struct blockmark *tstp;
- register struct formalrtn *tfp;
- struct iorec **ip;
- int mypid;
- int ti, ti2;
- short ts;
- FILE *tf;
- /* register */ union progcntr stack; /* Interpreted stack */
-
- mypid = getpid();
-
- /*
- * Setup sets up any hardware specific parameters before
- * starting the interpreter. Typically this is macro- or inline-
- * replaced by "machdep.h" or interp.sed.
- */
- setup();
- /*
- * necessary only on systems which do not initialize
- * memory to zero
- */
- for (ip = &_actfile[3]; ip < &_actfile[MAXFILES]; *ip++ = FILNIL)
- /* void */;
- /*
- * set up global environment, then ``call'' the main program
- */
- STACKALIGN(tl, 2 * sizeof(struct iorec *));
- _display.frame[0].locvars = pushsp(tl);
- _display.frame[0].locvars += 2 * sizeof(struct iorec *);
- *(struct iorec **)(_display.frame[0].locvars + OUTPUT_OFF) = OUTPUT;
- *(struct iorec **)(_display.frame[0].locvars + INPUT_OFF) = INPUT;
- STACKALIGN(tl, sizeof(struct blockmark));
- stp = (struct blockmark *)pushsp(tl);
- _dp = &_display.frame[0];
- pc.cp = base;
-
- for(;;) {
- # ifdef PXDEBUG
- if (++opcptr == 10)
- opcptr = 0;
- opc[opcptr] = *pc.ucp;
- # endif PXDEBUG
- # ifdef PROFILE
- _profcnts[*pc.ucp]++;
- # endif PROFILE
-
- /*
- * Save away the program counter to a fixed location for pdx.
- */
- pdx_pc = pc;
-
- /*
- * Having the label below makes dbx not work
- * to debug this interpreter,
- * since it thinks a new function called loopaddr()
- * has started here, and it won't display the local
- * variables of interpreter(). You have to compile
- * -DDBX to avoid this problem...
- */
- # ifndef DBX
- ;asm("_loopaddr:");
- # endif DBX
-
- switch (*pc.ucp++) {
- case O_BPT: /* breakpoint trap */
- PFLUSH();
- kill(mypid, SIGILL);
- pc.ucp--;
- continue;
- case O_NODUMP:
- _nodump = TRUE;
- /* and fall through */
- case O_BEG:
- _dp += 1; /* enter local scope */
- stp->odisp = *_dp; /* save old display value */
- tl = *pc.ucp++; /* tl = name size */
- stp->entry = pc.hdrp; /* pointer to entry info */
- tl1 = pc.hdrp->framesze;/* tl1 = size of frame */
- _lino = pc.hdrp->offset;
- _runtst = pc.hdrp->tests;
- disableovrflo();
- if (_runtst)
- enableovrflo();
- pc.cp += (int)tl; /* skip over proc hdr info */
- stp->file = curfile; /* save active file */
- STACKALIGN(tl2, tl1);
- tcp = pushsp(tl2); /* tcp = new top of stack */
- if (_runtst) /* zero stack frame */
- blkclr(tcp, tl1);
- tcp += (int)tl1; /* offsets of locals are neg */
- _dp->locvars = tcp; /* set new display pointer */
- _dp->stp = stp;
- stp->tos = pushsp((long)0); /* set tos pointer */
- continue;
- case O_END:
- PCLOSE(_dp->locvars); /* flush & close local files */
- stp = _dp->stp;
- curfile = stp->file; /* restore old active file */
- *_dp = stp->odisp; /* restore old display entry */
- if (_dp == &_display.frame[1])
- return; /* exiting main proc ??? */
- _lino = stp->lino; /* restore lino, pc, dp */
- pc.cp = stp->pc;
- _dp = stp->dp;
- _runtst = stp->entry->tests;
- disableovrflo();
- if (_runtst)
- enableovrflo();
- STACKALIGN(tl, stp->entry->framesze);
- STACKALIGN(tl1, sizeof(struct blockmark));
- popsp(tl + /* pop local vars */
- tl1 + /* pop stack frame */
- stp->entry->nargs);/* pop parms */
- continue;
- case O_CALL:
- tl = *pc.cp++;
- PCLONGVAL(tl1);
- tcp = base + tl1 + sizeof(short);/* new entry point */
- GETLONGVAL(tl1, tcp);
- tcp = base + tl1;
- STACKALIGN(tl1, sizeof(struct blockmark));
- stp = (struct blockmark *)pushsp(tl1);
- stp->lino = _lino; /* save lino, pc, dp */
- stp->pc = pc.cp;
- stp->dp = _dp;
- _dp = &_display.frame[tl]; /* set up new display ptr */
- pc.cp = tcp;
- continue;
- case O_FCALL:
- pc.cp++;
- tcp = popaddr(); /* ptr to display save area */
- tfp = (struct formalrtn *)popaddr();
- STACKALIGN(tl, sizeof(struct blockmark));
- stp = (struct blockmark *)pushsp(tl);
- stp->lino = _lino; /* save lino, pc, dp */
- stp->pc = pc.cp;
- stp->dp = _dp;
- pc.cp = (char *)(tfp->fentryaddr);/* new entry point */
- _dp = &_display.frame[tfp->fbn];/* new display ptr */
- blkcpy(&_display.frame[1], tcp,
- tfp->fbn * sizeof(struct dispsave));
- blkcpy(&tfp->fdisp[0], &_display.frame[1],
- tfp->fbn * sizeof(struct dispsave));
- continue;
- case O_FRTN:
- tl = *pc.cp++; /* tl = size of return obj */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = pushsp((long)(0));
- tfp = *(struct formalrtn **)(tcp + tl);
- tcp1 = *(char **)
- (tcp + tl + sizeof(struct formalrtn *));
- if (tl != 0) {
- blkcpy(tcp, tcp + sizeof(struct formalrtn *)
- + sizeof(char *), tl);
- }
- STACKALIGN(tl,
- sizeof(struct formalrtn *) + sizeof (char *));
- popsp(tl);
- blkcpy(tcp1, &_display.frame[1],
- tfp->fbn * sizeof(struct dispsave));
- continue;
- case O_FSAV:
- tfp = (struct formalrtn *)popaddr();
- tfp->fbn = *pc.cp++; /* blk number of routine */
- PCLONGVAL(tl);
- tcp = base + tl + sizeof(short);/* new entry point */
- GETLONGVAL(tl, tcp);
- tfp->fentryaddr = (long (*)())(base + tl);
- blkcpy(&_display.frame[1], &tfp->fdisp[0],
- tfp->fbn * sizeof(struct dispsave));
- pushaddr(tfp);
- continue;
- case O_SDUP2:
- pc.cp++;
- tl = pop2();
- push2((short)(tl));
- push2((short)(tl));
- continue;
- case O_SDUP4:
- pc.cp++;
- tl = pop4();
- push4(tl);
- push4(tl);
- continue;
- case O_TRA:
- pc.cp++;
- pc.cp += *pc.sp;
- continue;
- case O_TRA4:
- pc.cp++;
- PCLONGVAL(tl);
- pc.cp = base + tl;
- continue;
- case O_GOTO:
- tstp = _display.frame[*pc.cp++].stp; /* ptr to
- exit frame */
- PCLONGVAL(tl);
- pc.cp = base + tl;
- stp = _dp->stp;
- while (tstp != stp) {
- if (_dp == &_display.frame[1])
- ERROR("Active frame not found in non-local goto\n", 0); /* exiting prog ??? */
- PCLOSE(_dp->locvars); /* close local files */
- curfile = stp->file; /* restore active file */
- *_dp = stp->odisp; /* old display entry */
- _dp = stp->dp; /* restore dp */
- stp = _dp->stp;
- }
- /* pop locals, stack frame, parms, and return values */
- popsp((long)(stp->tos - pushsp((long)(0))));
- continue;
- case O_LINO:
- if (_dp->stp->tos != pushsp((long)(0)))
- ERROR("Panic: stack not empty between statements\n");
- _lino = *pc.cp++; /* set line number */
- if (_lino == 0)
- _lino = *pc.sp++;
- if (_runtst) {
- LINO(); /* inc statement count */
- continue;
- }
- _stcnt++;
- continue;
- case O_PUSH:
- tl = *pc.cp++;
- if (tl == 0)
- PCLONGVAL(tl);
- STACKALIGN(tl1, -tl);
- tcp = pushsp(tl1);
- if (_runtst)
- blkclr(tcp, tl1);
- continue;
- case O_IF:
- pc.cp++;
- if (pop2()) {
- pc.sp++;
- continue;
- }
- pc.cp += *pc.sp;
- continue;
- case O_REL2:
- tl = pop2();
- tl1 = pop2();
- goto cmplong;
- case O_REL24:
- tl = pop2();
- tl1 = pop4();
- goto cmplong;
- case O_REL42:
- tl = pop4();
- tl1 = pop2();
- goto cmplong;
- case O_REL4:
- tl = pop4();
- tl1 = pop4();
- cmplong:
- switch (*pc.cp++) {
- case releq:
- push2(tl1 == tl);
- continue;
- case relne:
- push2(tl1 != tl);
- continue;
- case rellt:
- push2(tl1 < tl);
- continue;
- case relgt:
- push2(tl1 > tl);
- continue;
- case relle:
- push2(tl1 <= tl);
- continue;
- case relge:
- push2(tl1 >= tl);
- continue;
- default:
- ERROR("Panic: bad relation %d to REL4*\n",
- *(pc.cp - 1));
- continue;
- }
- case O_RELG:
- tl2 = *pc.cp++; /* tc has jump opcode */
- tl = *pc.usp++; /* tl has comparison length */
- STACKALIGN(tl1, tl); /* tl1 has arg stack length */
- tcp = pushsp((long)(0));/* tcp pts to first arg */
- switch (tl2) {
- case releq:
- tb = RELEQ(tl, tcp + tl1, tcp);
- break;
- case relne:
- tb = RELNE(tl, tcp + tl1, tcp);
- break;
- case rellt:
- tb = RELSLT(tl, tcp + tl1, tcp);
- break;
- case relgt:
- tb = RELSGT(tl, tcp + tl1, tcp);
- break;
- case relle:
- tb = RELSLE(tl, tcp + tl1, tcp);
- break;
- case relge:
- tb = RELSGE(tl, tcp + tl1, tcp);
- break;
- default:
- ERROR("Panic: bad relation %d to RELG*\n", tl2);
- break;
- }
- popsp(tl1 << 1);
- push2((short)(tb));
- continue;
- case O_RELT:
- tl2 = *pc.cp++; /* tc has jump opcode */
- tl1 = *pc.usp++; /* tl1 has comparison length */
- tcp = pushsp((long)(0));/* tcp pts to first arg */
- switch (tl2) {
- case releq:
- tb = RELEQ(tl1, tcp + tl1, tcp);
- break;
- case relne:
- tb = RELNE(tl1, tcp + tl1, tcp);
- break;
- case rellt:
- tb = RELTLT(tl1, tcp + tl1, tcp);
- break;
- case relgt:
- tb = RELTGT(tl1, tcp + tl1, tcp);
- break;
- case relle:
- tb = RELTLE(tl1, tcp + tl1, tcp);
- break;
- case relge:
- tb = RELTGE(tl1, tcp + tl1, tcp);
- break;
- default:
- ERROR("Panic: bad relation %d to RELT*\n", tl2);
- break;
- }
- STACKALIGN(tl, tl1);
- popsp(tl << 1);
- push2((short)(tb));
- continue;
- case O_REL28:
- td = pop2();
- td1 = pop8();
- goto cmpdbl;
- case O_REL48:
- td = pop4();
- td1 = pop8();
- goto cmpdbl;
- case O_REL82:
- td = pop8();
- td1 = pop2();
- goto cmpdbl;
- case O_REL84:
- td = pop8();
- td1 = pop4();
- goto cmpdbl;
- case O_REL8:
- td = pop8();
- td1 = pop8();
- cmpdbl:
- switch (*pc.cp++) {
- case releq:
- push2(td1 == td);
- continue;
- case relne:
- push2(td1 != td);
- continue;
- case rellt:
- push2(td1 < td);
- continue;
- case relgt:
- push2(td1 > td);
- continue;
- case relle:
- push2(td1 <= td);
- continue;
- case relge:
- push2(td1 >= td);
- continue;
- default:
- ERROR("Panic: bad relation %d to REL8*\n",
- *(pc.cp - 1));
- continue;
- }
- case O_AND:
- pc.cp++;
- tl = pop2();
- tl1 = pop2();
- push2(tl1 & tl);
- continue;
- case O_OR:
- pc.cp++;
- tl = pop2();
- tl1 = pop2();
- push2(tl1 | tl);
- continue;
- case O_NOT:
- pc.cp++;
- tl = pop2();
- push2(tl ^ 1);
- continue;
- case O_AS2:
- pc.cp++;
- tl = pop2();
- *(short *)popaddr() = tl;
- continue;
- case O_AS4:
- pc.cp++;
- tl = pop4();
- *(long *)popaddr() = tl;
- continue;
- case O_AS24:
- pc.cp++;
- tl = pop2();
- *(long *)popaddr() = tl;
- continue;
- case O_AS42:
- pc.cp++;
- tl = pop4();
- *(short *)popaddr() = tl;
- continue;
- case O_AS21:
- pc.cp++;
- tl = pop2();
- *popaddr() = tl;
- continue;
- case O_AS41:
- pc.cp++;
- tl = pop4();
- *popaddr() = tl;
- continue;
- case O_AS28:
- pc.cp++;
- tl = pop2();
- *(double *)popaddr() = tl;
- continue;
- case O_AS48:
- pc.cp++;
- tl = pop4();
- *(double *)popaddr() = tl;
- continue;
- case O_AS8:
- pc.cp++;
- t8 = popsze8();
- *(struct sze8 *)popaddr() = t8;
- continue;
- case O_AS:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- STACKALIGN(tl1, tl);
- tcp = pushsp((long)(0));
- blkcpy(tcp, *(char **)(tcp + tl1), tl);
- popsp(tl1 + sizeof(char *));
- continue;
- case O_VAS:
- pc.cp++;
- tl = pop4();
- tcp1 = popaddr();
- tcp = popaddr();
- blkcpy(tcp1, tcp, tl);
- continue;
- case O_INX2P2:
- tl = *pc.cp++; /* tl has shift amount */
- tl1 = pop2();
- tl1 = (tl1 - *pc.sp++) << tl;
- tcp = popaddr();
- pushaddr(tcp + tl1);
- continue;
- case O_INX4P2:
- tl = *pc.cp++; /* tl has shift amount */
- tl1 = pop4();
- tl1 = (tl1 - *pc.sp++) << tl;
- tcp = popaddr();
- pushaddr(tcp + tl1);
- continue;
- case O_INX2:
- tl = *pc.cp++; /* tl has element size */
- if (tl == 0)
- tl = *pc.usp++;
- tl1 = pop2(); /* index */
- tl2 = *pc.sp++;
- tcp = popaddr();
- pushaddr(tcp + (tl1 - tl2) * tl);
- tl = *pc.usp++;
- if (_runtst)
- SUBSC(tl1, tl2, tl); /* range check */
- continue;
- case O_INX4:
- tl = *pc.cp++; /* tl has element size */
- if (tl == 0)
- tl = *pc.usp++;
- tl1 = pop4(); /* index */
- tl2 = *pc.sp++;
- tcp = popaddr();
- pushaddr(tcp + (tl1 - tl2) * tl);
- tl = *pc.usp++;
- if (_runtst)
- SUBSC(tl1, tl2, tl); /* range check */
- continue;
- case O_VINX2:
- pc.cp++;
- tl = pop2(); /* tl has element size */
- tl1 = pop2(); /* upper bound */
- tl2 = pop2(); /* lower bound */
- tl3 = pop2(); /* index */
- tcp = popaddr();
- pushaddr(tcp + (tl3 - tl2) * tl);
- if (_runtst)
- SUBSC(tl3, tl2, tl1); /* range check */
- continue;
- case O_VINX24:
- pc.cp++;
- tl = pop2(); /* tl has element size */
- tl1 = pop2(); /* upper bound */
- tl2 = pop2(); /* lower bound */
- tl3 = pop4(); /* index */
- tcp = popaddr();
- pushaddr(tcp + (tl3 - tl2) * tl);
- if (_runtst)
- SUBSC(tl3, tl2, tl1); /* range check */
- continue;
- case O_VINX42:
- pc.cp++;
- tl = pop4(); /* tl has element size */
- tl1 = pop4(); /* upper bound */
- tl2 = pop4(); /* lower bound */
- tl3 = pop2(); /* index */
- tcp = popaddr();
- pushaddr(tcp + (tl3 - tl2) * tl);
- if (_runtst)
- SUBSC(tl3, tl2, tl1); /* range check */
- continue;
- case O_VINX4:
- pc.cp++;
- tl = pop4(); /* tl has element size */
- tl1 = pop4(); /* upper bound */
- tl2 = pop4(); /* lower bound */
- tl3 = pop4(); /* index */
- tcp = popaddr();
- pushaddr(tcp + (tl3 - tl2) * tl);
- if (_runtst)
- SUBSC(tl3, tl2, tl1); /* range check */
- continue;
- case O_OFF:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- tcp = popaddr();
- pushaddr(tcp + tl);
- continue;
- case O_NIL:
- pc.cp++;
- tcp = popaddr();
- NIL(tcp);
- pushaddr(tcp);
- continue;
- case O_ADD2:
- pc.cp++;
- tl = pop2();
- tl1 = pop2();
- push4(tl1 + tl);
- continue;
- case O_ADD4:
- pc.cp++;
- tl = pop4();
- tl1 = pop4();
- push4(tl1 + tl);
- continue;
- case O_ADD24:
- pc.cp++;
- tl = pop2();
- tl1 = pop4();
- push4(tl1 + tl);
- continue;
- case O_ADD42:
- pc.cp++;
- tl = pop4();
- tl1 = pop2();
- push4(tl1 + tl);
- continue;
- case O_ADD28:
- pc.cp++;
- tl = pop2();
- td = pop8();
- push8(td + tl);
- continue;
- case O_ADD48:
- pc.cp++;
- tl = pop4();
- td = pop8();
- push8(td + tl);
- continue;
- case O_ADD82:
- pc.cp++;
- td = pop8();
- td1 = pop2();
- push8(td1 + td);
- continue;
- case O_ADD84:
- pc.cp++;
- td = pop8();
- td1 = pop4();
- push8(td1 + td);
- continue;
- case O_SUB2:
- pc.cp++;
- tl = pop2();
- tl1 = pop2();
- push4(tl1 - tl);
- continue;
- case O_SUB4:
- pc.cp++;
- tl = pop4();
- tl1 = pop4();
- push4(tl1 - tl);
- continue;
- case O_SUB24:
- pc.cp++;
- tl = pop2();
- tl1 = pop4();
- push4(tl1 - tl);
- continue;
- case O_SUB42:
- pc.cp++;
- tl = pop4();
- tl1 = pop2();
- push4(tl1 - tl);
- continue;
- case O_SUB28:
- pc.cp++;
- tl = pop2();
- td = pop8();
- push8(td - tl);
- continue;
- case O_SUB48:
- pc.cp++;
- tl = pop4();
- td = pop8();
- push8(td - tl);
- continue;
- case O_SUB82:
- pc.cp++;
- td = pop8();
- td1 = pop2();
- push8(td1 - td);
- continue;
- case O_SUB84:
- pc.cp++;
- td = pop8();
- td1 = pop4();
- push8(td1 - td);
- continue;
- case O_MUL2:
- pc.cp++;
- tl = pop2();
- tl1 = pop2();
- push4(tl1 * tl);
- continue;
- case O_MUL4:
- pc.cp++;
- tl = pop4();
- tl1 = pop4();
- push4(tl1 * tl);
- continue;
- case O_MUL24:
- pc.cp++;
- tl = pop2();
- tl1 = pop4();
- push4(tl1 * tl);
- continue;
- case O_MUL42:
- pc.cp++;
- tl = pop4();
- tl1 = pop2();
- push4(tl1 * tl);
- continue;
- case O_MUL28:
- pc.cp++;
- tl = pop2();
- td = pop8();
- push8(td * tl);
- continue;
- case O_MUL48:
- pc.cp++;
- tl = pop4();
- td = pop8();
- push8(td * tl);
- continue;
- case O_MUL82:
- pc.cp++;
- td = pop8();
- td1 = pop2();
- push8(td1 * td);
- continue;
- case O_MUL84:
- pc.cp++;
- td = pop8();
- td1 = pop4();
- push8(td1 * td);
- continue;
- case O_ABS2:
- case O_ABS4:
- pc.cp++;
- tl = pop4();
- push4(tl >= 0 ? tl : -tl);
- continue;
- case O_ABS8:
- pc.cp++;
- td = pop8();
- push8(td >= 0.0 ? td : -td);
- continue;
- case O_NEG2:
- pc.cp++;
- ts = -pop2();
- push4((long)ts);
- continue;
- case O_NEG4:
- pc.cp++;
- tl = -pop4();
- push4(tl);
- continue;
- case O_NEG8:
- pc.cp++;
- td = -pop8();
- push8(td);
- continue;
- case O_DIV2:
- pc.cp++;
- tl = pop2();
- tl1 = pop2();
- push4(tl1 / tl);
- continue;
- case O_DIV4:
- pc.cp++;
- tl = pop4();
- tl1 = pop4();
- push4(tl1 / tl);
- continue;
- case O_DIV24:
- pc.cp++;
- tl = pop2();
- tl1 = pop4();
- push4(tl1 / tl);
- continue;
- case O_DIV42:
- pc.cp++;
- tl = pop4();
- tl1 = pop2();
- push4(tl1 / tl);
- continue;
- case O_MOD2:
- pc.cp++;
- tl = pop2();
- tl1 = pop2();
- push4(tl1 % tl);
- continue;
- case O_MOD4:
- pc.cp++;
- tl = pop4();
- tl1 = pop4();
- push4(tl1 % tl);
- continue;
- case O_MOD24:
- pc.cp++;
- tl = pop2();
- tl1 = pop4();
- push4(tl1 % tl);
- continue;
- case O_MOD42:
- pc.cp++;
- tl = pop4();
- tl1 = pop2();
- push4(tl1 % tl);
- continue;
- case O_ADD8:
- pc.cp++;
- td = pop8();
- td1 = pop8();
- push8(td1 + td);
- continue;
- case O_SUB8:
- pc.cp++;
- td = pop8();
- td1 = pop8();
- push8(td1 - td);
- continue;
- case O_MUL8:
- pc.cp++;
- td = pop8();
- td1 = pop8();
- push8(td1 * td);
- continue;
- case O_DVD8:
- pc.cp++;
- td = pop8();
- td1 = pop8();
- push8(td1 / td);
- continue;
- case O_STOI:
- pc.cp++;
- ts = pop2();
- push4((long)ts);
- continue;
- case O_STOD:
- pc.cp++;
- td = pop2();
- push8(td);
- continue;
- case O_ITOD:
- pc.cp++;
- td = pop4();
- push8(td);
- continue;
- case O_ITOS:
- pc.cp++;
- tl = pop4();
- push2((short)tl);
- continue;
- case O_DVD2:
- pc.cp++;
- td = pop2();
- td1 = pop2();
- push8(td1 / td);
- continue;
- case O_DVD4:
- pc.cp++;
- td = pop4();
- td1 = pop4();
- push8(td1 / td);
- continue;
- case O_DVD24:
- pc.cp++;
- td = pop2();
- td1 = pop4();
- push8(td1 / td);
- continue;
- case O_DVD42:
- pc.cp++;
- td = pop4();
- td1 = pop2();
- push8(td1 / td);
- continue;
- case O_DVD28:
- pc.cp++;
- td = pop2();
- td1 = pop8();
- push8(td1 / td);
- continue;
- case O_DVD48:
- pc.cp++;
- td = pop4();
- td1 = pop8();
- push8(td1 / td);
- continue;
- case O_DVD82:
- pc.cp++;
- td = pop8();
- td1 = pop2();
- push8(td1 / td);
- continue;
- case O_DVD84:
- pc.cp++;
- td = pop8();
- td1 = pop4();
- push8(td1 / td);
- continue;
- case O_RV1:
- tcp = _display.raw[*pc.ucp++];
- push2((short)(*(tcp + *pc.sp++)));
- continue;
- case O_RV14:
- tcp = _display.raw[*pc.ucp++];
- push4((long)(*(tcp + *pc.sp++)));
- continue;
- case O_RV2:
- tcp = _display.raw[*pc.ucp++];
- push2(*(short *)(tcp + *pc.sp++));
- continue;
- case O_RV24:
- tcp = _display.raw[*pc.ucp++];
- push4((long)(*(short *)(tcp + *pc.sp++)));
- continue;
- case O_RV4:
- tcp = _display.raw[*pc.ucp++];
- push4(*(long *)(tcp + *pc.sp++));
- continue;
- case O_RV8:
- tcp = _display.raw[*pc.ucp++];
- pushsze8(*(struct sze8 *)(tcp + *pc.sp++));
- continue;
- case O_RV:
- tcp = _display.raw[*pc.ucp++];
- tcp += *pc.sp++;
- tl = *pc.usp++;
- STACKALIGN(tl1, tl);
- tcp1 = pushsp(tl1);
- blkcpy(tcp, tcp1, tl);
- continue;
- case O_LV:
- tcp = _display.raw[*pc.ucp++];
- pushaddr(tcp + *pc.sp++);
- continue;
- case O_LRV1:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- push2((short)(*(tcp + tl)));
- continue;
- case O_LRV14:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- push4((long)(*(tcp + tl)));
- continue;
- case O_LRV2:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- push2(*(short *)(tcp + tl));
- continue;
- case O_LRV24:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- push4((long)(*(short *)(tcp + tl)));
- continue;
- case O_LRV4:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- push4(*(long *)(tcp + tl));
- continue;
- case O_LRV8:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- pushsze8(*(struct sze8 *)(tcp + tl));
- continue;
- case O_LRV:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- tcp += tl;
- tl = *pc.usp++;
- STACKALIGN(tl1, tl);
- tcp1 = pushsp(tl1);
- blkcpy(tcp, tcp1, tl);
- continue;
- case O_LLV:
- tcp = _display.raw[*pc.ucp++];
- PCLONGVAL(tl);
- pushaddr(tcp + tl);
- continue;
- case O_IND1:
- pc.cp++;
- ts = *popaddr();
- push2(ts);
- continue;
- case O_IND14:
- pc.cp++;
- ti = *popaddr();
- push4((long)ti);
- continue;
- case O_IND2:
- pc.cp++;
- ts = *(short *)(popaddr());
- push2(ts);
- continue;
- case O_IND24:
- pc.cp++;
- ts = *(short *)(popaddr());
- push4((long)ts);
- continue;
- case O_IND4:
- pc.cp++;
- tl = *(long *)(popaddr());
- push4(tl);
- continue;
- case O_IND8:
- pc.cp++;
- t8 = *(struct sze8 *)(popaddr());
- pushsze8(t8);
- continue;
- case O_IND:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- tcp = popaddr();
- STACKALIGN(tl1, tl);
- tcp1 = pushsp(tl1);
- blkcpy(tcp, tcp1, tl);
- continue;
- case O_CON1:
- push2((short)(*pc.cp++));
- continue;
- case O_CON14:
- push4((long)(*pc.cp++));
- continue;
- case O_CON2:
- pc.cp++;
- push2(*pc.sp++);
- continue;
- case O_CON24:
- pc.cp++;
- push4((long)(*pc.sp++));
- continue;
- case O_CON4:
- pc.cp++;
- PCLONGVAL(tl);
- push4(tl);
- continue;
- case O_CON8:
- pc.cp++;
- tcp = pushsp(sizeof(double));
- blkcpy(pc.cp, tcp, sizeof(double));
- pc.dbp++;
- continue;
- case O_CON:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- STACKALIGN(tl1, tl);
- tcp = pushsp(tl1);
- blkcpy(pc.cp, tcp, tl);
- pc.cp += (int)tl;
- continue;
- case O_CONG:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- STACKALIGN(tl1, tl);
- tcp = pushsp(tl1);
- blkcpy(pc.cp, tcp, tl1);
- pc.cp += (int)((tl + 2) & ~1);
- continue;
- case O_LVCON:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- pushaddr(pc.cp);
- tl = (tl + 1) & ~1;
- pc.cp += (int)tl;
- continue;
- case O_RANG2:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop2();
- push2((short)(RANG4(tl1, tl, (long)(*pc.sp++))));
- continue;
- case O_RANG42:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop4();
- push4(RANG4(tl1, tl, (long)(*pc.sp++)));
- continue;
- case O_RSNG2:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop2();
- push2((short)(RSNG4(tl1, tl)));
- continue;
- case O_RSNG42:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop4();
- push4(RSNG4(tl1, tl));
- continue;
- case O_RANG4:
- tl = *pc.cp++;
- if (tl == 0)
- PCLONGVAL(tl);
- tl1 = pop4();
- PCLONGVAL(tl2);
- push4(RANG4(tl1, tl, tl2));
- continue;
- case O_RANG24:
- tl = *pc.cp++;
- if (tl == 0)
- PCLONGVAL(tl);
- tl1 = pop2();
- PCLONGVAL(tl2);
- push2((short)(RANG4(tl1, tl, tl2)));
- continue;
- case O_RSNG4:
- tl = *pc.cp++;
- if (tl == 0)
- PCLONGVAL(tl);
- tl1 = pop4();
- push4(RSNG4(tl1, tl));
- continue;
- case O_RSNG24:
- tl = *pc.cp++;
- if (tl == 0)
- PCLONGVAL(tl);
- tl1 = pop2();
- push2((short)(RSNG4(tl1, tl)));
- continue;
- case O_STLIM:
- pc.cp++;
- tl = pop4();
- STLIM(tl);
- continue;
- case O_LLIMIT:
- pc.cp++;
- tcp = popaddr();
- tl = pop4();
- LLIMIT(tcp, tl);
- continue;
- case O_BUFF:
- BUFF((long)(*pc.cp++));
- continue;
- case O_HALT:
- pc.cp++;
- if (_nodump == TRUE)
- psexit(0);
- fputs("\nCall to procedure halt\n", stderr);
- backtrace("Halted");
- psexit(0);
- continue;
- case O_PXPBUF:
- pc.cp++;
- PCLONGVAL(tl);
- _cntrs = tl;
- PCLONGVAL(tl);
- _rtns = tl;
- NEW(&_pcpcount, (_cntrs + 1) * sizeof(long));
- blkclr(_pcpcount, (_cntrs + 1) * sizeof(long));
- continue;
- case O_COUNT:
- pc.cp++;
- _pcpcount[*pc.usp++]++;
- continue;
- case O_CASE1OP:
- tl = *pc.cp++; /* tl = number of cases */
- if (tl == 0)
- tl = *pc.usp++;
- tsp = pc.sp + tl; /* ptr to end of jump table */
- tcp = (char *)tsp; /* tcp = ptr to case values */
- tl1 = pop2(); /* tl1 = element to find */
- for(; tl > 0; tl--) /* look for element */
- if (tl1 == *tcp++)
- break;
- if (tl == 0) /* default case => error */
- CASERNG(tl1);
- pc.cp += *(tsp - tl);
- continue;
- case O_CASE2OP:
- tl = *pc.cp++; /* tl = number of cases */
- if (tl == 0)
- tl = *pc.usp++;
- tsp = pc.sp + tl; /* ptr to end of jump table */
- tsp1 = tsp; /* tsp1 = ptr to case values */
- tl1 = (unsigned short)pop2();/* tl1 = element to find */
- for(; tl > 0; tl--) /* look for element */
- if (tl1 == *tsp++)
- break;
- if (tl == 0) /* default case => error */
- CASERNG(tl1);
- pc.cp += *(tsp1 - tl);
- continue;
- case O_CASE4OP:
- tl = *pc.cp++; /* tl = number of cases */
- if (tl == 0)
- tl = *pc.usp++;
- tsp1 = pc.sp + tl; /* ptr to end of jump table */
- tlp = (long *)tsp1; /* tlp = ptr to case values */
- tl1 = pop4(); /* tl1 = element to find */
- for(; tl > 0; tl--) { /* look for element */
- GETLONGVAL(tl2, tlp++);
- if (tl1 == tl2)
- break;
- }
- if (tl == 0) /* default case => error */
- CASERNG(tl1);
- pc.cp += *(tsp1 - tl);
- continue;
- case O_ADDT:
- tl = *pc.cp++; /* tl has comparison length */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = pushsp((long)(0));/* tcp pts to first arg */
- ADDT(tcp + tl, tcp + tl, tcp, tl >> 2);
- popsp(tl);
- continue;
- case O_SUBT:
- tl = *pc.cp++; /* tl has comparison length */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = pushsp((long)(0));/* tcp pts to first arg */
- SUBT(tcp + tl, tcp + tl, tcp, tl >> 2);
- popsp(tl);
- continue;
- case O_MULT:
- tl = *pc.cp++; /* tl has comparison length */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = pushsp((long)(0));/* tcp pts to first arg */
- MULT(tcp + tl, tcp + tl, tcp, tl >> 2);
- popsp(tl);
- continue;
- case O_INCT:
- tl = *pc.cp++; /* tl has number of args */
- if (tl == 0)
- tl = *pc.usp++;
- tb = INCT();
- popsp(tl*sizeof(long));
- push2((short)(tb));
- continue;
- case O_CTTOT:
- tl = *pc.cp++; /* tl has number of args */
- if (tl == 0)
- tl = *pc.usp++;
- tl1 = tl * sizeof(long); /* Size of all args */
- tcp = pushsp((long)(0)) + tl1; /* tcp pts to result */
- tl1 = pop4(); /* Pop the 4 fixed args */
- tl2 = pop4();
- tl3 = pop4();
- tl4 = pop4();
- tcp2 = pushsp((long)0); /* tcp2 -> data values */
- CTTOTA(tcp, tl1, tl2, tl3, tl4, tcp2);
- popsp(tl*sizeof(long) - 4*sizeof(long)); /* Pop data */
- continue;
- case O_CARD:
- tl = *pc.cp++; /* tl has comparison length */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = pushsp((long)(0));/* tcp pts to set */
- tl1 = CARD(tcp, tl);
- popsp(tl);
- push2((short)(tl1));
- continue;
- case O_IN:
- tl = *pc.cp++; /* tl has comparison length */
- if (tl == 0)
- tl = *pc.usp++;
- tl1 = pop4(); /* tl1 is the element */
- tcp = pushsp((long)(0));/* tcp pts to set */
- tl2 = *pc.sp++; /* lower bound */
- tb = IN(tl1, tl2, (long)(*pc.usp++), tcp);
- popsp(tl);
- push2((short)(tb));
- continue;
- case O_ASRT:
- pc.cp++;
- tl = pop4();
- tcp = popaddr();
- ASRTS(tl, tcp);
- continue;
- case O_FOR1U:
- tl1 = *pc.cp++; /* tl1 loop branch */
- if (tl1 == 0)
- tl1 = *pc.sp++;
- tcp = popaddr(); /* tcp = ptr to index var */
- tl = pop4(); /* tl upper bound */
- if (*tcp == tl) /* loop is done, fall through */
- continue;
- *tcp += 1; /* inc index var */
- pc.cp += tl1; /* return to top of loop */
- continue;
- case O_FOR2U:
- tl1 = *pc.cp++; /* tl1 loop branch */
- if (tl1 == 0)
- tl1 = *pc.sp++;
- tsp = (short *)popaddr(); /* tsp = ptr to index var */
- tl = pop4(); /* tl upper bound */
- if (*tsp == tl) /* loop is done, fall through */
- continue;
- *tsp += 1; /* inc index var */
- pc.cp += tl1; /* return to top of loop */
- continue;
- case O_FOR4U:
- tl1 = *pc.cp++; /* tl1 loop branch */
- if (tl1 == 0)
- tl1 = *pc.sp++;
- tlp = (long *)popaddr(); /* tlp = ptr to index var */
- tl = pop4(); /* tl upper bound */
- if (*tlp == tl) /* loop is done, fall through */
- continue;
- *tlp += 1; /* inc index var */
- pc.cp += tl1; /* return to top of loop */
- continue;
- case O_FOR1D:
- tl1 = *pc.cp++; /* tl1 loop branch */
- if (tl1 == 0)
- tl1 = *pc.sp++;
- tcp = popaddr(); /* tcp = ptr to index var */
- tl = pop4(); /* tl upper bound */
- if (*tcp == tl) /* loop is done, fall through */
- continue;
- *tcp -= 1; /* dec index var */
- pc.cp += tl1; /* return to top of loop */
- continue;
- case O_FOR2D:
- tl1 = *pc.cp++; /* tl1 loop branch */
- if (tl1 == 0)
- tl1 = *pc.sp++;
- tsp = (short *)popaddr(); /* tsp = ptr to index var */
- tl = pop4(); /* tl upper bound */
- if (*tsp == tl) /* loop is done, fall through */
- continue;
- *tsp -= 1; /* dec index var */
- pc.cp += tl1; /* return to top of loop */
- continue;
- case O_FOR4D:
- tl1 = *pc.cp++; /* tl1 loop branch */
- if (tl1 == 0)
- tl1 = *pc.sp++;
- tlp = (long *)popaddr(); /* tlp = ptr to index var */
- tl = pop4(); /* tl upper bound */
- if (*tlp == tl) /* loop is done, fall through */
- continue;
- *tlp -= 1; /* dec index var */
- pc.cp += tl1; /* return to top of loop */
- continue;
- case O_READE:
- pc.cp++;
- PCLONGVAL(tl);
- push2((short)(READE(curfile, base + tl)));
- continue;
- case O_READ4:
- pc.cp++;
- push4(READ4(curfile));
- continue;
- case O_READC:
- pc.cp++;
- push2((short)(READC(curfile)));
- continue;
- case O_READ8:
- pc.cp++;
- push8(READ8(curfile));
- continue;
- case O_READLN:
- pc.cp++;
- READLN(curfile);
- continue;
- case O_EOF:
- pc.cp++;
- tcp = popaddr();
- push2((short)(TEOF(tcp)));
- continue;
- case O_EOLN:
- pc.cp++;
- tcp = popaddr();
- push2((short)(TEOLN(tcp)));
- continue;
- case O_WRITEC:
- pc.cp++;
- ti = popint();
- tf = popfile();
- if (_runtst) {
- WRITEC(curfile, ti, tf);
- continue;
- }
- fputc(ti, tf);
- continue;
- case O_WRITES:
- pc.cp++; /* Skip arg size */
- tf = popfile();
- ti = popint();
- ti2 = popint();
- tcp2 = popaddr();
- if (_runtst) {
- WRITES(curfile, tf, ti, ti2, tcp2);
- continue;
- }
- fwrite(tf, ti, ti2, tcp2);
- continue;
- case O_WRITEF:
- tf = popfile();
- tcp = popaddr();
- tcp2 = pushsp((long)0); /* Addr of printf's args */
- if (_runtst) {
- VWRITEF(curfile, tf, tcp, tcp2);
- } else {
- vfprintf(tf, tcp, tcp2);
- }
- popsp((long)
- (*pc.cp++) - (sizeof (FILE *)) - sizeof (char *));
- continue;
- case O_WRITLN:
- pc.cp++;
- if (_runtst) {
- WRITLN(curfile);
- continue;
- }
- fputc('\n', ACTFILE(curfile));
- continue;
- case O_PAGE:
- pc.cp++;
- if (_runtst) {
- PAGE(curfile);
- continue;
- }
- fputc('', ACTFILE(curfile));
- continue;
- case O_NAM:
- pc.cp++;
- tl = pop4();
- PCLONGVAL(tl1);
- pushaddr(NAM(tl, base + tl1));
- continue;
- case O_MAX:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- tl1 = pop4();
- if (_runtst) {
- push4(MAX(tl1, tl, (long)(*pc.usp++)));
- continue;
- }
- tl1 -= tl;
- tl = *pc.usp++;
- push4(tl1 > tl ? tl1 : tl);
- continue;
- case O_MIN:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.usp++;
- tl1 = pop4();
- push4(tl1 < tl ? tl1 : tl);
- continue;
- case O_UNIT:
- pc.cp++;
- curfile = UNIT(popaddr());
- continue;
- case O_UNITINP:
- pc.cp++;
- curfile = INPUT;
- continue;
- case O_UNITOUT:
- pc.cp++;
- curfile = OUTPUT;
- continue;
- case O_MESSAGE:
- pc.cp++;
- PFLUSH();
- curfile = ERR;
- continue;
- case O_PUT:
- pc.cp++;
- PUT(curfile);
- continue;
- case O_GET:
- pc.cp++;
- GET(curfile);
- continue;
- case O_FNIL:
- pc.cp++;
- tcp = popaddr();
- pushaddr(FNIL(tcp));
- continue;
- case O_DEFNAME:
- pc.cp++;
- tcp2 = popaddr();
- tcp = popaddr();
- tl = pop4();
- tl2 = pop4();
- DEFNAME((struct iorec *)tcp2, tcp, tl, tl2);
- continue;
- case O_RESET:
- pc.cp++;
- tcp2 = popaddr();
- tcp = popaddr();
- tl = pop4();
- tl2 = pop4();
- RESET((struct iorec *)tcp2, tcp, tl, tl2);
- continue;
- case O_REWRITE:
- pc.cp++;
- tcp2 = popaddr();
- tcp = popaddr();
- tl = pop4();
- tl2 = pop4();
- REWRITE((struct iorec *)tcp2, tcp, tl, tl2);
- continue;
- case O_FILE:
- pc.cp++;
- pushaddr(ACTFILE(curfile));
- continue;
- case O_REMOVE:
- pc.cp++;
- tcp = popaddr();
- tl = pop4();
- REMOVE(tcp, tl);
- continue;
- case O_FLUSH:
- pc.cp++;
- tcp = popaddr();
- FLUSH((struct iorec *)tcp);
- continue;
- case O_PACK:
- pc.cp++;
- tl = pop4();
- tcp = popaddr();
- tcp2 = popaddr();
- tl1 = pop4();
- tl2 = pop4();
- tl3 = pop4();
- tl4 = pop4();
- PACK(tl, tcp, tcp2, tl1, tl2, tl3, tl4);
- continue;
- case O_UNPACK:
- pc.cp++;
- tl = pop4();
- tcp = popaddr();
- tcp2 = popaddr();
- tl1 = pop4();
- tl2 = pop4();
- tl3 = pop4();
- tl4 = pop4();
- UNPACK(tl, tcp, tcp2, tl1, tl2, tl3, tl4);
- continue;
- case O_ARGC:
- pc.cp++;
- push4((long)_argc);
- continue;
- case O_ARGV:
- tl = *pc.cp++; /* tl = size of char array */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = popaddr(); /* tcp = addr of char array */
- tl1 = pop4(); /* tl1 = argv subscript */
- ARGV(tl1, tcp, tl);
- continue;
- case O_CLCK:
- pc.cp++;
- push4(CLCK());
- continue;
- case O_WCLCK:
- pc.cp++;
- push4(time(0));
- continue;
- case O_SCLCK:
- pc.cp++;
- push4(SCLCK());
- continue;
- case O_NEW:
- tl = *pc.cp++; /* tl = size being new'ed */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = popaddr(); /* ptr to ptr being new'ed */
- NEW(tcp, tl);
- if (_runtst) {
- blkclr(*((char **)(tcp)), tl);
- }
- continue;
- case O_DISPOSE:
- tl = *pc.cp++; /* tl = size being disposed */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = popaddr(); /* ptr to ptr being disposed */
- DISPOSE(tcp, tl);
- *(char **)tcp = (char *)0;
- continue;
- case O_DFDISP:
- tl = *pc.cp++; /* tl = size being disposed */
- if (tl == 0)
- tl = *pc.usp++;
- tcp = popaddr(); /* ptr to ptr being disposed */
- DFDISPOSE(tcp, tl);
- *(char **)tcp = (char *)0;
- continue;
- case O_DATE:
- pc.cp++;
- DATE(popaddr());
- continue;
- case O_TIME:
- pc.cp++;
- TIME(popaddr());
- continue;
- case O_UNDEF:
- pc.cp++;
- td = pop8();
- push2((short)(0));
- continue;
- case O_ATAN:
- pc.cp++;
- td = pop8();
- if (_runtst) {
- push8(ATAN(td));
- continue;
- }
- push8(atan(td));
- continue;
- case O_COS:
- pc.cp++;
- td = pop8();
- if (_runtst) {
- push8(COS(td));
- continue;
- }
- push8(cos(td));
- continue;
- case O_EXP:
- pc.cp++;
- td = pop8();
- if (_runtst) {
- push8(EXP(td));
- continue;
- }
- push8(exp(td));
- continue;
- case O_LN:
- pc.cp++;
- td = pop8();
- if (_runtst) {
- push8(LN(td));
- continue;
- }
- push8(log(td));
- continue;
- case O_SIN:
- pc.cp++;
- td = pop8();
- if (_runtst) {
- push8(SIN(td));
- continue;
- }
- push8(sin(td));
- continue;
- case O_SQRT:
- pc.cp++;
- td = pop8();
- if (_runtst) {
- push8(SQRT(td));
- continue;
- }
- push8(sqrt(td));
- continue;
- case O_CHR2:
- case O_CHR4:
- pc.cp++;
- tl = pop4();
- if (_runtst) {
- push2((short)(CHR(tl)));
- continue;
- }
- push2((short)tl);
- continue;
- case O_ODD2:
- case O_ODD4:
- pc.cp++;
- tl = pop4();
- push2((short)(tl & 1));
- continue;
- case O_SUCC2:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop4();
- if (_runtst) {
- push2((short)(SUCC(tl1, tl, (long)(*pc.sp++))));
- continue;
- }
- push2((short)(tl1 + 1));
- pc.sp++;
- continue;
- case O_SUCC24:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop4();
- if (_runtst) {
- push4(SUCC(tl1, tl, (long)(*pc.sp++)));
- continue;
- }
- push4(tl1 + 1);
- pc.sp++;
- continue;
- case O_SUCC4:
- tl = *pc.cp++;
- if (tl == 0)
- PCLONGVAL(tl);
- tl1 = pop4();
- if (_runtst) {
- PCLONGVAL(tl2);
- push4(SUCC(tl1, tl, (long)(tl2)));
- continue;
- }
- push4(tl1 + 1);
- pc.lp++;
- continue;
- case O_PRED2:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop4();
- if (_runtst) {
- push2((short)(PRED(tl1, tl, (long)(*pc.sp++))));
- continue;
- }
- push2((short)(tl1 - 1));
- pc.sp++;
- continue;
- case O_PRED24:
- tl = *pc.cp++;
- if (tl == 0)
- tl = *pc.sp++;
- tl1 = pop4();
- if (_runtst) {
- push4(PRED(tl1, tl, (long)(*pc.sp++)));
- continue;
- }
- push4(tl1 - 1);
- pc.sp++;
- continue;
- case O_PRED4:
- tl = *pc.cp++;
- if (tl == 0)
- PCLONGVAL(tl);
- tl1 = pop4();
- if (_runtst) {
- PCLONGVAL(tl2);
- push4(PRED(tl1, tl, (long)(tl2)));
- continue;
- }
- push4(tl1 - 1);
- pc.lp++;
- continue;
- case O_SEED:
- pc.cp++;
- tl = pop4();
- push4(SEED(tl));
- continue;
- case O_RANDOM:
- pc.cp++;
- td = pop8(); /* Argument is ignored */
- push8(RANDOM());
- continue;
- case O_EXPO:
- pc.cp++;
- td = pop8();
- push4(EXPO(td));
- continue;
- case O_SQR2:
- case O_SQR4:
- pc.cp++;
- tl = pop4();
- push4(tl * tl);
- continue;
- case O_SQR8:
- pc.cp++;
- td = pop8();
- push8(td * td);
- continue;
- case O_ROUND:
- pc.cp++;
- td = pop8();
- push4(ROUND(td));
- continue;
- case O_TRUNC:
- pc.cp++;
- td = pop8();
- push4(TRUNC(td));
- continue;
- default:
- ERROR("Panic: bad op code\n");
- continue;
- }
- }
- }
-