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:     }

Defined functions

andable defined in line 175; never used
cast defined in line 6; used 2 times
cendarg defined in line 179; never used
cinit defined in line 243; never used
cisreg defined in line 183; never used
clocal defined in line 16; never used
commdec defined in line 303; never used
ctype defined in line 284; used 2 times
ecode defined in line 329; used 1 times
exname defined in line 265; used 3 times
fincode defined in line 228; never used
incode defined in line 210; never used
isitfloat defined in line 323; never used
isitlong defined in line 314; never used
noinit defined in line 295; never used
offcon defined in line 189; never used
vfdzero defined in line 252; never used
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 948
Valid CSS Valid XHTML 1.0 Strict