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