BSD 4_4 release
[unix-history] / usr / src / usr.bin / pascal / pdx / machine / nextaddr.c
index 37fc125..dc0ac5c 100644 (file)
@@ -1,6 +1,39 @@
-/* Copyright (c) 1982 Regents of the University of California */
+/*-
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 
-static char sccsid[] = "@(#)nextaddr.c 1.1 %G%";
+#ifndef lint
+static char sccsid[] = "@(#)nextaddr.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
 
 /*
  * Calculate the next address that will be executed from the current one.
 
 /*
  * Calculate the next address that will be executed from the current one.
@@ -25,243 +58,258 @@ static char sccsid[] = "@(#)nextaddr.c 1.1 %G%";
 #include "process/pxinfo.h"
 #include "process/process.rep"
 
 #include "process/pxinfo.h"
 #include "process/process.rep"
 
+#ifdef tahoe
+#define EVEN 3
+#else
+#define EVEN 1
+#endif
+
 LOCAL ADDRESS docase(), dofor();
 
 ADDRESS nextaddr(beginaddr, isnext)
 ADDRESS beginaddr;
 BOOLEAN isnext;
 {
 LOCAL ADDRESS docase(), dofor();
 
 ADDRESS nextaddr(beginaddr, isnext)
 ADDRESS beginaddr;
 BOOLEAN isnext;
 {
-       register PXOP op;
-       ADDRESS addr;
-       short offset;
-       int nextbyte;
-       SYM *s;
-       union {
-               short word;
-               char byte[2];
-       } o;
-
-       addr = beginaddr;
-       iread(&o.word, addr, sizeof(o.word));
-       op = (PXOP) o.byte[0];
-       nextbyte = o.byte[1];
-       addr += sizeof(short);
-       switch(op) {
-
-#      if (isvaxpx)
-       /*
-        * The version of px on the VAX assumes that the instruction
-        * at the entry point of a function is a TRA4 to the beginning
-        * of the block.
-        */
-#      endif
-               case O_CALL: {
-                       ADDRESS eaddr;
-
-                       if (isnext) {
-                               addr += sizeof(int);
-                       } else {
-#                              if (isvaxpx)
-                                       iread(&eaddr, addr, sizeof(eaddr));
-                                       addr = eaddr + sizeof(short);
-                                       iread(&addr, addr, sizeof(addr));
-#                              else
-                                       iread(&offset, addr, sizeof(offset));
-                                       addr += offset;
-#                              endif
-                               stepto(addr);
-                               if (linelookup(addr) == 0) {
-                                       bpact();
-                                       addr = pc;
-                               }
-                               if (ss_lines && trcond()) {
-                                       s = whatblock(addr);
-                                       if (s == NIL) {
-                                               panic("bad call addr");
-                                       }
-                                       printentry(s);
-                               }
-                       }
-                       break;
+    register PXOP op;
+    ADDRESS addr;
+    short offset;
+    int nextbyte;
+    SYM *s;
+    union {
+       short word;
+       char byte[2];
+    } o;
+
+#ifdef tahoe
+    doret(process);
+#endif
+    addr = beginaddr;
+    iread(&o.word, addr, sizeof(o.word));
+    op = (PXOP) o.byte[0];
+    nextbyte = o.byte[1];
+    addr += sizeof(short);
+    switch(op) {
+
+    /*
+     * The version of px we are using assumes that the instruction
+     * at the entry point of a function is a TRA4 to the beginning
+     * of the block.
+     */
+       case O_CALL: {
+           ADDRESS eaddr;
+
+           if (isnext) {
+               addr += sizeof(int);
+#ifdef tahoe
+               addr = (ADDRESS)(((int)addr + EVEN) & ~EVEN);
+#endif
+           } else {
+#ifdef tahoe
+               addr = (ADDRESS)(((int)addr + EVEN) & ~EVEN);
+#endif
+               iread(&eaddr, addr, sizeof(eaddr));
+               addr = eaddr + sizeof(short);
+#ifdef tahoe
+               addr = (ADDRESS)(((int)addr + EVEN) & ~EVEN);
+#endif
+               iread(&addr, addr, sizeof(addr));
+               stepto(addr);
+               if (linelookup(addr) == 0) {
+                   bpact();
+                   addr = pc;
                }
                }
-
-#      if (isvaxpx)
-               case O_FCALL: {
-                       ADDRESS eaddr;
-                       ADDRESS *fparam;
-
-                       if (!isnext) {
-                               stepto(addr - sizeof(short));
-                               dread(&fparam, process->sp + sizeof(ADDRESS), sizeof(fparam));
-                               dread(&eaddr, fparam, sizeof(eaddr));
-                               addr = eaddr - ENDOFF;
-                               stepto(addr);
-                               if (linelookup(addr) == 0) {
-                                       bpact();
-                                       addr = pc;
-                               }
-                               if (ss_lines && trcond()) {
-                                       s = whatblock(addr);
-                                       if (s == NIL) {
-                                               panic("bad call addr");
-                                       }
-                                       printentry(s);
-                               }
-                       }
-                       break;
+               if (ss_lines && trcond()) {
+                   s = whatblock(addr);
+                   if (s == NIL) {
+                       panic("bad call addr");
+                   }
+                   printentry(s);
                }
                }
-#      endif
-
-               case O_END:
-                       if ((addr - sizeof(short)) == lastaddr()) {
-                               stepto(addr - sizeof(short));
-                               endprogram();
-                       } else {
-                               addr = return_addr();
-                               s = whatblock(pc);
-                               stepto(addr);
-                               if (ss_lines && trcond()) {
-                                       printexit(s);
-                               }
-                               if (linelookup(addr) == 0) {
-                                       bpact();
-                                       addr = pc;
-                               }
-                       }
-                       break;
-
-#      if (isvaxpx)
-               case O_TRA4:
-               case O_GOTO:
-                       iread(&addr, addr, sizeof(addr));
-                       break;
-#      endif
-
-               case O_TRA:
-                       iread(&offset, addr, sizeof(offset));
-                       addr += offset;
-                       break;
-
-               case O_CASE1OP:
-                       addr = docase(nextbyte, 1, addr);
-                       break;
-
-               case O_CASE2OP:
-                       addr = docase(nextbyte, 2, addr);
-                       break;
-
-               case O_CASE4OP:
-                       addr = docase(nextbyte, 4, addr);
-                       break;
+           }
+           break;
+       }
 
 
-               case O_FOR1U:
-                       addr = dofor(2, addr, nextbyte, 1);
-                       break;
+       case O_FCALL: {
+           ADDRESS eaddr;
+           ADDRESS *fparam;
+
+           if (!isnext) {
+               stepto(addr - sizeof(short));
+#ifdef tahoe
+               doret(process);
+#endif
+               dread(&fparam, process->sp + sizeof(ADDRESS), sizeof(fparam));
+               dread(&eaddr, fparam, sizeof(eaddr));
+               addr = eaddr - ENDOFF;
+               stepto(addr);
+#ifdef tahoe
+               doret(process);
+#endif
+               if (linelookup(addr) == 0) {
+                   bpact();
+                   addr = pc;
+               }
+               if (ss_lines && trcond()) {
+                   s = whatblock(addr);
+                   if (s == NIL) {
+                       panic("bad call addr");
+                   }
+                   printentry(s);
+               }
+           }
+           break;
+       }
 
 
-               case O_FOR2U:
-                       addr = dofor(2, addr, nextbyte, 1);
-                       break;
+       case O_END:
+           if ((addr - sizeof(short)) == lastaddr()) {
+               stepto(addr - sizeof(short));
+               endprogram();
+           } else {
+               addr = return_addr();
+               s = whatblock(pc);
+               stepto(addr);
+               if (ss_lines && trcond()) {
+                   printexit(s);
+               }
+               if (linelookup(addr) == 0) {
+                   bpact();
+                   addr = pc;
+               }
+           }
+           break;
+
+       case O_TRA4:
+       case O_GOTO:
+#ifdef tahoe
+           addr = (ADDRESS)(((int)addr + EVEN) & ~EVEN);
+#endif
+           iread(&addr, addr, sizeof(addr));
+           break;
+
+       case O_TRA:
+           iread(&offset, addr, sizeof(offset));
+           addr += offset;
+           break;
+
+       case O_CON: {
+           short consize;
+
+           if (nextbyte == 0) {
+#ifdef tahoe
+               addr = (ADDRESS)(((int)addr + EVEN) & ~EVEN);
+#endif
+               iread(&consize, addr, sizeof(consize));
+               addr += sizeof(consize);
+           } else {
+               consize = nextbyte;
+           }
+           addr += consize;
+           break;
+       }
 
 
-               case O_FOR4U:
-                       addr = dofor(4, addr, nextbyte, 1);
+       case O_CASE1OP:
+           addr = docase(nextbyte, 1, addr);
+           break;
+
+       case O_CASE2OP:
+           addr = docase(nextbyte, 2, addr);
+           break;
+
+       case O_CASE4OP:
+           addr = docase(nextbyte, 4, addr);
+           break;
+
+       case O_FOR1U:
+           addr = dofor(2, addr, nextbyte, 1);
+           break;
+
+       case O_FOR2U:
+           addr = dofor(2, addr, nextbyte, 1);
+           break;
+
+       case O_FOR4U:
+           addr = dofor(4, addr, nextbyte, 1);
+           break;
+
+       case O_FOR1D:
+           addr = dofor(2, addr, nextbyte, -1);
+           break;
+
+       case O_FOR2D:
+           addr = dofor(2, addr, nextbyte, -1);
+           break;
+
+       case O_FOR4D:
+           addr = dofor(4, addr, nextbyte, -1);
+           break;
+
+       case O_IF:
+           stepto(addr - sizeof(short));
+#ifdef tahoe
+           doret(process);
+           dread(&offset, process->sp+sizeof(int)-sizeof(offset), sizeof(offset));
+#else
+           dread(&offset, process->sp, sizeof(offset));
+#endif
+           if (offset == 0) {
+               iread(&offset, addr, sizeof(offset));
+               addr += offset;
+           } else {
+               addr += sizeof(offset);
+           }
+           break;
+
+       default: {
+           int i;
+
+           for (i = 0; optab[op].argtype[i] != 0; i++) {
+               switch(optab[op].argtype[i]) {
+                   case ADDR4:
+                   case LWORD:
+                       addr += 4;
+#ifdef tahoe
+                       addr = (ADDRESS)(((int)addr + EVEN) & ~EVEN);
+#endif
                        break;
 
                        break;
 
-               case O_FOR1D:
-                       addr = dofor(2, addr, nextbyte, -1);
+                   case SUBOP:
                        break;
 
                        break;
 
-               case O_FOR2D:
-                       addr = dofor(2, addr, nextbyte, -1);
+                   case ADDR2:
+                   case HWORD:
+                   case PSUBOP:
+                   case DISP:
+                   case VLEN:
+                       if (i != 0 || nextbyte == 0) {
+                           addr += sizeof(short);
+                       }
                        break;
 
                        break;
 
-               case O_FOR4D:
-                       addr = dofor(4, addr, nextbyte, -1);
-                       break;
+                   case STRING: {
+                       char c;
 
 
-               case O_IF:
-                       stepto(addr - sizeof(short));
-                       dread(&offset, process->sp, sizeof(offset));
-                       if (offset == 0) {
-                               iread(&offset, addr, sizeof(offset));
-                               addr += offset;
-                       } else {
-                               addr += sizeof(offset);
+                       while (nextbyte > 0) {
+                           iread(&c, addr, 1);
+                           if (c == '\0') {
+                               break;
+                           }
+                           nextbyte--;
+                           addr++;
                        }
                        }
+                       addr++;
+                       addr = (ADDRESS)(((int)addr + EVEN) & ~EVEN);
                        break;
                        break;
+                   }
 
 
-               default: {
-#      if (isvaxpx)
-                       int i;
-
-                       for (i = 0; optab[op].argtype[i] != 0; i++) {
-                               switch(optab[op].argtype[i]) {
-                                       case ADDR4:
-                                       case LWORD:
-                                               addr += 4;
-                                               break;
-
-                                       case SUBOP:
-                                               break;
-
-                                       case ADDR2:
-                                       case HWORD:
-                                       case PSUBOP:
-                                       case DISP:
-                                       case VLEN:
-                                               if (i != 0 || nextbyte == 0) {
-                                                       addr += sizeof(short);
-                                               }
-                                               break;
-
-                                       case STRING: {
-                                               char c;
-
-                                               while (nextbyte > 0) {
-                                                       iread(&c, addr, 1);
-                                                       if (c == '\0') {
-                                                               break;
-                                                       }
-                                                       nextbyte--;
-                                                       addr++;
-                                               }
-                                               addr++;
-                                               if ((addr&1) != 0) {
-                                                       addr++;
-                                               }
-                                               break;
-                                       }
-
-                                       default:
-                                               panic("bad argtype");
-                                               /*NOTREACHED*/
-                               }
-                       }
-#      else
-                       int oplen;
-
-                       oplen = optab[op].nargs;
-                       if (oplen < 0) {
-                               oplen = (-oplen) - 1;
-                       } else  if (oplen > 0 && nextbyte != 0) {
-                               oplen--;
-                       }
-                       oplen *= sizeof(int);
-                       switch (op) {
-                               case O_BEG:
-                               case O_NODUMP:
-                                       oplen += 10;
-                                       break;
-
-                               case O_CON:
-                                       oplen += ((nextbyte + 1)&~1);
-                                       break;
-                       }
-                       addr += oplen;
-#      endif
-                       break;
+                   default:
+                       panic("bad argtype");
+                       /*NOTREACHED*/
                }
                }
+           }
+           break;
        }
        }
