📄 vax.c
字号:
/****************************************************************Copyright 1990, 1992, 1993, 1994 by AT&T Bell Laboratories and Bellcore.Permission to use, copy, modify, and distribute this softwareand its documentation for any purpose and without fee is herebygranted, provided that the above copyright notice appear in allcopies and that both that the copyright notice and thispermission notice and warranty disclaimer appear in supportingdocumentation, and that the names of AT&T Bell Laboratories orBellcore or any of their entities not be used in advertising orpublicity pertaining to distribution of the software withoutspecific, written prior permission.AT&T and Bellcore disclaim all warranties with regard to thissoftware, including all implied warranties of merchantabilityand fitness. In no event shall AT&T or Bellcore be liable forany special, indirect or consequential damages or any damageswhatsoever resulting from loss of use, data or profits, whetherin an action of contract, negligence or other tortious action,arising out of or in connection with the use or performance ofthis software.****************************************************************/#include "defs.h"#include "pccdefs.h"#include "output.h"int regnum[] = { 11, 10, 9, 8, 7, 6 };/* Put out a constant integer */ void#ifdef KR_headersprconi(fp, n) FILEP fp; ftnint n;#elseprconi(FILEP fp, ftnint n)#endif{ fprintf(fp, "\t%ld\n", n);}/* Put out a constant address */ void#ifdef KR_headersprcona(fp, a) FILEP fp; ftnint a;#elseprcona(FILEP fp, ftnint a)#endif{ fprintf(fp, "\tL%ld\n", a);} void#ifdef KR_headersprconr(fp, x, k) FILEP fp; Constp x; int k;#elseprconr(FILEP fp, Constp x, int k)#endif{ char *x0, *x1; char cdsbuf0[64], cdsbuf1[64]; if (k > 1) { if (x->vstg) { x0 = x->Const.cds[0]; x1 = x->Const.cds[1]; } else { x0 = cds(dtos(x->Const.cd[0]), cdsbuf0); x1 = cds(dtos(x->Const.cd[1]), cdsbuf1); } fprintf(fp, "\t%s %s\n", x0, x1); } else fprintf(fp, "\t%s\n", x->vstg ? x->Const.cds[0] : cds(dtos(x->Const.cd[0]), cdsbuf0));} char *#ifdef KR_headersmemname(stg, mem) int stg; long mem;#elsememname(int stg, long mem)#endif{ static char s[20]; switch(stg) { case STGCOMMON: case STGEXT: sprintf(s, "_%s", extsymtab[mem].cextname); break; case STGBSS: case STGINIT: sprintf(s, "v.%ld", mem); break; case STGCONST: sprintf(s, "L%ld", mem); break; case STGEQUIV: sprintf(s, "q.%ld", mem+eqvstart); break; default: badstg("memname", stg); } return(s);}extern void addrlit Argdcl((Addrp));/* make_int_expr -- takes an arbitrary expression, and replaces all occurrences of arguments with indirection */ expptr#ifdef KR_headersmake_int_expr(e) expptr e;#elsemake_int_expr(expptr e)#endif{ chainp listp; Addrp ap; if (e != ENULL) switch (e -> tag) { case TADDR: if (e -> addrblock.vstg == STGARG && !e->addrblock.isarray) e = mkexpr (OPWHATSIN, e, ENULL); break; case TEXPR: e -> exprblock.leftp = make_int_expr (e -> exprblock.leftp); e -> exprblock.rightp = make_int_expr (e -> exprblock.rightp); break; case TLIST: for(listp = e->listblock.listp; listp; listp = listp->nextp) if ((ap = (Addrp)listp->datap) && ap->tag == TADDR && ap->uname_tag == UNAM_CONST) addrlit(ap); break; default: break; } /* switch */ return e;} /* make_int_expr *//* prune_left_conv -- used in prolog() to strip type cast away from left-hand side of parameter adjustments. This is necessary to avoid error messages from cktype() */ expptr#ifdef KR_headersprune_left_conv(e) expptr e;#elseprune_left_conv(expptr e)#endif{ struct Exprblock *leftp; if (e && e -> tag == TEXPR && e -> exprblock.leftp && e -> exprblock.leftp -> tag == TEXPR) { leftp = &(e -> exprblock.leftp -> exprblock); if (leftp -> opcode == OPCONV) { e -> exprblock.leftp = leftp -> leftp; free ((charptr) leftp); } } return e;} /* prune_left_conv */ static int wrote_comment; static FILE *comment_file; static voidwrite_comment(Void){ if (!wrote_comment) { wrote_comment = 1; nice_printf (comment_file, "/* Parameter adjustments */\n"); } } static int *count_args(Void){ register int *ac; register chainp cp; register struct Entrypoint *ep; register Namep q; ac = (int *)ckalloc(nallargs*sizeof(int)); for(ep = entries; ep; ep = ep->entnextp) for(cp = ep->arglist; cp; cp = cp->nextp) if (q = (Namep)cp->datap) ac[q->argno]++; return ac; } static int nu, *refs, *used; static void awalk Argdcl((expptr)); static void#ifdef KR_headersaawalk(P) struct Primblock *P;#elseaawalk(struct Primblock *P)#endif{ chainp p; expptr q; if (P->argsp) for(p = P->argsp->listp; p; p = p->nextp) { q = (expptr)p->datap; if (q->tag != TCONST) awalk(q); } if (P->namep->vtype == TYCHAR) { if (q = P->fcharp) awalk(q); if (q = P->lcharp) awalk(q); } } static void#ifdef KR_headersafwalk(P) struct Primblock *P;#elseafwalk(struct Primblock *P)#endif{ chainp p; expptr q; Namep np; for(p = P->argsp->listp; p; p = p->nextp) { q = (expptr)p->datap; switch(q->tag) { case TPRIM: np = q->primblock.namep; if (np->vknownarg) if (!refs[np->argno]++) used[nu++] = np->argno; if (q->primblock.argsp == 0) { if (q->primblock.namep->vclass == CLPROC && q->primblock.namep->vprocclass != PTHISPROC || q->primblock.namep->vdim != NULL) continue; } default: awalk(q); /* no break */ case TCONST: continue; } } } static void#ifdef KR_headersawalk(e) expptr e;#elseawalk(expptr e)#endif{ Namep np; top: if (!e) return; switch(e->tag) { default: badtag("awalk", e->tag); case TCONST: case TERROR: case TLIST: return; case TADDR: if (e->addrblock.uname_tag == UNAM_NAME) { np = e->addrblock.user.name; if (np->vknownarg && !refs[np->argno]++) used[nu++] = np->argno; } e = e->addrblock.memoffset; goto top; case TPRIM: np = e->primblock.namep; if (np->vknownarg && !refs[np->argno]++) used[nu++] = np->argno; if (e->primblock.argsp && np->vclass != CLVAR) afwalk((struct Primblock *)e); else aawalk((struct Primblock *)e); return; case TEXPR: awalk(e->exprblock.rightp); e = e->exprblock.leftp; goto top; } } static chainp#ifdef KR_headersargsort(p0) chainp p0;#elseargsort(chainp p0)#endif{ Namep *args, q, *stack; int i, nargs, nout, nst; chainp *d, *da, p, rv, *rvp; struct Dimblock *dp; if (!p0) return p0; for(nargs = 0, p = p0; p; p = p->nextp) nargs++; args = (Namep *)ckalloc(i = nargs*(sizeof(Namep) + 2*sizeof(chainp) + 2*sizeof(int))); memset((char *)args, 0, i); stack = args + nargs; d = (chainp *)(stack + nargs); refs = (int *)(d + nargs); used = refs + nargs; for(p = p0; p; p = p->nextp) { q = (Namep) p->datap; args[q->argno] = q; } for(p = p0; p; p = p->nextp) { q = (Namep) p->datap; if (!(dp = q->vdim)) continue; i = dp->ndim; while(--i >= 0) awalk(dp->dims[i].dimexpr); awalk(dp->basexpr); while(nu > 0) { refs[i = used[--nu]] = 0; d[i] = mkchain((char *)q, d[i]); } } for(i = nst = 0; i < nargs; i++) for(p = d[i]; p; p = p->nextp) refs[((Namep)p->datap)->argno]++; while(--i >= 0) if (!refs[i]) stack[nst++] = args[i]; if (nst == nargs) { rv = p0; goto done; } nout = 0; rv = 0; rvp = &rv; while(nst > 0) { nout++; q = stack[--nst]; *rvp = p = mkchain((char *)q, CHNULL); rvp = &p->nextp; da = d + q->argno; for(p = *da; p; p = p->nextp) if (!--refs[(q = (Namep)p->datap)->argno]) stack[nst++] = q; frchain(da); } if (nout < nargs) for(i = 0; i < nargs; i++) if (refs[i]) { q = args[i]; errstr("Can't adjust %.38s correctly\n\ due to dependencies among arguments.", q->fvarname); *rvp = p = mkchain((char *)q, CHNULL); rvp = &p->nextp; frchain(d+i); } done: free((char *)args); return rv; } void#ifdef KR_headersprolog(outfile, p) FILE *outfile; register chainp p;#elseprolog(FILE *outfile, register chainp p)#endif{ int addif, addif0, i, nd, size; int *ac; register Namep q; register struct Dimblock *dp; chainp p0, p1; if(procclass == CLBLOCK) return; p0 = p; p1 = p = argsort(p); wrote_comment = 0; comment_file = outfile; ac = 0;/* Compute the base addresses and offsets for the array parameters, and assign these values to local variables */ addif = addif0 = nentry > 1; for(; p ; p = p->nextp) { q = (Namep) p->datap; if(dp = q->vdim) /* if this param is an array ... */ { expptr Q, expr; /* See whether to protect the following with an if. */ /* This only happens when there are multiple entries. */ nd = dp->ndim - 1; if (addif0) { if (!ac) ac = count_args(); if (ac[q->argno] == nentry) addif = 0; else if (dp->basexpr || dp->baseoffset->constblock.Const.ci) addif = 1; else for(addif = i = 0; i <= nd; i++) if (dp->dims[i].dimexpr && (i < nd || !q->vlastdim)) { addif = 1; break; } if (addif) { write_comment(); nice_printf(outfile, "if (%s) {\n", /*}*/ q->cvarname); next_tab(outfile); } } for(i = 0 ; i <= nd; ++i)/* Store the variable length of each dimension (which is fixed upon runtime procedure entry) into a local variable */ if ((Q = dp->dims[i].dimexpr) && (i < nd || !q->vlastdim)) { expr = (expptr)cpexpr(Q); write_comment(); out_and_free_statement (outfile, mkexpr (OPASSIGN, fixtype(cpexpr(dp->dims[i].dimsize)), expr)); } /* if dp -> dims[i].dimexpr *//* size will equal the size of a single element, or -1 if the type is variable length character type */ size = typesize[ q->vtype ]; if(q->vtype == TYCHAR) if( ISICON(q->vleng) ) size *= q->vleng->constblock.Const.ci; else size = -1; /* Fudge the argument pointers for arrays so subscripts * are 0-based. Not done if array bounds are being checked. */ if(dp->basexpr) {/* Compute the base offset for this procedure */ write_comment(); out_and_free_statement (outfile, mkexpr (OPASSIGN, cpexpr(fixtype(dp->baseoffset)), cpexpr(fixtype(dp->basexpr)))); } /* if dp -> basexpr */ if(! checksubs) { if(dp->basexpr) { expptr tp;/* If the base of this array has a variable adjustment ... */ tp = (expptr) cpexpr (dp -> baseoffset); if(size < 0 || q -> vtype == TYCHAR) tp = mkexpr (OPSTAR, tp, cpexpr (q -> vleng)); write_comment(); tp = mkexpr (OPMINUSEQ, mkconv (TYADDR, (expptr)p->datap), mkconv(TYINT, fixtype (fixtype (tp))));/* Avoid type clash by removing the type conversion */ tp = prune_left_conv (tp); out_and_free_statement (outfile, tp); } else if(dp->baseoffset->constblock.Const.ci != 0) {/* if the base of this array has a nonzero constant adjustment ... */ expptr tp; write_comment(); if(size > 0 && q -> vtype != TYCHAR) { tp = prune_left_conv (mkexpr (OPMINUSEQ, mkconv (TYADDR, (expptr)p->datap), mkconv (TYINT, fixtype (cpexpr (dp->baseoffset))))); out_and_free_statement (outfile, tp); } else { tp = prune_left_conv (mkexpr (OPMINUSEQ, mkconv (TYADDR, (expptr)p->datap), mkconv (TYINT, fixtype (mkexpr (OPSTAR, cpexpr (dp -> baseoffset), cpexpr (q -> vleng)))))); out_and_free_statement (outfile, tp); } /* else */ } /* if dp -> baseoffset -> const */ } /* if !checksubs */ if (addif) { nice_printf(outfile, /*{*/ "}\n"); prev_tab(outfile); } } } if (wrote_comment) nice_printf (outfile, "\n/* Function Body */\n"); if (ac) free((char *)ac); if (p0 != p1) frchain(&p1);} /* prolog */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -