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