00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "defs.h"
00025 #include "pccdefs.h"
00026 #include "output.h"
00027
00028 int regnum[] = {
00029 11, 10, 9, 8, 7, 6 };
00030
00031
00032
00033 void
00034 #ifdef KR_headers
00035 prconi(fp, n)
00036 FILEP fp;
00037 ftnint n;
00038 #else
00039 prconi(FILEP fp, ftnint n)
00040 #endif
00041 {
00042 fprintf(fp, "\t%ld\n", n);
00043 }
00044
00045 #ifndef NO_LONG_LONG
00046 void
00047 #ifdef KR_headers
00048 prconq(fp, n) FILEP fp; Llong n;
00049 #else
00050 prconq(FILEP fp, Llong n)
00051 #endif
00052 {
00053 fprintf(fp, "\t%lld\n", n);
00054 }
00055 #endif
00056
00057
00058
00059
00060 void
00061 #ifdef KR_headers
00062 prcona(fp, a)
00063 FILEP fp;
00064 ftnint a;
00065 #else
00066 prcona(FILEP fp, ftnint a)
00067 #endif
00068 {
00069 fprintf(fp, "\tL%ld\n", a);
00070 }
00071
00072
00073 void
00074 #ifdef KR_headers
00075 prconr(fp, x, k)
00076 FILEP fp;
00077 Constp x;
00078 int k;
00079 #else
00080 prconr(FILEP fp, Constp x, int k)
00081 #endif
00082 {
00083 char *x0, *x1;
00084 char cdsbuf0[64], cdsbuf1[64];
00085
00086 if (k > 1) {
00087 if (x->vstg) {
00088 x0 = x->Const.cds[0];
00089 x1 = x->Const.cds[1];
00090 }
00091 else {
00092 x0 = cds(dtos(x->Const.cd[0]), cdsbuf0);
00093 x1 = cds(dtos(x->Const.cd[1]), cdsbuf1);
00094 }
00095 fprintf(fp, "\t%s %s\n", x0, x1);
00096 }
00097 else
00098 fprintf(fp, "\t%s\n", x->vstg ? x->Const.cds[0]
00099 : cds(dtos(x->Const.cd[0]), cdsbuf0));
00100 }
00101
00102
00103 char *
00104 #ifdef KR_headers
00105 memname(stg, mem)
00106 int stg;
00107 long mem;
00108 #else
00109 memname(int stg, long mem)
00110 #endif
00111 {
00112 static char s[20];
00113
00114 switch(stg)
00115 {
00116 case STGCOMMON:
00117 case STGEXT:
00118 sprintf(s, "_%s", extsymtab[mem].cextname);
00119 break;
00120
00121 case STGBSS:
00122 case STGINIT:
00123 sprintf(s, "v.%ld", mem);
00124 break;
00125
00126 case STGCONST:
00127 sprintf(s, "L%ld", mem);
00128 break;
00129
00130 case STGEQUIV:
00131 sprintf(s, "q.%ld", mem+eqvstart);
00132 break;
00133
00134 default:
00135 badstg("memname", stg);
00136 }
00137 return(s);
00138 }
00139
00140 extern void addrlit Argdcl((Addrp));
00141
00142
00143
00144
00145 expptr
00146 #ifdef KR_headers
00147 make_int_expr(e)
00148 expptr e;
00149 #else
00150 make_int_expr(expptr e)
00151 #endif
00152 {
00153 chainp listp;
00154 Addrp ap;
00155 expptr e1;
00156
00157 if (e != ENULL)
00158 switch (e -> tag) {
00159 case TADDR:
00160 if (e->addrblock.isarray) {
00161 if (e1 = e->addrblock.memoffset)
00162 e->addrblock.memoffset = make_int_expr(e1);
00163 }
00164 else if (e->addrblock.vstg == STGARG
00165 || e->addrblock.vstg == STGCOMMON
00166 && e->addrblock.uname_tag == UNAM_NAME
00167 && e->addrblock.user.name->vcommequiv)
00168 e = mkexpr(OPWHATSIN, e, ENULL);
00169 break;
00170 case TEXPR:
00171 e -> exprblock.leftp = make_int_expr (e -> exprblock.leftp);
00172 e -> exprblock.rightp = make_int_expr (e -> exprblock.rightp);
00173 break;
00174 case TLIST:
00175 for(listp = e->listblock.listp; listp; listp = listp->nextp)
00176 if ((ap = (Addrp)listp->datap)
00177 && ap->tag == TADDR
00178 && ap->uname_tag == UNAM_CONST)
00179 addrlit(ap);
00180 break;
00181 default:
00182 break;
00183 }
00184
00185 return e;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 expptr
00195 #ifdef KR_headers
00196 prune_left_conv(e)
00197 expptr e;
00198 #else
00199 prune_left_conv(expptr e)
00200 #endif
00201 {
00202 struct Exprblock *leftp;
00203
00204 if (e && e -> tag == TEXPR && e -> exprblock.leftp &&
00205 e -> exprblock.leftp -> tag == TEXPR) {
00206 leftp = &(e -> exprblock.leftp -> exprblock);
00207 if (leftp -> opcode == OPCONV) {
00208 e -> exprblock.leftp = leftp -> leftp;
00209 free ((charptr) leftp);
00210 }
00211 }
00212
00213 return e;
00214 }
00215
00216
00217 static int wrote_comment;
00218 static FILE *comment_file;
00219
00220 static void
00221 write_comment(Void)
00222 {
00223 if (!wrote_comment) {
00224 wrote_comment = 1;
00225 nice_printf (comment_file, "/* Parameter adjustments */\n");
00226 }
00227 }
00228
00229 static int *
00230 count_args(Void)
00231 {
00232 register int *ac;
00233 register chainp cp;
00234 register struct Entrypoint *ep;
00235 register Namep q;
00236
00237 ac = (int *)ckalloc(nallargs*sizeof(int));
00238
00239 for(ep = entries; ep; ep = ep->entnextp)
00240 for(cp = ep->arglist; cp; cp = cp->nextp)
00241 if (q = (Namep)cp->datap)
00242 ac[q->argno]++;
00243 return ac;
00244 }
00245
00246 static int nu, *refs, *used;
00247 static void awalk Argdcl((expptr));
00248
00249 static void
00250 #ifdef KR_headers
00251 aawalk(P)
00252 struct Primblock *P;
00253 #else
00254 aawalk(struct Primblock *P)
00255 #endif
00256 {
00257 chainp p;
00258 expptr q;
00259
00260 if (P->argsp)
00261 for(p = P->argsp->listp; p; p = p->nextp) {
00262 q = (expptr)p->datap;
00263 if (q->tag != TCONST)
00264 awalk(q);
00265 }
00266 if (P->namep->vtype == TYCHAR) {
00267 if (q = P->fcharp)
00268 awalk(q);
00269 if (q = P->lcharp)
00270 awalk(q);
00271 }
00272 }
00273
00274 static void
00275 #ifdef KR_headers
00276 afwalk(P)
00277 struct Primblock *P;
00278 #else
00279 afwalk(struct Primblock *P)
00280 #endif
00281 {
00282 chainp p;
00283 expptr q;
00284 Namep np;
00285
00286 for(p = P->argsp->listp; p; p = p->nextp) {
00287 q = (expptr)p->datap;
00288 switch(q->tag) {
00289 case TPRIM:
00290 np = q->primblock.namep;
00291 if (np->vknownarg)
00292 if (!refs[np->argno]++)
00293 used[nu++] = np->argno;
00294 if (q->primblock.argsp == 0) {
00295 if (q->primblock.namep->vclass == CLPROC
00296 && q->primblock.namep->vprocclass
00297 != PTHISPROC
00298 || q->primblock.namep->vdim != NULL)
00299 continue;
00300 }
00301 default:
00302 awalk(q);
00303
00304 case TCONST:
00305 continue;
00306 }
00307 }
00308 }
00309
00310 static void
00311 #ifdef KR_headers
00312 awalk(e)
00313 expptr e;
00314 #else
00315 awalk(expptr e)
00316 #endif
00317 {
00318 Namep np;
00319 top:
00320 if (!e)
00321 return;
00322 switch(e->tag) {
00323 default:
00324 badtag("awalk", e->tag);
00325 case TCONST:
00326 case TERROR:
00327 case TLIST:
00328 return;
00329 case TADDR:
00330 if (e->addrblock.uname_tag == UNAM_NAME) {
00331 np = e->addrblock.user.name;
00332 if (np->vknownarg && !refs[np->argno]++)
00333 used[nu++] = np->argno;
00334 }
00335 e = e->addrblock.memoffset;
00336 goto top;
00337 case TPRIM:
00338 np = e->primblock.namep;
00339 if (np->vknownarg && !refs[np->argno]++)
00340 used[nu++] = np->argno;
00341 if (e->primblock.argsp && np->vclass != CLVAR)
00342 afwalk((struct Primblock *)e);
00343 else
00344 aawalk((struct Primblock *)e);
00345 return;
00346 case TEXPR:
00347 awalk(e->exprblock.rightp);
00348 e = e->exprblock.leftp;
00349 goto top;
00350 }
00351 }
00352
00353 static chainp
00354 #ifdef KR_headers
00355 argsort(p0)
00356 chainp p0;
00357 #else
00358 argsort(chainp p0)
00359 #endif
00360 {
00361 Namep *args, q, *stack;
00362 int i, nargs, nout, nst;
00363 chainp *d, *da, p, rv, *rvp;
00364 struct Dimblock *dp;
00365
00366 if (!p0)
00367 return p0;
00368 for(nargs = 0, p = p0; p; p = p->nextp)
00369 nargs++;
00370 args = (Namep *)ckalloc(i = nargs*(sizeof(Namep) + 2*sizeof(chainp)
00371 + 2*sizeof(int)));
00372 memset((char *)args, 0, i);
00373 stack = args + nargs;
00374 d = (chainp *)(stack + nargs);
00375 refs = (int *)(d + nargs);
00376 used = refs + nargs;
00377
00378 for(p = p0; p; p = p->nextp) {
00379 q = (Namep) p->datap;
00380 args[q->argno] = q;
00381 }
00382 for(p = p0; p; p = p->nextp) {
00383 q = (Namep) p->datap;
00384 if (!(dp = q->vdim))
00385 continue;
00386 i = dp->ndim;
00387 while(--i >= 0)
00388 awalk(dp->dims[i].dimexpr);
00389 awalk(dp->basexpr);
00390 while(nu > 0) {
00391 refs[i = used[--nu]] = 0;
00392 d[i] = mkchain((char *)q, d[i]);
00393 }
00394 }
00395 for(i = nst = 0; i < nargs; i++)
00396 for(p = d[i]; p; p = p->nextp)
00397 refs[((Namep)p->datap)->argno]++;
00398 while(--i >= 0)
00399 if (!refs[i])
00400 stack[nst++] = args[i];
00401 if (nst == nargs) {
00402 rv = p0;
00403 goto done;
00404 }
00405 nout = 0;
00406 rv = 0;
00407 rvp = &rv;
00408 while(nst > 0) {
00409 nout++;
00410 q = stack[--nst];
00411 *rvp = p = mkchain((char *)q, CHNULL);
00412 rvp = &p->nextp;
00413 da = d + q->argno;
00414 for(p = *da; p; p = p->nextp)
00415 if (!--refs[(q = (Namep)p->datap)->argno])
00416 stack[nst++] = q;
00417 frchain(da);
00418 }
00419 if (nout < nargs)
00420 for(i = 0; i < nargs; i++)
00421 if (refs[i]) {
00422 q = args[i];
00423 errstr("Can't adjust %.38s correctly\n\
00424 due to dependencies among arguments.",
00425 q->fvarname);
00426 *rvp = p = mkchain((char *)q, CHNULL);
00427 rvp = &p->nextp;
00428 frchain(d+i);
00429 }
00430 done:
00431 free((char *)args);
00432 return rv;
00433 }
00434
00435 void
00436 #ifdef KR_headers
00437 prolog(outfile, p)
00438 FILE *outfile;
00439 register chainp p;
00440 #else
00441 prolog(FILE *outfile, register chainp p)
00442 #endif
00443 {
00444 int addif, addif0, i, nd;
00445 ftnint size;
00446 int *ac;
00447 register Namep q;
00448 register struct Dimblock *dp;
00449 chainp p0, p1;
00450
00451 if(procclass == CLBLOCK)
00452 return;
00453 p0 = p;
00454 p1 = p = argsort(p);
00455 wrote_comment = 0;
00456 comment_file = outfile;
00457 ac = 0;
00458
00459
00460
00461
00462 addif = addif0 = nentry > 1;
00463 for(; p ; p = p->nextp)
00464 {
00465 q = (Namep) p->datap;
00466 if(dp = q->vdim)
00467 {
00468 expptr Q, expr;
00469
00470
00471
00472
00473 nd = dp->ndim - 1;
00474 if (addif0) {
00475 if (!ac)
00476 ac = count_args();
00477 if (ac[q->argno] == nentry)
00478 addif = 0;
00479 else if (dp->basexpr
00480 || dp->baseoffset->constblock.Const.ci)
00481 addif = 1;
00482 else for(addif = i = 0; i <= nd; i++)
00483 if (dp->dims[i].dimexpr
00484 && (i < nd || !q->vlastdim)) {
00485 addif = 1;
00486 break;
00487 }
00488 if (addif) {
00489 write_comment();
00490 nice_printf(outfile, "if (%s) {\n",
00491 q->cvarname);
00492 next_tab(outfile);
00493 }
00494 }
00495 for(i = 0 ; i <= nd; ++i)
00496
00497
00498
00499
00500 if ((Q = dp->dims[i].dimexpr)
00501 && (i < nd || !q->vlastdim)) {
00502 expr = (expptr)cpexpr(Q);
00503 write_comment();
00504 out_and_free_statement (outfile, mkexpr (OPASSIGN,
00505 fixtype(cpexpr(dp->dims[i].dimsize)), expr));
00506 }
00507
00508
00509
00510
00511 size = typesize[ q->vtype ];
00512 if(q->vtype == TYCHAR)
00513 if( ISICON(q->vleng) )
00514 size *= q->vleng->constblock.Const.ci;
00515 else
00516 size = -1;
00517
00518
00519
00520
00521 if(dp->basexpr) {
00522
00523
00524
00525 write_comment();
00526 out_and_free_statement (outfile, mkexpr (OPASSIGN,
00527 cpexpr(fixtype(dp->baseoffset)),
00528 cpexpr(fixtype(dp->basexpr))));
00529 }
00530
00531 if(! checksubs) {
00532 if(dp->basexpr) {
00533 expptr tp;
00534
00535
00536
00537 tp = (expptr) cpexpr (dp -> baseoffset);
00538 if(size < 0 || q -> vtype == TYCHAR)
00539 tp = mkexpr (OPSTAR, tp, cpexpr (q -> vleng));
00540
00541 write_comment();
00542 tp = mkexpr (OPMINUSEQ,
00543 mkconv (TYADDR, (expptr)p->datap),
00544 mkconv(TYINT, fixtype
00545 (fixtype (tp))));
00546
00547 tp = prune_left_conv (tp);
00548 out_and_free_statement (outfile, tp);
00549 } else if(dp->baseoffset->constblock.Const.ci != 0) {
00550
00551
00552
00553 expptr tp;
00554
00555 write_comment();
00556 if(size > 0 && q -> vtype != TYCHAR) {
00557 tp = prune_left_conv (mkexpr (OPMINUSEQ,
00558 mkconv (TYADDR, (expptr)p->datap),
00559 mkconv (TYINT, fixtype
00560 (cpexpr (dp->baseoffset)))));
00561 out_and_free_statement (outfile, tp);
00562 } else {
00563 tp = prune_left_conv (mkexpr (OPMINUSEQ,
00564 mkconv (TYADDR, (expptr)p->datap),
00565 mkconv (TYINT, fixtype
00566 (mkexpr (OPSTAR, cpexpr (dp -> baseoffset),
00567 cpexpr (q -> vleng))))));
00568 out_and_free_statement (outfile, tp);
00569 }
00570 }
00571 }
00572
00573 if (addif) {
00574 nice_printf(outfile, "}\n");
00575 prev_tab(outfile);
00576 }
00577 }
00578 }
00579 if (wrote_comment)
00580 nice_printf (outfile, "\n/* Function Body */\n");
00581 if (ac)
00582 free((char *)ac);
00583 if (p0 != p1)
00584 frchain(&p1);
00585 }