1: # include "pass1.h"
   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->in.left->in.op = FREE;
  12:     p->in.op = FREE;
  13:     return( p->in.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->in.op ){
  37: 
  38:     case NAME:
  39:         if( p->tn.rval < 0 ) { /* already processed; ignore... */
  40:             return(p);
  41:             }
  42:         q = &stab[p->tn.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->tn.lval = 0;
  50:             r->tn.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->tn.lval = 0;
  59:             p->tn.rval = -q->offset;
  60:             break;
  61: 
  62:         case REGISTER:
  63:             p->in.op = REG;
  64:             p->tn.lval = 0;
  65:             p->tn.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->in.left->in.type) || ISPTR(p->in.right->in.type)){
  75:             p->in.op += (ULT-LT);
  76:             }
  77:         break;
  78: 
  79:     case PCONV:
  80:         /* do pointer conversions for char and longs */
  81:         ml = p->in.left->in.type;
  82:         if( ( ml==CHAR || ml==UCHAR || ml==LONG || ml==ULONG ) && p->in.left->in.op != ICON ) break;
  83: 
  84:         /* pointers all have the same representation; the type is inherited */
  85:         p->in.left->in.type = p->in.type;
  86:         p->in.left->fn.cdim = p->fn.cdim;
  87:         p->in.left->fn.csiz = p->fn.csiz;
  88:         p->in.op = FREE;
  89:         return( p->in.left );
  90: 
  91:     case SCONV:
  92:         m = (p->in.type == FLOAT || p->in.type == DOUBLE );
  93:         ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE );
  94:         o = p->in.left->in.op;
  95:         if( (o == FCON || o == DCON) && ml && !m ) {
  96:             /* float type to int type */
  97:             r = block( ICON, (NODE *)NULL, (NODE *)NULL, LONG, 0, 0 );
  98:             if( o == FCON )
  99:                 r->tn.lval = (long) p->in.left->fpn.fval;
 100:             else
 101:                 r->tn.lval = (long) p->in.left->dpn.dval;
 102:             r->tn.rval = NONAME;
 103:             p->in.left->in.op = FREE;
 104:             p->in.left = r;
 105:             }
 106:         else
 107: #ifdef SPRECC
 108:             if ( ml || m )
 109: #else
 110:             if ( ml != m )
 111: #endif
 112:                 break;
 113: 
 114:         /* now, look for conversions downwards */
 115: 
 116:         m = p->in.type;
 117:         ml = p->in.left->in.type;
 118:         if( p->in.left->in.op == ICON ){ /* simulate the conversion here */
 119:             CONSZ val;
 120:             val = p->in.left->tn.lval;
 121:             switch( m ){
 122:             case CHAR:
 123:                 p->in.left->tn.lval = (char) val;
 124:                 break;
 125:             case UCHAR:
 126:                 p->in.left->tn.lval = val & 0XFF;
 127:                 break;
 128:             case UNSIGNED:
 129:                 p->in.left->tn.lval = val & 0XFFFFL;
 130:                 break;
 131:             case INT:
 132:                 p->in.left->tn.lval = (int)val;
 133:                 break;
 134:                 }
 135:             p->in.left->in.type = m;
 136:             }
 137:         else {
 138:             /* meaningful ones are conversion of int to char, int to short,
 139: 			   and short to char, and unsigned version of them */
 140:             if( m==CHAR || m==UCHAR ){
 141:                 if( ml==LONG || ml==ULONG ) break;
 142:                 }
 143:             else if( m==INT || m==UNSIGNED ){
 144:                 if( ml==LONG || ml==ULONG ) break;
 145:                 }
 146:             else if( m==LONG || m==ULONG ){
 147:                 if( ml!=LONG && ml!= ULONG ) break;
 148:                 }
 149:             }
 150: 
 151:         /* clobber conversion */
 152:         p->in.op = FREE;
 153:         return( p->in.left );  /* conversion gets clobbered */
 154: 
 155:     case ASSIGN:
 156:         /* get rid of SCONV for assignments
 157: 		   from LONG -> CHAR|INT	*/
 158:         if( p->in.right->in.op == SCONV ) {
 159:             m = p->in.right->in.type;
 160:             ml = p->in.right->in.left->in.type;
 161:             if( ( m==LONG || m==ULONG ) &&
 162:                 ml!=FLOAT && ml!=DOUBLE ) {
 163:                 p->in.right->in.op = FREE;
 164:                 p->in.right = p->in.right->in.left;
 165:                 }
 166:             }
 167:         break;
 168: 
 169:     case PVCONV:
 170:     case PMCONV:
 171:         if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0);
 172:         p->in.op = FREE;
 173:         return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );
 174: 
 175:     case PLUS:
 176:     case MINUS:
 177:     case LS:
 178:     case MUL:
 179:         /* optimize address calculations with long indexes */
 180:         if( ISPTR( p->in.type ) || ISARY( p->in.type ) ) {
 181:             if( p->in.left->in.type==LONG || p->in.left->in.type==ULONG )
 182:                 p->in.left = cast( p->in.left, INT );
 183:             if( p->in.right->in.type==LONG || p->in.right->in.type==ULONG )
 184:                 p->in.right = cast( p->in.right, INT );
 185:             }
 186:         break;
 187: 
 188:     case FLD:
 189:         /* make sure that the second pass does not make the
 190: 		   descendant of a FLD operator into a doubly indexed OREG */
 191: 
 192:         if( p->in.left->in.op == UNARY MUL
 193:                 && (r=p->in.left->in.left)->in.op == PCONV)
 194:             if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS )
 195:                 if( ISPTR(r->in.type) ) {
 196:                     if( ISUNSIGNED(p->in.left->in.type) )
 197:                         p->in.left->in.type = UCHAR;
 198:                     else
 199:                         p->in.left->in.type = CHAR;
 200:                 }
 201:         break;
 202:         }
 203: 
 204:     return(p);
 205:     }
 206: 
 207: andable( p ) NODE *p; {
 208:     return(1);  /* all names can have & taken on them */
 209:     }
 210: 
 211: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
 212:     autooff = AUTOINIT;
 213:     }
 214: 
 215: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */
 216: 
 217: #ifdef TRUST_REG_CHAR_AND_REG_SHORT
 218:     if( t==INT || t==UNSIGNED               /* tbl */
 219:         || t==CHAR || t==UCHAR || t==SHORT      /* tbl */
 220:         || t==USHORT || ISPTR(t)) return(1);        /* tbl */
 221: #else
 222:     if( t==INT || t==UNSIGNED               /* wnj */
 223: #ifdef  SPRECC
 224:         || t==FLOAT
 225: #endif
 226:         || ISPTR(t)) return (1);            /* wnj */
 227: #endif
 228:     return(0);
 229:     }
 230: 
 231: NODE *
 232: offcon( off, t, d, s ) OFFSZ off; TWORD t; {
 233: 
 234:     /* return a node, for structure references, which is suitable for
 235: 	   being added to a pointer of type t, in order to be off bits offset
 236: 	   into a structure */
 237: 
 238:     register NODE *p;
 239: 
 240:     /* t, d, and s are the type, dimension offset, and sizeoffset */
 241:     /* in general they  are necessary for offcon, but not on H'well */
 242: 
 243:     p = bcon(0);
 244:     p->tn.lval = off/SZCHAR;
 245:     return(p);
 246: 
 247:     }
 248: 
 249: static inwd /* current bit offsed in word */;
 250: static word /* word being built from fields */;
 251: 
 252: incode( p, sz ) register NODE *p; {
 253: 
 254:     /* generate initialization code for assigning a constant c
 255: 		to a field of width sz */
 256:     /* we assume that the proper alignment has been obtained */
 257:     /* inoff is updated to have the proper final value */
 258:     /* we also assume sz  < SZINT */
 259: 
 260:     if((sz+inwd) > SZINT) cerror("incode: field > int");
 261:     word |= ((unsigned)(p->tn.lval<<(16-sz))) >> (16-sz-inwd);
 262:     inwd += sz;
 263:     inoff += sz;
 264:     if(inoff%SZINT == 0) {
 265:         printf( "	%o\n", word);
 266:         word = inwd = 0;
 267:         }
 268:     }
 269: 
 270: fincode( d, sz ) double d; {
 271:     /* output code to initialize space of size sz to the value d */
 272:     /* the proper alignment has been obtained */
 273:     /* inoff is updated to have the proper final value */
 274:     /* on the target machine, write it out in octal! */
 275: 
 276:     register int *mi = (int *)&d;
 277: 
 278:     if( sz==SZDOUBLE )
 279:         printf( "	%o; %o; %o; %o\n", mi[0], mi[1], mi[2], mi[3] );
 280:     else
 281:         printf( "	%o; %o\n", mi[0], mi[1] );
 282:     inoff += sz;
 283:     }
 284: 
 285: cinit( p, sz ) NODE *p; {
 286:     NODE *l;
 287: 
 288:     /*
 289: 	 * as a favor (?) to people who want to write
 290: 	 *     int i = 9600/134.5;
 291: 	 * we will, under the proper circumstances, do
 292: 	 * a coersion here.
 293: 	 */
 294:     switch (p->in.type) {
 295:     case INT:
 296:     case UNSIGNED:
 297:         l = p->in.left;
 298:         if (l->in.op != SCONV ||
 299:             (l->in.left->tn.op != DCON && l->in.left->tn.op != FCON))
 300:             break;
 301:         l->in.op = FREE;
 302:         l = l->in.left;
 303:         l->tn.lval = l->tn.op == DCON ? (long)(l->dpn.dval) :
 304:             (long)(l->fpn.fval);
 305:         l->tn.rval = NONAME;
 306:         l->tn.op = ICON;
 307:         l->tn.type = INT;
 308:         p->in.left = l;
 309:         break;
 310:     }
 311:     /* arrange for the initialization of p into a space of size sz */
 312:     /* the proper alignment has been opbtained */
 313:     /* inoff is updated to have the proper final value */
 314:     ecode( p );
 315:     inoff += sz;
 316:     }
 317: 
 318: vfdzero( n ){ /* define n bits of zeros in a vfd */
 319: 
 320:     if( n <= 0 ) return;
 321: 
 322:     inwd += n;
 323:     inoff += n;
 324:     if( inoff%ALINT ==0 ) {
 325:         printf( "	%o\n", word );
 326:         word = inwd = 0;
 327:         }
 328:     }
 329: 
 330: char *
 331: exname( p ) char *p; {
 332:     /* make a name look like an external name in the local machine */
 333: 
 334: #ifndef FLEXNAMES
 335:     static char text[NCHNAM+1];
 336: #else
 337:     static char text[256+1];
 338: #endif
 339: 
 340:     register i;
 341: 
 342:     text[0] = '_';
 343: #ifndef FLEXNAMES
 344:     for( i=1; *p&&i<NCHNAM; ++i )
 345: #else
 346:     for( i=1; *p; ++i )
 347: #endif
 348:         text[i] = *p++;
 349: 
 350:     text[i] = '\0';
 351: #ifndef FLEXNAMES
 352:     text[NCHNAM] = '\0';  /* truncate */
 353: #endif
 354: 
 355:     return( text );
 356:     }
 357: 
 358: ctype( type ) TWORD type;
 359:      { /* map types which are not defined on the local machine */
 360:     switch( BTYPE(type) ){
 361: 
 362:     case SHORT:
 363:         MODTYPE(type,INT);
 364:         break;
 365:     case USHORT:
 366:         MODTYPE(type,UNSIGNED);
 367:         }
 368:     return( type );
 369:     }
 370: 
 371: noinit() { /* curid is a variable which is defined but
 372: 	is not initialized (and not a function );
 373: 	This routine returns the stroage class for an uninitialized declaration */
 374: 
 375:     return(EXTERN);
 376: 
 377:     }
 378: 
 379: commdec( id ){ /* make a common declaration for id, if reasonable */
 380:     register struct symtab *q;
 381:     OFFSZ off, tsize();
 382: 
 383:     q = &stab[id];
 384:     printf( "	.comm	%s,", exname( q->sname ) );
 385:     off = tsize( q->stype, q->dimoff, q->sizoff );
 386:     printf( CONFMT, off/SZCHAR );
 387:     printf( ".\n" );
 388:     }
 389: 
 390: isitlong( cb, ce ){ /* is lastcon to be long or short */
 391:     /* cb is the first character of the representation, ce the last */
 392: 
 393:     if( ce == 'l' || ce == 'L' ||
 394:         lastcon >= (1L << (SZINT-1) ) ) return (1);
 395:     return(0);
 396:     }
 397: 
 398: isitfloat( s ) char *s; {
 399:     union cvt {
 400:         double  d;
 401:         int n[4];
 402:     } cvt;
 403:     double atof();
 404: 
 405:     /* avoid floating point exception for double -> float conversions */
 406:     dcon = cvt.d = atof(s);
 407:     if( cvt.n[1] == 0 ){
 408:         fcon = dcon;
 409:         return( FCON );
 410:         }
 411:     return( DCON );
 412:     }
 413: 
 414: ecode( p ) NODE *p; {
 415: 
 416:     /* walk the tree and write out the nodes.. */
 417: 
 418:     if( nerrors ) return;
 419:     p2tree( p );
 420:     p2compile( p );
 421:     }
 422: 
 423: #ifndef ONEPASS
 424: tlen(p) NODE *p;
 425: {
 426:     switch(p->in.type) {
 427:         case CHAR:
 428:         case UCHAR:
 429:             return(1);
 430: 
 431:         case LONG:
 432:         case ULONG:
 433:         case FLOAT:
 434:             return(4);
 435: 
 436:         case DOUBLE:
 437:             return(8);
 438: 
 439:         default:
 440:             return(2);
 441:         }
 442:     }
 443: #endif

Defined functions

andable defined in line 207; never used
cast defined in line 6; used 2 times
cendarg defined in line 211; never used
cinit defined in line 285; never used
cisreg defined in line 215; never used
clocal defined in line 16; never used
commdec defined in line 379; never used
ctype defined in line 358; never used
ecode defined in line 414; used 1 times
exname defined in line 330; used 3 times
fincode defined in line 270; never used
incode defined in line 252; never used
isitfloat defined in line 398; never used
isitlong defined in line 390; never used
noinit defined in line 371; never used
offcon defined in line 231; never used
tlen defined in line 424; used 5 times
vfdzero defined in line 318; never used

Defined union's

cvt defined in line 399; never used
Last modified: 1991-07-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2580
Valid CSS Valid XHTML 1.0 Strict