|
|
1.1 ! root 1: /* @(#) local.c: 1.7 3/19/84 */ ! 2: /* local.c - machine dependent stuff for front end ! 3: * ! 4: * WE 32000 ! 5: * ! 6: */ ! 7: ! 8: #include <signal.h> ! 9: #include "mfile1.h" ! 10: ! 11: int dsflag = 0; /* symbol info initially enabled */ ! 12: static int dlflag = 0; /* line number info initially enabled */ ! 13: ! 14: /* location counters for PROG, DATA, ADATA, ISTRNG, STRNG */ ! 15: char *locnames[] = ! 16: { ! 17: " .text\n", ! 18: " .data\n", ! 19: " .data\n", ! 20: " .data 1\n", ! 21: " .data 1\n", ! 22: }; ! 23: ! 24: int minrvar = TOTREGS; ! 25: ! 26: static char *tmpfn; ! 27: static FILE *outfile = stdout; ! 28: static FILE *tmpfp; ! 29: ! 30: #ifdef M32B ! 31: int wloop_level = LL_BOT; /* place "while" test at loop end */ ! 32: int floop_level = LL_BOT; /* place "for" test at loop end */ ! 33: #else ! 34: int wloop_level = LL_BOT; /* place "while" test at loop end */ ! 35: int floop_level = LL_BOT; /* place "for" test at top and bot */ ! 36: #endif ! 37: ! 38: ! 39: myexit(n) ! 40: { ! 41: unlink(tmpfn); ! 42: if (n == 1) ! 43: n = 51; ! 44: exit(n); ! 45: } ! 46: ! 47: getout() ! 48: { ! 49: myexit(55); ! 50: } ! 51: ! 52: FILE *fopen(); ! 53: static int proflag; ! 54: ! 55: main(argc, argv) ! 56: int argc; ! 57: char **argv; ! 58: { ! 59: int j, m, n; ! 60: char buf[BUFSIZ], *gotnm = NULL, *findnm; ! 61: ! 62: /* catch signals if they're not now being ignored */ ! 63: ! 64: if (signal(SIGHUP, SIG_IGN) != SIG_IGN) ! 65: signal(SIGHUP, getout); ! 66: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 67: signal(SIGINT, getout); ! 68: if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) ! 69: signal(SIGQUIT, getout); ! 70: if (signal(SIGTERM, SIG_IGN) != SIG_IGN) ! 71: signal(SIGTERM, getout); ! 72: ! 73: for (m = 1; m < argc && argv[m][0] == '-'; ++m) ! 74: { ! 75: switch( argv[m][1] ) ! 76: { ! 77: case 'i': /* input file name */ ! 78: if (!freopen(argv[m+1], "r", stdin)) ! 79: { ! 80: fprintf(stderr, "Can't open %s\n", argv[m+1]); ! 81: myexit(2); ! 82: } ! 83: n = 2; ! 84: break; ! 85: ! 86: case 'o': /* output file name */ ! 87: if (!freopen(argv[m+1], "w", stdout)) ! 88: { ! 89: fprintf(stderr, "Can't open %s\n", argv[m+1]); ! 90: myexit(2); ! 91: } ! 92: n = 2; ! 93: break; ! 94: ! 95: case 'f': /* .c source file name */ ! 96: for (gotnm = findnm = argv[m+1]; *findnm; ++findnm) ! 97: if (*findnm == '/') ! 98: gotnm = findnm + 1; ! 99: n = 2; ! 100: break; ! 101: ! 102: case 'd': /* prevent symbolic debug output */ ! 103: if (argv[m][2] == 'l' || argv[m][3] == 'l') ! 104: dlflag = 1; ! 105: if (argv[m][2] == 's' || argv[m][3] == 's') ! 106: dsflag = 1; ! 107: n = 1; ! 108: break; ! 109: ! 110: case '1': /* debug flags to front */ ! 111: argv[m][1] = 'X'; ! 112: continue; ! 113: ! 114: case '2': /* debug flags to back */ ! 115: argv[m]++; ! 116: argv[m][0] = '-'; ! 117: continue; ! 118: ! 119: case 'V': /* print version info */ ! 120: fputs("WE32000 pcc2 compiler: @(#)local.c SVR2\n", ! 121: stderr); ! 122: n = 1; ! 123: break; ! 124: ! 125: case 'p': ! 126: ++proflag; ! 127: n = 1; ! 128: break; ! 129: ! 130: default: ! 131: continue; ! 132: ! 133: } ! 134: ! 135: argc -= n; ! 136: for( j = m; j < argc; ++j ) ! 137: argv[j] = argv[j+n]; ! 138: m--; ! 139: } ! 140: ! 141: if (gotnm != NULL) ! 142: { ! 143: strcpy(ftitle, "\""); ! 144: strcat(ftitle, gotnm); ! 145: strcat(ftitle, "\""); ! 146: } ! 147: n = mainp1(argc, argv); ! 148: fclose(tmpfp); ! 149: if (!(tmpfp = fopen(tmpfn, "r"))) ! 150: cerror("string file disappeared???"); ! 151: while (m = fread(buf, 1, BUFSIZ, tmpfp)) ! 152: fwrite(buf, 1, m, stdout); ! 153: myexit(n); ! 154: } ! 155: ! 156: beg_file() ! 157: { ! 158: /* called as the very first thing by the parser to do machine ! 159: * dependent stuff ! 160: */ ! 161: register char *p, *s; ! 162: char *mktemp(); ! 163: ! 164: /* note: double quotes already in ftitle... */ ! 165: p = ftitle + strlen( ftitle ) - 2; ! 166: s = p - 14; /* max name length */ ! 167: while ( p > s && *p != '"' && *p != '/' ) ! 168: --p; ! 169: printf( "\t.file\t\"%.15s\n", p + 1 ); ! 170: if(!(tmpfp= fopen(tmpfn = mktemp("pcc2SXXXXXX"), "w"))) ! 171: cerror("can't create string file\n"); ! 172: } ! 173: ! 174: locctr(l) /* output the location counter */ ! 175: { ! 176: static int lastloc = PROG, lastpd = PROG; ! 177: int retval = lastloc; /* value to return at end */ ! 178: ! 179: curloc = l; ! 180: switch (l) ! 181: { ! 182: case PROG: ! 183: if (lastloc == PROG) ! 184: break; ! 185: if (lastpd == DATA) ! 186: puts(" .text"); ! 187: lastpd = PROG; ! 188: outfile = stdout; ! 189: break; ! 190: ! 191: case DATA: ! 192: case ADATA: ! 193: if (lastloc == DATA || lastloc == ADATA) ! 194: break; ! 195: if (lastpd == PROG) ! 196: puts(" .data"); ! 197: lastpd = DATA; ! 198: outfile = stdout; ! 199: break; ! 200: ! 201: case STRNG: ! 202: case ISTRNG: ! 203: /* output string initializers to a temporary file for now ! 204: * don't update lastloc ! 205: */ ! 206: ! 207: outfile = tmpfp; ! 208: break; ! 209: ! 210: default: ! 211: cerror( "illegal location counter" ); ! 212: } ! 213: ! 214: lastloc = l; ! 215: return( retval ); /* declare previous loc. ctr. */ ! 216: } ! 217: ! 218: NODE * ! 219: treecpy(p) /* first pass version of tcopy() */ ! 220: register NODE *p; ! 221: { ! 222: /* make a fresh copy of p */ ! 223: register NODE *q; ! 224: ! 225: q = talloc(); ! 226: *q = *p; ! 227: switch (optype(q->in.op)) ! 228: { ! 229: case BITYPE: ! 230: q->in.right = treecpy(p->in.right); ! 231: case UTYPE: ! 232: q->in.left = treecpy(p->in.left); ! 233: } ! 234: return (q); ! 235: } ! 236: ! 237: ! 238: NODE * ! 239: clocal(p) /* manipulate the parse tree for local xforms */ ! 240: register NODE *p; ! 241: { ! 242: register NODE *l, *r; ! 243: ! 244: #if defined(M32B) && defined(IMPREGAL) ! 245: if ((p->in.op == VAUTO || p->in.op == VPARAM) && p->in.pad[0] == '@') ! 246: { ! 247: raname(p); ! 248: p->in.pad[0] = '~'; /*has been raname()'d*/ ! 249: } ! 250: #endif ! 251: if (!asgbinop(p->in.op) && p->in.op != ASSIGN) ! 252: return (p); ! 253: r = p->in.right; ! 254: if (optype(r->in.op) == LTYPE) ! 255: return (p); ! 256: l = r->in.left; ! 257: if (r->in.op == QUEST || ! 258: (r->in.op == CONV && l->in.op == QUEST) || ! 259: (r->in.op == CONV && l->in.op == CONV && ! 260: l->in.left->in.op == QUEST)) ! 261: /* distribute assigns over colons */ ! 262: { ! 263: register NODE *pwork; ! 264: NODE *pcpy = treecpy(p), *pnew; ! 265: #ifndef NODBG ! 266: extern int xdebug, eprint(); ! 267: ! 268: if (xdebug) ! 269: { ! 270: puts("Entering [op]=?: distribution"); ! 271: eprint(p); ! 272: } ! 273: #endif ! 274: pnew = pcpy->in.right; ! 275: while (pnew->in.op != QUEST) ! 276: pnew = pnew->in.left; ! 277: /* ! 278: * pnew is top of new tree ! 279: */ ! 280: if ((pwork = p)->in.right->in.op == QUEST) ! 281: { ! 282: tfree(pwork->in.right); ! 283: pwork->in.right = pnew->in.right->in.left; ! 284: pnew->in.right->in.left = pwork; ! 285: /* at this point, 1/2 distributed. Tree looks like: ! 286: * ASSIGN|ASGOP ! 287: * LVAL QUEST ! 288: * EXPR1 COLON ! 289: * ASSIGN|ASGOP EXPR3 ! 290: * LVAL EXPR2 ! 291: * pnew "holds" new tree from QUEST node ! 292: */ ! 293: } ! 294: else ! 295: { ! 296: NODE *pholdtop = pwork; ! 297: ! 298: pwork = pwork->in.right; ! 299: while (pwork->in.left->in.op != QUEST) ! 300: pwork = pwork->in.left; ! 301: tfree(pwork->in.left); ! 302: pwork->in.left = pnew->in.right->in.left; ! 303: pnew->in.right->in.left = pholdtop; ! 304: /* at this point, 1/2 distributed. Tree looks like: ! 305: * ASSIGN|ASGOP ! 306: * LVAL ANY # OF CONVs ! 307: * QUEST ! 308: * EXPR1 COLON ! 309: * ASSIGN|ASGOP EXPR3 ! 310: * LVAL ANY # OF CONVs ! 311: * EXPR2 ! 312: * pnew "holds" new tree from QUEST node ! 313: */ ! 314: } ! 315: if ((pwork = pcpy)->in.right->in.op == QUEST) ! 316: { ! 317: pwork->in.right = pnew->in.right->in.right; ! 318: pnew->in.right->in.right = pwork; ! 319: /* ! 320: * done with the easy case ! 321: */ ! 322: } ! 323: else ! 324: { ! 325: NODE *pholdtop = pwork; ! 326: ! 327: pwork = pwork->in.right; ! 328: while (pwork->in.left->in.op != QUEST) ! 329: pwork = pwork->in.left; ! 330: pwork->in.left = pnew->in.right->in.right; ! 331: pnew->in.right->in.right = pholdtop; ! 332: /* ! 333: * done with the CONVs case ! 334: */ ! 335: } ! 336: p = pnew; ! 337: #ifndef NODBG ! 338: if (xdebug) ! 339: { ! 340: puts("Leaving [op]=?: distribution"); ! 341: eprint(p); ! 342: } ! 343: #endif ! 344: } ! 345: return(p); ! 346: } ! 347: ! 348: ! 349: cisreg(t) /* can auto of type t go in reg */ ! 350: TWORD t; ! 351: { ! 352: int nregs; ! 353: ! 354: /* ! 355: * Only allow register basic types or pointers. ! 356: * Someday, maybe allow register small-struct ! 357: */ ! 358: switch (t) ! 359: { ! 360: case CHAR: case SHORT: case INT: case LONG: ! 361: case UCHAR: case USHORT: case UNSIGNED: case ULONG: ! 362: case FLOAT: case DOUBLE: ! 363: break; ! 364: default: ! 365: if (ISPTR(t)) ! 366: break; ! 367: return (0); ! 368: } ! 369: nregs = (t == DOUBLE ? 2 : 1); ! 370: if (regvar + nregs <= TOTREGS-NRGS) /* check for too many */ ! 371: { ! 372: regvar += nregs; /* number now in use */ ! 373: if ((TOTREGS - regvar) < minrvar) ! 374: minrvar -= nregs; ! 375: nextrvar = TOTREGS - regvar; ! 376: return (1); ! 377: } ! 378: else ! 379: return (0); ! 380: } ! 381: ! 382: incode( p, sz ) ! 383: register NODE *p; ! 384: { ! 385: /* generate initialization code for assigning a constant c ! 386: * to a field of width sz ! 387: * we assume that the proper alignment has been obtained and sz < SZINT ! 388: * inoff is updated to have the proper final value ! 389: */ ! 390: if (inoff % SZINT == 0 ) ! 391: printf(" .word %d:%d", sz, p->tn.lval); ! 392: else ! 393: printf(",%d:%d", sz, p->tn.lval); ! 394: inoff += sz; ! 395: if (inoff % SZINT == 0) ! 396: putchar('\n'); ! 397: } ! 398: ! 399: vfdzero(n) /* define n bits of zeros in a vfd */ ! 400: int n; ! 401: { ! 402: if( n <= 0 ) ! 403: return; ! 404: if (inoff % SZINT == 0 ) ! 405: printf(" .word %d:0", n); ! 406: else ! 407: printf(",%d:0", n); ! 408: inoff += n; ! 409: if (inoff % SZINT == 0) ! 410: putchar('\n'); ! 411: } ! 412: ! 413: fincode(d, sz) /* floating initialization */ ! 414: double d; ! 415: int sz; ! 416: { ! 417: #if defined(u3b) || defined(u3b5) || defined(u3b2) ! 418: union { double d; float f; int i[2] } cheat; ! 419: ! 420: if (sz == SZDOUBLE) ! 421: { ! 422: cheat.d = d; ! 423: printf(" .word 0x%x,0x%x\n", cheat.i[0], cheat.i[1]); ! 424: } ! 425: else ! 426: { ! 427: cheat.f = d; ! 428: printf(" .word 0x%x\n", cheat.i[0]); ! 429: } ! 430: #else ! 431: printf("\t.%s\t%.15e\n", sz == SZDOUBLE ? "double" : "float", d); ! 432: #endif ! 433: inoff += sz; ! 434: } ! 435: ! 436: ! 437: char * ! 438: exname(p) /* a name using external naming conventions */ ! 439: char *p; ! 440: { ! 441: return( p ); ! 442: } ! 443: ! 444: ! 445: commdec(id) /* generate a .comm from stab index id */ ! 446: int id; ! 447: { ! 448: register struct symtab *psym; ! 449: OFFSZ n; ! 450: ! 451: psym = &stab[id]; ! 452: n = tsize(psym->stype, psym->dimoff, psym->sizoff) / SZCHAR; ! 453: # ifndef NOSYMB ! 454: if ( psym->slevel == 0) ! 455: prdef(psym, dsflag); /* output debug info */ ! 456: # endif ! 457: if (psym->sclass == STATIC) ! 458: printf(" .bss %s,%ld,%ld\n", exname(psym->sname), ! 459: n, nalign(psym->stype)); ! 460: else if (psym->sclass == EXTERN) ! 461: printf(" .comm %s,%ld\n", exname(psym->sname), n); ! 462: ! 463: ! 464: else ! 465: cerror("Non-static/external in common"); ! 466: } ! 467: ! 468: ! 469: static ! 470: nalign(t) /* figure alignment for type t */ ! 471: TWORD t; ! 472: { ! 473: int aln; ! 474: ! 475: if (ISPTR(t)) ! 476: aln = ALPOINT; ! 477: else switch (BTYPE(t)) ! 478: { ! 479: case CHAR: ! 480: case UCHAR: ! 481: aln = ALCHAR; ! 482: break; ! 483: case SHORT: ! 484: case USHORT: ! 485: aln = ALSHORT; ! 486: break; ! 487: case INT: ! 488: case UNSIGNED: ! 489: case ENUMTY: ! 490: aln = ALINT; ! 491: break; ! 492: case LONG: ! 493: case ULONG: ! 494: aln = ALLONG; ! 495: break; ! 496: case FLOAT: ! 497: aln = ALFLOAT; ! 498: break; ! 499: case DOUBLE: ! 500: aln = ALDOUBLE; ! 501: break; ! 502: case STRTY: ! 503: case UNIONTY: ! 504: aln = ALSTRUCT; ! 505: break; ! 506: default: ! 507: cerror("Confused type in nalign"); ! 508: /*NOTREACHED*/ ! 509: } ! 510: return (aln / SZCHAR); ! 511: } ! 512: ! 513: ! 514: branch(n) /* branch to label n or return */ ! 515: int n; ! 516: { ! 517: if (!reached) /* return <expr>; } comes here 2x */ ! 518: return; ! 519: else ! 520: printf(" jmp .L%d\n", n); ! 521: } ! 522: ! 523: ! 524: defalign(n) /* align to multiple of n */ ! 525: int n; ! 526: { ! 527: if ((n /= SZCHAR) > 1) ! 528: printf(" .align %d\n", n); ! 529: } ! 530: ! 531: ! 532: deflab(n) /* label n */ ! 533: int n; ! 534: { ! 535: fprintf(outfile, ".L%d:\n", n); ! 536: } ! 537: ! 538: ! 539: efcode() /* wind up a function */ ! 540: { ! 541: extern int maxboff, maxtemp, maxarg; ! 542: extern int strftn; /* non-zero if function is structure function, ! 543: ** contains label number of local static value ! 544: */ ! 545: register int i, enterval; ! 546: ! 547: deflab(retlab); ! 548: ! 549: efdebug(); /* end of function debug info */ ! 550: ! 551: if (strftn) /* return addr in 1st auto */ ! 552: printf(" movw 0(%%fp),%%r0\n", ftnno); ! 553: printf("\t.set\t.F%d,%d\n\t.set\t.R%d,%d\n\tret\t&.R%d\n", ftnno, ! 554: (maxtemp + maxboff) / SZCHAR, ftnno, TOTREGS - minrvar, ftnno); ! 555: minrvar = TOTREGS; ! 556: } ! 557: ! 558: ! 559: bfcode(a, n) /* begin function code. a is array of n stab */ ! 560: int a[], n; /* indices corresponding to incoming args */ ! 561: { ! 562: int temp; ! 563: ! 564: #if defined(M32B) && defined(IMPREGAL) ! 565: rainit(); ! 566: #endif ! 567: printf(" save &.R%d\n", ftnno); ! 568: if (proflag) ! 569: { ! 570: puts(" .data"); ! 571: temp = getlab(); ! 572: deflab(temp); ! 573: puts("\t.align\t4\n\t.word 0\n .text"); ! 574: printf(" movw &.L%d,%%r0\n",temp); ! 575: puts(" jsb _mcount"); ! 576: } ! 577: printf(" addw2 &.F%d,%%sp\n", ftnno); ! 578: retlab = getlab(); ! 579: bfdebug( a, n, dsflag ); /* do debug info at fcn begin */ ! 580: } ! 581: ! 582: ! 583: defnam(psym) /* current location is name from psym */ ! 584: register struct symtab *psym; ! 585: { ! 586: /* define the current location as the name psym->sname ! 587: * first give the debugging info for external definitions ! 588: */ ! 589: if( psym->slevel == 0 ) /* make sure it's external */ ! 590: ISFTN(psym->stype) ? prdef(psym,0) : prdef(psym,dsflag); ! 591: ! 592: if (psym->sclass == EXTDEF) ! 593: printf(" .globl %s\n", exname(psym->sname)); ! 594: printf("%s:\n", exname(psym->sname)); ! 595: } ! 596: ! 597: ! 598: bycode(ch, loc) /* byte ch into string location loc */ ! 599: int ch, loc; ! 600: { ! 601: if (ch < 0) /* eos */ ! 602: { ! 603: if (loc) ! 604: putc('\n', outfile); ! 605: } ! 606: else ! 607: { ! 608: if ((loc % 10) == 0) ! 609: fputs("\n .byte ", outfile); ! 610: else ! 611: putc(',', outfile); ! 612: fprintf(outfile, "%d", ch); ! 613: } ! 614: } ! 615: ! 616: zecode(n) /* n words of 0 */ ! 617: register int n; ! 618: { ! 619: if (n <= 0) /* this is possible, folks */ ! 620: return; ! 621: printf(" .zero %d\n", (SZINT / SZCHAR) * n); ! 622: inoff += n * SZINT; ! 623: } ! 624: ! 625: struct sw heapsw[SWITSZ]; /* heap for switches */ ! 626: ! 627: genswitch(p, n) ! 628: register struct sw *p; ! 629: int n; ! 630: { ! 631: /* p points to an array of structures, each consisting */ ! 632: /* of a constant value and a label. */ ! 633: /* The first is >=0 if there is a default label; its */ ! 634: /* value is the label number. The entries p[1] to p[n] */ ! 635: /* are the nontrivial cases */ ! 636: ! 637: register int i; ! 638: register CONSZ j, range; ! 639: register int dlab, swlab; ! 640: ! 641: range = p[n].sval-p[1].sval; ! 642: if (range > 0 && range <= (3 * n) && n >= 4) ! 643: { /* implement a direct switch */ ! 644: dlab = (p->slab >= 0) ? p->slab : getlab(); ! 645: if (p[1].sval) ! 646: #if defined(M32B) && defined(IMPSWREG) ! 647: { ! 648: printf("\tsubw3\t&%ld,%%r%d,%%r0\n\tjneg\t.L%d\n", ! 649: p[1].sval, swregno, dlab); ! 650: swregno = 0; ! 651: } ! 652: #else ! 653: printf("\tsubw2\t&%ld,%%r0\n\tjneg\t.L%d\n", ! 654: p[1].sval, dlab); ! 655: #endif ! 656: swlab = getlab(); ! 657: #if defined(M32B) && defined(IMPSWREG) ! 658: printf("\tcmpw\t%%r%d,&%d\n\tjg\t.L%d\n\tALSW3\t&2,%%r%d,%%r0\n" ! 659: , swregno, range, dlab, swregno); ! 660: printf("\tcmpw\t%%r%d,&0\n\tjneg\t.L%d\n", ! 661: swregno, dlab); ! 662: #else ! 663: printf("\tcmpw\t%%r0,&%d\n\tjg\t.L%d\n\tALSW3\t&2,%%r0,%%r0\n", ! 664: range, dlab); ! 665: printf("\tcmpw\t%%r0,&0 \n\tjneg\t.L%d\n", dlab); ! 666: #endif ! 667: printf("\tjmp\t*.L%d(%%r0)\n", swlab); ! 668: locctr(ADATA); /* output table */ ! 669: defalign(ALPOINT); ! 670: puts("#SWBEG"); ! 671: deflab(swlab); ! 672: for (i = 1, j = p[1].sval; i <= n; ++j) ! 673: printf(" .word .L%d\n", ! 674: (j == p[i].sval) ? p[i++].slab : dlab ); ! 675: puts("#SWEND"); ! 676: locctr(PROG); ! 677: if (p->slab < 0) ! 678: deflab(dlab); ! 679: } ! 680: else if ( n > 8 ) ! 681: { ! 682: heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab(); ! 683: makeheap( p, n, 1 ); /* build heap */ ! 684: walkheap( 1, n ); /* produce code */ ! 685: if( p->slab >= 0 ) ! 686: branch( dlab ); ! 687: else ! 688: deflab( dlab ); ! 689: } ! 690: else /* simple switch code */ ! 691: { ! 692: for (i = 1; i <= n; ++i) ! 693: #if defined(M32B) && defined(IMPSWREG) ! 694: printf("\tcmpw\t&%ld,%%r%d\n\tje\t.L%d\n", ! 695: p[i].sval, swregno, p[i].slab); ! 696: #else ! 697: printf("\tcmpw\t&%ld,%%r0\n\tje\t.L%d\n", ! 698: p[i].sval, p[i].slab); ! 699: #endif ! 700: if (p->slab >= 0) ! 701: branch(p->slab); ! 702: } ! 703: } ! 704: ! 705: makeheap( p, m, n ) ! 706: register struct sw *p; ! 707: { ! 708: register int q; ! 709: ! 710: if( n >= SWITSZ ) ! 711: cerror( "heap switch size exceeded" ); ! 712: q = select( m ); ! 713: heapsw[n] = p[q]; ! 714: if( q > 1 ) ! 715: makeheap( p, q-1, 2*n ); ! 716: if( q < m ) ! 717: makeheap( p+q, m-q, 2*n+1 ); ! 718: } ! 719: ! 720: select( m ) ! 721: { ! 722: register int l, i, k; ! 723: ! 724: for( i=1; ; i*=2 ) ! 725: if( (i-1) > m ) break; ! 726: l = ((k = i/2 - 1) + 1)/2; ! 727: return( l + (m-k < l ? m-k : l) ); ! 728: } ! 729: ! 730: walkheap( start, limit ) ! 731: { ! 732: int label; ! 733: ! 734: if( start > limit ) ! 735: return; ! 736: #if defined(M32B) && defined(IMPSWREG) ! 737: fprintf( outfile, "\tcmpw\t%%r%d,&%ld\n\tje\t.L%d\n", ! 738: swregno, heapsw[start].sval, heapsw[start].slab ); ! 739: #else ! 740: fprintf( outfile, "\tcmpw\t%%r0,&%ld\n\tje\t.L%d\n", ! 741: heapsw[start].sval, heapsw[start].slab ); ! 742: #endif ! 743: if( (2*start) > limit ) ! 744: { ! 745: fprintf( outfile, " jmp .L%d\n", heapsw[0].slab ); ! 746: return; ! 747: } ! 748: if( (2*start+1) <= limit ) ! 749: { ! 750: label = getlab(); ! 751: fprintf( outfile, " jg .L%d\n", label ); ! 752: } ! 753: else ! 754: fprintf( outfile, " jg .L%d\n", heapsw[0].slab ); ! 755: walkheap( 2*start, limit ); ! 756: if( (2*start+1) <= limit ) ! 757: { ! 758: fprintf( outfile, ".L%d:\n", label ); ! 759: walkheap( 2*start+1, limit ); ! 760: } ! 761: } ! 762: ! 763: #ifdef M32B ! 764: NODE * ! 765: setswreg( p ) ! 766: NODE *p; ! 767: { ! 768: NODE *q; ! 769: ! 770: swregno = 0; ! 771: #ifdef IMPSWREG ! 772: if (p->in.op == ASSIGN && p->in.left->in.op == SNODE) ! 773: { ! 774: q = p->in.right; ! 775: if( q->in.op == REG ) ! 776: { ! 777: swregno = q->tn.rval; ! 778: p->in.op = FREE; ! 779: p->in.left->in.op = FREE; ! 780: p = q; ! 781: } ! 782: } ! 783: #endif ! 784: return( p ); ! 785: } ! 786: ! 787: NODE * ! 788: myand(p) ! 789: NODE *p; ! 790: { ! 791: #ifdef IMPREGAL ! 792: raua(p); ! 793: #endif ! 794: return(p); ! 795: } ! 796: #endif ! 797: ! 798: ! 799: ! 800: /* interface routines to debug output */ ! 801: ! 802: fixdef(p) ! 803: struct symtab * p; ! 804: { ! 805: fix1def(p,dsflag); /* pass along flag */ ! 806: return; ! 807: } ! 808: ! 809: strend(dimst) ! 810: int dimst; ! 811: { ! 812: str1end( dimst, dsflag ); /* pass along flag */ ! 813: return; ! 814: } ! 815: ! 816: sdbline() ! 817: { ! 818: sdbln1( dlflag ); /* pass along flag */ ! 819: return; ! 820: } ! 821: ! 822: aoend() ! 823: { ! 824: aoend1( dsflag ); /* pass along flag */ ! 825: return; ! 826: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.