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