1: # include "mfile1" 2: 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: case LT: 71: case LE: 72: case GT: 73: case GE: 74: if( ISPTR( p->left->type ) || ISPTR( p->right->type ) ){ 75: p->op += (ULT-LT); 76: } 77: break; 78: 79: case PCONV: 80: /* do pointer conversions for char and longs */ 81: ml = p->left->type; 82: if( ( ml==CHAR || ml==UCHAR || ml==LONG || ml==ULONG ) && p->left->op != ICON ) break; 83: 84: /* pointers all have the same representation; the type is inherited */ 85: p->left->type = p->type; 86: p->left->cdim = p->cdim; 87: p->left->csiz = p->csiz; 88: p->op = FREE; 89: return( p->left ); 90: 91: case SCONV: 92: m = (p->type == FLOAT || p->type == DOUBLE ); 93: ml = (p->left->type == FLOAT || p->left->type == DOUBLE ); 94: if( m != ml ) break; 95: 96: /* now, look for conversions downwards */ 97: 98: m = p->type; 99: ml = p->left->type; 100: if( p->left->op == ICON ){ /* simulate the conversion here */ 101: CONSZ val; 102: val = p->left->lval; 103: switch( m ){ 104: case CHAR: 105: p->left->lval = (char) val; 106: break; 107: case UCHAR: 108: p->left->lval = val & 0XFF; 109: break; 110: case UNSIGNED: 111: p->left->lval = val & 0XFFFFL; 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==LONG || ml==ULONG ) break; 124: } 125: else if( m==INT || m==UNSIGNED ){ 126: if( ml==LONG || ml==ULONG ) break; 127: } 128: else if( m==LONG || m==ULONG ){ 129: if( ml!=LONG && ml!= ULONG ) break; 130: } 131: } 132: 133: /* clobber conversion */ 134: p->op = FREE; 135: return( p->left ); /* conversion gets clobbered */ 136: 137: case ASSIGN: 138: /* get rid of SCONV for assignments 139: from LONG -> CHAR|INT */ 140: if( p->right->op == SCONV ) { 141: m = p->right->type; 142: ml = p->right->left->type; 143: if( ( m==LONG || m==ULONG ) && 144: ml!=FLOAT && ml!=DOUBLE ) { 145: p->right->op = FREE; 146: p->right = p->right->left; 147: } 148: } 149: break; 150: 151: case PVCONV: 152: case PMCONV: 153: if( p->right->op != ICON ) cerror( "bad conversion", 0); 154: p->op = FREE; 155: return( buildtree( o==PMCONV?MUL:DIV, p->left, p->right ) ); 156: 157: case PLUS: 158: case MINUS: 159: case LS: 160: case MUL: 161: /* optimize address calculations with long indexes */ 162: if( ISPTR( p->type ) || ISARY( p->type ) ) { 163: if( p->left->type==LONG || p->left->type==ULONG ) 164: p->left = cast( p->left, INT ); 165: if( p->right->type==LONG || p->right->type==ULONG ) 166: p->right = cast( p->right, INT ); 167: } 168: break; 169: 170: } 171: 172: return(p); 173: } 174: 175: andable( p ) NODE *p; { 176: return(1); /* all names can have & taken on them */ 177: } 178: 179: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */ 180: autooff = AUTOINIT; 181: } 182: 183: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */ 184: 185: if( t==INT || t==UNSIGNED || ISPTR(t) ) return(1); 186: return(0); 187: } 188: 189: NODE * 190: offcon( off, t, d, s ) OFFSZ off; TWORD t; { 191: 192: /* return a node, for structure references, which is suitable for 193: being added to a pointer of type t, in order to be off bits offset 194: into a structure */ 195: 196: register NODE *p; 197: 198: /* t, d, and s are the type, dimension offset, and sizeoffset */ 199: /* in general they are necessary for offcon, but not on H'well */ 200: 201: p = bcon(0); 202: p->lval = off/SZCHAR; 203: return(p); 204: 205: } 206: 207: static inwd /* current bit offsed in word */; 208: static word /* word being built from fields */; 209: 210: incode( p, sz ) register NODE *p; { 211: 212: /* generate initialization code for assigning a constant c 213: to a field of width sz */ 214: /* we assume that the proper alignment has been obtained */ 215: /* inoff is updated to have the proper final value */ 216: /* we also assume sz < SZINT */ 217: 218: if((sz+inwd) > SZINT) cerror("incode: field > int"); 219: word |= p->lval<<inwd; 220: inwd += sz; 221: inoff += sz; 222: if(inoff%SZINT == 0) { 223: printf( " %o\n", word); 224: word = inwd = 0; 225: } 226: } 227: 228: fincode( d, sz ) double d; { 229: /* output code to initialize space of size sz to the value d */ 230: /* the proper alignment has been obtained */ 231: /* inoff is updated to have the proper final value */ 232: /* on the target machine, write it out in octal! */ 233: 234: register int *mi = (int *)&d; 235: 236: if( sz==SZDOUBLE ) 237: printf( " %o; %o; %o; %o\n", mi[0], mi[1], mi[2], mi[3] ); 238: else 239: printf( " %o; %o\n", mi[0], mi[1] ); 240: inoff += sz; 241: } 242: 243: cinit( p, sz ) NODE *p; { 244: /* arrange for the initialization of p into a space of 245: size sz */ 246: /* the proper alignment has been opbtained */ 247: /* inoff is updated to have the proper final value */ 248: ecode( p ); 249: inoff += sz; 250: } 251: 252: vfdzero( n ){ /* define n bits of zeros in a vfd */ 253: 254: if( n <= 0 ) return; 255: 256: inwd += n; 257: inoff += n; 258: if( inoff%ALINT ==0 ) { 259: printf( " %o\n", word ); 260: word = inwd = 0; 261: } 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: static char text[NCHNAM+1]; 270: 271: register i; 272: 273: text[0] = '_'; 274: for( i=1; *p&&i<NCHNAM; ++i ){ 275: text[i] = *p++; 276: } 277: 278: text[i] = '\0'; 279: text[NCHNAM] = '\0'; /* truncate */ 280: 281: return( text ); 282: } 283: 284: ctype( type ) TWORD type; { /* map types which are not defined on the local machine */ 285: switch( BTYPE(type) ){ 286: case SHORT: 287: MODTYPE(type,INT); 288: break; 289: case USHORT: 290: MODTYPE(type,UNSIGNED); 291: } 292: return( type ); 293: } 294: 295: noinit() { /* curid is a variable which is defined but 296: is not initialized (and not a function ); 297: This routine returns the stroage class for an uninitialized declaration */ 298: 299: return(EXTERN); 300: 301: } 302: 303: commdec( id ){ /* make a common declaration for id, if reasonable */ 304: register struct symtab *q; 305: OFFSZ off; 306: 307: q = &stab[id]; 308: printf( " .comm %s,", exname( q->sname ) ); 309: off = tsize( q->stype, q->dimoff, q->sizoff ); 310: printf( CONFMT, off/SZCHAR ); 311: printf( ".\n" ); 312: } 313: 314: isitlong( cb, ce ){ /* is lastcon to be long or short */ 315: /* cb is the first character of the representation, ce the last */ 316: 317: if( ce == 'l' || ce == 'L' || 318: lastcon >= (1L << (SZINT-1) ) ) return (1); 319: return(0); 320: } 321: 322: 323: isitfloat( s ) char *s; { 324: double atof(); 325: dcon = atof(s); 326: return( FCON ); 327: } 328: 329: ecode( p ) NODE *p; { 330: 331: /* walk the tree and write out the nodes.. */ 332: 333: if( nerrors ) return; 334: p2tree( p ); 335: p2compile( p ); 336: }