#include "defs" #ifdef SDB # include <a.out.h> extern int types2[]; #endif #include "pccdefs" /* PDP11-780/VAX - SPECIFIC ROUTINES */ int maxregvar = MAXREGVAR; int regnum[] = { 11, 10, 9, 8, 7, 6 } ; static int regmask[] = { 0, 0x800, 0xc00, 0xe00, 0xf00, 0xf80, 0xfc0 }; ftnint intcon[14] = { 2, 2, 2, 2, 15, 31, 24, 56, -128, -128, 127, 127, 32767, 2147483647 }; #if HERE == VAX /* then put in constants in octal */ long realcon[6][2] = { { 0200, 0 }, { 0200, 0 }, { 037777677777, 0 }, { 037777677777, 037777777777 }, { 032200, 0 }, { 022200, 0 } }; #else double realcon[6] = { 2.9387358771e-39, 2.938735877055718800e-39 1.7014117332e+38, 1.701411834604692250e+38 5.960464e-8, 1.38777878078144567e-17, }; #endif prsave() { int proflab; p2pi("\t.word\t0x%x", regmask[highregvar]); /* register variable mask */ if(profileflag) { proflab = newlabel(); fprintf(asmfile, "L%d:\t.space\t4\n", proflab); p2pi("\tmovab\tL%d,r0", proflab); p2pass("\tjsb\tmcount"); } p2pi("\tsubl2\t$.F%d,sp", procno); } goret(type) int type; { p2pass("\tret"); } /* * move argument slot arg1 (relative to ap) * to slot arg2 (relative to ARGREG) */ mvarg(type, arg1, arg2) int type, arg1, arg2; { p2pij("\tmovl\t%d(ap),%d(fp)", arg1+ARGOFFSET, arg2+argloc); } prlabel(fp, k) FILEP fp; int k; { fprintf(fp, "L%d:\n", k); } prconi(fp, type, n) FILEP fp; int type; ftnint n; { fprintf(fp, "\t%s\t%ld\n", (type==TYSHORT ? ".word" : ".long"), n); } prcona(fp, a) FILEP fp; ftnint a; { fprintf(fp, "\t.long\tL%ld\n", a); } #ifndef vax prconr(fp, type, x) FILEP fp; int type; float x; { fprintf(fp, "\t%s\t0f%e\n", (type==TYREAL ? ".float" : ".double"), x); } #endif #ifdef vax prconr(fp, type, x) FILEP fp; int type; double x; { long int *n; n = &x; /* nonportable cheat */ if(type == TYREAL) fprintf(fp, "\t.long\t0x%X\n", n[0]); else fprintf(fp, "\t.long\t0x%X,0x%X\n", n[0], n[1]); } #endif preven(k) int k; { register int lg; if(k > 4) lg = 3; else if(k > 2) lg = 2; else if(k > 1) lg = 1; else return; fprintf(asmfile, "\t.align\t%d\n", lg); } vaxgoto(index, nlab, labs) expptr index; register int nlab; struct Labelblock *labs[]; { register int i; register int arrlab; putforce(TYINT, index); p2pi("\tcasel\tr0,$1,$%d", nlab-1); p2pi("L%d:", arrlab = newlabel() ); for(i = 0; i< nlab ; ++i) if( labs[i] ) p2pij("\t.word\tL%d-L%d", labs[i]->labelno, arrlab); } prarif(p, neg, zer, pos) expptr p; int neg, zer, pos; { putforce(p->headblock.vtype, p); if( ISINT(p->headblock.vtype) ) p2pass("\ttstl\tr0"); else p2pass("\ttstd\tr0"); p2pi("\tjlss\tL%d", neg); p2pi("\tjeql\tL%d", zer); p2pi("\tjbr\tL%d", pos); } char *memname(stg, mem) int stg, mem; { static char s[20]; switch(stg) { case STGCOMMON: case STGEXT: sprintf(s, "_%s", varstr(XL, extsymtab[mem].extname) ); break; case STGBSS: case STGINIT: sprintf(s, "v.%d", mem); break; case STGCONST: sprintf(s, "L%d", mem); break; case STGEQUIV: sprintf(s, "q.%d", mem+eqvstart); break; default: fatali("memname: invalid vstg %d", stg); } return(s); } prlocvar(s, len) char *s; ftnint len; { fprintf(asmfile, "\t.lcomm\t%s,%ld\n", s, len); } prext(name, leng, init) char *name; ftnint leng; int init; { if(leng == 0) fprintf(asmfile, "\t.globl\t_%s\n", name); else fprintf(asmfile, "\t.comm\t_%s,%ld\n", name, leng); } prendproc() { } prtail() { } prolog(ep, argvec) struct Entrypoint *ep; struct Addrblock *argvec; { int i, argslot, proflab; int size; register chainp p; register struct Nameblock *q; register struct Dimblock *dp; expptr tp; if(procclass == CLMAIN) p2pass( "_MAIN__:" ); if(ep->entryname) p2ps("_%s:", varstr(XL, ep->entryname->extname)); if(procclass == CLBLOCK) return; prsave(); if(argvec) { argloc = argvec->memoffset->constblock.const.ci + SZINT; /* first slot holds count */ if(proctype == TYCHAR) { mvarg(TYADDR, 0, chslot); mvarg(TYLENG, SZADDR, chlgslot); argslot = SZADDR + SZLENG; } else if( ISCOMPLEX(proctype) ) { mvarg(TYADDR, 0, cxslot); argslot = SZADDR; } else argslot = 0; for(p = ep->arglist ; p ; p =p->nextp) { q = p->datap; mvarg(TYADDR, argslot, q->vardesc.varno); argslot += SZADDR; } for(p = ep->arglist ; p ; p = p->nextp) { q = p->datap; if(q->vtype==TYCHAR || q->vclass==CLPROC) { if(q->vleng && q->vleng->headblock.tag!=TCONST) mvarg(TYLENG, argslot, q->vleng->nameblock.vardesc.varno); argslot += SZLENG; } } p2pi("\taddl3\t$%d,fp,ap", argloc-ARGOFFSET); p2pi("\tmovl\t$%d,(ap)\n", lastargslot/SZADDR); } for(p = ep->arglist ; p ; p = p->nextp) { q = p->datap; if(dp = q->vdim) { for(i = 0 ; i < dp->ndim ; ++i) if(dp->dims[i].dimexpr) puteq( fixtype(cpexpr(dp->dims[i].dimsize)), fixtype(cpexpr(dp->dims[i].dimexpr))); size = typesize[ q->vtype ]; if(q->vtype == TYCHAR) if( ISICON(q->vleng) ) size *= q->vleng->constblock.const.ci; else size = -1; /* on VAX, get more efficient subscripting if subscripts have zero-base, so fudge the argument pointers for arrays. Not done if array bounds are being checked. */ if(dp->basexpr) puteq( cpexpr(fixtype(dp->baseoffset)), cpexpr(fixtype(dp->basexpr))); if(! checksubs) { if(dp->basexpr) { if(size > 0) tp = ICON(size); else tp = cpexpr(q->vleng); putforce(TYINT, fixtype( mkexpr(OPSTAR, tp, cpexpr(dp->baseoffset)) )); p2pi("\tsubl2\tr0,%d(ap)", p->datap->nameblock.vardesc.varno + ARGOFFSET); } else if(dp->baseoffset->constblock.const.ci != 0) { char buff[25]; if(size > 0) { sprintf(buff, "\tsubl2\t$%ld,%d(ap)", dp->baseoffset->constblock.const.ci * size, p->datap->nameblock.vardesc.varno + ARGOFFSET); } else { putforce(TYINT, mkexpr(OPSTAR, cpexpr(dp->baseoffset), cpexpr(q->vleng) )); sprintf(buff, "\tsubl2\tr0,%d(ap)", p->datap->nameblock.vardesc.varno + ARGOFFSET); } p2pass(buff); } } } } if(typeaddr) puteq( cpexpr(typeaddr), mkaddcon(ep->typelabel) ); /* replace to avoid long jump problem putgoto(ep->entrylabel); */ p2pi("\tjmp\tL%d", ep->entrylabel); } prhead(fp) FILEP fp; { #if FAMILY==PCC p2triple(P2LBRACKET, ARGREG-highregvar, procno); p2word( (long) (BITSPERCHAR*autoleng) ); p2flush(); #endif } prdbginfo() { } #ifdef SDB # ifdef UCBVAXASM char *stabdline(code, type) int code; int type; { static char buff[30]; sprintf(buff, "\t.stabd\t0%o,0,0%o\n", code, type); return(buff); } # endif prstab(s, code, type, loc) char *s, *loc; int code, type; { char * stabline(); if(sdbflag) fprintf(asmfile, stabline(s,code,type,loc) ); } char *stabline(s, code, type, loc) register char *s; int code; int type; char *loc; { static char buff[50] = "\t.stab\t\t"; register char *t; register int i = 0; #ifdef UCBVAXASM t = buff + 8; if(s == NULL) buff[6] = 'n'; /* .stabn line */ else { buff[6] = 's'; /* .stabs line */ *t++ = '"'; while(*s!='\0' && *s!=' ' && i<8) { *t++ = *s++; ++i; } *t++ = '"'; *t++ = ','; } #else t = buff + 7; if(s) while( *s!='\0' && *s!=' ' && i<8 ) { *t++ = '\''; *t++ = *s++; *t++ = ','; ++i; } for( ; i<8 ; ++i) { *t++ = '0'; *t++ = ','; } #endif sprintf(t, "0%o,0,0%o,%s\n", code, type, (loc? loc : "0") ); return(buff); } prstleng(np, leng) register struct Nameblock *np; ftnint leng; { ftnint iarrlen(); prstab( varstr(XL,np->varname), N_LENG, 0, convic(leng) ); } stabtype(p) register struct Nameblock *p; { register int type; register int shift; type = types2[p->vtype]; if(p->vdim) { type |= 060; /* .stab code for array */ shift = 2; } else if(p->vclass == CLPROC) { type |= 040; /* .stab code for function */ shift = 2; } else shift = 0; if(p->vstg == STGARG) type |= (020 << shift); /* code for pointer-to */ return(type); } prstssym(np) register struct Nameblock *np; { prstab(varstr(VL,np->varname), N_SSYM, stabtype(np), convic(np->voffset) ); } #endif