|
|
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 octal! */ ! 237: ! 238: ! 239: printf(" %s 0%c%.20e\n", sz == SZDOUBLE ? ".double" : ".float", ! 240: sz == SZDOUBLE ? 'd' : 'f', d); ! 241: inoff += sz; ! 242: } ! 243: ! 244: cinit( p, sz ) NODE *p; { ! 245: /* arrange for the initialization of p into a space of ! 246: size sz */ ! 247: /* the proper alignment has been opbtained */ ! 248: /* inoff is updated to have the proper final value */ ! 249: ecode( p ); ! 250: inoff += sz; ! 251: } ! 252: ! 253: vfdzero( n ){ /* define n bits of zeros in a vfd */ ! 254: ! 255: if( n <= 0 ) return; ! 256: ! 257: inwd += n; ! 258: inoff += n; ! 259: if( inoff%ALINT ==0 ) { ! 260: printf( " .long 0x%x\n", word ); ! 261: word = inwd = 0; ! 262: } ! 263: } ! 264: ! 265: char * ! 266: exname( p ) char *p; { ! 267: /* make a name look like an external name in the local machine */ ! 268: ! 269: #ifndef FLEXNAMES ! 270: static char text[NCHNAM+1]; ! 271: #else ! 272: static char text[BUFSIZ+1]; ! 273: #endif ! 274: ! 275: register i; ! 276: ! 277: text[0] = '_'; ! 278: #ifndef FLEXNAMES ! 279: for( i=1; *p&&i<NCHNAM; ++i ){ ! 280: #else ! 281: for( i=1; *p; ++i ){ ! 282: #endif ! 283: text[i] = *p++; ! 284: } ! 285: ! 286: text[i] = '\0'; ! 287: #ifndef FLEXNAMES ! 288: text[NCHNAM] = '\0'; /* truncate */ ! 289: #endif ! 290: ! 291: return( text ); ! 292: } ! 293: ! 294: ctype( type ){ /* map types which are not defined on the local machine */ ! 295: switch( BTYPE(type) ){ ! 296: ! 297: case LONG: ! 298: MODTYPE(type,INT); ! 299: break; ! 300: ! 301: case ULONG: ! 302: MODTYPE(type,UNSIGNED); ! 303: } ! 304: return( type ); ! 305: } ! 306: ! 307: noinit( t ) { /* curid is a variable which is defined but ! 308: is not initialized (and not a function ); ! 309: This routine returns the stroage class for an uninitialized declaration */ ! 310: ! 311: return(EXTERN); ! 312: ! 313: } ! 314: ! 315: commdec( id ){ /* make a common declaration for id, if reasonable */ ! 316: register struct symtab *q; ! 317: OFFSZ off, tsize(); ! 318: ! 319: q = &stab[id]; ! 320: printf( " .comm %s,", exname( q->sname ) ); ! 321: off = tsize( q->stype, q->dimoff, q->sizoff ); ! 322: printf( CONFMT, off/SZCHAR ); ! 323: printf( "\n" ); ! 324: } ! 325: ! 326: isitlong( cb, ce ){ /* is lastcon to be long or short */ ! 327: /* cb is the first character of the representation, ce the last */ ! 328: ! 329: if( ce == 'l' || ce == 'L' || ! 330: lastcon >= (1L << (SZINT-1) ) ) return (1); ! 331: return(0); ! 332: } ! 333: ! 334: ! 335: isitfloat( s ) char *s; { ! 336: double atof(); ! 337: dcon = atof(s); ! 338: return( FCON ); ! 339: } ! 340: ! 341: ecode( p ) NODE *p; { ! 342: ! 343: /* walk the tree and write out the nodes.. */ ! 344: ! 345: if( nerrors ) return; ! 346: p2tree( p ); ! 347: p2compile( p ); ! 348: } ! 349: ! 350: #include <sys/types.h> ! 351: #include <a.out.h> ! 352: #include <stab.h> ! 353: extern int ddebug; ! 354: extern int gdebug; ! 355: ! 356: fixarg(p) ! 357: struct symtab *p; { ! 358: pstab(p->sname, N_PSYM); ! 359: if (gdebug) printf("0,%d,%d\n", p->stype, argoff/SZCHAR); ! 360: poffs(p); ! 361: } ! 362: int stabLCSYM; ! 363: ! 364: outstab(p) ! 365: struct symtab *p; { ! 366: register TWORD ptype; ! 367: register char *pname; ! 368: register char pclass; ! 369: register int poffset; ! 370: ! 371: if (!gdebug) return; ! 372: ! 373: ptype = p->stype; ! 374: pname = p->sname; ! 375: pclass = p->sclass; ! 376: poffset = p->offset; ! 377: ! 378: if (ISFTN(ptype)) { ! 379: return; ! 380: } ! 381: ! 382: switch (pclass) { ! 383: ! 384: case AUTO: ! 385: pstab(pname, N_LSYM); ! 386: printf("0,%d,%d\n", ptype, (-poffset)/SZCHAR); ! 387: poffs(p); ! 388: return; ! 389: ! 390: case EXTDEF: ! 391: case EXTERN: ! 392: pstab(pname, N_GSYM); ! 393: printf("0,%d,0\n", ptype); ! 394: poffs(p); ! 395: return; ! 396: ! 397: case STATIC: ! 398: #ifdef LCOMM ! 399: /* stabLCSYM is 1 during nidcl so we can get stab type right */ ! 400: pstab(pname, stabLCSYM ? N_LCSYM : N_STSYM); ! 401: #else ! 402: pstab(pname, N_STSYM); ! 403: #endif ! 404: if (p->slevel > 1) { ! 405: printf("0,%d,L%d\n", ptype, poffset); ! 406: } else { ! 407: printf("0,%d,%s\n", ptype, exname(pname)); ! 408: } ! 409: poffs(p); ! 410: return; ! 411: ! 412: case REGISTER: ! 413: pstab(pname, N_RSYM); ! 414: printf("0,%d,%d\n", ptype, poffset); ! 415: poffs(p); ! 416: return; ! 417: ! 418: case MOS: ! 419: case MOU: ! 420: pstab(pname, N_SSYM); ! 421: printf("0,%d,%d\n", ptype, poffset/SZCHAR); ! 422: poffs(p); ! 423: return; ! 424: ! 425: case PARAM: ! 426: /* parameter stab entries are processed in dclargs() */ ! 427: return; ! 428: ! 429: default: ! 430: #ifndef FLEXNAMES ! 431: if (ddebug) printf(" No .stab for %.8s\n", pname); ! 432: #else ! 433: if (ddebug) printf(" No .stab for %s\n", pname); ! 434: #endif ! 435: ! 436: } ! 437: } ! 438: ! 439: pstab(name, type) ! 440: char *name; ! 441: int type; { ! 442: register int i; ! 443: register char c; ! 444: if (!gdebug) return; ! 445: /* locctr(PROG); /* .stabs must appear in .text for c2 */ ! 446: #ifdef ASSTRINGS ! 447: if ( name[0] == '\0') ! 448: printf("\t.stabn\t"); ! 449: else ! 450: #ifndef FLEXNAMES ! 451: printf("\t.stabs\t\"%.8s\", ", name); ! 452: #else ! 453: printf("\t.stabs\t\"%s\", ", name); ! 454: #endif ! 455: #else ! 456: printf(" .stab "); ! 457: for(i=0; i<8; i++) ! 458: if (c = name[i]) printf("'%c,", c); ! 459: else printf("0,"); ! 460: #endif ! 461: printf("0%o,", type); ! 462: } ! 463: ! 464: #ifdef STABDOT ! 465: pstabdot(type, value) ! 466: int type; ! 467: int value; ! 468: { ! 469: if ( ! gdebug) return; ! 470: /* locctr(PROG); /* .stabs must appear in .text for c2 */ ! 471: printf("\t.stabd\t"); ! 472: printf("0%o,0,0%o\n",type, value); ! 473: } ! 474: #endif ! 475: ! 476: poffs(p) ! 477: register struct symtab *p; { ! 478: int s; ! 479: if (!gdebug) return; ! 480: if ((s = dimtab[p->sizoff]/SZCHAR) > 1) { ! 481: pstab(p->sname, N_LENG); ! 482: printf("1,0,%d\n", s); ! 483: } ! 484: } ! 485: ! 486: extern char NULLNAME[8]; ! 487: extern int labelno; ! 488: extern int fdefflag; ! 489: ! 490: psline() { ! 491: static int lastlineno; ! 492: register char *cp, *cq; ! 493: register int i; ! 494: ! 495: if (!gdebug) return; ! 496: ! 497: cq = ititle; ! 498: cp = ftitle; ! 499: ! 500: while ( *cq ) if ( *cp++ != *cq++ ) goto neq; ! 501: if ( *cp == '\0' ) goto eq; ! 502: ! 503: neq: for (i=0; i<100; i++) ! 504: ititle[i] = '\0'; ! 505: cp = ftitle; ! 506: cq = ititle; ! 507: while ( *cp ) ! 508: *cq++ = *cp++; ! 509: *cq = '\0'; ! 510: *--cq = '\0'; ! 511: #ifndef FLEXNAMES ! 512: for ( cp = ititle+1; *(cp-1); cp += 8 ) { ! 513: pstab(cp, N_SOL); ! 514: if (gdebug) printf("0,0,LL%d\n", labelno); ! 515: } ! 516: #else ! 517: pstab(ititle+1, N_SOL); ! 518: if (gdebug) printf("0,0,LL%d\n", labelno); ! 519: #endif ! 520: *cq = '"'; ! 521: printf("LL%d:\n", labelno++); ! 522: ! 523: eq: if (lineno == lastlineno) return; ! 524: lastlineno = lineno; ! 525: ! 526: if (fdefflag) { ! 527: #ifdef STABDOT ! 528: pstabdot(N_SLINE, lineno); ! 529: #else ! 530: pstab(NULLNAME, N_SLINE); ! 531: printf("0,%d,LL%d\n", lineno, labelno); ! 532: printf("LL%d:\n", labelno++); ! 533: #endif ! 534: } ! 535: } ! 536: ! 537: plcstab(level) { ! 538: if (!gdebug) return; ! 539: #ifdef STABDOT ! 540: pstabdot(N_LBRAC, level); ! 541: #else ! 542: pstab(NULLNAME, N_LBRAC); ! 543: printf("0,%d,LL%d\n", level, labelno); ! 544: printf("LL%d:\n", labelno++); ! 545: #endif ! 546: } ! 547: ! 548: prcstab(level) { ! 549: if (!gdebug) return; ! 550: #ifdef STABDOT ! 551: pstabdot(N_RBRAC, level); ! 552: #else ! 553: pstab(NULLNAME, N_RBRAC); ! 554: printf("0,%d,LL%d\n", level, labelno); ! 555: printf("LL%d:\n", labelno++); ! 556: #endif ! 557: } ! 558: ! 559: pfstab(sname) ! 560: char *sname; { ! 561: if (!gdebug) return; ! 562: pstab(sname, N_FUN); ! 563: #ifndef FLEXNAMES ! 564: printf("0,%d,_%.7s\n", lineno, sname); ! 565: #else ! 566: printf("0,%d,_%s\n", lineno, sname); ! 567: #endif ! 568: } ! 569: ! 570: #ifndef ONEPASS ! 571: tlen(p) NODE *p; ! 572: { ! 573: switch(p->in.type) { ! 574: case CHAR: ! 575: case UCHAR: ! 576: return(1); ! 577: ! 578: case SHORT: ! 579: case USHORT: ! 580: return(2); ! 581: ! 582: case DOUBLE: ! 583: return(8); ! 584: ! 585: default: ! 586: return(4); ! 587: } ! 588: } ! 589: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.