align O_RV, run pc2 after /lib/c2
[unix-history] / usr / src / usr.bin / pascal / px / interp.c
index dfc82ef..809d092 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (c) 1979 Regents of the University of California */
 
 /* Copyright (c) 1979 Regents of the University of California */
 
-static char sccsid[] = "@(#)interp.c 1.3 %G%";
+static char sccsid[] = "@(#)interp.c 1.8 %G%";
 
 #include <math.h>
 #include "vars.h"
 
 #include <math.h>
 #include "vars.h"
@@ -19,9 +19,11 @@ long _lino = 0;
 int    _argc;
 char   **_argv;
 long   _mode;
 int    _argc;
 char   **_argv;
 long   _mode;
-long   _nodump;
+long   _runtst = TRUE;
+long   _nodump = FALSE;
 long   _stlim = 500000;
 long   _stcnt = 0;
 long   _stlim = 500000;
 long   _stcnt = 0;
+long   _seed = 1;
 char   *_minptr = (char *)0x7fffffff;
 char   *_maxptr = (char *)0;
 long   *_pcpcount = (long *)0;
 char   *_minptr = (char *)0x7fffffff;
 char   *_maxptr = (char *)0;
 long   *_pcpcount = (long *)0;
@@ -108,17 +110,24 @@ interpreter(base)
        /*
         * the following variables are used as scratch
         */
        /*
         * the following variables are used as scratch
         */
-       double td, td1;
+       register char *tcp;
        register long tl, tl1, tl2;
        register long tl, tl1, tl2;
+       double td, td1;
+       struct sze8 t8;
        long *tlp;
        short *tsp, *tsp1;
        long *tlp;
        short *tsp, *tsp1;
-       register char *tcp;
        char *tcp1;
        struct stack *tstp;
        struct formalrtn *tfp;
        union progcntr tpc;
        struct iorec **ip;
 
        char *tcp1;
        struct stack *tstp;
        struct formalrtn *tfp;
        union progcntr tpc;
        struct iorec **ip;
 
+       /*
+        * Setup sets up any hardware specific parameters before
+        * starting the interpreter. Typically this is inline replaced
+        * by interp.sed to utilize specific machine instructions.
+        */
+        setup();
        /*
         * necessary only on systems which do not initialize
         * memory to zero
        /*
         * necessary only on systems which do not initialize
         * memory to zero
@@ -132,7 +141,6 @@ interpreter(base)
        _display.frame[0].locvars += 8; /* local offsets are negative */
        *(struct iorec **)(_display.frame[0].locvars - 4) = OUTPUT;
        *(struct iorec **)(_display.frame[0].locvars - 8) = INPUT;
        _display.frame[0].locvars += 8; /* local offsets are negative */
        *(struct iorec **)(_display.frame[0].locvars - 4) = OUTPUT;
        *(struct iorec **)(_display.frame[0].locvars - 8) = INPUT;
-       enableovrflo();
        stp = (struct stack *)pushsp(sizeof(struct stack));
        _dp = &_display.frame[0];
        pc.cp = base;
        stp = (struct stack *)pushsp(sizeof(struct stack));
        _dp = &_display.frame[0];
        pc.cp = base;
@@ -150,18 +158,20 @@ interpreter(base)
                        panic(PBADOP);
                        continue;
                case O_NODUMP:
                        panic(PBADOP);
                        continue;
                case O_NODUMP:
-                       _nodump++;
-                       disableovrflo();
+                       _nodump = TRUE;
                        /* and fall through */
                case O_BEG:
                        _dp += 1;               /* enter local scope */
                        stp->odisp = *_dp;      /* save old display value */
                        tl = *pc.ucp++;         /* tl = name size */
                        stp->entry = pc.hdrp;   /* pointer to entry info */
                        /* and fall through */
                case O_BEG:
                        _dp += 1;               /* enter local scope */
                        stp->odisp = *_dp;      /* save old display value */
                        tl = *pc.ucp++;         /* tl = name size */
                        stp->entry = pc.hdrp;   /* pointer to entry info */
