# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/pdx/machine/nextaddr.c

##### Functions

    docase            X
    dofor             X
    isendofproc       X
    nextaddr          X

       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[] = "@(#)nextaddr.c	5.1 (Berkeley) 6/6/85";
       9: #endif not lint
      10: /*
      11:  * Calculate the next address that will be executed from the current one.
      12:  *
      13:  * If the next address depends on runtime data (e.g. a conditional
      14:  * branch will depend on the value on top of the stack),
      15:  * we must execute up to the given address with "stepto".
      16:  *
      17:  * If the second argument is TRUE, we treat a CALL instruction as
      18:  * straight line rather than following it as a branch.
      19:  */
      20:
      21: #include "defs.h"
      22: #include "machine.h"
      23: #include "process.h"
      24: #include "breakpoint.h"
      25: #include "sym.h"
      26: #include "pxops.h"
      27: #include "optab.h"
      28: #include "mappings.h"
      29: #include "runtime.h"
      30: #include "process/pxinfo.h"
      31: #include "process/process.rep"
      32:
      33: LOCAL ADDRESS docase(), dofor();
      34:
      35: ADDRESS nextaddr(beginaddr, isnext)
      36: ADDRESS beginaddr;
      37: BOOLEAN isnext;
      38: {
      39:     register PXOP op;
      40:     ADDRESS addr;
      41:     short offset;
      42:     int nextbyte;
      43:     SYM *s;
      44:     union {
      45:     short word;
      46:     char byte[2];
      47:     } o;
      48:
      49:     addr = beginaddr;
      50:     iread(&o.word, addr, sizeof(o.word));
      51:     op = (PXOP) o.byte[0];
      52:     nextbyte = o.byte[1];
      53:     addr += sizeof(short);
      54:     switch(op) {
      55:
      56: #   if (isvaxpx)
      57:     /*
      58:      * The version of px on the VAX assumes that the instruction
      59:      * at the entry point of a function is a TRA4 to the beginning
      60:      * of the block.
      61:      */
      62: #   endif
      63:     case O_CALL: {
      64:         ADDRESS eaddr;
      65:
      66:         if (isnext) {
      67:         addr += sizeof(int);
      68:         } else {
      69: #               if (isvaxpx)
      70:             iread(&eaddr, addr, sizeof(eaddr));
      71:             addr = eaddr + sizeof(short);
      72:             iread(&addr, addr, sizeof(addr));
      73: #               else
      74:             iread(&offset, addr, sizeof(offset));
      75:             addr += offset;
      76: #               endif
      77:         stepto(addr);
      78:         if (linelookup(addr) == 0) {
      79:             bpact();
      80:             addr = pc;
      81:         }
      82:         if (ss_lines && trcond()) {
      83:             s = whatblock(addr);
      84:             if (s == NIL) {
      85:             panic("bad call addr");
      86:             }
      87:             printentry(s);
      88:         }
      89:         }
      90:         break;
      91:     }
      92:
      93: #   if (isvaxpx)
      94:     case O_FCALL: {
      95:         ADDRESS eaddr;
      96:         ADDRESS *fparam;
      97:
      98:         if (!isnext) {
      99:         stepto(addr - sizeof(short));
     100:         dread(&fparam, process->sp + sizeof(ADDRESS), sizeof(fparam));
     101:         dread(&eaddr, fparam, sizeof(eaddr));
     102:         addr = eaddr - ENDOFF;
     103:         stepto(addr);
     104:         if (linelookup(addr) == 0) {
     105:             bpact();
     106:             addr = pc;
     107:         }
     108:         if (ss_lines && trcond()) {
     109:             s = whatblock(addr);
     110:             if (s == NIL) {
     111:             panic("bad call addr");
     112:             }
     113:             printentry(s);
     114:         }
     115:         }
     116:         break;
     117:     }
     118: #   endif
     119:
     120:     case O_END:
     121:         if ((addr - sizeof(short)) == lastaddr()) {
     122:         stepto(addr - sizeof(short));
     123:         endprogram();
     124:         } else {
     125:         addr = return_addr();
     126:         s = whatblock(pc);
     127:         stepto(addr);
     128:         if (ss_lines && trcond()) {
     129:             printexit(s);
     130:         }
     131:         if (linelookup(addr) == 0) {
     132:             bpact();
     133:             addr = pc;
     134:         }
     135:         }
     136:         break;
     137:
     138: #   if (isvaxpx)
     139:     case O_TRA4:
     140:     case O_GOTO:
     141:         iread(&addr, addr, sizeof(addr));
     142:         break;
     143: #   endif
     144:
     145:     case O_TRA:
     146:         iread(&offset, addr, sizeof(offset));
     147:         addr += offset;
     148:         break;
     149:
     150:     case O_CON: {
     151:         short consize;
     152:
     153:         if (nextbyte == 0) {
     154:         iread(&consize, addr, sizeof(consize));
     155:         addr += sizeof(consize);
     156:         } else {
     157:         consize = nextbyte;
     158:         }
     159:         addr += consize;
     160:         break;
     161:     }
     162:
     163:     case O_CASE1OP:
     164:         addr = docase(nextbyte, 1, addr);
     165:         break;
     166:
     167:     case O_CASE2OP:
     168:         addr = docase(nextbyte, 2, addr);
     169:         break;
     170:
     171:     case O_CASE4OP:
     172:         addr = docase(nextbyte, 4, addr);
     173:         break;
     174:
     175:     case O_FOR1U:
     176:         addr = dofor(2, addr, nextbyte, 1);
     177:         break;
     178:
     179:     case O_FOR2U:
     180:         addr = dofor(2, addr, nextbyte, 1);
     181:         break;
     182:
     183:     case O_FOR4U:
     184:         addr = dofor(4, addr, nextbyte, 1);
     185:         break;
     186:
     187:     case O_FOR1D:
     188:         addr = dofor(2, addr, nextbyte, -1);
     189:         break;
     190:
     191:     case O_FOR2D:
     192:         addr = dofor(2, addr, nextbyte, -1);
     193:         break;
     194:
     195:     case O_FOR4D:
     196:         addr = dofor(4, addr, nextbyte, -1);
     197:         break;
     198:
     199:     case O_IF:
     200:         stepto(addr - sizeof(short));
     201:         dread(&offset, process->sp, sizeof(offset));
     202:         if (offset == 0) {
     203:         iread(&offset, addr, sizeof(offset));
     204:         addr += offset;
     205:         } else {
     206:         addr += sizeof(offset);
     207:         }
     208:         break;
     209:
     210:     default: {
     211: #   if (isvaxpx)
     212:         int i;
     213:
     214:         for (i = 0; optab[op].argtype[i] != 0; i++) {
     215:         switch(optab[op].argtype[i]) {
     216:             case ADDR4:
     217:             case LWORD:
     218:             addr += 4;
     219:             break;
     220:
     221:             case SUBOP:
     222:             break;
     223:
     224:             case ADDR2:
     225:             case HWORD:
     226:             case PSUBOP:
     227:             case DISP:
     228:             case VLEN:
     229:             if (i != 0 || nextbyte == 0) {
     230:                 addr += sizeof(short);
     231:             }
     232:             break;
     233:
     234:             case STRING: {
     235:             char c;
     236:
     237:             while (nextbyte > 0) {
     238:                 iread(&c, addr, 1);
     239:                 if (c == '\0') {
     240:                 break;
     241:                 }
     242:                 nextbyte--;
     243:                 addr++;
     244:             }
     245:             addr++;
     246:             if ((addr&1) != 0) {
     247:                 addr++;
     248:             }
     249:             break;
     250:             }
     251:
     252:             default:
     253:             panic("bad argtype");
     254:             /*NOTREACHED*/
     255:         }
     256:         }
     257: #   else
     258:         int oplen;
     259:
     260:         oplen = optab[op].nargs;
     261:         if (oplen < 0) {
     262:         oplen = (-oplen) - 1;
     263:         } else  if (oplen > 0 && nextbyte != 0) {
     264:         oplen--;
     265:         }
     266:         oplen *= sizeof(int);
     267:         switch (op) {
     268:         case O_BEG:
     269:         case O_NODUMP:
     270:             oplen += 10;
     271:             break;
     272:
     273:         case O_CON:
     274:             oplen += ((nextbyte + 1)&~1);
     275:             break;
     276:         }
     277:         addr += oplen;
     278: #   endif
     279:         break;
     280:     }
     281:     }
     282:     return addr;
     283: }
     284:
     285: /*
     286:  * Find the next address that will be executed after the
     287:  * case statement at the given address.
     288:  */
     289:
     290: LOCAL ADDRESS docase(ncases, size, addr)
     291: int ncases;
     292: int size;
     293: ADDRESS addr;
     294: {
     295:     register ADDRESS i;
     296:     ADDRESS firstval, lastval, jmptable;
     297:     short offset;
     298:     long swtval, caseval;
     299:
     300:     stepto(addr - 2);
     301:     if (ncases == 0) {
     302:     iread(&ncases, addr, sizeof(ncases));
     303:     addr += sizeof(short);
     304:     }
     305:     jmptable = addr;
     306:     firstval = jmptable + ncases*sizeof(short);
     307:     lastval = firstval + ncases*size;
     308:     if (size <= 2) {
     309:     dread(&swtval, process->sp, 2);
     310:     } else {
     311:     dread(&swtval, process->sp, size);
     312:     }
     313:     for (i = firstval; i < lastval; i += size) {
     314:     iread(&caseval, i, size);
     315:     if (cmp(&swtval, &caseval, size) == 0) {
     316:         i = ((i - firstval) / size) * sizeof(offset);
     317:         iread(&offset, jmptable + i, sizeof(offset));
     318:         addr = jmptable + offset;
     319:         return addr;
     320:     }
     321:     }
     322:     return((lastval+1)&~1);
     323: }
     324:
     325: LOCAL ADDRESS dofor(size, addr, subop, incr)
     326: int size;
     327: ADDRESS addr;
     328: short subop;
     329: int incr;
     330: {
     331:     register PROCESS *p;
     332:     long i, limit, lower;
     333:     ADDRESS valaddr;
     334:     short offset;
     335:
     336:     stepto(addr - sizeof(short));
     337:     p = process;
     338:     i = limit = 0;
     339:     if (subop == 0) {
     340:     addr += size;
     341:     }
     342:     dread(&valaddr, p->sp, sizeof(valaddr));
     343:     dread(&i, valaddr, size);
     344:     dread(&limit, p->sp + sizeof(valaddr), size);
     345:     i += (incr << (8*(sizeof(i) - size)));
     346:     addr += size;
     347:
     348: /*
     349:  * It is very slow to go through the loop again and again.
     350:  * If it is desired to just skip to the end, the next 4 lines
     351:  * should be skipped.
     352:  */
     353:     if ((incr > 0 && i < limit) || (incr < 0 && i > limit)) {
     354:     iread(&offset, addr, sizeof(offset));
     355:     return(addr + offset);
     356:     } else {
     357:     return(addr + sizeof(short));
     358:     }
     359: }
     360:
     361: /*
     362:  * Determine whether or not the given address corresponds to the
     363:  * end of a procedure.
     364:  */
     365:
     366: BOOLEAN isendofproc(addr)
     367: ADDRESS addr;
     368: {
     369:     PXOP op;
     370:
     371:     iread(&op, addr, sizeof(op));
     372:     return (op == O_END);
     373: }

#### Defined functions

docase defined in line 290; used 4 times

- in line 33, 164-172(3)

dofor defined in line 325; used 7 times

- in line 33, 176-196(6)

isendofproc defined in line 366; never used
nextaddr defined in line 35; never used

#### Defined variables

sccsid defined in line 8; never used

Last modified: 1985-06-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1442 |