Annotation of researchv9/jerq/sgs/optim/optutil.c, revision 1.1.1.1

1.1       root        1: /* @(#) optutil.c: 1.3 3/27/84                         */
                      2: /* optutil.c
                      3: **
                      4: **     Optimizer utilities for 3B code improver (PCI).
                      5: **
                      6: **
                      7: ** This module contains utility routines for the various peephole
                      8: ** window optimizations.
                      9: */
                     10: 
                     11: /* #include <ctype.h> -- optim.h takes care of this */
                     12: /* #include "defs" -- optim.h takes care of this; machine-dependent defs */
                     13: #include "optim.h"                     /* machine independent optimizer defs */
                     14: 
                     15: extern long atol();
                     16: /* isreg -- is operand string a register reference?
                     17: **
                     18: ** This routine tells whether an operand string is a register reference.
                     19: */
                     20: 
                     21: boolean
                     22: isreg(s)
                     23: char * s;                              /* operand string */
                     24: {
                     25: /* assume operand is a register reference if it begins with a % */
                     26: 
                     27:        return(*s == '%');
                     28: }
                     29: 
                     30: 
                     31: 
                     32: /* isnib -- is operand a nibble?
                     33: **
                     34: ** This routine tests an operand string and tells whether it is an
                     35: ** immediate operand that can fit in a nibble (4 bits).
                     36: */
                     37: 
                     38: boolean
                     39: isnib(s)
                     40: char * s;                              /* operand string to check */
                     41: {
                     42:     long x;                            /* temporary to hold value */
                     43: 
                     44: /* Return true if the operand begins with a '&', it is numeric,
                     45: ** and the numeric value is between 0 and 15.
                     46: */
                     47: 
                     48:     return(    *s == '&'               /* begins with & */
                     49:           &&   isdigit(*++s)           /* operand is numeric */
                     50:           &&   (x = atol(s)) >= 0      /* is positive */
                     51:           &&   x <= 15                 /* and <= 15 */
                     52:          );
                     53: }
                     54: /* isnegnib -- is operand a negative nibble?
                     55: **
                     56: ** This routine tests whether an operand string is an immediate operand
                     57: ** with a value between -1 and -15.  Another condition tested is that
                     58: ** the minus sign immediately follows an '&'.  (This condition is
                     59: ** important if the operand is overwritten.)
                     60: */
                     61: 
                     62: boolean
                     63: isnegnib(s)
                     64: char * s;                              /* operand string */
                     65: {
                     66:     long n;                            /* temporary operand value */
                     67: 
                     68:     return(
                     69:                s != NULL
                     70:            &&  *s++ == '&'             /* operand starts with & */
                     71:            &&  *s++ == '-'             /* followed by - */
                     72:            &&  isdigit(*s)             /* operand is numeric */
                     73:            &&  1 <= (n = atol(s))      /* (positive) value between 1... */
                     74:            &&  n <= 15                 /* and 15 */
                     75:            );
                     76: }
                     77: /* getbit -- get bit number for power of 2
                     78: **
                     79: ** This routine tests whether an operand is a power of 2.  If not, it
                     80: ** returns -1.  Otherwise it returns a bit number, which is also the
                     81: ** exponent of 2.
                     82: */
                     83: 
                     84: int
                     85: getbit(s)
                     86: char * s;                              /* pointer to operand string */
                     87: {
                     88:     int bit = 0;                       /* initialize bit number for later */
                     89:     long n;                            /* numeric value of operand */
                     90:     boolean isnumlit();
                     91: 
                     92:     if ( (! isnumlit(s)) || (n = atol(s+1)) < 0 )
                     93:        return(-1);                     /* check for numeric literal with
                     94:                                        ** good value
                     95:                                        */
                     96: 
                     97: /* This test really works, although it looks suspicious.  A power of two
                     98: ** has only one bit set, so that value minus one has all of the bits to
                     99: ** the right of the original bit set.  Anding them together gives zero.
                    100: ** No other value yields zero.
                    101: */
                    102: 
                    103:     if ( ( n & (n-1) ) != 0)
                    104:        return(-1);                     /* not a power of 2 */
                    105: 
                    106: /* Shift right until the word is zero */
                    107: 
                    108:     while ((n = n>>1) != 0)
                    109:        bit++;                          /* bump bit number each time */
                    110: 
                    111:     return(bit);                       /* return bit number */
                    112: }
                    113: /* insert -- insert new instruction node
                    114: **
                    115: ** This routine inserts a new instruction node after the one pointed
                    116: ** to.  The fields in the node are initialized to null values.
                    117: */
                    118: 
                    119: NODE *                                 /* return pointer to the new node */
                    120: insert(pn)
                    121: NODE * pn;                             /* node to add pointer after */
                    122: {
                    123:     NODE * Saveop();                   /* in machine-independent part */
                    124:     NODE * new = Saveop(0,"",0,GHOST); /* create isolated node, init. */
                    125: 
                    126:     APPNODE(new,pn);                   /* append new node after current */
                    127: 
                    128:     return(new);                       /* return pointer to the new one */
                    129: }
                    130: /* chgop -- change op code number and op code string in node
                    131: **
                    132: ** This routine changes the op code information in a node.  The
                    133: ** operand information is unaffected.
                    134: */
                    135: 
                    136: void
                    137: chgop(n,op,op_code)
                    138: NODE * n;                              /* pointer to node to change */
                    139: int op;                                        /* op code number */
                    140: char * op_code;                                /* pointer to op code string */
                    141: {
                    142:     n->op = op;                                /* set op code number */
                    143:     n->opcode = op_code;               /* and string */
                    144:     return;
                    145: }
                    146: /* copyopn -- copy operand string
                    147: **
                    148: ** This routine duplicates an operand string in a new piece of memory.
                    149: ** The caller can specify a +/- number of additional bytes required,
                    150: ** as well as an offset for copying.
                    151: */
                    152: 
                    153: char *                                 /* return duplicate string */
                    154: copyopn(s,extra,offset)
                    155: char * s;                              /* original operand string */
                    156: int extra;                             /* number of extra (or fewer) chars */
                    157: int offset;                            /* offset in original operand from
                    158:                                        ** which to start copying.
                    159:                                        */
                    160: {
                    161:     int len = strlen(s) + extra;       /* length of duplicate */
                    162:     char * stemp;                      /* future duplicate string */
                    163: 
                    164:     if (len <= 0)
                    165:        return(NULL);                   /* deleted everything */
                    166:     
                    167:     stemp = getspace(len+1);           /* get new string (+1 for null byte) */
                    168:     return(strcpy(stemp,s+offset));    /* return copy */
                    169: }
                    170: /* isdyadic -- is instruction dyadic
                    171: **
                    172: ** This routine tells whether an instruction is dyadic according
                    173: ** to the following conditions:
                    174: **
                    175: **     1.      It takes two operands.
                    176: **     2.      It reads the first operand, writes the second.
                    177: **     3.      It sets the condition codes according to the value stored in
                    178: **             the second operand.
                    179: **     4.      The operands have normal address mode meanings:  disallow,
                    180: **             for example, MOVAW, which does address arithmetic of op1.
                    181: */
                    182: 
                    183: boolean
                    184: isdyadic(n)
                    185: NODE * n;                              /* instruction node to test */
                    186: {
                    187:     switch(n->op)                      /* dispatch on op code number */
                    188:     {
                    189:     case MCOMW:
                    190:     case MOVZBH:
                    191:     case MOVZBW:
                    192:     case MOVZHW:
                    193:     case ANDW2:
                    194:     case ORW2:
                    195:     case XORW2:
                    196:     case LLSW2:
                    197:     case LRSW2:
                    198:     case MOVW:
                    199:     case MOVBBH:
                    200:     case MOVBBW:
                    201:     case MOVBHW:
                    202:     case MOVTHB:
                    203:     case MOVTWB:
                    204:     case MOVTWH:
                    205:     case MNEGW:
                    206:     case ADDW2:
                    207:     case SUBW2:
                    208:     case MULW2:
                    209:     case UMULW2:
                    210:     case DIVW2:
                    211:     case UDIVW2:
                    212:     case UMODW2:
                    213:     case ALSW2:
                    214:     case ARSW2:
                    215:        return(true);                   /* all of these are dyadic */
                    216:     default:
                    217:        return(false);                  /* others are not */
                    218:     }
                    219: }
                    220: /* istriadic -- is instruction triadic?
                    221: **
                    222: ** This routine serves a similar function to isdyadic, except that
                    223: ** it also returns the related dyadic op code number and string.
                    224: ** The only instructions included here are the obvious ones.  They
                    225: ** are assumed to have integer operands (by callers).
                    226: */
                    227: 
                    228: /* define macro to use below */
                    229: 
                    230: #define CHANGE(op,new,newst)   case op: *pnewop=new;*pnewopcode=newst;break;
                    231: 
                    232: 
                    233: boolean
                    234: istriadic(n,pnewop,pnewopcode)
                    235: NODE * n;                              /* node to test */
                    236: int * pnewop;                          /* place to put equiv. dyadic # */
                    237: char ** pnewopcode;                    /* place to put equiv. dyadic string */
                    238: {
                    239:     switch (n->op)                     /* dispatch on op code number */
                    240:     {
                    241:     CHANGE(ADDW3,ADDW2,"addw2");
                    242:     CHANGE(SUBW3,SUBW2,"subw2");
                    243:     CHANGE(MULW3,MULW2,"mulw2");
                    244:     CHANGE(UMULW3,UMULW2,"umulw2");
                    245:     CHANGE(DIVW3,DIVW2,"divw2");
                    246:     CHANGE(UDIVW3,UDIVW2,"udivw2");
                    247:     CHANGE(MODW3,MODW2,"modw2");
                    248:     CHANGE(UMODW3,UMODW2,"umodw2");
                    249:     CHANGE(ALSW3,ALSW2,"alsw2");
                    250:     CHANGE(ARSW3,ARSW2,"arsw2");
                    251:     CHANGE(ANDW3,ANDW2,"andw2");
                    252:     CHANGE(ORW3,ORW2,"orw2");
                    253:     CHANGE(XORW3,XORW2,"xorw2");
                    254:     CHANGE(LLSW3,LLSW2,"llsw2");
                    255:     CHANGE(LRSW3,LRSW2,"lrsw2");
                    256:     default:                           /* for op codes not found */
                    257:        return(false);
                    258:     }
                    259:     return(true);                      /* found op code */
                    260: }
                    261: /* totriadic -- can dyadic be made triadic?
                    262: **
                    263: ** This routine checks a dyadic instruction to see if it can be
                    264: ** made triadic.  If so, it returns the opcode number and string
                    265: ** for the corresponding triadic.  Totriadic is really the inverse
                    266: ** of istriadic.
                    267: */
                    268: 
                    269: boolean
                    270: totriadic(n,pnewop,pnewopcode)
                    271: NODE * n;                              /* node to test */
                    272: int * pnewop;                          /* place to put equiv. triadic # */
                    273: char ** pnewopcode;                    /* place to put equiv. triadic string */
                    274: {
                    275:     switch (n->op)                     /* dispatch on op code number */
                    276:     {
                    277:     CHANGE(ADDW2,ADDW3,"addw3");
                    278:     CHANGE(SUBW2,SUBW3,"subw3");
                    279:     CHANGE(MULW2,MULW3,"mulw3");
                    280:     CHANGE(UMULW2,UMULW3,"umulw3");
                    281:     CHANGE(DIVW2,DIVW3,"divw3");
                    282:     CHANGE(UDIVW2,UDIVW3,"udivw3");
                    283:     CHANGE(MODW2,MODW3,"modw3");
                    284:     CHANGE(UMODW2,UMODW3,"umodw3");
                    285:     CHANGE(ALSW2,ALSW3,"alsw3");
                    286:     CHANGE(ARSW2,ARSW3,"arsw3");
                    287:     CHANGE(ANDW2,ANDW3,"andw3");
                    288:     CHANGE(ORW2,ORW3,"orw3");
                    289:     CHANGE(XORW2,XORW3,"xorw3");
                    290:     CHANGE(LLSW2,LLSW3,"llsw3");
                    291:     CHANGE(LRSW2,LRSW3,"lrsw3");
                    292:     default:                           /* for op codes not found */
                    293:        return(false);
                    294:     }
                    295:     return(true);                      /* found op code */
                    296: }
                    297: /* makelive -- make register live
                    298: **
                    299: ** This routine marks a register operand as live.
                    300: */
                    301: 
                    302: void
                    303: makelive(s,n)
                    304: char * s;                              /* operand string (to %r0) */
                    305: NODE * n;                              /* pointer to node to enliven */
                    306: {
                    307:     n->nlive |= setreg(s);
                    308:     return;
                    309: }
                    310: 
                    311: 
                    312: 
                    313: /* makedead -- make register dead
                    314: **
                    315: ** This routine marks a register operand as dead.
                    316: */
                    317: 
                    318: void
                    319: makedead(s,n)
                    320: char * s;                              /* operand string (to %rn) */
                    321: NODE * n;                              /* pointer to node to kill */
                    322: {
                    323:     n->nlive &= ~ setreg(s);
                    324:     return;
                    325: }
                    326: /* isindex -- is operand an index off a register?
                    327: **
                    328: ** This routine checks whether an operand string is of the
                    329: ** form:
                    330: **
                    331: **     n(%rn)
                    332: **
                    333: ** and whether it uses a designated register.
                    334: **
                    335: ** Actually, it cheats:  it just checks for an initial digit or sign followed
                    336: ** by a (.  In fact the ( test is a cheat, because we just check to see
                    337: ** if there's a ( in the string.
                    338: */
                    339: 
                    340: boolean
                    341: isindex(s,r)
                    342: char * s;                              /* operand string to test */
                    343: char * r;                              /* register operand string to check
                    344:                                        ** for
                    345:                                        */
                    346: 
                    347: {
                    348:     char * strchr();
                    349: 
                    350:     if(*s == '*')
                    351:                s++;
                    352:     return(
                    353:                usesreg(s,r)
                    354:            &&  (isdigit(*s) || *s == '-') /* could be leading sign, too */
                    355:            &&  strchr(s,'(') != (char *) 0
                    356:            );
                    357: }
                    358: /* ismove -- is instruction a move?
                    359: **
                    360: ** This routine determines whether an instruction is a move-type.
                    361: ** There is a multiplicity of move instructions which copy, zero-
                    362: ** or sign-extend, and truncate.  This routine returns the natural
                    363: ** size of the source and destination operands.
                    364: */
                    365: 
                    366: boolean
                    367: ismove(n,srcsize,dstsize)
                    368: NODE * n;                              /* pointer to instruction node */
                    369: int * srcsize;                         /* place to put size of source
                    370:                                        ** operand (in bytes)
                    371:                                        */
                    372: int * dstsize;                         /* place to put size of destination */
                    373: {
                    374:     register int srctemp = 1;          /* temporary source size */
                    375:     register int dsttemp = 4;          /* temporary destination size */
                    376: /* Initial values chosen on basis of most common value of each. */
                    377: 
                    378:     switch (n->op)                     /* dispatch on op-code number */
                    379:     {
                    380:     case MOVZBH:
                    381:                        dsttemp = 2;    break;
                    382:     case MOVZBW:
                    383:                                        break;
                    384:     case MOVZHW:
                    385:        srctemp = 2;                    break;
                    386: 
                    387:     case MOVB:
                    388:                        dsttemp = 1;    break;
                    389:     case MOVH:
                    390:        srctemp = 2;    dsttemp = 2;    break;
                    391:     case MOVW:
                    392:        srctemp = 4;                    break;
                    393: 
                    394:     case MOVBBH:
                    395:                        dsttemp = 2;    break;
                    396:     case MOVBBW:
                    397:                                        break;
                    398:     case MOVBHW:
                    399:        srctemp = 2;                    break;
                    400: 
                    401:     case MOVTHB:
                    402:        srctemp = 2;    dsttemp = 1;    break;
                    403:     case MOVTWB:
                    404:        srctemp = 4;    dsttemp = 1;    break;
                    405:     case MOVTWH:
                    406:        srctemp = 4;    dsttemp = 2;    break;
                    407:     default:
                    408:        return(false);                  /* not a move instruction */
                    409:     }
                    410:     *srcsize = srctemp;                        /* copy out correct values */
                    411:     *dstsize = dsttemp;
                    412:     return(true);                      /* found a move */
                    413: }
                    414: /* iszoffset -- is operand zero offset from register
                    415: **
                    416: ** This routine determines whether a given operand is an indexed
                    417: ** operation from a designated register, where the index is zero.
                    418: */
                    419: 
                    420: boolean
                    421: iszoffset(operand,reg)
                    422: register char * operand;               /* operand string */
                    423: char * reg;                            /* register string */
                    424: {
                    425: 
                    426: /* We use a quick and dirty strategy here:  we test the operand for
                    427: ** zero, followed by (, with matching register numbers in the right
                    428: ** place.  We assume register designations are "%rn".
                    429: */
                    430: 
                    431:     return(
                    432:                *operand == '0'
                    433:            &&  *(operand+1) == '('
                    434:            &&  *(operand+4) == *(reg+2)
                    435:          );
                    436: }
                    437: /* exchange -- exchange node and successor
                    438: **
                    439: ** This routine reverses the linkages of two nodes so the first is
                    440: ** the second and the second is the first.
                    441: */
                    442: 
                    443: void
                    444: exchange(first)
                    445: NODE * first;                          /* pointer to first of two nodes */
                    446: {
                    447: 
                    448: /* This can probably be done with fewer temporaries, but it's a lot
                    449: ** easier to understand what's going on this way....
                    450: */
                    451: 
                    452:     NODE * prev = first->back;         /* predecessor of first node */
                    453:     NODE * second = first->forw;       /* second node of pair to exchange */
                    454:     NODE * next = second->forw;                /* successor of second node */
                    455: 
                    456:     prev->forw = second;               /* second will now be first */
                    457:     second->back = prev;
                    458: 
                    459:     first->forw = next;                        /* successor of old first is now
                    460:                                        ** 'next'
                    461:                                        */
                    462:     next->back=first;                  /* 'next's' predecessor now 'first' */
                    463: 
                    464:     second->forw = first;
                    465:     first->back = second;              /* re-link connection of node pair */
                    466: 
                    467:     return;
                    468: }
                    469: /* doindirect -- resolve indirect references
                    470: **
                    471: ** This routine changes variable references of the form
                    472: **     0(%rn)
                    473: ** to
                    474: **     *var
                    475: ** where possible.  Its purpose is to make it possible to discard a
                    476: ** register load.
                    477: **
                    478: ** Here's the scenario:  we're handed an instruction, the name of the
                    479: ** register whose zero-index use we want to change, and the real location
                    480: ** of the variable.  For example, in the sequence
                    481: **
                    482: **     movw xyz,%r0
                    483: **     addw2 0(%r0),%r1
                    484: **
                    485: ** the instruction we would be handed is the addw2, the register would be
                    486: ** %r0, and the real location of the variable is 'xyz'.
                    487: **
                    488: ** Complications:
                    489: **     1.  The register must be dead after the instruction.
                    490: **     2.  We want to change all such references in the instruction.
                    491: **     3.  If there are any other uses of the register than a zero
                    492: **             index, like actually using the register contents or
                    493: **             using an index other than zero (e.g., 4(%r0)), we
                    494: **             can't make the transformation, since we're going to
                    495: **             eliminate the preceding register load.
                    496: **     4.  ... except that if the destination of a triadic instruction or
                    497: **             move is the register it's safe to proceed.
                    498: **
                    499: ** One, possibly unsafe assumption:
                    500: **     The algorithm assumes that unused operands in an instruction (like
                    501: **     operands 3 and 4 in a dyadic) are always NULL.  We also assume that
                    502: **     an instruction has a "destination" (returned by 'dst') if and only
                    503: **     if it can alter something.  We further assume that the destination
                    504: **     is always the last operand.
                    505: */
                    506: 
                    507: boolean                                        /* true if the transformation
                    508:                                        ** was made
                    509:                                        */
                    510: doindirect(n,reg,repl)
                    511: NODE * n;                              /* instruction node to examine */
                    512: char * reg;                            /* register (string) to look for */
                    513: char * repl;                           /* operand string to use */
                    514: {
                    515:     boolean first = true;              /* if examining first real operand */
                    516:     int indmask = 0;                   /* will have bits set telling which
                    517:                                        ** operands to change
                    518:                                        */
                    519:     int i;                             /* loop index */
                    520:     char * operand;                    /* current operand */
                    521:     int src,dest;                      /* for ismove (but unused) */
                    522: /* Begin:  check whether transformation can be made, note which operands
                    523: ** to change if so.
                    524: */
                    525: 
                    526:     if (
                    527:            isret(n)                    /* will show register dead, which
                    528:                                        ** will confuse us
                    529:                                        */
                    530:        ||  ! (
                    531:                  isdead(reg,n)         /* reg must be dead after n */
                    532:               || ( ismove(n,&src,&dest) && samereg(n->op2,reg) )
                    533:               )                        /* unless set by this inst. as move */
                    534:        ||  *repl == '*'                /* can't do it if replacement is
                    535:                                        ** already an indirect...
                    536:                                        */
                    537:        ||  *repl == '&'                /* or an immediate */
                    538:        )
                    539:        return(false);                  /* can't do it */
                    540: 
                    541: /* Now scan operands for things that can't be transformed.  We do this
                    542: ** backward from higher numbered operands on the assumption that a
                    543: ** destination, which we treat differently, is the highest numbered
                    544: ** non-null operand.
                    545: */
                    546: 
                    547:     for ( i = MAXOPS; i > 0; i-- )
                    548:     {
                    549:        int opn;                        /* op code number in istriadic */
                    550:        char * opst;                    /* op code string in istriadic */
                    551: 
                    552:        if ( (operand = n->ops[i]) != NULL )
                    553:        {                               /* found an operand */
                    554:            if (iszoffset(operand,reg)) /* this is what we want! */
                    555:                indmask |= 1<<i;        /* remember where it is */
                    556:            
                    557:            /* otherwise can only use register if this is the last
                    558:            ** operand (but the first we'll find) and the instruction
                    559:            ** is triadic
                    560:            */
                    561: 
                    562:            else if (
                    563:                         ! (    samereg(operand,reg)
                    564:                            &&  first
                    565:                            &&  (
                    566:                                    istriadic(n,&opn,&opst)
                    567:                                 || ismove(n,&src,&dest)
                    568:                                )
                    569:                            )
                    570:                     &&  usesreg(operand,reg)
                    571:                     )
                    572:                return(false);          /* bad use of register */
                    573:            
                    574:            first = false;              /* no longer looking at first (last)
                    575:                                        ** operand
                    576:                                        */
                    577:        }
                    578:     }
                    579:     /* Reaching here, we have successfully scanned all operands without
                    580:     ** finding any register references that violate the required conditions.
                    581:     */
                    582: 
                    583:     if (indmask == 0)                  /* if no register references... */
                    584:        return(false);                  /* say we didn't change anything */
                    585:     if ( !isiros(repl) ) return( false ); /* check for mmio */
                    586: /* Now we're ready to do the actual transformations.  If the replacement
                    587: ** operand is a register reference, we create a new operand reference
                    588: ** of the form:
                    589: **     0(reg) --> 0(repl)
                    590: **
                    591: ** Otherwise we have a vanilla operand.  Rewrite it as
                    592: **
                    593: **     0(reg) --> *repl
                    594: */
                    595: 
                    596:     {                                  /* for some more variables */
                    597:        char * indstring;               /* new operand string */
                    598:        int extra;                      /* number of extra chars in xform */
                    599:        char * format;                  /* sprintf format string for xform */
                    600: 
                    601:        if (isreg(repl))                /* replacement is also reference */
                    602:        {
                    603:            format = "0(%s)";           /* to form 0(repl) */
                    604:            extra = 3;                  /* for 0 ( ) */
                    605:        }
                    606:        else
                    607:        {
                    608:            format = "*%s";             /* rewrite as *repl */
                    609:            extra = 1;                  /* prepend * only */
                    610:        }
                    611: 
                    612:        indstring = getspace(strlen(repl) + extra + 1);
                    613:                                        /* allocate space + 1 for null */
                    614:        (void) sprintf(indstring,format,repl);
                    615:                                        /* build replacement */
                    616:        
                    617:        wchange();                      /* Finally!  About to make changes */
                    618: 
                    619:        /* loop through operands, replacing ones whose bit is set in mask */
                    620: 
                    621:        for ( i = MAXOPS; i > 0; i-- )
                    622:        {
                    623:            if ( (indmask & (1<<i)) != 0)
                    624:                n->ops[i] = indstring;  /* stick in replacement string */
                    625:        }
                    626: 
                    627:        return(true);                   /* say we changed stuff */
                    628:     } /* end extra block */
                    629: }
                    630: /* isnumlit -- is operand a numeric literal
                    631: **
                    632: ** This routine tests operand strings for the form
                    633: **
                    634: **     &[-]n
                    635: **
                    636: ** where n is a positive integer.
                    637: */
                    638: 
                    639: boolean
                    640: isnumlit(s)
                    641: char * s;                              /* pointer to operand string */
                    642: {
                    643:     if (*s++ != '&')
                    644:        return(false);
                    645:     
                    646:     if (*s == '-')                     /* sign okay */
                    647:        s++;
                    648:     
                    649:     while (*s != '\0')                 /* check for all digits */
                    650:        if ( ! isdigit(*s++) )
                    651:            return(false);
                    652:     
                    653:     return(true);                      /* passed all tests */
                    654: }
                    655: /* usesvar -- does first operand use second?
                    656: **
                    657: ** This routine is a generalization of "usesreg":  it returns true
                    658: ** if the first operand uses the second.  An example is
                    659: ** v1 = "*p", v2 = "p".  v1 uses the contents of v2.
                    660: */
                    661: 
                    662: boolean
                    663: usesvar(v1,v2)
                    664: char * v1;                             /* using operand */
                    665: char * v2;                             /* used operand */
                    666: {
                    667:     if (isreg(v2) && usesreg(v1,v2))
                    668:        return(true);                   /* handle register case specially */
                    669: 
                    670:     if (*v1 == '*')                    /* check for initial indirect */
                    671:        v1++;
                    672: 
                    673:     return(strcmp(v1,v2) == 0);                /* result is result of compare */
                    674: }
                    675: 
                    676: 
                    677: /* These routines try to preserve the line number information.
                    678:    The criterion for saving or discarding line number information is
                    679:    that the state of the machine from a C point of view should be the
                    680:    same at any given line both before and after the optimization.
                    681:    If it would not be then the line number is deleted.
                    682:    The exceptions to the above are that the state of the condition codes 
                    683:    and of dead registers is ignored. 
                    684:    
                    685:        May 1983 */
                    686: 
                    687: /* NOTE: All instruction nodes that these routines assume will be tossed
                    688:          have their uniqids set to IDVAL.  For example, in the merges,
                    689:          the uniqids of the original instructions are set to IDVAL
                    690:          and then the uniqid of the resultant instruction is computed.
                    691:          This has the effect of setting the uniqid of the instruction 
                    692:          not corresponding to the resultant to IDVAL. This fact is used 
                    693:          in some instances where lnmrginst2 is called -- see w2opt.c */
                    694: 
                    695: /* delete instruction -- save line number
                    696:        if the instruction below has no line number or has a line number
                    697:        greater than the present instruction, the present number 
                    698:        is transfered down */
                    699: 
                    700: void
                    701: ldelin(nodep)
                    702: NODE * nodep;
                    703: {
                    704:        if(nodep->uniqid == IDVAL)
                    705:                return;
                    706: 
                    707:        if(nodep->forw != &ntail && 
                    708:           (nodep->forw->uniqid > nodep->uniqid 
                    709:                 || nodep->forw->uniqid == IDVAL))
                    710:                nodep->forw->uniqid = nodep->uniqid;
                    711: 
                    712:        nodep->uniqid = IDVAL;
                    713: 
                    714: }
                    715: 
                    716: /* more conservative version of lndelinst that does not overwrite
                    717:        line numbers below */
                    718: void
                    719: ldelin2(nodep)
                    720: NODE *nodep;
                    721: {
                    722:        if(nodep == IDVAL)
                    723:                return;
                    724: 
                    725:        if(nodep->forw != &ntail && nodep->forw->uniqid == IDVAL)
                    726:                nodep->forw->uniqid = nodep->uniqid;
                    727: 
                    728:        nodep->uniqid = IDVAL;
                    729: 
                    730: }
                    731: 
                    732: 
                    733: /* exchange instructions
                    734:        The line number of the first instruction, if any, is given to the
                    735:        second instruction.  The line number of the second instruction is 
                    736:        deleted. */
                    737: void
                    738: lexchin(nodep1,nodep2)
                    739: NODE *nodep1, *nodep2;
                    740: {
                    741:        if(nodep1->uniqid != IDVAL) {
                    742:                nodep2->uniqid = nodep1->uniqid;
                    743:                nodep1->uniqid = IDVAL;
                    744:        }
                    745:        else {
                    746:                nodep2->uniqid = IDVAL;
                    747:        }
                    748: }
                    749: 
                    750: 
                    751: /* merge instructions - case 1
                    752:        The result instruction is given the line number of the
                    753:        top instruction, if it exists, or else it is given the line
                    754:        number of the bottom instruction. */
                    755: void
                    756: lmrgin1(nodep1,nodep2,resnode)
                    757: NODE *nodep1, *nodep2, *resnode;
                    758: {
                    759:        IDTYPE val1, val2;
                    760: 
                    761:        val1 = nodep1->uniqid;
                    762:        val2 = nodep2->uniqid;
                    763: 
                    764:        nodep1->uniqid = nodep2->uniqid = IDVAL;
                    765: 
                    766:        if(val1 != IDVAL)
                    767:                resnode->uniqid = val1;
                    768:        else 
                    769:                resnode->uniqid = val2;
                    770: 
                    771: }
                    772: 
                    773: 
                    774: /* instruction merge - case 2
                    775:        The resultant instruction is given the line number of the
                    776:        top instruction, if it exists, else it is not given a line number */
                    777: void
                    778: lmrgin2(nodep1,nodep2,resnode)
                    779: NODE *nodep1, *nodep2, *resnode;
                    780: {
                    781:        IDTYPE val1;
                    782: 
                    783:        val1 = nodep1->uniqid;
                    784: 
                    785:        nodep1->uniqid = nodep2->uniqid = IDVAL;
                    786: 
                    787:        resnode->uniqid = val1;
                    788: 
                    789: }
                    790: 
                    791: /* instruction merge - case 3
                    792:        The resultant instruction is given the line number of the first
                    793:        instruction, if it exists. The instruction below the pair to be 
                    794:        merged is given the line number of the second instruction, 
                    795:        if it exists */
                    796: void
                    797: lmrgin3(nodep1,nodep2,resnode)
                    798: NODE *nodep1, *nodep2, *resnode;
                    799: {
                    800:        IDTYPE val1;
                    801: 
                    802:        ldelin2(nodep2);
                    803: 
                    804:        val1 = nodep1->uniqid;
                    805: 
                    806:        nodep1->uniqid = nodep2->uniqid = IDVAL;
                    807: 
                    808:        resnode->uniqid = val1;
                    809: }
                    810: 
                    811: /* isiros  --  is operand either immediate, register or on stack?
                    812: **
                    813: ** This routine returns true if the the operand 
                    814: ** pointed to by its argument has address mode
                    815: **
                    816: **             immediate,
                    817: **             register, or
                    818: **             offset from a stack pointer (fp, ap, or sp).
                    819: **
                    820: ** This test is provided for checking operands to see whether they
                    821: ** can be memory mapped i/o references.
                    822: */
                    823: 
                    824: boolean
                    825: isiros( op )
                    826: char *op;
                    827: {
                    828:        return( *op == '&' ||
                    829:                *op == '%' ||
                    830:                ( *op != '*' && 
                    831:                        ( usesreg( op, "%fp" ) ||
                    832:                        usesreg( op, "%ap" ) ||
                    833:                        usesreg( op, "%sp" ) 
                    834:                        ) 
                    835:                )
                    836:              );
                    837: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.