-                       tl1 = *pc.lp++;         /* tl1 = local variable size */
-                       pc.lp++;                /* skip over number of args */
-                       _lino = *pc.usp++;      /* set new lino */
-                       pc.cp += tl;            /* skip over name text */
+                       tl1 = pc.hdrp->framesze;/* tl1 = size of frame */
+                       _lino = pc.hdrp->offset;
+                       _runtst = pc.hdrp->tests;
+                       disableovrflo();
+                       if (_runtst)
+                               enableovrflo();
+                       pc.cp += tl;            /* skip over proc hdr info */
                        stp->file = curfile;    /* save active file */
                        tcp = pushsp(tl1);      /* tcp = new top of stack */
                        blkclr(tl1, tcp);       /* zero stack frame */
                        stp->file = curfile;    /* save active file */
                        tcp = pushsp(tl1);      /* tcp = new top of stack */
                        blkclr(tl1, tcp);       /* zero stack frame */
@@ -180,6 +190,10 @@ interpreter(base)
                        _lino = stp->lino;      /* restore lino, pc, dp */
                        pc.cp = stp->pc.cp;
                        _dp = stp->dp;
                        _lino = stp->lino;      /* restore lino, pc, dp */
                        pc.cp = stp->pc.cp;
                        _dp = stp->dp;
+                       _runtst = stp->entry->tests;
+                       disableovrflo();
+                       if (_runtst)
+                               enableovrflo();
                        popsp(stp->entry->framesze +    /* pop local vars */
                              sizeof(struct stack) +    /* pop stack frame */
                              stp->entry->nargs);       /* pop parms */
                        popsp(stp->entry->framesze +    /* pop local vars */
                              sizeof(struct stack) +    /* pop stack frame */
                              stp->entry->nargs);       /* pop parms */
@@ -206,14 +220,16 @@ interpreter(base)
                        stp->pc.cp = pc.cp;
                        stp->dp = _dp;
                        pc.cp = tfp->entryaddr; /* calc new entry point */
                        stp->pc.cp = pc.cp;
                        stp->dp = _dp;
                        pc.cp = tfp->entryaddr; /* calc new entry point */
