|
|
1.1 ! root 1: # include "cpass1.h" ! 2: #ifndef lint ! 3: static char sccsid[] = "@(#)local.c 1.1 86/02/03 Copyr 1985 Sun Micro"; ! 4: #endif ! 5: ! 6: ! 7: /* ! 8: * Copyright (c) 1985 by Sun Microsystems, Inc. ! 9: */ ! 10: ! 11: ! 12: /* ! 13: * local.68 -- sym linked from local.c -- 68000 version ! 14: */ ! 15: ! 16: /* this file contains code which is dependent on the target machine */ ! 17: ! 18: NODE * ! 19: cast( p, t ) register NODE *p; TWORD t; ! 20: { ! 21: /* cast node p to type t */ ! 22: ! 23: p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p ); ! 24: p->in.left->in.op = FREE; ! 25: p->in.op = FREE; ! 26: return( p->in.right ); ! 27: } ! 28: ! 29: NODE * ! 30: clocal(p) NODE *p; ! 31: { ! 32: ! 33: /* this is called to do local transformations on ! 34: an expression tree preparitory to its being ! 35: written out in intermediate code. ! 36: */ ! 37: ! 38: /* the major essential job is rewriting the ! 39: automatic variables and arguments in terms of ! 40: REG and OREG nodes */ ! 41: /* conversion ops which are not necessary are also clobbered here */ ! 42: /* in addition, any special features (such as rewriting ! 43: exclusive or) are easily handled here as well */ ! 44: ! 45: register struct symtab *q; ! 46: register NODE *r; ! 47: register o; ! 48: register m, ml; ! 49: int fldsize, fldoff; ! 50: TWORD fldtype; ! 51: ! 52: switch( o = p->in.op ){ ! 53: ! 54: case NAME: ! 55: if( p->tn.rval<0 || p->tn.rval==NONAME ) { /* already processed; ignore... */ ! 56: return(p); ! 57: } ! 58: if (BTYPE(p->in.type) == TERROR) ! 59: return(p); ! 60: q = STP(p->tn.rval); ! 61: switch( q->sclass ){ ! 62: ! 63: case AUTO: ! 64: case PARAM: ! 65: /* fake up a structure reference */ ! 66: r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 ); ! 67: r->tn.lval = 0; ! 68: r->tn.rval = (q->sclass==AUTO?STKREG:ARGREG); ! 69: p = stref( block( STREF, r, p, 0, 0, 0 ) ); ! 70: break; ! 71: ! 72: case ULABEL: ! 73: case LABEL: ! 74: case STATIC: ! 75: if( q->slevel == 0 ) break; ! 76: p->tn.lval = 0; ! 77: p->tn.rval = -q->offset; ! 78: break; ! 79: ! 80: case REGISTER: ! 81: p->in.op = REG; ! 82: p->tn.lval = 0; ! 83: p->tn.rval = q->offset; ! 84: break; ! 85: ! 86: } ! 87: break; ! 88: ! 89: case PCONV: ! 90: /* do pointer conversions for char and short */ ! 91: ml = p->in.left->in.type; ! 92: if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ){ ! 93: p->in.op = SCONV; ! 94: break; ! 95: } ! 96: ! 97: /* pointers all have the same representation; the type is inherited */ ! 98: ! 99: inherit: ! 100: p->in.left->in.type = p->in.type; ! 101: p->in.left->fn.cdim = p->fn.cdim; ! 102: p->in.left->fn.csiz = p->fn.csiz; ! 103: p->in.op = FREE; ! 104: return( p->in.left ); ! 105: ! 106: case SCONV: ! 107: /* now, look for conversions downwards */ ! 108: ! 109: m = p->in.type; ! 110: ml = p->in.left->in.type; ! 111: if( p->in.left->in.op == ICON ){ ! 112: /* simulate the conversion here */ ! 113: CONSZ val; ! 114: if ((val=p->in.left->tn.rval) != NONAME ! 115: && dimtab[p->fn.csiz] < SZPOINT ){ ! 116: /* a relocatable icon is being shortened */ ! 117: /* DO NOT SHORTEN IT!! */ ! 118: werror("shortening &%s may loose significance", ! 119: val<=0?"(constant)":STP(val)->sname); ! 120: break; ! 121: } ! 122: shorten_int: ! 123: val = p->in.left->tn.lval; ! 124: switch( m ){ ! 125: case CHAR: ! 126: p->in.left->tn.lval = (char) val; ! 127: break; ! 128: case UCHAR: ! 129: p->in.left->tn.lval = val & 0XFF; ! 130: break; ! 131: case USHORT: ! 132: p->in.left->tn.lval = val & 0XFFFFL; ! 133: break; ! 134: case SHORT: ! 135: p->in.left->tn.lval = (short)val; ! 136: break; ! 137: case UNSIGNED: ! 138: p->in.left->tn.lval = val & 0xFFFFFFFFL; ! 139: break; ! 140: case INT: ! 141: p->in.left->tn.lval = (int)val; ! 142: break; ! 143: case DOUBLE: ! 144: case FLOAT: ! 145: p->in.left->fpn.dval = (double)val; ! 146: p->in.left->in.op = FCON; ! 147: break; ! 148: } ! 149: p->in.left->in.type = m; ! 150: } else if( p->in.left->in.op == FCON ){ ! 151: /* simulate the conversion here */ ! 152: if (m!=DOUBLE && m!=FLOAT){ ! 153: /* conversion to int-like things */ ! 154: /* convert to int first, then to actual thing */ ! 155: p->in.left->tn.lval = (CONSZ)p->in.left->fpn.dval; ! 156: p->in.left->tn.rval = NONAME; ! 157: p->in.left->tn.name = (char*)0; ! 158: p->in.left->tn.op = ICON; ! 159: p->in.left->tn.type = INT; ! 160: if (m != INT) ! 161: goto shorten_int; ! 162: } else ! 163: p->in.left->in.type = m; ! 164: } else { ! 165: m = (m ==FLOAT || m ==DOUBLE); ! 166: ml = (ml==FLOAT || ml==DOUBLE); ! 167: if (m != ml ) break; ! 168: else if( tlen(p) == tlen(p->in.left) ) ! 169: goto inherit; ! 170: else if (p->in.type != 0) ! 171: break; ! 172: /* fall through and clobber conversion to void */ ! 173: } ! 174: p->in.op = FREE; ! 175: return( p->in.left ); /* conversion gets clobbered */ ! 176: ! 177: case PVCONV: ! 178: case PMCONV: ! 179: if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0); ! 180: p->in.op = FREE; ! 181: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) ); ! 182: ! 183: case CALL: ! 184: case UNARY CALL: ! 185: if (p->in.type == FLOAT) ! 186: #ifdef FLOATMATH ! 187: if (FLOATMATH<=1) ! 188: #endif ! 189: p->in.type = DOUBLE; /* no such thing as a float fn */ ! 190: break; ! 191: ! 192: #ifdef FLOATMATH ! 193: case PLUS: ! 194: case MINUS: ! 195: case DIV: ! 196: case MUL: ! 197: case ASG PLUS: ! 198: case ASG MINUS: ! 199: case ASG DIV: ! 200: case ASG MUL: ! 201: if (!floatmath) break; ! 202: #endif FLOATMATH ! 203: case ASSIGN: ! 204: if (p->in.type == FLOAT && p->in.right->tn.op == FCON) ! 205: p->in.right->tn.type = p->in.right->fn.csiz = FLOAT; ! 206: break; ! 207: ! 208: case FORCE: ! 209: /* we do not FORCE little things. Ints or better only */ ! 210: switch ( p->in.type ){ ! 211: case CHAR: ! 212: case SHORT: ! 213: p->in.left = makety(p->in.left,INT,0,INT); ! 214: p->in.type = INT; ! 215: break; ! 216: case UCHAR: ! 217: case USHORT: ! 218: p->in.left = makety(p->in.left,UNSIGNED,0,UNSIGNED); ! 219: p->in.type = UNSIGNED; ! 220: break; ! 221: } ! 222: break; ! 223: ! 224: ! 225: } /* switch */ ! 226: ! 227: return(p); ! 228: } ! 229: ! 230: andable( p ) NODE *p; ! 231: { ! 232: return(1); /* all names can have & taken on them */ ! 233: } ! 234: ! 235: cendarg() ! 236: { /* at the end of the arguments of a ftn, set the automatic offset */ ! 237: autooff = AUTOINIT; ! 238: } ! 239: ! 240: cisreg( t ) ! 241: TWORD t; ! 242: { ! 243: /* is an automatic variable of type t OK for a register variable */ ! 244: switch (t) { ! 245: case DOUBLE: ! 246: return( use68881 ); ! 247: case FLOAT: ! 248: case INT: ! 249: case UNSIGNED: ! 250: case SHORT: ! 251: case USHORT: ! 252: case CHAR: ! 253: case UCHAR: ! 254: return(1); ! 255: default: ! 256: return( ISPTR(t) ); ! 257: } ! 258: } ! 259: ! 260: NODE * ! 261: offcon( off, t, d, s ) OFFSZ off; TWORD t; ! 262: { ! 263: ! 264: /* return a node, for structure references, which is suitable for ! 265: being added to a pointer of type t, in order to be off bits offset ! 266: into a structure */ ! 267: ! 268: register NODE *p; ! 269: ! 270: /* t, d, and s are the type, dimension offset, and sizeoffset */ ! 271: /* in general they are necessary for offcon, but not on H'well */ ! 272: ! 273: p = bcon(0); ! 274: p->tn.lval = off/SZCHAR; ! 275: return(p); ! 276: ! 277: } ! 278: ! 279: ! 280: static inwd; /* current bit offsed in word */ ! 281: static word; /* word being built from fields */ ! 282: ! 283: incode( p, sz ) register NODE *p; ! 284: { ! 285: ! 286: /* generate initialization code for assigning a constant c ! 287: to a field of width sz */ ! 288: /* we assume that the proper alignment has been obtained */ ! 289: /* inoff is updated to have the proper final value */ ! 290: /* we also assume sz < SZINT */ ! 291: ! 292: if((sz+inwd) > SZINT) cerror("incode: field > int"); ! 293: word |= (p->tn.lval & ((1 << sz) -1)) << (SZINT - sz - inwd); ! 294: inwd += sz; ! 295: inoff += sz; ! 296: while (inwd >= 16) { ! 297: printf( " .word %ld\n", (word>>16)&0xFFFFL ); ! 298: word <<= 16; ! 299: inwd -= 16; ! 300: } ! 301: } ! 302: ! 303: cinit( p, sz ) NODE *p; ! 304: { ! 305: /* arrange for the initialization of p into a space of ! 306: size sz */ ! 307: /* the proper alignment has been opbtained */ ! 308: /* inoff is updated to have the proper final value */ ! 309: /* ! 310: as a favor (?) to people who want to write ! 311: int i = 9600/134.5; ! 312: we will, under the proper circumstances, do ! 313: a coersion here. ! 314: */ ! 315: NODE *l; ! 316: ! 317: switch (p->in.type) { ! 318: case INT: ! 319: case UNSIGNED: ! 320: l = p->in.left; ! 321: if (l->in.op != SCONV || l->in.left->tn.op != FCON) break; ! 322: l->in.op = FREE; ! 323: l = l->in.left; ! 324: l->tn.lval = (long)(l->fpn.dval); ! 325: l->tn.rval = NONAME; ! 326: l->tn.op = ICON; ! 327: l->tn.type = INT; ! 328: p->in.left = l; ! 329: break; ! 330: } ! 331: ecode( p ); ! 332: inoff += sz; ! 333: } ! 334: ! 335: vfdzero( n ) ! 336: { /* define n bits of zeros in a vfd */ ! 337: ! 338: if( n <= 0 ) return; ! 339: ! 340: inwd += n; ! 341: inoff += n; ! 342: while (inwd >= 16) { ! 343: printf( " .word %ld\n", (word>>16)&0xFFFFL ); ! 344: word <<= 16; ! 345: inwd -= 16; ! 346: } ! 347: } ! 348: ! 349: char * ! 350: exname( p ) char *p; ! 351: { ! 352: /* make a name look like an external name in the local machine */ ! 353: ! 354: #ifndef FLEXNAMES ! 355: static char text[NCHNAM+1]; ! 356: #else ! 357: static char text[BUFSIZ+1]; ! 358: #endif ! 359: ! 360: register i; ! 361: ! 362: text[0] = '_'; ! 363: #ifndef FLEXNAMES ! 364: for( i=1; *p&&i<NCHNAM; ++i ){ ! 365: #else ! 366: for( i=1; *p; ++i ){ ! 367: #endif ! 368: text[i] = *p++; ! 369: } ! 370: ! 371: text[i] = '\0'; ! 372: #ifndef FLEXNAMES ! 373: text[NCHNAM] = '\0'; /* truncate */ ! 374: #endif ! 375: ! 376: return( text ); ! 377: } ! 378: ! 379: ctype( type ) ! 380: { /* map types which are not defined on the local machine */ ! 381: switch( BTYPE(type) ){ ! 382: ! 383: case LONG: ! 384: MODTYPE(type,INT); ! 385: break; ! 386: ! 387: case ULONG: ! 388: MODTYPE(type,UNSIGNED); ! 389: } ! 390: return( type ); ! 391: } ! 392: ! 393: noinit( t ) ! 394: { /* curid is a variable which is defined but ! 395: is not initialized (and not a function ); ! 396: This routine returns the stroage class for an uninitialized declaration */ ! 397: ! 398: return(EXTERN); ! 399: ! 400: } ! 401: ! 402: commdec( id ) ! 403: { /* make a common declaration for id, if reasonable */ ! 404: register struct symtab *q; ! 405: OFFSZ off, tsize(); ! 406: ! 407: q = STP(id); ! 408: printf( " .comm %s,", exname( q->sname ) ); ! 409: off = tsize( q->stype, q->dimoff, q->sizoff ); ! 410: printf( CONFMT, off/SZCHAR ); ! 411: printf( "\n" ); ! 412: } ! 413: ! 414: isitlong( cb, ce ) ! 415: { /* is lastcon to be long or short */ ! 416: /* cb is the first character of the representation, ce the last */ ! 417: ! 418: if( ce == 'l' || ce == 'L' || ! 419: lastcon >= (1L << (SZINT-1) ) ) return (1); ! 420: return(0); ! 421: } ! 422: ! 423: ! 424: isitfloat( s ) char *s; ! 425: { ! 426: double atof(); ! 427: dcon = atof(s); ! 428: return( FCON ); ! 429: } ! 430: ! 431: ecode( p ) NODE *p; { ! 432: ! 433: /* walk the tree and write out the nodes.. */ ! 434: ! 435: if( nerrors ) return; ! 436: p2tree( p ); ! 437: p2compile( p ); ! 438: } ! 439: ! 440: #ifndef ONEPASS ! 441: tlen(p) NODE *p; ! 442: { ! 443: switch(p->in.type) { ! 444: case CHAR: ! 445: case UCHAR: ! 446: return(1); ! 447: ! 448: case SHORT: ! 449: case USHORT: ! 450: return(2); ! 451: ! 452: case DOUBLE: ! 453: return(8); ! 454: ! 455: default: ! 456: return(4); ! 457: } ! 458: } ! 459: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.