# 2.11BSD#431 - /usr/src/lib/pcc/local.c

##### Functions

    andable           X
    cast              X
    cendarg           X
    cinit             X
    cisreg            X
    clocal            X
    commdec           X
    ctype             X
    ecode             X
    exname            X
    fincode           X
    incode            X
    isitfloat         X
    isitlong          X
    noinit            X
    offcon            X
    tlen              X
    vfdzero           X

##### unions's

    cvt               X

       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

- in line 182-184(2)

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

- in line 314

exname defined in line 330; used 3 times

- in line 384
- in /usr/src/lib/pcc/code.c line 222-225(2)

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

- in /usr/src/lib/pcc/order.c line 30, 429-443(4)

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