|
|
1.1 ! root 1: ! 2: #ifndef lint ! 3: static char *rcsid = ! 4: "$Header: vax.c,v 1.6 84/02/29 16:45:23 sklower Exp $"; ! 5: #endif ! 6: ! 7: /* -[Mon Mar 21 19:35:50 1983 by jkf]- ! 8: * vax.c $Locker: $ ! 9: * vax specific functions ! 10: * ! 11: * (c) copyright 1982, Regents of the University of California ! 12: */ ! 13: ! 14: #include "global.h" ! 15: #include <signal.h> ! 16: #include "vaxframe.h" ! 17: ! 18: /* exarith(a,b,c,lo,hi) ! 19: * int a,b,c; ! 20: * int *lo, *hi; ! 21: * Exact arithmetic. ! 22: * a,b and c are 32 bit 2's complement integers ! 23: * calculates x=a*b+c to twice the precision of an int. ! 24: * In the vax version, the 30 low bits only are returned ! 25: * in *lo,and the next 32 bits of precision are returned in * hi. ! 26: * this works since exarith is used either for calculating the sum of ! 27: * two 32 bit numbers, (which is at most 33 bits), or ! 28: * multiplying a 30 bit number by a 32 bit numbers, ! 29: * which has a maximum precision of 62 bits. ! 30: * If *phi is 0 or -1 then ! 31: * x doesn't need any more than 31 bits plus sign to describe, so we ! 32: * place the sign in the high two bits of *lo and return 0 from this ! 33: * routine. A non zero return indicates that x requires more than 31 bits ! 34: * to describe. ! 35: */ ! 36: exarith(a,b,c,phi,plo) ! 37: int *phi, *plo; ! 38: { ! 39: asm(" emul 4(ap),8(ap),12(ap),r2 #r2 = a*b + c to 64 bits"); ! 40: asm(" extzv $0,$30,r2,*20(ap) #get new lo"); ! 41: asm(" extv $30,$32,r2,r0 #get new carry"); ! 42: asm(" beql out # hi = 0, no work necessary"); ! 43: asm(" movl r0,*16(ap) # save hi"); ! 44: asm(" mcoml r0,r0 # Is hi = -1 (it'll fit in one word)"); ! 45: asm(" bneq out # it doesn't"); ! 46: asm(" bisl2 $0xc0000000,*20(ap) # alter low so that it is ok."); ! 47: asm("out: ret"); ! 48: } ! 49: ! 50: mmuladd (a, b, c, m) ! 51: int a, b, c, m; ! 52: { ! 53: asm ("emul 4(ap),8(ap),12(ap),r0"); ! 54: asm ("ediv 16(ap),r0,r2,r0"); ! 55: } ! 56: ! 57: Imuldiv() { ! 58: asm(" emul 4(ap),8(ap),12(ap),r0"); ! 59: asm(" ediv 16(ap),r0,*20(ap),*24(ap)"); ! 60: } ! 61: ! 62: callg_(funct,arglist) ! 63: lispval (*funct)(); ! 64: int *arglist; ! 65: { ! 66: asm(" callg *8(ap),*4(ap)"); ! 67: } ! 68: ! 69: #include <errno.h> ! 70: #define WRITE 4 ! 71: #define READ 3 ! 72: ! 73: #ifdef os_vms ! 74: #define _read _$real_read ! 75: #define _write _$real_write ! 76: #else ! 77: #define _read(a,b,c) syscall(READ,a,b,c) ! 78: #define _write(a,b,c) syscall(WRITE,a,b,c) ! 79: #endif ! 80: ! 81: /*C library -- write ! 82: nwritten = write(file, buffer, count); ! 83: nwritten == -1 means error ! 84: */ ! 85: write(file, buffer, count) ! 86: char *buffer; ! 87: { ! 88: register lispval handy; ! 89: int retval; ! 90: if((file != 1) || (Vcntlw->a.clb == nil)) goto top; ! 91: /* since ^w is non nil, we do not want to print to the terminal, ! 92: but we must be sure to return a correct value from the write ! 93: in case there is no write to ptport ! 94: */ ! 95: retval = count; ! 96: goto skipit; ! 97: top: ! 98: retval = _write(file,buffer,count); ! 99: ! 100: skipit: ! 101: if(file==1) { ! 102: handy = Vptport->a.clb; ! 103: if(handy!=nil && TYPE(handy)==PORT && handy->p->_file!=1) { ! 104: fflush(handy->p); ! 105: file = handy->p->_file; ! 106: goto top; ! 107: } ! 108: } ! 109: return(retval); ! 110: } ! 111: ! 112: /* ! 113: * ! 114: *nread = read(file, buffer, count); ! 115: *nread ==0 means eof; nread == -1 means error ! 116: * ! 117: */ ! 118: ! 119: read(file,buffer,count) ! 120: { ! 121: extern int errno; ! 122: register int Size; ! 123: again: ! 124: Size = _read(file,buffer,count); ! 125: if ((Size >= 0) || (errno != EINTR)) return(Size); ! 126: if(sigintcnt > 0) sigcall(SIGINT); ! 127: goto again; ! 128: } ! 129: ! 130: lispval ! 131: Lpolyev() ! 132: { ! 133: register int count; ! 134: register double *handy, *base; ! 135: register struct argent *argp; ! 136: lispval result; int type; ! 137: char *alloca(); ! 138: Keepxs(); ! 139: ! 140: count = 2 * (((int) np) - (int) lbot); ! 141: if(count == 0) ! 142: return(inewint(0)); ! 143: if(count == 8) ! 144: return(lbot->val); ! 145: base = handy = (double *) alloca(count); ! 146: for(argp = lbot; argp < np; argp++) { ! 147: while((type = TYPE(argp->val))!=DOUB && type!=INT) ! 148: argp->val = (lispval) errorh2(Vermisc,"%%machine-polyev:non-real arg",nil,TRUE,73,lbot,argp->val); ! 149: if(TYPE(argp->val)==INT) { ! 150: *handy++ = argp->val->i; ! 151: } else ! 152: *handy++ = argp->val->r; ! 153: } ! 154: count = count/sizeof(double) - 2; ! 155: asm("polyd (r9),r11,8(r9)"); ! 156: asm("movd r0,(r9)"); ! 157: result = newdoub(); ! 158: result->r = *base; ! 159: Freexs(); ! 160: return(result); ! 161: } ! 162: ! 163: lispval ! 164: Lrot() ! 165: { ! 166: register rot,val; /* these must be the first registers */ ! 167: register struct argent *mylbot = lbot; ! 168: ! 169: chkarg(2,"rot"); ! 170: if((TYPE(mylbot->val) != INT) || (TYPE(mylbot[1].val) != INT)) ! 171: errorh2(Vermisc, ! 172: "Non ints to rot", ! 173: nil,FALSE,0,mylbot->val,mylbot[1].val); ! 174: val = mylbot[0].val->i; ! 175: rot = mylbot[1].val->i; ! 176: rot = rot % 32 ; /* bring it down below one byte in size */ ! 177: asm(" rotl r11,r10,r10 "); /* rotate val by rot and put back in val */ ! 178: return( inewint(val)); ! 179: } ! 180: /* new version of showstack, ! 181: We will set fp to point where the register fp points. ! 182: Then fp+2 = saved ap ! 183: fp+4 = saved pc ! 184: fp+3 = saved fp ! 185: ap+1 = first arg ! 186: If we find that the saved pc is somewhere in the routine eval, ! 187: then we print the first argument to that eval frame. This is done ! 188: by looking one beyond the saved ap. ! 189: */ ! 190: lispval ! 191: Lshostk() ! 192: { lispval isho(); ! 193: return(isho(1)); ! 194: } ! 195: static lispval ! 196: isho(f) ! 197: int f; ! 198: { ! 199: register struct machframe *myfp; register lispval handy; ! 200: int **fp; /* this must be the first local */ ! 201: int virgin=1; ! 202: lispval linterp(); ! 203: lispval _qfuncl(),tynames(); /* locations in qfuncl */ ! 204: extern int plevel,plength; ! 205: ! 206: if(TYPE(Vprinlevel->a.clb) == INT) ! 207: { ! 208: plevel = Vprinlevel->a.clb->i; ! 209: } ! 210: else plevel = -1; ! 211: if(TYPE(Vprinlength->a.clb) == INT) ! 212: { ! 213: plength = Vprinlength->a.clb->i; ! 214: } ! 215: else plength = -1; ! 216: ! 217: if(f==1) ! 218: printf("Forms in evaluation:\n"); ! 219: else ! 220: printf("Backtrace:\n\n"); ! 221: ! 222: myfp = (struct machframe *) (&fp +1); /* point to current frame */ ! 223: ! 224: while(TRUE) ! 225: { ! 226: if( (myfp->pc > eval && /* interpreted code */ ! 227: myfp->pc < popnames) ! 228: || ! 229: (myfp->pc > Lfuncal && /* compiled code */ ! 230: myfp->pc < linterp) ) ! 231: { ! 232: if(((int) myfp->ap[0]) == 1) /* only if arg given */ ! 233: { handy = (myfp->ap[1]); ! 234: if(f==1) ! 235: printr(handy,stdout), putchar('\n'); ! 236: else { ! 237: if(virgin) ! 238: virgin = 0; ! 239: else ! 240: printf(" -- "); ! 241: printr((TYPE(handy)==DTPR)?handy->d.car:handy,stdout); ! 242: } ! 243: } ! 244: ! 245: } ! 246: ! 247: if(myfp > myfp->fp) break; /* end of frames */ ! 248: else myfp = myfp->fp; ! 249: } ! 250: putchar('\n'); ! 251: return(nil); ! 252: } ! 253: ! 254: /* ! 255: * ! 256: * (baktrace) ! 257: * ! 258: * baktrace will print the names of all functions being evaluated ! 259: * from the current one (baktrace) down to the first one. ! 260: * currently it only prints the function name. Planned is a ! 261: * list of local variables in all stack frames. ! 262: * written by jkf. ! 263: * ! 264: */ ! 265: lispval ! 266: Lbaktrace() ! 267: { ! 268: isho(0); ! 269: } ! 270: ! 271: /* ! 272: * (int:showstack 'stack_pointer) ! 273: * return ! 274: * nil if at the end of the stack or illegal ! 275: * ( expresssion . next_stack_pointer) otherwise ! 276: * where expression is something passed to eval ! 277: * very vax specific ! 278: */ ! 279: lispval ! 280: LIshowstack() ! 281: { ! 282: int **fp; /* must be the first local variable */ ! 283: register lispval handy; ! 284: register struct machframe *myfp; ! 285: lispval retval, Lfuncal(), Ifuncal(); ! 286: Savestack(2); ! 287: ! 288: chkarg(1,"int:showstack"); ! 289: ! 290: if((TYPE(handy=lbot[0].val) != INT) && (handy != nil)) ! 291: error("int:showstack non fixnum arg", FALSE); ! 292: ! 293: if(handy == nil) ! 294: myfp = (struct machframe *) (&fp +1); ! 295: else ! 296: myfp = (struct machframe *) handy->i; ! 297: ! 298: if((int ***)myfp <= &fp) error("int:showstack illegal stack value",FALSE); ! 299: while(myfp > 0) ! 300: { ! 301: if( (myfp->pc > eval && /* interpreted code */ ! 302: myfp->pc < popnames) ! 303: || ! 304: (myfp->pc > Ifuncal && /* compiled code */ ! 305: myfp->pc < Lfuncal) ) ! 306: { ! 307: if(((int) myfp->ap[0]) == 1) /* only if arg given */ ! 308: { ! 309: handy = (lispval)(myfp->ap[1]); /* arg to eval */ ! 310: ! 311: protect(retval=newdot()); ! 312: retval->d.car = handy; ! 313: if(myfp > myfp->fp) ! 314: myfp = 0; /* end of frames */ ! 315: else ! 316: myfp = myfp->fp; ! 317: retval->d.cdr = inewint(myfp); ! 318: return(retval); ! 319: } ! 320: } ! 321: if(myfp > myfp->fp) ! 322: myfp = 0; /* end of frames */ ! 323: else ! 324: myfp = myfp->fp; ! 325: ! 326: } ! 327: return(nil); ! 328: } ! 329: #include "frame.h" ! 330: /* ! 331: * this code is very similar to ftolsp. ! 332: * if it gets revised, so should this. ! 333: */ ! 334: lispval ! 335: dothunk(func,count,arglist) ! 336: lispval func; ! 337: long count; ! 338: register long *arglist; ! 339: { ! 340: ! 341: lispval save; ! 342: pbuf pb; ! 343: Savestack(1); ! 344: ! 345: if(errp->class==F_TO_FORT) ! 346: np = errp->svnp; ! 347: errp = Pushframe(F_TO_LISP,nil,nil); ! 348: lbot = np; ! 349: np++->val = func; ! 350: arglist++; ! 351: for(; count > 0; count--) ! 352: np++->val = inewint(*arglist++); ! 353: save = Lfuncal(); ! 354: errp = Popframe(); ! 355: Restorestack(); ! 356: return(save); ! 357: } ! 358: /* ! 359: _thcpy: ! 360: movl (sp),r0 ! 361: pushl ap ! 362: pushl (r0)+ ! 363: pushl (r0)+ ! 364: calls $3,_dothunk ! 365: ret */ ! 366: static char fourwords[] = "0123456789012345"; ! 367: ! 368: lispval ! 369: Lmkcth() ! 370: { ! 371: register struct argent *mylbot = lbot; ! 372: register struct thunk { ! 373: short mask; ! 374: short jsri; ! 375: char *thcpy; ! 376: long count; ! 377: lispval func; ! 378: } *th; ! 379: extern char thcpy[]; ! 380: ! 381: chkarg(2,"make-c-thunk"); ! 382: th = (struct thunk *)pinewstr(fourwords); ! 383: th->mask = 0; ! 384: th->jsri = 0x9f16; ! 385: th->thcpy = thcpy; ! 386: th->func = mylbot->val; ! 387: th->count = mylbot[1].val->i; ! 388: ! 389: return((lispval)th); ! 390: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.