-                       tpc.sp = pc.sp + 1;
-                       tl -= tpc.hdrp->nargs;
-                       if (tl != 0) {
-                               if (tl > 0)
-                                       tl += sizeof(int) - 1;
-                               else
-                                       tl -= sizeof(int) - 1;
-                               ERROR(ENARGS, tl / sizeof(int));
+                       if (_runtst) {
+                               tpc.sp = pc.sp + 1;
+                               tl -= tpc.hdrp->nargs;
+                               if (tl != 0) {
+                                       if (tl > 0)
+                                               tl += sizeof(int) - 1;
+                                       else
+                                               tl -= sizeof(int) - 1;
+                                       ERROR(ENARGS, tl / sizeof(int));
+                               }
                        }
                        _dp = &_display.frame[tfp->cbn];/* new display ptr */
                        blkcpy(sizeof(struct disp) * tfp->cbn,
                        }
                        _dp = &_display.frame[tfp->cbn];/* new display ptr */
                        blkcpy(sizeof(struct disp) * tfp->cbn,
@@ -297,10 +313,11 @@ interpreter(base)
                        continue;
                case O_IF:
                        pc.cp++;
                        continue;
                case O_IF:
                        pc.cp++;
-                       if (pop2())
+                       if (pop2()) {
                                pc.sp++;
                                pc.sp++;
-                       else
-                               pc.cp += *pc.sp;
+                               continue;
+                       }
+                       pc.cp += *pc.sp;
                        continue;
                case O_REL2:
                        tl = pop2();
                        continue;
                case O_REL2:
                        tl = pop2();
@@ -500,8 +517,8 @@ interpreter(base)
                        continue;
                case O_AS8:
                        pc.cp++;
                        continue;
                case O_AS8:
                        pc.cp++;
-                       td = pop8();
-                       *(double *)popaddr() = td;
+                       t8 = popsze8();
+                       *(struct sze8 *)popaddr() = t8;
                        continue;
                case O_AS:
                        tl = *pc.cp++;
                        continue;
                case O_AS:
                        tl = *pc.cp++;
@@ -528,8 +545,10 @@ interpreter(base)
                                tl = *pc.usp++;
                        tl1 = pop2();           /* index */
                        tl2 = *pc.sp++;
                                tl = *pc.usp++;
                        tl1 = pop2();           /* index */
                        tl2 = *pc.sp++;
-                       SUBSC(tl1, tl2, *pc.usp++); /* range check */
                        pushaddr(popaddr() + (tl1 - tl2) * tl);
                        pushaddr(popaddr() + (tl1 - tl2) * tl);
+                       tl = *pc.usp++;
+                       if (_runtst)
+                               SUBSC(tl1, tl2, tl); /* range check */
                        continue;
                case O_INX4:
                        tl = *pc.cp++;          /* tl has element size */
                        continue;
                case O_INX4:
                        tl = *pc.cp++;          /* tl has element size */
@@ -537,8 +556,10 @@ interpreter(base)
                                tl = *pc.usp++;
                        tl1 = pop4();           /* index */
                        tl2 = *pc.sp++;
                                tl = *pc.usp++;
                        tl1 = pop4();           /* index */
                        tl2 = *pc.sp++;
-                       SUBSC(tl1, tl2, *pc.usp++); /* range check */
                        pushaddr(popaddr() + (tl1 - tl2) * tl);
                        pushaddr(popaddr() + (tl1 - tl2) * tl);
+                       tl = *pc.usp++;
+                       if (_runtst)
+                               SUBSC(tl1, tl2, tl); /* range check */
                        continue;
                case O_OFF:
                        tl = *pc.cp++;
                        continue;
                case O_OFF:
                        tl = *pc.cp++;
@@ -827,13 +848,13 @@ interpreter(base)
                        continue;
                case O_RV8:
                        tcp = _display.raw[*pc.ucp++];
                        continue;
                case O_RV8:
                        tcp = _display.raw[*pc.ucp++];
-                       push8(*(double *)(tcp + *pc.sp++));
+                       pushsze8(*(struct sze8 *)(tcp + *pc.sp++));
                        continue;
                case O_RV:
                        tcp = _display.raw[*pc.ucp++];
                        tcp += *pc.sp++;
                        tl = *pc.usp++;
                        continue;
                case O_RV:
                        tcp = _display.raw[*pc.ucp++];
                        tcp += *pc.sp++;
                        tl = *pc.usp++;
-                       tcp1 = pushsp(tl);
+                       tcp1 = pushsp((tl + 1) & ~1);
                        blkcpy(tl, tcp, tcp1);
                        continue;
                case O_LV:
                        blkcpy(tl, tcp, tcp1);
                        continue;
                case O_LV:
@@ -862,7 +883,7 @@ interpreter(base)
                        continue;
                case O_LRV8:
                        tcp = _display.raw[*pc.ucp++];
                        continue;
                case O_LRV8:
                        tcp = _display.raw[*pc.ucp++];
-                       push8(*(double *)(tcp + *pc.lp++));
+                       pushsze8(*(struct sze8 *)(tcp + *pc.lp++));
                        continue;
                case O_LRV:
                        tcp = _display.raw[*pc.ucp++];
                        continue;
                case O_LRV:
                        tcp = _display.raw[*pc.ucp++];
@@ -897,7 +918,7 @@ interpreter(base)
                        continue;
                case O_IND8:
                        pc.cp++;
                        continue;
                case O_IND8:
                        pc.cp++;
-                       push8(*(double *)(popaddr()));
+                       pushsze8(*(struct sze8 *)(popaddr()));
                        continue;
                case O_IND:
                        tl = *pc.cp++;
                        continue;
                case O_IND:
                        tl = *pc.cp++;
@@ -998,9 +1019,8 @@ interpreter(base)
                        continue;
                case O_STLIM:
                        pc.cp++;
                        continue;
                case O_STLIM:
                        pc.cp++;
-                       _stlim = pop4();
-                       _stcnt--;
-                       LINO();
+                       STLIM();
+                       popargs(1);
                        continue;
                case O_LLIMIT:
                        pc.cp++;
                        continue;
                case O_LLIMIT:
                        pc.cp++;
@@ -1035,7 +1055,7 @@ interpreter(base)
                                if (tl1 == *tcp++)
                                        break;
                        if (tl == 0)            /* default case => error */
                                if (tl1 == *tcp++)
                                        break;
                        if (tl == 0)            /* default case => error */
-                               ERROR(ECASE, tl2);
+                               ERROR(ECASE, tl1);
                        pc.cp += *(tsp - tl);
                        continue;
                case O_CASE2OP:
                        pc.cp += *(tsp - tl);
                        continue;
                case O_CASE2OP:
@@ -1049,7 +1069,7 @@ interpreter(base)
                                if (tl1 == *tsp1++)
                                        break;
                        if (tl == 0)            /* default case => error */
                                if (tl1 == *tsp1++)
                                        break;
                        if (tl == 0)            /* default case => error */
-                               ERROR(ECASE, tl2);
+                               ERROR(ECASE, tl1);
                        pc.cp += *(tsp - tl);
                        continue;
                case O_CASE4OP:
                        pc.cp += *(tsp - tl);
                        continue;
                case O_CASE4OP:
@@ -1063,7 +1083,7 @@ interpreter(base)
                                if (tl1 == *tlp++)
                                        break;
                        if (tl == 0)            /* default case => error */
                                if (tl1 == *tlp++)
                                        break;
                        if (tl == 0)            /* default case => error */
-                               ERROR(ECASE, tl2);
+                               ERROR(ECASE, tl1);
                        pc.cp += *(tsp - tl);
                        continue;
                case O_ADDT:
                        pc.cp += *(tsp - tl);
                        continue;
                case O_ADDT:
@@ -1135,61 +1155,91 @@ interpreter(base)
                        pc.cp++;
                        tcp = (char *)pop4();   /* tcp = ptr to index var */
                        if (*tcp < pop4()) {    /* still going up */
                        pc.cp++;
                        tcp = (char *)pop4();   /* tcp = ptr to index var */
                        if (*tcp < pop4()) {    /* still going up */
-                               *tcp += 1;      /* inc index var */
+                               tl = *tcp + 1;  /* inc index var */
+                               tl1 = *pc.sp++; /* index lower bound */
+                               tl2 = *pc.sp++; /* index upper bound */
+                               if (_runtst)
+                                       RANG4(tl, tl1, tl2);
+                               *tcp = tl;      /* update index var */
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
-                       pc.sp++;                /* else fall through */
+                       pc.sp += 3;             /* else fall through */
                        continue;
                case O_FOR2U:
                        pc.cp++;
                        tsp = (short *)pop4();  /* tsp = ptr to index var */
                        if (*tsp < pop4()) {    /* still going up */
                        continue;
                case O_FOR2U:
                        pc.cp++;
                        tsp = (short *)pop4();  /* tsp = ptr to index var */
                        if (*tsp < pop4()) {    /* still going up */
-                               *tsp += 1;      /* inc index var */
+                               tl = *tsp + 1;  /* inc index var */
+                               tl1 = *pc.sp++; /* index lower bound */
+                               tl2 = *pc.sp++; /* index upper bound */
+                               if (_runtst)
+                                       RANG4(tl, tl1, tl2);
+                               *tsp = tl;      /* update index var */
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
-                       pc.sp++;                /* else fall through */
+                       pc.sp += 3;             /* else fall through */
                        continue;
                case O_FOR4U:
                        pc.cp++;
                        tlp = (long *)pop4();   /* tlp = ptr to index var */
                        if (*tlp < pop4()) {    /* still going up */
                        continue;
                case O_FOR4U:
                        pc.cp++;
                        tlp = (long *)pop4();   /* tlp = ptr to index var */
                        if (*tlp < pop4()) {    /* still going up */
-                               *tlp += 1;      /* inc index var */
+                               tl = *tlp + 1;  /* inc index var */
+                               tl1 = *pc.lp++; /* index lower bound */
+                               tl2 = *pc.lp++; /* index upper bound */
+                               if (_runtst)
+                                       RANG4(tl, tl1, tl2);
+                               *tlp = tl;      /* update index var */
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
-                       pc.sp++;                /* else fall through */
+                       pc.sp += 5;             /* else fall through */
                        continue;
                case O_FOR1D:
                        pc.cp++;
                        tcp = (char *)pop4();   /* tcp = ptr to index var */
                        if (*tcp > pop4()) {    /* still going down */
                        continue;
                case O_FOR1D:
                        pc.cp++;
                        tcp = (char *)pop4();   /* tcp = ptr to index var */
                        if (*tcp > pop4()) {    /* still going down */
-                               *tcp -= 1;      /* dec index var */
+                               tl = *tcp - 1;  /* inc index var */
+                               tl1 = *pc.sp++; /* index lower bound */
+                               tl2 = *pc.sp++; /* index upper bound */
+                               if (_runtst)
+                                       RANG4(tl, tl1, tl2);
+                               *tcp = tl;      /* update index var */
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
-                       pc.sp++;                /* else fall through */
+                       pc.sp += 3;             /* else fall through */
                        continue;
                case O_FOR2D:
                        pc.cp++;
                        tsp = (short *)pop4();  /* tsp = ptr to index var */
                        if (*tsp > pop4()) {    /* still going down */
                        continue;
                case O_FOR2D:
                        pc.cp++;
                        tsp = (short *)pop4();  /* tsp = ptr to index var */
                        if (*tsp > pop4()) {    /* still going down */
-                               *tsp -= 1;      /* dec index var */
+                               tl = *tsp - 1;  /* inc index var */
+                               tl1 = *pc.sp++; /* index lower bound */
+                               tl2 = *pc.sp++; /* index upper bound */
+                               if (_runtst)
+                                       RANG4(tl, tl1, tl2);
+                               *tsp = tl;      /* update index var */
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
-                       pc.sp++;                /* else fall through */
+                       pc.sp += 3;             /* else fall through */
                        continue;
                case O_FOR4D:
                        pc.cp++;
                        tlp = (long *)pop4();   /* tlp = ptr to index var */
                        if (*tlp > pop4()) {    /* still going down */
                        continue;
                case O_FOR4D:
                        pc.cp++;
                        tlp = (long *)pop4();   /* tlp = ptr to index var */
                        if (*tlp > pop4()) {    /* still going down */
-                               *tlp -= 1;      /* dec index var */
+                               tl = *tlp - 1;  /* inc index var */
+                               tl1 = *pc.lp++; /* index lower bound */
+                               tl2 = *pc.lp++; /* index upper bound */
+                               if (_runtst)
+                                       RANG4(tl, tl1, tl2);
+                               *tlp = tl;      /* update index var */
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
                                pc.cp += *pc.sp;/* return to top of loop */
                                continue;
                        }
-                       pc.sp++;                /* else fall through */
+                       pc.sp += 5;             /* else fall through */
                        continue;
                case O_READE:
                        pc.cp++;
                        continue;
                case O_READE:
                        pc.cp++;
@@ -1221,25 +1271,48 @@ interpreter(base)
                        continue;
                case O_WRITEC:
                        pc.cp++;
                        continue;
                case O_WRITEC:
                        pc.cp++;
-                       WRITEC(curfile);
+                       if (_runtst) {
+                               WRITEC(curfile);
+                               popargs(2);
+                               continue;
+                       }
+                       fputc();
                        popargs(2);
                        continue;
                case O_WRITES:
                        pc.cp++;
                        popargs(2);
                        continue;
                case O_WRITES:
                        pc.cp++;
-                       WRITES(curfile);
+                       if (_runtst) {
+                               WRITES(curfile);
+                               popargs(4);
+                               continue;
+                       }
+                       fwrite();
                        popargs(4);
                        continue;
                case O_WRITEF:
                        popargs(4);
                        continue;
                case O_WRITEF:
-                       WRITEF(curfile);
+                       if (_runtst) {
+                               WRITEF(curfile);
+                               popargs(*pc.cp++);
+                               continue;
+                       }
+                       fprintf();
                        popargs(*pc.cp++);
                        continue;
                case O_WRITLN:
                        pc.cp++;
                        popargs(*pc.cp++);
                        continue;
                case O_WRITLN:
                        pc.cp++;
-                       WRITLN(curfile);
+                       if (_runtst) {
+                               WRITLN(curfile);
+                               continue;
+                       }
+                       fputc('\n', ACTFILE(curfile));
                        continue;
                case O_PAGE:
                        pc.cp++;
                        continue;
                case O_PAGE:
                        pc.cp++;
-                       PAGE(curfile);
+                       if (_runtst) {
+                               PAGE(curfile);
+                               continue;
+                       }
+                       fputc('^L', ACTFILE(curfile));
                        continue;
                case O_NAM:
                        pc.cp++;
                        continue;
                case O_NAM:
                        pc.cp++;
@@ -1251,7 +1324,13 @@ interpreter(base)
                        if (tl == 0)
                                tl = *pc.usp++;
                        tl1 = pop4();
                        if (tl == 0)
                                tl = *pc.usp++;
                        tl1 = pop4();
-                       push4(MAX(tl1, tl, *pc.usp++));
+                       if (_runtst) {
+                               push4(MAX(tl1, tl, *pc.usp++));
+                               continue;
+                       }
+                       tl1 -= tl;
+                       tl = *pc.usp++;
+                       push4(tl1 > tl ? tl1 : tl);
                        continue;
                case O_MIN:
                        tl = *pc.cp++;
                        continue;
                case O_MIN:
                        tl = *pc.cp++;
@@ -1365,7 +1444,11 @@ interpreter(base)
                        if (tl == 0)
                                tl = *pc.usp++;
                        tcp = popaddr();        /* ptr to ptr being new'ed */
                        if (tl == 0)
                                tl = *pc.usp++;
                        tcp = popaddr();        /* ptr to ptr being new'ed */
-                       NEWZ(tcp, tl);
+                       if (_runtst) {
+                               NEWZ(tcp, tl);
+                               continue;
+                       }
+                       NEW(tcp, tl);
                        continue;
                case O_DATE:
                        pc.cp++;
                        continue;
                case O_DATE:
                        pc.cp++;
@@ -1394,7 +1477,11 @@ interpreter(base)
                        continue;
                case O_LN:
                        pc.cp++;
                        continue;
                case O_LN:
                        pc.cp++;
-                       push8(LN(pop8()));
+                       if (_runtst) {
+                               push8(LN(pop8()));
+                               continue;
+                       }
+                       push8(log(pop8()));
                        continue;
                case O_SIN:
                        pc.cp++;
                        continue;
                case O_SIN:
                        pc.cp++;
@@ -1402,12 +1489,20 @@ interpreter(base)
                        continue;
                case O_SQRT:
                        pc.cp++;
                        continue;
                case O_SQRT:
                        pc.cp++;
-                       push8(SQRT(pop8()));
+                       if (_runtst) {
+                               push8(SQRT(pop8()));
+                               continue;
+                       }
+                       push8(sqrt(pop8()));
                        continue;
                case O_CHR2:
                case O_CHR4:
                        pc.cp++;
                        continue;
                case O_CHR2:
                case O_CHR4:
                        pc.cp++;
-                       push2(CHR(pop4()));
+                       if (_runtst) {
+                               push2(CHR(pop4()));
+                               continue;
+                       }
+                       push2(pop4());
                        continue;
                case O_ODD2:
                case O_ODD4:
                        continue;
                case O_ODD2:
                case O_ODD4:
@@ -1419,42 +1514,72 @@ interpreter(base)
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
-                       push2(SUCC(tl1, tl, *pc.sp++));
+                       if (_runtst) {
+                               push2(SUCC(tl1, tl, *pc.sp++));
+                               continue;
+                       }
+                       push2(tl1 + 1);
+                       pc.sp++;
                        continue;
                case O_SUCC24:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
                        continue;
                case O_SUCC24:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
-                       push4(SUCC(tl1, tl, *pc.sp++));
+                       if (_runtst) {
+                               push4(SUCC(tl1, tl, *pc.sp++));
+                               continue;
+                       }
+                       push4(tl1 + 1);
+                       pc.sp++;
                        continue;
                case O_SUCC4:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.lp++;
                        tl1 = pop4();
                        continue;
                case O_SUCC4:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.lp++;
                        tl1 = pop4();
-                       push4(SUCC(tl1, tl, *pc.lp++));
+                       if (_runtst) {
+                               push4(SUCC(tl1, tl, *pc.lp++));
+                               continue;
+                       }
+                       push4(tl1 + 1);
+                       pc.lp++;
                        continue;
                case O_PRED2:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
                        continue;
                case O_PRED2:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
-                       push2(PRED(tl1, tl, *pc.sp++));
+                       if (_runtst) {
+                               push2(PRED(tl1, tl, *pc.sp++));
+                               continue;
+                       }
+                       push2(tl1 - 1);
+                       pc.sp++;
                        continue;
                case O_PRED24:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
                        continue;
                case O_PRED24:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.sp++;
                        tl1 = pop4();
-                       push4(PRED(tl1, tl, *pc.sp++));
+                       if (_runtst) {
+                               push4(PRED(tl1, tl, *pc.sp++));
+                               continue;
+                       }
+                       push4(tl1 - 1);
+                       pc.sp++;
                        continue;
                case O_PRED4:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.lp++;
                        tl1 = pop4();
                        continue;
                case O_PRED4:
                        tl = *pc.cp++;
                        if (tl == 0)
                                tl = *pc.lp++;
                        tl1 = pop4();
-                       push4(PRED(tl1, tl, *pc.lp++));
+                       if (_runtst) {
+                               push4(PRED(tl1, tl, *pc.lp++));
+                               continue;
+                       }
+                       push4(tl1 - 1);
+                       pc.lp++;
                        continue;
                case O_SEED:
                        pc.cp++;
                        continue;
                case O_SEED:
                        pc.cp++;