|
|
1.1 ! root 1: static char *sccsid ="%W% (Berkeley) %G%"; ! 2: # include "mfile1" ! 3: ! 4: /* this file contains code which is dependent on the target machine */ ! 5: ! 6: NODE * ! 7: cast( p, t ) register NODE *p; TWORD t; { ! 8: /* cast node p to type t */ ! 9: ! 10: p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p ); ! 11: p->in.left->in.op = FREE; ! 12: p->in.op = FREE; ! 13: return( p->in.right ); ! 14: } ! 15: ! 16: NODE * ! 17: clocal(p) NODE *p; { ! 18: ! 19: /* this is called to do local transformations on ! 20: an expression tree preparitory to its being ! 21: written out in intermediate code. ! 22: */ ! 23: ! 24: /* the major essential job is rewriting the ! 25: automatic variables and arguments in terms of ! 26: REG and OREG nodes */ ! 27: /* conversion ops which are not necessary are also clobbered here */ ! 28: /* in addition, any special features (such as rewriting ! 29: exclusive or) are easily handled here as well */ ! 30: ! 31: register struct symtab *q; ! 32: register NODE *r; ! 33: register o; ! 34: register m, ml; ! 35: ! 36: switch( o = p->in.op ){ ! 37: ! 38: case NAME: ! 39: if( p->tn.rval < 0 ) { /* already processed; ignore... */ ! 40: return(p); ! 41: } ! 42: q = &stab[p->tn.rval]; ! 43: switch( q->sclass ){ ! 44: ! 45: case AUTO: ! 46: case PARAM: ! 47: /* fake up a structure reference */ ! 48: r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 ); ! 49: r->tn.lval = 0; ! 50: r->tn.rval = (q->sclass==AUTO?STKREG:ARGREG); ! 51: p = stref( block( STREF, r, p, 0, 0, 0 ) ); ! 52: break; ! 53: ! 54: case ULABEL: ! 55: case LABEL: ! 56: case STATIC: ! 57: if( q->slevel == 0 ) break; ! 58: p->tn.lval = 0; ! 59: p->tn.rval = -q->offset; ! 60: break; ! 61: ! 62: case REGISTER: ! 63: p->in.op = REG; ! 64: p->tn.lval = 0; ! 65: p->tn.rval = q->offset; ! 66: break; ! 67: ! 68: } ! 69: break; ! 70: ! 71: case PCONV: ! 72: /* do pointer conversions for char and longs */ ! 73: ml = p->in.left->in.type; ! 74: if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ) break; ! 75: ! 76: /* pointers all have the same representation; the type is inherited */ ! 77: ! 78: inherit: ! 79: p->in.left->in.type = p->in.type; ! 80: p->in.left->fn.cdim = p->fn.cdim; ! 81: p->in.left->fn.csiz = p->fn.csiz; ! 82: p->in.op = FREE; ! 83: return( p->in.left ); ! 84: ! 85: case SCONV: ! 86: m = (p->in.type == FLOAT || p->in.type == DOUBLE ); ! 87: ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE ); ! 88: if( m != ml ) break; ! 89: ! 90: /* now, look for conversions downwards */ ! 91: ! 92: m = p->in.type; ! 93: ml = p->in.left->in.type; ! 94: if( p->in.left->in.op == ICON ){ /* simulate the conversion here */ ! 95: CONSZ val; ! 96: val = p->in.left->tn.lval; ! 97: switch( m ){ ! 98: case CHAR: ! 99: p->in.left->tn.lval = (char) val; ! 100: break; ! 101: case UCHAR: ! 102: p->in.left->tn.lval = val & 0XFF; ! 103: break; ! 104: case USHORT: ! 105: p->in.left->tn.lval = val & 0XFFFFL; ! 106: break; ! 107: case SHORT: ! 108: p->in.left->tn.lval = (short)val; ! 109: break; ! 110: case UNSIGNED: ! 111: p->in.left->tn.lval = val & 0xFFFFFFFFL; ! 112: break; ! 113: case INT: ! 114: p->in.left->tn.lval = (int)val; ! 115: break; ! 116: } ! 117: p->in.left->in.type = m; ! 118: } ! 119: else { ! 120: /* meaningful ones are conversion of int to char, int to short, ! 121: and short to char, and unsigned version of them */ ! 122: if( m==CHAR || m==UCHAR ){ ! 123: if( ml!=CHAR && ml!= UCHAR ) break; ! 124: } ! 125: else if( m==SHORT || m==USHORT ){ ! 126: if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) break; ! 127: } ! 128: } ! 129: ! 130: /* clobber conversion */ ! 131: if( tlen(p) == tlen(p->in.left) ) goto inherit; ! 132: p->in.op = FREE; ! 133: return( p->in.left ); /* conversion gets clobbered */ ! 134: ! 135: case PVCONV: ! 136: case PMCONV: ! 137: if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0); ! 138: p->in.op = FREE; ! 139: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) ); ! 140: ! 141: case RS: ! 142: case ASG RS: ! 143: /* convert >> to << with negative shift count */ ! 144: /* only if type of left operand is not unsigned */ ! 145: ! 146: if( ISUNSIGNED(p->in.left->in.type) ) break; ! 147: p->in.right = buildtree( UNARY MINUS, p->in.right, NIL ); ! 148: if( p->in.op == RS ) p->in.op = LS; ! 149: else p->in.op = ASG LS; ! 150: break; ! 151: ! 152: case FLD: ! 153: /* make sure that the second pass does not make the ! 154: descendant of a FLD operator into a doubly indexed OREG */ ! 155: ! 156: if( p->in.left->in.op == UNARY MUL ! 157: && (r=p->in.left->in.left)->in.op == PCONV) ! 158: if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS ) ! 159: if( ISPTR(r->in.type) ) { ! 160: if( ISUNSIGNED(p->in.left->in.type) ) ! 161: p->in.left->in.type = UCHAR; ! 162: else ! 163: p->in.left->in.type = CHAR; ! 164: } ! 165: break; ! 166: } ! 167: ! 168: return(p); ! 169: } ! 170: ! 171: andable( p ) NODE *p; { ! 172: return(1); /* all names can have & taken on them */ ! 173: } ! 174: ! 175: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */ ! 176: autooff = AUTOINIT; ! 177: } ! 178: ! 179: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */ ! 180: ! 181: #ifdef TRUST_REG_CHAR_AND_REG_SHORT ! 182: if( t==INT || t==UNSIGNED || t==LONG || t==ULONG /* tbl */ ! 183: || t==CHAR || t==UCHAR || t==SHORT /* tbl */ ! 184: || t==USHORT || ISPTR(t)) return(1); /* tbl */ ! 185: #else ! 186: if( t==INT || t==UNSIGNED || t==LONG || t==ULONG /* wnj */ ! 187: || ISPTR(t)) return (1); /* wnj */ ! 188: #endif ! 189: return(0); ! 190: } ! 191: ! 192: NODE * ! 193: offcon( off, t, d, s ) OFFSZ off; TWORD t; { ! 194: ! 195: /* return a node, for structure references, which is suitable for ! 196: being added to a pointer of type t, in order to be off bits offset ! 197: into a structure */ ! 198: ! 199: register NODE *p; ! 200: ! 201: /* t, d, and s are the type, dimension offset, and sizeoffset */ ! 202: /* in general they are necessary for offcon, but not on H'well */ ! 203: ! 204: p = bcon(0); ! 205: p->tn.lval = off/SZCHAR; ! 206: return(p); ! 207: ! 208: } ! 209: ! 210: ! 211: static inwd /* current bit offsed in word */; ! 212: static word /* word being built from fields */; ! 213: ! 214: incode( p, sz ) register NODE *p; { ! 215: ! 216: /* generate initialization code for assigning a constant c ! 217: to a field of width sz */ ! 218: /* we assume that the proper alignment has been obtained */ ! 219: /* inoff is updated to have the proper final value */ ! 220: /* we also assume sz < SZINT */ ! 221: ! 222: if((sz+inwd) > SZINT) cerror("incode: field > int"); ! 223: word |= ((unsigned)(p->tn.lval<<(32-sz))) >> (32-sz-inwd); ! 224: inwd += sz; ! 225: inoff += sz; ! 226: if(inoff%SZINT == 0) { ! 227: printf( " .long 0x%x\n", word); ! 228: word = inwd = 0; ! 229: } ! 230: } ! 231: ! 232: fincode( d, sz ) double d; { ! 233: /* output code to initialize space of size sz to the value d */ ! 234: /* the proper alignment has been obtained */ ! 235: /* inoff is updated to have the proper final value */ ! 236: /* on the target machine, write it out in hex! (ark) */ ! 237: ! 238: ! 239: #ifdef vax ! 240: if (sz == SZDOUBLE) ! 241: printf (" .long 0x%lx,0x%lx\n", d); ! 242: else ! 243: printf (" .long 0x%lx\n", d); ! 244: #else ! 245: printf(" %s 0%c%.20e\n", sz == SZDOUBLE ? ".double" : ".float", ! 246: sz == SZDOUBLE ? 'd' : 'f', d); ! 247: #endif ! 248: inoff += sz; ! 249: } ! 250: ! 251: cinit( p, sz ) NODE *p; { ! 252: /* arrange for the initialization of p into a space of ! 253: size sz */ ! 254: /* the proper alignment has been opbtained */ ! 255: /* inoff is updated to have the proper final value */ ! 256: ecode( p ); ! 257: inoff += sz; ! 258: } ! 259: ! 260: vfdzero( n ){ /* define n bits of zeros in a vfd */ ! 261: ! 262: if( n <= 0 ) return; ! 263: ! 264: inwd += n; ! 265: inoff += n; ! 266: if( inoff%ALINT ==0 ) { ! 267: printf( " .long 0x%x\n", word ); ! 268: word = inwd = 0; ! 269: } ! 270: } ! 271: ! 272: char * ! 273: exname( p ) char *p; { ! 274: /* make a name look like an external name in the local machine */ ! 275: ! 276: #ifndef FLEXNAMES ! 277: static char text[NCHNAM+1]; ! 278: #else ! 279: static char text[BUFSIZ+1]; ! 280: #endif ! 281: ! 282: register i; ! 283: ! 284: text[0] = '_'; ! 285: #ifndef FLEXNAMES ! 286: for( i=1; *p&&i<NCHNAM; ++i ){ ! 287: #else ! 288: for( i=1; *p; ++i ){ ! 289: #endif ! 290: text[i] = *p++; ! 291: } ! 292: ! 293: text[i] = '\0'; ! 294: #ifndef FLEXNAMES ! 295: text[NCHNAM] = '\0'; /* truncate */ ! 296: #endif ! 297: ! 298: return( text ); ! 299: } ! 300: ! 301: ctype( type ){ /* map types which are not defined on the local machine */ ! 302: switch( BTYPE(type) ){ ! 303: ! 304: case LONG: ! 305: MODTYPE(type,INT); ! 306: break; ! 307: ! 308: case ULONG: ! 309: MODTYPE(type,UNSIGNED); ! 310: } ! 311: return( type ); ! 312: } ! 313: ! 314: noinit( t ) { /* curid is a variable which is defined but ! 315: is not initialized (and not a function ); ! 316: This routine returns the stroage class for an uninitialized declaration */ ! 317: ! 318: return(EXTERN); ! 319: ! 320: } ! 321: ! 322: commdec( id ){ /* make a common declaration for id, if reasonable */ ! 323: register struct symtab *q; ! 324: OFFSZ off, tsize(); ! 325: ! 326: q = &stab[id]; ! 327: printf( " .comm %s,", exname( q->sname ) ); ! 328: off = tsize( q->stype, q->dimoff, q->sizoff ); ! 329: printf( CONFMT, off/SZCHAR ); ! 330: printf( "\n" ); ! 331: } ! 332: ! 333: isitlong( cb, ce ){ /* is lastcon to be long or short */ ! 334: /* cb is the first character of the representation, ce the last */ ! 335: ! 336: if( ce == 'l' || ce == 'L' || ! 337: lastcon >= (1L << (SZINT-1) ) ) return (1); ! 338: return(0); ! 339: } ! 340: ! 341: ! 342: isitfloat( s ) char *s; { ! 343: double atof(); ! 344: dcon = atof(s); ! 345: return( FCON ); ! 346: } ! 347: ! 348: ecode( p ) NODE *p; { ! 349: ! 350: /* walk the tree and write out the nodes.. */ ! 351: ! 352: if( nerrors ) return; ! 353: p2tree( p ); ! 354: p2compile( p ); ! 355: } ! 356: ! 357: #include <sys/types.h> ! 358: #include <a.out.h> ! 359: #include <stab.h> ! 360: extern int ddebug; ! 361: extern int gdebug; ! 362: ! 363: fixarg(p) ! 364: struct symtab *p; { ! 365: pstab(p->sname, N_PSYM); ! 366: if (gdebug) printf("0,%d,%d\n", p->stype, argoff/SZCHAR); ! 367: poffs(p); ! 368: } ! 369: int stabLCSYM; ! 370: ! 371: outstab(p) ! 372: struct symtab *p; { ! 373: register TWORD ptype; ! 374: register char *pname; ! 375: register char pclass; ! 376: register int poffset; ! 377: ! 378: if (!gdebug) return; ! 379: ! 380: ptype = p->stype; ! 381: pname = p->sname; ! 382: pclass = p->sclass; ! 383: poffset = p->offset; ! 384: ! 385: if (ISFTN(ptype)) { ! 386: return; ! 387: } ! 388: ! 389: switch (pclass) { ! 390: ! 391: case AUTO: ! 392: pstab(pname, N_LSYM); ! 393: printf("0,%d,%d\n", ptype, (-poffset)/SZCHAR); ! 394: poffs(p); ! 395: return; ! 396: ! 397: case EXTDEF: ! 398: case EXTERN: ! 399: pstab(pname, N_GSYM); ! 400: printf("0,%d,0\n", ptype); ! 401: poffs(p); ! 402: return; ! 403: ! 404: case STATIC: ! 405: #ifdef LCOMM ! 406: /* stabLCSYM is 1 during nidcl so we can get stab type right */ ! 407: pstab(pname, stabLCSYM ? N_LCSYM : N_STSYM); ! 408: #else ! 409: pstab(pname, N_STSYM); ! 410: #endif ! 411: if (p->slevel > 1) { ! 412: printf("0,%d,L%d\n", ptype, poffset); ! 413: } else { ! 414: printf("0,%d,%s\n", ptype, exname(pname)); ! 415: } ! 416: poffs(p); ! 417: return; ! 418: ! 419: case REGISTER: ! 420: pstab(pname, N_RSYM); ! 421: printf("0,%d,%d\n", ptype, poffset); ! 422: poffs(p); ! 423: return; ! 424: ! 425: case MOS: ! 426: case MOU: ! 427: pstab(pname, N_SSYM); ! 428: printf("0,%d,%d\n", ptype, poffset/SZCHAR); ! 429: poffs(p); ! 430: return; ! 431: ! 432: case PARAM: ! 433: /* parameter stab entries are processed in dclargs() */ ! 434: return; ! 435: ! 436: default: ! 437: #ifndef FLEXNAMES ! 438: if (ddebug) printf(" No .stab for %.8s\n", pname); ! 439: #else ! 440: if (ddebug) printf(" No .stab for %s\n", pname); ! 441: #endif ! 442: ! 443: } ! 444: } ! 445: ! 446: pstab(name, type) ! 447: char *name; ! 448: int type; { ! 449: register int i; ! 450: register char c; ! 451: if (!gdebug) return; ! 452: /* locctr(PROG); /* .stabs must appear in .text for c2 */ ! 453: #ifdef ASSTRINGS ! 454: if ( name[0] == '\0') ! 455: printf("\t.stabn\t"); ! 456: else ! 457: #ifndef FLEXNAMES ! 458: printf("\t.stabs\t\"%.8s\", ", name); ! 459: #else ! 460: printf("\t.stabs\t\"%s\", ", name); ! 461: #endif ! 462: #else ! 463: printf(" .stab "); ! 464: for(i=0; i<8; i++) ! 465: if (c = name[i]) printf("'%c,", c); ! 466: else printf("0,"); ! 467: #endif ! 468: printf("0%o,", type); ! 469: } ! 470: ! 471: #ifdef STABDOT ! 472: pstabdot(type, value) ! 473: int type; ! 474: int value; ! 475: { ! 476: if ( ! gdebug) return; ! 477: /* locctr(PROG); /* .stabs must appear in .text for c2 */ ! 478: printf("\t.stabd\t"); ! 479: printf("0%o,0,0%o\n",type, value); ! 480: } ! 481: #endif ! 482: ! 483: poffs(p) ! 484: register struct symtab *p; { ! 485: int s; ! 486: if (!gdebug) return; ! 487: if ((s = dimtab[p->sizoff]/SZCHAR) > 1) { ! 488: pstab(p->sname, N_LENG); ! 489: printf("1,0,%d\n", s); ! 490: } ! 491: } ! 492: ! 493: extern char NULLNAME[8]; ! 494: extern int labelno; ! 495: extern int fdefflag; ! 496: ! 497: psline() { ! 498: static int lastlineno; ! 499: register char *cp, *cq; ! 500: register int i; ! 501: ! 502: if (!gdebug) return; ! 503: ! 504: cq = ititle; ! 505: cp = ftitle; ! 506: ! 507: while ( *cq ) if ( *cp++ != *cq++ ) goto neq; ! 508: if ( *cp == '\0' ) goto eq; ! 509: ! 510: neq: for (i=0; i<100; i++) ! 511: ititle[i] = '\0'; ! 512: cp = ftitle; ! 513: cq = ititle; ! 514: while ( *cp ) ! 515: *cq++ = *cp++; ! 516: *cq = '\0'; ! 517: *--cq = '\0'; ! 518: #ifndef FLEXNAMES ! 519: for ( cp = ititle+1; *(cp-1); cp += 8 ) { ! 520: pstab(cp, N_SOL); ! 521: if (gdebug) printf("0,0,LL%d\n", labelno); ! 522: } ! 523: #else ! 524: pstab(ititle+1, N_SOL); ! 525: if (gdebug) printf("0,0,LL%d\n", labelno); ! 526: #endif ! 527: *cq = '"'; ! 528: printf("LL%d:\n", labelno++); ! 529: ! 530: eq: if (lineno == lastlineno) return; ! 531: lastlineno = lineno; ! 532: ! 533: if (fdefflag) { ! 534: #ifdef STABDOT ! 535: pstabdot(N_SLINE, lineno); ! 536: #else ! 537: pstab(NULLNAME, N_SLINE); ! 538: printf("0,%d,LL%d\n", lineno, labelno); ! 539: printf("LL%d:\n", labelno++); ! 540: #endif ! 541: } ! 542: } ! 543: ! 544: plcstab(level) { ! 545: if (!gdebug) return; ! 546: #ifdef STABDOT ! 547: pstabdot(N_LBRAC, level); ! 548: #else ! 549: pstab(NULLNAME, N_LBRAC); ! 550: printf("0,%d,LL%d\n", level, labelno); ! 551: printf("LL%d:\n", labelno++); ! 552: #endif ! 553: } ! 554: ! 555: prcstab(level) { ! 556: if (!gdebug) return; ! 557: #ifdef STABDOT ! 558: pstabdot(N_RBRAC, level); ! 559: #else ! 560: pstab(NULLNAME, N_RBRAC); ! 561: printf("0,%d,LL%d\n", level, labelno); ! 562: printf("LL%d:\n", labelno++); ! 563: #endif ! 564: } ! 565: ! 566: pfstab(sname) ! 567: char *sname; { ! 568: if (!gdebug) return; ! 569: pstab(sname, N_FUN); ! 570: #ifndef FLEXNAMES ! 571: printf("0,%d,_%.7s\n", lineno, sname); ! 572: #else ! 573: printf("0,%d,_%s\n", lineno, sname); ! 574: #endif ! 575: } ! 576: ! 577: #ifndef ONEPASS ! 578: tlen(p) NODE *p; ! 579: { ! 580: switch(p->in.type) { ! 581: case CHAR: ! 582: case UCHAR: ! 583: return(1); ! 584: ! 585: case SHORT: ! 586: case USHORT: ! 587: return(2); ! 588: ! 589: case DOUBLE: ! 590: return(8); ! 591: ! 592: default: ! 593: return(4); ! 594: } ! 595: } ! 596: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.