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