|
|
1.1 ! root 1: # include "mfile1" ! 2: ! 3: /* this file contains code which is dependent on the target machine */ ! 4: ! 5: NODE * ! 6: clocal(p) NODE *p; { ! 7: ! 8: /* this is called to do local transformations on ! 9: an expression tree preparitory to its being ! 10: written out in intermediate code. ! 11: */ ! 12: ! 13: /* the major essential job is rewriting the ! 14: automatic variables and arguments in terms of ! 15: REG and OREG nodes */ ! 16: /* conversion ops which are not necessary are also clobbered here */ ! 17: /* in addition, any special features (such as rewriting ! 18: exclusive or) are easily handled here as well */ ! 19: ! 20: register struct symtab *q; ! 21: register NODE *r; ! 22: register o; ! 23: register m, ml; ! 24: ! 25: switch( o = p->in.op ){ ! 26: ! 27: case NAME: ! 28: if( p->tn.rval < 0 ) { /* already processed; ignore... */ ! 29: return(p); ! 30: } ! 31: q = &stab[p->tn.rval]; ! 32: switch( q->sclass ){ ! 33: ! 34: case AUTO: ! 35: case PARAM: ! 36: /* fake up a structure reference */ ! 37: r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 ); ! 38: r->tn.lval = 0; ! 39: r->tn.rval = STKREG; ! 40: p = stref( block( STREF, r, p, 0, 0, 0 ) ); ! 41: break; ! 42: ! 43: case ULABEL: ! 44: case LABEL: ! 45: case STATIC: ! 46: if( q->slevel == 0 ) break; ! 47: p->tn.lval = 0; ! 48: p->tn.rval = -q->offset; ! 49: break; ! 50: ! 51: case REGISTER: ! 52: p->in.op = REG; ! 53: p->tn.lval = 0; ! 54: p->tn.rval = q->offset; ! 55: #ifdef REG_CHAR ! 56: m = p->in.type; ! 57: if( m==CHAR || m==SHORT ) ! 58: p->in.type = INT; ! 59: else if( m==UCHAR || m==USHORT ) ! 60: p->in.type = UNSIGNED; ! 61: #endif ! 62: break; ! 63: ! 64: } ! 65: break; ! 66: ! 67: case LT: ! 68: case LE: ! 69: case GT: ! 70: case GE: ! 71: if( ISPTR( p->in.left->in.type ) || ISPTR( p->in.right->in.type ) ){ ! 72: p->in.op += (ULT-LT); ! 73: } ! 74: break; ! 75: ! 76: case PCONV: ! 77: /* do pointer conversions for char and longs */ ! 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 versions thereof */ ! 127: if( m==CHAR || m==UCHAR ){ ! 128: if( ml!=CHAR && ml!= UCHAR ) break; ! 129: } ! 130: else if( m==SHORT || m==USHORT ){ ! 131: if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) break; ! 132: } ! 133: } ! 134: ! 135: /* clobber conversion */ ! 136: if( tlen(p) == tlen(p->in.left) ) goto inherit; ! 137: p->in.op = FREE; ! 138: return( p->in.left ); /* conversion gets clobbered */ ! 139: ! 140: case PVCONV: ! 141: case PMCONV: ! 142: if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0); ! 143: p->in.op = FREE; ! 144: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) ); ! 145: ! 146: case FLD: ! 147: /* make sure that the second pass does not make the ! 148: descendant of a FLD operator into a doubly indexed OREG */ ! 149: ! 150: if( p->in.left->in.op == UNARY MUL ! 151: && (r=p->in.left->in.left)->in.op == PCONV) ! 152: if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS ) ! 153: if( ISPTR(r->in.type) ) { ! 154: if( ISUNSIGNED(p->in.left->in.type) ) ! 155: p->in.left->in.type = UNSIGNED; ! 156: else ! 157: p->in.left->in.type = INT; ! 158: } ! 159: break; ! 160: } ! 161: ! 162: return(p); ! 163: } ! 164: ! 165: andable( p ) NODE *p; { ! 166: return(1); /* all names can have & taken on them */ ! 167: } ! 168: ! 169: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */ ! 170: autooff = AUTOINIT; ! 171: } ! 172: ! 173: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */ ! 174: ! 175: if( t==INT || t==UNSIGNED || t==LONG || t==ULONG /* tbl */ ! 176: #ifdef REG_CHAR ! 177: || t==CHAR || t==UCHAR || t==SHORT || t==USHORT /* tbl */ ! 178: #endif ! 179: || ISPTR(t)) return (1); /* wnj */ ! 180: return(0); ! 181: } ! 182: ! 183: NODE * ! 184: offcon( off, t, d, s ) OFFSZ off; TWORD t; { ! 185: ! 186: /* return a node, for structure references, which is suitable for ! 187: being added to a pointer of type t, in order to be off bits offset ! 188: into a structure */ ! 189: ! 190: register NODE *p; ! 191: ! 192: /* t, d, and s are the type, dimension offset, and sizeoffset */ ! 193: /* in general they are necessary for offcon, but not on H'well */ ! 194: ! 195: p = bcon(0); ! 196: p->tn.lval = off/SZCHAR; ! 197: return(p); ! 198: ! 199: } ! 200: ! 201: ! 202: static inwd /* current bit offsed in word */; ! 203: static CONSZ word /* word being built from fields */; ! 204: ! 205: incode( p, sz ) register NODE *p; { ! 206: ! 207: /* generate initialization code for assigning a constant c ! 208: to a field of width sz */ ! 209: /* we assume that the proper alignment has been obtained */ ! 210: /* inoff is updated to have the proper final value */ ! 211: /* we also assume sz < SZINT */ ! 212: ! 213: inwd += sz; ! 214: if(inwd > SZINT) cerror("incode: field > int"); ! 215: word |= (p->tn.lval&((1L<<sz)-1)) << (SZINT-inwd); ! 216: inoff += sz; ! 217: if(inoff%SZINT == 0) { ! 218: printf( " .long 0x%08X\n", word); ! 219: word = inwd = 0; ! 220: } ! 221: } ! 222: ! 223: fincode( d, sz ) double d; register sz; { ! 224: /* output code to initialize space of size sz to the value d */ ! 225: /* the proper alignment has been obtained */ ! 226: /* inoff is updated to have the proper final value */ ! 227: /* this code should be the same for PDP, VAX and Tahoe */ ! 228: ! 229: register struct sh4 { ! 230: unsigned short sh[4]; ! 231: } *x; ! 232: # ifdef SFCON ! 233: register type; ! 234: # endif ! 235: ! 236: x = (struct sh4 *)&d; ! 237: printf(" .long 0x%04x%04x", x->sh[0], x->sh[1]); ! 238: # ifdef SFCON ! 239: if(sz==0) ! 240: if(x->sh[2]==0 && x->sh[3]==0) { ! 241: sz = SZFLOAT; ! 242: type = FLOAT; ! 243: } else { ! 244: sz = SZDOUBLE; ! 245: type = DOUBLE; ! 246: } ! 247: # endif ! 248: if(sz == SZDOUBLE) { ! 249: printf(", 0x%04x%04x", x->sh[2], x->sh[3]); ! 250: printf(" # .double"); ! 251: } else ! 252: printf(" # .float"); ! 253: printf(" %.20g\n", d); ! 254: inoff += sz; ! 255: # ifdef SFCON ! 256: return type; ! 257: # endif ! 258: } ! 259: ! 260: cinit( p, sz ) NODE *p; { ! 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 ){ /* define n bits of zeros in a vfd */ ! 270: ! 271: if( n <= 0 ) return; ! 272: ! 273: inwd += n; ! 274: inoff += n; ! 275: if( inoff%ALINT ==0 ) { ! 276: printf( " .long 0x%08X\n", word ); ! 277: word = inwd = 0; ! 278: } ! 279: } ! 280: ! 281: char * ! 282: exname( p ) char *p; { ! 283: /* make a name look like an external name in the local machine */ ! 284: ! 285: #ifndef FLEXNAMES ! 286: static char text[NCHNAM+1]; ! 287: #else ! 288: static char text[BUFSIZ+1]; ! 289: #endif ! 290: ! 291: register i; ! 292: ! 293: text[0] = '_'; ! 294: #ifndef FLEXNAMES ! 295: for( i=1; *p&&i<NCHNAM; ++i ){ ! 296: #else ! 297: for( i=1; *p; ++i ){ ! 298: #endif ! 299: text[i] = *p++; ! 300: } ! 301: ! 302: text[i] = '\0'; ! 303: #ifndef FLEXNAMES ! 304: text[NCHNAM] = '\0'; /* truncate */ ! 305: #endif ! 306: ! 307: return( text ); ! 308: } ! 309: ! 310: ctype( type )TWORD type;{ /* map types which are not defined on the local machine */ ! 311: switch( BTYPE(type) ){ ! 312: ! 313: case LONG: ! 314: MODTYPE(type,INT); ! 315: break; ! 316: ! 317: case ULONG: ! 318: MODTYPE(type,UNSIGNED); ! 319: } ! 320: return( type ); ! 321: } ! 322: ! 323: noinit() { /* curid is a variable which is defined but ! 324: is not initialized (and not a function ); ! 325: This routine returns the stroage class for an uninitialized declaration */ ! 326: ! 327: return(EXTERN); ! 328: ! 329: } ! 330: ! 331: commdec( id ){ /* make a common declaration for id, if reasonable */ ! 332: register struct symtab *q; ! 333: OFFSZ off, tsize(); ! 334: ! 335: q = &stab[id]; ! 336: printf( " .comm %s,", exname( q->sname ) ); ! 337: off = tsize( q->stype, q->dimoff, q->sizoff ); ! 338: printf( "%d" /*CONFMT*/, off/SZCHAR ); ! 339: printf( "\n" ); ! 340: } ! 341: ! 342: ! 343: isitfloat( s ) char *s; { ! 344: double atof(); ! 345: dcon = atof(s); ! 346: return( FCON ); ! 347: } ! 348: ! 349: ecode( p ) NODE *p; { ! 350: ! 351: /* walk the tree and write out the nodes.. */ ! 352: ! 353: if( nerrors ) return; ! 354: p2tree( p ); ! 355: p2compile( p ); ! 356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.