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