|
|
1.1 ! root 1: # include <stdio.h> ! 2: extern int Pflag, bbcnt; ! 3: # include "mfile1.h" ! 4: ! 5: int minrvar = 11; ! 6: int wloop_level = LL_BOT; ! 7: int floop_level = LL_BOT; ! 8: int maxboff; ! 9: int maxtemp; ! 10: codgen(p) ! 11: NODE *p; ! 12: { extern int bothdebug; ! 13: if(bothdebug) ! 14: tfree(p); ! 15: } /* so pcc2 stuff doesn't get loaded */ ! 16: #if !defined(COMBINED) ! 17: ! 18: main( argc, argv ) char *argv[]; ! 19: { ! 20: int r; char errbuf[BUFSIZ]; ! 21: ! 22: setbuf(stderr, errbuf); ! 23: r = mainp1( argc, argv ); ! 24: flushx(); ! 25: return( r ); ! 26: } ! 27: ! 28: beg_file() ! 29: { ! 30: /* called as the very first thing by the parser to do machine ! 31: * dependent stuff ! 32: */ ! 33: regvar = minrvar; ! 34: dbfile(NULL); ! 35: } ! 36: ! 37: #else /* defined(COMBINED) */ ! 38: ! 39: locctr(i) ! 40: int i; ! 41: { ! 42: static int last = PROG; ! 43: ! 44: if (i == last) ! 45: return; ! 46: else if (i == PROG) ! 47: printx(" .text\n"); ! 48: else if (i == DATA) ! 49: printx(" .data\n"); ! 50: else ! 51: cerror("funny location counter"); ! 52: last = i; ! 53: } ! 54: ! 55: #endif ! 56: ! 57: NODE * ! 58: treecpy(p) /* first pass version of tcopy() */ ! 59: register NODE *p; ! 60: { ! 61: /* make a fresh copy of p */ ! 62: register NODE *q; ! 63: ! 64: q = talloc(); ! 65: *q = *p; ! 66: switch (optype(q->in.op)) ! 67: { ! 68: case BITYPE: ! 69: q->in.right = treecpy(p->in.right); ! 70: case UTYPE: ! 71: q->in.left = treecpy(p->in.left); ! 72: } ! 73: return (q); ! 74: } ! 75: ! 76: #if !defined(COMBINED) ! 77: ! 78: NODE * ! 79: clocal(p) NODE *p; ! 80: { ! 81: register NODE *l,*ll,*r; ! 82: if( p->in.op == STAR ) ! 83: { /* if it looks like index mode put the */ ! 84: /* offset on the right */ ! 85: l = p->in.left; ! 86: if( l->in.op == PLUS ) ! 87: { ! 88: ll = l->in.left; ! 89: if( ll->in.op != MUL && ll->in.op != UNARY AND ) ! 90: { ! 91: if( (l->in.right)->in.op == MUL ) ! 92: { ! 93: r = l->in.right; ! 94: l->in.right = l->in.left; ! 95: l->in.left = r; ! 96: } ! 97: } ! 98: } ! 99: } ! 100: #ifdef DASSOVCOL ! 101: if (!asgbinop(p->in.op) && p->in.op != ASSIGN) ! 102: return (p); ! 103: r = p->in.right; ! 104: if (optype(r->in.op) == LTYPE) ! 105: return (p); ! 106: l = r->in.left; ! 107: if (r->in.op == QUEST || (r->in.op == CONV && l->in.op == QUEST) || ! 108: (r->in.op == CONV && l->in.op == CONV && ! 109: l->in.left->in.op == QUEST)) ! 110: /* distribute assigns over colons */ ! 111: { ! 112: register NODE *pwork; ! 113: NODE *pcpy = treecpy(p), *pnew; ! 114: #ifndef NODBG ! 115: extern int xdebug, eprint(); ! 116: ! 117: if (xdebug) ! 118: { ! 119: puts("Entering [op]=?: distribution"); ! 120: eprint(p); ! 121: } ! 122: #endif ! 123: pnew = pcpy->in.right; ! 124: while (pnew->in.op != QUEST) ! 125: pnew = pnew->in.left; ! 126: /* ! 127: * pnew is top of new tree ! 128: */ ! 129: if ((pwork = p)->in.right->in.op == QUEST) ! 130: { ! 131: tfree(pwork->in.right); ! 132: pwork->in.right = pnew->in.right->in.left; ! 133: pnew->in.right->in.left = pwork; ! 134: /* at this point, 1/2 distributed. Tree looks like: ! 135: * ASSIGN|ASGOP ! 136: * LVAL QUEST ! 137: * EXPR1 COLON ! 138: * ASSIGN|ASGOP EXPR3 ! 139: * LVAL EXPR2 ! 140: * pnew "holds" new tree from QUEST node ! 141: */ ! 142: } ! 143: else ! 144: { ! 145: NODE *pholdtop = pwork; ! 146: ! 147: pwork = pwork->in.right; ! 148: while (pwork->in.left->in.op != QUEST) ! 149: pwork = pwork->in.left; ! 150: tfree(pwork->in.left); ! 151: pwork->in.left = pnew->in.right->in.left; ! 152: pnew->in.right->in.left = pholdtop; ! 153: /* at this point, 1/2 distributed. Tree looks like: ! 154: * ASSIGN|ASGOP ! 155: * LVAL ANY # OF CONVs ! 156: * QUEST ! 157: * EXPR1 COLON ! 158: * ASSIGN|ASGOP EXPR3 ! 159: * LVAL ANY # OF CONVs ! 160: * EXPR2 ! 161: * pnew "holds" new tree from QUEST node ! 162: */ ! 163: } ! 164: if ((pwork = pcpy)->in.right->in.op == QUEST) ! 165: { ! 166: pwork->in.right = pnew->in.right->in.right; ! 167: pnew->in.right->in.right = pwork; ! 168: /* ! 169: * done with the easy case ! 170: */ ! 171: } ! 172: else ! 173: { ! 174: NODE *pholdtop = pwork; ! 175: ! 176: pwork = pwork->in.right; ! 177: while (pwork->in.left->in.op != QUEST) ! 178: pwork = pwork->in.left; ! 179: pwork->in.left = pnew->in.right->in.right; ! 180: pnew->in.right->in.right = pholdtop; ! 181: /* ! 182: * done with the CONVs case ! 183: */ ! 184: } ! 185: p = pnew; ! 186: #ifndef NODBG ! 187: if (xdebug) ! 188: { ! 189: puts("Leaving [op]=?: distribution"); ! 190: eprint(p); ! 191: } ! 192: #endif ! 193: } ! 194: #endif ! 195: return(p); ! 196: } ! 197: #endif ! 198: ! 199: cisreg( t ) TWORD t; ! 200: { /* is an automatic variable of type t OK for a register variable */ ! 201: ! 202: if( t==INT || t==UNSIGNED || ISPTR(t) || t==CHAR || t==UCHAR ! 203: || t==SHORT || t==USHORT || t==FLOAT ! 204: /* (sigh) || t==STRTY || t == UNIONTY*/ ) ! 205: { ! 206: if( regvar >= 6 ) ! 207: { ! 208: nextrvar = regvar--; ! 209: if( regvar < minrvar ) minrvar = regvar; ! 210: return(1); ! 211: } ! 212: } ! 213: return(0); ! 214: } ! 215: ! 216: opbigsz( op ) ! 217: { ! 218: /* the size below which we do not shrink ops */ ! 219: switch( op ) ! 220: { ! 221: ! 222: default: ! 223: return( SZINT ); ! 224: ! 225: case PLUS: ! 226: case MINUS: ! 227: case OR: ! 228: case AND: ! 229: case ER: ! 230: case COMPL: ! 231: case UNARY MINUS: ! 232: return( SZCHAR ); ! 233: ! 234: } ! 235: } ! 236: ! 237: branch(n) /* branch to label n or return */ ! 238: int n; ! 239: { ! 240: if (!reached) /* return <expr>; } comes here 2x */ ! 241: return; ! 242: genubr(n); ! 243: } ! 244: ! 245: #if !defined(COMBINED) ! 246: /* direct switch beginning */ ! 247: static int tablelabel; ! 248: ! 249: struct sw heapsw[SWITSZ]; /* heap for switches */ ! 250: ! 251: /* test for whether to do a direct switch */ ! 252: # ifndef DSWTEST ! 253: # define DSWTEST(r,n) (r>0 && r<=(3*n) && n>=4) ! 254: # endif ! 255: /* test for whether to do a heap switch */ ! 256: # ifndef HEAPTEST ! 257: # define HEAPTEST( n ) (n>8) ! 258: # endif ! 259: ! 260: genswitch(p,n) register struct sw *p; ! 261: { ! 262: /* p points to an array of structures, each consisting ! 263: of a constant value and a label. ! 264: The first is >=0 if there is a default label; ! 265: its value is the label number ! 266: The entries p[1] to p[n] are the nontrivial cases ! 267: */ ! 268: register i; ! 269: register CONSZ j, range; ! 270: register dlab, swlab; ! 271: ! 272: range = p[n].sval-p[1].sval; ! 273: ! 274: if( DSWTEST( range, n ) ) ! 275: { /* implement a direct switch */ ! 276: ! 277: swlab = getlab(); ! 278: dlab = ((p->slab >= 0) ? p->slab : getlab()); ! 279: ! 280: dswbegin( n, p[1].sval, range, swlab, dlab ); ! 281: ! 282: for( i=1,j=p[1].sval; i<=n; j++) ! 283: { ! 284: if( j == p[i].sval ) ! 285: { ! 286: dswcase( p[i].slab ); ! 287: j = p[i++].sval; ! 288: } ! 289: else ! 290: { ! 291: dswcase( dlab ); ! 292: } ! 293: } ! 294: ! 295: /* in case dswbegin changed location counters... */ ! 296: locctr( PROG ); ! 297: ! 298: if( p->slab >= 0 ) genubr( dlab ); ! 299: else deflab( dlab ); ! 300: return; ! 301: } ! 302: ! 303: if( HEAPTEST(n) ) ! 304: { /* heap switch */ ! 305: ! 306: heapsw[0].slab = dlab = (p->slab >= 0 ? p->slab : getlab()); ! 307: makeheap(p, n, 1); /* build heap */ ! 308: walkheap(1, n); /* produce code */ ! 309: ! 310: if( p->slab >= 0 ) ! 311: genubr( dlab ); ! 312: else ! 313: deflab( dlab ); ! 314: return; ! 315: } ! 316: ! 317: /* simple switch code */ ! 318: ! 319: for( i=1; i<=n; ++i ) sswtest( p[i].sval, p[i].slab ); ! 320: if( p->slab>=0 ) genubr( p->slab ); ! 321: ! 322: } ! 323: ! 324: makeheap(p, m, n) ! 325: register struct sw *p; ! 326: { ! 327: register int q; ! 328: ! 329: q = select(m); ! 330: heapsw[n] = p[q]; ! 331: if( q>1 ) makeheap(p, q-1, 2*n); ! 332: if( q<m ) makeheap(p+q, m-q, 2*n+1); ! 333: } ! 334: ! 335: select(m) { ! 336: register int l,i,k; ! 337: ! 338: for(i=1; ; i*=2) ! 339: if( (i-1) > m ) break; ! 340: l = ((k = i/2 - 1) + 1)/2; ! 341: return( l + (m-k < l ? m-k : l)); ! 342: } ! 343: ! 344: walkheap(start, limit) ! 345: { ! 346: int label; ! 347: ! 348: ! 349: if( start > limit ) return; ! 350: sswtest( heapsw[start].sval, heapsw[start].slab ); ! 351: if( (2*start) > limit ) { ! 352: genubr( heapsw[0].slab ); ! 353: return; ! 354: } ! 355: if( (2*start+1) <= limit ) { ! 356: label = getlab(); ! 357: hswelse( label ); ! 358: } else ! 359: hswelse( heapsw[0].slab ); ! 360: walkheap( 2*start, limit); ! 361: if( (2*start+1) <= limit ) { ! 362: deflab( label ); ! 363: walkheap( 2*start+1, limit); ! 364: } ! 365: } ! 366: ! 367: ! 368: dswbegin( numb, first, range, labl, dlab ) ! 369: CONSZ first, range; ! 370: int numb, labl, dlab; ! 371: { ! 372: printx(" casel r0,$%ld,$%ld\n", first, range ); ! 373: printx("L%d:\n", labl ); ! 374: tablelabel = labl; ! 375: } ! 376: ! 377: dswcase( l ) ! 378: int l; ! 379: { ! 380: printx(" .word L%d-L%d\n", l, tablelabel ); ! 381: } ! 382: ! 383: sswtest( val, lab ) ! 384: CONSZ val; ! 385: int lab; ! 386: { ! 387: printx( " cmpl r0,$%ld\n jeql L%d\n", val, lab ); ! 388: } ! 389: ! 390: hswelse( lab ) ! 391: int lab; ! 392: { ! 393: printx(" jgtr L%d\n", lab ); ! 394: } ! 395: #endif /* COMBINED */ ! 396: ! 397: OFFSZ inoff; /* size of offset in structure */ ! 398: ! 399: static inwd; /* current bit offset in word */ ! 400: static long word; /* word being built from fields */ ! 401: ! 402: zecode( n ) ! 403: int n; ! 404: { ! 405: /* n integer words of zeros */ ! 406: if (n <= 0) return; ! 407: printx( " .space %d\n", 4*n ); ! 408: inoff += n*SZINT; ! 409: } ! 410: ! 411: vfdzero( n ){ /* define n bits of zeros in a vfd */ ! 412: ! 413: /* this could be done more cleverly: the following is safe */ ! 414: ! 415: sz_incode( (CONSZ)0, n ); ! 416: } ! 417: ! 418: incode (p, sz) ! 419: NODE *p; ! 420: { ! 421: sz_incode(p->tn.lval, sz); ! 422: } ! 423: ! 424: sz_incode( val, sz ) ! 425: CONSZ val; ! 426: { ! 427: ! 428: /* generate initialization code for assigning a constant c ! 429: to a field of width sz */ ! 430: /* we assume that the proper alignment has been obtained */ ! 431: /* inoff is updated to have the proper final value */ ! 432: ! 433: if((sz+inwd) > SZLONG) cerror("incode: field > long"); ! 434: ! 435: /* this code will have to be replaced if the size of a long on ! 436: /* the target machine differs from that on the host machine */ ! 437: ! 438: # ifdef RTOLBYTES ! 439: word |= ((unsigned)(val<<(SZLONG-sz))) >> (SZLONG-sz-inwd); ! 440: # else ! 441: word |= ((unsigned)(val<<(SZLONG-sz))) >> inwd; ! 442: # endif ! 443: inwd += sz; ! 444: inoff += sz; ! 445: ! 446: /* if initialization can be carried out using shorts, do it */ ! 447: # if (SZSHORT >= ALINIT) ! 448: if(inwd == SZSHORT ) ! 449: { ! 450: # ifdef RTOLBYTES ! 451: genshort( (short) word ); ! 452: # else ! 453: genshort( (short) (word>>(SZLONG-SZSHORT)) ); ! 454: # endif ! 455: word = inwd = 0; ! 456: } else ! 457: # endif ! 458: if( inwd == SZLONG ) ! 459: { ! 460: genlong( word ); ! 461: word = inwd = 0; ! 462: } ! 463: } ! 464: ! 465: fincode( d, sz ) ! 466: double d; ! 467: int sz; ! 468: { ! 469: /* output code to initialize space of size sz to the value d */ ! 470: /* the proper alignment has been obtained */ ! 471: /* on the target machine, write it out in hex! */ ! 472: ! 473: #if defined(vax) ! 474: union { float f; double d; int i[2] } cheat; ! 475: ! 476: if (sz == SZDOUBLE) ! 477: { ! 478: cheat.d = d; ! 479: printx("\t.long\t0x%x,0x%x\t# %.20e\n", cheat.i[0], cheat.i[1], ! 480: cheat.d); ! 481: } ! 482: else ! 483: { ! 484: cheat.f = d; ! 485: printx("\t.long\t0x%x\t# %.20e\n", cheat.i[0], cheat.f); ! 486: } ! 487: #else ! 488: printx(" %s 0%c%.20e\n", ! 489: sz == SZDOUBLE ? ".double" : ".float", ! 490: sz == SZDOUBLE ? 'd' : 'f', d); ! 491: #endif ! 492: inoff += sz; ! 493: ! 494: } ! 495: ! 496: int ftlab1, ftlab2; ! 497: int proflag; ! 498: ! 499: int ent_mask[] = { ! 500: 0,0,0,0,0, 0xfc0, 0xf80, 0xf00, 0xe00, 0xc00, 0x800, 0}; ! 501: ! 502: #if defined(COMBINED) ! 503: efcode(type) ! 504: int type; ! 505: #else ! 506: efcode() ! 507: #endif ! 508: { ! 509: /* code for the end of a function */ ! 510: long spoff; /* offset from stack pointer */ ! 511: ! 512: #if defined(COMBINED) ! 513: deflab(retlab); ! 514: repl_retval(type); ! 515: printx("\tret\n"); ! 516: #else ! 517: genret( strftn, strftn, retlab ); ! 518: #endif ! 519: printx( " .set L.R%d,0x%x\n", ftnno, ent_mask[minrvar] ); ! 520: ! 521: #ifdef FORT ! 522: spoff = maxboff; ! 523: if( spoff >= BITOOR(AUTOINIT) ) spoff -= BITOOR(AUTOINIT); ! 524: spoff += maxtemp; ! 525: spoff /= SZCHAR; ! 526: printx( " .set L.F%d,%ld\n", ftnno, spoff / SZCHAR ); ! 527: #else ! 528: spoff = maxboff; ! 529: if( spoff >= BITOOR(AUTOINIT) ) spoff -= BITOOR(AUTOINIT); ! 530: spoff += maxtemp; ! 531: spoff /= SZCHAR; ! 532: printx("\t.set\tL.SO%d,0x%x\n", ftnno, spoff); ! 533: #endif ! 534: regvar = minrvar = 11; ! 535: #ifdef GDEBUG ! 536: dbfunend(getlab()); ! 537: #endif ! 538: } ! 539: ! 540: bfcode( a, n ) ! 541: int a[], n; ! 542: { ! 543: /* code for the beginning of a function; a is an array of ! 544: indices in stab for the arguments; n is the number */ ! 545: register i; ! 546: ! 547: /* routine prolog */ ! 548: ! 549: printx( " .word L.R%d\n", ftnno); ! 550: printx("\tsubl2\t$L.SO%d,sp\n", ftnno); ! 551: ! 552: retlab = getlab(); ! 553: ! 554: if( proflag ) ! 555: { /* profile code */ ! 556: i = getlab(); ! 557: printx(" movab L%d,r0\n", i); ! 558: printx(" jsb mcount\n"); ! 559: printx(" .data\n"); ! 560: printx(" .align 2\n"); ! 561: printx("L%d: .long 0\n", i); ! 562: printx(" .text\n"); ! 563: } ! 564: if(Pflag) { ! 565: printx("\t.data\n\t.comm _proFptr,4\n\t.text\n"); ! 566: printx("\ttstl locprof+4\n\tbneq L%da\n", ++bbcnt); ! 567: printx("\tmovl _proFptr,locprof+4\n\tmoval locprof,_proFptr\n"); ! 568: printx("#entry %d\n", bbcnt); ! 569: printf("L%da:\tincl locprof+%d\n", bbcnt, 4*(bbcnt+3)); ! 570: } ! 571: #ifdef GDEBUG ! 572: dbfunbeg(&stab[curftn]); ! 573: for (i = 0; i < n; ++i) { ! 574: extern TWORD argty[]; ! 575: extern int argsoff[]; ! 576: struct symtab q; ! 577: q = stab[a[i]]; ! 578: q.sclass = PARAM; ! 579: q.stype = argty[i]; ! 580: q.offset = argsoff[i]; ! 581: dbfunarg(&q); ! 582: } ! 583: #endif ! 584: } ! 585: ! 586: defnam( psym ) ! 587: register struct symtab *psym; ! 588: { ! 589: /* define the current location as the name psym->sname ! 590: * first give the debugging info for external definitions ! 591: */ ! 592: /*if( psym->slevel == 0 ) /* make sure it's external */ ! 593: /* ISFTN(psym->stype) ? prdef(psym,0) : prdef(psym,dsflag); ! 594: */ ! 595: ! 596: if (psym->sclass == EXTDEF) ! 597: printx( " .globl %s\n", exname(psym->sname) ); ! 598: printx("%s:\n", exname(psym->sname)); ! 599: } ! 600: ! 601: commdec(id) /* generate a .comm from stab index id */ ! 602: int id; ! 603: { ! 604: #if !defined(COMBINED) ! 605: register struct symtab *psym; ! 606: OFFSZ n; ! 607: ! 608: psym = &stab[id]; ! 609: psym->sflags |= SBSS; ! 610: n = tsize(psym->stype, psym->dimoff, psym->sizoff) / SZCHAR; ! 611: if (psym->sclass == STATIC) ! 612: if (psym->slevel) ! 613: printx(" .lcomm L%d,%ld\n", psym->offset, n); ! 614: else ! 615: printx(" .lcomm %s,%ld\n", exname(psym->sname), n); ! 616: else if (psym->sclass == EXTERN) ! 617: printx(" .comm %s,%ld\n", exname(psym->sname), n); ! 618: ! 619: else ! 620: cerror("Non-static/external in common"); ! 621: #endif ! 622: } ! 623: ! 624: myfcon(p) ! 625: NODE *p; ! 626: { ! 627: union { double d; int i[2]; } u; ! 628: ! 629: u.d = p->fpn.dval; ! 630: if (u.i[1] == 0) /* no significant lo bits, shorten */ ! 631: { ! 632: p->fn.type = FLOAT; ! 633: p->fn.csiz = FLOAT; ! 634: } ! 635: } ! 636:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.