00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "defs.h"
00028 #include "pccdefs.h"
00029 #include "output.h"
00030 #include "names.h"
00031 #include "p1defs.h"
00032
00033 static Addrp intdouble Argdcl((Addrp));
00034 static Addrp putcx1 Argdcl((tagptr));
00035 static tagptr putaddr Argdcl((tagptr));
00036 static tagptr putcall Argdcl((tagptr, Addrp*));
00037 static tagptr putcat Argdcl((tagptr, tagptr));
00038 static Addrp putch1 Argdcl((tagptr));
00039 static tagptr putchcmp Argdcl((tagptr));
00040 static tagptr putcheq Argdcl((tagptr));
00041 static void putct1 Argdcl((tagptr, Addrp, Addrp, ptr));
00042 static tagptr putcxcmp Argdcl((tagptr));
00043 static Addrp putcxeq Argdcl((tagptr));
00044 static tagptr putmnmx Argdcl((tagptr));
00045 static tagptr putop Argdcl((tagptr));
00046 static tagptr putpower Argdcl((tagptr));
00047
00048 extern int init_ac[TYSUBR+1];
00049 extern int ops2[];
00050 extern int proc_argchanges, proc_protochanges;
00051 extern int krparens;
00052
00053 #define P2BUFFMAX 128
00054
00055
00056
00057
00058 void
00059 #ifdef KR_headers
00060 puthead(s, classKRH)
00061 char *s;
00062 int classKRH;
00063 #else
00064 puthead(char *s, int classKRH)
00065 #endif
00066 {
00067 if (headerdone == NO) {
00068 if (classKRH == CLMAIN)
00069 s = "MAIN__";
00070 p1_head (classKRH, s);
00071 headerdone = YES;
00072 }
00073 }
00074
00075 void
00076 #ifdef KR_headers
00077 putif(p, else_if_p)
00078 register expptr p;
00079 int else_if_p;
00080 #else
00081 putif(register expptr p, int else_if_p)
00082 #endif
00083 {
00084 register int k;
00085 int n;
00086 long where;
00087
00088 if (else_if_p) {
00089 p1put(P1_ELSEIFSTART);
00090 where = ftell(pass1_file);
00091 }
00092 if( !ISLOGICAL((k = (p = fixtype(p))->headblock.vtype )) )
00093 {
00094 if(k != TYERROR)
00095 err("non-logical expression in IF statement");
00096 }
00097 else {
00098 if (else_if_p) {
00099 if (ei_next >= ei_last)
00100 {
00101 k = ei_last - ei_first;
00102 n = k + 100;
00103 ei_next = mem(n,0);
00104 ei_last = ei_first + n;
00105 if (k)
00106 memcpy(ei_next, ei_first, k);
00107 ei_first = ei_next;
00108 ei_next += k;
00109 ei_last = ei_first + n;
00110 }
00111 p = putx(p);
00112 if (*ei_next++ = ftell(pass1_file) > where) {
00113 p1_if(p);
00114 new_endif();
00115 }
00116 else
00117 p1_elif(p);
00118 }
00119 else {
00120 p = putx(p);
00121 p1_if(p);
00122 }
00123 }
00124 }
00125
00126 void
00127 #ifdef KR_headers
00128 putout(p)
00129 expptr p;
00130 #else
00131 putout(expptr p)
00132 #endif
00133 {
00134 p1_expr (p);
00135
00136
00137
00138 }
00139
00140
00141 void
00142 #ifdef KR_headers
00143 putcmgo(index, nlab, labs)
00144 expptr index;
00145 int nlab;
00146 struct Labelblock **labs;
00147 #else
00148 putcmgo(expptr index, int nlab, struct Labelblock **labs)
00149 #endif
00150 {
00151 if(! ISINT(index->headblock.vtype) )
00152 {
00153 execerr("computed goto index must be integer", CNULL);
00154 return;
00155 }
00156
00157 p1comp_goto (index, nlab, labs);
00158 }
00159
00160 static expptr
00161 #ifdef KR_headers
00162 krput(p)
00163 register expptr p;
00164 #else
00165 krput(register expptr p)
00166 #endif
00167 {
00168 register expptr e, e1;
00169 register unsigned op;
00170 int t = krparens == 2 ? TYDREAL : p->exprblock.vtype;
00171
00172 op = p->exprblock.opcode;
00173 e = p->exprblock.leftp;
00174 if (e->tag == TEXPR && e->exprblock.opcode == op) {
00175 e1 = (expptr)mktmp(t, ENULL);
00176 putout(putassign(cpexpr(e1), e));
00177 p->exprblock.leftp = e1;
00178 }
00179 else
00180 p->exprblock.leftp = putx(e);
00181
00182 e = p->exprblock.rightp;
00183 if (e->tag == TEXPR && e->exprblock.opcode == op) {
00184 e1 = (expptr)mktmp(t, ENULL);
00185 putout(putassign(cpexpr(e1), e));
00186 p->exprblock.rightp = e1;
00187 }
00188 else
00189 p->exprblock.rightp = putx(e);
00190 return p;
00191 }
00192
00193 expptr
00194 #ifdef KR_headers
00195 putx(p)
00196 register expptr p;
00197 #else
00198 putx(register expptr p)
00199 #endif
00200 {
00201 int opc;
00202 int k;
00203
00204 if (p)
00205 switch(p->tag)
00206 {
00207 case TERROR:
00208 break;
00209
00210 case TCONST:
00211 switch(p->constblock.vtype)
00212 {
00213 case TYLOGICAL1:
00214 case TYLOGICAL2:
00215 case TYLOGICAL:
00216 #ifdef TYQUAD
00217 case TYQUAD:
00218 #endif
00219 case TYLONG:
00220 case TYSHORT:
00221 case TYINT1:
00222 break;
00223
00224 case TYADDR:
00225 break;
00226 case TYREAL:
00227 case TYDREAL:
00228
00229
00230
00231
00232 break;
00233 default:
00234 p = putx( (expptr)putconst((Constp)p) );
00235 break;
00236 }
00237 break;
00238
00239 case TEXPR:
00240 switch(opc = p->exprblock.opcode)
00241 {
00242 case OPCALL:
00243 case OPCCALL:
00244 if( ISCOMPLEX(p->exprblock.vtype) )
00245 p = putcxop(p);
00246 else p = putcall(p, (Addrp *)NULL);
00247 break;
00248
00249 case OPMIN:
00250 case OPMAX:
00251 p = putmnmx(p);
00252 break;
00253
00254
00255 case OPASSIGN:
00256 if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
00257 || ISCOMPLEX(p->exprblock.rightp->headblock.vtype)) {
00258 (void) putcxeq(p);
00259 p = ENULL;
00260 } else if( ISCHAR(p) )
00261 p = putcheq(p);
00262 else
00263 goto putopp;
00264 break;
00265
00266 case OPEQ:
00267 case OPNE:
00268 if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
00269 ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
00270 {
00271 p = putcxcmp(p);
00272 break;
00273 }
00274 case OPLT:
00275 case OPLE:
00276 case OPGT:
00277 case OPGE:
00278 if(ISCHAR(p->exprblock.leftp))
00279 {
00280 p = putchcmp(p);
00281 break;
00282 }
00283 goto putopp;
00284
00285 case OPPOWER:
00286 p = putpower(p);
00287 break;
00288
00289 case OPSTAR:
00290
00291 if(INT(p->exprblock.leftp->headblock.vtype) &&
00292 ISICON(p->exprblock.rightp) &&
00293 ( (k = log_2(p->exprblock.rightp->constblock.Const.ci))>0) )
00294 {
00295 p->exprblock.opcode = OPLSHIFT;
00296 frexpr(p->exprblock.rightp);
00297 p->exprblock.rightp = ICON(k);
00298 goto putopp;
00299 }
00300 if (krparens && ISREAL(p->exprblock.vtype))
00301 return krput(p);
00302
00303 case OPMOD:
00304 goto putopp;
00305 case OPPLUS:
00306 if (krparens && ISREAL(p->exprblock.vtype))
00307 return krput(p);
00308 case OPMINUS:
00309 case OPSLASH:
00310 case OPNEG:
00311 case OPNEG1:
00312 case OPABS:
00313 case OPDABS:
00314 if( ISCOMPLEX(p->exprblock.vtype) )
00315 p = putcxop(p);
00316 else goto putopp;
00317 break;
00318
00319 case OPCONV:
00320 if( ISCOMPLEX(p->exprblock.vtype) )
00321 p = putcxop(p);
00322 else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
00323 {
00324 p = putx( mkconv(p->exprblock.vtype,
00325 (expptr)realpart(putcx1(p->exprblock.leftp))));
00326 }
00327 else goto putopp;
00328 break;
00329
00330 case OPNOT:
00331 case OPOR:
00332 case OPAND:
00333 case OPEQV:
00334 case OPNEQV:
00335 case OPADDR:
00336 case OPPLUSEQ:
00337 case OPSTAREQ:
00338 case OPCOMMA:
00339 case OPQUEST:
00340 case OPCOLON:
00341 case OPBITOR:
00342 case OPBITAND:
00343 case OPBITXOR:
00344 case OPBITNOT:
00345 case OPLSHIFT:
00346 case OPRSHIFT:
00347 case OPASSIGNI:
00348 case OPIDENTITY:
00349 case OPCHARCAST:
00350 case OPMIN2:
00351 case OPMAX2:
00352 case OPDMIN:
00353 case OPDMAX:
00354 case OPBITTEST:
00355 case OPBITCLR:
00356 case OPBITSET:
00357 #ifdef TYQUAD
00358 case OPQBITSET:
00359 case OPQBITCLR:
00360 #endif
00361 putopp:
00362 p = putop(p);
00363 break;
00364
00365 case OPCONCAT:
00366
00367 p = (expptr)putch1(p);
00368 break;
00369
00370 default:
00371 badop("putx", opc);
00372 p = errnode ();
00373 }
00374 break;
00375
00376 case TADDR:
00377 p = putaddr(p);
00378 break;
00379
00380 default:
00381 badtag("putx", p->tag);
00382 p = errnode ();
00383 }
00384
00385 return p;
00386 }
00387
00388
00389
00390 LOCAL expptr
00391 #ifdef KR_headers
00392 putop(p)
00393 expptr p;
00394 #else
00395 putop(expptr p)
00396 #endif
00397 {
00398 expptr lp, tp;
00399 int pt, lt, lt1;
00400 int comma;
00401 char *hsave;
00402
00403 switch(p->exprblock.opcode)
00404 {
00405 case OPCONV:
00406 pt = p->exprblock.vtype;
00407 lp = p->exprblock.leftp;
00408 lt = lp->headblock.vtype;
00409
00410
00411
00412 while(p->tag==TEXPR && p->exprblock.opcode==OPCONV &&
00413 ( (ISREAL(pt)&&ONEOF(lt,MSKREAL|MSKCOMPLEX)) ||
00414 (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
00415 {
00416 if(pt==TYDREAL && lt==TYREAL)
00417 {
00418 if(lp->tag==TEXPR
00419 && lp->exprblock.opcode == OPCONV) {
00420 lt1 = lp->exprblock.leftp->headblock.vtype;
00421 if (lt1 == TYDREAL) {
00422 lp->exprblock.leftp =
00423 putx(lp->exprblock.leftp);
00424 return p;
00425 }
00426 if (lt1 == TYDCOMPLEX) {
00427 lp->exprblock.leftp = putx(
00428 (expptr)realpart(
00429 putcx1(lp->exprblock.leftp)));
00430 return p;
00431 }
00432 }
00433 break;
00434 }
00435 else if (ISREAL(pt) && ISCOMPLEX(lt)) {
00436 p->exprblock.leftp = putx(mkconv(pt,
00437 (expptr)realpart(
00438 putcx1(p->exprblock.leftp))));
00439 break;
00440 }
00441 if(lt==TYCHAR && lp->tag==TEXPR &&
00442 lp->exprblock.opcode==OPCALL)
00443 {
00444
00445
00446
00447
00448 putout (putcall (lp, (Addrp *) &(p ->
00449 exprblock.leftp)));
00450 return putop (p);
00451 }
00452 if (lt == TYCHAR) {
00453 if (ISCONST(p->exprblock.leftp)
00454 && ISNUMERIC(p->exprblock.vtype)) {
00455 hsave = halign;
00456 halign = 0;
00457 p->exprblock.leftp = putx((expptr)
00458 putconst((Constp)
00459 p->exprblock.leftp));
00460 halign = hsave;
00461 }
00462 else
00463 p->exprblock.leftp =
00464 putx(p->exprblock.leftp);
00465 return p;
00466 }
00467 if (pt < lt && ONEOF(lt,MSKINT|MSKREAL))
00468 break;
00469 frexpr(p->exprblock.vleng);
00470 free( (charptr) p );
00471 p = lp;
00472 if (p->tag != TEXPR)
00473 goto retputx;
00474 pt = lt;
00475 lp = p->exprblock.leftp;
00476 lt = lp->headblock.vtype;
00477 }
00478 if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
00479 break;
00480 retputx:
00481 return putx(p);
00482
00483 case OPADDR:
00484 comma = NO;
00485 lp = p->exprblock.leftp;
00486 free( (charptr) p );
00487 if(lp->tag != TADDR)
00488 {
00489 tp = (expptr)
00490 mktmp(lp->headblock.vtype,lp->headblock.vleng);
00491 p = putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
00492 lp = tp;
00493 comma = YES;
00494 }
00495 if(comma)
00496 p = mkexpr(OPCOMMA, p, putaddr(lp));
00497 else
00498 p = (expptr)putaddr(lp);
00499 return p;
00500
00501 case OPASSIGN:
00502 case OPASSIGNI:
00503 case OPLT:
00504 case OPLE:
00505 case OPGT:
00506 case OPGE:
00507 case OPEQ:
00508 case OPNE:
00509 ;
00510 }
00511
00512 if( ops2[p->exprblock.opcode] <= 0)
00513 badop("putop", p->exprblock.opcode);
00514 lp = p->exprblock.leftp = putx(p->exprblock.leftp);
00515 if (p -> exprblock.rightp) {
00516 tp = p->exprblock.rightp = putx(p->exprblock.rightp);
00517 if (ISCONST(tp) && ISCONST(lp))
00518 p = fold(p);
00519 }
00520 return p;
00521 }
00522
00523 LOCAL expptr
00524 #ifdef KR_headers
00525 putpower(p)
00526 expptr p;
00527 #else
00528 putpower(expptr p)
00529 #endif
00530 {
00531 expptr base;
00532 Addrp t1, t2;
00533 ftnint k;
00534 int type;
00535 char buf[80];
00536
00537 if(!ISICON(p->exprblock.rightp) ||
00538 (k = p->exprblock.rightp->constblock.Const.ci)<2)
00539 Fatal("putpower: bad call");
00540 base = p->exprblock.leftp;
00541 type = base->headblock.vtype;
00542 t1 = mktmp(type, ENULL);
00543 t2 = NULL;
00544
00545 free ((charptr) p);
00546 p = putassign (cpexpr((expptr) t1), base);
00547
00548 sprintf (buf, "Computing %ld%s power", k,
00549 k == 2 ? "nd" : k == 3 ? "rd" : "th");
00550 p1_comment (buf);
00551
00552 for( ; (k&1)==0 && k>2 ; k>>=1 )
00553 {
00554 p = mkexpr (OPCOMMA, p, putsteq(t1, t1));
00555 }
00556
00557 if(k == 2) {
00558
00559
00560 putout (p);
00561 p = putx( mkexpr(OPSTAR, cpexpr((expptr)t1), cpexpr((expptr)t1)));
00562 } else {
00563 t2 = mktmp(type, ENULL);
00564 p = mkexpr (OPCOMMA, p, putassign(cpexpr((expptr)t2),
00565 cpexpr((expptr)t1)));
00566
00567 for(k>>=1 ; k>1 ; k>>=1)
00568 {
00569 p = mkexpr (OPCOMMA, p, putsteq(t1, t1));
00570 if(k & 1)
00571 {
00572 p = mkexpr (OPCOMMA, p, putsteq(t2, t1));
00573 }
00574 }
00575
00576 putout (p);
00577 p = putx( mkexpr(OPSTAR, cpexpr((expptr)t2),
00578 mkexpr(OPSTAR, cpexpr((expptr)t1), cpexpr((expptr)t1))));
00579 }
00580 frexpr((expptr)t1);
00581 if(t2)
00582 frexpr((expptr)t2);
00583 return p;
00584 }
00585
00586
00587
00588
00589 LOCAL Addrp
00590 #ifdef KR_headers
00591 intdouble(p)
00592 Addrp p;
00593 #else
00594 intdouble(Addrp p)
00595 #endif
00596 {
00597 register Addrp t;
00598
00599 t = mktmp(TYDREAL, ENULL);
00600 putout (putassign(cpexpr((expptr)t), (expptr)p));
00601 return(t);
00602 }
00603
00604
00605
00606
00607
00608
00609
00610 LOCAL Addrp
00611 #ifdef KR_headers
00612 putcxeq(p)
00613 register expptr p;
00614 #else
00615 putcxeq(register expptr p)
00616 #endif
00617 {
00618 register Addrp lp, rp;
00619 expptr code;
00620
00621 if(p->tag != TEXPR)
00622 badtag("putcxeq", p->tag);
00623
00624 lp = putcx1(p->exprblock.leftp);
00625 rp = putcx1(p->exprblock.rightp);
00626 code = putassign ( (expptr)realpart(lp), (expptr)realpart(rp));
00627
00628 if( ISCOMPLEX(p->exprblock.vtype) )
00629 {
00630 code = mkexpr (OPCOMMA, code, putassign
00631 (imagpart(lp), imagpart(rp)));
00632 }
00633 putout (code);
00634 frexpr((expptr)rp);
00635 free ((charptr) p);
00636 return lp;
00637 }
00638
00639
00640
00641
00642
00643
00644 expptr
00645 #ifdef KR_headers
00646 putcxop(p)
00647 expptr p;
00648 #else
00649 putcxop(expptr p)
00650 #endif
00651 {
00652 return (expptr)putaddr((expptr)putcx1(p));
00653 }
00654
00655 #define PAIR(x,y) mkexpr (OPCOMMA, (x), (y))
00656
00657 LOCAL Addrp
00658 #ifdef KR_headers
00659 putcx1(p)
00660 register expptr p;
00661 #else
00662 putcx1(register expptr p)
00663 #endif
00664 {
00665 expptr q;
00666 Addrp lp, rp;
00667 register Addrp resp;
00668 int opcode;
00669 int ltype, rtype;
00670 long ts, tskludge;
00671
00672 if(p == NULL)
00673 return(NULL);
00674
00675 switch(p->tag)
00676 {
00677 case TCONST:
00678 if( ISCOMPLEX(p->constblock.vtype) )
00679 p = (expptr) putconst((Constp)p);
00680 return( (Addrp) p );
00681
00682 case TADDR:
00683 resp = &p->addrblock;
00684 if (addressable(p))
00685 return (Addrp) p;
00686 ts = tskludge = 0;
00687 if (q = resp->memoffset) {
00688 if (resp->uname_tag == UNAM_REF) {
00689 q = cpexpr((tagptr)resp);
00690 q->addrblock.vtype = tyint;
00691 q->addrblock.cmplx_sub = 1;
00692 p->addrblock.skip_offset = 1;
00693 resp->user.name->vsubscrused = 1;
00694 resp->uname_tag = UNAM_NAME;
00695 tskludge = typesize[resp->vtype]
00696 * (resp->Field ? 2 : 1);
00697 }
00698 else if (resp->isarray
00699 && resp->vtype != TYCHAR) {
00700 if (ONEOF(resp->vstg, M(STGCOMMON)|M(STGEQUIV))
00701 && resp->uname_tag == UNAM_NAME)
00702 q = mkexpr(OPMINUS, q,
00703 mkintcon(resp->user.name->voffset));
00704 ts = typesize[resp->vtype]
00705 * (resp->Field ? 2 : 1);
00706 q = resp->memoffset = mkexpr(OPSLASH, q,
00707 ICON(ts));
00708 }
00709 }
00710 resp = mktmp(tyint, ENULL);
00711 putout(putassign(cpexpr((expptr)resp), q));
00712 p->addrblock.memoffset = tskludge
00713 ? mkexpr(OPSTAR, (expptr)resp, ICON(tskludge))
00714 : (expptr)resp;
00715 if (ts) {
00716 resp = &p->addrblock;
00717 q = mkexpr(OPSTAR, resp->memoffset, ICON(ts));
00718 if (ONEOF(resp->vstg, M(STGCOMMON)|M(STGEQUIV))
00719 && resp->uname_tag == UNAM_NAME)
00720 q = mkexpr(OPPLUS, q,
00721 mkintcon(resp->user.name->voffset));
00722 resp->memoffset = q;
00723 }
00724 return (Addrp) p;
00725
00726 case TEXPR:
00727 if( ISCOMPLEX(p->exprblock.vtype) )
00728 break;
00729 resp = mktmp(p->exprblock.vtype, ENULL);
00730
00731 putout (putassign( cpexpr((expptr)resp), p));
00732 return(resp);
00733
00734 case TERROR:
00735 return NULL;
00736
00737 default:
00738 badtag("putcx1", p->tag);
00739 }
00740
00741 opcode = p->exprblock.opcode;
00742 if(opcode==OPCALL || opcode==OPCCALL)
00743 {
00744 Addrp t;
00745 p = putcall(p, &t);
00746 putout(p);
00747 return t;
00748 }
00749 else if(opcode == OPASSIGN)
00750 {
00751 return putcxeq (p);
00752 }
00753
00754
00755
00756 resp = mktmp(p->exprblock.vtype, ENULL);
00757 if(lp = putcx1(p->exprblock.leftp) )
00758 ltype = lp->vtype;
00759 if(rp = putcx1(p->exprblock.rightp) )
00760 rtype = rp->vtype;
00761
00762 switch(opcode)
00763 {
00764 case OPCOMMA:
00765 frexpr((expptr)resp);
00766 resp = rp;
00767 rp = NULL;
00768 break;
00769
00770 case OPNEG:
00771 case OPNEG1:
00772 putout (PAIR (
00773 putassign( (expptr)realpart(resp),
00774 mkexpr(OPNEG, (expptr)realpart(lp), ENULL)),
00775 putassign( imagpart(resp),
00776 mkexpr(OPNEG, imagpart(lp), ENULL))));
00777 break;
00778
00779 case OPPLUS:
00780 case OPMINUS: { expptr r;
00781 r = putassign( (expptr)realpart(resp),
00782 mkexpr(opcode, (expptr)realpart(lp), (expptr)realpart(rp) ));
00783 if(rtype < TYCOMPLEX)
00784 q = putassign( imagpart(resp), imagpart(lp) );
00785 else if(ltype < TYCOMPLEX)
00786 {
00787 if(opcode == OPPLUS)
00788 q = putassign( imagpart(resp), imagpart(rp) );
00789 else
00790 q = putassign( imagpart(resp),
00791 mkexpr(OPNEG, imagpart(rp), ENULL) );
00792 }
00793 else
00794 q = putassign( imagpart(resp),
00795 mkexpr(opcode, imagpart(lp), imagpart(rp) ));
00796 r = PAIR (r, q);
00797 putout (r);
00798 break;
00799 }
00800 case OPSTAR:
00801 if(ltype < TYCOMPLEX)
00802 {
00803 if( ISINT(ltype) )
00804 lp = intdouble(lp);
00805 putout (PAIR (
00806 putassign( (expptr)realpart(resp),
00807 mkexpr(OPSTAR, cpexpr((expptr)lp),
00808 (expptr)realpart(rp))),
00809 putassign( imagpart(resp),
00810 mkexpr(OPSTAR, cpexpr((expptr)lp), imagpart(rp)))));
00811 }
00812 else if(rtype < TYCOMPLEX)
00813 {
00814 if( ISINT(rtype) )
00815 rp = intdouble(rp);
00816 putout (PAIR (
00817 putassign( (expptr)realpart(resp),
00818 mkexpr(OPSTAR, cpexpr((expptr)rp),
00819 (expptr)realpart(lp))),
00820 putassign( imagpart(resp),
00821 mkexpr(OPSTAR, cpexpr((expptr)rp), imagpart(lp)))));
00822 }
00823 else {
00824 putout (PAIR (
00825 putassign( (expptr)realpart(resp), mkexpr(OPMINUS,
00826 mkexpr(OPSTAR, (expptr)realpart(lp),
00827 (expptr)realpart(rp)),
00828 mkexpr(OPSTAR, imagpart(lp), imagpart(rp)))),
00829 putassign( imagpart(resp), mkexpr(OPPLUS,
00830 mkexpr(OPSTAR, (expptr)realpart(lp), imagpart(rp)),
00831 mkexpr(OPSTAR, imagpart(lp),
00832 (expptr)realpart(rp))))));
00833 }
00834 break;
00835
00836 case OPSLASH:
00837
00838
00839
00840 if( ISINT(rtype) )
00841 rp = intdouble(rp);
00842 putout (PAIR (
00843 putassign( (expptr)realpart(resp),
00844 mkexpr(OPSLASH, (expptr)realpart(lp), cpexpr((expptr)rp))),
00845 putassign( imagpart(resp),
00846 mkexpr(OPSLASH, imagpart(lp), cpexpr((expptr)rp)))));
00847 break;
00848
00849 case OPCONV:
00850 if (!lp)
00851 break;
00852 if(ISCOMPLEX(lp->vtype) )
00853 q = imagpart(lp);
00854 else if(rp != NULL)
00855 q = (expptr) realpart(rp);
00856 else
00857 q = mkrealcon(TYDREAL, "0");
00858 putout (PAIR (
00859 putassign( (expptr)realpart(resp), (expptr)realpart(lp)),
00860 putassign( imagpart(resp), q)));
00861 break;
00862
00863 default:
00864 badop("putcx1", opcode);
00865 }
00866
00867 frexpr((expptr)lp);
00868 frexpr((expptr)rp);
00869 free( (charptr) p );
00870 return(resp);
00871 }
00872
00873
00874
00875
00876
00877
00878
00879 LOCAL expptr
00880 #ifdef KR_headers
00881 putcxcmp(p)
00882 register expptr p;
00883 #else
00884 putcxcmp(register expptr p)
00885 #endif
00886 {
00887 int opcode;
00888 register Addrp lp, rp;
00889 expptr q;
00890
00891 if(p->tag != TEXPR)
00892 badtag("putcxcmp", p->tag);
00893
00894 opcode = p->exprblock.opcode;
00895 lp = putcx1(p->exprblock.leftp);
00896 rp = putcx1(p->exprblock.rightp);
00897
00898 q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
00899 mkexpr(opcode, (expptr)realpart(lp), (expptr)realpart(rp)),
00900 mkexpr(opcode, imagpart(lp), imagpart(rp)) );
00901
00902 free( (charptr) lp);
00903 free( (charptr) rp);
00904 free( (charptr) p );
00905 if (ISCONST(q))
00906 return q;
00907 return putx( fixexpr((Exprp)q) );
00908 }
00909
00910
00911
00912 LOCAL Addrp
00913 #ifdef KR_headers
00914 putch1(p)
00915 register expptr p;
00916 #else
00917 putch1(register expptr p)
00918 #endif
00919 {
00920 Addrp t;
00921 expptr e;
00922
00923 switch(p->tag)
00924 {
00925 case TCONST:
00926 return( putconst((Constp)p) );
00927
00928 case TADDR:
00929 return( (Addrp) p );
00930
00931 case TEXPR:
00932 switch(p->exprblock.opcode)
00933 {
00934 expptr q;
00935
00936 case OPCALL:
00937 case OPCCALL:
00938
00939 p = putcall(p, &t);
00940 putout (p);
00941 break;
00942
00943 case OPCONCAT:
00944 t = mktmp(TYCHAR, ICON(lencat(p)));
00945 q = (expptr) cpexpr(p->headblock.vleng);
00946 p = putcat( cpexpr((expptr)t), p );
00947
00948 frexpr(t->vleng);
00949 t->vleng = q;
00950 putout (p);
00951 break;
00952
00953 case OPCONV:
00954 if(!ISICON(p->exprblock.vleng)
00955 || p->exprblock.vleng->constblock.Const.ci!=1
00956 || ! INT(p->exprblock.leftp->headblock.vtype) )
00957 Fatal("putch1: bad character conversion");
00958 t = mktmp(TYCHAR, ICON(1));
00959 e = mkexpr(OPCONV, (expptr)t, ENULL);
00960 e->headblock.vtype = TYCHAR;
00961 p = putop( mkexpr(OPASSIGN, cpexpr(e), p));
00962 putout (p);
00963 break;
00964 default:
00965 badop("putch1", p->exprblock.opcode);
00966 }
00967 return(t);
00968
00969 default:
00970 badtag("putch1", p->tag);
00971 }
00972 return 0;
00973 }
00974
00975
00976
00977
00978
00979 Addrp
00980 #ifdef KR_headers
00981 putchop(p)
00982 expptr p;
00983 #else
00984 putchop(expptr p)
00985 #endif
00986 {
00987 p = putaddr((expptr)putch1(p));
00988 return (Addrp)p;
00989 }
00990
00991
00992
00993
00994 LOCAL expptr
00995 #ifdef KR_headers
00996 putcheq(p)
00997 register expptr p;
00998 #else
00999 putcheq(register expptr p)
01000 #endif
01001 {
01002 expptr lp, rp;
01003 int nbad;
01004
01005 if(p->tag != TEXPR)
01006 badtag("putcheq", p->tag);
01007
01008 lp = p->exprblock.leftp;
01009 rp = p->exprblock.rightp;
01010 frexpr(p->exprblock.vleng);
01011 free( (charptr) p );
01012
01013
01014
01015
01016 nbad = badchleng(lp) + badchleng(rp);
01017 if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
01018 p = putcat(lp, rp);
01019 else if( !nbad
01020 && ISONE(lp->headblock.vleng)
01021 && ISONE(rp->headblock.vleng) ) {
01022 lp = mkexpr(OPCONV, lp, ENULL);
01023 rp = mkexpr(OPCONV, rp, ENULL);
01024 lp->headblock.vtype = rp->headblock.vtype = TYCHAR;
01025 p = putop(mkexpr(OPASSIGN, lp, rp));
01026 }
01027 else
01028 p = putx( call2(TYSUBR, "s_copy", lp, rp) );
01029 return p;
01030 }
01031
01032
01033
01034
01035 LOCAL expptr
01036 #ifdef KR_headers
01037 putchcmp(p)
01038 register expptr p;
01039 #else
01040 putchcmp(register expptr p)
01041 #endif
01042 {
01043 expptr lp, rp;
01044
01045 if(p->tag != TEXPR)
01046 badtag("putchcmp", p->tag);
01047
01048 lp = p->exprblock.leftp;
01049 rp = p->exprblock.rightp;
01050
01051 if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) ) {
01052 lp = mkexpr(OPCONV, lp, ENULL);
01053 rp = mkexpr(OPCONV, rp, ENULL);
01054 lp->headblock.vtype = rp->headblock.vtype = TYCHAR;
01055 }
01056 else {
01057 lp = call2(TYINT,"s_cmp", lp, rp);
01058 rp = ICON(0);
01059 }
01060 p->exprblock.leftp = lp;
01061 p->exprblock.rightp = rp;
01062 p = putop(p);
01063 return p;
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 LOCAL expptr
01081 #ifdef KR_headers
01082 putcat(lhs0, rhs)
01083 expptr lhs0;
01084 register expptr rhs;
01085 #else
01086 putcat(expptr lhs0, register expptr rhs)
01087 #endif
01088 {
01089 register Addrp lhs = (Addrp)lhs0;
01090 int n, tyi;
01091 Addrp length_var, string_var;
01092 expptr p;
01093 static char Writing_concatenation[] = "Writing concatenation";
01094
01095
01096
01097 n = ncat(rhs);
01098 length_var = mktmpn(n, tyioint, ENULL);
01099 string_var = mktmpn(n, TYADDR, ENULL);
01100 frtemp((Addrp)cpexpr((expptr)length_var));
01101 frtemp((Addrp)cpexpr((expptr)string_var));
01102
01103
01104
01105 n = 0;
01106
01107
01108 p1_comment(Writing_concatenation);
01109 putct1(rhs, length_var, string_var, &n);
01110
01111
01112
01113 tyi = tyint;
01114 tyint = tyioint;
01115 p = putx (call4 (TYSUBR, "s_cat",
01116 (expptr)lhs,
01117 (expptr)string_var,
01118 (expptr)length_var,
01119 (expptr)putconst((Constp)ICON(n))));
01120 tyint = tyi;
01121
01122 return p;
01123 }
01124
01125
01126
01127
01128
01129 LOCAL void
01130 #ifdef KR_headers
01131 putct1(q, length_var, string_var, ip)
01132 register expptr q;
01133 register Addrp length_var;
01134 register Addrp string_var;
01135 int *ip;
01136 #else
01137 putct1(register expptr q, register Addrp length_var, register Addrp string_var, int *ip)
01138 #endif
01139 {
01140 int i;
01141 Addrp length_copy, string_copy;
01142 expptr e;
01143 extern int szleng;
01144
01145 if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
01146 {
01147 putct1(q->exprblock.leftp, length_var, string_var,
01148 ip);
01149 putct1(q->exprblock.rightp, length_var, string_var,
01150 ip);
01151 frexpr (q -> exprblock.vleng);
01152 free ((charptr) q);
01153 }
01154 else
01155 {
01156 i = (*ip)++;
01157 e = cpexpr(q->headblock.vleng);
01158 if (!e)
01159 return;
01160 length_copy = (Addrp) cpexpr((expptr)length_var);
01161 length_copy->memoffset =
01162 mkexpr(OPPLUS,length_copy->memoffset, ICON(i*szleng));
01163 string_copy = (Addrp) cpexpr((expptr)string_var);
01164 string_copy->memoffset =
01165 mkexpr(OPPLUS, string_copy->memoffset,
01166 ICON(i*typesize[TYADDR]));
01167 putout (PAIR (putassign((expptr)length_copy, e),
01168 putassign((expptr)string_copy, addrof((expptr)putch1(q)))));
01169 }
01170 }
01171
01172
01173
01174 LOCAL expptr
01175 #ifdef KR_headers
01176 putaddr(p0)
01177 expptr p0;
01178 #else
01179 putaddr(expptr p0)
01180 #endif
01181 {
01182 register Addrp p;
01183 chainp cp;
01184
01185 if (!(p = (Addrp)p0))
01186 return ENULL;
01187
01188 if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
01189 {
01190 frexpr((expptr)p);
01191 return ENULL;
01192 }
01193 if (p->isarray && p->memoffset)
01194 if (p->uname_tag == UNAM_REF) {
01195 cp = p->memoffset->listblock.listp;
01196 for(; cp; cp = cp->nextp)
01197 cp->datap = (char *)fixtype((tagptr)cp->datap);
01198 }
01199 else
01200 p->memoffset = putx(p->memoffset);
01201 return (expptr) p;
01202 }
01203
01204 LOCAL expptr
01205 #ifdef KR_headers
01206 addrfix(e)
01207 expptr e;
01208 #else
01209 addrfix(expptr e)
01210 #endif
01211
01212 {
01213 return e->tag == TADDR ? mkexpr(OPIDENTITY, e, ENULL) : e;
01214 }
01215
01216 LOCAL int
01217 #ifdef KR_headers
01218 typekludge(ccall, q, at, j)
01219 int ccall;
01220 register expptr q;
01221 Atype *at;
01222 int j;
01223 #else
01224 typekludge(int ccall, register expptr q, Atype *at, int j)
01225 #endif
01226
01227 {
01228 register int i, k;
01229 extern int iocalladdr;
01230 register Namep np;
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 k = q->headblock.vtype;
01242 if (ccall) {
01243 if (k == TYREAL)
01244 k = TYDREAL;
01245 return k + 100;
01246 }
01247 if (k == TYADDR)
01248 return iocalladdr;
01249 i = q->tag;
01250 if ((i == TEXPR && q->exprblock.opcode != OPCOMMA_ARG)
01251 || (i == TADDR && q->addrblock.charleng)
01252 || i == TCONST)
01253 k = TYFTNLEN + 100;
01254 else if (i == TADDR)
01255 switch(q->addrblock.vclass) {
01256 case CLPROC:
01257 if (q->addrblock.uname_tag != UNAM_NAME)
01258 k += 200;
01259 else if ((np = q->addrblock.user.name)->vprocclass
01260 != PTHISPROC) {
01261 if (k && !np->vimpltype)
01262 k += 200;
01263 else {
01264 if (j > 200 && infertypes && j < 300) {
01265 k = j;
01266 inferdcl(np, j-200);
01267 }
01268 else k = (np->vstg == STGEXT
01269 ? extsymtab[np->vardesc.varno].extype
01270 : 0) + 200;
01271 at->cp = mkchain((char *)np, at->cp);
01272 }
01273 }
01274 else if (k == TYSUBR)
01275 k += 200;
01276 break;
01277
01278 case CLUNKNOWN:
01279 if (q->addrblock.vstg == STGARG
01280 && q->addrblock.uname_tag == UNAM_NAME) {
01281 k += 400;
01282 at->cp = mkchain((char *)q->addrblock.user.name,
01283 at->cp);
01284 }
01285 }
01286 else if (i == TNAME && q->nameblock.vstg == STGARG) {
01287 np = &q->nameblock;
01288 switch(np->vclass) {
01289 case CLPROC:
01290 if (!np->vimpltype)
01291 k += 200;
01292 else if (j <= 200 || !infertypes || j >= 300)
01293 k += 300;
01294 else {
01295 k = j;
01296 inferdcl(np, j-200);
01297 }
01298 goto add2chain;
01299
01300 case CLUNKNOWN:
01301
01302 if (np->vimpltype && j && infertypes
01303 && j < 300) {
01304 inferdcl(np, j % 100);
01305 k = j;
01306 }
01307 else
01308 k += 400;
01309
01310
01311
01312
01313 add2chain:
01314 at->cp = mkchain((char *)np, at->cp);
01315 }
01316 }
01317 return k;
01318 }
01319
01320 char *
01321 #ifdef KR_headers
01322 Argtype(k, buf)
01323 int k;
01324 char *buf;
01325 #else
01326 Argtype(int k, char *buf)
01327 #endif
01328 {
01329 if (k < 100) {
01330 sprintf(buf, "%s variable", ftn_types[k]);
01331 return buf;
01332 }
01333 if (k < 200) {
01334 k -= 100;
01335 return ftn_types[k];
01336 }
01337 if (k < 300) {
01338 k -= 200;
01339 if (k == TYSUBR)
01340 return ftn_types[TYSUBR];
01341 sprintf(buf, "%s function", ftn_types[k]);
01342 return buf;
01343 }
01344 if (k < 400)
01345 return "external argument";
01346 k -= 400;
01347 sprintf(buf, "%s argument", ftn_types[k]);
01348 return buf;
01349 }
01350
01351 static void
01352 #ifdef KR_headers
01353 atype_squawk(at, msg)
01354 Argtypes *at;
01355 char *msg;
01356 #else
01357 atype_squawk(Argtypes *at, char *msg)
01358 #endif
01359 {
01360 register Atype *a, *ae;
01361 warn(msg);
01362 for(a = at->atypes, ae = a + at->nargs; a < ae; a++)
01363 frchain(&a->cp);
01364 at->nargs = -1;
01365 if (at->changes & 2 && !at->defined)
01366 proc_protochanges++;
01367 }
01368
01369 static char inconsist[] = "inconsistent calling sequences for ";
01370
01371 void
01372 #ifdef KR_headers
01373 bad_atypes(at, fname, i, j, k, here, prev)
01374 Argtypes *at;
01375 char *fname;
01376 int i;
01377 int j;
01378 int k;
01379 char *here;
01380 char *prev;
01381 #else
01382 bad_atypes(Argtypes *at, char *fname, int i, int j, int k, char *here, char *prev)
01383 #endif
01384 {
01385 char buf[208], buf1[32], buf2[32];
01386
01387 sprintf(buf, "%s%.90s,\n\targ %d: %s%s%s %s.",
01388 inconsist, fname, i, here, Argtype(k, buf1),
01389 prev, Argtype(j, buf2));
01390 atype_squawk(at, buf);
01391 }
01392
01393 int
01394 #ifdef KR_headers
01395 type_fixup(at, a, k)
01396 Argtypes *at;
01397 Atype *a;
01398 int k;
01399 #else
01400 type_fixup(Argtypes *at, Atype *a, int k)
01401 #endif
01402 {
01403 register struct Entrypoint *ep;
01404 if (!infertypes)
01405 return 0;
01406 for(ep = entries; ep; ep = ep->entnextp)
01407 if (ep->entryname && at == ep->entryname->arginfo) {
01408 a->type = k % 100;
01409 return proc_argchanges = 1;
01410 }
01411 return 0;
01412 }
01413
01414
01415 void
01416 #ifdef KR_headers
01417 save_argtypes(arglist, at0, at1, ccall, fname, stg, nchargs, type, zap)
01418 chainp arglist;
01419 Argtypes **at0;
01420 Argtypes **at1;
01421 int ccall;
01422 char *fname;
01423 int stg;
01424 int nchargs;
01425 int type;
01426 int zap;
01427 #else
01428 save_argtypes(chainp arglist, Argtypes **at0, Argtypes **at1, int ccall, char *fname, int stg, int nchargs, int type, int zap)
01429 #endif
01430 {
01431 Argtypes *at;
01432 chainp cp;
01433 int i, i0, j, k, nargs, nbad, *t, *te;
01434 Atype *atypes;
01435 expptr q;
01436 char buf[208], buf1[32], buf2[32];
01437 static int initargs[4] = {TYCOMPLEX, TYDCOMPLEX, TYCHAR, TYFTNLEN+100};
01438 static int *init_ap[TYSUBR+1] = {0,0,0,0,0,0,0,
01439 #ifdef TYQUAD
01440 0,
01441 #endif
01442 initargs, initargs+1,0,0,0,initargs+2};
01443
01444 i0 = init_ac[type];
01445 t = init_ap[type];
01446 te = t + i0;
01447 if (at = *at0) {
01448 *at1 = at;
01449 nargs = at->nargs;
01450 if (nargs < 0 && type && at->changes & 2 && !at->defined)
01451 --proc_protochanges;
01452 if (at->dnargs >= 0 && zap != 2)
01453 type = 0;
01454 if (nargs < 0) {
01455 if (type)
01456 goto newlist;
01457 return;
01458 }
01459 atypes = at->atypes;
01460 i = nchargs;
01461 for(nbad = 0; t < te; atypes++) {
01462 if (++i > nargs) {
01463 toomany:
01464 i = nchargs + i0;
01465 for(cp = arglist; cp; cp = cp->nextp)
01466 i++;
01467 toofew:
01468 switch(zap) {
01469 case 2: zap = 6; break;
01470 case 1: if (at->defined & 4)
01471 return;
01472 }
01473 sprintf(buf,
01474 "%s%.90s:\n\there %d, previously %d args and string lengths.",
01475 inconsist, fname, i, nargs);
01476 atype_squawk(at, buf);
01477 if (type) {
01478 t = init_ap[type];
01479 goto newlist;
01480 }
01481 return;
01482 }
01483 j = atypes->type;
01484 k = *t++;
01485 if (j != k && j-400 != k) {
01486 cp = 0;
01487 goto badtypes;
01488 }
01489 }
01490 for(cp = arglist; cp; atypes++, cp = cp->nextp) {
01491 if (++i > nargs)
01492 goto toomany;
01493 j = atypes->type;
01494 if (!(q = (expptr)cp->datap))
01495 continue;
01496 k = typekludge(ccall, q, atypes, j);
01497 if (k >= 300 || k == j)
01498 continue;
01499 if (j >= 300) {
01500 if (k >= 200) {
01501 if (k == TYUNKNOWN + 200)
01502 continue;
01503 if (j % 100 != k - 200
01504 && k != TYSUBR + 200
01505 && j != TYUNKNOWN + 300
01506 && !type_fixup(at,atypes,k))
01507 goto badtypes;
01508 }
01509 else if (j % 100 % TYSUBR != k % TYSUBR
01510 && !type_fixup(at,atypes,k))
01511 goto badtypes;
01512 }
01513 else if (k < 200 || j < 200)
01514 if (j) {
01515 if (k == TYUNKNOWN
01516 && q->tag == TNAME
01517 && q->nameblock.vinfproc) {
01518 q->nameblock.vdcldone = 0;
01519 impldcl((Namep)q);
01520 }
01521 goto badtypes;
01522 }
01523 else ;
01524 else if (k == TYUNKNOWN+200)
01525 continue;
01526 else if (j != TYUNKNOWN+200)
01527 {
01528 badtypes:
01529 if (++nbad == 1)
01530 bad_atypes(at, fname, i - nchargs,
01531 j, k, "here ", ", previously");
01532 else
01533 fprintf(stderr,
01534 "\targ %d: here %s, previously %s.\n",
01535 i - nchargs, Argtype(k,buf1),
01536 Argtype(j,buf2));
01537 if (!cp)
01538 break;
01539 continue;
01540 }
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551 if (!nbad) {
01552 atypes->type = k;
01553 at->changes |= 1;
01554 }
01555 }
01556 if (i < nargs)
01557 goto toofew;
01558 if (nbad) {
01559 if (type) {
01560
01561 t = init_ap[type];
01562 te = t + i0;
01563 proc_argchanges = 1;
01564 goto newlist;
01565 }
01566 return;
01567 }
01568 if (zap == 1 && (at->changes & 5) != 5)
01569 at->changes = 0;
01570 return;
01571 }
01572 newlist:
01573 i = i0 + nchargs;
01574 for(cp = arglist; cp; cp = cp->nextp)
01575 i++;
01576 k = sizeof(Argtypes) + (i-1)*sizeof(Atype);
01577 *at0 = *at1 = at = stg == STGEXT ? (Argtypes *)gmem(k,1)
01578 : (Argtypes *) mem(k,1);
01579 at->dnargs = at->nargs = i;
01580 at->defined = zap & 6;
01581 at->changes = type ? 0 : 4;
01582 atypes = at->atypes;
01583 for(; t < te; atypes++) {
01584 atypes->type = *t++;
01585 atypes->cp = 0;
01586 }
01587 for(cp = arglist; cp; atypes++, cp = cp->nextp) {
01588 atypes->cp = 0;
01589 atypes->type = (q = (expptr)cp->datap)
01590 ? typekludge(ccall, q, atypes, 0)
01591 : 0;
01592 }
01593 for(; --nchargs >= 0; atypes++) {
01594 atypes->type = TYFTNLEN + 100;
01595 atypes->cp = 0;
01596 }
01597 }
01598
01599 static char*
01600 #ifdef KR_headers
01601 get_argtypes(p, pat0, pat1) Exprp p; Argtypes ***pat0, ***pat1;
01602 #else
01603 get_argtypes(Exprp p, Argtypes ***pat0, Argtypes ***pat1)
01604 #endif
01605 {
01606 Addrp a;
01607 Argtypes **at0, **at1;
01608 Namep np;
01609 expptr rp;
01610 Extsym *e;
01611 char *fname;
01612
01613 a = (Addrp)p->leftp;
01614 switch(a->vstg) {
01615 case STGEXT:
01616 switch(a->uname_tag) {
01617 case UNAM_EXTERN:
01618 e = extsymtab + a->memno;
01619 at0 = at1 = &e->arginfo;
01620 fname = e->fextname;
01621 break;
01622 case UNAM_NAME:
01623 np = a->user.name;
01624 at0 = &extsymtab[np->vardesc.varno].arginfo;
01625 at1 = &np->arginfo;
01626 fname = np->fvarname;
01627 break;
01628 default:
01629 goto bug;
01630 }
01631 break;
01632 case STGARG:
01633 if (a->uname_tag != UNAM_NAME)
01634 goto bug;
01635 np = a->user.name;
01636 at0 = at1 = &np->arginfo;
01637 fname = np->fvarname;
01638 break;
01639 default:
01640 bug:
01641 Fatal("Confusion in saveargtypes");
01642 }
01643 *pat0 = at0;
01644 *pat1 = at1;
01645 return fname;
01646 }
01647
01648 void
01649 #ifdef KR_headers
01650 saveargtypes(p)
01651 register Exprp p;
01652 #else
01653 saveargtypes(register Exprp p)
01654 #endif
01655
01656 {
01657 Argtypes **at0, **at1;
01658 chainp arglist;
01659 expptr rp;
01660 char *fname;
01661
01662 fname = get_argtypes(p, &at0, &at1);
01663 rp = p->rightp;
01664 arglist = rp && rp->tag == TLIST ? rp->listblock.listp : 0;
01665 save_argtypes(arglist, at0, at1, p->opcode == OPCCALL,
01666 fname, p->leftp->addrblock.vstg, 0, 0, 0);
01667 }
01668
01669
01670
01671
01672
01673
01674 LOCAL expptr
01675 #ifdef KR_headers
01676 putcall(p0, temp)
01677 expptr p0;
01678 Addrp *temp;
01679 #else
01680 putcall(expptr p0, Addrp *temp)
01681 #endif
01682 {
01683 register Exprp p = (Exprp)p0;
01684 chainp arglist;
01685 chainp charsp;
01686
01687
01688
01689 chainp cp;
01690 register expptr q;
01691 Addrp fval;
01692 int type;
01693
01694 int byvalue;
01695
01696
01697 char *s;
01698 Argtypes *at, **at0, **at1;
01699 Atype *At, *Ate;
01700
01701 type = p -> vtype;
01702 charsp = NULL;
01703 byvalue = (p->opcode == OPCCALL);
01704
01705
01706
01707 if (p == (Exprp) NULL)
01708 err ("putcall: NULL call expression");
01709 else if (p -> tag != TEXPR)
01710 erri ("putcall: expected TEXPR, got '%d'", p -> tag);
01711
01712
01713
01714 if(p->rightp && p -> rightp -> tag == TLIST)
01715 arglist = p->rightp->listblock.listp;
01716 else
01717 arglist = NULL;
01718
01719
01720
01721
01722 if (!byvalue) {
01723 get_argtypes(p, &at0, &at1);
01724 At = Ate = 0;
01725 if ((at = *at0) && at->nargs >= 0) {
01726 At = at->atypes;
01727 Ate = At + at->nargs;
01728 At += init_ac[type];
01729 }
01730 for(cp = arglist ; cp ; cp = cp->nextp) {
01731 q = (expptr) cp->datap;
01732 if( ISCONST(q) ) {
01733
01734
01735
01736
01737 q = (expptr) putconst((Constp)q);
01738 cp->datap = (char *) q;
01739 }
01740
01741
01742
01743
01744 if( ISCHAR(q) &&
01745 (q->headblock.vclass != CLPROC
01746 || q->headblock.vstg == STGARG
01747 && q->tag == TADDR
01748 && q->addrblock.uname_tag == UNAM_NAME
01749 && q->addrblock.user.name->vprocclass == PTHISPROC)
01750 && (!At || At->type % 100 % TYSUBR == TYCHAR))
01751 {
01752 p0 = cpexpr(q->headblock.vleng);
01753 charsp = mkchain((char *)p0, charsp);
01754 if (q->headblock.vclass == CLUNKNOWN
01755 && q->headblock.vstg == STGARG)
01756 q->addrblock.user.name->vpassed = 1;
01757 else if (q->tag == TADDR
01758 && q->addrblock.uname_tag == UNAM_CONST)
01759 p0->constblock.Const.ci
01760 += q->addrblock.user.Const.ccp1.blanks;
01761 }
01762 if (At && ++At == Ate)
01763 At = 0;
01764 }
01765 }
01766 charsp = revchain(charsp);
01767
01768
01769
01770 if(type == TYCHAR)
01771 {
01772 if( ISICON(p->vleng) )
01773 {
01774
01775
01776
01777 fval = mktmp(TYCHAR, p->vleng);
01778 }
01779 else {
01780 err("adjustable character function");
01781 if (temp)
01782 *temp = 0;
01783 return 0;
01784 }
01785 }
01786
01787
01788
01789 else if( ISCOMPLEX(type) )
01790 fval = mktmp(type, ENULL);
01791 else
01792 fval = NULL;
01793
01794
01795
01796 p -> leftp = putx(fixtype(putaddr(p->leftp)));
01797
01798 if(fval)
01799 {
01800 chainp prepend;
01801
01802
01803
01804
01805 prepend = mkchain((char *)putx(putaddr(cpexpr((expptr)fval))), arglist);
01806
01807
01808
01809 if(type==TYCHAR)
01810 {
01811
01812 prepend->nextp = mkchain((char *)putx(mkconv(TYLENG,
01813 p->vleng)), arglist);
01814 }
01815 if (!(q = p->rightp))
01816 p->rightp = q = (expptr)mklist(CHNULL);
01817 q->listblock.listp = prepend;
01818 }
01819
01820
01821
01822 for(cp = arglist ; cp ; cp = cp->nextp)
01823 {
01824 q = (expptr) (cp->datap);
01825 if (q == ENULL)
01826 err ("putcall: NULL argument");
01827
01828
01829
01830
01831 if (q -> tag == TCONST && !byvalue)
01832 q = (expptr) putconst ((Constp)q);
01833
01834 if(q->tag==TADDR && (byvalue || q->addrblock.vstg!=STGREG) ) {
01835 if (q->addrblock.parenused
01836 && !byvalue && q->headblock.vtype != TYCHAR)
01837 goto make_copy;
01838 cp->datap = (char *)putaddr(q);
01839 }
01840 else if( ISCOMPLEX(q->headblock.vtype) )
01841 cp -> datap = (char *) putx (fixtype(putcxop(q)));
01842 else if (ISCHAR(q) )
01843 cp -> datap = (char *) putx (fixtype((expptr)putchop(q)));
01844 else if( ! ISERROR(q) )
01845 {
01846 if(byvalue) {
01847 if (q->tag == TEXPR && q->exprblock.opcode == OPCONV) {
01848 if (ISCOMPLEX(q->exprblock.leftp->headblock.vtype)
01849 && q->exprblock.leftp->tag == TEXPR)
01850 q->exprblock.leftp = putcxop(q->exprblock.leftp);
01851 else
01852 q->exprblock.leftp = putx(q->exprblock.leftp);
01853 }
01854 else
01855 cp -> datap = (char *) putx(q);
01856 }
01857 else if (q->tag == TEXPR && q->exprblock.opcode == OPCHARCAST)
01858 cp -> datap = (char *) putx(q);
01859 else {
01860 expptr t, t1;
01861
01862
01863
01864 make_copy:
01865 t = (expptr) mktmp(q->headblock.vtype, q->headblock.vleng);
01866
01867
01868
01869
01870 t1 = putassign( cpexpr(t), q );
01871 if (doin_setbound)
01872 t = mkexpr(OPCOMMA_ARG, t1, t);
01873 else
01874 putout(t1);
01875 cp -> datap = (char *) t;
01876 }
01877 }
01878 }
01879
01880
01881
01882 for(cp = charsp ; cp ; cp = cp->nextp)
01883 cp->datap = (char *)addrfix(putx(
01884
01885 (s = cp->datap) ? mkconv(TYLENG,(expptr)s)
01886 : ICON(0)));
01887
01888
01889
01890 hookup (arglist, charsp);
01891
01892
01893
01894
01895 if (temp) *temp = fval;
01896 else frexpr ((expptr)fval);
01897
01898 saveargtypes(p);
01899
01900 return (expptr) p;
01901 }
01902
01903
01904
01905
01906
01907
01908 LOCAL expptr
01909 #ifdef KR_headers
01910 putmnmx(p)
01911 register expptr p;
01912 #else
01913 putmnmx(register expptr p)
01914 #endif
01915 {
01916 int op, op2, type;
01917 expptr arg, qp, temp;
01918 chainp p0, p1;
01919 Addrp sp, tp;
01920 char comment_buf[80];
01921 char *what;
01922
01923 if(p->tag != TEXPR)
01924 badtag("putmnmx", p->tag);
01925
01926 type = p->exprblock.vtype;
01927 op = p->exprblock.opcode;
01928 op2 = op == OPMIN ? OPMIN2 : OPMAX2;
01929 p0 = p->exprblock.leftp->listblock.listp;
01930 free( (charptr) (p->exprblock.leftp) );
01931 free( (charptr) p );
01932
01933
01934
01935 if (addressable((expptr)p0->datap)
01936 && (p1 = p0->nextp)
01937 && addressable((expptr)p1->datap)
01938 && !p1->nextp) {
01939 if (type == TYREAL && forcedouble)
01940 op2 = op == OPMIN ? OPDMIN : OPDMAX;
01941 p = mkexpr(op2, mkconv(type, cpexpr((expptr)p0->datap)),
01942 mkconv(type, cpexpr((expptr)p1->datap)));
01943 frchain(&p0);
01944 return p;
01945 }
01946
01947
01948
01949 sp = mktmp(type, ENULL);
01950
01951
01952
01953
01954 tp = (Addrp) NULL;
01955 qp = ENULL;
01956 for (p1 = p0 -> nextp; p1; p1 = p1 -> nextp)
01957 if (!addressable ((expptr) p1 -> datap)) {
01958 tp = mktmp(type, ENULL);
01959 qp = mkexpr(op2, cpexpr((expptr)sp), cpexpr((expptr)tp));
01960 qp = fixexpr((Exprp)qp);
01961 break;
01962 }
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977 if (!doin_setbound) {
01978 switch(op) {
01979 case OPLT:
01980 case OPMIN:
01981 case OPDMIN:
01982 case OPMIN2:
01983 what = "IN";
01984 break;
01985 default:
01986 what = "AX";
01987 }
01988 sprintf (comment_buf, "Computing M%s", what);
01989 p1_comment (comment_buf);
01990 }
01991
01992 p1 = p0->nextp;
01993 temp = (expptr)p0->datap;
01994 if (addressable(temp) && addressable((expptr)p1->datap)) {
01995 p = mkconv(type, cpexpr(temp));
01996 arg = mkconv(type, cpexpr((expptr)p1->datap));
01997 temp = mkexpr(op2, p, arg);
01998 if (!ISCONST(temp))
01999 temp = fixexpr((Exprp)temp);
02000 p1 = p1->nextp;
02001 }
02002 p = putassign (cpexpr((expptr)sp), temp);
02003
02004 for(; p1 ; p1 = p1->nextp)
02005 {
02006 if (addressable ((expptr) p1 -> datap)) {
02007 arg = mkconv(type, cpexpr((expptr)p1->datap));
02008 temp = mkexpr(op2, cpexpr((expptr)sp), arg);
02009 temp = fixexpr((Exprp)temp);
02010 } else {
02011 temp = (expptr) cpexpr (qp);
02012 p = mkexpr(OPCOMMA, p,
02013 putassign(cpexpr((expptr)tp), (expptr)p1->datap));
02014 }
02015
02016 if(p1->nextp)
02017 p = mkexpr(OPCOMMA, p,
02018 putassign(cpexpr((expptr)sp), temp));
02019 else {
02020 if (type == TYREAL && forcedouble)
02021 temp->exprblock.opcode =
02022 op == OPMIN ? OPDMIN : OPDMAX;
02023 if (doin_setbound)
02024 p = mkexpr(OPCOMMA, p, temp);
02025 else {
02026 putout (p);
02027 p = putx(temp);
02028 }
02029 if (qp)
02030 frexpr (qp);
02031 }
02032 }
02033
02034 frchain( &p0 );
02035 return p;
02036 }
02037
02038
02039 void
02040 #ifdef KR_headers
02041 putwhile(p)
02042 expptr p;
02043 #else
02044 putwhile(expptr p)
02045 #endif
02046 {
02047 long where;
02048 int k, n;
02049
02050 if (wh_next >= wh_last)
02051 {
02052 k = wh_last - wh_first;
02053 n = k + 100;
02054 wh_next = mem(n,0);
02055 wh_last = wh_first + n;
02056 if (k)
02057 memcpy(wh_next, wh_first, k);
02058 wh_first = wh_next;
02059 wh_next += k;
02060 wh_last = wh_first + n;
02061 }
02062 p1put(P1_WHILE1START);
02063 where = ftell(pass1_file);
02064 if( !ISLOGICAL((k = (p = fixtype(p))->headblock.vtype)))
02065 {
02066 if(k != TYERROR)
02067 err("non-logical expression in DO WHILE statement");
02068 }
02069 else {
02070 p = putx(p);
02071 *wh_next++ = ftell(pass1_file) > where;
02072 p1put(P1_WHILE2START);
02073 p1_expr(p);
02074 }
02075 }