12080Smckusick /* Copyright (c) 1979 Regents of the University of California */ 22080Smckusick 3*2239Smckusic static char sccsid[] = "@(#)interp.c 1.7 01/26/81"; 42080Smckusick 52080Smckusick #include <math.h> 62080Smckusick #include "vars.h" 72080Smckusick #include "panics.h" 82080Smckusick #include "h02opcs.h" 92080Smckusick #include "machdep.h" 102080Smckusick #include "h01errs.h" 112080Smckusick #include "libpc.h" 122080Smckusick 132080Smckusick /* 142080Smckusick * program variables 152080Smckusick */ 162109Smckusic union disply _display; 172080Smckusick struct disp *_dp; 182080Smckusick long _lino = 0; 192080Smckusick int _argc; 202080Smckusick char **_argv; 212080Smckusick long _mode; 222191Smckusic long _runtst = TRUE; 232191Smckusic long _nodump = FALSE; 242080Smckusick long _stlim = 500000; 252080Smckusick long _stcnt = 0; 262191Smckusic long _seed = 1; 272080Smckusick char *_minptr = (char *)0x7fffffff; 282080Smckusick char *_maxptr = (char *)0; 292080Smckusick long *_pcpcount = (long *)0; 302080Smckusick long _cntrs = 0; 312080Smckusick long _rtns = 0; 322080Smckusick 332080Smckusick /* 342080Smckusick * file record variables 352080Smckusick */ 362080Smckusick long _filefre = PREDEF; 372080Smckusick struct iorechd _fchain = { 382080Smckusick 0, 0, 0, 0, /* only use fchain field */ 392080Smckusick INPUT /* fchain */ 402080Smckusick }; 412080Smckusick struct iorec *_actfile[MAXFILES] = { 422080Smckusick INPUT, 432080Smckusick OUTPUT, 442080Smckusick ERR 452080Smckusick }; 462080Smckusick 472080Smckusick /* 482080Smckusick * standard files 492080Smckusick */ 502080Smckusick char _inwin, _outwin, _errwin; 512080Smckusick struct iorechd input = { 522080Smckusick &_inwin, /* fileptr */ 532080Smckusick 0, /* lcount */ 542080Smckusick 0x7fffffff, /* llimit */ 552080Smckusick &_iob[0], /* fbuf */ 562080Smckusick OUTPUT, /* fchain */ 572080Smckusick STDLVL, /* flev */ 582080Smckusick "standard input", /* pfname */ 592080Smckusick FTEXT | FREAD | SYNC, /* funit */ 602080Smckusick 0, /* fblk */ 612080Smckusick 1 /* fsize */ 622080Smckusick }; 632080Smckusick struct iorechd output = { 642080Smckusick &_outwin, /* fileptr */ 652080Smckusick 0, /* lcount */ 662080Smckusick 0x7fffffff, /* llimit */ 672080Smckusick &_iob[1], /* fbuf */ 682080Smckusick ERR, /* fchain */ 692080Smckusick STDLVL, /* flev */ 702080Smckusick "standard output", /* pfname */ 712080Smckusick FTEXT | FWRITE | EOFF, /* funit */ 722080Smckusick 1, /* fblk */ 732080Smckusick 1 /* fsize */ 742080Smckusick }; 752080Smckusick struct iorechd _err = { 762080Smckusick &_errwin, /* fileptr */ 772080Smckusick 0, /* lcount */ 782080Smckusick 0x7fffffff, /* llimit */ 792080Smckusick &_iob[2], /* fbuf */ 802080Smckusick FILNIL, /* fchain */ 812080Smckusick STDLVL, /* flev */ 822080Smckusick "Message file", /* pfname */ 832080Smckusick FTEXT | FWRITE | EOFF, /* funit */ 842080Smckusick 2, /* fblk */ 852080Smckusick 1 /* fsize */ 862080Smckusick }; 872080Smckusick 882109Smckusic /* 892109Smckusic * Px profile array 902109Smckusic */ 912109Smckusic #ifdef PROFILE 922109Smckusic long _profcnts[NUMOPS]; 932109Smckusic #endif PROFILE 942109Smckusic 952109Smckusic /* 962109Smckusic * debugging variables 972109Smckusic */ 982109Smckusic #ifdef DEBUG 992109Smckusic char opc[10]; 1002109Smckusic long opcptr = 9; 1012109Smckusic #endif DEBUG 1022109Smckusic 1032080Smckusick interpreter(base) 1042080Smckusick char *base; 1052080Smckusick { 1062080Smckusick union progcntr pc; /* interpreted program cntr */ 1072080Smckusick register char *vpc; /* register used for "pc" */ 1082080Smckusick struct iorec *curfile; /* active file */ 1092080Smckusick register struct stack *stp; /* active stack frame ptr */ 1102080Smckusick /* 1112080Smckusick * the following variables are used as scratch 1122080Smckusick */ 113*2239Smckusic register char *tcp; 114*2239Smckusic register long tl, tl1, tl2; 1152080Smckusick double td, td1; 116*2239Smckusic struct sze8 t8; 1172080Smckusick long *tlp; 1182080Smckusick short *tsp, *tsp1; 1192080Smckusick char *tcp1; 1202080Smckusick struct stack *tstp; 1212080Smckusick struct formalrtn *tfp; 1222080Smckusick union progcntr tpc; 1232080Smckusick struct iorec **ip; 1242080Smckusick 1252080Smckusick /* 126*2239Smckusic * Setup sets up any hardware specific parameters before 127*2239Smckusic * starting the interpreter. Typically this is inline replaced 128*2239Smckusic * by interp.sed to utilize specific machine instructions. 129*2239Smckusic */ 130*2239Smckusic setup(); 131*2239Smckusic /* 1322080Smckusick * necessary only on systems which do not initialize 1332080Smckusick * memory to zero 1342080Smckusick */ 1352080Smckusick for (ip = &_actfile[3]; ip < &_actfile[MAXFILES]; *ip++ = FILNIL) 1362080Smckusick /* void */; 1372080Smckusick /* 1382080Smckusick * set up global environment, then ``call'' the main program 1392080Smckusick */ 1402109Smckusic _display.frame[0].locvars = pushsp(2 * sizeof(struct iorec *)); 1412109Smckusic _display.frame[0].locvars += 8; /* local offsets are negative */ 1422109Smckusic *(struct iorec **)(_display.frame[0].locvars - 4) = OUTPUT; 1432109Smckusic *(struct iorec **)(_display.frame[0].locvars - 8) = INPUT; 1442080Smckusick stp = (struct stack *)pushsp(sizeof(struct stack)); 1452109Smckusic _dp = &_display.frame[0]; 1462080Smckusick pc.cp = base; 1472080Smckusick for(;;) { 1482109Smckusic # ifdef DEBUG 1492080Smckusick if (++opcptr == 10) 1502080Smckusick opcptr = 0; 1512080Smckusick opc[opcptr] = *pc.ucp; 1522109Smckusic # endif DEBUG 1532109Smckusic # ifdef PROFILE 1542109Smckusic _profcnts[*pc.ucp]++; 1552109Smckusic # endif PROFILE 1562080Smckusick switch (*pc.ucp++) { 1572080Smckusick default: 1582080Smckusick panic(PBADOP); 1592080Smckusick continue; 1602080Smckusick case O_NODUMP: 1612191Smckusic _nodump = TRUE; 1622080Smckusick /* and fall through */ 1632080Smckusick case O_BEG: 1642080Smckusick _dp += 1; /* enter local scope */ 1652080Smckusick stp->odisp = *_dp; /* save old display value */ 1662080Smckusick tl = *pc.ucp++; /* tl = name size */ 1672080Smckusick stp->entry = pc.hdrp; /* pointer to entry info */ 1682191Smckusic tl1 = pc.hdrp->framesze;/* tl1 = size of frame */ 1692191Smckusic _lino = pc.hdrp->offset; 1702191Smckusic _runtst = pc.hdrp->tests; 1712191Smckusic disableovrflo(); 1722191Smckusic if (_runtst) 1732191Smckusic enableovrflo(); 1742219Smckusic pc.cp += tl; /* skip over proc hdr info */ 1752080Smckusick stp->file = curfile; /* save active file */ 1762080Smckusick tcp = pushsp(tl1); /* tcp = new top of stack */ 1772080Smckusick blkclr(tl1, tcp); /* zero stack frame */ 1782109Smckusic tcp += tl1; /* offsets of locals are neg */ 1792109Smckusic _dp->locvars = tcp; /* set new display pointer */ 1802109Smckusic _dp->stp = stp; 1812080Smckusick stp->tos = pushsp(0); /* set top of stack pointer */ 1822080Smckusick continue; 1832080Smckusick case O_END: 1842080Smckusick PCLOSE(_dp->locvars); /* flush & close local files */ 1852080Smckusick stp = _dp->stp; 1862080Smckusick curfile = stp->file; /* restore old active file */ 1872080Smckusick *_dp = stp->odisp; /* restore old display entry */ 1882109Smckusic if (_dp == &_display.frame[1]) 1892080Smckusick return; /* exiting main proc ??? */ 1902080Smckusick _lino = stp->lino; /* restore lino, pc, dp */ 1912080Smckusick pc.cp = stp->pc.cp; 1922080Smckusick _dp = stp->dp; 1932191Smckusic _runtst = stp->entry->tests; 1942191Smckusic disableovrflo(); 1952191Smckusic if (_runtst) 1962191Smckusic enableovrflo(); 1972109Smckusic popsp(stp->entry->framesze + /* pop local vars */ 1982080Smckusick sizeof(struct stack) + /* pop stack frame */ 1992080Smckusick stp->entry->nargs); /* pop parms */ 2002080Smckusick continue; 2012080Smckusick case O_CALL: 2022080Smckusick tl = *pc.cp++; 2032080Smckusick tcp = base + *pc.lp++;/* calc new entry point */ 2042080Smckusick tcp += sizeof(short); 2052080Smckusick tcp = base + *(long *)tcp; 2062080Smckusick stp = (struct stack *)pushsp(sizeof(struct stack)); 2072080Smckusick stp->lino = _lino; /* save lino, pc, dp */ 2082080Smckusick stp->pc.cp = pc.cp; 2092080Smckusick stp->dp = _dp; 2102109Smckusic _dp = &_display.frame[tl]; /* set up new display ptr */ 2112080Smckusick pc.cp = tcp; 2122080Smckusick continue; 2132080Smckusick case O_FCALL: 2142080Smckusick tl = *pc.cp++; /* tl = number of args */ 2152080Smckusick if (tl == 0) 2162080Smckusick tl = *pc.lp++; 2172080Smckusick tfp = (struct formalrtn *)popaddr(); 2182080Smckusick stp = (struct stack *)pushsp(sizeof(struct stack)); 2192080Smckusick stp->lino = _lino; /* save lino, pc, dp */ 2202080Smckusick stp->pc.cp = pc.cp; 2212080Smckusick stp->dp = _dp; 2222080Smckusick pc.cp = tfp->entryaddr; /* calc new entry point */ 2232191Smckusic if (_runtst) { 2242191Smckusic tpc.sp = pc.sp + 1; 2252191Smckusic tl -= tpc.hdrp->nargs; 2262191Smckusic if (tl != 0) { 2272191Smckusic if (tl > 0) 2282191Smckusic tl += sizeof(int) - 1; 2292191Smckusic else 2302191Smckusic tl -= sizeof(int) - 1; 2312191Smckusic ERROR(ENARGS, tl / sizeof(int)); 2322191Smckusic } 2332080Smckusick } 2342109Smckusic _dp = &_display.frame[tfp->cbn];/* new display ptr */ 2352080Smckusick blkcpy(sizeof(struct disp) * tfp->cbn, 2362109Smckusic &_display.frame[1], &tfp->disp[tfp->cbn]); 2372080Smckusick blkcpy(sizeof(struct disp) * tfp->cbn, 2382109Smckusic &tfp->disp[0], &_display.frame[1]); 2392080Smckusick continue; 2402080Smckusick case O_FRTN: 2412080Smckusick tl = *pc.cp++; /* tl = size of return obj */ 2422080Smckusick if (tl == 0) 2432080Smckusick tl = *pc.usp++; 2442080Smckusick tcp = pushsp(0); 2452080Smckusick tfp = *(struct formalrtn **)(tcp + tl); 2462080Smckusick blkcpy(tl, tcp, tcp + sizeof(struct formalrtn *)); 2472080Smckusick popsp(sizeof(struct formalrtn *)); 2482080Smckusick blkcpy(sizeof(struct disp) * tfp->cbn, 2492109Smckusic &tfp->disp[tfp->cbn], &_display.frame[1]); 2502080Smckusick continue; 2512080Smckusick case O_FSAV: 2522080Smckusick tfp = (struct formalrtn *)popaddr(); 2532080Smckusick tfp->cbn = *pc.cp++; /* blk number of routine */ 2542080Smckusick tcp = base + *pc.lp++;/* calc new entry point */ 2552080Smckusick tcp += sizeof(short); 2562080Smckusick tfp->entryaddr = base + *(long *)tcp; 2572080Smckusick blkcpy(sizeof(struct disp) * tfp->cbn, 2582109Smckusic &_display.frame[1], &tfp->disp[0]); 2592080Smckusick pushaddr(tfp); 2602080Smckusick continue; 2612080Smckusick case O_SDUP2: 2622080Smckusick pc.cp++; 2632080Smckusick tl = pop2(); 2642080Smckusick push2(tl); 2652080Smckusick push2(tl); 2662080Smckusick continue; 2672080Smckusick case O_SDUP4: 2682080Smckusick pc.cp++; 2692080Smckusick tl = pop4(); 2702080Smckusick push4(tl); 2712080Smckusick push4(tl); 2722080Smckusick continue; 2732080Smckusick case O_TRA: 2742080Smckusick pc.cp++; 2752080Smckusick pc.cp += *pc.sp; 2762080Smckusick continue; 2772080Smckusick case O_TRA4: 2782080Smckusick pc.cp++; 2792080Smckusick pc.cp = base + *pc.lp; 2802080Smckusick continue; 2812080Smckusick case O_GOTO: 2822109Smckusic tstp = _display.frame[*pc.cp++].stp; /* ptr to 2832109Smckusic exit frame */ 2842080Smckusick pc.cp = base + *pc.lp; 2852080Smckusick stp = _dp->stp; 2862080Smckusick while (tstp != stp) { 2872109Smckusic if (_dp == &_display.frame[1]) 2882080Smckusick ERROR(EGOTO); /* exiting prog ??? */ 2892080Smckusick PCLOSE(_dp->locvars); /* close local files */ 2902080Smckusick curfile = stp->file; /* restore active file */ 2912080Smckusick *_dp = stp->odisp; /* old display entry */ 2922080Smckusick _dp = stp->dp; /* restore dp */ 2932080Smckusick stp = _dp->stp; 2942080Smckusick } 2952080Smckusick /* pop locals, stack frame, parms, and return values */ 2962080Smckusick popsp(stp->tos - pushsp(0)); 2972080Smckusick continue; 2982080Smckusick case O_LINO: 2992080Smckusick if (_dp->stp->tos != pushsp(0)) 3002080Smckusick panic(PSTKNEMP); 3012080Smckusick _lino = *pc.cp++; /* set line number */ 3022080Smckusick if (_lino == 0) 3032080Smckusick _lino = *pc.sp++; 3042080Smckusick LINO(); /* inc statement count */ 3052080Smckusick continue; 3062080Smckusick case O_PUSH: 3072080Smckusick tl = *pc.cp++; 3082080Smckusick if (tl == 0) 3092080Smckusick tl = *pc.usp++; 3102080Smckusick tl = (-tl + 1) & ~1; 3112080Smckusick tcp = pushsp(tl); 3122080Smckusick blkclr(tl, tcp); 3132080Smckusick continue; 3142080Smckusick case O_IF: 3152080Smckusick pc.cp++; 3162191Smckusic if (pop2()) { 3172080Smckusick pc.sp++; 3182191Smckusic continue; 3192191Smckusic } 3202191Smckusic pc.cp += *pc.sp; 3212080Smckusick continue; 3222080Smckusick case O_REL2: 3232080Smckusick tl = pop2(); 3242080Smckusick tl1 = pop2(); 3252080Smckusick goto cmplong; 3262080Smckusick case O_REL24: 3272080Smckusick tl = pop2(); 3282080Smckusick tl1 = pop4(); 3292080Smckusick goto cmplong; 3302080Smckusick case O_REL42: 3312080Smckusick tl = pop4(); 3322080Smckusick tl1 = pop2(); 3332080Smckusick goto cmplong; 3342080Smckusick case O_REL4: 3352080Smckusick tl = pop4(); 3362080Smckusick tl1 = pop4(); 3372080Smckusick cmplong: 3382080Smckusick tl2 = *pc.cp++; 3392080Smckusick switch (tl2) { 3402080Smckusick case releq: 3412080Smckusick push2(tl1 == tl); 3422080Smckusick continue; 3432080Smckusick case relne: 3442080Smckusick push2(tl1 != tl); 3452080Smckusick continue; 3462080Smckusick case rellt: 3472080Smckusick push2(tl1 < tl); 3482080Smckusick continue; 3492080Smckusick case relgt: 3502080Smckusick push2(tl1 > tl); 3512080Smckusick continue; 3522080Smckusick case relle: 3532080Smckusick push2(tl1 <= tl); 3542080Smckusick continue; 3552080Smckusick case relge: 3562080Smckusick push2(tl1 >= tl); 3572080Smckusick continue; 3582080Smckusick default: 3592080Smckusick panic(PSYSTEM); 3602080Smckusick continue; 3612080Smckusick } 3622080Smckusick case O_RELG: 3632080Smckusick tl2 = *pc.cp++; /* tc has jump opcode */ 3642080Smckusick tl = *pc.usp++; /* tl has comparison length */ 3652080Smckusick tl1 = (tl + 1) & ~1; /* tl1 has arg stack length */ 3662080Smckusick tcp = pushsp(0); /* tcp pts to first arg */ 3672080Smckusick switch (tl2) { 3682080Smckusick case releq: 3692080Smckusick tl = RELEQ(tl, tcp + tl1, tcp); 3702080Smckusick break; 3712080Smckusick case relne: 3722080Smckusick tl = RELNE(tl, tcp + tl1, tcp); 3732080Smckusick break; 3742080Smckusick case rellt: 3752080Smckusick tl = RELSLT(tl, tcp + tl1, tcp); 3762080Smckusick break; 3772080Smckusick case relgt: 3782080Smckusick tl = RELSGT(tl, tcp + tl1, tcp); 3792080Smckusick break; 3802080Smckusick case relle: 3812080Smckusick tl = RELSLE(tl, tcp + tl1, tcp); 3822080Smckusick break; 3832080Smckusick case relge: 3842080Smckusick tl = RELSGE(tl, tcp + tl1, tcp); 3852080Smckusick break; 3862080Smckusick default: 3872080Smckusick panic(PSYSTEM); 3882080Smckusick break; 3892080Smckusick } 3902080Smckusick popsp(tl1 << 1); 3912080Smckusick push2(tl); 3922080Smckusick continue; 3932080Smckusick case O_RELT: 3942080Smckusick tl2 = *pc.cp++; /* tc has jump opcode */ 3952080Smckusick tl1 = *pc.usp++; /* tl1 has comparison length */ 3962080Smckusick tcp = pushsp(0); /* tcp pts to first arg */ 3972080Smckusick switch (tl2) { 3982080Smckusick case releq: 3992080Smckusick tl = RELEQ(tl1, tcp + tl1, tcp); 4002080Smckusick break; 4012080Smckusick case relne: 4022080Smckusick tl = RELNE(tl1, tcp + tl1, tcp); 4032080Smckusick break; 4042080Smckusick case rellt: 4052080Smckusick tl = RELTLT(tl1, tcp + tl1, tcp); 4062080Smckusick break; 4072080Smckusick case relgt: 4082080Smckusick tl = RELTGT(tl1, tcp + tl1, tcp); 4092080Smckusick break; 4102080Smckusick case relle: 4112080Smckusick tl = RELTLE(tl1, tcp + tl1, tcp); 4122080Smckusick break; 4132080Smckusick case relge: 4142080Smckusick tl = RELTGE(tl1, tcp + tl1, tcp); 4152080Smckusick break; 4162080Smckusick default: 4172080Smckusick panic(PSYSTEM); 4182080Smckusick break; 4192080Smckusick } 4202080Smckusick popsp(tl1 << 1); 4212080Smckusick push2(tl); 4222080Smckusick continue; 4232080Smckusick case O_REL28: 4242080Smckusick td = pop2(); 4252080Smckusick td1 = pop8(); 4262080Smckusick goto cmpdbl; 4272080Smckusick case O_REL48: 4282080Smckusick td = pop4(); 4292080Smckusick td1 = pop8(); 4302080Smckusick goto cmpdbl; 4312080Smckusick case O_REL82: 4322080Smckusick td = pop8(); 4332080Smckusick td1 = pop2(); 4342080Smckusick goto cmpdbl; 4352080Smckusick case O_REL84: 4362080Smckusick td = pop8(); 4372080Smckusick td1 = pop4(); 4382080Smckusick goto cmpdbl; 4392080Smckusick case O_REL8: 4402080Smckusick td = pop8(); 4412080Smckusick td1 = pop8(); 4422080Smckusick cmpdbl: 4432080Smckusick switch (*pc.cp++) { 4442080Smckusick case releq: 4452080Smckusick push2(td1 == td); 4462080Smckusick continue; 4472080Smckusick case relne: 4482080Smckusick push2(td1 != td); 4492080Smckusick continue; 4502080Smckusick case rellt: 4512080Smckusick push2(td1 < td); 4522080Smckusick continue; 4532080Smckusick case relgt: 4542080Smckusick push2(td1 > td); 4552080Smckusick continue; 4562080Smckusick case relle: 4572080Smckusick push2(td1 <= td); 4582080Smckusick continue; 4592080Smckusick case relge: 4602080Smckusick push2(td1 >= td); 4612080Smckusick continue; 4622080Smckusick default: 4632080Smckusick panic(PSYSTEM); 4642080Smckusick continue; 4652080Smckusick } 4662080Smckusick case O_AND: 4672080Smckusick pc.cp++; 4682080Smckusick push2(pop2() & pop2()); 4692080Smckusick continue; 4702080Smckusick case O_OR: 4712080Smckusick pc.cp++; 4722080Smckusick push2(pop2() | pop2()); 4732080Smckusick continue; 4742080Smckusick case O_NOT: 4752080Smckusick pc.cp++; 4762080Smckusick push2(pop2() ^ 1); 4772080Smckusick continue; 4782080Smckusick case O_AS2: 4792080Smckusick pc.cp++; 4802080Smckusick tl = pop2(); 4812080Smckusick *(short *)popaddr() = tl; 4822080Smckusick continue; 4832080Smckusick case O_AS4: 4842080Smckusick pc.cp++; 4852080Smckusick tl = pop4(); 4862080Smckusick *(long *)popaddr() = tl; 4872080Smckusick continue; 4882080Smckusick case O_AS24: 4892080Smckusick pc.cp++; 4902080Smckusick tl = pop2(); 4912080Smckusick *(long *)popaddr() = tl; 4922080Smckusick continue; 4932080Smckusick case O_AS42: 4942080Smckusick pc.cp++; 4952080Smckusick tl = pop4(); 4962080Smckusick *(short *)popaddr() = tl; 4972080Smckusick continue; 4982080Smckusick case O_AS21: 4992080Smckusick pc.cp++; 5002080Smckusick tl = pop2(); 5012080Smckusick *popaddr() = tl; 5022080Smckusick continue; 5032080Smckusick case O_AS41: 5042080Smckusick pc.cp++; 5052080Smckusick tl = pop4(); 5062080Smckusick *popaddr() = tl; 5072080Smckusick continue; 5082080Smckusick case O_AS28: 5092080Smckusick pc.cp++; 5102080Smckusick tl = pop2(); 5112080Smckusick *(double *)popaddr() = tl; 5122080Smckusick continue; 5132080Smckusick case O_AS48: 5142080Smckusick pc.cp++; 5152080Smckusick tl = pop4(); 5162080Smckusick *(double *)popaddr() = tl; 5172080Smckusick continue; 5182080Smckusick case O_AS8: 5192080Smckusick pc.cp++; 520*2239Smckusic t8 = popsze8(); 521*2239Smckusic *(struct sze8 *)popaddr() = t8; 5222080Smckusick continue; 5232080Smckusick case O_AS: 5242080Smckusick tl = *pc.cp++; 5252080Smckusick if (tl == 0) 5262080Smckusick tl = *pc.usp++; 5272080Smckusick tl1 = (tl + 1) & ~1; 5282080Smckusick tcp = pushsp(0); 5292080Smckusick blkcpy(tl, tcp, *(char **)(tcp + tl1)); 5302080Smckusick popsp(tl1 + sizeof(char *)); 5312080Smckusick continue; 5322080Smckusick case O_INX2P2: 5332080Smckusick tl = *pc.cp++; /* tl has shift amount */ 5342080Smckusick tl1 = (pop2() - *pc.sp++) << tl; 5352080Smckusick pushaddr(popaddr() + tl1); 5362080Smckusick continue; 5372080Smckusick case O_INX4P2: 5382080Smckusick tl = *pc.cp++; /* tl has shift amount */ 5392080Smckusick tl1 = (pop4() - *pc.sp++) << tl; 5402080Smckusick pushaddr(popaddr() + tl1); 5412080Smckusick continue; 5422080Smckusick case O_INX2: 5432080Smckusick tl = *pc.cp++; /* tl has element size */ 5442080Smckusick if (tl == 0) 5452080Smckusick tl = *pc.usp++; 5462080Smckusick tl1 = pop2(); /* index */ 5472080Smckusick tl2 = *pc.sp++; 5482080Smckusick pushaddr(popaddr() + (tl1 - tl2) * tl); 5492191Smckusic tl = *pc.usp++; 5502191Smckusic if (_runtst) 5512191Smckusic SUBSC(tl1, tl2, tl); /* range check */ 5522080Smckusick continue; 5532080Smckusick case O_INX4: 5542080Smckusick tl = *pc.cp++; /* tl has element size */ 5552080Smckusick if (tl == 0) 5562080Smckusick tl = *pc.usp++; 5572080Smckusick tl1 = pop4(); /* index */ 5582080Smckusick tl2 = *pc.sp++; 5592080Smckusick pushaddr(popaddr() + (tl1 - tl2) * tl); 5602191Smckusic tl = *pc.usp++; 5612191Smckusic if (_runtst) 5622191Smckusic SUBSC(tl1, tl2, tl); /* range check */ 5632080Smckusick continue; 5642080Smckusick case O_OFF: 5652080Smckusick tl = *pc.cp++; 5662080Smckusick if (tl == 0) 5672080Smckusick tl = *pc.usp++; 5682080Smckusick push4(pop4() + tl); 5692080Smckusick continue; 5702080Smckusick case O_NIL: 5712080Smckusick pc.cp++; 5722080Smckusick NIL(); 5732080Smckusick continue; 5742080Smckusick case O_ADD2: 5752080Smckusick pc.cp++; 5762080Smckusick push4(pop2() + pop2()); 5772080Smckusick continue; 5782080Smckusick case O_ADD4: 5792080Smckusick pc.cp++; 5802080Smckusick push4(pop4() + pop4()); 5812080Smckusick continue; 5822080Smckusick case O_ADD24: 5832080Smckusick pc.cp++; 5842080Smckusick tl = pop2(); 5852080Smckusick push4(pop4() + tl); 5862080Smckusick continue; 5872080Smckusick case O_ADD42: 5882080Smckusick pc.cp++; 5892080Smckusick tl = pop4(); 5902080Smckusick push4(pop2() + tl); 5912080Smckusick continue; 5922080Smckusick case O_ADD28: 5932080Smckusick pc.cp++; 5942080Smckusick tl = pop2(); 5952080Smckusick push8(pop8() + tl); 5962080Smckusick continue; 5972080Smckusick case O_ADD48: 5982080Smckusick pc.cp++; 5992080Smckusick tl = pop4(); 6002080Smckusick push8(pop8() + tl); 6012080Smckusick continue; 6022080Smckusick case O_ADD82: 6032080Smckusick pc.cp++; 6042080Smckusick td = pop8(); 6052080Smckusick push8(pop2() + td); 6062080Smckusick continue; 6072080Smckusick case O_ADD84: 6082080Smckusick pc.cp++; 6092080Smckusick td = pop8(); 6102080Smckusick push8(pop4() + td); 6112080Smckusick continue; 6122080Smckusick case O_SUB2: 6132080Smckusick pc.cp++; 6142080Smckusick tl = pop2(); 6152080Smckusick push4(pop2() - tl); 6162080Smckusick continue; 6172080Smckusick case O_SUB4: 6182080Smckusick pc.cp++; 6192080Smckusick tl = pop4(); 6202080Smckusick push4(pop4() - tl); 6212080Smckusick continue; 6222080Smckusick case O_SUB24: 6232080Smckusick pc.cp++; 6242080Smckusick tl = pop2(); 6252080Smckusick push4(pop4() - tl); 6262080Smckusick continue; 6272080Smckusick case O_SUB42: 6282080Smckusick pc.cp++; 6292080Smckusick tl = pop4(); 6302080Smckusick push4(pop2() - tl); 6312080Smckusick continue; 6322080Smckusick case O_SUB28: 6332080Smckusick pc.cp++; 6342080Smckusick tl = pop2(); 6352080Smckusick push8(pop8() - tl); 6362080Smckusick continue; 6372080Smckusick case O_SUB48: 6382080Smckusick pc.cp++; 6392080Smckusick tl = pop4(); 6402080Smckusick push8(pop8() - tl); 6412080Smckusick continue; 6422080Smckusick case O_SUB82: 6432080Smckusick pc.cp++; 6442080Smckusick td = pop8(); 6452080Smckusick push8(pop2() - td); 6462080Smckusick continue; 6472080Smckusick case O_SUB84: 6482080Smckusick pc.cp++; 6492080Smckusick td = pop8(); 6502080Smckusick push8(pop4() - td); 6512080Smckusick continue; 6522080Smckusick case O_MUL2: 6532080Smckusick pc.cp++; 6542080Smckusick push4(pop2() * pop2()); 6552080Smckusick continue; 6562080Smckusick case O_MUL4: 6572080Smckusick pc.cp++; 6582080Smckusick push4(pop4() * pop4()); 6592080Smckusick continue; 6602080Smckusick case O_MUL24: 6612080Smckusick pc.cp++; 6622080Smckusick tl = pop2(); 6632080Smckusick push4(pop4() * tl); 6642080Smckusick continue; 6652080Smckusick case O_MUL42: 6662080Smckusick pc.cp++; 6672080Smckusick tl = pop4(); 6682080Smckusick push4(pop2() * tl); 6692080Smckusick continue; 6702080Smckusick case O_MUL28: 6712080Smckusick pc.cp++; 6722080Smckusick tl = pop2(); 6732080Smckusick push8(pop8() * tl); 6742080Smckusick continue; 6752080Smckusick case O_MUL48: 6762080Smckusick pc.cp++; 6772080Smckusick tl = pop4(); 6782080Smckusick push8(pop8() * tl); 6792080Smckusick continue; 6802080Smckusick case O_MUL82: 6812080Smckusick pc.cp++; 6822080Smckusick td = pop8(); 6832080Smckusick push8(pop2() * td); 6842080Smckusick continue; 6852080Smckusick case O_MUL84: 6862080Smckusick pc.cp++; 6872080Smckusick td = pop8(); 6882080Smckusick push8(pop4() * td); 6892080Smckusick continue; 6902080Smckusick case O_ABS2: 6912080Smckusick case O_ABS4: 6922080Smckusick pc.cp++; 6932080Smckusick tl = pop4(); 6942080Smckusick push4(tl >= 0 ? tl : -tl); 6952080Smckusick continue; 6962080Smckusick case O_ABS8: 6972080Smckusick pc.cp++; 6982080Smckusick td = pop8(); 6992080Smckusick push8(td >= 0.0 ? td : -td); 7002080Smckusick continue; 7012080Smckusick case O_NEG2: 7022080Smckusick pc.cp++; 7032080Smckusick push4(-pop2()); 7042080Smckusick continue; 7052080Smckusick case O_NEG4: 7062080Smckusick pc.cp++; 7072080Smckusick push4(-pop4()); 7082080Smckusick continue; 7092080Smckusick case O_NEG8: 7102080Smckusick pc.cp++; 7112080Smckusick push8(-pop8()); 7122080Smckusick continue; 7132080Smckusick case O_DIV2: 7142080Smckusick pc.cp++; 7152080Smckusick tl = pop2(); 7162080Smckusick push4(pop2() / tl); 7172080Smckusick continue; 7182080Smckusick case O_DIV4: 7192080Smckusick pc.cp++; 7202080Smckusick tl = pop4(); 7212080Smckusick push4(pop4() / tl); 7222080Smckusick continue; 7232080Smckusick case O_DIV24: 7242080Smckusick pc.cp++; 7252080Smckusick tl = pop2(); 7262080Smckusick push4(pop4() / tl); 7272080Smckusick continue; 7282080Smckusick case O_DIV42: 7292080Smckusick pc.cp++; 7302080Smckusick tl = pop4(); 7312080Smckusick push4(pop2() / tl); 7322080Smckusick continue; 7332080Smckusick case O_MOD2: 7342080Smckusick pc.cp++; 7352080Smckusick tl = pop2(); 7362080Smckusick push4(pop2() % tl); 7372080Smckusick continue; 7382080Smckusick case O_MOD4: 7392080Smckusick pc.cp++; 7402080Smckusick tl = pop4(); 7412080Smckusick push4(pop4() % tl); 7422080Smckusick continue; 7432080Smckusick case O_MOD24: 7442080Smckusick pc.cp++; 7452080Smckusick tl = pop2(); 7462080Smckusick push4(pop4() % tl); 7472080Smckusick continue; 7482080Smckusick case O_MOD42: 7492080Smckusick pc.cp++; 7502080Smckusick tl = pop4(); 7512080Smckusick push4(pop2() % tl); 7522080Smckusick continue; 7532080Smckusick case O_ADD8: 7542080Smckusick pc.cp++; 7552080Smckusick push8(pop8() + pop8()); 7562080Smckusick continue; 7572080Smckusick case O_SUB8: 7582080Smckusick pc.cp++; 7592080Smckusick td = pop8(); 7602080Smckusick push8(pop8() - td); 7612080Smckusick continue; 7622080Smckusick case O_MUL8: 7632080Smckusick pc.cp++; 7642080Smckusick push8(pop8() * pop8()); 7652080Smckusick continue; 7662080Smckusick case O_DVD8: 7672080Smckusick pc.cp++; 7682080Smckusick td = pop8(); 7692080Smckusick push8(pop8() / td); 7702080Smckusick continue; 7712080Smckusick case O_STOI: 7722080Smckusick pc.cp++; 7732080Smckusick push4(pop2()); 7742080Smckusick continue; 7752080Smckusick case O_STOD: 7762080Smckusick pc.cp++; 7772080Smckusick td = pop2(); 7782080Smckusick push8(td); 7792080Smckusick continue; 7802080Smckusick case O_ITOD: 7812080Smckusick pc.cp++; 7822080Smckusick td = pop4(); 7832080Smckusick push8(td); 7842080Smckusick continue; 7852080Smckusick case O_ITOS: 7862080Smckusick pc.cp++; 7872080Smckusick push2(pop4()); 7882080Smckusick continue; 7892080Smckusick case O_DVD2: 7902080Smckusick pc.cp++; 7912080Smckusick td = pop2(); 7922080Smckusick push8(pop2() / td); 7932080Smckusick continue; 7942080Smckusick case O_DVD4: 7952080Smckusick pc.cp++; 7962080Smckusick td = pop4(); 7972080Smckusick push8(pop4() / td); 7982080Smckusick continue; 7992080Smckusick case O_DVD24: 8002080Smckusick pc.cp++; 8012080Smckusick td = pop2(); 8022080Smckusick push8(pop4() / td); 8032080Smckusick continue; 8042080Smckusick case O_DVD42: 8052080Smckusick pc.cp++; 8062080Smckusick td = pop4(); 8072080Smckusick push8(pop2() / td); 8082080Smckusick continue; 8092080Smckusick case O_DVD28: 8102080Smckusick pc.cp++; 8112080Smckusick td = pop2(); 8122080Smckusick push8(pop8() / td); 8132080Smckusick continue; 8142080Smckusick case O_DVD48: 8152080Smckusick pc.cp++; 8162080Smckusick td = pop4(); 8172080Smckusick push8(pop8() / td); 8182080Smckusick continue; 8192080Smckusick case O_DVD82: 8202080Smckusick pc.cp++; 8212080Smckusick td = pop8(); 8222080Smckusick push8(pop2() / td); 8232080Smckusick continue; 8242080Smckusick case O_DVD84: 8252080Smckusick pc.cp++; 8262080Smckusick td = pop8(); 8272080Smckusick push8(pop4() / td); 8282080Smckusick continue; 8292080Smckusick case O_RV1: 8302109Smckusic tcp = _display.raw[*pc.ucp++]; 8312080Smckusick push2(*(tcp + *pc.sp++)); 8322080Smckusick continue; 8332080Smckusick case O_RV14: 8342109Smckusic tcp = _display.raw[*pc.ucp++]; 8352080Smckusick push4(*(tcp + *pc.sp++)); 8362080Smckusick continue; 8372080Smckusick case O_RV2: 8382109Smckusic tcp = _display.raw[*pc.ucp++]; 8392080Smckusick push2(*(short *)(tcp + *pc.sp++)); 8402080Smckusick continue; 8412080Smckusick case O_RV24: 8422109Smckusic tcp = _display.raw[*pc.ucp++]; 8432080Smckusick push4(*(short *)(tcp + *pc.sp++)); 8442080Smckusick continue; 8452080Smckusick case O_RV4: 8462109Smckusic tcp = _display.raw[*pc.ucp++]; 8472080Smckusick push4(*(long *)(tcp + *pc.sp++)); 8482080Smckusick continue; 8492080Smckusick case O_RV8: 8502109Smckusic tcp = _display.raw[*pc.ucp++]; 851*2239Smckusic pushsze8(*(struct sze8 *)(tcp + *pc.sp++)); 8522080Smckusick continue; 8532080Smckusick case O_RV: 8542109Smckusic tcp = _display.raw[*pc.ucp++]; 8552080Smckusick tcp += *pc.sp++; 8562080Smckusick tl = *pc.usp++; 8572080Smckusick tcp1 = pushsp(tl); 8582080Smckusick blkcpy(tl, tcp, tcp1); 8592080Smckusick continue; 8602080Smckusick case O_LV: 8612109Smckusic tcp = _display.raw[*pc.ucp++]; 8622080Smckusick pushaddr(tcp + *pc.sp++); 8632080Smckusick continue; 8642080Smckusick case O_LRV1: 8652109Smckusic tcp = _display.raw[*pc.ucp++]; 8662080Smckusick push2(*(tcp + *pc.lp++)); 8672080Smckusick continue; 8682080Smckusick case O_LRV14: 8692109Smckusic tcp = _display.raw[*pc.ucp++]; 8702080Smckusick push4(*(tcp + *pc.lp++)); 8712080Smckusick continue; 8722080Smckusick case O_LRV2: 8732109Smckusic tcp = _display.raw[*pc.ucp++]; 8742080Smckusick push2(*(short *)(tcp + *pc.lp++)); 8752080Smckusick continue; 8762080Smckusick case O_LRV24: 8772109Smckusic tcp = _display.raw[*pc.ucp++]; 8782080Smckusick push4(*(short *)(tcp + *pc.lp++)); 8792080Smckusick continue; 8802080Smckusick case O_LRV4: 8812109Smckusic tcp = _display.raw[*pc.ucp++]; 8822080Smckusick push4(*(long *)(tcp + *pc.lp++)); 8832080Smckusick continue; 8842080Smckusick case O_LRV8: 8852109Smckusic tcp = _display.raw[*pc.ucp++]; 886*2239Smckusic pushsze8(*(struct sze8 *)(tcp + *pc.lp++)); 8872080Smckusick continue; 8882080Smckusick case O_LRV: 8892109Smckusic tcp = _display.raw[*pc.ucp++]; 8902080Smckusick tcp += *pc.lp++; 8912080Smckusick tl = *pc.usp++; 8922080Smckusick tcp1 = pushsp(tl); 8932080Smckusick blkcpy(tl, tcp, tcp1); 8942080Smckusick continue; 8952080Smckusick case O_LLV: 8962109Smckusic tcp = _display.raw[*pc.ucp++]; 8972080Smckusick pushaddr(tcp + *pc.lp++); 8982080Smckusick continue; 8992080Smckusick case O_IND1: 9002080Smckusick pc.cp++; 9012080Smckusick push2(*popaddr()); 9022080Smckusick continue; 9032080Smckusick case O_IND14: 9042080Smckusick pc.cp++; 9052080Smckusick push4(*popaddr()); 9062080Smckusick continue; 9072080Smckusick case O_IND2: 9082080Smckusick pc.cp++; 9092080Smckusick push2(*(short *)(popaddr())); 9102080Smckusick continue; 9112080Smckusick case O_IND24: 9122080Smckusick pc.cp++; 9132080Smckusick push4(*(short *)(popaddr())); 9142080Smckusick continue; 9152080Smckusick case O_IND4: 9162080Smckusick pc.cp++; 9172080Smckusick push4(*(long *)(popaddr())); 9182080Smckusick continue; 9192080Smckusick case O_IND8: 9202080Smckusick pc.cp++; 921*2239Smckusic pushsze8(*(struct sze8 *)(popaddr())); 9222080Smckusick continue; 9232080Smckusick case O_IND: 9242080Smckusick tl = *pc.cp++; 9252080Smckusick if (tl == 0) 9262080Smckusick tl = *pc.usp++; 9272080Smckusick tcp = popaddr(); 9282080Smckusick tcp1 = pushsp((tl + 1) & ~1); 9292080Smckusick blkcpy(tl, tcp, tcp1); 9302080Smckusick continue; 9312080Smckusick case O_CON1: 9322080Smckusick push2(*pc.cp++); 9332080Smckusick continue; 9342080Smckusick case O_CON14: 9352080Smckusick push4(*pc.cp++); 9362080Smckusick continue; 9372080Smckusick case O_CON2: 9382080Smckusick pc.cp++; 9392080Smckusick push2(*pc.sp++); 9402080Smckusick continue; 9412080Smckusick case O_CON24: 9422080Smckusick pc.cp++; 9432080Smckusick push4(*pc.sp++); 9442080Smckusick continue; 9452080Smckusick case O_CON4: 9462080Smckusick pc.cp++; 9472080Smckusick push4(*pc.lp++); 9482080Smckusick continue; 9492080Smckusick case O_CON8: 9502080Smckusick pc.cp++; 9512080Smckusick push8(*pc.dp++); 9522080Smckusick continue; 9532080Smckusick case O_CON: 9542080Smckusick tl = *pc.cp++; 9552080Smckusick if (tl == 0) 9562080Smckusick tl = *pc.usp++; 9572080Smckusick tl = (tl + 1) & ~1; 9582080Smckusick tcp = pushsp(tl); 9592080Smckusick blkcpy(tl, pc.cp, tcp); 9602080Smckusick pc.cp += tl; 9612080Smckusick continue; 9622080Smckusick case O_LVCON: 9632080Smckusick tl = *pc.cp++; 9642080Smckusick if (tl == 0) 9652080Smckusick tl = *pc.usp++; 9662080Smckusick tl = (tl + 1) & ~1; 9672080Smckusick pushaddr(pc.cp); 9682080Smckusick pc.cp += tl; 9692080Smckusick continue; 9702080Smckusick case O_RANG2: 9712080Smckusick tl = *pc.cp++; 9722080Smckusick if (tl == 0) 9732080Smckusick tl = *pc.sp++; 9742080Smckusick tl1 = pop2(); 9752080Smckusick push2(RANG4(tl1, tl, *pc.sp++)); 9762080Smckusick continue; 9772080Smckusick case O_RANG42: 9782080Smckusick tl = *pc.cp++; 9792080Smckusick if (tl == 0) 9802080Smckusick tl = *pc.sp++; 9812080Smckusick tl1 = pop4(); 9822080Smckusick push4(RANG4(tl1, tl, *pc.sp++)); 9832080Smckusick continue; 9842080Smckusick case O_RSNG2: 9852080Smckusick tl = *pc.cp++; 9862080Smckusick if (tl == 0) 9872080Smckusick tl = *pc.sp++; 9882080Smckusick tl1 = pop2(); 9892080Smckusick push2(RSNG4(tl1, tl)); 9902080Smckusick continue; 9912080Smckusick case O_RSNG42: 9922080Smckusick tl = *pc.cp++; 9932080Smckusick if (tl == 0) 9942080Smckusick tl = *pc.sp++; 9952080Smckusick tl1 = pop4(); 9962080Smckusick push4(RSNG4(tl1, tl)); 9972080Smckusick continue; 9982080Smckusick case O_RANG4: 9992080Smckusick pc.cp++; 10002080Smckusick tl = *pc.lp++; 10012080Smckusick tl1 = pop4(); 10022080Smckusick push4(RANG4(tl1, tl, *pc.lp++)); 10032080Smckusick continue; 10042080Smckusick case O_RANG24: 10052080Smckusick pc.cp++; 10062080Smckusick tl = *pc.lp++; 10072080Smckusick tl1 = pop2(); 10082080Smckusick push2(RANG4(tl1, tl, *pc.lp++)); 10092080Smckusick continue; 10102080Smckusick case O_RSNG4: 10112080Smckusick pc.cp++; 10122080Smckusick tl = pop4(); 10132080Smckusick push4(RSNG4(tl, *pc.lp++)); 10142080Smckusick continue; 10152080Smckusick case O_RSNG24: 10162080Smckusick pc.cp++; 10172080Smckusick tl = pop2(); 10182080Smckusick push2(RSNG4(tl, *pc.lp++)); 10192080Smckusick continue; 10202080Smckusick case O_STLIM: 10212080Smckusick pc.cp++; 10222121Smckusic STLIM(); 10232121Smckusic popargs(1); 10242080Smckusick continue; 10252080Smckusick case O_LLIMIT: 10262080Smckusick pc.cp++; 10272080Smckusick LLIMIT(); 10282080Smckusick popargs(2); 10292080Smckusick continue; 10302080Smckusick case O_BUFF: 10312080Smckusick BUFF(*pc.cp++); 10322080Smckusick continue; 10332080Smckusick case O_HALT: 10342080Smckusick pc.cp++; 10352080Smckusick panic(PHALT); 10362080Smckusick continue; 10372080Smckusick case O_PXPBUF: 10382080Smckusick pc.cp++; 10392080Smckusick _cntrs = *pc.lp++; 10402080Smckusick _rtns = *pc.lp++; 10412080Smckusick _pcpcount = (long *)calloc(_cntrs + 1, sizeof(long)); 10422080Smckusick continue; 10432080Smckusick case O_COUNT: 10442080Smckusick pc.cp++; 10452080Smckusick _pcpcount[*pc.usp++]++; 10462080Smckusick continue; 10472080Smckusick case O_CASE1OP: 10482080Smckusick tl = *pc.cp++; /* tl = number of cases */ 10492080Smckusick if (tl == 0) 10502080Smckusick tl = *pc.usp++; 10512080Smckusick tsp = pc.sp + tl; /* ptr to end of jump table */ 10522080Smckusick tcp = (char *)tsp; /* tcp = ptr to case values */ 10532080Smckusick tl1 = pop2(); /* tl1 = element to find */ 10542080Smckusick for(; tl > 0; tl--) /* look for element */ 10552080Smckusick if (tl1 == *tcp++) 10562080Smckusick break; 10572080Smckusick if (tl == 0) /* default case => error */ 10582231Smckusic ERROR(ECASE, tl1); 10592080Smckusick pc.cp += *(tsp - tl); 10602080Smckusick continue; 10612080Smckusick case O_CASE2OP: 10622080Smckusick tl = *pc.cp++; /* tl = number of cases */ 10632080Smckusick if (tl == 0) 10642080Smckusick tl = *pc.usp++; 10652080Smckusick tsp = pc.sp + tl; /* ptr to end of jump table */ 10662080Smckusick tsp1 = tsp; /* tsp1 = ptr to case values */ 10672080Smckusick tl1 = (unsigned short)pop2();/* tl1 = element to find */ 10682080Smckusick for(; tl > 0; tl--) /* look for element */ 10692080Smckusick if (tl1 == *tsp1++) 10702080Smckusick break; 10712080Smckusick if (tl == 0) /* default case => error */ 10722231Smckusic ERROR(ECASE, tl1); 10732080Smckusick pc.cp += *(tsp - tl); 10742080Smckusick continue; 10752080Smckusick case O_CASE4OP: 10762080Smckusick tl = *pc.cp++; /* tl = number of cases */ 10772080Smckusick if (tl == 0) 10782080Smckusick tl = *pc.usp++; 10792080Smckusick tsp = pc.sp + tl; /* ptr to end of jump table */ 10802080Smckusick tlp = (long *)tsp; /* tlp = ptr to case values */ 10812080Smckusick tl1 = pop4(); /* tl1 = element to find */ 10822080Smckusick for(; tl > 0; tl--) /* look for element */ 10832080Smckusick if (tl1 == *tlp++) 10842080Smckusick break; 10852080Smckusick if (tl == 0) /* default case => error */ 10862231Smckusic ERROR(ECASE, tl1); 10872080Smckusick pc.cp += *(tsp - tl); 10882080Smckusick continue; 10892080Smckusick case O_ADDT: 10902080Smckusick tl = *pc.cp++; /* tl has comparison length */ 10912080Smckusick if (tl == 0) 10922080Smckusick tl = *pc.usp++; 10932080Smckusick tcp = pushsp(0); /* tcp pts to first arg */ 10942080Smckusick ADDT(tcp + tl, tcp + tl, tcp, tl >> 2); 10952080Smckusick popsp(tl); 10962080Smckusick continue; 10972080Smckusick case O_SUBT: 10982080Smckusick tl = *pc.cp++; /* tl has comparison length */ 10992080Smckusick if (tl == 0) 11002080Smckusick tl = *pc.usp++; 11012080Smckusick tcp = pushsp(0); /* tcp pts to first arg */ 11022080Smckusick SUBT(tcp + tl, tcp + tl, tcp, tl >> 2); 11032080Smckusick popsp(tl); 11042080Smckusick continue; 11052080Smckusick case O_MULT: 11062080Smckusick tl = *pc.cp++; /* tl has comparison length */ 11072080Smckusick if (tl == 0) 11082080Smckusick tl = *pc.usp++; 11092080Smckusick tcp = pushsp(0); /* tcp pts to first arg */ 11102080Smckusick MULT(tcp + tl, tcp + tl, tcp, tl >> 2); 11112080Smckusick popsp(tl); 11122080Smckusick continue; 11132080Smckusick case O_INCT: 11142080Smckusick tl = *pc.cp++; /* tl has number of args */ 11152080Smckusick if (tl == 0) 11162080Smckusick tl = *pc.usp++; 11172080Smckusick tl1 = INCT(); 11182080Smckusick popargs(tl); 11192080Smckusick push2(tl1); 11202080Smckusick continue; 11212080Smckusick case O_CTTOT: 11222080Smckusick tl = *pc.cp++; /* tl has number of args */ 11232080Smckusick if (tl == 0) 11242080Smckusick tl = *pc.usp++; 11252080Smckusick tl1 = tl * sizeof(long); 11262080Smckusick tcp = pushsp(0) + tl1; /* tcp pts to result space */ 11272080Smckusick CTTOT(tcp); 11282080Smckusick popargs(tl); 11292080Smckusick continue; 11302080Smckusick case O_CARD: 11312080Smckusick tl = *pc.cp++; /* tl has comparison length */ 11322080Smckusick if (tl == 0) 11332080Smckusick tl = *pc.usp++; 11342080Smckusick tcp = pushsp(0); /* tcp pts to set */ 11352080Smckusick tl1 = CARD(tcp, tl); 11362080Smckusick popsp(tl); 11372080Smckusick push2(tl1); 11382080Smckusick continue; 11392080Smckusick case O_IN: 11402080Smckusick tl = *pc.cp++; /* tl has comparison length */ 11412080Smckusick if (tl == 0) 11422080Smckusick tl = *pc.usp++; 11432080Smckusick tl1 = pop4(); /* tl1 is the element */ 11442080Smckusick tcp = pushsp(0); /* tcp pts to set */ 11452080Smckusick tl2 = *pc.usp++; /* lower bound */ 11462080Smckusick tl1 = IN(tl1, tl2, *pc.usp++, tcp); 11472080Smckusick popsp(tl); 11482080Smckusick push2(tl1); 11492080Smckusick continue; 11502080Smckusick case O_ASRT: 11512080Smckusick pc.cp++; 11522109Smckusic ASRT(pop2(), ""); 11532080Smckusick continue; 11542080Smckusick case O_FOR1U: 11552080Smckusick pc.cp++; 11562080Smckusick tcp = (char *)pop4(); /* tcp = ptr to index var */ 11572080Smckusick if (*tcp < pop4()) { /* still going up */ 11582191Smckusic tl = *tcp + 1; /* inc index var */ 11592191Smckusic tl1 = *pc.sp++; /* index lower bound */ 11602191Smckusic tl2 = *pc.sp++; /* index upper bound */ 11612191Smckusic if (_runtst) 11622191Smckusic RANG4(tl, tl1, tl2); 11632191Smckusic *tcp = tl; /* update index var */ 11642080Smckusick pc.cp += *pc.sp;/* return to top of loop */ 11652080Smckusick continue; 11662080Smckusick } 11672191Smckusic pc.sp += 3; /* else fall through */ 11682080Smckusick continue; 11692080Smckusick case O_FOR2U: 11702080Smckusick pc.cp++; 11712080Smckusick tsp = (short *)pop4(); /* tsp = ptr to index var */ 11722080Smckusick if (*tsp < pop4()) { /* still going up */ 11732191Smckusic tl = *tsp + 1; /* inc index var */ 11742191Smckusic tl1 = *pc.sp++; /* index lower bound */ 11752191Smckusic tl2 = *pc.sp++; /* index upper bound */ 11762191Smckusic if (_runtst) 11772191Smckusic RANG4(tl, tl1, tl2); 11782191Smckusic *tsp = tl; /* update index var */ 11792080Smckusick pc.cp += *pc.sp;/* return to top of loop */ 11802080Smckusick continue; 11812080Smckusick } 11822191Smckusic pc.sp += 3; /* else fall through */ 11832080Smckusick continue; 11842080Smckusick case O_FOR4U: 11852080Smckusick pc.cp++; 11862080Smckusick tlp = (long *)pop4(); /* tlp = ptr to index var */ 11872080Smckusick if (*tlp < pop4()) { /* still going up */ 11882191Smckusic tl = *tlp + 1; /* inc index var */ 11892191Smckusic tl1 = *pc.lp++; /* index lower bound */ 11902191Smckusic tl2 = *pc.lp++; /* index upper bound */ 11912191Smckusic if (_runtst) 11922191Smckusic RANG4(tl, tl1, tl2); 11932191Smckusic *tlp = tl; /* update index var */ 11942080Smckusick pc.cp += *pc.sp;/* return to top of loop */ 11952080Smckusick continue; 11962080Smckusick } 11972191Smckusic pc.sp += 5; /* else fall through */ 11982080Smckusick continue; 11992080Smckusick case O_FOR1D: 12002080Smckusick pc.cp++; 12012080Smckusick tcp = (char *)pop4(); /* tcp = ptr to index var */ 12022080Smckusick if (*tcp > pop4()) { /* still going down */ 12032191Smckusic tl = *tcp - 1; /* inc index var */ 12042191Smckusic tl1 = *pc.sp++; /* index lower bound */ 12052191Smckusic tl2 = *pc.sp++; /* index upper bound */ 12062191Smckusic if (_runtst) 12072191Smckusic RANG4(tl, tl1, tl2); 12082191Smckusic *tcp = tl; /* update index var */ 12092080Smckusick pc.cp += *pc.sp;/* return to top of loop */ 12102080Smckusick continue; 12112080Smckusick } 12122191Smckusic pc.sp += 3; /* else fall through */ 12132080Smckusick continue; 12142080Smckusick case O_FOR2D: 12152080Smckusick pc.cp++; 12162080Smckusick tsp = (short *)pop4(); /* tsp = ptr to index var */ 12172080Smckusick if (*tsp > pop4()) { /* still going down */ 12182191Smckusic tl = *tsp - 1; /* inc index var */ 12192191Smckusic tl1 = *pc.sp++; /* index lower bound */ 12202191Smckusic tl2 = *pc.sp++; /* index upper bound */ 12212191Smckusic if (_runtst) 12222191Smckusic RANG4(tl, tl1, tl2); 12232191Smckusic *tsp = tl; /* update index var */ 12242080Smckusick pc.cp += *pc.sp;/* return to top of loop */ 12252080Smckusick continue; 12262080Smckusick } 12272191Smckusic pc.sp += 3; /* else fall through */ 12282080Smckusick continue; 12292080Smckusick case O_FOR4D: 12302080Smckusick pc.cp++; 12312080Smckusick tlp = (long *)pop4(); /* tlp = ptr to index var */ 12322080Smckusick if (*tlp > pop4()) { /* still going down */ 12332191Smckusic tl = *tlp - 1; /* inc index var */ 12342191Smckusic tl1 = *pc.lp++; /* index lower bound */ 12352191Smckusic tl2 = *pc.lp++; /* index upper bound */ 12362191Smckusic if (_runtst) 12372191Smckusic RANG4(tl, tl1, tl2); 12382191Smckusic *tlp = tl; /* update index var */ 12392080Smckusick pc.cp += *pc.sp;/* return to top of loop */ 12402080Smckusick continue; 12412080Smckusick } 12422191Smckusic pc.sp += 5; /* else fall through */ 12432080Smckusick continue; 12442080Smckusick case O_READE: 12452080Smckusick pc.cp++; 12462080Smckusick push2(READE(curfile, base + *pc.lp++)); 12472080Smckusick continue; 12482080Smckusick case O_READ4: 12492080Smckusick pc.cp++; 12502080Smckusick push4(READ4(curfile)); 12512080Smckusick continue; 12522080Smckusick case O_READC: 12532080Smckusick pc.cp++; 12542080Smckusick push2(READC(curfile)); 12552080Smckusick continue; 12562080Smckusick case O_READ8: 12572080Smckusick pc.cp++; 12582080Smckusick push8(READ8(curfile)); 12592080Smckusick continue; 12602080Smckusick case O_READLN: 12612080Smckusick pc.cp++; 12622080Smckusick READLN(curfile); 12632080Smckusick continue; 12642080Smckusick case O_EOF: 12652080Smckusick pc.cp++; 12662080Smckusick push2(TEOF(popaddr())); 12672080Smckusick continue; 12682080Smckusick case O_EOLN: 12692080Smckusick pc.cp++; 12702080Smckusick push2(TEOLN(popaddr())); 12712080Smckusick continue; 12722080Smckusick case O_WRITEC: 12732080Smckusick pc.cp++; 12742191Smckusic if (_runtst) { 12752191Smckusic WRITEC(curfile); 12762191Smckusic popargs(2); 12772191Smckusic continue; 12782191Smckusic } 12792191Smckusic fputc(); 12802080Smckusick popargs(2); 12812080Smckusick continue; 12822080Smckusick case O_WRITES: 12832080Smckusick pc.cp++; 12842191Smckusic if (_runtst) { 12852191Smckusic WRITES(curfile); 12862191Smckusic popargs(4); 12872191Smckusic continue; 12882191Smckusic } 12892191Smckusic fwrite(); 12902080Smckusick popargs(4); 12912080Smckusick continue; 12922080Smckusick case O_WRITEF: 12932191Smckusic if (_runtst) { 12942191Smckusic WRITEF(curfile); 12952191Smckusic popargs(*pc.cp++); 12962191Smckusic continue; 12972191Smckusic } 12982191Smckusic fprintf(); 12992080Smckusick popargs(*pc.cp++); 13002080Smckusick continue; 13012080Smckusick case O_WRITLN: 13022080Smckusick pc.cp++; 13032191Smckusic if (_runtst) { 13042191Smckusic WRITLN(curfile); 13052191Smckusic continue; 13062191Smckusic } 13072191Smckusic fputc('\n', ACTFILE(curfile)); 13082080Smckusick continue; 13092080Smckusick case O_PAGE: 13102080Smckusick pc.cp++; 13112191Smckusic if (_runtst) { 13122191Smckusic PAGE(curfile); 13132191Smckusic continue; 13142191Smckusic } 13152191Smckusic fputc('^L', ACTFILE(curfile)); 13162080Smckusick continue; 13172080Smckusick case O_NAM: 13182080Smckusick pc.cp++; 13192080Smckusick tl = pop4(); 13202080Smckusick pushaddr(NAM(tl, base + *pc.lp++)); 13212080Smckusick continue; 13222080Smckusick case O_MAX: 13232080Smckusick tl = *pc.cp++; 13242080Smckusick if (tl == 0) 13252080Smckusick tl = *pc.usp++; 13262080Smckusick tl1 = pop4(); 13272191Smckusic if (_runtst) { 13282191Smckusic push4(MAX(tl1, tl, *pc.usp++)); 13292191Smckusic continue; 13302191Smckusic } 13312191Smckusic tl1 -= tl; 13322191Smckusic tl = *pc.usp++; 13332191Smckusic push4(tl1 > tl ? tl1 : tl); 13342080Smckusick continue; 13352080Smckusick case O_MIN: 13362080Smckusick tl = *pc.cp++; 13372080Smckusick if (tl == 0) 13382080Smckusick tl = *pc.usp++; 13392080Smckusick tl1 = pop4(); 13402080Smckusick push4(tl1 < tl ? tl1 : tl); 13412080Smckusick continue; 13422080Smckusick case O_UNIT: 13432080Smckusick pc.cp++; 13442080Smckusick curfile = UNIT(popaddr()); 13452080Smckusick continue; 13462080Smckusick case O_UNITINP: 13472080Smckusick pc.cp++; 13482080Smckusick curfile = INPUT; 13492080Smckusick continue; 13502080Smckusick case O_UNITOUT: 13512080Smckusick pc.cp++; 13522080Smckusick curfile = OUTPUT; 13532080Smckusick continue; 13542080Smckusick case O_MESSAGE: 13552080Smckusick pc.cp++; 13562080Smckusick PFLUSH(); 13572080Smckusick curfile = ERR; 13582080Smckusick continue; 13592109Smckusic case O_PUT: 13602109Smckusic pc.cp++; 13612109Smckusic PUT(curfile); 13622109Smckusic continue; 13632080Smckusick case O_GET: 13642080Smckusick pc.cp++; 13652080Smckusick GET(curfile); 13662080Smckusick continue; 13672080Smckusick case O_FNIL: 13682080Smckusick pc.cp++; 13692080Smckusick pushaddr(FNIL(popaddr())); 13702080Smckusick continue; 13712080Smckusick case O_DEFNAME: 13722080Smckusick pc.cp++; 13732080Smckusick DEFNAME(); 13742080Smckusick popargs(4); 13752080Smckusick continue; 13762080Smckusick case O_RESET: 13772080Smckusick pc.cp++; 13782080Smckusick RESET(); 13792080Smckusick popargs(4); 13802080Smckusick continue; 13812080Smckusick case O_REWRITE: 13822080Smckusick pc.cp++; 13832080Smckusick REWRITE(); 13842080Smckusick popargs(4); 13852080Smckusick continue; 13862080Smckusick case O_FILE: 13872080Smckusick pc.cp++; 13882080Smckusick pushaddr(ACTFILE(curfile)); 13892080Smckusick continue; 13902080Smckusick case O_REMOVE: 13912080Smckusick pc.cp++; 13922080Smckusick REMOVE(); 13932080Smckusick popargs(2); 13942080Smckusick continue; 13952080Smckusick case O_FLUSH: 13962080Smckusick pc.cp++; 13972080Smckusick FLUSH(); 13982080Smckusick popargs(1); 13992080Smckusick continue; 14002080Smckusick case O_PACK: 14012080Smckusick pc.cp++; 14022080Smckusick PACK(); 14032080Smckusick popargs(7); 14042080Smckusick continue; 14052080Smckusick case O_UNPACK: 14062080Smckusick pc.cp++; 14072080Smckusick UNPACK(); 14082080Smckusick popargs(7); 14092080Smckusick continue; 14102080Smckusick case O_ARGC: 14112080Smckusick pc.cp++; 14122080Smckusick push4(_argc); 14132080Smckusick continue; 14142080Smckusick case O_ARGV: 14152080Smckusick tl = *pc.cp++; /* tl = size of char array */ 14162080Smckusick if (tl == 0) 14172080Smckusick tl = *pc.usp++; 14182080Smckusick tcp = popaddr(); /* tcp = addr of char array */ 14192080Smckusick tl1 = pop4(); /* tl1 = argv subscript */ 14202080Smckusick ARGV(tl1, tcp, tl); 14212080Smckusick continue; 14222080Smckusick case O_CLCK: 14232080Smckusick pc.cp++; 14242080Smckusick push4(CLCK()); 14252080Smckusick continue; 14262080Smckusick case O_WCLCK: 14272080Smckusick pc.cp++; 14282080Smckusick push4(time(0)); 14292080Smckusick continue; 14302080Smckusick case O_SCLCK: 14312080Smckusick pc.cp++; 14322080Smckusick push4(SCLCK()); 14332080Smckusick continue; 14342080Smckusick case O_DISPOSE: 14352080Smckusick tl = *pc.cp++; /* tl = size being disposed */ 14362080Smckusick if (tl == 0) 14372080Smckusick tl = *pc.usp++; 14382080Smckusick tcp = popaddr(); /* ptr to ptr being disposed */ 14392080Smckusick DISPOSE(tcp, tl); 14402080Smckusick *(char **)tcp = (char *)0; 14412080Smckusick continue; 14422080Smckusick case O_NEW: 14432080Smckusick tl = *pc.cp++; /* tl = size being new'ed */ 14442080Smckusick if (tl == 0) 14452080Smckusick tl = *pc.usp++; 14462080Smckusick tcp = popaddr(); /* ptr to ptr being new'ed */ 14472191Smckusic if (_runtst) { 14482191Smckusic NEWZ(tcp, tl); 14492191Smckusic continue; 14502191Smckusic } 14512191Smckusic NEW(tcp, tl); 14522080Smckusick continue; 14532080Smckusick case O_DATE: 14542080Smckusick pc.cp++; 14552080Smckusick DATE(popaddr()); 14562080Smckusick continue; 14572080Smckusick case O_TIME: 14582080Smckusick pc.cp++; 14592080Smckusick TIME(popaddr()); 14602080Smckusick continue; 14612080Smckusick case O_UNDEF: 14622080Smckusick pc.cp++; 14632080Smckusick pop8(); 14642080Smckusick push2(0); 14652080Smckusick continue; 14662080Smckusick case O_ATAN: 14672080Smckusick pc.cp++; 14682080Smckusick push8(atan(pop8())); 14692080Smckusick continue; 14702080Smckusick case O_COS: 14712080Smckusick pc.cp++; 14722080Smckusick push8(cos(pop8())); 14732080Smckusick continue; 14742080Smckusick case O_EXP: 14752080Smckusick pc.cp++; 14762080Smckusick push8(exp(pop8())); 14772080Smckusick continue; 14782080Smckusick case O_LN: 14792080Smckusick pc.cp++; 14802191Smckusic if (_runtst) { 14812191Smckusic push8(LN(pop8())); 14822191Smckusic continue; 14832191Smckusic } 14842191Smckusic push8(log(pop8())); 14852080Smckusick continue; 14862080Smckusick case O_SIN: 14872080Smckusick pc.cp++; 14882080Smckusick push8(sin(pop8())); 14892080Smckusick continue; 14902080Smckusick case O_SQRT: 14912080Smckusick pc.cp++; 14922191Smckusic if (_runtst) { 14932191Smckusic push8(SQRT(pop8())); 14942191Smckusic continue; 14952191Smckusic } 14962191Smckusic push8(sqrt(pop8())); 14972080Smckusick continue; 14982080Smckusick case O_CHR2: 14992080Smckusick case O_CHR4: 15002080Smckusick pc.cp++; 15012191Smckusic if (_runtst) { 15022191Smckusic push2(CHR(pop4())); 15032191Smckusic continue; 15042191Smckusic } 15052191Smckusic push2(pop4()); 15062080Smckusick continue; 15072080Smckusick case O_ODD2: 15082080Smckusick case O_ODD4: 15092080Smckusick pc.cp++; 15102080Smckusick push2(pop4() & 1); 15112080Smckusick continue; 15122080Smckusick case O_SUCC2: 15132109Smckusic tl = *pc.cp++; 15142109Smckusic if (tl == 0) 15152109Smckusic tl = *pc.sp++; 15162109Smckusic tl1 = pop4(); 15172191Smckusic if (_runtst) { 15182191Smckusic push2(SUCC(tl1, tl, *pc.sp++)); 15192191Smckusic continue; 15202191Smckusic } 15212191Smckusic push2(tl1 + 1); 15222191Smckusic pc.sp++; 15232080Smckusick continue; 15242080Smckusick case O_SUCC24: 15252109Smckusic tl = *pc.cp++; 15262109Smckusic if (tl == 0) 15272109Smckusic tl = *pc.sp++; 15282109Smckusic tl1 = pop4(); 15292191Smckusic if (_runtst) { 15302191Smckusic push4(SUCC(tl1, tl, *pc.sp++)); 15312191Smckusic continue; 15322191Smckusic } 15332191Smckusic push4(tl1 + 1); 15342191Smckusic pc.sp++; 15352109Smckusic continue; 15362080Smckusick case O_SUCC4: 15372109Smckusic tl = *pc.cp++; 15382109Smckusic if (tl == 0) 15392109Smckusic tl = *pc.lp++; 15402109Smckusic tl1 = pop4(); 15412191Smckusic if (_runtst) { 15422191Smckusic push4(SUCC(tl1, tl, *pc.lp++)); 15432191Smckusic continue; 15442191Smckusic } 15452191Smckusic push4(tl1 + 1); 15462191Smckusic pc.lp++; 15472080Smckusick continue; 15482080Smckusick case O_PRED2: 15492109Smckusic tl = *pc.cp++; 15502109Smckusic if (tl == 0) 15512109Smckusic tl = *pc.sp++; 15522109Smckusic tl1 = pop4(); 15532191Smckusic if (_runtst) { 15542191Smckusic push2(PRED(tl1, tl, *pc.sp++)); 15552191Smckusic continue; 15562191Smckusic } 15572191Smckusic push2(tl1 - 1); 15582191Smckusic pc.sp++; 15592080Smckusick continue; 15602080Smckusick case O_PRED24: 15612109Smckusic tl = *pc.cp++; 15622109Smckusic if (tl == 0) 15632109Smckusic tl = *pc.sp++; 15642109Smckusic tl1 = pop4(); 15652191Smckusic if (_runtst) { 15662191Smckusic push4(PRED(tl1, tl, *pc.sp++)); 15672191Smckusic continue; 15682191Smckusic } 15692191Smckusic push4(tl1 - 1); 15702191Smckusic pc.sp++; 15712109Smckusic continue; 15722080Smckusick case O_PRED4: 15732109Smckusic tl = *pc.cp++; 15742109Smckusic if (tl == 0) 15752109Smckusic tl = *pc.lp++; 15762109Smckusic tl1 = pop4(); 15772191Smckusic if (_runtst) { 15782191Smckusic push4(PRED(tl1, tl, *pc.lp++)); 15792191Smckusic continue; 15802191Smckusic } 15812191Smckusic push4(tl1 - 1); 15822191Smckusic pc.lp++; 15832080Smckusick continue; 15842080Smckusick case O_SEED: 15852080Smckusick pc.cp++; 15862080Smckusick push4(SEED(pop4())); 15872080Smckusick continue; 15882080Smckusick case O_RANDOM: 15892080Smckusick pc.cp++; 15902080Smckusick push8(RANDOM(pop8())); 15912080Smckusick continue; 15922080Smckusick case O_EXPO: 15932080Smckusick pc.cp++; 15942080Smckusick push4(EXPO(pop8())); 15952080Smckusick continue; 15962080Smckusick case O_SQR2: 15972080Smckusick case O_SQR4: 15982080Smckusick pc.cp++; 15992080Smckusick tl = pop4(); 16002080Smckusick push4(tl * tl); 16012080Smckusick continue; 16022080Smckusick case O_SQR8: 16032080Smckusick pc.cp++; 16042080Smckusick td = pop8(); 16052080Smckusick push8(td * td); 16062080Smckusick continue; 16072080Smckusick case O_ROUND: 16082080Smckusick pc.cp++; 16092080Smckusick push4(ROUND(pop8())); 16102080Smckusick continue; 16112080Smckusick case O_TRUNC: 16122080Smckusick pc.cp++; 16132080Smckusick push4(TRUNC(pop8())); 16142080Smckusick continue; 16152080Smckusick } 16162080Smckusick } 16172080Smckusick } 1618