-       return addr;
+    }
+    return addr;
 }
 
 /*
 }
 
 /*
@@ -274,34 +322,54 @@ int ncases;
 int size;
 ADDRESS addr;
 {
 int size;
 ADDRESS addr;
 {
-       register ADDRESS i;
-       ADDRESS firstval, lastval, jmptable;
-       short offset;
-       long swtval, caseval;
-
-       stepto(addr - 2);
-       if (ncases == 0) {
-               iread(&ncases, addr, sizeof(ncases));
-               addr += sizeof(short);
-       }
-       jmptable = addr;
-       firstval = jmptable + ncases*sizeof(short);
-       lastval = firstval + ncases*size;
-       if (size <= 2) {
-               dread(&swtval, process->sp, 2);
-       } else {
-               dread(&swtval, process->sp, size);
-       }
-       for (i = firstval; i < lastval; i += size) {
-               iread(&caseval, i, size);
-               if (cmp(&swtval, &caseval, size) == 0) {
-                       i = ((i - firstval) / size) * sizeof(offset);
-                       iread(&offset, jmptable + i, sizeof(offset));
-                       addr = jmptable + offset;
-                       return addr;
-               }
+    register ADDRESS i;
+    ADDRESS firstval, lastval, jmptable;
+    short offset;
+    long swtval, caseval;
+
+    stepto(addr - 2);
+#ifdef tahoe
+    doret(process);
+#endif
+    if (ncases == 0) {
+       iread(&ncases, addr, sizeof(ncases));
+       addr += sizeof(short);
+    }
+    jmptable = addr;
+    firstval = jmptable + ncases*sizeof(short);
+#ifdef tahoe
+    if (size == 4) {
+       firstval = (ADDRESS)(((int)firstval + EVEN) & ~EVEN);
+    }
+#endif
+    lastval = firstval + ncases*size;
+#ifdef tahoe
+    if (size <= 4) {
+       dread(&swtval, process->sp, 4);
+#else
+    if (size <= 2) {
+       dread(&swtval, process->sp, 2);
+#endif
+    } else {
+       dread(&swtval, process->sp, size);
+    }
+    for (i = firstval; i < lastval; i += size) {
+       caseval = 0;
+#ifdef tahoe
+       iread((char *)&caseval + sizeof caseval - size, i, size);
+       if (swtval == caseval)
+#else
+       iread(&caseval, i, size);
+       if (cmp(&swtval, &caseval, size) == 0)
+#endif
+       {
+           i = ((i - firstval) / size) * sizeof(offset);
+           iread(&offset, jmptable + i, sizeof(offset));
+           addr = jmptable + offset;
+           return addr;
        }
        }
-       return((lastval+1)&~1);
+    }
+    return((lastval+1)&~1);
 }
 
 LOCAL ADDRESS dofor(size, addr, subop, incr)
 }
 
 LOCAL ADDRESS dofor(size, addr, subop, incr)
@@ -310,33 +378,51 @@ ADDRESS addr;
 short subop;
 int incr;
 {
 short subop;
 int incr;
 {
-       register PROCESS *p;
-       long i, limit, lower;
-       ADDRESS valaddr;
-       short offset;
-
-       stepto(addr - sizeof(short));
-       p = process;
-       i = limit = 0;
-       if (subop == 0) {
-               addr += size;
-       }
-       dread(&valaddr, p->sp, sizeof(valaddr));
-       dread(&i, valaddr, size);
-       dread(&limit, p->sp + sizeof(valaddr), size);
-       i += (incr << (8*(sizeof(i) - size)));
-       addr += size;
+    register PROCESS *p;
+    long i, limit;
+    ADDRESS valaddr;
+
+    stepto(addr - sizeof(short));
+    p = process;
+#ifdef tahoe
+    doret(p);
+#endif
+    i = limit = 0;
+    if (subop == 0) {
+       dread(&subop, addr, sizeof (short));
+       addr += sizeof (short);
+    }
+    dread(&valaddr, p->sp, sizeof(valaddr));
+#ifdef tahoe
+    dread((char *)&i + sizeof i - size, valaddr, size);
+#else
+    dread(&i, valaddr, size);
+#endif
+    dread(&limit, p->sp + sizeof(valaddr), sizeof limit);
+    i += incr;
+
 /*
  * It is very slow to go through the loop again and again.
 /*
  * It is very slow to go through the loop again and again.
- * So for the time being, we just skip to the end.
- *
-       if ((incr > 0 && i < limit) || (incr < 0 && i > limit)) {
-               iread(&offset, addr, sizeof(offset));
-               return(addr + offset);
-       } else {
+ * If it is desired to just skip to the end, the next 4 lines
+ * should be skipped.
  */
  */
-               return(addr + sizeof(short));
+    if ((incr > 0 && i < limit) || (incr < 0 && i > limit)) {
+       return(addr + subop);
+    } else {
+       return(addr);
+    }
+}
+
 /*
 /*
-       }
+ * Determine whether or not the given address corresponds to the
+ * end of a procedure.
  */
  */
+
+BOOLEAN isendofproc(addr)
+ADDRESS addr;
+{
+    PXOP op;
+
+    iread(&op, addr, sizeof(op));
+    return (op == O_END);
 }
 }